当前位置: 首页 > article >正文

[Unity角色控制专题] 详细解释如何使用Character Controller配合脚本实现跳跃功能与落地抖动?

        本文无门槛,并且代码十分简单

        有需要的小伙伴可可以查看上一个文章的基本控制 来自行考虑如何实现跳跃功能:[Unity角色控制专题] 详细说明如何使用Character Controller配合脚本实现类似MC的第一人称控制(仅移动与视角摇晃)-CSDN博客

         来看实现效果: 

1.跳跃模拟

        加了角色控制器就不要用刚体了 会产生冲突 如果做物理模拟可以写另外一个脚本 下次再说

因此就需要额外的参数:

    [Header("跳跃力度")]
    public float jumpForce = 4.0f;
    private float verticalVelocity; //垂直高度
    [Header("重力系数")]
    public float gravity = 9.81f;

 额外的代码,写在Move函数里 最后会有所有代码的总结

      //跳跃逻辑
      if (Controller.isGrounded) {
          verticalVelocity = -gravity * Time.deltaTime; // 微小重力保证贴地
          if (Input.GetKeyDown(KeyCode.Space)) {
           
              isJumping = true; // 开始跳跃
              verticalVelocity = jumpForce;
          }
      }
      else {
          verticalVelocity -= gravity * Time.deltaTime;
      }
   Controller.Move(moveDirection + Vector3.up * verticalVelocity * Time.deltaTime);

        具体做了什么 一张图就能解释:

         至于为什么gravity要写成9.81其实这个无所谓 我是贴近现实才使用这个数字

        官方第三人称项目示例是写成2的(其向上的位移很大),只要能保证功能实现就可以了

2.落地抖动

        关键在于一个状态的控制 落地的瞬间检测到两个bool都是ture的话 就让摄像机向下位移一小点,然后lerp回原位就好了


    [Header("跳跃落地抖动强度")]
    public float landingSharkFrequency = 0.2f;
    private bool isJumping; 


  if (Controller.isGrounded && isJumping) {
      JumpShark();
      isJumping = false; // 结束跳跃
  }

   private void JumpShark() {
       HeadCamera.transform.localPosition = originalCameraPos + new Vector3(0f, -landingSharkFrequency, 0f);
    
   }

3.总结

        落地高度不同 摄像机抖动强度可以不同,因此可以根据跳跃力度大小来让相机抖动强度做出改变 这里我就不再赘述了 我并没有实现这个功能 因为暂时不需要

        

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.InputSystem.XR;
using static UnityEditor.Searcher.SearcherWindow.Alignment;

public class CCLearn : MonoBehaviour {

    private Camera HeadCamera;
    private CharacterController Controller;

    #region 玩家视角
    public Vector2 xY;
    [Header("鼠标灵敏度")]
    public float mouseSensitivity = 1.0f;
    [Header("上下视角钳制角度")]
    public Vector2 VirticalPersective = new Vector2(-90, 90);

    private float currentVerticalAngle;

    #endregion

    #region 玩家移动
    private Vector2 xZ;
    Vector3 moveDirection;
    [Header("移动速度")]
    public float moveSpeed = 3.0f;
    [Header("跑步速度")]
    public float runSpeed = 6.0f;
    [Header("移动噪音值")]
    public float noicse = 1.0f;
    #endregion


    #region 玩家跳跃
    [Header("跳跃力度")]
    public float jumpForce = 4.0f;
    private float verticalVelocity; //垂直高度
    [Header("重力系数")]
    public float gravity = 9.81f;
    [Header("跳跃落地噪音值")]
    public float jumpNoicse = 3.0f;
    [Header("跳跃落地抖动强度")]
    public float landingSharkFrequency = 0.2f;
    private bool isJumping; 
    #endregion


    #region 摄像机摇晃
    private Vector3 originalCameraPos;
    [Header("移动摇晃强度")]
    public float shakeIntensity = 0.05f;
    [Header("移动机摇晃频率")]
    public float shakeFrequency = 10f;
    #endregion

    // Start is called once before the first execution of Update after the MonoBehaviour is created
    void Start() {
        Controller = GetComponent<CharacterController>();
        HeadCamera = transform.Find("Head").GetComponentInChildren<Camera>();

        HideMouse();
        originalCameraPos = HeadCamera.transform.localPosition; // 初始化相机的原始位置
    }
    private void HideMouse() {
        // 锁定鼠标光标并隐藏
        Cursor.lockState = CursorLockMode.Locked;
        Cursor.visible = false;
    }
    // Update is called once per frame
    void Update() {
        PersPactive();
        Move();
        CameraShake();
    }

    private void PersPactive() {
        xY = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")) * mouseSensitivity;

        currentVerticalAngle -= xY.y;
        currentVerticalAngle = Mathf.Clamp(currentVerticalAngle, VirticalPersective.x, VirticalPersective.y);

        //相机上下视角
        HeadCamera.transform.localRotation = Quaternion.Euler(currentVerticalAngle, 0f, 0f);
        //角色旋转
        this.transform.Rotate(Vector3.up * xY.x);
    }
    private void Move() {
        xZ = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"));

        moveDirection = (transform.forward * xZ.y + transform.right * xZ.x).normalized * moveSpeed * Time.deltaTime;
        //加速
        if (Input.GetKey(KeyCode.LeftShift)) {
            moveDirection = (transform.forward * xZ.y + transform.right * xZ.x).normalized * runSpeed * Time.deltaTime;
        }
        //跳跃逻辑
        if (Controller.isGrounded) {
            verticalVelocity = -gravity * Time.deltaTime; // 微小重力保证贴地
            if (Input.GetKeyDown(KeyCode.Space)) {
             
                isJumping = true; // 开始跳跃
                verticalVelocity = jumpForce;
            }
        }
        else {
            verticalVelocity -= gravity * Time.deltaTime;
        }

        Controller.Move(moveDirection + Vector3.up * verticalVelocity * Time.deltaTime);

        if (Controller.isGrounded && isJumping) {
            JumpShark();
            isJumping = false; // 结束跳跃
        }
    }

    private void CameraShake() {
        if (xZ.magnitude != 0) {
            float shakeOffsetX = Mathf.Sin(Time.time * shakeFrequency) * shakeIntensity;
            float shakeOffsetY = Mathf.Cos(Time.time * shakeFrequency * 2f) * shakeIntensity * 0.5f;
            HeadCamera.transform.localPosition = originalCameraPos + new Vector3(shakeOffsetX, shakeOffsetY, 0f);
        }
        else {
            HeadCamera.transform.localPosition = Vector3.Lerp(HeadCamera.transform.localPosition, originalCameraPos, Time.deltaTime * 10f);
        }
    }
    private void JumpShark() {
        HeadCamera.transform.localPosition = originalCameraPos + new Vector3(0f, -landingSharkFrequency, 0f);
     
    }
}

        


http://www.kler.cn/a/540423.html

相关文章:

  • ffmpeg -formats
  • ASP.NET Core JWT
  • 01单片机上电后没有正常运行怎么办
  • 基于Java的远程视频会议系统(源码+系统+论文)
  • 消息队列MQ
  • Android双屏异显Presentation接口使用说明
  • docker的卷映射如何手动指定位置
  • 信创领域的PostgreSQL管理员认证
  • 2.10学习总结
  • Qt中QTreeWidget的使用
  • 查出 product 表中所有 detail 字段包含 xxx 的完整记录
  • Linux常用命令——磁盘管理类
  • RTD2775QT/RTD2795QT瑞昱显示器芯片方案
  • Python 项目中创建虚拟环境(Virtual Environment)
  • JAVA 学习路线 学习大纲(java 进阶路线)
  • 利用子问题思路解决二叉树相关Oj题
  • 基于蜘蛛蜂优化算法的无人机集群三维路径规划Matlab实现
  • 力扣 单词拆分
  • 【网络安全.渗透测试】Cobalt strike(CS)工具使用说明
  • 测试某操作系统通过dd和UltraISO两种方式安装服务器(ARM)
  • 利用二分法进行 SQL 时间盲注
  • 科研工作中如何高效利用LabVIEW
  • C#语言的云计算
  • shell脚本控制——使用新的shell启动脚本
  • DFS+回溯+剪枝(深度优先搜索)——搜索算法
  • 保姆级教程Docker部署Zookeeper模式的Kafka镜像