TickTimer
소개
특정 로직을 트리거하기 전에 일정 시간 동안 기다리는 것이 유용한 경우가 많습니다. TickTimer
는 Fusion에서 안전하고 편리하며 대역폭에 효율적인 방법입니다. TickTimer
는 이름에도 불구하고 타이머가 아니라 목표 틱 값을 저장하고 현재 시뮬레이션 틱을 이용하여 검사를 실행하는 구조체입니다.
TickTimer
는 현재 틱(NetworkRunner
에서)과 대상 틱(TickTimer
을 초기화 할 때 저장)을 사용하여 다른 타이머와 동일한 정보를 제공하고 다음과 같은 질문을 관리할 수 있습니다.
- 타이머가 만료되었나요?
- 타이머가 작동하나요?
- 틱은 얼마나 남았나요?
TickTimer
는 부동소수점 또는 정수형을 증가시키거나 감소하는 대신 대상 틱을 사용하기 때문에 변경되지 않고 타이머 로직이 로컬이기 때문에 [Networked]
게임 상태의 일부로 포함될 때 대역폭을 덜 사용합니다.
노트: TickTimer
는 TickTimer.CreateFromSeconds()
로 초기화할 때도 대상 틱을 사용합니다. 이것과 틱 속도를 염두에 두고 계산된 대상 틱은 경과된 초에 따라 약간의 정확도를 잃을 수 있습니다. 예, TickTimer.CreateFromSeconds(1.37f)
.
API
CreateFromSeconds
: 제공된 Seconds 의 양과 현재 시뮬레이션 틱을 사용하여 계산된 대상 틱과 함께 새TickTimer
를 리턴합니다.CreateFromTicks
: 제공된 Ticks 의 양과 현재 시뮬레이션 틱을 사용하여 계산된 대상 틱과 함께 새TickTimer
를 리턴합니다.RemainingTime
:TickTimer
가 만료될 때까지 남은 시간 Seconds 를 리턴합니다.RemainingTicks
:TickTimer
가 만료될 때까지 Ticks 의 남은 시간을 리턴합니다.IsRunning
:TickTimer
대상 틱이 현재 시뮬레이션 틱보다 클 경우 true를 반환합니다.Expired
:TickTimer
가 실행 중이고 대상 틱이 현재 시뮬레이션 틱보다 작거나 같으면 true를 반환합니다.ExpiredOrNotRunning
:TickTimer
가default
,TickTimer.None
인 경우 또는 실행 중이며 대상 틱이 현재 시뮬레이션 틱보다 작거나 같으면 true를 반환합니다
TickTimer 리셋
시뮬레이션 틱이 저장된 대상 틱보다 커진 이후 에는 모든 틱에 대해 TickTimer
가 만료되었다는 것에 대해 true를 반환합니다. 이 값을 한 번만 가져오려면 이 조건이 참으로 평가되는 첫 번째 틱 후에 TickTimer
를 재설정하는 것이 유용합니다. 이 작업은 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
의 사용자 지정 및 단순화된 버전입니다.
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 사이의 정규화된 부동소수점을 리턴하려면 경과된 틱 수를 타이머가 카운트하는 총 틱 수로 나눕니다.
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