一、制作敌人预制体
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()
{
// 计时器每秒-1
changeDirectionTimer -= 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()
{
// 计时器每秒-1
changeDirectionTimer -= 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;
}
// 计时器每秒-1
changeDirectionTimer -= 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;
}
// 计时器每秒-1
changeDirectionTimer -= 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文件
本章完。感谢阅读!