在Unity中实现《幽灵行者》风格的跑酷动作

打印 上一主题 下一主题

主题 1878|帖子 1878|积分 5634

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
基础设置


  • 角色控制器选择

    • 使用Character Controller组件或Rigidbody + Capsule Collider
    • 推荐使用Character Controller以获得更精确的运动控制

  • 输入系统

    • 使用Unity的新输入系统(Input System Package)处理玩家输入

滑铲实现

  1. public class SlideController : MonoBehaviour
  2. {
  3.     [Header("Slide Settings")]
  4.     public float slideSpeed = 10f;
  5.     public float slideDuration = 1f;
  6.     public float slideCooldown = 0.5f;
  7.     public float slideHeight = 0.5f;
  8.     public float normalHeight = 2f;
  9.    
  10.     private CharacterController controller;
  11.     private bool isSliding = false;
  12.     private float slideTimer;
  13.     private float cooldownTimer;
  14.     void Start()
  15.     {
  16.         controller = GetComponent<CharacterController>();
  17.     }
  18.     void Update()
  19.     {
  20.         HandleSlide();
  21.     }
  22.     void HandleSlide()
  23.     {
  24.         if (cooldownTimer > 0)
  25.         {
  26.             cooldownTimer -= Time.deltaTime;
  27.             return;
  28.         }
  29.         if (Input.GetKeyDown(KeyCode.LeftControl) && !isSliding)
  30.         {
  31.             StartSlide();
  32.         }
  33.         if (isSliding)
  34.         {
  35.             slideTimer -= Time.deltaTime;
  36.             if (slideTimer <= 0)
  37.             {
  38.                 EndSlide();
  39.             }
  40.             
  41.             // 保持滑铲速度
  42.             Vector3 moveDirection = transform.forward * slideSpeed;
  43.             controller.Move(moveDirection * Time.deltaTime);
  44.         }
  45.     }
  46.     void StartSlide()
  47.     {
  48.         isSliding = true;
  49.         slideTimer = slideDuration;
  50.         controller.height = slideHeight;
  51.         controller.center = new Vector3(0, slideHeight * 0.5f, 0);
  52.     }
  53.     void EndSlide()
  54.     {
  55.         isSliding = false;
  56.         cooldownTimer = slideCooldown;
  57.         controller.height = normalHeight;
  58.         controller.center = new Vector3(0, normalHeight * 0.5f, 0);
  59.     }
  60. }
复制代码
贴墙跑实现

  1. public class WallRunController : MonoBehaviour
  2. {
  3.     [Header("Wall Run Settings")]
  4.     public float wallRunSpeed = 8f;
  5.     public float wallRunGravity = 2f;
  6.     public float wallRunDuration = 2f;
  7.     public float wallJumpForce = 10f;
  8.     public LayerMask wallRunLayer;
  9.    
  10.     private CharacterController controller;
  11.     private bool isWallRunning = false;
  12.     private Vector3 wallNormal;
  13.     private float wallRunTimer;
  14.     void Start()
  15.     {
  16.         controller = GetComponent<CharacterController>();
  17.     }
  18.     void Update()
  19.     {
  20.         CheckWallRun();
  21.         HandleWallRun();
  22.     }
  23.     void CheckWallRun()
  24.     {
  25.         if (isWallRunning) return;
  26.         
  27.         RaycastHit hit;
  28.         if (Physics.Raycast(transform.position, transform.right, out hit, 1f, wallRunLayer))
  29.         {
  30.             StartWallRun(hit.normal, false);
  31.         }
  32.         else if (Physics.Raycast(transform.position, -transform.right, out hit, 1f, wallRunLayer))
  33.         {
  34.             StartWallRun(hit.normal, true);
  35.         }
  36.     }
  37.     void StartWallRun(Vector3 normal, bool isLeftWall)
  38.     {
  39.         isWallRunning = true;
  40.         wallNormal = normal;
  41.         wallRunTimer = wallRunDuration;
  42.         
  43.         // 调整角色朝向与墙面平行
  44.         Vector3 cross = Vector3.Cross(normal, Vector3.up);
  45.         transform.rotation = Quaternion.LookRotation(cross, normal);
  46.     }
  47.     void HandleWallRun()
  48.     {
  49.         if (!isWallRunning) return;
  50.         
  51.         wallRunTimer -= Time.deltaTime;
  52.         
  53.         // 沿墙面移动
  54.         Vector3 moveDirection = transform.forward * wallRunSpeed;
  55.         
  56.         // 应用自定义重力
  57.         moveDirection.y -= wallRunGravity * Time.deltaTime;
  58.         
  59.         controller.Move(moveDirection * Time.deltaTime);
  60.         
  61.         // 检查是否应该结束贴墙跑
  62.         if (wallRunTimer <= 0 || !Physics.Raycast(transform.position, wallNormal, 1f, wallRunLayer))
  63.         {
  64.             EndWallRun();
  65.         }
  66.         
  67.         // 墙跳
  68.         if (Input.GetButtonDown("Jump"))
  69.         {
  70.             WallJump();
  71.         }
  72.     }
  73.     void WallJump()
  74.     {
  75.         Vector3 jumpDirection = (wallNormal + Vector3.up).normalized;
  76.         // 应用跳跃力...
  77.         EndWallRun();
  78.     }
  79.     void EndWallRun()
  80.     {
  81.         isWallRunning = false;
  82.     }
  83. }
复制代码
高级本事


  • 动画混合

    • 使用Animator Controller混合差异动作的动画
    • 设置得当的过渡条件和混合树

  • 运动曲线

    • 使用AnimationCurve调解动作的速度变化,使过渡更自然

  • 相机结果

    • 在特殊动作时添加相机震动、视野变化等结果
    • 使用Cinemachine实现平滑的相机跟随

  • 物理材质

    • 为差异表面设置差异的物理材质,影响摩擦力和弹跳结果

  • 粒子结果

    • 在滑铲时添加灰尘粒子
    • 在贴墙跑时添加墙面火花结果

优化建议


  • 状态机模式

    • 实现一个完整的状态机管理系统,管理跑酷的各种状态
    • 例如:站立、奔跑、滑铲、贴墙跑、跳跃等状态

  • 输入缓冲

    • 实现输入缓冲系统,使动作衔接更流畅

  • 物理预测

    • 使用射线检测预测即将到来的动作时机(如火线可滑铲地域或可贴墙跑的表面)


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

老婆出轨

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表