c# - Unity3d:按下鼠标中键围绕屏幕中心旋转相机

标签 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);
    }
}

最佳答案

在您的 orbit 函数中,您确定要环绕的物体,从屏幕中心转换一条射线并环绕碰撞:

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/

相关文章:

c# - debug z-axis-rotation 不为0,而在inspector中为0

unity3d - 统一图形用户界面 : splitting vertical layout group by ratio

c# - Unity3d c# - Vector3 作为默认参数

c# - WPF 文档查看器更新问题

c# - 我有什么选择可以从 .NET 中的代码生成 PDF 报告以获取科学数据 (winforms)

c# - BitmapImage - 图像下载问题

c# - 一个单一的 MonoBehaviour 类有什么好处?

c# - header 命名空间不匹配问题

ios - Unity IOS 应用无法使用 UnityWebRequest 调用自签名证书 HTTPS

c# - 我可以在 Mac 上用 C# 编程吗?