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