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;
}
}
댓글
댓글 쓰기