unity 状态机 巡逻 追击 死亡 代码实现
时间: 2023-09-29 20:03:01 浏览: 53
以下是一个简单的Unity状态机,用于实现巡逻、追击和死亡行为:
```csharp
public class EnemyStateMachine : MonoBehaviour
{
public Transform[] patrolPoints; // 巡逻点
public float patrolSpeed = 3f; // 巡逻速度
public float chaseSpeed = 5f; // 追击速度
public float chaseRange = 10f; // 追击范围
public float attackRange = 2f; // 攻击范围
public float attackRate = 1f; // 攻击间隔
public int attackPower = 10; // 攻击力
public float deathDelay = 3f; // 死亡延迟
private Animator animator; // 动画控制器
private NavMeshAgent agent; // 导航代理
private Transform player; // 玩家
private int patrolIndex = 0; // 巡逻点索引
private float lastAttackTime = 0f; // 上次攻击时间
private bool isDead = false; // 是否死亡
private void Start()
{
animator = GetComponent<Animator>();
agent = GetComponent<NavMeshAgent>();
player = GameObject.FindGameObjectWithTag("Player").transform; // 假设玩家标签为"Player"
}
private void Update()
{
if (isDead)
return;
float distance = Vector3.Distance(transform.position, player.position);
// 如果玩家在攻击范围内并且攻击间隔已经过去,就攻击玩家
if (distance <= attackRange && Time.time - lastAttackTime >= attackRate)
{
Attack();
lastAttackTime = Time.time;
}
// 如果玩家在追击范围内,就追击玩家
else if (distance <= chaseRange)
{
Chase();
}
// 否则巡逻
else
{
Patrol();
}
}
private void Patrol()
{
agent.speed = patrolSpeed;
animator.SetBool("isWalking", true);
animator.SetBool("isRunning", false);
agent.SetDestination(patrolPoints[patrolIndex].position);
if (agent.remainingDistance <= agent.stoppingDistance)
{
patrolIndex = (patrolIndex + 1) % patrolPoints.Length;
}
}
private void Chase()
{
agent.speed = chaseSpeed;
animator.SetBool("isWalking", false);
animator.SetBool("isRunning", true);
agent.SetDestination(player.position);
}
private void Attack()
{
animator.SetBool("isAttacking", true);
player.GetComponent<PlayerHealth>().TakeDamage(attackPower); // 假设玩家有一个叫做PlayerHealth的组件来处理扣血
Invoke("ResetAttack", 1f); // 1秒后重置攻击状态
}
private void ResetAttack()
{
animator.SetBool("isAttacking", false);
}
public void Die()
{
if (isDead)
return;
animator.SetBool("isDead", true);
isDead = true;
agent.enabled = false;
Invoke("DestroySelf", deathDelay);
}
private void DestroySelf()
{
Destroy(gameObject);
}
}
```
该脚本需要挂载在敌人对象上,并且需要设置巡逻点和一些参数。在巡逻、追击和攻击时,分别设置动画状态和目标位置,攻击时还需要调用玩家组件的TakeDamage方法。在死亡时,设置动画状态为死亡并在一段延迟后销毁自身。