在当前位置摇动相机 Unity3D

Shake camera on current position Unity3D

我制作了脚本,其中相机跟随播放器和相机抖动器以获得效果。但问题是相机在其默认 (0, 0, 0) 位置开始晃动。它跳到那个位置开始摇晃并 returns 播放器。我怎样才能让相机在它的当前位置抖动。这是我的代码:

public Transform target;
public float smoothTime = 0.3F;
private Vector3 velocity = Vector3.zero;

private const float _COROUTINE_FREQUENCY = 0.05f;
private Camera _mainCamera;
private Vector3 _initCamPos;
private bool _shaking;

void Start()
{
    _mainCamera = Camera.main;
}

void Update()
{
    // Define a target position above and behind the target transform
    Vector3 targetPosition = target.TransformPoint(new Vector3(0, 0, -10));
     
    // Smoothly move the camera towards that target position
    transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime);
    if (Bullet.hit && !_shaking){
        StartCoroutine(_ShakingCamera());
    }
}

public void Shake(){
    StartCoroutine(_ShakingCamera());
}

public IEnumerator _ShakingCamera(float magnitude = 0.2f)
{
    _shaking = true;

    _initCamPos = _mainCamera.transform.position;
    float t = 0f, x, y;
    while (t < 0.3f)
    {
        x = Random.Range(-0.35f, 0.35f) * magnitude;
        y = Random.Range(-0.35f, 0.35f) * magnitude;

        _mainCamera.transform.position = new Vector3(x, y, _initCamPos.z);

        t += _COROUTINE_FREQUENCY;
        yield return new WaitForSeconds(_COROUTINE_FREQUENCY);
    }

    _mainCamera.transform.position = _initCamPos;
    _shaking = false;
}

基本原理应该是这样的“Camera Target Position + Shake-Offset

public Transform target;
public float smoothTime = 0.3F;
private Vector3 velocity = Vector3.zero;

private const float _COROUTINE_FREQUENCY = 0.05f;
private Camera _mainCamera;
private Vector3 _initCamPos;
private bool _shaking;
private Vector3 shakeOffset = Vector3.zero; // the offset variable

void Start()
{
    _mainCamera = Camera.main;
}

void Update()
{
    // Define a target position above and behind the target transform
    Vector3 targetPosition = target.TransformPoint(new Vector3(0, 0, -10));
 
    // Smoothly move the camera towards that target position
    transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, smoothTime);
    if (Bullet.hit && !_shaking){
        StartCoroutine(_ShakingCamera());
    }

    _mainCamera.position = targetPosition + shakeOffset; // set camera position here, shakeOffset is 0,0,0 when not shaking. 
}

public void Shake(){
    StartCoroutine(_ShakingCamera());
}

    public IEnumerator _ShakingCamera(float magnitude = 0.2f)
    {
    _shaking = true;
    
    _initCamPos = _mainCamera.transform.position;
    float t = 0f, x, y;
    while (t < 0.3f)
    {
        x = Random.Range(-0.35f, 0.35f) * magnitude;
        y = Random.Range(-0.35f, 0.35f) * magnitude;

        shakeOffset = new Vector3(x,y, _initCamPos.z); // define shakeOffset here
    
        // _mainCamera.transform.position = new Vector3(x, y, _initCamPos.z); not required here, see Update()
        
        t += _COROUTINE_FREQUENCY;
        yield return new WaitForSeconds(_COROUTINE_FREQUENCY);
    }

    // reset offset:
    shakeOffset = Vector3.zero;

    // _mainCamera.transform.position = // not required here, see Update() 
_shaking = false;
}

然后,每当你想移动相机(WASD、鼠标、操纵杆...)时,你只需修改 targetPosition,然后让你疯狂地使用 shakeOffset,因为你可以随时将其 Lerp 回到 0,0,0。因此,您可以独立于抖动移动相机。

注意:像我在这里那样设置位置会“破坏”SmoothDamp 效果。你需要决定是否也应该抑制抖动,或者你是否想要平滑地移动相机并立即添加抖动(如果感觉更强烈)。我也没有测试这段代码,但希望你明白了要点并理解了原理。

简单求解,初始位置必须添加到摇动的位置,所以把这部分:

_mainCamera.transform.position = _initCamPos + new Vector3(x, y);

而不是:

_mainCamera.transform.position = new Vector3(x, y, _initCamPos.z);