【问题标题】:Prevent Camera from going below Player in Unity在 Unity 中防止相机低于玩家
【发布时间】:2021-08-24 22:04:40
【问题描述】:

我有一个脚本,玩家可以用鼠标控制相机。问题是玩家可以使用鼠标将其移动到下方,如下所示:

我不想要这个,我想在 Y 位置低于玩家 Y 位置时停止相机。

这是我的相机代码:



using System.Collections;
using UnityEngine;

public class CameraController : MonoBehaviour
{
    private Vector3 offset;

    public Transform player;

    public float camPosX;
    public float camPosY;
    public float camPosZ;

    public float camRotationX;
    public float camRotationY;
    public float camRotationZ;

    public float turnSpeed;

    private void Start()
    {
        offset = new Vector3(player.position.x + camPosX, player.position.y + camPosY, player.position.z + camPosZ);
        transform.rotation = Quaternion.Euler(camRotationX, camRotationY, camRotationZ);
    }

    private void Update()
    {
        offset = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * turnSpeed, Vector3.up) * Quaternion.AngleAxis(Input.GetAxis("Mouse Y") * turnSpeed, Vector3.right) * offset;
            transform.position = player.position + offset;
        transform.LookAt(player.position);
    }
}

我已尝试通过检查相机 Y 位置是否小于玩家 Y 位置来解决此问题,如果是这样,我不会更新相机位置。

这是我用于此的代码:

    private void Update()
    {
        
        offset = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * turnSpeed, Vector3.up) * Quaternion.AngleAxis(Input.GetAxis("Mouse Y") * turnSpeed, Vector3.right) * offset;
        if (!((player.position + offset).y < player.position.y))
        {
            transform.position = player.position + offset;
        }
        transform.LookAt(player);
    }

这解决了主要问题,但有时会导致整个摄像机移动出现故障......就像有时它完全停止移动并且只是看着玩家而不是跟随它。像这样

我不知道如何解决这个问题,感谢任何帮助

【问题讨论】:

    标签: unity3d camera


    【解决方案1】:

    我认为您的问题不是更新相机位置而是将其设置为玩家的高度。

    我认为您可以将相机 Y 值与玩家的值进行比较,如果相机的值小于玩家的值,则将它们设置为相等。

    if(camPos.y < player.position.y)
    {
        Vector3 newPosition = new Vector3(transform.position.x, player.position.y, transform.position.z);
        transform.position = newPosition;
    }    
    

    希望对你有帮助!

    【讨论】:

    • 我认为如果您唯一想要的是防止相机低于某个水平,它可能会起作用。我发现这是一个很好的解决方案。但是,就我而言,这是语法错误。您无法单独修改 transform.position 值。您需要创建一个 Vector3,然后将其应用于 transform.position。但这个想法对我来说似乎是正确的。
    【解决方案2】:

    我还创建了一个第三人称相机,我通过将 RayCast 从播放器拍摄到相机来解决了这个问题。如果 RayCast 击中某物,它会将相机放置到击中位置。

    在我的脚本中,我首先旋转相机,然后将其“推”远离播放器。 RayCast 告诉我可以将相机推多远。

    1. 您获取用户输入并根据输入数据旋转相机。 (此时相机位于目标位置,例如:玩家。)
    1. 您从目标位置向摄像机拍摄 RayCast。如果它击中某物并且在您指定的范围内,则将相机位置设置为 RayCast 命中点。

    我在这里发布我的代码,这样你就可以看到我在说什么。

    private Quaternion rotation = Quaternion.identity;  //Creates a quaternion with only zeros (x=0, y=0, z=0, w=0)
    private float speedX;
    private float speedY;
    
    public void GetInput()
    {
        speedX = Input.GetAxis("Horizontal");
        speedY = Input.GetAxis("Vertical");
    }
    
    private void NormalRotation()
    {
        //Set rotation values
        rotation.x += speedX * horizontalSpeed * Time.deltaTime;
        rotation.y += speedY * verticalSpeed * Time.deltaTime;
        rotation.y = Mathf.Clamp(rotation.y, -50, 90);
    
        //Apply rotation
        transform.rotation = Quaternion.Euler(rotation.y, rotation.x, rotation.z);
    }
    

    变量rotation 是一个预定义的Quaternion,用于存储我的输入值。 我们只需要管理我们的 X 和 Y 坐标,因为我们只在这些轴上移动。

    我夹住 Y,这样相机就不会从玩家下方太多,也不会越过它。

    然后,我应用旋转。 (请记住,您可能需要根据输入处理更改轴的顺序。我可能更改了两个输入,因为我的 X 和 Y 已切换。

    这里是距离计算:

    private void CalculateFinalPosition()
    {
        //Setup temporary variables
        RaycastHit hit;
        Vector3 targetPosition = target.position + target.up * height;
        Vector3 direction = (transform.position - targetPosition).normalized;
        finalDistance = maxDistance;
    
        //Check collision
        if (Physics.Raycast(targetPosition, direction, out hit, Mathf.Infinity)) { finalDistance = hit.distance - 0.1f; }
    
        //Apply position
        finalDistance = Mathf.Clamp(finalDistance, minDistance, maxDistance);
        transform.position = (target.position + target.up * height) - transform.forward * finalDistance;
    }
    

    现在,这可能需要一些解释。

    targetPosition 等于你的目标位置,但是,我使用了一些偏移量(高度),所以我在这里计算最终的目标位置。

    maxDistance 表示您设置的浮点数。它限制了相机距离目标的距离。

    我们将 RayCast 射入direction 并查看它是否发生碰撞。如果是这样,我们将finalDistance 修改为命中的距离(hit.distance)。而且我想确保相机永远不会与任何东西发生碰撞,所以我将它稍微推向目标(0.1)。

    我将finalDistance 固定在所需范围内。然后,我将相机放在目标位置 (target.position + target.up * height) 并将其推开 (-transform.forward * finalDistance)。

    这是它的工作过程(您可能需要手动设置 0.1,因为它可能像这里一样有点错误。您可以根据需要进行试验以找到完美的值。):@987654321 @

    如果您需要它以供参考或使用,我会给您一个 link 脚本。

    【讨论】:

    • 谢谢。我认为@zoidberg 的回答可能对我目前没有边的测试地图有好处,但我确实计划让我的地图更复杂,并且使用 Raycast 将帮助相机不会进入墙壁。
    • 另外,我如何使用输入值创建Quaternion.. 对不起初学者问题,团结和 c# 的第二天...
    • 这几乎没什么,你只是创建一个变量。但我会编辑我的答案,所以会很清楚!
    • 好吧,无论如何我让它工作了,但我不得不对你的代码做一些改变。如果未来有人在读这个,这里是对我有用的代码:pastebin.com/hrpwr3N3
    • 我已经在答案中添加了链接,但我会把它放在这里。这是我原来的相机控制器脚本。尝试使用这个。请阅读自述文件,以便您可以正确使用它。主要部分是这样做:在您的一个脚本(您想要获取输入的位置)中调用 SetValue(float x, float y) 方法。这样您就可以控制相机。 github.com/B3N11/standalone-modules/tree/main/Around%20Camera
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2020-07-26
    • 1970-01-01
    相关资源
    最近更新 更多