unity3D 實現物體(人物)移動到滑鼠點選的位置
阿新 • • 發佈:2019-01-31
1、通過輸入滑鼠右鍵獲取游標在螢幕上的座標資訊,if(Input.GetMouseButtonDown(1)){ Vector3 mousePosition= Input.MousePosition;}//此處獲得的是游標在螢幕上的相對座標,不方便直接使用。2、將該游標轉化為世界座標//從相機中打出一個經過mousePosition的射線Ray ray=Camera.main.ScreenPointRay(mousePosition);//獲取射線打中物體的資訊(在實際運用中會增加對物體的限制,一般為僅限地面)RaycastHit hitInfo;if(Physics.Raycast(ray, out hitInfo)){ Vector3 endPoint =hitInfo.point;}3、獲取位移向量//終點座標-起點座標=起點到終點的位移向量;Vector3 v = endPoint - tank.position;4、實現移動//通過Update函式每幀進行位置變更來實現位置的移動;//位置+向量=新的位置//將位移向量v 歸一化,方便用速度變數控制var next=v.normalized * speed * Time.deltaTime;tank.position+=next;5、實現轉向//獲取forward 與位移向量的夾角float angle=Vector3.Angle(v, tank.forward)//通過轉速變數來控制轉向速度float minAngle = Mathf.Min(angle, angluarSpeed * Time.deltaTime);//利用叉乘的方法實現轉向,叉乘方法對與辨認左右極為便利 transform.Rotate(Vector3.Cross(tank.forward,v.normalized),minAngle);一下為完整程式碼:(在上面基礎上進行了拓展實現了連續點選幾個位置,坦克逐個巡邏的功能
轉向的實現發放上用了點乘的方法。)
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class MoveToTarget : MonoBehaviour { Transform MyTrans; List<Vector3> endPoints; float speed = 5; float angluarSpeed = 100; void Start() { MyTrans = GetComponent<Transform>(); endPoints = new List<Vector3>(); } void Update() { if (Input.GetMouseButtonDown(1)) { UpdateControl(); } if (endPoints.Count > 0) { Vector3 v = endPoints[0] - MyTrans.position; var dot = Vector3.Dot(v, MyTrans.right); Vector3 next = v.normalized * speed * Time.deltaTime; float angle = Vector3.Angle(v, MyTrans.forward); if (Vector3.SqrMagnitude(v) > 1f) { float minAngle = Mathf.Min(angle, angluarSpeed * Time.deltaTime); //點乘 if (angle > 1f) { //transform.Rotate(Vector3.Cross(tank.forward, v.normalized), minAngle); if (dot > 0) { MyTrans.Rotate(new Vector3(0, minAngle, 0)); } else { MyTrans.Rotate(new Vector3(0, -minAngle, 0)); } } else { MyTrans.LookAt(endPoints[0]); MyTrans.position += next; } } else { endPoints.RemoveAt(0); } } } void UpdateControl() { //獲取螢幕座標 Vector3 mousepostion = Input.mousePosition; //定義從螢幕 Ray ray = Camera.main.ScreenPointToRay(mousepostion); RaycastHit hitInfo; if (Physics.Raycast(ray, out hitInfo)) { if (Input.GetKey(KeyCode.LeftShift)) { AddEndPoint(hitInfo.point); } else { ReSetEndPoint(hitInfo.point); } //transform.LookAt(endPoint); //transform.Translate(movePoint * 0.1f); } } void AddEndPoint(Vector3 endPoint) { endPoint.y = MyTrans.position.y; endPoints.Add(endPoint); } void ReSetEndPoint(Vector3 endPoint) { endPoint.y = MyTrans.position.y; endPoints.Clear(); endPoints.Add(endPoint); } }