구현 아이디어?
번개가 치는 상황에서 전역적으로 밝아지는것을 만들때는 현 씬 자체가 어두운 상태(밤)이 대부분이다. 이 점을 이용하여 단순히 씬에서 사용하는 Directional Light를 밝게 한다.
안개가 껴 있는 상황에서는 주변이 밝아져도 안개때문에 밝은 상태가 멀리 못가기에 잠시동안 안개를 맑게 했다 다시 돌려놓는 방향으로 구현하였다.
//ThunderManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ThunderManager : MonoBehaviour
{
//디렉셔널 라이트의 Light 컴포넌트
[SerializeField] private Light mDirLight;
//씬의 음향효과를 관장하는 사운드 매니저
private SoundManager mSoundManager;
//반짝이는 기능을 담당하는 mThunderCoroutine과 잠시 후 번개 소리를 출력을 담당하는 mSoundCoroutine
private Coroutine mThunderCoroutine, mSoundCoroutine;
//번개 효과를 시작하기 직전의 디렉셔널 라이트의 색상을 담는다
private Color mPrevLightColor;
//번개 효과를 시작하기 직전의 디렉셔널 라이트의 광도를 담는다
private float mPrevLightIntensity;
//번개 효과를 시작하기 직전의 안개 농도를 담는다
private float mPrevFogDensity;
//번개 효과를 자동으로 시작할 때 번개를 칠 때마다 딜레이 시간을 담는다
private float mOriginTimer;
//번개 효과를 자동으로 시작할때 다음 번개까지 남은 시간을 담는다
private float mCurrentTimer;
//번개 효과를 자동으로 치게할지 설정하는 변수
private bool mIsAuto = false;
//씬이 로드되면 사운드 매니저를 찾는다
void Start()
{
mSoundManager = FindObjectOfType<SoundManager>();
}
//timer 초마다 번개를 자동으로 치게 하는 함수
public void StartAutoThunder(float Timer = 60)
{
mOriginTimer = Timer;
mCurrentTimer = mOriginTimer;
mIsAuto = true;
}
//StartAutoThunder로 인해 자동으로 번개를 치는것을 중지하는 함수
public void StopAutoThunder()
{
mIsAuto = false;
}
//mIsAuto가 참인경우 지정된 시간초마다 번개를 치게한다
private void Update()
{
if(!mIsAuto) return;
mCurrentTimer -= Time.deltaTime;
if(mCurrentTimer < 0)
{
mCurrentTimer = mOriginTimer;
RunThunder(0, Random.Range(2, 10));
}
}
//실제로 번개를 치는 효과를 실행하는 함수
public void RunThunder(float delayTime = 0, float soundDelayTime = 0)
{
if(mThunderCoroutine != null)
{
mDirLight.color = mPrevLightColor;
mDirLight.intensity = mPrevLightIntensity;
RenderSettings.fogDensity = mPrevFogDensity;
StopCoroutine(mThunderCoroutine);
}
if(mSoundCoroutine != null)
{
StopCoroutine(mSoundCoroutine);
}
mPrevLightColor = mDirLight.color;
mPrevLightIntensity = mDirLight.intensity;
mPrevFogDensity = RenderSettings.fogDensity;
mThunderCoroutine = StartCoroutine("ThunderCor", delayTime);
mSoundCoroutine = StartCoroutine("ThunderSoundCor", soundDelayTime);
}
//순간 반짝이도록 빛과 안개를 잠깐동안 설정했다가 되돌리는 코루틴 함수
IEnumerator ThunderCor(float delayTime)
{
bool isFogActived = RenderSettings.fog;
yield return new WaitForSeconds(delayTime);
mDirLight.color = Color.white;
mDirLight.intensity = 1f;
if(isFogActived)
{
RenderSettings.fogDensity = mPrevFogDensity * 0.5f;
}
yield return new WaitForSeconds(0.05f);
mDirLight.color = mPrevLightColor;
mDirLight.intensity = mPrevLightIntensity;
if(isFogActived)
{
RenderSettings.fogDensity = mPrevFogDensity;
}
}
//번개가 친 후에 잠시 후 번개소리가 나도록 하는 코루틴 함수
IEnumerator ThunderSoundCor(float soundDelayTime)
{
yield return new WaitForSeconds(soundDelayTime);
mSoundManager.PlayThunderSound();
}
}
|
cs |
카메라를 흔들리게하는 카메라 매니저와 같이 씬 내에 하나의 매니저가 존재하며 해당 매니저에서 public 함수를 호출하는 방식으로 구현하였다.
[SerializeField] private Light mDirLight;
- 씬에서 사용하는 디렉셔널 라이트 오브젝트의 Light 컴포넌트를 담는다.
- 인스펙터에서 직접 넣어서 사용하도록 구현하였다.
private SoundManager mSoundManager;
- 번개소리를 출력하기 위해 씬 내의 모든 사운드를 관장하는 사운드 매니저이다.
private Coroutine mThunderCoroutine, mSoundCoroutine;
- 반짝이는 기능을 담당하고 번개 소리 출력을 담당하는 코루틴을 담는 변수들이다.
- 의도하지 않은 반복적인 호출에 버그가 나는것을 방지하기위해 코루틴을 저장하는 변수를 사용한다.
private Color mPrevLightColor;
private float mPrevLightIntensity;
private float mPrevFogDensity;
- 번개를 치는 함수를 호출할 때 디렉셔널 라이트와 안개에 대한 설정이 바뀌기 직전의 값을 각 변수에서 저장한다.
- 번개를 친 후 변경된 설정에서 다시 되돌아오기 위해 사용한다.
- 코루틴의 중복 실행 시 코루틴들을 초기화하고 새로운 코루틴을 실행하기 전에 설정들을 다시 되돌리는데 사용한다.
private float mOriginTimer;
- StartAutoThunder()함수가 실행되어 자동으로 일정 시간마다 번개를 칠 때 번개치는 함수의 간격에 대한 시간값을 저장하는 변수이다.
private float mCurrentTimer;
- StartAutoThunder()함수가 실행되어 자동으로 번개를 칠 때 다음 번개까지 남은 시간을 저장하는 변수이다.
private bool mIsAuto = false;
- StartAutoThunder()로 인해 mIsAuto 가 참이 되는데, mIsAuto가 참이면 Update()함수가 돌면서 mCurrentTimer를 감소시키고 번개를 치도록 한다.
void Start()
- 사운드 매니저를 찾아서 mSoundManager 변수에 저장한다.
public void StartAutoThunder(float Timer = 60)
- 외부에서 호출되며 기본 매개변수인 60은 60초마다 번개가 내리치도록 한다.
- mIsAuto를 참으로 하여 Update()의 내부가 프레임마다 실행되도록 한다.
public void StopAutoThunder()
- 외부에서 호출되며 단순히 mIsAuto를 거짓으로 만들어 Update()의 내부가 더 이상 실행되지 않도록 한다.
private void Update()
- StartAutoThunder()에 의해 mIsAuto가 참인경우에만 내부가 실행된다.
- mCurrentTimer가 감소하며 0보다 작아지는경우 RunThunder()함수를 호출한다.
public void RunThunder(float delayTime = 0, float soundDelayTime = 0)
- 번개의 효과를 시작하는 함수이다.
- delayTime은 변수의 값 초 후에 번쩍이게 하도록한다.
- soundDelayTime은 변수의 값 초 후에 번개소리를 출력하도록 한다.
- 외부에서 독립적으로 호출될 수 있으며, mIsAuto에 의한 자동 번개와 별개로 RunThunder의 매개변수인 delayTime초 후에 단독적으로 번개를 치도록 한다. 예시로 날씨가 아닌 번개속성의 공격으로 인한 의도한 번개 연출을 낼 수 있다.
- 이미 이전의 코루틴이 실행되고 있으면 해당 코루틴을 제거하고 변경된 빛과 안개 속성을 되돌려 놓은 후 다시 반짝이는 효과 코루틴과 소리출력 코루틴을 실행하도록 한다. 이 과정으로 비 정상적으로 동시다발적으로 번개가 내리쳐도 버그를 방지할 수 있다.
IEnumerator ThunderCor(float delayTime)
- 번개로 인한 전역적으로 반짝이는 효과를 담당하는 코루틴 함수이다.
- delayTime초 만큼 기다렸다가 디렉셔널 라이트의 광도는 1, 색상은 Color.white로 잠시동안 바꾼다. 동시에 안개가 켜져 있는 상태라면 안개의 농도를 반 줄인다.
- 애초부터 안개가 꺼져있다면 isFogActived가 거짓이 되는데, 거짓이라면 RenderSettings.fogDensity를 수정해서는 안된다.
- yield return new WaitForSeconds(0.05f); 코드와 그 이후는 0.05초 후에 다시 이전의 속성으로 돌려놓는다.
IEnumerator ThunderSoundCor(float soundDelayTime)
- 번개가 친 후에 soundDelayTime초 후 번개소리가 나도록 하는 코루틴 함수이다.
'unity game modules' 카테고리의 다른 글
[유니티] 대사 말풍선 기능 (0) | 2022.07.17 |
---|---|
[유니티] 오브젝트와 UI에 gif 이미지 출력 (0) | 2022.07.17 |
[유니티] 충돌 연출 및 RigidBody.AddForce()의 이해 (0) | 2022.07.17 |
[유니티] 카메라 흔들림 효과 (0) | 2022.07.17 |
[유니티] 안개 효과 (던전 입장 효과) (0) | 2022.07.16 |