Unity キャラクターの第三者の動き

以下は詳細な設定で、完全なコードは下部にあります

1.プレイヤー設定

1. 最初に、スクリプト PlayerController をキャラクターに追加します。追加されたその他のコンポーネントには、CapsuleCollider、Rigidbody、および Animator が含まれます。

2. 横軸と縦軸からなるベクトルを求める

// 获取轴使用Input.GetAxisRaw方法,平滑过渡通过代码来完成
// 由于未对输入进行平滑处理,键盘输入将始终为 -1、0 或 1。 如果您想自己完成键盘输入的所有平滑处理,这非常有用。
Vector2 input = new Vector2(Input.GetAxisRaw(GameConsts.HORIZONTAL_AXIS), Input.GetAxisRaw(GameConsts.VERTICAL_AXIS));
// 获取向量的标准化向量【向量的模为1】,没啥意义习惯这样做
Vector2 inputDir = input.normalized;

3. ワールドの前面に対する垂直軸と水平軸によって形成される現在のベクトルの間の角度を取得します

float targetRotation = Mathf.Atan2(input.x, input.y) * Mathf.Rad2Deg;

4. プレイヤーが移動したかどうかを判断する [プレイヤーが移動しない場合は、ステアリングを実行しないでください。移動しない場合、デフォルトではワールドの正面を向きます]

        if (inputDir != Vector2.zero)
        {
            // 【上面使用Input.GetAxisRaw,在这里过渡】平滑过渡玩家当前朝向
            transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref currentVelocity, smoothTime);
            // 设置动画
            animator.SetFloat(GameConsts.SPEED_PARAMETER, 1, 0.2f, Time.deltaTime);

            // 【使用变换组件移动】根据动画参数平滑过渡到最大速度
            // transform.Translate(transform.forward * playerSpeed * Time.deltaTime * animator.GetFloat(GameConsts.SPEED_PARAMETER), Space.World);
            // 【使用刚体组件移动】根据动画参数平滑过渡到最大速度
            PlayerRigidbody.MovePosition(transform.position + transform.forward * playerSpeed * Time.deltaTime * animator.GetFloat(GameConsts.SPEED_PARAMETER));
        }
        else
        {
            animator.SetFloat(GameConsts.SPEED_PARAMETER, 0, 0.2f, Time.deltaTime);
        }

2. カメラの設定

1. スクリプト CameraController を追加して、マウスの水平および垂直オフセットを取得および累積/減算します。

// 累加/减存储鼠标的位移量(由于Y轴增加默认尽头下移,所以用-=)
        mouseX += Input.GetAxis(GameConsts.MOUSE_X);
        mouseY -= Input.GetAxis(GameConsts.MOUSE_Y);

2. カメラとマウスの累積変位角度

// 摄像机加上鼠标的累计位移角度
        transform.eulerAngles = new Vector3(mouseY, mouseX, 0);

3. カメラの位置を設定します。距離はカメラと次のターゲットの間の距離です [カメラからキャラクターへのベクトルは、キャラクターの位置からカメラの位置を引いたものであるため、以下のコードは、カメラがプレイヤーの真後ろにあることを意味します。 、距離は距離です]

カメラの高さは、ターゲットを追うようにカメラを調整することで調整できます

// 设置摄像机位置
        transform.position = followTarget.position - transform.forward * distance;

3. プレーヤーの Y 軸の回転をカメラの Y 軸の回転と組み合わせて調整する

1. プレイヤーの回転角度 + カメラの回転角度

float targetRotation = Mathf.Atan2(input.x, input.y) * Mathf.Rad2Deg + followCamera.eulerAngles.y;

4. 完全なコード

PlayerController.cs

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [Header("玩家平滑移动到指定角度的近似时间")]
    public float smoothTime = 0.2f;

    [Header("玩家速度")]
    public float playerSpeed = 5f;

    /// <summary>
    /// 玩家平滑移动到指定角度的瞬时速度,由Mathf.SmoothDampAngle()自动填充值
    /// </summary>
    private float currentVelocity;

    private Animator animator;
    private Rigidbody PlayerRigidbody;

    /// <summary>
    /// 跟随玩家的摄像机
    /// </summary>
    private Transform followCamera;

    private void Awake()
    {
        animator = GetComponent<Animator>();
        PlayerRigidbody = GetComponent<Rigidbody>();
        followCamera = Camera.main.transform;
    }

    private void Update()
    {
        Vector2 input = new Vector2(Input.GetAxisRaw(GameConsts.HORIZONTAL_AXIS), Input.GetAxisRaw(GameConsts.VERTICAL_AXIS));
        Vector2 inputDir = input.normalized;
        float targetRotation = Mathf.Atan2(input.x, input.y) * Mathf.Rad2Deg + followCamera.eulerAngles.y;

        // 如果移动了
        if (inputDir != Vector2.zero)
        {
            // 平滑过渡玩家当前朝向
            transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref currentVelocity, smoothTime);
            // 设置动画
            animator.SetFloat(GameConsts.SPEED_PARAMETER, 1, 0.2f, Time.deltaTime);

            // 【使用变换组件移动】根据动画参数平滑过渡到最大速度
            // transform.Translate(transform.forward * playerSpeed * Time.deltaTime * animator.GetFloat(GameConsts.SPEED_PARAMETER), Space.World);
            // 【使用刚体组件移动】根据动画参数平滑过渡到最大速度
            PlayerRigidbody.MovePosition(transform.position + transform.forward * playerSpeed * Time.deltaTime * animator.GetFloat(GameConsts.SPEED_PARAMETER));
        }
        else
        {
            animator.SetFloat(GameConsts.SPEED_PARAMETER, 0, 0.2f, Time.deltaTime);
        }
    }
}

CameraController.cs

using UnityEngine;

public class CameraController : MonoBehaviour
{
    [Header("摄像机相对玩家的距离")]
    public float distance = 10f;

    private float mouseX;
    private float mouseY;

    /// <summary>
    /// 摄像机跟随目标
    /// </summary>
    private Transform followTarget;

    private void Awake()
    {
        followTarget = GameObject.FindWithTag(GameConsts.PLAYER_TAG).transform.Find(GameConsts.FOLLOW);
    }

    private void Update()
    {
        // 累加/减存储鼠标的位移量(由于Y轴增加默认尽头下移,所以用-=)
        mouseX += Input.GetAxis(GameConsts.MOUSE_X);
        mouseY -= Input.GetAxis(GameConsts.MOUSE_Y);
        // 摄像机加上鼠标的累计位移角度
        transform.eulerAngles = new Vector3(mouseY, mouseX, 0);
        // 设置摄像机位置
        transform.position = followTarget.position - transform.forward * distance;
    }
}

おすすめ

転載: blog.csdn.net/heaventianjianke/article/details/123515004