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

Unity沿坐标轴推物体:点击附近区域施力移动物体问题求助

Hey there! Let's break down what's going wrong with your current code and fix it to get that axis-aligned push effect you're after.

First, let's spot the issues in your current code:

  • You're using the target world position directly as the force vector — this is incorrect, because target is a point in space, not a direction relative to the player. So pushing with target * speed will send the player flying off in weird directions, not towards/away from your click.
  • Your distance check is reversed: you're applying force only when the click is farther than 2 units from the player, but you want to push when clicking near the player.
  • You're setting target.z = 0 after the distance check, which means your distance calculation uses a z-value that might not match your 2D scene (since all 2D objects should sit at z=0).
  • You're not normalizing the direction, so the force strength will vary based on how far the click is from the world origin — that leads to inconsistent push feel.

Here's the fixed implementation with axis-aligned push logic:

I'll cover two options: one for strict axis-aligned movement (X or Y only, matching your "沿坐标轴推动" requirement) and one for free 2D direction pushes, in case you want flexibility.

Option 1: Strict Axis-Aligned Push (X/Y Only)

This pushes the player either horizontally or vertically, depending on which axis your click is more aligned with relative to the player:

public float pushForce = 5f; // Renamed from "speed" for clearer intent
public GameObject player;
public float clickThreshold = 2f; // How close clicks need to be to trigger a push

private void Update()
{
    if (Input.GetMouseButtonDown(0))
    {
        // Convert mouse position to 2D world space (lock z to 0)
        Vector3 mouseWorldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
        mouseWorldPos.z = 0f;

        // Calculate distance between player and click point
        float distanceToClick = Vector3.Distance(player.transform.position, mouseWorldPos);

        // Only trigger push if click is within the "near" threshold
        if (distanceToClick <= clickThreshold)
        {
            // Get direction from player to click point
            Vector3 rawDirection = mouseWorldPos - player.transform.position;
            
            // Force axis-aligned movement: pick the dominant axis
            Vector3 axisAlignedDirection;
            if (Mathf.Abs(rawDirection.x) > Mathf.Abs(rawDirection.y))
            {
                // Push along X axis (left/right)
                axisAlignedDirection = new Vector3(Mathf.Sign(rawDirection.x), 0f, 0f);
            }
            else
            {
                // Push along Y axis (up/down)
                axisAlignedDirection = new Vector3(0f, Mathf.Sign(rawDirection.y), 0f);
            }

            // Apply one-time impulse force for a natural "push" feel
            Rigidbody2D playerRb = player.GetComponent<Rigidbody2D>();
            playerRb.AddForce(axisAlignedDirection * pushForce, ForceMode2D.Impulse);
        }
        else
        {
            Debug.Log("Click too far from player — no push applied");
        }
    }
}

Option 2: Free 2D Push (Any Direction)

If you want to push the player directly towards/away from the click point (not restricted to axes), simplify the direction logic:

// Inside the distance check block:
Vector3 direction = (mouseWorldPos - player.transform.position).normalized;
Rigidbody2D playerRb = player.GetComponent<Rigidbody2D>();
playerRb.AddForce(direction * pushForce, ForceMode2D.Impulse);

Key Improvements Explained:

  • Proper Direction Calculation: We use mouseWorldPos - player.transform.position to get a vector pointing from the player to the click, then normalize it to ensure consistent push strength no matter where you click within the threshold.
  • Axis-Aligned Logic: The Mathf.Abs check prioritizes the axis your click is closest to, which matches your requirement of pushing along coordinate axes.
  • ForceMode2D.Impulse: This applies a one-time burst of force, which feels like a natural push instead of continuous acceleration (the default Force mode would require handling in FixedUpdate for smooth results).
  • Correct Threshold Check: We only push when clicks are within your "near" zone, aligning with your goal of interacting with the player's surrounding area.
  • Clean Z-Axis Handling: We lock mouseWorldPos.z to 0 immediately after conversion to avoid 3D space confusion in your 2D scene.

Quick Setup Tips:

  • Ensure your player has a Rigidbody2D component, and adjust its Gravity Scale (set to 0 for floating movement, or positive if you want gravity to affect it).
  • Tweak pushForce and clickThreshold in the Inspector until the feel matches your reference image.
  • If you want to push the player away from the click instead of towards, reverse the direction: direction = player.transform.position - mouseWorldPos.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:18:27