Unity 2D에서 카메라 흔들기 구현하기(Camera Shaking)
카메라 흔들기 효과는,
- 타격감 구현 ( FPS를 예로 들면 총의 반동 표현)
- 지진, 폭발 등 특수효과를 더 실감나게
에 사용됩니다.
카메라 흔들기 스크립트의 개요는 다음과 같습니다.
- 게임오브젝트의 초기 position, rotation 저장하기
- position을 랜덤으로 받아서 게임오브젝트의 position에 저장하기
- rotation을 랜덤으로 받아서 게임오브젝트의 rotation에 저장하기
- 진동을 마친 후 초기 rotation, position으로 복귀
위 개요에서 2, 3번 과정을 한번 실행이 아닌, 원하는 시간만큼 진동을 지속해야 하므로
반복문을 사용합니다. 반복문의 조건은 한 변수에 현재 프레임의 시간을 더해주며(deltaTime), 원하는 시간만큼 실행되었는지 판단하는 것 입니다.
불규칙한 위치를 적용하기 위해서
Random.insideUnitCircle 을 사용하였습니다.
이 get함수는 x, y 좌표계에서 반지름이 1 인 원 안의 지점을 반환합니다.
현재 Unity 2D를 사용하고 있으므로 위 처럼 하였고, 만약 3D환경에서 개발하려고 한다면
Random.insideUnitSphere를 사용하면 되겠습니다.
불규칙한 회전을 적용하기 위해서
Mathf.PerlinNoise(Time.time * offset)을 사용하였습니다.
펄린노이즈 함수는 일정부분 연속된 난수를 반환합니다. 그 특성으로 구름이나 나무 등 랜덤하지만 규칙성 있어야 하는 난수에 적용합니다. seed 값을 Time으로 둔 경우 입니다.
응용 예시
이 코드는 전역변수에 public Transform shakeCamera 하였습니다.
이 스크립트를 진동효과를 구현하고싶은 오브젝트에 첨부한 후 shakeCamera에 그 오브젝트를 첨부하면 되겠습니다. 카메라 전체를 흔들고싶다면 카메라를, 상자를 흔들고 싶다면 상자 오브젝트에 첨부하면 됩니다.
소스코드 :
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ShakeCamera : MonoBehaviour { // 진동할 카메라의 transform public Transform shakeCamera; // 회전시킬 것인지를 판단할 변수 public bool shakeRotate = false; // 초기 좌표와 회전값을 저장할 변수 public Vector3 originPos; public Quaternion originRot; // Use this for initialization void Start () { // 초깃값 저장 originPos = shakeCamera.localPosition; originRot = shakeCamera.localRotation; } public IEnumerator Shake(float duration = 0.05f, float magnitudePos = 0.03f, float magnitudeRot = 0.1f) { // 지나간 시간을 누적할 변수 float passTime = 0.0f; // 진동시간동안 루프 돌림 while(passTime < duration) { // 불규칙한 위치를 산출 Vector3 shakePos = Random.insideUnitCircle ; // 카메라의 위치를 변경 shakePos.z = originPos.z / magnitudePos; shakeCamera.localPosition = shakePos * magnitudePos; // 불규칙한 회전을 사용할 경우 if (shakeRotate) { // 펄린노이즈함수로 불규칙한 회전값 생성 Vector3 shakeRot = new Vector3(0,0, Mathf.PerlinNoise(Time.time * magnitudeRot, 0.0f)); // 카메라 회전값 변경 shakeCamera.localRotation = Quaternion.Euler(shakeRot); } // 진동시간 누적 passTime += Time.deltaTime; yield return null; } // 진동 후 원상복구 shakeCamera.localPosition = originPos; shakeCamera.localRotation = originRot; } }
댓글
댓글 쓰기