【问题标题】:How Can I Stop My Camera From Rotating?如何阻止我的相机旋转?
【发布时间】:2018-01-23 02:18:03
【问题描述】:

我制作了我的 3d Agario 游戏的前身。这是一款以鼠标为导向的游戏。您使用鼠标来控制大部分移动。这包括相机的旋转。

我的问题是相机不会停止旋转。这是因为很难将鼠标置于屏幕中心,而我让相机旋转的方式是使用正弦方程。

这是我的代码:

//public
public GameObject player;
public float rotationSpeed;

//v3
private Vector3 mousePos;
private Vector3 playerPos;
private Vector3 camPos;

//float
private float sideX;
private float sideZ;
private float sideC;
private float camX;
private float camZ;
private float camC;
private float rotX;
private float rotZ;
private float rotC;
private float rotAngle;
private Quaternion currRotation;

//camera
private Camera hitCam;

void Start ()
{
    transform.rotation = Quaternion.Euler(30, 0, 0);
    transform.position = new Vector3(0, 15, 0);
}
void LateUpdate ()
{
    mousePos = HitCameraController.mousePos;
    playerPos = player.transform.position;

    sideX = (mousePos.x - playerPos.x);
    sideZ = (mousePos.z - playerPos.z);
    sideC = (Mathf.Sqrt(Mathf.Pow(sideX, 2) + Mathf.Pow(sideZ, 2)));

    camC = 15;
    camX = (camC * sideX) / sideC;
    camZ = (camC * sideZ) / sideC;

    rotX = (sideX + camX);
    rotZ = (sideZ + camZ);
    rotC = (Mathf.Sqrt(Mathf.Pow(rotX, 2) + Mathf.Pow(rotZ, 2)));

    if (rotX >= 0 && rotZ >= 0)
    {
        rotAngle = (Mathf.Asin(rotX / rotC) * Mathf.Rad2Deg);
    }
    if (rotX >= 0 && rotZ <= 0)
    {
        rotAngle = 180 - (Mathf.Asin(rotX / rotC) * Mathf.Rad2Deg);
    }
    if (rotX <= 0 && rotZ >= 0)
    {
        rotAngle = (Mathf.Asin(rotX / rotC) * Mathf.Rad2Deg);
    }
    if (rotX <= 0 && rotZ <= 0)
    {
        rotAngle = -180 - (Mathf.Asin(rotX / rotC) * Mathf.Rad2Deg);
    }
    camPos = new Vector3((playerPos.x - camX), 15, (playerPos.z - camZ));
    currRotation = Quaternion.Euler(30, rotAngle, 0);

    // Move Camera
    transform.position = camPos;

    // Rotate Camera

    /*transform.rotation = Quaternion.RotateTowards(
        transform.rotation, currRotation, 
        (rotationSpeed * Time.deltaTime));*/

    transform.rotation = currRotation;
}

我想创建一种“安全区”来阻止计算旋转角度。例如,如果我将鼠标保持在中心的某个边界内,相机将不会旋转。

我尝试使用“或”语句创建边界,但它没有给我想要的结果(即使我的鼠标在边界上,相机仍会旋转。相机会停在某个位置尝试,但在这样做之前它会非常抖动。)

我确切地知道为什么会发生这种情况:光线没有投射到静止的相机上;因此,即使我不移动鼠标,鼠标坐标也会始终改变。我尝试将光线投射到“Hit”相机(静止相机),但跟随相机无法捕捉到鼠标移动。我不知道如何解决这个问题,除了不断集思广益寻找一个直观的解决方案,但我的大脑只能创新这么多。

如果你能在我之前想到一个解决方案,请以任何方式告诉我。

【问题讨论】:

    标签: c# unity3d rotation raycasting mouse-position


    【解决方案1】:
    [...]
    void LateUpdate ()
    {
        mousePos = HitCameraController.mousePos;
        playerPos = player.transform.position;
    
        sideX = (mousePos.x - playerPos.x);
        sideZ = (mousePos.z - playerPos.z);
    
        sideC = (Mathf.Sqrt(Mathf.Pow(sideX, 2) + Mathf.Pow(sideZ, 2)));
    
        // New Stuff
        sideC -= 5f; // substract the safe-zone-radius
        if(sideC < 0f)
        {
            // Inside safe-zone, do nothing.
            sideC = 0f;
            sideX = 0f;
            sideZ = 0f;
        }else{
            // Outside safe-zone, correct values to avoid jumping.
            float x_ratio = sideX / sideZ; // be careful with "divide by zero"
            float z_ratio = sideZ / sideX;
            sideX -= 5 * x_ratio;
            sideZ -= 5 * z_ratio;
        }
        // End New Stuff
    
        camC = 15;
        camX = (camC * sideX) / sideC;
        camZ = (camC * sideZ) / sideC;
    
        rotX = (sideX + camX);
        rotZ = (sideZ + camZ);
        rotC = (Mathf.Sqrt(Mathf.Pow(rotX, 2) + Mathf.Pow(rotZ, 2)));
    
        if (rotX >= 0 && rotZ >= 0)
        {
            rotAngle = (Mathf.Asin(rotX / rotC) * Mathf.Rad2Deg);
        }
        if (rotX >= 0 && rotZ <= 0)
        {
            rotAngle = 180 - (Mathf.Asin(rotX / rotC) * Mathf.Rad2Deg);
        }
        if (rotX <= 0 && rotZ >= 0)
        {
            rotAngle = (Mathf.Asin(rotX / rotC) * Mathf.Rad2Deg);
        }
        if (rotX <= 0 && rotZ <= 0)
        {
            rotAngle = -180 - (Mathf.Asin(rotX / rotC) * Mathf.Rad2Deg);
        }
    
        camPos = new Vector3((playerPos.x - camX), 15, (playerPos.z - camZ));
        currRotation = Quaternion.Euler(30, rotAngle, 0);
    

    【讨论】:

    • 玩家是中心,但问题是sideC永远不会小于0,因为它是一个sqrt。我希望安全区在两个方向上距离相机中心 5 个单位。
    • 当然,我错过了 sqrt。那么你甚至不需要if-else。只需减去 5(也许您需要减去 5² ?)并检查它是否为&gt; 0。进行旋转计算时一定要减去相同的值,以免离开安全区时的跳动
    • 你能改写答案吗?
    • 我改了答案
    • 我让你知道我退出了这个游戏的进一步进展并开始制作一个新游戏。 :/ 这个游戏太复杂了,无法合理化。
    猜你喜欢
    • 2018-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 1970-01-01
    • 2021-06-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多