Unity笔记 Project03 第一人称移动
coconutnut

https://www.youtube.com/watch?v=_QajrabyTJc&ab_channel=Brackeys

层级

  • Player(空物体)-> 加Character Controller;PlayerMovement(Script)
    • Body(圆柱)-> 删除Collider
    • Main Camera -> 放在人物头部的位置;MouseLook(Script)

旋转

x轴横向旋转,转动Player和Camera

y轴纵向旋转,只转动Camera

移动

使用Character Controller的方法

重力

Character Controller不能使用Rigidbody🤪,只能代码解决

还需要通过GroundCheck和Layer来解决碰到地面时下落速度清零的问题

Tips

  • Update()中Time.deltaTime获取从上次调用Update()至今的时间

  • 控制爬楼梯跨度&斜坡角度 -> Character Controller中设置

看教程里的总结,用Character Controller和用RigidBody来控制确实挺不一样的,后面得看看用哪个更合适

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MouseLook : MonoBehaviour
{
public float mouseSensitivity = 100f;

// 在Unity中把Player拖过来
public Transform playerBody = null;

private float xRotation = 0f;

// Start is called before the first frame update
void Start()
{

}

// Update is called once per frame
void Update()
{
// Get Input
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

// 纵向旋转Camera
xRotation -= mouseY;
// 不直接用Rotate,因为要先限制旋转角度
xRotation = Mathf.Clamp(xRotation, -30f, 30f);
transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f);

// 横向旋转Player
playerBody.Rotate(Vector3.up * mouseX);
Debug.Log(mouseX);
Debug.Log("R:"+playerBody.transform.rotation);
Debug.Log("LR:"+playerBody.transform.localRotation);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMovement : MonoBehaviour
{
public CharacterController controller;

public float speed = 12f;
public float gravity = -9.81f;
public float jumpHeight = 3f;

public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;

Vector3 velocity;
bool isGrounded;

// Update is called once per frame
void Update()
{
// 防止向下的速度无限增大
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);

if(isGrounded && velocity.y < 0){
velocity.y = -2f;
}

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

// 这样写是全局坐标,不管Player面对什么方向
// Vector3 move = new Vector3(x, 0f, z);

Vector3 move = transform.right * x + transform.forward * z;
controller.Move(move * speed * Time.deltaTime);

// 跳跃
if(Input.GetButtonDown("Jump") && isGrounded){
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}

// 模拟重力
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}