室内第一人称移动逻辑

最近由于公司需要,在网上拼拼凑凑,加上自己的修改,完成了第一人称漫游的逻辑。

一共两个脚本,挂在到一个预制体上,该预制体要同时挂载CharacterController组件和一个Camera物体。

以下是截图:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;

public class FirstPeopleMove : MonoBehaviour
{
    public float speed = 6.0F;
    public float jumpSpeed = 8.0F;
    public float gravity = 20.0F;
    private Vector3 moveDirection = Vector3.zero;

    [HideInInspector]
   public CharacterController controller;
    private void Awake()
    {
        controller = GetComponent<CharacterController>();
    }
    void Start()
    {
       
    }
    void Update()
    {
        if (controller.isGrounded)
        {
            moveDirection = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
            moveDirection = transform.TransformDirection(moveDirection);
            moveDirection *= speed;
            if (Input.GetButton("Jump"))
                moveDirection.y = jumpSpeed;
        }
        moveDirection.y -= gravity * Time.deltaTime;
        controller.Move(moveDirection * Time.deltaTime);

      
    }

   

    /// <summary>
    /// 移动到某个目标位置
    /// </summary>
    /// <param name="target"></param>
    public void MoveTargetPosition(Vector3 target)
    {
        transform.DOMove(new Vector3(target.x,transform.position.y, target.z),2);// = new Vector3(target.x, 0.58f, target.z);

       
    }


    /// <summary>
    /// 移动到受限制的目标位置( 用于设备定位)
    /// </summary>
    public void MoveLimitTargetPosition(Vector3 target)
    {
        int time=2;
     
        if (Vector3.Distance(target, transform.position) < 5) time = 1;//若两点之间的距离小于5,则移动时间为1s,否则是2s

        transform.DOMove(new Vector3(target.x, transform.position.y, 0.6f), time).OnComplete(()=> {
            transform.DOLookAt(new Vector3(target.x, transform.position.y, target.z), 1).OnComplete(()=> {
                transform.GetComponent<FirstPeopleRotation>().SetRotation();

            });

        }); ;
       
    }

}
FirstPeopleMove
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FirstPeopleRotation : MonoBehaviour
{
    public float speed = 1;
    public float jumpPower = 5;
    public float gravity = 7f;

    public float mousespeed = 5f;


    public float minmouseY = -45f;
    public float maxmouseY = 45f;

    float RotationY = 0f;
    float RotationX = 0f;

    public Transform agretctCamera;

    private void Awake()
    {
      
    }
    // Use this for initialization
    void Start()
    {
       
    }

  
    void Update()
    {
        if (Input.GetMouseButton(0))
        {
            RotationX += agretctCamera.transform.localEulerAngles.y + Input.GetAxis("Mouse X") * mousespeed;
            RotationY -= Input.GetAxis("Mouse Y") * mousespeed;
            RotationY = Mathf.Clamp(RotationY, minmouseY, maxmouseY);

            this.transform.eulerAngles = new Vector3(0, RotationX, 0);
            agretctCamera.transform.eulerAngles = new Vector3(RotationY, RotationX, 0);
        }
    }



    /// <summary>
    /// 设置角度还原(是定位后的视角朝向不再和当前朝向冲突)
    /// </summary>
    public void SetRotation()
    {
        RotationY = agretctCamera.transform.localEulerAngles.x;
        RotationX = transform.eulerAngles.y;


    }
}
FirstPeopleRotation

 MoveTargetPosition和MoveLimitTargetPosition方法是我自己增加的。

MoveTargetPosition方法用于射线点击地面移动预制体位置。

MoveLimitTargetPosition方法用于点击设备将预制体自动移动到设备位置后视角看向设备位置。

最后一句代码transform.GetComponent<FirstPeopleRotation>().SetRotation();是为了解决视角旋转后出现的与当前计算朝向有冲突的问题,会导致朝向瞬间改变,添加完这句才会平滑移动朝向。

posted @ 2022-12-06 14:00  HuHuLikeSkill  阅读(28)  评论(0)    收藏  举报