[unity]角色第三人称移动脚本实现

使用刚体移动可以避免使用transform组件移动造成的角色碰到物体抽搐现象

大致的步骤:

获取Animator组件和刚体组件---->获取输入管理器的数据---->得到世界坐标---->世界坐标转为本地坐标---->获取前进量与转向量(前进量为本地坐标向前,转向量用artan表示)---->定义一个用于修改状态机中控制前进和转向的函数---->控制刚体的前进与转向

完整代码:

角色:

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;

public class ChaMove : MonoBehaviour
{
    public float speed=3;
    public float turnspeed = 10;
    Animator anim;
    Vector3 move;

    Rigidbody rigid;

    float forwardamount;//前进量
    float turnamount;//转向量

    Transform m_camera,m_transform;
    void Start()
    {
        anim= GetComponent<Animator>();
        rigid= GetComponent<Rigidbody>();
        m_camera = GameObject.FindGameObjectWithTag("MainCamera").transform;
        m_transform = this.transform;
    }

    // Update is called once per frame
    void Update()
    {

        Vector3 cameraForward = m_camera.forward;
        cameraForward.y = 0; // 忽略摄像机的垂直分量
        cameraForward.Normalize(); // 归一化向量

        float x = Input.GetAxis("Horizontal");
        float z = Input.GetAxis("Vertical");

        //世界坐标系move向量
        //move = Vector3.Scale(new Vector3(x, 0, z), cameraForward);
        move = cameraForward * z + Camera.main.transform.right * x;
        Vector3 localmove= transform.InverseTransformVector(move);

        forwardamount=localmove.z;
        turnamount = Mathf.Atan2(localmove.x, localmove.z);//反正切,x/z,x越大转向越大,z越大转向越小

        //transform.LookAt(transform.position + new Vector3(x, 0, z));
        //transform.position += new Vector3(x, 0, z) * speed * Time.deltaTime;

        if (Input.GetKey(KeyCode.LeftShift)) {
            forwardamount *= 2;
        }

        UpdateAnim();
    }
    private void FixedUpdate()
    {
        rigid.velocity/*刚体的移动速度*/= forwardamount*transform.forward * speed/*前进量*当前人物的前方速度*/+rigid.velocity.y*Vector3.up;
        rigid.MoveRotation(rigid.rotation/*原有的朝向*/* Quaternion.Euler(0,turnamount*turnspeed,0)/*新的转向角度*/);
    }

    void UpdateAnim()
    {
        //anim.SetFloat("Speed", move.magnitude);
        anim.SetFloat("Forward",forwardamount);
        anim.SetFloat("Turn", turnamount);

    }
}

 摄像机:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Camera_chontrol : MonoBehaviour
{
    public Transform pivot; // the object being followed
    public Vector3 pivotOffset = Vector3.zero; // offset from target's pivot
    public Transform target; // like a selected object (used with checking if objects between cam and target)

    public float distance = 10.0f; // distance from target (used with zoom)
    public float minDistance = 2f;
    public float maxDistance = 15f;
    public float zoomSpeed = 1f;

    public float xSpeed = 250.0f;
    public float ySpeed = 120.0f;

    public bool allowYTilt = true;
    public float yMinLimit = 30f;
    public float yMaxLimit = 80f;

    private float x = 0.0f;
    private float y = 0.0f;

    private float targetX = 0f;
    private float targetY = 0f;
    private float targetDistance = 0f;
    private float xVelocity = 1f;
    private float yVelocity = 1f;
    private float zoomVelocity = 1f;

    void Start()
    {
        var angles = transform.eulerAngles;
        targetX = x = angles.x;
        targetY = y = ClampAngle(angles.y, yMinLimit, yMaxLimit);
        targetDistance = distance;
    }

    void LateUpdate()
    {
        if (pivot)
        {
            float scroll = Input.GetAxis("Mouse ScrollWheel");

            if (scroll > 0.0f) targetDistance -= zoomSpeed;
            else if (scroll < 0.0f) targetDistance += zoomSpeed;
            targetDistance = Mathf.Clamp(targetDistance, minDistance, maxDistance);

            // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
            // right mouse button must be held down to tilt/rotate cam
            // or player can use the left mouse button while holding Ctr
            if (Input.GetMouseButton(1) || (Input.GetMouseButton(0) && (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl))))
            {
                targetX += Input.GetAxis("Mouse X") * xSpeed * 0.02f;
                if (allowYTilt)
                {
                    targetY -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
                    targetY = ClampAngle(targetY, yMinLimit, yMaxLimit);
                }
            }
            x = Mathf.SmoothDampAngle(x, targetX, ref xVelocity, 0.3f);
            if (allowYTilt) y = Mathf.SmoothDampAngle(y, targetY, ref yVelocity, 0.3f);
            else y = targetY;
            Quaternion rotation = Quaternion.Euler(y, x, 0);
            distance = Mathf.SmoothDamp(distance, targetDistance, ref zoomVelocity, 0.5f);

            // -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
            // apply
            Vector3 position = rotation * new Vector3(0.0f, 0.0f, -distance) + pivot.position + pivotOffset;
            transform.rotation = rotation;
            transform.position = position;

        }
    }

    private float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360) angle += 360;
        if (angle > 360) angle -= 360;
        return Mathf.Clamp(angle, min, max);
    }
}

 方法1:

 混合树(黄色)中:

注意:混合类型、三个运动域、两个参数

 (自上而下)三个状态分别为:待机,走路,跑步

 方法2:

但是要注意三条分别指向Jump动画的过渡中要把过渡持续时间改为0

 

 然后就可以自由拖动视角移动+角色向前为正方向移动

Unity实现第一人称(FPV, First Person View)和第三人称(TPV, Third Person View)之间的切换,通常涉及到以下几个步骤: 1. **设置基本角色控制器**:首先,你需要创建一个基础的角色控制器,比如`CharacterController`或自定义的脚本,用于控制角色移动。 2. **添加相机组件**:为每种视点模式分别添加相机。第一人称可以有一个跟随头部移动的相机(`FirstPersonCamera`),第三人称则需要一个主摄像机并保持固定距离(`ThirdPersonCamera`)。 3. **状态管理**:创建一个状态机或者使用`Switch`等条件语句,来控制当前的视点模式。你可以创建一个枚举或者布尔变量来表示是第一人称还是第三人称。 4. **切换函数**:编写两个函数,一个用于切换到第一人称,另一个切换到第三人称。在第一人称模式下,将玩家设置为跟随主角的眼睛,而在第三人称模式下,调整摄像机的位置和旋转。 5. **绑定事件**:关联游戏中的交互动作(如点击按钮、键盘快捷键)到相应的切换函数。例如,玩家按下某个键时执行切换操作。 6. **动画和视觉效果**:确保角色在切换时有适当的动画效果,并且UI元素(如视角图标)会随着视图模式的变化而更新。 **示例代码片段(伪代码)**: ```csharp public class CameraManager : MonoBehaviour { public bool IsThirdPerson { get; private set; } public CharacterController controller; public ThirdPersonCamera thirdPersonCam; public FirstPersonCamera firstPersonCam; void Start() { IsThirdPerson = true; // 初始为第三人称 } void SwitchToThirdPerson() { if (IsThirdPerson) return; // 第一人称逻辑... controller.transform.position = new Vector3(0, 1.6f, 0); // 高度调整 IsThirdPerson = true; thirdPersonCam.gameObject.SetActive(true); firstPersonCam.gameObject.SetActive(false); } void SwitchToFirstPerson() { if (!IsThirdPerson) return; // 第三人称逻辑... controller.transform.position = Vector3.zero; // 恢复到默认位置 IsThirdPerson = false; thirdPersonCam.gameObject.SetActive(false); firstPersonCam.gameObject.SetActive(true); } // 键盘绑定示例 void Update() { if (Input.GetKeyDown(KeyCode.T)) SwitchToThirdPerson(); else if (Input.GetKeyDown(KeyCode.F)) SwitchToFirstPerson(); } } //
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值