防止 Camera 在 Unity 中低于 Player

Prevent Camera from going below Player in Unity

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

我不想要这个并且想要在它的 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);
    }

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

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

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

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

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

希望对您有所帮助!

我也创建了一个 3rd person camera,我通过从玩家到相机拍摄 RayCast 解决了这个问题。如果 RayCast 击中某物,它会将相机置于击中位置。

在我的脚本中,我首先旋转 摄像机,然后“推” 摄像机远离玩家。 RayCast 告诉我可以将相机推多远。

  1. You get user input and rotate the camera according to the input data. (At this point the camera is at the target position, eg.: player.)
  1. You shoot a RayCast from the target position towards the camera. If it hits something and it is in a range you specified, then you set the camera position to the RayCast hitpoint.

我 post 我的代码在这里,所以你可以想象我在说什么。

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 is equals to your target's position, however, I use some offset (height), so I calculate the final target position here.

maxDistance represents a floating point number that you set. It limits how far the camera can get from the target.

We shoot the RayCast into direction and see if it collides. If it does, we modify finalDistance to the distance of the hit (hit.distance). And I want to make sure, that the camera never collides with anything, so I push it a little towards the target (by 0.1).

I clamp the finalDistance to keep it in the desired range. Then, I place the camera in the target position (target.position + target.up * height) and push it away (-transform.forward * finalDistance).

下面是它的工作过程(你可能想手动设置 0.1,因为它可能像这里一样有小问题。你可以尽可能多地试验它以找到完美的值。):

我给你一个 link 脚本,如果你需要它作为参考或使用。