Player
public class PlayerContral : MonoBehaviour {
//拿到它的動畫系統
private Animation ani;
// Use this for initialization
void Start () {
ani = GetComponent<Animation>();
}
// Update is called once per frame
void Update () {
//獲取移動向量(在做動畫前,讓物體移動)
//獲取水平軸
float horizontal = Input.GetAxis("Horizontal");
//獲取垂直軸
float vertical = Input.GetAxis("Vertical");
//組建成我們要移動的向量
Vector3 dir = new Vector3(horizontal, 0, vertical);
Debug.DrawRay(transform.position + Vector3.up, dir * 2);
//如果不等於零,就說明走起來了
if(dir != Vector3.zero)
{
//播放走的動畫
ani.Play("RunFront");
//轉向。先拿到轉的方向。看向一個向量,返回一個四元數
Quaternion q = Quaternion.LookRotation(dir);
/*轉身動作(利用插值,賦值不直接賦值q。
如果transform.rotation = q;這樣直接賦值q,由前到後,沒有轉身的過渡動作。)*/
transform.rotation = Quaternion.Lerp(transform.rotation,q,0.1f);
//前進。Vector3.forward向前方,每秒走兩米。子彈是transform.forward。
transform.Translate(Vector3.forward * 2 * Time.deltaTime);
}
else
{
//播放站立的動畫
ani.Play("Idle");
}
}
}
Enemy
public class EnemyControl : MonoBehaviour {
//可以移動的點
private Transform movePoints;
//將要移動到的點
private Transform nextPoint;
//玩家的點
private Transform playerPoint;
// Use this for initialization
void Start () {
//通過名稱找到它,並拿到它的位置
movePoints = GameObject.Find("MovePoints").transform;
playerPoint = GameObject.FindWithTag("Player").transform; //注意unity裏的標籤有沒有設置
//先刷新一下下一個點。否則會在原地。
RefreshPoint();
}
// Update is called once per frame
void Update () {
//獲得和玩家的距離
float playerDis = Vector3.Distance(transform.position, playerPoint.position);
//判斷和玩家之間有沒有障礙
Ray ray = new Ray(transform.position + Vector3.up * 0.5f, playerPoint.position-transform.position);
//此處注意要指明檢測強這一層(將牆放到第8層——1<<8),或者如下利用名稱
bool res = Physics.Raycast(ray, Vector3.Distance(transform.position, playerPoint.position),1<<LayerMask.NameToLayer("Wall"));
Debug.DrawRay(transform.position + Vector3.up * 0.5f, playerPoint.position - transform.position); //漏洞2:如果沒有追玩家。
//用這條檢測:把上面那條射線畫出來。原因是沒有指定檢測牆這一層,所以敵人到玩家的這條射線會檢測到它倆的碰撞體,返回結果是true.
//如果距離小於3,並且和玩家之間沒障礙,我們就向玩家移動
if (playerDis < 3 && res == false)
{
nextPoint = playerPoint;
}
//點
//獲取和當前目標點的距離
float pointDis = Vector3.Distance(transform.position, nextPoint.position);
//Debug.Log(pointDis); //漏洞2:如果人物走到第一個所以目標點後,沒有向下一個點的目標前進。
//用這條檢測:打印它距離目標點的距離。
//此處原因:由於它最終距離目標的最近距離是0.5多點,所以原本的0.3f太小。改成0.6f就好了。
//如果距離小於0.6f,尋找下一個目標點,保證和玩家的距離大於2
if (pointDis <= 0.6f && playerDis > 2f)
{
RefreshPoint();
}
//如果正在追擊玩家,距離過遠,丟失追擊,更改目標
if (nextPoint.position == playerPoint.position && playerDis > 4)
{
//刷新下一個點
RefreshPoint();
}
//再獲取一下和當前目標點的距離
pointDis = Vector3.Distance(transform.position, nextPoint.position);
//向目標點前進
if (pointDis > 0.6f)
{
//Debug.Log(nextPoint.position); //漏洞1:如果沒走,就用這條測試
//-Vector3.up*0.5f是因爲人物的中心在腳上,避免人物後仰
transform.LookAt(nextPoint.position - Vector3.up * 0.5f);
//向前方行走
transform.Translate(Vector3.forward * 1 * Time.deltaTime);
}
}
//刷新一下下一個點的位置
void RefreshPoint()
{
//創建一個List,保存需要臨時保存的點
List<Transform> points = new List<Transform>();
//遍歷MovePoints的子節點,看能移動到哪個位置
foreach (Transform trans in movePoints)
{
//利用射線。從自身位置向子節點發射線,如果這條射線沒有碰到物體,說明可以移動到那裏。
//Vector3.up * 0.5是因爲我們將MovePoints的敢賭設定在高於地面0.5米的位置。
//從我們的位置(transform.position + Vector3.up * 0.5f),發射向量(trans.position - transform.position),
Ray ray = new Ray(transform.position + Vector3.up * 0.5f,trans.position - transform.position);
//判斷射線情況
bool res = Physics.Raycast(ray, Vector3.Distance(transform.position, trans.position));
if(res == false)
{
//這點可以走。由於可以走的點很多,所以需要臨時保存一下。
points.Add(trans);
}
if(points.Count>0)
{
//刷新一下將要移動的點。隨機
nextPoint = points[Random.Range(0, points.Count)];
}
}
}
}