
与if语句一起使用时,状态机不是最佳选择,因此为了获得最佳性能,需要将它们与Switch语句一起使用。
所以在Update中,需要奠定Switch语句的基础:
void Update()
{
switch(_currentState)
{
}
}
对于每种情况的不同,需要使用不同的状态:
void Update()
{
switch(_currentState)
{
case( EnemyState.Chase):
break;
case( EnemyState.Attack):
break;
}
}
对于Attack状态,应该将代码模块化一点,并将攻击代码放在它自己的方法中:
void Attack()
{
if(Time.time > _nextAttack)
{
if (_playerHealth != null)
{
_playerHealth. Damage(10);
}
_nextAttack = Time.time + _attackDelay;
}
}
现在将其称为Attack case。
void Update()
{
switch(_currentstate)
{
case(EnemyState.Chase):
break;
case(Enemystate.Attack):
Attack();
break;
}
}
从以上代码可以理解CalculateMovement的属于为Chase:
void Update()
{
switch(_currentstate)
{
case( EnemyState.chase):
CalculateMovement();
break;
case(EnemyState.Attack):
Attack();
break;
}
}
现在就可以展示更清晰、更易读的Unity代码了,这是更新后的EnemyAI脚本:
using System.collections;
using System.collections.Generic;
using UnityEngine;
public class EnemyAI : MonoBehaviour
{
private characterController _controller;
private Gameobject _player;
Vector3 _direction,_velocity;
[SerializeField] private float _speed = l;
[SerializeField] private float _speedVariance;
private float _gravity;
public enum EnemyState
{
Idle,
chase,
Attack
}
[SerializeField] private EnemyState _currentState = EnemyState.chase;
private Health _playerHealth;
private float _attackDelay = 1.5f;
private float _nextAttack = -1f;
private void Start()
// 持有
_controller = GetComponent<CharacterController>();
if (_controller == null)
{
Debug.LogError("CharacterController is NULL");
}
_player = Gameobject . FindwithTag("Player");
if (_player == null)
{
Debug.LogError("Player is NULL");
}
_playerHealth = _player. GetComponent<Health>();
if( _playerHealth == null)
{
Debug.LogError("Player Health is NULL");
}
// 变量
_gravity = 1.2f;
_speedvariance = Random.Range(0f,.6f);
}
void Update()
{
switch( _currentState)
{
case(Enemystate.Chase):
calculateMovement();
break;
case(EnemyState.Attack ):
Attack();
break;
}
}
void Attack()
{
if(Time.time > _nextAttack)
{
if(_playerHealth != null)
{
_playerHealth.Damage(10);
}
_nextAttack = Time.time + _attackDelay;
}
}
void CalculateMovement()
{
if(_controller.isGrounded)
{
_direction = _player.transform.position - transform.position;
_direction.y = 0;
_direction.Normalize();
_velocity = _direction * (_speed + _speedVariance);
}
//转身看着玩家
transform.rotation = Quaternion.LookRotation(_direction);
_velocity.y -= _gravity;
_controller.Move(_velocity * Time.deltaTime);
}
void onTriggerEnter( collider other)
{
if (other.tag == "Player")
{
_currentstate = EnemyState.Attack;
}
}
void OnTriggerExit(Collider other)
{
if (other.tag == "Player")
{
_currentstate = EnemyState.Chase;
}
}
}