[Unity] 클래스 상속을 이용한 CameraShake 구현(Random, Sine, Animation)

728x90

클래스 상속을 이용한 CameraShake 구현 방법

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


// 카메라 셰이크를 위한 설정 정보를 기억할 구조체
[System.Serializable]
public struct CameraShakeInfo
{
    // 진폭
    public float amplitude;
    // 사인파 진동 빠르기
    public float sinSpeed;
}

// 모든 카메라 셰이크 클래스의 부모 클래스
public class CameraShakeBase
{
    // 카메라 초기 위치 기억변수
    protected Vector3 originPos;

    // 카메라 셰이크 초기화 함수
    public virtual void Init(Vector3 originPos)
    {
        this.originPos = originPos;
    }

    // 카메라 셰이크 재생 함수
    // transform : 카메라의 트랜스폼
    // info : 사용자가 정의한 카메라셰이크 설정 정보
    public virtual void Play(Transform transform, CameraShakeInfo info)
    {

    }

    // 카메라 셰이크 정지 함수
    // transform : 카메라의 트랜스폼
    public virtual void Stop(Transform transform)
    {

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

// 카메라셰이크를 수행할 클래스
public class CameraShake : MonoBehaviour
{
    // 카메라 트랜스폼
    public Transform targetCamera;
    // 재생 시간
    public float playTime = 0.1f;

    public enum CameraShakeType
    {
        Random,
        Sine,
        Animation
    }

    public CameraShakeType cameraShakeType = CameraShakeType.Random;

    CameraShakeBase cameraShake;

    // 사용자가 수정할 카메라셰이크를 위한 설정 정보
    [SerializeField]
    CameraShakeInfo info;

    // Start is called before the first frame update
    void Start()
    {
        cameraShake = CreateCameraShake(cameraShakeType);
        //cameraShake.Init(targetCamera.position);
    }

    // 디자인 패턴 중 팩토리 메서드
    public static CameraShakeBase CreateCameraShake(CameraShakeType type)
    {
        switch(type)
        {
            case CameraShakeType.Random:
                return new CameraShakeRandom();
            case CameraShakeType.Sine:
                return new CameraShakeSine();
                break;
            case CameraShakeType.Animation:
                break;
        }
        return null;
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetButtonDown("Fire1"))
        {
            PlayCameraShake();
        }
    }

    void PlayCameraShake()
    {
        // 카메라셰이크 종류에 따라 실행 방법이 다르다
        if(cameraShakeType != CameraShakeType.Animation)
        {
            StopAllCoroutines();
            StartCoroutine(Play());
        }
    }

    // 재생시간 동안 카메라셰이크 실행
    
    IEnumerator Play()
    {
        // 카메라셰이크 초기화
        cameraShake.Init(targetCamera.position);

        float currentTime = 0;
        // 재생 동안 카메라셰이크 클래스의 Play() 함수 호출
        while (currentTime < playTime)
        {
            currentTime += Time.deltaTime;
            // 카메라셰이크 클래스의 Play() 함수 호출
            cameraShake.Play(targetCamera, info);
            yield return null;
        }
        // 재생이 끝나면 Stop() 호출
        cameraShake.Stop(targetCamera);
    }
}

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

public class CameraShakeRandom : CameraShakeBase
{
    public override void Play(Transform transform, CameraShakeInfo info)
    {
        transform.position = originPos + Random.insideUnitSphere * info.amplitude * Time.deltaTime;
    }

    public override void Stop(Transform transform)
    {
        transform.position = originPos;
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraShakeRandom : CameraShakeBase
{
    public override void Play(Transform transform, CameraShakeInfo info)
    {
        transform.position = originPos + Random.insideUnitSphere * info.amplitude * Time.deltaTime;
    }

    public override void Stop(Transform transform)
    {
        transform.position = originPos;
    }
}

 

728x90