TickTimer
소개
특정 로직을 트리거 하기 전에 일정 시간 동안 대기하는 것이 유용할 때가 많습니다. TickTimer
는 Fusion에서 이를 안전하고, 편리하며, 대역폭 효율적으로 처리할 수 있는 방법을 제공합니다. 이름과 달리, TickTimer
는 실제 타이머가 아니라 대상 틱 값을 저장하고 현재 시뮬레이션 틱을 사용하여 검사를 수행하는 구조체입니다.
TickTimer
는 현재 틱(NetworkRunner
에서 제공)과 초기화 시 저장된 대상 틱을 사용하여 일반적인 타이머와 유사하게 작동하며 다음과 같은 질문에 답할 수 있습니다:
- 타이머가 만료되었습니까?
- 타이머가 실행 중입니까?
- 얼마나 많은 시간(틱)이 남아 있습니까?
TickTimer
는 float 또는 int 값을 증가/감소시키는 대신 대상 틱을 사용하므로 네트워크 상태에서 [Networked]
속성으로 포함될 때 변경되지 않아 대역폭을 절약할 수 있습니다.
참고: TickTimer.CreateFromSeconds()
로 초기화할 때도 TickTimer
는 대상 틱을 사용합니다. 이와 틱 속도를 고려할 때, 예를 들어 TickTimer.CreateFromSeconds(1.37f)
와 같이 초 단위로 생성된 경우, 계산된 대상 틱이 약간의 정확도를 잃을 수 있습니다.
API
CreateFromSeconds
: 제공된 초 값을 사용하여 대상 틱을 계산하고 새로운TickTimer
를 반환합니다.CreateFromTicks
: 제공된 틱(ticks) 값을 사용하여 대상 틱을 계산하고 새로운TickTimer
를 반환합니다.RemainingTime
:TickTimer
가 만료될 때까지 남은 시간을 초 단위로 반환합니다.RemainingTicks
:TickTimer
가 만료될 때까지 남은 시간을 틱 단위로 반환합니다.IsRunning
: 현재 시뮬레이션 틱보다 대상 틱이 크면 true를 반환합니다.Expired
:TickTimer
가 실행 중이며, 대상 틱이 현재 시뮬레이션 틱보다 작거나 같은 경우 true를 반환합니다.ExpiredOrNotRunning
:TickTimer
가default
,TickTimer.None
이거나 실행 중이며 대상 틱이 현재 시뮬레이션 틱보다 작거나 같은 경우 true를 반환 합니다.
TickTimer 재설정
TickTimer
는 대상 틱을 초과한 시뮬레이션 틱 이후 매 틱마다 만료 상태를 true로 반환합니다. 이를 한 번만 얻으려면 조건이 true로 평가된 첫 번째 틱에서 TickTimer
를 재설정하는 것이 유용합니다. 이는 TickTimer.None
또는 default
로 설정하여 수행할 수 있습니다.
C#
[Networked] TickTimer timer { get; set; }
void FixedUpdateNetwork()
{
if (timer.Expired(Runner))
{
// Execute Logic
// Reset timer
timer = TickTimer.None;
// alternatively: timer = default.
Debug.Log("Timer Expired");
}
}
사용자 정의 기능 생성
TickTimer
의 간단한 특성 덕분에 사용자 정의 버전을 만들어 더 많은 또는 다른 기능을 구현할 수 있습니다. 아래 예제에서는 타이머가 생성된 이후 경과된 틱을 계산하고 정규화된 값을 반환하는 기능을 추가한 간단한 사용자 정의 TickTimer
를 보여줍니다.
참고: 다음 코드는 사용자 정의 기능을 보여주기 위한 간단한 버전의 TickTimer
입니다.
C#
public struct CustomTickTimer : INetworkStruct
{
private int _target;
private int _initialTick;
public bool Expired(NetworkRunner runner) => runner.IsRunning && _target > 0
&& (Tick) _target <= runner.Simulation.Tick;
public bool IsRunning => _target > 0;
public static CustomTickTimer CreateFromTicks(NetworkRunner runner, int ticks)
{
if (runner == false || runner.IsRunning == false)
return new CustomTickTimer();
CustomTickTimer fromTicks = new CustomTickTimer();
fromTicks._target = (int) runner.Simulation.Tick + ticks;
fromTicks._initialTick = runner.Simulation.Tick;
return fromTicks;
}
public float NormalizedValue(NetworkRunner runner)
{
if (runner == null || runner.IsRunning == false || IsRunning == false)
return 0;
if (Expired(runner))
return 1;
return ElapsedTicks(runner) / (_target - (float)_initialTick);
}
public int ElapsedTicks(NetworkRunner runner)
{
if (runner == false || runner.IsRunning == false)
return 0;
if (IsRunning == false || Expired(runner))
return 0;
return runner.Simulation.Tick - _initialTick;
}
}
경과된 틱 계산
타이머가 생성된 이후 경과된 틱 수를 가져오려면 초기 틱 값을 NetworkRunner
의 현재 틱에서 빼십시오.
C#
public int ElapsedTicks(NetworkRunner runner)
{
if (runner == false || runner.IsRunning == false)
return 0;
if (IsRunning == false || Expired(runner))
return 0;
return runner.Simulation.Tick - _initialTick;
}
0에서 1 사이의 정규화된 값
타이머의 현재 진행 상황에 대한 0에서 1 사이의 정규화된 float 값을 반환하려면, 경과된 틱 수를 타이머가 계산 중인 총 틱 수로 나누십시오.
C#
public float NormalizedValue(NetworkRunner runner)
{
if (runner == null || runner.IsRunning == false || IsRunning == false)
return 0;
if (Expired(runner))
return 1;
return ElapsedTicks(runner) / (_target - (float)_initialTick);
}
이제, CustomTickTimer
를 사용하여 위 값을 표시할 수 있습니다.
C#
[Networked]
public CustomTickTimer MyTickTimer { get; set; }
public void StartTimer()
{
if (Runner.IsServer)
{
MyTickTimer = CustomTickTimer.CreateFromTicks(Runner, 120);
}
}
public override void FixedUpdateNetwork()
{
Debug.Log($"Elapsed {MyTickTimer.ElapsedTicks(Runner)} ticks.");
Debug.Log($"Normalized Value {MyTickTimer.NormalizedValue(Runner)}.");
if (MyTickTimer.Expired(Runner))
{
// Execute Logic
// Reset timer
MyTickTimer = default;
Debug.Log("Timer Finished on tick: " + Runner.Simulation.Tick);
}
}
Back to top