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);
}
}