Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | ||||||
| 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 9 | 10 | 11 | 12 | 13 | 14 | 15 |
| 16 | 17 | 18 | 19 | 20 | 21 | 22 |
| 23 | 24 | 25 | 26 | 27 | 28 | 29 |
| 30 | 31 |
Tags
- 블렌더도넛
- 자바스크립트
- 블렌더튜토리얼
- csharp
- cs기초
- blender4.0
- level1
- 도넛튜토리얼
- 3d모델링
- 백준
- 비트연산
- blender
- 알고리즘
- 카드뉴스
- 프로그래머스
- Photoshop
- boj
- 단계별문제풀이
- AI
- 포토샵
- Python
- 단계별로 풀어보기
- leetcode
- 코딩테스트
- 블렌더
- c언어
- 3d스터디
- 파이썬
- CS
- 3D그래픽
Archives
- Today
- Total
슬로우도파민
유니티에서 시간 측정하기 2 - DateTime 본문
유니티에서 시간 측정하기 1 에서 다룬 4가지 방법은 '게임이 켜져 있는 동안' 작동하는 유니티 엔진 내부의 시계라면,
DateTime은 C#에서 제공하는 기능으로 '현실 세계의 실제 시계'를 사용하는 방식입니다.
모바일 게임, 특히 방치형 게임이나 소셜 게임에서는 이 System.DateTime 이 타이머 구현에 절대 빠질 수 없는 핵심입니다.
언제 DateTime을 타이머로 사용하나요?
게임 내부 연산(Time.deltaTime)으로는 감당할 수 없는 장기적인 시간이나, 앱이 꺼져 있을 때도 흘러가야하는 시간을 측정할 때 쓰입니다.
- 행동력(스태미나) 회복: "하트가 1개 차오르는데 5분 대기"
- 건축물/업그레이드 타이머: "마을 회관 레벨업까지 24시간 소요"
- 일일 보상 초기화: "매일 밤 12시에 출석체크 및 일일 퀘스트 초기화"
- 오프라인 보상: 앱을 완전히 끄고(강제 종료) 며칠 뒤에 접속해도 경과한 시간을 계산할 때
DateTime 타이머 구현의 핵심 원리
DateTime을 사용할 때는 매 프레임 시간을 빼는 것이 아니라, '완료 목표 시간'을 기록해 두고 현재 시간과 지속해서 비교하는 방식을 사용합니다.
DateTime 간의 차이를 계산할 때는 TimeSpan 이라는 구조체를 사용하면 매우 편리합니다.
using System;
using UnityEngine;
public class DateTimeTimer : MonoBehaviour
{
private DateTime targetTime;
void Start()
{
// 예: 지금(DateTiem.Now)으로부터 2시간 뒤를 완료 시간으로 설정
targetTime = DateTime.Now.AddHours(2);
// 실제 게임에서는 앱을 꺼도 날아가지 않게 이 targetTime을 PlayerPrefs나 서버에 저장해둡니다.
}
void Update()
{
// 목표 시간에서 현재 시간을 빼서 남은 시간(TimeSpan)을 계산
TimeSpan timeLeft = targetTime - DateTime.Now;
// TotalSeconds(총 남은 초)가 0보다 크면 아직 시간이 남은 것
if (timeLeft.TotalSeconds > 0)
{
// 남은 시간을 00시간 00분 00초 포맷으로 UI에 표시하기 좋음
string timerText = $"{timeLeft.Hours}시간 {timeLeft.Minutes}분 {timeLeft.Seconds}초 남음";
// 예: myTextUI.text = timerText;
}
else
{
Debug.Log("건축 완료! / 하트 충전 완료");
// 완료 후 Update에서 더 이상 체크하지 않도록 스크립트를 끄거나 상태를 변경해야 합니다.
}
}
}
DateTime 사용 시 주의해야 할 2가지
- 저장 방식의 한계:
DateTime 객체 자체는 유니티의 기본 로컬 저장소인 PlayerPrefs 에 바로 저장할 수 없습니다. 따라서 .ToString() 을 이용해 문자열(String)로 변환해서 저장하거나, .Ticks 를 이용해 긴 숫자(long) 형태로 변환하여 저장한 뒤 불러올 때 다시 DateTime 으로 파싱(변환)해야 합니다. - 치명적인 약점 (기기 시간 조작):
DateTime.Now 는 스마트폰 기기에 설정된 시계를 기준으로 합니다. 즉, 유저가 게임을 끄고 스마트폰 설정에서 날짜를 내일로 바꾸고 들어오면 24시간 짜리 타이머가 즉시 완료되어 버립니다. (이른바 '타임슬립' 어뷰징).
경쟁이 없는 싱글 패키지 게임이라면 상관없지만, 재화와 직결되는 게임이라면 기기 시간이 아닌 인터넷 서버 시간(NTP)을 받아와서 비교해야 합니다.
