Unity3d:在按住鼠标中键的同时围绕屏幕中心旋转相机

时间:2019-05-28 17:34:50

标签: c# unity3d

我正在研究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);
    }
}

1 个答案:

答案 0 :(得分:1)

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

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;并在检查器中将其设置为仅与您所在的地面相撞。