简体   繁体   English

Unity3d-相机旋转平滑“错误”

[英]Unity3d - Camera rotation smoothing 'bug'

I made a simple racing game. 我做了一个简单的赛车游戏。 The camera follows the car (player) and its position and rotation is based on car's Y rotation. 摄像机跟随汽车(玩家)行驶,其位置和旋转基于汽车的Y旋转。 I want to smooth the camera rotation, but when it crosses 0 degree point, it rotates 360 degrees. 我想使相机旋转平稳,但是当它越过0度点时,它会旋转360度。 Here's the code: 这是代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Camera : MonoBehaviour {
    public Transform camera, player;


    void Update() {
        Vector3 cameraPosition = camera.transform.position;
        float cameraRotation = camera.eulerAngles.y;
        float playerRotation = player.eulerAngles.y;
        Vector3 playerPosition = player.transform.position;
        cameraPosition.x = (Mathf.Sin((playerRotation / 180) * Mathf.PI) * -6 + player.position.x);
        cameraPosition.y = playerPosition.y + 2.5f;
        cameraPosition.z = (Mathf.Cos((playerRotation / 180) * Mathf.PI) * -6 + player.position.z);
        camera.transform.position = cameraPosition;
        cameraRotation = cameraRotation + (playerRotation-cameraRotation)/2;
        camera.localRotation = Quaternion.Euler(20f, cameraRotation, 0f);
    }
}

I figured out that this rotation is caused by smoothing script: 我发现这种旋转是由平滑脚本引起的:

 cameraRotation = cameraRotation + (playerRotation-cameraRotation)/2;

How to prevent this unwanted rotation? 如何防止这种不必要的旋转?

This is how I would do it: 这就是我要做的:

public int smoothSpeed = 1f; // Change accordingly to increase/decrease smooth speed.

Then in update: 然后在更新中:

Vector3 directionToCar = player.position - camera.position;
Quaternion desiredRotation = Quaternion.LookRotation(directionToCar);
camera.rotation = Quaternion.Slerp(camera.rotation, desiredRotation, Time.deltaTime * smoothSpeed);

On a side node, if this camera script is attached to the camera, you don't have to make a field referencing the camera's transform. 在侧面节点上,如果此摄像机脚本已附加到摄像机,则不必创建一个引用摄像机变换的字段。 You can simply do transform.position instead of camera.transform.position . 您可以简单地执行transform.position而不是camera.transform.position

A simpler solution to using the Slerp is to use Mathf.SmoothDamp, which has a variant called Mathf.SmoothDampAngle which handles the looping correctly. 使用Slerp的一个更简单的解决方案是使用Mathf.SmoothDamp,它具有一个名为Mathf.SmoothDampAngle的变体,可以正确处理循环。 I've also had success doing the wraparound by hand but its not a very rewarding experience 我也成功完成了手工环绕操作,但这并不是非常有意义的体验

using UnityEngine;
public class RotFollow : MonoBehaviour
{
    [SerializeField] Transform carTransform;
    [SerializeField] float smoothTime = .4f; 

    float currentYAngle;
    float targetYAngle;
    float angleVel;
    void Update()
    {
        targetYAngle = carTransform.rotation.eulerAngles.y;
        currentYAngle =  Mathf.SmoothDampAngle(currentYAngle, targetYAngle, ref angleVel, smoothTime);
        transform.rotation = Quaternion.Euler(
                                        transform.rotation.eulerAngles.x,
                                        currentYAngle, 
                                        transform.rotation.eulerAngles.z);
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM