【问题标题】:Unity3d: rotate camera around center of the screen with middle mouse button pressedUnity3d:按下鼠标中键围绕屏幕中心旋转相机
【发布时间】:2019-05-29 02:29:18
【问题描述】:

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

我尝试了统一 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);
    }
}

【问题讨论】:

  • 尝试将光线从屏幕中心投射到世界表面,并使用该位置环绕。
  • 谢谢,你有机会为此提供一个代码 sn-p 吗?

标签: c# unity3d


【解决方案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; 并在检查器中将其设置为仅与您的地面所在的任何层发生碰撞。

【讨论】:

  • 你能说得更具体些吗?抱歉,我对此很陌生。一个更完整的解决方案会很棒。
  • @AndyBre 我编辑了我的答案以显示答案如何与MouseOrbitImproved
  • 谢谢@Ruzihm。我在您建议的解决方案中看不到鼠标按钮按下事件。知道如何仅在按下中间按钮时激活相机旋转吗?
  • @AndyBre 我编辑了这个问题以更清楚地说明这一点,并在我的回答中包含了一些内容。
  • 经过测试。都在工作。很好的答案!非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 2013-08-04
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 2014-08-05
相关资源
最近更新 更多