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)的空間位置,這可以通過先獲取屏幕坐標(biāo),然后轉(zhuǎn)成空間坐標(biāo);也可以通過射線直接獲取到空間位置。
其次 ,移動(dòng)物體到目的地,可直接通過差值進(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ā)生傾斜來看想目標(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平面,從而過濾掉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)文章
Unity ScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了Unity ScrollRect實(shí)現(xiàn)軌跡滑動(dòng)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
C#字節(jié)數(shù)組(byte[])和字符串相互轉(zhuǎn)換方式
這篇文章主要介紹了C#字節(jié)數(shù)組(byte[])和字符串相互轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
C# SendMail發(fā)送郵件功能實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了C# SendMail發(fā)送郵件功能實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
C#最簡(jiǎn)單的關(guān)閉子窗體更新父窗體的實(shí)現(xiàn)方法
原理就是將子窗體最為對(duì)話框模式彈出,當(dāng)窗體關(guān)閉或取消時(shí)更新主窗體2012-11-11

