반응형
추위 기능
낮일때는 추위가 회복되고 밤일때는 추위가 소모되는 UI를 구현했다.
아마 모닥불 주위에 있으면 추위가 회복되게 하는것도 나중에 추가할 수 있을 듯 싶다!
먼저 낮과 밤을 관리하는 오브젝트는 이렇다.
이 오브젝트 안에 Sun과 Moon 오브젝트도 들어있다.
이렇게 빛의 색을 정해주면 된다.
기능 코드
설명은 주석으로 달아두겠습니당.
DayNightCycle.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DayNightCycle : MonoBehaviour
{
[Range(0.0f, 1.0f)]
public float time; // 현재 시간을 나타내는 변수. 0.5는 정오
public float fullDayLength; // 하루의 길이. 본인은 30초로 설정함
public float startTime = 0.4f; // 시작 시간
private float timeRate; // 시간의 진행 속도
public Vector3 noon; // 정오의 태양 위치 벡터가 90 0 0
[Header("Sun")]
public Light sun; // 태양을 나타내는 Light 컴포넌트
public Gradient sumColor; // 시간에 따른 태양의 색
public AnimationCurve sunIntensity; // 시간에 따른 태양의 밝기
[Header("Moon")]
public Light moon; // 달을 나타내는 Light 컴포넌트
public Gradient moonColor; // 시간에 따른 달의 색
public AnimationCurve moonIntensity; // 시간에 따른 달의 밝기
[Header("Other Lighting")]
public AnimationCurve lightingIntensityMultiplier; // 시간에 따른 전체 조명 강도를 정의하는
public AnimationCurve reflectionIntensityMultiplier; // 시간에 따른 반사 강도
void Start()
{
// 하루의 길이에 기반하여 timeRate를 계산하고, time을 초기화
timeRate = 1.0f / fullDayLength;
time = startTime;
}
void Update()
{
// 현재 시간, 색, 조명 등을 업데이트
time = (time + timeRate * Time.deltaTime) % 1.0f;
UpdateLighting(sun, sumColor, sunIntensity);
UpdateLighting(moon, moonColor, moonIntensity);
RenderSettings.ambientIntensity = lightingIntensityMultiplier.Evaluate(time);
RenderSettings.reflectionIntensity = reflectionIntensityMultiplier.Evaluate(time);
}
// 특정 조명 업데이트 함수
void UpdateLighting(Light lightSource, Gradient gradient, AnimationCurve intensityCurve)
{
float intensity = intensityCurve.Evaluate(time); // 현재 시간에 따른 밝기를 계산
// 태양은 time - 0.25f, 달은 time - 0.75f
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);
}
}
}
PlayerCondition.cs
public class PlayerCondition : MonoBehaviour, IDamageable
{
// 생략
public UICondition uiCondition;
Condition cold { get { return uiCondition.cold; } }
public float coldRecoveryRate; // 낮 동안 추위가 회복되는 속도
public float coldDecayRate; // 밤 동안 추위가 소모되는 속도
public event Action OnTakeDamage;
public DayNightCycle dayNightCycle; // DayNightCycle 클래스 참조
void Start()
{
// DayNightCycle가 null일때 찾아서 할당
if (dayNightCycle == null)
{
dayNightCycle = FindObjectOfType<DayNightCycle>();
}
}
void Update()
{
hunger.Subtract(hunger.regenRate * Time.deltaTime);
stamina.Add(stamina.regenRate * Time.deltaTime);
// 0.25 이상이고 0.75 이하인 경우 아침 = 아침이면 추위 회복됨
// Add함수는 Condition에 있습니다.
if (dayNightCycle.time >= 0.25f && dayNightCycle.time <= 0.75f)
{
cold.Add(coldRecoveryRate * Time.deltaTime);
}
// 밤이면 추위타서 깎이는데 0되면 체력에도 영향감
else
{
cold.Subtract(coldDecayRate * Time.deltaTime);
}
// 추위가 0이면 체력 깎임
if (hunger.curValue == 0f || cold.curValue == 0f)
{
health.Subtract(noHungerHealthDecay * Time.deltaTime);
}
if(health.curValue == 0f)
{
Die();
}
}
// 생략
}
추위에 관련된 코드 부분만 남겨봤다.
깃허브
이번 개인 프로젝트는 디자인에는 전혀 손대지않았지만 필요한 기능 구현에는 문제없이 해결돼서 만족스럽다.
코드가 궁금하신분들은 확인하셔요. 볼품없는 코드지만..
>> 깃허브
오늘의 회고
개인프로젝트.. 3D는 조금 어려운 감이 있었다.
원래는 x, y 값만 신경써주면 됐는데 z값 까지 있어서 조금 복잡해졌고 3D 멀미도 심한편이라 되게 고된 프로젝트였다.
그래도 선택요구사항 하나 빼고는 모두 구현해서 만족한다.
물론 야매로 해서 이게 맞나? 싶은것들도 있는데 그래도 나는 내가 이해한대로 내 길을 간다..
사실 오늘 특강에서 직렬화와 역직렬화에 대해서 배웠는데 이건 오늘 올리기엔 내 머리가 아직 잠시만요 하고있어서 내일이나 정리해서 올릴 것 같다.
튜터님이 PlayerPrefs랑 XML, Yaml, Json등을 어떻게 직렬화하고 어떻게 역직렬화하는지 직접 구현해서 보여주셨는데 어렵게 생각했던 개념을 생각보다 이해하기 쉽게 알려주셨다.
개념자체는 쉽고 그런데 응용은.. 노력.. 해봐야겠다..
반응형
'Record > TIL' 카테고리의 다른 글
[Unity] 유니티 이벤트와 액션, 구독 기능 (0) | 2024.06.03 |
---|---|
[Unity] Find 함수 장단점 (0) | 2024.05.31 |
[Unity] 플랫폼 발사대 (포물선으로 튕겨내기) (4) | 2024.05.29 |
[Unity] 티스토리 너 가만안둔다.. (4) | 2024.05.29 |
[Unity] AI 네비게이션 (2) | 2024.05.27 |