Menu
CoddyTech

카메라 흔들림

Coddy Unity 여정의 물리와 게임플레이 섹션에 포함된 레슨. 71개 중 50번째.

흔들림은 무작위 오프셋이 짧게 이어지는 동작입니다. 몇 분의 1초 동안 카메라는 원래 위치 근처의 무작위 지점에 머뭅니다. 매 프레임마다 새로운 지점으로 이동한 다음 원래 위치로 돌아갑니다. 코루틴은 여러 프레임에 걸쳐 실행되고 저절로 끝나므로 적합합니다. 이 카메라는 바위가 떨어질 때 흔들립니다(다른 스크립트에서 BoulderLanded()를 호출하며, IEnumerator를 사용하기 위해 파일은 using System.Collections;로 시작합니다).

public float strength = 0.2f;
public float duration = 0.4f;
Vector3 rest;

void Start()
{
    rest = transform.localPosition;
}

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

IEnumerator Shake()
{
    float elapsed = 0f;
    while (elapsed < duration)
    {
        transform.localPosition = rest + Random.insideUnitSphere * strength;
        elapsed += Time.deltaTime;
        yield return null;
    }
    transform.localPosition = rest;
}

Random.insideUnitSphere * strength는 어느 방향으로든 최대 strength 길이만큼의 무작위 오프셋이며, yield return null은 다음 프레임에 새 오프셋을 선택합니다. 매 반복마다 Time.deltaTime을 더하면 실제 초 단위로 시간이 계산되므로, 어떤 프레임 속도에서도 흔들림은 duration 동안 지속됩니다. 마지막 줄은 카메라를 원래 위치로 되돌립니다. 이 줄이 없으면 카메라는 마지막 오프셋이 남긴 위치에 그대로 머뭅니다.

매 프레임마다 Unity는 모든 Update()를 실행한 다음, yield return null에서 대기 중인 코루틴을 실행하고, 그다음 모든 LateUpdate()를 실행합니다. 따라서 LateUpdate()에서 위치를 설정하는 추적 카메라는 흔들림으로 변경된 위치를 덮어씁니다. 카메라가 추적을 담당하는 빈 오브젝트의 자식이라면 localPosition을 흔들어 이 문제를 피할 수 있습니다. 부모 오브젝트는 움직이고, 카메라는 그 아래에서 제자리 주변으로 흔들립니다.

challenge icon

챌린지

중급

Space 키를 누르면 다음 카메라가 흔들리도록 하세요.

  1. Vector3 shake; 필드를 추가하고, LateUpdate()에서 transform.position = player.position + offset + shake;를 설정하세요.
  2. Shake()에서 elapsed < duration인 동안 shake = Random.insideUnitSphere * strength;를 실행하고, Time.deltaTime을 elapsed에 더한 다음 yield return null;을 실행하세요.
  3. 반복문이 끝난 후 shake = Vector3.zero;로 설정하세요.

‘플레이’를 누르고, 실행한 다음 Space 키를 누르세요. 카메라가 따라오면서 화면이 흔들립니다. 그런 다음 ‘확인’을 누르세요.

직접 해보기

using System.Collections;
using UnityEngine;

public class ShakeFollow : MonoBehaviour
{
    public Transform player;
    public Vector3 offset = new Vector3(0, 4, -8);
    public float strength = 0.3f;
    public float duration = 0.4f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            StartCoroutine(Shake());
        }
    }

    void LateUpdate()
    {
        transform.position = player.position + offset;
    }

    IEnumerator Shake()
    {
        // 카메라를 duration초 동안 따라가는 위치에서 최대 strength만큼 흔듭니다.
        yield return null;
    }
}

물리와 게임플레이의 모든 레슨

직접 연습해 보세요: Unity 플레이그라운드