接着三,此次主要是編碼操控怪物的動做
設定一下這個類的主要功能:
- 初始化的時候怪物站立,播放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.運行遊戲~!