Unity 三人称プレイヤー コントローラー + カメラ コントローラー

今日は、Unity の三人称視点でのプレーヤー コントローラーとカメラ コントローラーの簡単なスクリプト作成方法を共有します。

 

効果は次のとおりです。

1. 実施原則

主に、キャラクターの回転、キャラクターの移動、カメラの回転の 3 つの部分で実装されます。

1.キャラクターの動き:

まず、キャラクターの水平方向と垂直方向の動きのパラメーターを取得します。

inputH = Input.GetAxis("Horizontal");//获取水平/垂直移动参数
inputV = Input.GetAxis("Vertical");

キャラクターはカメラと同じ方向に移動するため、カメラの方向軸に従ってプレーヤーの移動方向を決定し、プレーヤー キャラクターの剛体コンポーネントを移動する必要があります。

moveDir = mCamera.TransformDirection(inputH, 0, inputV);//人物移动朝向
rigid.MovePosition(transform.position + new Vector3(moveDir.x,0,moveDir.z) * wSpeed * Time.fixedDeltaTime);//移动人物

 2. カメラの回転:

まずマウスの水平/垂直移動パラメータを取得し、次にカメラをキャラクターに追従させ、回転を更新します。

mouseX += Input.GetAxis("Mouse X") * xSpeed * Time.deltaTime;//更新鼠标水平/垂直移动参数
mouseY += Input.GetAxis("Mouse Y") * ySpeed * Time.deltaTime;
transform.position = body.position;//相机跟随人物移动
transform.rotation = Quaternion.Euler(mouseY, mouseX, 0);//相机旋转

3. キャラクターの回転:

まず、回転角度が水平/垂直移動のパラメータによって計算されます。

float targetRotation = (Mathf.Atan2(inputH, inputV) * Mathf.Rad2Deg + mCamera.eulerAngles.y

ここで注意したいのは、キャラクターの回転は現在のカメラの方向に基づいている必要があり、キャラクターモデルの方向のみに基づいていると、キャラクターの動きとキャラクターの回転方向が一致しなくなります。次の図に示すように、キャラクターは後方に移動し、カメラは前方に移動します。

角度を取得した後、Mathf.SmoothDampAngle() 関数を使用してキャラクターをよりスムーズに回転させます。

transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref currentVelocity, smoothTime, rSpeed, Time.deltaTime);

2. オブジェクトレベル

オブジェクトの階層は次のとおりです。

 

キャラクタープレハブにプレイヤーコンポーネントを実装し、RigidBodyやColliderなどのコンポーネントを作成します。プレイヤーキャラクターと同じ座標の空のオブジェクトをもう一つ作成し、MainCameraを子オブジェクトとして使用し、カメラの位置を調整します。

3. 完全なコード

PlayerController.cs

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

public class PlayerController : MonoBehaviour
{
    private Rigidbody rigid;//玩家刚体
    private Animator animator;//玩家动画机
    public Transform mCamera;//相机组件

    private Vector3 moveDir;//人物移动方向
    private float currentVelocity = 1;//目前的转向速度(SmoothDampAngle函数的返还参数)
    private float smoothTime = 0.1f;//完成平滑的时间(SmoothDampAngle函数的参数)
    public float wSpeed;//移动速度
    public float rSpeed;//旋转速度
    public float jPower;//跳跃力度
    private float inputH;//水平移动参数
    private float inputV;//垂直移动参数
    private bool isMove;//是否移动
    private bool isRun;//是否奔跑
    private bool isGround;//是否在地面上

    void Start()
    {
        rigid = GetComponent<Rigidbody>();
        animator = GetComponent<Animator>();
    }

    void Update()
    {
    }

    private void FixedUpdate()
    {
        inputH = Input.GetAxis("Horizontal");//获取水平/垂直移动参数
        inputV = Input.GetAxis("Vertical");
        animator.SetFloat("inputH", inputH);//更新动画机参数
        animator.SetFloat("inputV", Mathf.Abs(inputV));
        animator.SetBool("isMove", isMove);
        animator.SetBool("isRun", isRun);
        if(Input.GetKeyDown(KeyCode.Space))
        {
            isGround = false;
            animator.CrossFade("Jump", 0.1f);
            rigid.AddForce(0, jPower, 0);//给刚体向上的力
        }//更新跳跃动画
        if (inputH != 0 || inputV != 0)
        {
            isMove = true;
            transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, (Mathf.Atan2(inputH, inputV) * Mathf.Rad2Deg + mCamera.eulerAngles.y), ref currentVelocity, smoothTime, rSpeed, Time.deltaTime);
        }//改变人物朝向
        else
        {
            isMove = false;
        }//更新移动状态
        if (Input.GetKey(KeyCode.LeftShift))
        {
            wSpeed = 6;
            isRun = true;
        }//更新奔跑状态
        else
        {
            wSpeed = 3;
            isRun = false;
        }
        moveDir = mCamera.TransformDirection(inputH, 0, inputV);
        rigid.MovePosition(transform.position + new Vector3(moveDir.x,0,moveDir.z) * wSpeed * Time.fixedDeltaTime);//移动人物
    }

    private void OnCollisionEnter(Collision collision)
    {
        if(!isGround)
        {
            if(collision.gameObject.CompareTag("Ground"))
            {
                isGround = true;
            }
        }//判断是否接地
    }
}

カメラコントローラー.cs

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

public class CameraController : MonoBehaviour
{
    public Transform body;//玩家人物组件

    public float maxY = 40;//相机旋转上界限
    public float minY = -10;//相机旋转下界限
    public float xSpeed = 250;//相机纵向旋转速度
    public float ySpeed = 125;//相机横向旋转速度
    private float mouseX;//鼠标水平移动参数
    private float mouseY;//鼠标垂直移动参数

    void Start()
    {
        
    }

    void Update()
    {
        mouseX += Input.GetAxis("Mouse X") * xSpeed * Time.deltaTime;//更新鼠标水平/垂直移动参数
        mouseY += Input.GetAxis("Mouse Y") * ySpeed * Time.deltaTime;
        mouseY = clampAngle(mouseY);
        transform.position = body.position;//相机跟随人物移动
        transform.rotation = Quaternion.Euler(mouseY, mouseX, 0);//相机旋转
    }

    private float clampAngle(float angle)
    {
        if (angle < -360)
        {
            angle += 360;
        }
        if (angle > 360)
        {
            angle -= 360;
        }
        return Mathf.Clamp(angle, minY, maxY);
    }//控制相机上下旋转角度
}

コメントエリアで交流して学びましょう〜

おすすめ

転載: blog.csdn.net/weixin_64080879/article/details/128687557