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
targetworld position directly as the force vector — this is incorrect, becausetargetis a point in space, not a direction relative to the player. So pushing withtarget * speedwill 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 = 0after 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.positionto 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.Abscheck 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
Forcemode would require handling inFixedUpdatefor 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.zto 0 immediately after conversion to avoid 3D space confusion in your 2D scene.
Quick Setup Tips:
- Ensure your player has a
Rigidbody2Dcomponent, and adjust its Gravity Scale (set to 0 for floating movement, or positive if you want gravity to affect it). - Tweak
pushForceandclickThresholdin 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
相关产品推荐
相关产品推荐

