unity3D 实现物体(人物)移动到鼠标点击的位置

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函数每帧进行位置变更来实现位置的移动;
//位置+向量=新的位置
//将位移向量 归一,方便用速度变量控制
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);
    }
}

猜你喜欢

转载自blog.csdn.net/lizhenxiqnmlgb/article/details/80620393