一、制作敌人预制体
1. 在场景面板中添加敌人,并创建预制体
2. 设置敌人的锚点在底部
二、为敌人添加碰撞体积
1. 添加Box Collider 2D、Rigidbody 2D组件
2. 调整轴心点位置、层级、碰撞体积大小、刚体类型、锁定z轴
Body Type(刚体类型):Dynamic:自身运动,也会被其他刚体推动;Kinematic:自身运动,但不会被其他刚体推动;Static:自身不动,也不会被其他刚体推动
注意:敌人是碰撞器而不是触发器,所以不要勾选Is Trigger
三、编辑敌人脚本
1. 创建变量
public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 定义速度变量private float speed = 3.0f;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;
}
2. 初始化
public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 定义速度变量private float speed = 3.0f;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;}}
3. 编辑计时器、控制敌人移动
public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 定义速度变量private float speed = 3.0f;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;}void Update(){// 计时器每秒-1changeDirectionTimer -= Time.deltaTime;// 若计时器的值<0,改变方向,同时重置计时器的值if (changeDirectionTimer < 0) {direction *= -1;changeDirectionTimer = ChangeDirectionTime;}// 定义二维变量position,用来接收将要移动到的位置Vector2 position = rigidbody2d.position;// 改变position的值if(moveHorizontally) {position.x += speed * direction * Time.deltaTime;} else {position.y += speed * direction * Time.deltaTime;}// 控制敌人移动rigidbody2d.MovePosition(position);}}
4. Ruby和敌人碰撞的方法
public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 定义速度变量private float speed = 3.0f;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;}void Update(){// 计时器每秒-1changeDirectionTimer -= Time.deltaTime;// 若计时器的值<0,改变方向,同时重置计时器的值if (changeDirectionTimer < 0) {direction *= -1;changeDirectionTimer = ChangeDirectionTime;}// 定义二维变量position,用来接收将要移动到的位置Vector2 position = rigidbody2d.position;// 改变position的值if(moveHorizontally) {position.x += speed * direction * Time.deltaTime;} else {position.y += speed * direction * Time.deltaTime;}// 控制敌人移动rigidbody2d.MovePosition(position);}// 控制敌人和Ruby碰撞private void OnCollisionEnter2D(Collision2D collision) {Ruby ruby = collision.gameObject.GetComponent<Ruby>();if (ruby != null) {ruby.changeHealthPoint(-20);}}}
5. 添加敌人修复(即死亡效果)逻辑
添加布尔变量broken,表示是否修理好;在Update方法中进行判断,若已经修理好则return(停止移动);新建fix方法,在敌人生命值为0时调用
public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 敌人基础属性private int maxHealthPoint = 100;public int healthPoint;private float speed = 3.0f;private bool broken;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;// 为当前生命值赋值healthPoint = maxHealthPoint;// 敌人初始时是故障的broken = true;}void Update(){if (broken == false) {return;}// 计时器每秒-1changeDirectionTimer -= Time.deltaTime;// 若计时器的值<0,改变方向,同时重置计时器的值if (changeDirectionTimer < 0) {direction *= -1;changeDirectionTimer = ChangeDirectionTime;}// 定义二维变量position,用来接收将要移动到的位置Vector2 position = rigidbody2d.position;// 改变position的值if(moveHorizontally) {position.x += speed * direction * Time.deltaTime;} else {position.y += speed * direction * Time.deltaTime;}// 控制敌人移动rigidbody2d.MovePosition(position);}// 控制敌人和Ruby碰撞private void OnCollisionEnter2D(Collision2D collision) {Ruby ruby = collision.gameObject.GetComponent<Ruby>();if (ruby != null) {ruby.changeHealthPoint(-20);}}// 敌人改变生命值public void changeHealthPoint(int value){healthPoint = Mathf.Clamp(healthPoint+value, 0, maxHealthPoint);if(healthPoint <= 0) {enemyFixed();}}// 敌人修复完成public void enemyFixed(){broken = false;}}
6. 添加敌人动画控制器逻辑
public class Enemy : MonoBehaviour
{// 创建rigidbody2D对象Rigidbody2D rigidbody2d;// 创建动画控制器对象Animator animator;// 敌人基础属性private int maxHealthPoint = 100;public int healthPoint;private float speed = 3.0f;private bool broken;// 定义布尔变量,控制敌人移动是水平还是竖直方向public bool moveHorizontally = true;// 定义控制方向变量public int direction = 1;// 创建改变方向的时间间隔private const int ChangeDirectionTime = 3;// 创建改变方向的计时器private float changeDirectionTimer;void Start(){// 获取敌人刚体组件rigidbody2d = GetComponent<Rigidbody2D>();// 获取动画控制器组件animator = GetComponent<Animator>();// 计时器 = 改变方向的时间间隔changeDirectionTimer = ChangeDirectionTime;// 为当前生命值赋值healthPoint = maxHealthPoint;// 敌人初始时是故障的broken = true;// 设置初始动画if(moveHorizontally == true) {animator.SetFloat("MoveX", direction);} else {animator.SetFloat("MoveY", direction);}}void Update(){if (broken == false) {return;}// 计时器每秒-1changeDirectionTimer -= Time.deltaTime;// 若计时器的值<0,改变方向,同时重置计时器的值,更改动画播放的方向if (changeDirectionTimer < 0) {direction *= -1;changeDirectionTimer = ChangeDirectionTime;if(moveHorizontally == true) {animator.SetFloat("MoveX", direction);} else {animator.SetFloat("MoveY", direction);}}// 定义二维变量position,用来接收将要移动到的位置Vector2 position = rigidbody2d.position;// 改变position的值if(moveHorizontally) {position.x += speed * direction * Time.deltaTime;} else {position.y += speed * direction * Time.deltaTime;}// 控制敌人移动rigidbody2d.MovePosition(position);}// 控制敌人和Ruby碰撞private void OnCollisionEnter2D(Collision2D collision) {Ruby ruby = collision.gameObject.GetComponent<Ruby>();if (ruby != null) {ruby.changeHealthPoint(-20);}}// 敌人改变生命值public void changeHealthPoint(int value){healthPoint = Mathf.Clamp(healthPoint+value, 0, maxHealthPoint);if(healthPoint <= 0) {enemyFixed();}}// 敌人修复完成public void enemyFixed(){broken = false;animator.SetTrigger("Fixed");}}
四、为敌人添加动画
动画混合树详细教程:【Unity】动画混合树
1. 在Assets/Art/Animations/Animator文件夹中,新建Enemy的Animator Controller文件
2. 创建Move状态混合树
创建参数MoveX、MoveY(红色)
设置混合类型为2D简单方向(蓝色)
将两个参数设置为MoveX、MoveY(紫色)
创建四个Motion(黄色)
创建四个AnimationClip文件(敌人向四个方向移动的动画)并添加到Motion中(绿色)
修改四个Motion的两个参数的值(粉色)
3. 新建Fixed State,将Move通向Fixed,新建Trigger类型的Fixed参数,点击Move通向Fixed的箭头,将条件设置为Fixed
4. 给敌人添加Animator组件,并挂载Enemy的Animator Controller文件
本章完。感谢阅读!