목차
- 스카이박스로 하늘 만들기
- 조명으로 낮과 밤 만들기
스카이박스
전체 씬을 둘러싸서 하늘의 역할을 함. 6 Sided Skybox를 만들면 총 여섯 면으로 둘러싸고 있어서 6개 각각 텍스처 매핑할 수 있음.
스카이박스로 하늘 만들기
새 'Material' Create > Shader를 Skybox로 적용.
Window > Rendering > Lighting 창 열어서 Environment 탭에서 Skybox 머티리얼 지정해줄 수 있음.
스카이박스의 Sky와 Ground 색을 지정해줬다.
조명으로 낮과 밤 만들기
Directional Light의 Roatation을 조절해보면 90도일 때 해가 꼭데기(정오)에 있음. 0도일 때 해가 동쪽에 있고, 180도일 때 서쪽에 있으며 270도일 때 가장 깜깜하다.
이게 가능한 이유는 단순히 Directional Light가 있으면 그게 해가 되는 것이 아니라, 아까 Skybox를 지정해줬던 같은 Lighting 창 > Environment 탭의 Sun Source에 Directional Light를 넣었기 때문에 태양 효과를 볼 수 있는 것이다.
설정하는 것 뿐만 아니라 아래 옵션 중 Lighting Intensity Multiple, Reflections Intensity Multiple을 조절해줄 것이다.
조절해줄 때는 Sprite 애니메이션에서 일정 값 사이를 자연스럽게 보간해주던 것처럼, Key값을 설정해주면 그 사이사이를 보간해주는 방식으로 조절하게 된다.
AnimationCurve는 유니티에서 애니메이션의 키프레임을 사용하여 값을 보간하는 데 사용되는 클래스이다. 이 클래스를 사용해서 값을 부드럽게 변화시키는 커브를 정의하고, 이를 기반으로 애니메이션을 만들 수 있다.
1. Sun, Moon 만들어주기
씬의 Directional Light를 Sun으로, 복제본을 Moon으로 만듦.
2. DayNightCycle 스크립트 작성 및 설정
스크립트에서 해와 달의 사이클을 돌려준다. Evaluate는 Curve에서 특정 시간에 해당하는 값을 보간하여 반환한다.
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class DayNightCycle : MonoBehaviour
{
[Range(0f, 1f)]
public float time;
public float fullDayLength;
public float startTime = 0.4f; // 시간을 0~1로 잡을 것이기 때문에 타임이 0.5일 때 정오. 각도가 90도
private float timeRate;
public Vector3 noon; // Vector 90 0 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 lightingIntensityMultiplier;
public AnimationCurve reflectionIntensityMultiplier;
private void Start()
{
timeRate = 1f / fullDayLength;
time = startTime;
}
private void Update()
{
time = (time + timeRate * Time.deltaTime) % 1f; // time을 0~1로 지키기 위함
UpdateLighting(Sun, sunColor, sunIntensity);
UpdateLighting(Moon, moonColor, moonIntensity);
// 씬 전체의 환경광 밝기 조절 (0으로 하면 씬 전체가 어두워짐)
RenderSettings.ambientIntensity = lightingIntensityMultiplier.Evaluate(time);
// 씬 전체의 반사광 강도 조절
RenderSettings.reflectionIntensity = reflectionIntensityMultiplier.Evaluate(time);
}
void UpdateLighting(Light lightSource, Gradient gradient, AnimationCurve intensityCurve)
{
float intensity = intensityCurve.Evaluate(time); // time 시간에 해당하는 값을 보간하여 반환
// 360도의 0.5면 180도가 나옴. 우리의 0.5는 90도여야 함. 그래서 0.25를 빼주는 것.
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);
}
}
}
otherLighting으로 설정하는 것들은 다른 조명들의 세기를 조절하는 것이 아니라, 씬의 환경광과 반사광을 조절해서 어두워진 것처럼 만든다.
// 씬 전체의 환경광 밝기 조절 (0으로 하면 씬 전체가 어두워짐)
RenderSettings.ambientIntensity = lightingIntensityMultiplier.Evaluate(time);
// 씬 전체의 반사광 강도 조절
RenderSettings.reflectionIntensity = reflectionIntensityMultiplier.Evaluate(time);
만약 Update 함수에서 위 두 줄을 빼고 실행하면 아래와 같이 해가 졌을 때도 환경이 모두 잘보이게 된다.
3. 에디터에서 Intensity Curve 키값들 설정해주기
DayNightCycle 스크립트를 오브젝트에 붙여주고 Sun과 Moon 넣어줌. 그리고 각 조명의 intensity Curve와 Gradient할 Color값을 설정해준다.
- 그래프에서 우클릭하고 Add Key > 키를 우클릭해서 Edit Key > (time, value)쌍으로 애니메이션의 키가 될 수치 집어 넣음.
'공부 기록 > 유니티 Unity' 카테고리의 다른 글
[Unity/TIL] AI Navigation 사용해서 NPC 구현 (0) | 2025.03.06 |
---|---|
[Unity/TIL] 유니티 숙련 과정에서 알게 된 것들 (0) | 2025.03.05 |
[Unity/TIL] delegate, Action 활용 - UI 팝업창 (0) | 2025.02.28 |
[Unity/TIL] 특정 위치에 다른 오브젝트가 있는지 감지하는 방법 (3) | 2025.02.26 |
[Unity/TIL] DOTween으로 UI 애니메이션 만들기 (0) | 2025.02.25 |