Controlador de jugador en tercera persona Unity + controlador de cámara

Hoy compartiré con ustedes un método de secuencias de comandos simple para el controlador del reproductor y el controlador de la cámara en la perspectiva de tercera persona de Unity.

 

El efecto es el siguiente:

1. Principio de implementación

Se implementa principalmente en tres partes: rotación de personajes, movimiento de personajes y rotación de cámara.

1. Movimiento de personajes:

Primero obtenga los parámetros del movimiento horizontal y vertical del personaje:

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

Debido a que el personaje se mueve en la misma dirección que la cámara, es necesario determinar la dirección del movimiento del jugador de acuerdo con el eje de dirección de la cámara y luego mover el componente de cuerpo rígido del personaje del jugador:

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

 2. Rotación de la cámara:

Primero obtenga los parámetros de movimiento horizontal/vertical del mouse, luego haga que la cámara siga al personaje y actualice la rotación:

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. Rotación de personajes:

Primero, el ángulo de rotación se calcula mediante los parámetros del movimiento horizontal/vertical:

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

Tenga en cuenta aquí que la rotación del personaje debe basarse en la dirección de la cámara actual. Si solo se basa en la dirección del modelo de personaje, el movimiento del personaje será inconsistente con la dirección de rotación del personaje. Como se muestra en la siguiente figura, el personaje retrocede y la cámara avanza:

Después de obtener el ángulo, use la función Mathf.SmoothDampAngle() para rotar el carácter más suavemente:

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

2. Nivel de objeto

La jerarquía de objetos es la siguiente:

 

El componente del jugador se monta en el prefabricado del personaje y se crean componentes como RigidBody y Collider. Cree otro objeto vacío con las mismas coordenadas que el personaje del jugador, use MainCamera como un objeto secundario y ajuste la posición de la cámara.

3. Código completo

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;
            }
        }//判断是否接地
    }
}

CameraController.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);
    }//控制相机上下旋转角度
}

Bienvenidos a todos a intercambiar y aprender en el área de comentarios ~

Supongo que te gusta

Origin blog.csdn.net/weixin_64080879/article/details/128687557
Recomendado
Clasificación