接着三,此次主要是编码操控怪物的动做
设定一下这个类的主要功能:
- 初始化的时候怪物站立,播放idle动画
- 发现与主角位置 < 20 时冲向主角
- 被攻击时冲向主角
- 与主角距离 < 7时攻击主角
- 攻击方式随机3中
1.新建一个类EnemyController:
先定义一些变量:
//攻击距离范围
private const int ATTACK_DISTANCE = 7;
//吸引怪物距离
private const int RUN_TO_ROLE_DISTANCE = 20;
//攻击对应的生命减小值
private const int BlOOD_REDUCE_ATTACK1 = 5;
private const int BlOOD_REDUCE_ATTACK2 = 8;
private const int BlOOD_REDUCE_ATTACK3 = 10;
//怪物当前的状态
private const int STATE_IDLE = 1;
private const int STATE_RUN = 2;
private const int STATE_ATTACK = 3;
private const int STATE_DEAD = 4;
//当前状态
private int currentState;
//动画
private Animation ani;
//主角
private GameObject role;
//是否被攻击
private bool isAttacked = false;
//是否已经被主角吸引了仇恨
private bool isAttacking = false;
初始化的时候,先获取到怪物对象的动画组件以及主角对象。
// Use this for initialization
void Start () {
ani = animation;
role = GameObject.Find ("role");
}
2.而后在update()方法里面添加3个方法用来刷新怪物的动做
// Update is called once per frame
void Update () {
checkState();
checkAttack();
handlerAction ();
}
3.第一个方法checkState()主要是用于判断当前怪物与主句的位置
进行状态变动:
//检测怪物状态
private void checkState()
{
if (Vector3.Distance(role.transform.position, transform.position) <= RUN_TO_ROLE_DISTANCE
&& Vector3.Distance(role.transform.position, transform.position) > ATTACK_DISTANCE )
{
currentState = STATE_RUN;
}
else if (Vector3.Distance(role.transform.position, transform.position) <= ATTACK_DISTANCE)
{
currentState = STATE_ATTACK;
isAttacking = true; //设置怪物仇恨被激活
}
else
{
currentState = STATE_IDLE;
}
4.第二个方法checkAttack()主要是检测怪物的仇恨是否已被激活,若是是,
则不管距离多少都一直追着主角跑:
//是否已经被吸引了仇恨
private void checkAttack()
{
if(true == isAttacking)
{
transform.LookAt(role.transform);
if (Vector3.Distance(role.transform.position, transform.position) > 7)
{
run();
}
}
}
//朝主角跑来
private void run()
{
ani.Play("run");
transform.LookAt(role.transform);
//Returns this vector with a magnitude of 1 (Read Only).
//When normalized, a vector keeps the same direction but its length is 1.0.
Vector3 dir = (role.transform.position - transform.position).normalized;//追击方向
transform.Translate(-dir * Common.MOVE_SPEED * Time.deltaTime);//不停地移动
}
5.第三个方法handlerAction()是根据状态来处理怪物的动做:
//根据状态处理处理怪物动做
private void handlerAction()
{
switch (currentState) {
case STATE_IDLE:
ani.Play("idle");
break;
case STATE_RUN:
run();
break;
case STATE_ATTACK:
//上一次攻击完了以后才进行下一次攻击
if (false == ani.isPlaying)
{
attack();
}
break;
case STATE_DEAD:
dead();
break;
default:
Debug.Log("error state = "+currentState);
break;
}
}
//攻击
private void attack()
{
isAttacking = true;
int attackIndex = Random.Range (1, 4);
switch (attackIndex) {
case STATE_IDLE:
ani.Play("attack1");
//告诉主角生命减小量
//Calls the method named methodName on every MonoBehaviour in this game object.
role.SendMessage("reduceBlood", BlOOD_REDUCE_ATTACK1);
break;
case STATE_RUN:
ani.Play("attack2");
//告诉主角生命减小量
role.SendMessage("reduceBlood", BlOOD_REDUCE_ATTACK2);
break;
case STATE_ATTACK:
ani.Play("attack3");
//告诉主角生命减小量
role.SendMessage("reduceBlood", BlOOD_REDUCE_ATTACK3);
break;
default:
Debug.Log("error state = "+currentState);
break;
}
}
//死亡
private void dead()
{
Destroy (gameObject);
}
6.新建一个文件RoleBloodController并把它绑定在Role上:
public class RoleBloodController : MonoBehaviour{
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void reduceBlood(int reduceNum)
{
Debug.Log (reduceNum);
}
}
7.运行游戏~!