Unity實(shí)現(xiàn)移動(dòng)物體到鼠標(biāo)點(diǎn)擊位置
本文實(shí)例為大家分享了Unity實(shí)現(xiàn)移動(dòng)物體到鼠標(biāo)點(diǎn)擊位置的具體代碼,供大家參考,具體內(nèi)容如下
目的: 移動(dòng)物體到鼠標(biāo)點(diǎn)擊處屏幕所對(duì)應(yīng)的空間位置,并使物體正對(duì)著點(diǎn)擊的對(duì)象,不能傾斜。
首先,需要獲取點(diǎn)擊屏幕所對(duì)應(yīng)的空間位置,這可以通過(guò)先獲取屏幕坐標(biāo),然后轉(zhuǎn)成空間坐標(biāo);也可以通過(guò)射線直接獲取到空間位置。
其次 ,移動(dòng)物體到目的地,可直接通過(guò)差值進(jìn)行移動(dòng),使物體看向目標(biāo)點(diǎn),不能直接使用LookAt(),因?yàn)?,該函?shù)是使物體的前方面向目標(biāo)點(diǎn)(即物體的forward指向
由物體到目標(biāo)點(diǎn)的向量,這可能使物體在X,Y,Z方向都產(chǎn)生旋轉(zhuǎn),也就產(chǎn)生了傾斜)。當(dāng)目標(biāo)點(diǎn)和物體高度不一致時(shí),比如站著的人 ,讓他走向地面上某一位置,如果使用
LookAt則可能會(huì)導(dǎo)致人歪著看向目標(biāo)點(diǎn),如下圖所示,而通常我們想要的只是人面向物體的方向。
//物體的正方向只Z的方向,朝向點(diǎn)擊處,夠?qū)⒛P蜁r(shí)要調(diào)好 using UnityEngine; using System.Collections; public class Move : MonoBehaviour { private Vector3 targetPos; // Use this for initialization void Start () { } // Update is called once per frame void Update () { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if(Physics.Raycast(ray,out hit,1000.0f)){ targetPos = hit.point; } turnForward2(transform, targetPos); } //transform.LookAt(targetPos); transform.position = Vector3.Lerp(transform.position, targetPos, Time.deltaTime); } /// <summary> /// 直接用transform.LookAt(targetPos);當(dāng)目標(biāo)點(diǎn)和遠(yuǎn)點(diǎn)不在一個(gè)高度時(shí),會(huì)使物體發(fā)生傾斜來(lái)看想目標(biāo)點(diǎn) /// 該方法使物體朝向指向的方向,同時(shí)保持物體不傾斜,只繞y軸旋轉(zhuǎn)一定角度 /// </summary> /// <param name="origin"></param> /// <param name="target"></param> void turnForward(Transform origin,Vector3 target) { //Vector3 forward_dir = target - origin.position; //Quaternion rotate = Quaternion.FromToRotation(origin.forward, forward_dir); //float angle = rotate.eulerAngles.y; //origin.rotation *= rotate; //將原坐標(biāo)和目的坐標(biāo)映射到XOZ平面,從而過(guò)濾掉y軸方向的旋轉(zhuǎn)的影響 Vector3 t1 = new Vector3(origin.position.x, 0, origin.position.z); Vector3 t2 = new Vector3(target.x, 0, target.z); Vector3 forward_dir = t2-t1; Quaternion rotate = Quaternion.FromToRotation(origin.forward, forward_dir); float angle = rotate.eulerAngles.y; origin.rotation *= rotate;//實(shí)現(xiàn)旋轉(zhuǎn)。 } /// <summary> /// 只繞y軸旋轉(zhuǎn) /// </summary> /// <param name="origin"></param> /// <param name="target"></param> void turnForward2(Transform origin, Vector3 target) { Vector3 forward_dir = target - origin.position; Quaternion rotate = Quaternion.FromToRotation(origin.forward, forward_dir); float angle = rotate.eulerAngles.y; // origin.rotation *= rotate; // origin.Rotate(0f, angle, 0f); origin.Rotate(Vector3.up,angle); } }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#調(diào)用sql2000存儲(chǔ)過(guò)程方法小結(jié)
這篇文章主要介紹了C#調(diào)用sql2000存儲(chǔ)過(guò)程的方法,以實(shí)例形式分別對(duì)調(diào)用帶輸入?yún)?shù)及輸出參數(shù)的存儲(chǔ)過(guò)程進(jìn)行了詳細(xì)分析,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2014-10-10C#Process的OutputDataReceived事件不觸發(fā)問(wèn)題及解決
這篇文章主要介紹了C#Process的OutputDataReceived事件不觸發(fā)問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02詳解如何在C#中循環(huán)訪問(wèn)目錄樹(shù)
在C#中,訪問(wèn)文件系統(tǒng)是常見(jiàn)的需求之一,有時(shí)我們需要遍歷目錄樹(shù)以執(zhí)行某些操作,例如搜索文件、計(jì)算目錄大小或執(zhí)行批量處理,本文將詳細(xì)介紹如何在C#中循環(huán)訪問(wèn)目錄樹(shù),并提供一個(gè)完整的示例,需要的朋友可以參考下2024-08-08C#網(wǎng)絡(luò)編程基礎(chǔ)之進(jìn)程和線程詳解
這篇文章主要介紹了C#網(wǎng)絡(luò)編程基礎(chǔ)之進(jìn)程和線程詳解,本文對(duì)進(jìn)程、線程、線程池知識(shí)做了淺顯易懂的講解,并配有代碼實(shí)例,需要的朋友可以參考下2014-08-08C#對(duì)多個(gè)集合和數(shù)組的操作方法(合并,去重,判斷)
下面小編就為大家?guī)?lái)一篇C#對(duì)多個(gè)集合和數(shù)組的操作方法(合并,去重,判斷)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-12-12詳解C# 利用反射根據(jù)類名創(chuàng)建類的實(shí)例對(duì)象
這篇文章主要介紹了詳解C# 利用反射根據(jù)類名創(chuàng)建類的實(shí)例對(duì)象,“反射”其實(shí)就是利用程序集的元數(shù)據(jù)信息,感興趣的小伙伴們可以參考一下。2017-03-03c#同步兩個(gè)子目錄文件示例分享 兩個(gè)文件夾同步
這篇文章主要介紹了使用c#同步兩個(gè)子目錄文件的方法,大家參考使用吧2014-01-01