본문 바로가기
🌐 유니티 (Unity)

Day 33 - 3D 게임(해와 달)

by shin0707 2024. 5. 28.
728x90
반응형

  • 주제

>> 유니티 3D 조명 변화


  • 공부내용

Gradient : 색상 변화를 표현하는 데 사용

AnimationCurve : 시간에 따른 값을 정의하는 데 사용

lightSource.transform.eulerAngles : 광원의 회전을 설정

RenderSettings.ambientIntensity : 환경 조명의 강도를 설정(낮에는 더 밝게, 밤에는 더 어둡게)

 

1. 단순한 낮과 밤의 조명 변화

주기적으로 조명의 색상을 변화시켜 낮과 밤의 효과를 구현한 예제

using UnityEngine;

public class SimpleDayNight : MonoBehaviour
{
    public Light directionalLight; // 광원
    public Gradient lightColor; // 색상 그라디언트
    public float dayDuration = 10f; // 하루의 길이 (초 단위)
    private float time; // 현재 시간

    void Update()
    {
        time += Time.deltaTime / dayDuration; // 시간 업데이트
        time %= 1f; // 0과 1 사이의 값으로 유지

        directionalLight.color = lightColor.Evaluate(time); // 시간에 따른 색상 설정
    }
}

 

2. 주기적인 환경 조명 변화

Rendersettings를 사용하여 주기적으로 환경 조명을 변화시키는 예제

using UnityEngine;

public class EnvironmentLighting : MonoBehaviour
{
    public AnimationCurve lightingIntensityCurve; // 조명 강도 곡선
    public float cycleDuration = 10f; // 주기 길이 (초 단위)
    private float time; // 현재 시간

    void Update()
    {
        time += Time.deltaTime / cycleDuration; // 시간 업데이트
        time %= 1f; // 0과 1 사이의 값으로 유지

        RenderSettings.ambientIntensity = lightingIntensityCurve.Evaluate(time); // 시간에 따른 조명 강도 설정
    }
}

 

3. AnimationCurve 없이 해와 달 구현하는 예제

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

public class DayNightCycle : MonoBehaviour
{
    [Range(0.0f, 1.0f)] // time 변수의 범위를 0.0에서 1.0으로 설정
    public float time; // 현재 시간 비율 변수
    public float fullDayLength = 120f; // 하루의 길이 변수 (기본값: 120초)
    public float startTime = 0.4f; // 초기 시작 시간 (0.5f가 정오)
    private float timeRate; // 시간 비율 변수
    public Vector3 noon; // 정오의 각도 (90, 0, 0)

    [Header("Sun")] // 태양 관련 설정 섹션
    public Light sun; // 태양 광원
    public Color dayColor = Color.white; // 태양의 색상
    public float dayIntensity = 1f; // 태양의 강도

    [Header("Moon")] // 달 관련 설정 섹션
    public Light moon; // 달 광원
    public Color nightColor = Color.white; // 달의 색상
    public float nightIntensity = 0.5f; // 달의 강도

    [Header("Other Lighting")] // 기타 조명 설정 섹션
    public float maxAmbientIntensity = 1f; // 최대 환경 조명 강도
    public float minAmbientIntensity = 0.2f; // 최소 환경 조명 강도

    private void Start()
    {
        timeRate = 1.0f / fullDayLength; // 하루 길이에 따른 시간 비율 계산
        time = startTime; // 초기 시간 설정
    }

    private void Update()
    {
        time = (time + timeRate * Time.deltaTime) % 1.0f; // 시간 업데이트 및 하루 주기 계산

        UpdateLighting(); // 조명 업데이트
    }

    void UpdateLighting()
    {
        // 태양과 달의 각도 계산
        sun.transform.eulerAngles = (time - 0.25f) * noon * 4.0f; // 태양 각도 업데이트
        moon.transform.eulerAngles = (time - 0.75f) * noon * 4.0f; // 달 각도 업데이트

        // 현재 시간이 낮인지 밤인지 확인
        bool isDay = time > 0.25f && time < 0.75f;

        // 태양과 달의 색상 및 강도 설정
        if (isDay)
        {
            sun.color = dayColor;
            sun.intensity = dayIntensity;
            moon.intensity = 0f;
        }
        else
        {
            moon.color = nightColor;
            moon.intensity = nightIntensity;
            sun.intensity = 0f;
        }

        // 환경 조명 강도 설정
        RenderSettings.ambientIntensity = Mathf.Lerp(minAmbientIntensity, maxAmbientIntensity, sun.intensity);
    }
}

 

3-1. 해와 달의 부드러운 전환

위 스크립트에 UpdateLighting 메서드 내 "// 태양과 달의 색상 및 강도 설정 " 부분

if (isDay)
        {
            sun.color = dayColor;
            sun.intensity = Mathf.Lerp(sun.intensity, dayIntensity, Time.deltaTime);
            moon.intensity = Mathf.Lerp(moon.intensity, 0f, Time.deltaTime);
        }
        else
        {
            moon.color = nightColor;
            moon.intensity = Mathf.Lerp(moon.intensity, nightIntensity, Time.deltaTime);
            sun.intensity = Mathf.Lerp(sun.intensity, 0f, Time.deltaTime);
        }

 

3-2. 정오와 자정을 강조

위 스크립트에 UpdateLighting 메서드 내 "// 태양과 달의 색상 및 강도 설정 " 부분

if (isDay)
        {
            sun.color = dayColor;
            sun.intensity = Mathf.Lerp(0f, maxDayIntensity, Mathf.PingPong(time * 2, 1));
            moon.intensity = 0f;
        }
        else
        {
            moon.color = nightColor;
            moon.intensity = Mathf.Lerp(0f, maxNightIntensity, Mathf.PingPong((time - 0.5f) * 2, 1));
            sun.intensity = 0f;
        }

 

728x90
반응형

loading