Article directory
The final effect of this section
Preface
This section follows the previous one and mainly implements weapon functions.
melee weapons
Added Bullet, bullet script
public class Bullet : MonoBehaviour
{
public float damage; // 子弹的伤害值
/// <summary>
/// 初始化子弹的属性
/// </summary>
/// <param name="damage">伤害值</param>
public void Init(float damage)
{
this.damage = damage; // 设置子弹的伤害值
}
}
Added new melee weapon prefab, added triggers, mounting scripts, and configuration parameters
Modify Enemy enemy script and add trigger detection
void OnTriggerEnter2D(Collider2D collision)
{
if (!collision.CompareTag("Bullet")) return;
health -= collision.GetComponent<Bullet>().damage;
if (health > 0)
{
}
else
{
Dead();
}
}
void Dead()
{
gameObject.SetActive(false);
}
Effect, enemies die on contact
Control melee weapon spawning
Configure melee weapons into the object pool
Added Weapon. Control weapon/bullet generation
public class Weapon : MonoBehaviour
{
public int id; // 武器/子弹的ID
public int prefabId; // 武器/子弹预制体的ID
public float damage; // 武器/子弹的伤害值
public int count; // 发射武器/子弹的数量
public float speed; // 武器旋转的速度
void Start()
{
Init(); // 初始化武器属性
}
void Update()
{
switch (id)
{
case 0:
transform.Rotate(Vector3.back, speed * Time.deltaTime); // 绕z轴旋转武器
break;
default:
break;
}
}
/// <summary>
/// 初始化武器/子弹属性
/// </summary>
public void Init()
{
switch (id)
{
case 0:
speed = 150; // 设置武器旋转的速度
Batch();
break;
default:
break;
}
}
/// <summary>
/// 批量配置武器属性
/// </summary>
void Batch()
{
for (int index = 0; index < count; index++)
{
Transform bullet = GameManager.instance.pool.Get(prefabId).transform; // 从对象池中获取武器预制体的实例
bullet.parent = transform; // 设置武器的父级为武器
Vector3 rotvec = Vector3.forward * 360 * index / count; // 计算武器的旋转角度,使其均匀分布在圆周上
bullet.Rotate(rotvec); // 设置武器的旋转角度
bullet.Translate(bullet.up * 1.5f, Space.World); // 将武器沿着自身的y轴方向向前移动一定距离
bullet.GetComponent<Bullet>().Init(damage); // 初始化武器的属性
}
}
}
Mount configuration parameters
Single weapon effect
Multiple weapon effect
Upgrades increase weapon damage and quantity
Modify Weapon
void Update()
{
//。。。
//测试
if (Input.GetKeyDown(KeyCode.Space))
{
LevelUp(20, 5);
}
}
/// <summary>
/// 批量配置武器属性
/// </summary>
void Batch()
{
for (int index = 0; index < count; index++)
{
Transform bullet;
if (index < transform.childCount)
{
bullet = transform.GetChild(index);
}
else
{
bullet = GameManager.instance.pool.Get(prefabId).transform;// 从对象池中获取武器预制体的实例
bullet.parent = transform;// 设置武器的父级为武器
}
//。。。
}
}
Effect
Find the enemy closest to the protagonist
Add Scanner
public class Scanner : MonoBehaviour
{
public float scanRange; // 扫描范围
public LayerMask targetLayer; // 目标层
public RaycastHit2D[] targets; // 扫描到的目标
public Transform nearestTarget; // 最近的目标
void FixedUpdate()
{
targets = Physics2D.CircleCastAll(transform.position, scanRange, Vector2.zero, 0, targetLayer); // 在扫描范围内发射圆形光线,获取扫描到的目标
nearestTarget = GetNearest();
}
// 获取最近的目标
Transform GetNearest()
{
Transform result = null; // 初始化最近的目标为null
float diff = scanRange; // 初始化最小距离为100,用于后面比较
foreach (RaycastHit2D target in targets)
{
Vector3 myPos = transform.position; // 获取自身位置
Vector3 targetPos = target.transform.position; // 获取目标位置
float curDiff = Vector3.Distance(myPos, targetPos); // 计算自身与目标的距离
if (curDiff < diff) // 如果当前目标距离比之前的最小距离还小,说明这个目标更近
{
diff = curDiff; // 更新最小距离
result = target.transform; // 更新最近的目标
}
}
return result; // 返回最近的目标
}
//场景窗口可视化射线
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(transform.position, scanRange);
Gizmos.color = Color.red;
}
}
Mount script, configuration parameters
The effect is to obtain the enemy closest to you.
bullet prefab
Object pool mounted bullet
generate bullets
Modify Weapon
float timer;
Player player;
void Start()
{
player = GameManager.instance.player;
Init(); // 初始化武器属性
}
void Update()
{
switch (id)
{
//。。。
default:
timer += Time.deltaTime;
if (timer > speed)
{
timer = 0f;
Fire();
}
break;
}
}
/// <summary>
/// 初始化武器/子弹属性
/// </summary>
public void Init()
{
switch (id)
{
//。。。
default:
speed = 0.3f;
break;
}
}
//发射子弹
void Fire()
{
if (!player.scanner.nearestTarget) return;
Transform bullet = GameManager.instance.pool.Get(prefabId).transform;
bullet.position = transform.position;
}
Modify Player to obtain recent enemy data
[NonReorderable]
public Scanner scanner;
scanner = GetComponent<Scanner>();
Configure bullet generation container and data
Effect, generate a bullet every 0.3 seconds
fire bullets
Modify Bullet
Rigidbody2D rigid;
private int per; // 子弹的穿透次数
void Awake()
{
rigid = GetComponent<Rigidbody2D>(); // 获取子弹的刚体组件
}
public void Init(float damage, int per, Vector3 dir)
{
this.damage = damage; // 初始化子弹的伤害值
this.per = per; // 初始化子弹的穿透次数
if (per > -1)
{
rigid.velocity = dir * 15f; // 如果子弹具有穿透次数,则设置子弹的初始速度和方向
}
}
void OnTriggerEnter2D(Collider2D collision)
{
if (!collision.CompareTag("Enemy") || per == -1) return; // 如果碰撞物体不是敌人或子弹没有穿透次数,直接返回
per--; // 穿透次数减一
if (per == -1)
{
rigid.velocity = Vector2.zero; // 如果穿透次数减到-1,即没有穿透能力了,将子弹的速度设为零
gameObject.SetActive(false); // 将子弹设为非激活状态,使其隐藏或回收
}
}
Modify Weapon
void Batch()
{
//。。。
bullet.GetComponent<Bullet>().Init(damage, -1, Vector3.zero); // 初始化武器的属性
}
}
// 发射子弹
void Fire()
{
if (!player.scanner.nearestTarget) return; // 如果玩家的扫描器没有最近的目标,直接返回
Vector3 targetPos = player.scanner.nearestTarget.position; // 获取最近目标的位置
Vector3 dir = targetPos - transform.position; // 计算从当前位置指向目标位置的方向向量
dir = dir.normalized; // 将方向向量归一化,使其成为单位向量
Transform bullet = GameManager.instance.pool.Get(prefabId).transform; // 从对象池中获取一个子弹对象
bullet.position = transform.position; // 设置子弹的初始位置为当前位置
bullet.rotation = Quaternion.FromToRotation(Vector3.up, dir); // 将子弹的朝向调整为指向目标位置的方向
bullet.GetComponent<Bullet>().Init(damage, count, dir); // 初始化子弹的伤害值、穿透次数和初始速度方向
}
Effect
Modify Weapon and upgrade testing
//测试
if (Input.GetKeyDown(KeyCode.Space))
{
LevelUp(10, 1);
}
The effect is that after the upgrade, the bullet has a certain degree of penetration.
reference
【Video】https://www.youtube.com/watch?v=MmW166cHj54&list=PLO-mt5Iu5TeZF8xMHqtT_DhAPKmjF6i3x
Source code
Source code is in the last section
end
Giving roses to others will leave a lingering fragrance in your hands! If the content of the article is helpful to you, please don't be stingy with your 点赞评论和关注
so that I can receive feedback as soon as possible. Every time you 支持
The greatest motivation for creation. Of course, if you find 存在错误
or 更好的解决方法
in the article, you are welcome to comment and send me a private message!
Good, I am向宇
,https://xiangyu.blog.csdn.net
A developer who has been working quietly in a small company recently started studying Unity by himself out of interest. If you encounter any problems, you are also welcome to comment and send me a private message. Although I may not necessarily know some of the questions, I will check the information from all parties and try to give the best suggestions. I hope to help more people who want to learn programming. People, encourage each other~