오늘은 뭔가 조용하지만 조용하지 않은 멘붕과 멘붕의 날이었다.
일단 어제 포기했던 낮과밤의 자연스러운 전환은 코루틴을 이용해 해결했고....
이상한거 구현하고 으아악 하고 다시 없애고 다른거 구현하고의 반복이었다.
일단 자연스러운 낮과밤은 코루틴을 이용해 구현했는데
public class TimeManager : Singleton<TimeManager>
{
private Coroutine transitionRoutine; // 전환 코루틴
private IEnumerator LightTransitionCoroutine()
{
float timeElapsed = 0f;
float startSunIntensity = sun.intensity;
float targetSunIntensity = (currentTimeState == TimeState.Day) ? dayLightIntensity : 0f;
float startMoonIntensity = moon.intensity;
float targetMoonIntensity = (currentTimeState == TimeState.Night) ? nightLightIntensity : 0f;
float startAmbient = RenderSettings.ambientIntensity;
float targetAmbient = (currentTimeState == TimeState.Day) ? dayAmbientIntensity : nightAmbientIntensity;
float startReflection = RenderSettings.reflectionIntensity;
float targetReflection = (currentTimeState == TimeState.Day) ? dayReflectionIntensity : nightReflectionIntensity;
Color startSunColor = sun.color;
Color targetSunColor = (currentTimeState == TimeState.Day)
? new Color(1.0f, 244f / 255f, 214f / 255f)
: new Color(0.2f, 0.2f, 0.2f);
moon.gameObject.SetActive(true); // 항상 켜두고 밝기만 조절
while (timeElapsed < transitionDuration)
{
float t = timeElapsed / transitionDuration;
sun.intensity = Mathf.Lerp(startSunIntensity, targetSunIntensity, t);
sun.color = Color.Lerp(startSunColor, targetSunColor, t);
moon.intensity = Mathf.Lerp(startMoonIntensity, targetMoonIntensity, t);
RenderSettings.ambientIntensity = Mathf.Lerp(startAmbient, targetAmbient, t);
RenderSettings.reflectionIntensity = Mathf.Lerp(startReflection, targetReflection, t);
timeElapsed += Time.deltaTime;
yield return null;
}
// 보정
sun.intensity = targetSunIntensity;
sun.color = targetSunColor;
moon.intensity = targetMoonIntensity;
moon.gameObject.SetActive(currentTimeState == TimeState.Night);
RenderSettings.ambientIntensity = targetAmbient;
RenderSettings.reflectionIntensity = targetReflection;
transitionRoutine = null;
}
// 조명 즉시적용
private void ApplyLightingInstant()
{
sun.intensity = (currentTimeState == TimeState.Day) ? dayLightIntensity : 0f;
sun.color = (currentTimeState == TimeState.Day)
? new Color(1.0f, 244f / 255f, 214f / 255f)
: new Color(0.2f, 0.2f, 0.2f);
moon.intensity = (currentTimeState == TimeState.Night) ? nightLightIntensity : 0f;
moon.color = nightLightColor;
moon.gameObject.SetActive(currentTimeState == TimeState.Night);
RenderSettings.ambientIntensity = (currentTimeState == TimeState.Day) ? dayAmbientIntensity : nightAmbientIntensity;
RenderSettings.reflectionIntensity = (currentTimeState == TimeState.Day) ? dayReflectionIntensity : nightReflectionIntensity;
}
}
낮과 밤이 바뀔 때 조명을 자연스럽게 전환해주는 역할을 하며
태양과 달의 밝기, 색, 광 등의 요소들이 시간에 따라 서서히 변화해서 부드럽게 전환할 수 있게 해주었다.
다만 달의 경우 그림자때문에 넣어주었는데 아직은 제대로 되는게 없긴 하다..
추가로 낮동안엔 전투가 진행되는데 뭔가 낮에 전투가 진행되는게 긴장감이 없어보여 스크린이펙트를 추가해달라는 요청이 있었는데
이부분은 처음에 내가 잘못 이해해서 데미지를 피격당할때 뜨는 이펙트로 생각해서... 잘못 구현했었는데 어떤식으로 구현해야할까 고민하다 생각한것중 하나는 애니메이션을 이용하여 구현할까 하였지만 이부분도 코루틴을 이용하여 투명도 조절로 구현해주었다.
public class TimeManager : Singleton<TimeManager>
{
[Header("Battle Screen Settings")]
public Image battleScreen;
public float battleScreenBlinkInterval = 0.5f; // 깜빡임 간격
public float battleScreenMinAlpha = 0.2f; // 최소 투명도
public float battleScreenMaxAlpha = 0.3f; // 최대 투명도
private Coroutine battleScreenRoutine; // 배틀스크린 깜빡임 코루틴
private void Start()
{
// 시작 초기값은 밤
currentTimeState = TimeState.Night;
ApplyLightingInstant();
// 배틀스크린 초기화
if (battleScreen != null)
{
battleScreen.color = Color.clear;
}
}
private void OnEnable()
{
// 씬이 활성화될 때 배틀스크린 상태 확인
UpdateBattleScreenState();
}
private void OnDisable()
{
// 씬이 비활성화될 때 코루틴 정리
if (battleScreenRoutine != null)
{
StopCoroutine(battleScreenRoutine);
battleScreenRoutine = null;
}
}
public void SetDay()
{
if (currentTimeState != TimeState.Day)
{
UpdateBattleScreenState();
}
}
public void SetNight()
{
if (currentTimeState != TimeState.Night)
{
UpdateBattleScreenState();
}
}
private void UpdateBattleScreenState()
{
if (battleScreen == null) return;
// 이미 실행 중인 코루틴이 있으면 중지
if (battleScreenRoutine != null)
{
StopCoroutine(battleScreenRoutine);
battleScreenRoutine = null;
battleScreen.color = Color.clear; // 투명하게 초기화
}
// 낮 상태일 때만 깜빡임 시작
if (currentTimeState == TimeState.Day)
{
battleScreen.gameObject.SetActive(true);
battleScreenRoutine = StartCoroutine(ShowBattleScreen());
}
else
{
battleScreen.gameObject.SetActive(false); // 밤엔 비활성화
}
}
// 배틀스크린 깜빡임 효과
private IEnumerator ShowBattleScreen()
{
float alpha = battleScreenMinAlpha;
float direction = 1f; // 1이면 증가, -1이면 감소
Color baseColor = new Color(1f, 0f, 0f);
while (currentTimeState == TimeState.Day)
{
// 알파값 증가 또는 감소
alpha += direction * Time.deltaTime * 0.2f; // 속도 조절 (0.2는 조정 가능)
// 방향 반전 조건
if (alpha >= battleScreenMaxAlpha)
{
alpha = battleScreenMaxAlpha;
direction = -1f;
}
else if (alpha <= battleScreenMinAlpha)
{
alpha = battleScreenMinAlpha;
direction = 1f;
}
battleScreen.color = new Color(baseColor.r, baseColor.g, baseColor.b, alpha);
yield return null; // 매 프레임 갱신
}
battleScreen.color = Color.clear;
}
}
낮일때만 화면위에 있는 이미지의 투명도를 조절해주게 해주었으며 밤이되면 꺼지고 낮이되면 켜진다.
이렇게 해서 타임 부분도 어느정도 마무리다.
- 사실 이 부분들은 타임매니저에 들어가는게 맞나 싶었지만 일단 이쪽에 구현하고 나중에 필요할경우 분리하기로 했다.

프리펩도 바꿔줘서 깔끔할줄 알았으나 블록타일 크기 조절 실패로 ㅎㅎ...... 조금 지저분하지만 일단 이렇게 마무리!
'Unity > Project' 카테고리의 다른 글
| [Unity] 내배캠 최종프로젝트 : 루시퍼 서바이벌 20일차, 중간점검 (0) | 2025.05.02 |
|---|---|
| [Unity] 내배캠 최종프로젝트 : 루시퍼 서바이벌 19일차, (0) | 2025.05.01 |
| [Unity] 내배캠 최종프로젝트 : 루시퍼 서바이벌 17일차, (0) | 2025.04.30 |
| [Unity] 내배캠 최종프로젝트 : 루시퍼 서바이벌 16일차, (0) | 2025.04.28 |
| [Unity] 내배캠 최종프로젝트 : 루시퍼 서바이벌 15일차, 배치지옥 (0) | 2025.04.25 |