20240112-【UNITY 学习】实现第一人称移动教程

1、创建一个空物体,挂载Rigidbody组件,并设置相应参数

在这里插入图片描述

2、在上述空物体下创建一个胶囊体,两个空物体,一个用来控制朝向,另一个用来控制摄像机

在这里插入图片描述

3、给摄像机创建一个父物体,并挂载脚本MoveCamera_01.cs

在这里插入图片描述

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

public class MoveCamera_01 : MonoBehaviour
{
   
    public Transform cameraPosition;
    private void Update()
    {
   
        transform.position = cameraPosition.position;
    }
}

4、给摄像机挂载脚本PlayerCam_01.cs

在这里插入图片描述

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

public class PlayerCam_01 : MonoBehaviour
{
   
    // 视觉灵敏度参数
    public float sensX = 400;
    public float sensY = 400;

    // 视角垂直旋转角度限制
    public float minAngle = -90f;
    public float maxAngle = 90f;

    // 角色朝向的 Transform,用于水平旋转
    public Transform orientation;

    // 当前的 X 和 Y 旋转角度
    private float xRotation;
    private float yRotation;

    private void Start()
    {
   
        // 初始时锁定鼠标光标并隐藏光标
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }

    private void Update()
    {
   
        // 获取鼠标输入
        float mouseX = Input.GetAxisRaw("Mouse X") * Time.deltaTime * sensX;
        float mouseY = Input.GetAxisRaw("Mouse Y") * Time.deltaTime * sensY;

        // 更新水平旋转角度
        yRotation += mouseX;

        // 更新垂直旋转角度,并限制在指定范围内
        xRotation -= mouseY;
        xRotation = Mathf.Clamp(xRotation, minAngle, maxAngle);

        // 应用旋转到摄像机的 Transform 上,实现视角旋转
        transform.rotation = Quaternion.Euler(xRotation, yRotation, 0);

        // 应用水平旋转到角色的 Transform 上,使角色朝向与摄像机一致
        orientation.rotation = Quaternion.Euler(0, yRotation, 0);
    }
}

5、给主角挂载脚本PlayerMovement_01.cs

在这里插入图片描述

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

public class PlayerMovement_01 : MonoBehaviour
{
   
    public float moveSpeed = 7; // 玩家移动速度

    public float groundDrag = 5; // 地面时的阻力

    public float playerHeight = 2; // 玩家身高
    public LayerMask whatIsGround; // 地面的LayerMask
    private bool grounded; // 是否在地面上

    public float jumpForce = 6; // 跳跃力度
    public float jumpCooldown = 0.25f; // 跳跃冷却时间
    public float airMultiplier = 0.4f; // 空中移动速度衰减
    private bool readyToJump = true; // 是否可以跳跃

    public KeyCode jumpKey = KeyCode.Space; // 跳跃键

    public Transform orientation; // 玩家朝向的Transform

    private float h; // 水平输入
    private float v; // 垂直输入

    private Vector3 moveDirection; // 移动方向

    private Rigidbody rb; // 玩家刚体

    private void Start()
    {
   
        rb = GetComponent<Rigidbody>();
        rb.freezeRotation = true; // 防止刚体旋转
    }

    private void Update()
    {
   
        grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);

        MyInput();

        SpeedControl();

        if (grounded)
            rb.drag = groundDrag;
        else
            rb.drag = 0;
    }

    private void FixedUpdate()
    {
   
        MovePlayer();
    }

    private void MyInput()
    {
   
        h = Input.GetAxisRaw("Horizontal");
        v = Input.GetAxisRaw("Vertical");

        if (Input.GetKey(jumpKey) && readyToJump && grounded)
        {
   
            readyToJump = false;

            Jump();

            Invoke(nameof(ResetJump), jumpCooldown);
        }
    }

    private void MovePlayer()
    {
   
        // 根据朝向计算移动方向
        moveDirection = orientation.forward * v + orientation.right * h;

        if (grounded)
        {
   
            rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);
        }
        else if (!grounded)
        {
   
            rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier, ForceMode.Force);
        }
    }

    private void SpeedControl()
    {
   
        Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);

        if (flatVel.magnitude > moveSpeed)
        {
   
            // 限制速度在设定范围内
            Vector3 limitedVel = flatVel.normalized * moveSpeed;

            rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
        }
    }

    private void Jump()
    {
   
        //rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
        rb.velocity = Vector3.zero;

        // 添加向上的力以实现跳跃
        rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
    }

    private void ResetJump()
    {
   
        readyToJump = true;
    }
}

相关推荐

  1. Unity】控制人物左右移动和跑步的实现

    2024-01-13 08:32:02       10 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-13 08:32:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-13 08:32:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-13 08:32:02       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-13 08:32:02       20 阅读

热门阅读

  1. C# 各数据类型 范围

    2024-01-13 08:32:02       39 阅读
  2. 【RabbitMQ】4 Spring/SpringBoot整合RabbitMQ

    2024-01-13 08:32:02       33 阅读
  3. vuex-class,vue-class-component和vue-property-decorator

    2024-01-13 08:32:02       30 阅读
  4. git撤销命令大全

    2024-01-13 08:32:02       34 阅读
  5. Linux消息队列

    2024-01-13 08:32:02       33 阅读
  6. 基于kafka_exporter&prometheus&grafana的kafka监控实现

    2024-01-13 08:32:02       32 阅读
  7. 【机器学习】机器学习上机作业聚类算法

    2024-01-13 08:32:02       38 阅读
  8. 鸿蒙HarmonyOS-HTTP网络数据请求

    2024-01-13 08:32:02       41 阅读
  9. Hexo 环境搭建

    2024-01-13 08:32:02       40 阅读