1vdlrwnsv1 님의 블로그
유니티 개발 숙련주차 3. 조명기능 만져서 낮과 밤 구현 본문
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DayNightCycle : MonoBehaviour
{
[Range(0.0f, 1.0f)]
public float time;
public float fullDayLength;
public float startTime = 0.4f;
private float timeRate;
public Vector3 noon; //vector(90 y 0)
[Header("Sun")]
public Light sun;
public Gradient sunColor;
public AnimationCurve sunIntensity;
[Header("Moon")]
public Light moon;
public Gradient moonColor;
public AnimationCurve moonIntensity;
[Header("Other Lighting")]
public AnimationCurve lighingIntensityMultiplier;
public AnimationCurve ReflectionIntensityMultiplier;
// Start is called before the first frame update
void Start()
{
timeRate = 1.0f / fullDayLength;
time = startTime;
}
// Update is called once per frame
void Update()
{
time = (time + timeRate * Time.deltaTime) % 1.0f;
UpdateLighting(sun, sunColor, sunIntensity);
UpdateLighting(moon, moonColor, moonIntensity);
RenderSettings.ambientIntensity = lighingIntensityMultiplier.Evaluate(time);
RenderSettings.reflectionIntensity = ReflectionIntensityMultiplier.Evaluate(time);
}
void UpdateLighting(Light lightSource, Gradient gradient, AnimationCurve intensityCurve)
{
float intensity = intensityCurve.Evaluate(time);
lightSource.transform.eulerAngles = (time - (lightSource == sun ? 0.25f : 0.75f)) * noon * 4f;
lightSource.color = gradient.Evaluate(time);
lightSource.intensity = intensity;
GameObject go = lightSource.gameObject;
if(lightSource.intensity == 0 && go.activeInHierarchy)
{
go.SetActive(false);
}
else if(lightSource.intensity > 0 && !go.activeInHierarchy)
{
go.SetActive(true);
}
}
}
변수 설명
- time: 현재 시간(0~1 범위로 순환, 0은 시작 시간, 1은 하루가 끝난 상태)
- fullDayLength: 하루 길이
- startTime: 시작 시간 (0.4f로 설정하면 하루의 40% 지점부터 시작)
- timeRate: 시간 속도, 하루의 길이에 맞춰서 계산됨.
- noon: 태양의 정오 위치 (Vector3(90, y, 0) 형태로 설정)
태양 관련 변수
- sun: 태양을 담당하는 Light 객체.
- sunColor: 태양 색상을 시간에 따라 변화시키는 Gradient 객체.
- sunIntensity: 태양의 밝기를 시간에 맞춰 변화시키는 AnimationCurve 객체.
달 관련 변수
- moon: 달을 담당하는 Light 객체.
- moonColor: 달 색상을 시간에 맞춰 변화시키는 Gradient 객체.
- moonIntensity: 달의 밝기를 시간에 맞춰 변화시키는 AnimationCurve 객체.
기타 조명 관련 변수
- lighingIntensityMultiplier: 기타 조명의 밝기를 시간에 맞춰 변화시키는 AnimationCurve 객체.
- ReflectionIntensityMultiplier: 반사광의 강도를 시간에 맞춰 변화시키는 AnimationCurve 객체.
주요 함수
Start()
- timeRate = 1.0f / fullDayLength;
하루를 1로 설정하고, fullDayLength에 맞춰 시간의 흐름 속도를 계산. - time = startTime;
게임이 시작할 때 startTime에서 시작하도록 설정.
Update()
- time = (time + timeRate * Time.deltaTime) % 1.0f;
매 프레임마다 time을 업데이트. timeRate에 따라 하루를 진행시키며 1로 나눠서 0~1 범위로 순환하도록 함. - UpdateLighting(sun, sunColor, sunIntensity);
태양에 대해 UpdateLighting 함수를 호출. - UpdateLighting(moon, moonColor, moonIntensity);
달에 대해 UpdateLighting 함수를 호출. - RenderSettings.ambientIntensity = lighingIntensityMultiplier.Evaluate(time);
시간에 맞춰 다른 조명의 밝기를 조정. - RenderSettings.reflectionIntensity = ReflectionIntensityMultiplier.Evaluate(time);
시간에 맞춰 반사광의 강도를 조정.
UpdateLighting(Light lightSource, Gradient gradient, AnimationCurve intensityCurve)
- lightSource.transform.eulerAngles = (time - (lightSource == sun ? 0.25f : 0.75f)) * noon * 4f;
주어진 lightSource(태양 또는 달)의 위치를 계산하여 회전시킴. sun은 정오가 0.25f로, moon은 0.75f로 설정되어 서로 다른 시간대에 맞춰 위치가 변함. - lightSource.color = gradient.Evaluate(time);
시간에 맞춰 lightSource의 색상을 gradient에 맞춰 업데이트. - lightSource.intensity = intensity;
시간에 맞춰 lightSource의 밝기를 intensity로 설정. - if (lightSource.intensity == 0 && go.activeInHierarchy)
밝기가 0이면 해당 조명을 비활성화하여 보이지 않게 함. - else if (lightSource.intensity > 0 && !go.activeInHierarchy)
밝기가 0보다 크면 조명을 활성화하여 보이게 함.

밤에서 정오로 갈수록 태양의 intensity(밝기)가 커져야함 반대로 낮에서 자정으로 갈때는 태양의 intenty가 낮아지고 달 조명의 intensity가 커져야 하니 AnimationCurve를 태양과는 반대로 설정해주면됨
'Unity숙련주차' 카테고리의 다른 글
Unity, 밸브사의 Portal 게임을 클론 해보자잇 (0) | 2025.03.18 |
---|---|
유니티 개발 숙련주차4. 아이템 상호작용 (0) | 2025.03.06 |
유니티 개발 숙련 2. 플레이어에게 데미지 주기 (0) | 2025.03.05 |
유니티 게임개발 숙련 1. 플레이어 만들기 (0) | 2025.03.04 |