Today I will share with you a simple scripting method for the player controller and camera controller in the third-person perspective of Unity.
The effect is as follows:
1. Implementation principle
It is mainly implemented in three parts: character rotation, character movement, and camera rotation.
1. Character movement:
First get the parameters of the character's horizontal and vertical movement:
inputH = Input.GetAxis("Horizontal");//获取水平/垂直移动参数
inputV = Input.GetAxis("Vertical");
Because the character moves in the same direction as the camera, it is necessary to determine the player's movement direction according to the direction axis of the camera, and then move the player character rigid body component:
moveDir = mCamera.TransformDirection(inputH, 0, inputV);//人物移动朝向
rigid.MovePosition(transform.position + new Vector3(moveDir.x,0,moveDir.z) * wSpeed * Time.fixedDeltaTime);//移动人物
2. Camera rotation:
First get the mouse horizontal/vertical movement parameters, then make the camera follow the character and update the rotation:
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. Character rotation:
First, the rotation angle is calculated by the parameters of the horizontal/vertical movement:
float targetRotation = (Mathf.Atan2(inputH, inputV) * Mathf.Rad2Deg + mCamera.eulerAngles.y
Note here that the rotation of the character should be based on the direction of the current camera. If it is only based on the direction of the character model, the movement of the character will be inconsistent with the direction of the rotation of the character. As shown in the figure below, the character moves backwards and the camera moves forward:
After obtaining the angle, use the Mathf.SmoothDampAngle() function to rotate the character more smoothly:
transform.eulerAngles = Vector3.up * Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref currentVelocity, smoothTime, rSpeed, Time.deltaTime);
2. Object level
The object hierarchy is as follows:
The player component is mounted on the character prefab, and components such as RigidBody and Collider are created. Create another empty object with the same coordinates as the player character, use MainCamera as a child object, and adjust the camera position.
3. Complete code
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);
}//控制相机上下旋转角度
}
Welcome everyone to exchange and learn in the comment area~