【Unity3D】自動尋路的跳躍
阿新 • • 發佈:2019-01-07
《【Unity3D】自動尋路》(點選開啟連結)萬般好,但鎖死Y軸這點導致非常蛋疼的一個問題,我需要在自動尋路的過程允許遊戲主角進行跳躍。畢竟玩家都說了,在3D遊戲裡面不讓主角跳躍是一個很嚴重的問題,就像《阿瑪拉王國》本來做得非常好,但就是不能跳,導致大打折扣。那麼如果在Unity3D自動尋路的過程中進行跳躍呢?下面舉一個例子說明這個問題:
如圖所示,假設圖中的小球就是我們的主角,我按左鍵可以讓它自動尋路,按右鍵可以讓它跳,同時到了邊界還不會出現一堵無形的牆,小球能自然滑落的。
具體制作過程如下所示:
1、一如《【Unity3D】自動尋路》(點選開啟連結)拖Plane,整些Cube作障礙體,Sphere做主角,同時設定一個光源,並給這些東西加上材質。然後儲存場景,將Plane和Cube設定為Navigation Static,小球加上Nav Mesh Agent和Rigidbody,完成自動尋路的烘培。
2、給小球賦予GameScript.cs如下所示,則完成:
這裡的難點就是因為自動尋路Nav Mesh Agent鎖死了Y軸,導致和剛體Rigidbody想在3D世界中自由進行物理運動產生衝突,那麼我們在小球需要跳躍的時候就不要這個自動尋路好了,同時自動尋路Nav Mesh Agent一旦小球到達了Plane的邊界也會不知道為何會自動產生一股無形的牆,非要小球不能滑落,這裡也和剛體Rigidbody產生衝突的,我們也是需要解除自動尋路Nav Mesh Agent,讓小球得以滑落。using UnityEngine; using System.Collections; public class GameScript : MonoBehaviour { private NavMeshAgent navMeshAgent; private bool is_jumping, out_of_bound;//用於設定小球是否跳躍和已經到達自動尋路邊緣的flag void Start() { navMeshAgent = gameObject.GetComponent<NavMeshAgent>();//初始化navMeshAgent is_jumping = false; out_of_bound = false; } void Update() { if (Input.GetMouseButtonDown(0) && !is_jumping && !out_of_bound) {//如果不是在跳躍、不是到達自動尋路邊緣,按下滑鼠左鍵 //自動尋路 Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit mHit; if (Physics.Raycast(mRay, out mHit)) { if (mHit.collider.gameObject.name == "Plane")//如果點的是Plane上的一點 { this.rigidbody.velocity = new Vector3(0, 0, 0);//這裡是考慮到跳躍落地之後,使用者馬上要自動尋路的情況 navMeshAgent.SetDestination(mHit.point); } } } if (Input.GetMouseButtonDown(1) && !is_jumping && !out_of_bound)//按下滑鼠右鍵的話 { Ray mRay = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit mHit; if (Physics.Raycast(mRay, out mHit)) { if (mHit.collider.gameObject.name == "Plane") { navMeshAgent.enabled = false;//取消自動尋路 is_jumping = true;//讓小球進行跳躍 this.rigidbody.velocity = new Vector3(0, 0, 0); this.rigidbody.velocity = mHit.point + new Vector3(0, 5, 0);//基於一個點選位置方向加上y=5的向量速度 } } } if ((this.transform.position.x > 4.6 && this.rigidbody.velocity.x > 0.01) || (this.transform.position.x < -4.6 && this.rigidbody.velocity.x < -0.01) || (this.transform.position.z > 4.6 && this.rigidbody.velocity.z > 0.01) || (this.transform.position.z < -4.6 && this.rigidbody.velocity.z < -0.01)) {//如果已經到了Plane的邊緣 out_of_bound = true; navMeshAgent.enabled = false;//關閉自動尋路 } if (this.transform.position.y < -3)//如果小球已經掉得太下方 { Application.LoadLevel("Navmesh_jump");//重新開始 } } //小球如果和Plane開始碰撞 void OnCollisionEnter(Collision collision) { if (collision.collider.gameObject.name == "Plane" && is_jumping) { is_jumping = false; navMeshAgent.enabled = true;//重新開啟自動尋路 } } }
綜上所述,其實來來去去是如果協調好自動尋路Nav Mesh Agent在何時開關的問題。這裡在設定兩個flag之後,在使用者點選右鍵則讓小球進行跳躍狀態,執行《【Unity3D】用滑鼠點選事件、AddForce完成跳躍與二段跳》( 點選開啟連結)對跳躍的處理,然後用到《【Unity3D】利用物體碰撞檢測、鍵盤輸入處理完成平衡球遊戲》(點選開啟連結)對碰撞檢查的內容,設定進行跳躍狀態的小球一旦與Plane碰撞,則重新回到自動尋路的狀態。