我正在开发一款RTS游戏,并且希望像在任何RTS策略游戏中一样,在按下鼠标按钮时支持摄像机围绕屏幕的当前中心旋转。

我尝试了unity Wiki(在下面复制)上显示的MouseOrbitImproved脚本,但是它需要相机使用的目标对象来旋转。我的问题是我的目标始终是屏幕的当前中心。

任何想法如何做到这一点,但仅在按下鼠标中键时?

using UnityEngine;
using System.Collections;

[AddComponentMenu("Camera-Control/Mouse Orbit with zoom")]
public class MouseOrbitImproved : MonoBehaviour {

    public Transform target;
    public float distance = 5.0f;
    public float xSpeed = 120.0f;
    public float ySpeed = 120.0f;

    public float yMinLimit = -20f;
    public float yMaxLimit = 80f;

    public float distanceMin = .5f;
    public float distanceMax = 15f;

    private Rigidbody rigidbody;

    float x = 0.0f;
    float y = 0.0f;

    // Use this for initialization
    void Start ()
    {
        Vector3 angles = transform.eulerAngles;
        x = angles.y;
        y = angles.x;

        rigidbody = GetComponent<Rigidbody>();

        // Make the rigid body not change rotation
        if (rigidbody != null)
        {
            rigidbody.freezeRotation = true;
        }
    }

    void LateUpdate ()
    {
        if (target)
        {
            x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
            y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;

            y = ClampAngle(y, yMinLimit, yMaxLimit);

            Quaternion rotation = Quaternion.Euler(y, x, 0);

            distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel")*5, distanceMin, distanceMax);

            RaycastHit hit;
            if (Physics.Linecast (target.position, transform.position, out hit))
            {
                distance -=  hit.distance;
            }
            Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
            Vector3 position = rotation * negDistance + target.position;

            transform.rotation = rotation;
            transform.position = position;
        }
    }

    public static float ClampAngle(float angle, float min, float max)
    {
        if (angle < -360F)
            angle += 360F;
        if (angle > 360F)
            angle -= 360F;
        return Mathf.Clamp(angle, min, max);
    }
}

最佳答案

在确定您要绕行的物体的轨道功能中,从屏幕中心发出光线,并在碰撞周围进行绕行:

public LayerMask groundLayerMask; // mask to choose orbitable layers

...

Ray screenRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2f, Screen.height/2f, 0f));`

RaycastHit hitInfo;
Physics.Raycast(screenRay, out hitInfo, Mathf.Infinity, groundLayerMask.value);

Vector3 orbitPosition = hitInfo.point;


您可以使用Input.GetMouseButton(2)检查是否按下了鼠标中键。绕行之前,请对其进行检查,并且只有在其按下时才能检测到鼠标输入的变化。

MouseOrbitImproved代码中,在LateUpdate方法中可能看起来像这样:

void LateUpdate ()
{
    // Skip mouse input here if middle mouse button is not pressed
    if (Input.GetMouseButton(2))
    {
        x += Input.GetAxis("Mouse X") * xSpeed * distance * 0.02f;
        y -= Input.GetAxis("Mouse Y") * ySpeed * 0.02f;
        y = ClampAngle(y, yMinLimit, yMaxLimit);
    }

    Quaternion rotation = Quaternion.Euler(y, x, 0);

    distance = Mathf.Clamp(distance - Input.GetAxis("Mouse ScrollWheel")*5, distanceMin, distanceMax);

    Ray screenRay = Camera.main.ScreenPointToRay(new Vector3(Screen.width/2f, Screen.height/2f, 0f));`

    RaycastHit hitInfo;
    Physics.Raycast(screenRay, out hitInfo, Mathf.Infinity, groundLayerMask.value);

    Vector3 orbitPosition = hitInfo.point;

    Vector3 negDistance = new Vector3(0.0f, 0.0f, -distance);
    Vector3 position = rotation * negDistance + orbitPosition ;

    transform.rotation = rotation;
    transform.position = position;
}


在类字段中,除去public Transform target;并添加public LayerMask groundLayerMask;并将其在检查器中设置为仅与您的地面相撞。

关于c# - Unity3d:按下鼠标中键围绕屏幕中心旋转相机,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56347447/

10-13 06:53