You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity无物理组件实现连续瓦片跳跃及旋转异常修复求助

问题修复方案

核心问题分析

  1. 连续跳跃高度异常:原代码中CalculateArcHeight错误修改了持久化的targetArcHeight,导致后续跳跃高度基于错误累积值,而非设定的arcHeight。
  2. 旋转X轴卡死:Quaternion.LookRotation会生成包含X轴的旋转,玩家只需要绕Y轴转向,多余的X轴旋转累积引发异常。

修改后的完整代码

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

public class PlayerController : MonoBehaviour
{
    private PlayerControls controls;

    Vector3 _startPosition;
    Vector3 lastPosition;
    Quaternion targetRotation;
    bool jumping = false;
    public AudioSource audioListener;
    public AudioClip JumpSound;
    public float rayLength = 1.4f; // 修正拼写错误:rayLenght → rayLength
    public LayerMask groundLayer;

    float parabola = 0f;
    float _stepScale;
    float _progress;
    public float speed;
    public float arcHeight;
    Vector3 targetDestination;
    private float targetArcHeight; // 仅用于当前跳跃的临时高度

    private bool ableToJump = true;

    private void Awake()
    {
        controls = new PlayerControls();
    }

    private void OnEnable()
    {
        controls.Enable();
    }

    private void OnDisable()
    {
        controls.Disable();
    }

    void Start()
    {
        controls.Main.Movement.performed += ctx => Move(ctx.ReadValue<Vector2>());
        lastPosition = transform.position;
        targetRotation = transform.rotation; // 初始化旋转为当前值,避免初始帧跳变
    }

    private void Move(Vector2 direction)
    {
        if (ableToJump)
        {
            _progress = 0f;
            ableToJump = false;
            _startPosition = transform.position;

            // 修复:直接使用设定的arcHeight作为当前跳跃的相对高度
            targetArcHeight = arcHeight;

            Vector3 movement = new Vector3(direction.x, 0, direction.y);
            // 修复:目标位置基于当前起跳位置,而非lastPosition
            targetDestination = _startPosition + movement;
            lastPosition = targetDestination;
            
            float distance = Vector3.Distance(_startPosition, targetDestination);
            _stepScale = speed / distance;

            audioListener.PlayOneShot(JumpSound);
            
            // 修复旋转:仅保留Y轴转向,X/Z轴旋转清零
            Vector3 lookDir = targetDestination - _startPosition;
            lookDir.y = 0; // 忽略Y轴差异,只计算水平转向
            targetRotation = Quaternion.LookRotation(lookDir);
            jumping = true;
        }
    }

    void Update()
    {
        if (jumping)
        {
            _progress = Mathf.Min(_progress + Time.deltaTime * _stepScale, 1.0f);
            parabola = 1.0f - 4.0f * (_progress - 0.5f) * (_progress - 0.5f);

            Vector3 nextPos = Vector3.Lerp(_startPosition, targetDestination, _progress);
            // 抛物线高度是相对于起跳位置的增量,直接叠加即可
            nextPos.y += parabola * targetArcHeight;

            transform.position = nextPos;

            // 跳跃后期允许再次起跳
            if (_progress >= 0.6f)
            {
                ableToJump = true;
            }

            // 跳跃完全结束后重置状态
            if (_progress >= 1.0f)
            {
                jumping = false;
            }
        }
        // 平滑旋转,仅应用Y轴旋转
        transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, 10f * Time.deltaTime);
    }

    // 移除错误的CalculateArcHeight方法
}

关键修改点说明

  • 跳跃高度修复:删除CalculateArcHeight,每次跳跃直接将targetArcHeight设为arcHeight,确保所有跳跃的相对高度都是设定值;同时修正目标位置计算逻辑,基于当前起跳位置而非lastPosition,避免连续跳跃偏移。
  • 旋转问题修复:计算转向方向时忽略Y轴差异,生成的旋转仅包含Y轴角度,确保玩家只会水平转向,不会出现X轴旋转异常。
  • 细节优化:修正变量拼写错误,初始化旋转值避免初始帧跳变,增加跳跃结束后的状态重置逻辑。

内容的提问来源于stack exchange,提问作者Димитър Димитров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:53:13