본문 바로가기

Unity/Unity 스파르타

8주차 - 밤낮 바꾸기

728x90

using UnityEngine.Events;

UnityEvent OnTakeDamage;

 - 버튼 컴포넌트의 버튼 함수를 추가하는 것 마냥 이벤트를 추가할 수 있음

 

오른쪽 하단 Auto Generate Lighting Off 에서 스카이 박스와 Sun 설정을 할 수 있음.

 

 

1. 밤과 낮에 쓰일 Directional Light 를 만들어 줍니다.

  • Light 에있는 Intensity(빛의 세기) 를 사용해 밤과 낮을 표현할 것입니다.
  • 각각 밤과 낮에 쓰일 Light, Ligth 에 적용시킬 Gradient, 시간에따라 Intensity를 적용시킬 AnimationCurve를 준비해 줍니다.

* AnimationCurve를 사용해 빛의 세기, 빛의 색을 모두 관리할 것이기 때문에 시간을 0 ~ 1 사이의 값으로 만들어 주는게 중요합니다.

 

2. 하루 주기를 정해주고 계속해서 시간이 흘러가게 만들어 줍니다.

    private void Start()
    {
        timeRate = 1.0f / fullDayLength;
    }
     private void Update()
    {
        time = (time + timeRate * Time.deltaTime) % 1.0f;
    }
  • 먼저 시간 비율을 구해줍니다.
    • 예를 들어 하루를 30초라고 생각하면, 하루(30초)중 1에 해당하는 시간 비율을 의미합니다.
    • 위에서 구한 시간비율에 Time.deltaTime을 곱해준뒤 시간 변수에 더해주고, 1.0f로 나눠 나머지를 구해줍니다
      • 시간을 0~1 사이의 값으로 구해야 하기때문에 1.0f로 나눠 나머지를 구해줍니다.

4. 밤과 낮을 바꿔주는 함수를 작성해 봅니다.

  • 그전에 밤과 낮의 길이를 생각해 봅니다.
    • AnimationCurve 에 적용시킬 낮의 길이와 밤의 길이를 생각해줍니다. 낮의 경우 0.3~0.8 까지가 낮이고 나머지를 밤으로 설정해 줄것입니다.
  • 우리는 빛의 세기를, 위에서 만든 밤과 낮의 AnimationCurve에 time을 Evaluate 시켜줄 것입니다. 
float intensity = intensityCurve.Evaluate(time);
  • 밤과, 낮의 Light를 시간에 따라 transform.eulerAngles 를 사용해 x축 기준으로 360도 각도로 회전 시켜 줍니다
source.transform.eulerAngles = (time - (source == sun ? 0.25f : 0.75f)) * noon * 4.0f;
  • 360도 기준으로 해가 떠야되는 위치를 잡아줘야 합니다.
void UpdateLighting(Light source,Gradient color,AnimationCurve intensityCurve)
    {
        float intensity = intensityCurve.Evaluate(time);

        source.transform.eulerAngles = (time - (source == sun ? 0.25f : 0.75f)) * noon * 4.0f;
        
        source.color = color.Evaluate(time);
        source.intensity = intensity;

        GameObject go = source.gameObject;
        if (source.intensity == 0 && go.activeInHierarchy)
            go.SetActive(false);
        else if (source.intensity > 0 && !go.activeInHierarchy)
            go.SetActive(true);
       
    }
  • 낮과 밤에 설정한 Gradiant를 Evaluate로 시간에 따라 색을 설정해주고,
  • Evaluate 한 빛이 세기를 설정
  • 밤 또는 낮의 빛의 세기가 0 일경우 오브젝트를 꺼두고, 세기가 0보다 클 경우에만 오브젝트를 켜줍니다.
    private void Update()
    {
        time = (time + timeRate * Time.deltaTime) % 1.0f;

        UpdateLighting(sun, sunColor, sunIntensity);
        UpdateLighting(moon, moonColor, moonIntensity);
        
        RenderSettings.ambientIntensity = lightingIntensityMultiplier.Evaluate(time);
        RenderSettings.reflectionIntensity = reflectionIntensityMultiplier.Evaluate(time);
    }

 

RederSettings 에 접근해 ambientIntensity 와 reflectionIntensity 을 AnimationCurve를 사용해 설정해줍니다

  • ambientIntensity : 조명의 영향을 받는 주변 조명의 강도를 조절해주며 실시간 조명 및 그림자 계산에 영향을 줍니다. 값이 높을수록 조명에 의한 그림자의 명암이 뚜렷해지고, 값이 낮을수록 그림자의 부드러움이 증가할 수 있습니다.
  • reflectionIntensity : 주변 조명에 의해 물체가 얼마나 많은 주변 환경을 반사하여 보여줄지를 결정하는 데 사용됩니다. 실시간 조명 및 그림자 계산에도 영향을 줍니다. 값이 높을수록 물체의 반사가 더 선명하고 강렬해지며, 값이 낮을수록 반사의 부드러움이 증가할 수 있습니다.
728x90