unity3d俯视角简易移动控制脚本及其易错点小分享
涉及方法:
本文分別采用了 ‘collider+rigidbody’ / ‘character controller’ 兩種方式共四種情況來分享
在代碼中input采用unity基本的“Horizontal”+“Vertical”輸入獲取(unity新的那個input system用過包但還沒自己實際了解過嘿嘿(●ˇ?ˇ●))
如果是collider+rigidbody的話,使用的是rigidbody的MovePosition()方法
如果是character controller的話使用的是該控制器的simplemove函數(對應還有一個move函數,區別在于simplemove在被調用時將使物體具備重力,move函數則和translate相似。)
對于鼠標控制方向的情況通過raycast+getpoint方法獲取當前主攝像機與鼠標產生的射線找到與平面的交點,然后使用transform組件的LookAt方法調整朝向。
【使用character controller】準備:
【使用character controller】編寫move腳本:
第一種情況:角色移動方向與角色朝向一致:
{一些細節和注意事項都寫在代碼注釋中辣~}
using UnityEngine;/*** 功能:角色移動控制[角色移動時永遠朝正面]* */ public class move : MonoBehaviour {//速度變量public float speed;//定義角色控制器public CharacterController cc;void Start(){//組件cc變量cc = transform.GetComponent<CharacterController>();//速度賦值speed = 10;}void Update(){//調用移動方法move_by_cc();}void move_by_cc(){//水平方向的輸入獲取(即A-D鍵或←→鍵)float x = Input.GetAxisRaw("Horizontal");//垂直方面的輸入獲取float z = Input.GetAxisRaw("Vertical");/* GetAxis()的返回值初始為0,在-1到1之間變化,對應的GetAxisRaw()則不會變化,直接返回1或-1 *//*上面的input使用GetAxis()時在松開按鍵后角色會繼續移動一小部分距離,會產生一種“冰面滑動”的效果,使用GetAxisRaw()的話則即按即動,即松即停*/if (Mathf.Abs(x)>0.1f || Mathf.Abs(z) > 0.1f){//移動方向Vector3 toward_dir = new Vector3(x, 0, z);//角色朝向與移動方向一致transform.LookAt(transform.position + toward_dir);//不同于move函數,這里以秒為單位不能*Time.deltatime,不然會無法移動cc.SimpleMove(transform.forward * speed);}} }第二種情況:角色移動方向可以不與角色朝向一致(鍵盤控制移動,鼠標控制朝向):
{一些細節和注意事項都寫在代碼注釋中辣~}
using UnityEngine;/*** 功能:角色移動控制[鍵盤控制移動,鼠標控制朝向]* */ public class move2 : MonoBehaviour {//速度變量public float speed;//定義角色控制器public CharacterController cc;//攝像機public Camera viewCamera;void Start(){//組件cc變量cc = transform.GetComponent<CharacterController>();//速度賦值speed = 5;//當前主攝像機viewCamera = Camera.main;}void Update(){//調用移動方法move_by_cc();}void move_by_cc(){/*移動部分*///水平方向的輸入獲取(即A-D鍵或←→鍵)float x = Input.GetAxisRaw("Horizontal");//垂直方面的輸入獲取float z = Input.GetAxisRaw("Vertical");/* GetAxis()的返回值初始為0,在-1到1之間變化,對應的GetAxisRaw()則不會變化,直接返回1或-1 *//*上面的input使用GetAxis()時在松開按鍵后角色會繼續移動一小部分距離,會產生一種“滑滑”的效果,使用GetAxisRaw()的話則即按即動,即送即停*/if (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f){//移動方向Vector3 toward_dir = new Vector3(x,0,z);//不同于move函數,這里以秒為單位不能*Time.deltatime,不然會無法移動//(normalized指單位化,即此時該向量不具備大小僅具備方向)cc.SimpleMove(toward_dir.normalized * speed);}/*鼠標朝向部分*///生成從攝像機發射的射線,該射線穿過當前鼠標位置【因為視角透視原因,鼠標位置并不能代表實際我們希望的朝向,所以需要通過射線找到與平面的實際交點】Ray ray = viewCamera.ScreenPointToRay(Input.mousePosition);//創建一個平面,第一個參數和第二個參數構成法線,且平面穿過第二個參數點Plane groundPlane = new Plane(Vector3.up, Vector3.zero);//平面與射線相交返回發射點到相交點的距離float rayDistance;Vector3 point = Vector3.zero;//Raycast計算相交點并返回距離if (groundPlane.Raycast(ray, out rayDistance)){//獲取到射線與平面的相交點,耶~point = ray.GetPoint(rayDistance);//指示線打印-用于測試//Debug.DrawLine(ray.origin, point, Color.red);}//角色朝向-鼠標預期方向Vector3 heightCorrectedPoint = new Vector3(point.x, transform.position.y, point.z);transform.LookAt(heightCorrectedPoint);} }------------------------------------------------------------------另一種方式------------------------------------------------------------------
【使用collider+rigidbody】準備:
【使用collider+rigidbody】】編寫move腳本:
第一種情況:角色移動方向與角色朝向一致:
{一些細節和注意事項都寫在代碼注釋中辣~}
using UnityEngine;/*** 功能:角色移動控制[角色移動時永遠朝正面]* */ public class move3 : MonoBehaviour {//速度變量public float speed;//Rb剛體public Rigidbody rb;void Start(){//組件rb變量rb = transform.GetComponent<Rigidbody>();//速度賦值speed = 7;} //【將Update函數修改為FixedUpdate,并且deltaTime修改為fixedDeltatime移動似乎會流暢一些,感覺有一點點變化,但是也不確定是不是心理作用】void Update(){//調用移動方法move_by_rb();}void move_by_rb(){//水平方向的輸入獲取(即A-D鍵或←→鍵)float x = Input.GetAxisRaw("Horizontal");//垂直方面的輸入獲取float z = Input.GetAxisRaw("Vertical");/* GetAxis()的返回值初始為0,在-1到1之間變化,對應的GetAxisRaw()則不會變化,直接返回1或-1 *//*上面的input使用GetAxis()時在松開按鍵后角色會繼續移動一小部分距離,會產生一種“滑滑”的效果,使用GetAxisRaw()的話則即按即動,即送即停*/if (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f){//移動方向Vector3 toward_dir = new Vector3(x, 0, z);//角色朝向移動方向transform.LookAt(transform.position + toward_dir);//MovePosition方法,以幀為單位,記得*Time.deltaTime哦~(normalized指單位化,即此時該向量不具備大小僅具備方向)rb.MovePosition(rb.position + toward_dir.normalized * speed * Time.deltaTime);}} }第二種情況:角色移動方向可以不與角色朝向一致(鍵盤控制移動,鼠標控制朝向):
{一些細節和注意事項都寫在代碼注釋中辣~}
using UnityEngine;/*** 功能:角色移動控制[角色移動時永遠朝正面]* */ public class move4 : MonoBehaviour {//速度變量public float speed;//Rb剛體public Rigidbody rb;//攝像機public Camera viewCamera;void Start(){//組件rb變量rb = transform.GetComponent<Rigidbody>();//速度賦值speed = 7;//主攝像機viewCamera = Camera.main;}//【將Update函數修改為FixedUpdate,并且deltaTime修改為fixedDeltatime移動似乎會流暢一些,感覺有一點點變化,但是也不確定是不是心理作用】void Update(){//調用移動方法move_by_rb();}void move_by_rb(){/*移動部分*///水平方向的輸入獲取(即A-D鍵或←→鍵)float x = Input.GetAxisRaw("Horizontal");//垂直方面的輸入獲取float z = Input.GetAxisRaw("Vertical");/* GetAxis()的返回值初始為0,在-1到1之間變化,對應的GetAxisRaw()則不會變化,直接返回1或-1 *//*上面的input使用GetAxis()時在松開按鍵后角色會繼續移動一小部分距離,會產生一種“滑滑”的效果,使用GetAxisRaw()的話則即按即動,即送即停*/if (Mathf.Abs(x) > 0.1f || Mathf.Abs(z) > 0.1f){//移動方向Vector3 toward_dir = new Vector3(x, 0, z);//MovePosition方法,以幀為單位,記得*Time.deltaTime哦~(normalized指單位化,即此時該向量不具備大小僅具備方向)rb.MovePosition(rb.position + toward_dir.normalized * speed * Time.deltaTime);}/*鼠標朝向部分*///生成從攝像機發射的射線,該射線穿過當前鼠標位置【因為視角透視原因,鼠標位置并不能代表實際我們希望的朝向,所以需要通過射線找到與平面的實際交點】Ray ray = viewCamera.ScreenPointToRay(Input.mousePosition);//創建一個平面,第一個參數和第二個參數構成法線,且平面穿過第二個參數點Plane groundPlane = new Plane(Vector3.up, Vector3.zero);//平面與射線相交返回發射點到相交點的距離float rayDistance;Vector3 point = Vector3.zero;//Raycast計算相交點并返回距離if (groundPlane.Raycast(ray, out rayDistance)){//獲取到射線與平面的相交點,耶~point = ray.GetPoint(rayDistance);//指示線打印-用于測試//Debug.DrawLine(ray.origin, point, Color.red);}//角色朝向-鼠標預期方向Vector3 heightCorrectedPoint = new Vector3(point.x, transform.position.y, point.z);transform.LookAt(heightCorrectedPoint);} }以上就是本次的分享內容辣~(●ˇ?ˇ●),可以看到兩種方式的本質操作是沒有什么較大的區別的,僅在于準備部分的不同和代碼中對應組件的調用不同而已,不過這里還要告訴大家的是,一般使用character controller是為了自定義一些更‘游戲化’的物理效果,而collider+rigidbody的方法則更偏向于真實物理世界,但是很多時候游戲不一定越真實就越舒服。
總結
以上是生活随笔為你收集整理的unity3d俯视角简易移动控制脚本及其易错点小分享的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人间词话(6)
- 下一篇: android 重力感应view,And