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

Unity3D:如何使空父物体沿相机transform.forward方向移动以实现RTS相机滚轮缩放

Fixing RTS Camera Scroll Wheel (Zoom via Forward Direction)

Got it, let's get that scroll wheel behavior working the way you want! The key issue right now is that you're adjusting the camera's Y position directly, but you need to move the parent object along the camera's own transform.forward axis to simulate that smooth zoom-in/zoom-out effect.

Step-by-Step Fix

First, let's clarify your setup: your camera is a child of a rotation-reset empty object. We'll need to target that parent object for movement instead of the camera itself for the scroll action.

  1. Add a Parent Reference
    Add a public variable to reference the camera's parent object (this makes it explicit and avoids relying on transform.parent which can break if the hierarchy changes):

    public Transform cameraParent; // Assign this in the Inspector to your empty parent object
    
  2. Rewrite Scroll Wheel Logic
    Replace the existing scroll wheel code with logic that moves the parent along the camera's forward direction. We'll also adjust the position clamping to target the parent object instead of the camera.

  3. Adjust Movement & Clamping
    Ensure all position clamping applies to the parent object, since that's now the root of your camera movement.

Modified Full Code

Here's your updated script with key changes marked:

public class CameraController : MonoBehaviour {
    public float panSpeed = 50f;
    public float rotSpeed = 50f;
    public float scrollSpeed = 5f;
    public float dragSpeed = 5f;
    private Vector3 dragOrigin;

    // New: Reference to your camera's parent empty object
    public Transform cameraParent;

    [Header("Position Limits (for Parent Object)")]
    public float minY = 10f;
    public float maxY = 80f;
    public float minX = 10f;
    public float maxX = 80f;
    public float minZ = 10f;
    public float maxZ = 80f;

    void Update() {
        // Use parent object's position instead of camera's
        Vector3 newPos = cameraParent.position;

        if(GameManager.gameIsOver) {
            this.enabled = false;
            return;
        }

        // WASD Movement (keeping your existing logic, but targeting parent)
        if(Input.GetKey(KeyCode.W)) {
            newPos += new Vector3(transform.forward.x,0,transform.forward.z) * panSpeed * Time.unscaledDeltaTime;
        }
        if(Input.GetKey(KeyCode.S)) {
            newPos += new Vector3(-transform.forward.x,0,-transform.forward.z) * panSpeed * Time.unscaledDeltaTime;
        }
        if(Input.GetKey(KeyCode.A)) {
            newPos += -transform.right * panSpeed * Time.unscaledDeltaTime;
        }
        if(Input.GetKey(KeyCode.D)) {
            newPos += transform.right * panSpeed * Time.unscaledDeltaTime;
        }

        // Rotation (rotates the camera itself, which is correct for your setup)
        if(Input.GetKey(KeyCode.Q)) {
            transform.Rotate(Vector3.down * rotSpeed * Time.unscaledDeltaTime, Space.World);
        }
        if(Input.GetKey(KeyCode.E)) {
            transform.Rotate(Vector3.up * rotSpeed * Time.unscaledDeltaTime, Space.World);
        }

        // Scroll Wheel Zoom (updated logic)
        float scroll = Input.GetAxis("Mouse ScrollWheel");
        // Move parent along camera's forward direction: positive scroll = zoom in, negative = zoom out
        newPos += transform.forward * scroll * 1000 * scrollSpeed * Time.unscaledDeltaTime;

        // Clamp parent position to your limits
        newPos.y = Mathf.Clamp(newPos.y, minY, maxY);
        newPos.x = Mathf.Clamp(newPos.x, minX, maxX);
        newPos.z = Mathf.Clamp(newPos.z, minZ, maxZ);

        // Apply position to parent
        cameraParent.position = newPos;
        UpdateDrag();
    }

    void UpdateDrag() {
        if (Input.GetMouseButtonDown(2)) {
            dragOrigin = Input.mousePosition;
        }

        if (Input.GetMouseButton(2)) {
            Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition - dragOrigin);
            Vector3 move = new Vector3(pos.x * dragSpeed, 0, pos.y * dragSpeed);
            // Move parent instead of camera for consistent drag behavior
            cameraParent.Translate(-move, Space.Self);
            dragOrigin = Input.mousePosition;
        }
    }
}

Key Explanations

  • Parent Reference: By targeting the parent object, we leverage your hierarchy setup to keep movement logic clean (since the parent has no rotation, its axes align with world space for easy horizontal movement).
  • Scroll Direction: transform.forward uses the camera's own facing direction (with that 65° X rotation), so moving the parent along this axis will naturally zoom the camera closer to or farther from the area it's looking at.
  • Drag Update: I also updated the drag logic to move the parent instead of the camera, which keeps all movement consistent on the root object.

Quick Setup Tip

Don't forget to drag your empty parent object into the cameraParent field in the Inspector for this to work!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 09:32:41