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

Unity2D平台游戏角色贴墙粘滞问题求助:如何解决该移动异常?

Fixing Wall-Sticking in Your 2D Platformer

Hey there! That wall-sticking issue is super common when starting out with 2D platformers—let's break down what's causing it and how to fix it, covering both your code and Unity settings.

First, Why Is This Happening?

Your current code directly sets the Rigidbody2D's velocity to a fixed value when holding movement keys. When your character presses against a wall, Unity's physics engine tries to push the character away to resolve the collision, but your code immediately overrides the velocity right back. This constant "tug-of-war" between the physics engine and your input logic creates that sticky feeling. On top of that, your collision-based jump logic triggers on all collisions (including walls), which adds unexpected behavior too.

Step 1: Fix Your Movement Code

Let's rewrite the movement to work with Unity's physics instead of fighting against it. Here's how to adjust your PlayerController script:

1. Update Movement Logic (Stop Directly Setting Velocity)

Instead of hard-setting velocity to ±moveSpeed, use smooth acceleration and let the physics engine handle collisions naturally. Replace your HorMoveKeyDown method with this:

private void HorMoveKeyDown() {
    // Get raw input for snappier keyboard controls
    float moveInput = Input.GetKey("d") ? 1f : Input.GetKey("a") ? -1f : 0f;
    
    // Calculate target velocity and smooth transition to it
    float targetVelocityX = moveInput * moveSpeed;
    float smoothVelocityX = Mathf.MoveTowards(myRigBody.velocity.x, targetVelocityX, 10f * Time.deltaTime);
    
    myRigBody.velocity = new Vector2(smoothVelocityX, myRigBody.velocity.y);
}

This way, if the physics engine modifies the X velocity (like when hitting a wall), your code will gradually adjust instead of forcing it back instantly.

2. Fix Jump Collision Logic

Your current OnCollisionEnter2D and OnCollisionExit2D reset jumps on any collision (including walls), which is not what you want. Instead, use a ground check to detect when you're actually on the ground:

  1. Add a small empty GameObject as a child of your player, placed just below their feet (name it GroundCheck).
  2. Update your script with these changes:
// Add these serialized fields at the top
[SerializeField] private Transform groundCheck;
[SerializeField] private LayerMask groundLayer;
private bool isGrounded;

void Update() {
    // Check if the ground check overlaps with the ground layer
    isGrounded = Physics2D.OverlapCircle(groundCheck.position, 0.1f, groundLayer);
    
    // Reset jumps only when grounded
    if (isGrounded) {
        jumpsAvailable = maxJumps;
    }

    // Update joystick movement to use smooth velocity too
    if (usingJoystick) {
        moveInput = Input.GetAxis("Horizontal");
        float targetVelocityX = moveInput * moveSpeed;
        float smoothVelocityX = Mathf.MoveTowards(myRigBody.velocity.x, targetVelocityX, 10f * Time.deltaTime);
        myRigBody.velocity = new Vector2(smoothVelocityX, myRigBody.velocity.y);
    } else {
        HorMoveKeyDown();
        JumpKeyDown();
    }
    HorDrag();
}

// Remove the old OnCollisionEnter2D and OnCollisionExit2D methods entirely

Make sure to set the groundLayer in the Inspector to the layer you're using for ground objects (don't include walls here!).

3. Tweak Horizontal Drag

Your HorDrag method can stay, but using Mathf.MoveTowards makes it smoother and more consistent:

private void HorDrag() {
    if (!(Input.GetKey("a") || Input.GetKey("d"))) {
        myRigBody.velocity = new Vector2(Mathf.MoveTowards(myRigBody.velocity.x, 0f, xDrag * Time.deltaTime), myRigBody.velocity.y);
    }
}

Step 2: Adjust Unity Editor Settings

Even with fixed code, physics materials can cause sticking. Let's fix that:

  • Add Physics Material 2D: Create a new Physics Material 2D (right-click in Project window → Physics 2D → Physics Material 2D). Set its Friction to 0 and Bounciness to 0. Assign this material to both your player's Collider2D and your wall Collider2Ds to eliminate friction-based sticking.
  • Rigidbody2D Settings: Select your player's Rigidbody2D:
    • Set Collision Detection to Continuous (prevents collision glitches at higher speeds).
    • Check Freeze Rotation Z (so your player doesn't spin when hitting walls).
    • Ensure Gravity Scale is set to a reasonable value (like 3 or 4—too high can cause weird collision behavior).

Final Notes

Test these changes step by step—start with the code fixes, then adjust the physics materials if you still see sticking. Platformer movement is all about balancing smooth input with natural physics, so don't hesitate to tweak the acceleration or drag values until it feels right for your game!

内容的提问来源于stack exchange,提问作者ShapesGameDev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 14:07:36