๐ Photon Fusion 2
๐ซ Memo
๐ซง NetworkRunner
- ํฌํค ๋งค๋์
- ํฌํค๊ณผ ๊ด๋ จ๋ ์ค์ , ์กฐ์์ ํ๊ธฐ ์ํ
- INetworkRunnerCallbacks
- ํฌํค ์ด๋ฒคํธ๋ฅผ ๋ฐ๊ธฐ ์ํ ์ธํฐํ์ด์ค, ๋งค๊ฐ๋ณ์์ runner๊ฐ ๋ค์ด๊ฐ
- runner.Spawn (๋คํธ์ํฌ Instantiate)
- runner.Despawn (๋คํธ์ํฌ Destroy)
๐ซง NetworkObject
- ๋๊ธฐํ ๋๊ธฐ ์ํ ๋ชจ๋ ์ค๋ธ์ ํธ๋ NetworkObject๊ฐ ๋ฌ๋ ค์์ด์ผ ํจ
- ํน๋ณํ ๊ธฐ๋ฅ์ ์๊ณ , ๋จ์ํ ๋คํธ์ํฌ ์์์ ๋๊ตฐ์ง ๊ตฌ๋ณํ๋ ID๋ฅผ ์ ๊ณตํ๋ ์ปดํฌ๋ํธ
๐ซง NetworkTransform
- Transform์ ๋๊ธฐํ ์ํค๋ Class
์ด๋ฅผ ์์ ๋ฐ์ผ๋ฉด ๋ง์ฐฌ๊ฐ์ง๋ก Transform์ ๋๊ธฐํ
- Interpolation
- ๋คํธ์ํฌ ์์ ์ด์ ๋ก ์์ง์์ด ๋๋ ๋๊ฒจ๋ณด์ด๋ ๊ฒ์ ๋ณด๊ฐ์์ผ์ฃผ๋
- ๋๋ฌธ์ ์ต์์/๋ถ๋ชจ ์ค๋ธ์ ํธ๊ฐ ์๋๋ผ, ์์ ์ค๋ธ์ ํธ(Mesh, Sprite ๋ฑ ์๊ฐ์ ์ธ ํํ)๋ฅผ ํ๊ฒ์ผ๋ก ์ง์ ํด์ค์ผ ํจ
๐ซง NetworkBehaviour
- FixedUpdateNetwork๋ฅผ ์ฌ์ฉํ ์ ์์
๐ซง FixedUpdateNetwork
- ์๋ฎฌ๋ ์ด์
ํฑ,
์์ธก
๊ณผ์ค์ ์ฐ์ฐ
, ์ฌ์์ธก ๋ฑ ํ ํ๋ ์์ ์ฌ๋ฌ ๋ฒ ์คํ ๋ ์ ์์ - Update, FixedUpdate ๋์ ์ฌ์ฉ
- (Update, FixedUpdate๋ ์ ๋ํฐ ์ด๋ฒคํธ๋๊น ์ฌ๋ฌ ๋ฒ ์คํ๋๋ฉด ์ด์ํ๋๊น)
GetInput(out ์ ๋ ฅ ๊ตฌ์กฐ์ฒด)๋ก ์ ๋ ฅ์ ๋ฐ์์ฌ ์ ์์
- Fusion2
- Proxies ๋ ์ด์ ๊ธฐ๋ณธ์ ์ผ๋ก FixedUpdateNetwork๋ฅผ ์คํํ์ง ์์
Runner.SetIsSimulated(Object, true)
๋ก ์ค์ ๊ฐ๋ฅ (Spawned์์ ์คํํ๋ ๊ฒ ๋ฒ ์คํธ)
๐ซง Runner.Spawn
onBeforeSpawned
์ Server/Host์์๋ง ๋์ํ๊ธฐ ๋๋ฌธ์, Network ์์ฑ์ ๋ณ๊ฒฝํ๋ ๊ฒ์ ์ธ ๊ฒ
๐ซง Spawned
if (Object.HasStateAuthority == false) return;
์ ํจ๊ป ์ด๋ค๋ฉด, VRChat์์ Start-IsMaster ๊ฐ์ด ๋ง์คํฐ(Host)๊ฐ ๋ฑ ํ ๋ฒ ์คํํ๋ ๋ช ๋ น ๊ฐ๋ฅ- ๊ฒ์ ์ํ, ์ค๋ธ์ ํธ ์ํ ์ด๊ธฐํ
๐ซง PlayerRef
- ํ๋ ์ด์ด๋ฅผ ๊ตฌ๋ถ ์ง๋
- NetworkObject Spawn ์, ์ด ์ค๋ธ์ ํธ์ ์
๋ ฅ ๊ถํ์ ๋๊ฐ ๊ฐ์ง์ง PlayerRef๋ก ์ค์ ๊ฐ๋ฅ
- NetworkBehaviour์ FixedUpdateNetwork, GetInput์์ ์ด๋ค ์ ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ง
๐ซง TickTimer
- ์ฒ์ ์์ฑ๋ ์๊ฐ ๊ธฐ์ค Timer
- TickTimer.CreateFromSeonds(Runner, ์๊ฐ)
FixedUpdateNetwork์์ timer.Expired(Runner)๋ก ์ฒดํฌํ๊ณ Despawn
- Awake๋ ๋คํธ์ํฌ๋ ๋๊ธฐํ ๋์ง์๊ธฐ ๋๋ฌธ์ Awake์์ ์ด๊ธฐํํ๋ฉด ์๋จ
- ์ค๋ธ์ ํธ ์์ฑ ์ ์ฝ๋ฐฑ ํจ์๋ก ์ด๊ธฐํํด์ผ ํจ (๊ทธ๋์ผ ์ฒ์ ์์ฑ๋ ๋ ๋๊ธฐํ)
๐ซง ๋ฌผ๋ฆฌ ์ฐ์ฐ
- Rigidbody, NetworkRigidbody
- ์ฑ๋ฅ ์์ ์ด์ ๋ก dll(์ด์ ๋ธ๋ฆฌ)๋ก
- NetworkTransform ๋ง์ฐฌ ๊ฐ์ง๋ก Interpolation
- NetworkTransform๋ฅผ ๋ถ์ด์ง ์์
- ์ฑ๋ฅ์ด ์์ข์์ ์ฌ์ฉ ์์
๐ซง ์ ๋ ฅ
- OnInput์ ํตํด ์
๋ ฅ์ ๋ฐ์ (INetworkRunnerCallbacks)
- INetworkInput์ ์์ ๋ฐ๋, ์ฌ์ฉ์ ์ ์ ์ ๋ ฅ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ฒด๋ฅผ ์ ์ํด์ผ ํจ (i.e. NetworkInputData)
- OnInput์์ ์
๋ ฅ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ฒด๋ฅผ ๋ง๋ค์ด ๊ฐ์ ์ค์ ํ๊ณ ,
input.Set(๊ตฌ์กฐ์ฒด);
๋ก ํ ๋น
์ ๋ ฅ์ ๋ฐ์์ฌ ๋๋ ์ด๋ฅผ ๋ฐ์์์ผ ํจ
- ์ ์ด๋ ๊ฒ ํ๋๋
- ์๋ฒ๊ฐ ์ด๋์ ์์ผ์ผ ํ๊ธฐ ๋๋ฌธ
- ๋คํธ์ํฌ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์๊ฐ ์ง์ฐ์ด ๋ฐ์ํ๋ค
- ํ ๋ช ์ด ๋ชจ๋ ๊ถํ์ ๊ฐ์ง๋ ์๋ฒ๊ฐ ๋๊ณ , ํด๋ผ๋ ์๋ฒ์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด ์๋ฒ๊ฐ ์ฒ๋ฆฌ๋ฅผ ํ๋๋ก ํ๋๋ฐ,
- ํด๋ผ๊ฐ ๊ณต๊ฒฉ ๋ฒํผ์ ๋๋ ๋ค
- ์๋ฒ์์ ์น์ธ์ ๋ฐ์์ผ ํ๋๋ฐ
- ๊ฐ๋๋ฐ 2ํฑ, ๋์์ค๋๋ฐ 2ํฑ -> 4ํฑ ํ์ ๊ณต๊ฒฉ ํ๋ ๊ฒ ๋ณด์ฌ์ง (์ง์ฐ)
- ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ์์ธก์ ์ฌ์ฉ
- 2ํฑ ์ ๋ ๊ฑธ๋ฆด๊ฑฐ๋ผ ์์ํ๊ณ 2ํฑ ์ดํ ๋ฏธ๋ฆฌ ๋ก์ปฌ๋ก ๊ณต๊ฒฉ
- ํด๋ผ๋ ์ด๋์ ๊ดํ ๊ถํ์ ์๊ณ , ์
๋ ฅ์ ๊ดํ ๊ถํ๋ง ์์
- ์๋ฒ๊ฐ ์ด๋ ์ํด
- ํด๋ผ๊ฐ ์ด๋ ์ํจ ๊ฒ์ ์์ธก
- ์๋ฒ๊ฐ ์ด๋์ ์์ผ์ผ ํ๊ธฐ ๋๋ฌธ
๐ซง ์์ธก
- ์๋ฅผ ๋ค์ด ์ด์์ด๋ ๊ณต
- ๋ชจ๋ ์ด๋์ ์๋ฒ๋ก ๊ฒ์ฆ ๋ฐ์ผ๋ฉด ๋๋ ๋๊ฒจ ๋ณด์ผ ๊ฒ
- ํ์ง๋ง ์์ผ๋ก ๊ณ์ํด์ ๊ฐ ๊ฒ ๊ฐ์ -> ๋๋ ์ด ๋งํผ ์์ธก
- ๋๋ ์ด ์ดํ ์๋ฒ๋ก๋ถํฐ ์ด๋ ๋ฐ์ดํฐ๊ฐ ๋์ฐฉํ ์ดํ ๋ค์ ๋ ๋๋ ์ด ๋งํผ ์์ธก, ๋ฐ๋ณต
- ์ฐธ๊ณ : ์์ธกํ ๋ ๋ง๋ค FixedUpdateNetwork๊ฐ ์คํ, FixedUpdateNetwork๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์์ธก
๐ซง NetworkBool
- ๋ด๋ถ์ ์ผ๋ก ์ด์ ๋ธ๋ฆฌ ๋ง๋ค ๋ถ ๋ฐ์ดํธ ํฌ๊ธฐ๊ฐ ๋ค๋ฅด๋ค?
- ํต์ ํ ๋ ๋ฐ์ดํธ ํฌ๊ธฐ๊ฐ ๋ค๋ฅด๋ฉด ๋ฌธ์ ๊ฐ ๋ ์ ์์ด์
- ํฌ๊ธฐ๊ฐ ๊ฐ์ ๊ฒ์ด ๋ณด์ฅ๋๋๋ก, NetworkBool
- ๋ค๋ฅธ ๋ฐ์ดํฐ๋ ์๊ด ์์
๐ซง Network ์ดํธ๋ฆฌ๋ทฐํธ
- ํ๋กํผํฐ ๋๊ธฐํ
- StateAuthority ํ๋ ์ด์ด ๊ธฐ์ค
- OnChanged = nameof(ํจ์ ์ด๋ฆ)
- FixedUpdateNetwork๋ ์์ธก, ์ค์ ์ฐ์ฐ, ์ฌ์์ธก ๋ฑ ์ฌ๋ฌ ๋ฒ ํธ์ถ ๋ ์ ์์
- OnChanged๋ ํ๋ ์ ๊ธฐ์ค์ผ๋ก ๋ณํ๋ฅผ ๊ฐ์ง
- ํ ํ๋ ์ ์ฌ์ด์ True, False, True๋ก ๋ณํํ๋ค๋ฉด, ํ ํ๋ ์ ์ฌ์ด์ ๊ฐ์ด ๋ณํํ์ง ์์์์ผ๋ก OnChanged๊ฐ ํธ์ถ๋์ง ์์
VRChat๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก, StateAuthority(VRChat์์ Owner)๊ฐ ์๋ ํ๋ ์ด์ด๊ฐ ๊ฐ์ ๋ณ๊ฒฝํ๋ฉด, ๋ก์ปฌ๋ก๋ง ๋์ํ๊ณ , ์ธ์ ๋ ์ง StateAuthority(Owner)์ ๊ฐ์ผ๋ก ๋๊ธฐํ ๋ ์ ์์
- Fusion 2
- ํ๋กํผํฐ์ Get/Set์ ์ปค์คํ ์ฝ๋๋ก ๋์ ํ๊ธฐ ๋๋ฌธ์, Get/Set์ ๊ธฐ์ค์ผ๋ก ๋ณํ๋ฅผ ๊ฐ์งํ๋ฉด ์๋๊ณ , ๋ณ๋์ Setter ๊ตฌํ๋ ๋ก์ปฌ๋ก๋ง ๋์ํจ
Spawned
์์ChangeDetector
๋ณ์์GetChangeDetector(ChangeDetector.Scoure.SimulationState)
๋ฅผ ํ ๋นํ๊ณ ,Render
์์ ์๋์ ๊ฐ์ด ๋ณํ๋ฅผ ๊ฐ์ง
1
2
3
4
5
6
7
8
9
10
11
12
public override void Render()
{
foreach (var change in _changeDetector.DetectChanges(this))
{
switch (change)
{
case nameof(๋ณ์):
// ๋ณํ ์ ์ํํ ๋ช
๋ น
break;
}
}
}
- ์ด๋ฌํ ๋์์ ์ฌ๋ฌ ๋ฒ ์คํ๋ ์ ์๊ณ (์์ธก ์ดํ ํ๋ฆฐ ์์ธก์ ๊ณ ์น๋ ค๊ณ ํ ๋ฒ ๋ ์คํ๋๋ค๋์ง), ์คํต ๋ ์ ์๊ณ (๋ฐ์ดํฐ๊ฐ ๋๋ฌํ๊ธฐ๋ ์ฑ ์ ์ ์๋ ๊ฐ์ผ๋ก ๋์์จ๋ค๋์ง), ๋๋ฝ๋ ์ ์์ (Packet Drop)
RPC๋ณด๋ค ๋น ๋ฅธ ์์ ์ ๋ณํ๋ฅผ ๊ฐ์งํ ์ ์์ (๊ฐ์ด ๋ณํํ ๋คํธ์ํฌ Tick ์ดํ ๋ฐ๋ก)
- Spawned๊ฐ ์คํ๋๋ ์์ ์๋ ์ด๋ฏธ Network ์ดํธ๋ฆฌ๋ทฐํธ๊ฐ ๋ถ์ ์์ฑ๋ค์ด ๋ชจ๋ ๋๊ธฐํ ๋ ์ดํ
๐ซง Render
- ์๊ฐ์ ์ธ ๊ณ์ฐ์ Render์์ Like LateUpdate
- FixedUpdateNetwork๋ ์์ธก, ์ค์ ์ฐ์ฐ, ์ฌ์์ธก ๋ฑ ์ฌ๋ฌ ๋ฒ ํธ์ถ ๋ ์ ์๊ธฐ ๋๋ฌธ์, ๋คํธ์ํฌ๊ฐ ํ์์๋ ์๊ฐ ์ ์ธ ์ฐ์ฐ์ ์ค๋ณต ์ฐ์ฐ์ผ๋ก ์์ ๋ญ๋น๊ฐ ๋ ์ ์์
๐ซง Remote Procedure Calls, RPC
- ์๊ฒฉ Procedure/ํจ์ ์ฝ
- ์๊ฒฉํ๊ฒ ๋๊ธฐํ ๋์ง ์์, ํฑ๋ ์ฌ์ฉ ์ํจ
- ์ง์ฐ๋๊ฑฐ๋, ๋ก์ค, ์์ค๋ ์ ์์
- Update์์ ๊ทธ๋ฅ ๋ณด๋
if (Input && Object.HasInputAuthority) RPC_SendMessage("Sans");
- ํฌ๊ฒ ์ค์ํ์ง ์์ ๊ฒ, Like ํ์ค ๊ฐ์ ํํ
๐ซง ETC
- ์๋ ํธ์คํธ ๋ชจ๋
- Shared Mode : ๊ฐ์ ์ด๋ ๊ถํ์ ๊ฐ์ง
- Predictive Spawn : ํด๋ผ์์ Spawning๋ ์์ธก
- Lag Compensation : ์ง์ฐ ๋ณด์, ํด๋ผ ๊ธฐ์กด์ผ๋ก ํ์ (ํต ๋ฌธ์ )
- Area Of Interest : Interest Area์ ์์ง ์๋ ์ค๋ธ์ ํธ๋ ๋๊ธฐํํ์ง ์๋
์ด ๊ธฐ์ฌ๋ ์ ์๊ถ์์ CC BY 4.0 ๋ผ์ด์ผ์ค๋ฅผ ๋ฐ๋ฆ
๋๋ค.