筆記15 炸彈人遊戲

筆記15 炸彈人遊戲

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)];
            }
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章