ãã°ããåã«ãUnite Asiaã«ã³ãã¡ã¬ã³ã¹ã§ãUnityéçºè
åãã®æ°ãããã«ããã¬ã€ã€ãŒããŒã«ããã¯ãããžãŒããµãŒãã¹ã®éçºãçºè¡šããŸããã ãã®ãããžã§ã¯ãã®å
éšåã¯UNETã§ãããããã¯åã«Unity Networkingãæå³ããŸãã ããããç§ãã¡ã®èšç»ã¯åçŽãªãããã¯ãŒã¯ãã¯ããã«è¶
ããŠããŸãã ãåç¥ã®ãšãããUnityã®äž»ãªç®æšã¯ãã²ãŒã éçºããã»ã¹ãæ°äž»åããããšã§ãã Unity NetworkingããŒã ã¯ããã«ããã¬ã€ã€ãŒã²ãŒã ã®éçºãæ°äž»åããããšèããŠããŸãã ãã¹ãŠã®ã²ãŒã éçºè
ããããããã¿ã€ãã®ãã«ããã¬ã€ã€ãŒã²ãŒã ãä»»æã®æ°ã®ãã¬ãŒã€ãŒã§éçºã§ããããã«ããããšèããŠããŸãã ãã¡ãããããã¯æãç°¡åãªã¿ã¹ã¯ã§ã¯ãããŸããããéå»ã«ãã¹ãŠè§£æ±ºããŠãããæ¬åœã«ããçŽããããšæã£ãŠããŸãïŒæ¬åœã«ã¯ãŒã«ã ããã§ãïŒïŒã ç§ãã¡ã¯ãå
±éã®ç®æšãããã€ãã®ãã§ãŒãºã«åå²ããããšã«ããŸããããããã®ãã§ãŒãºã¯ãUnityéçºè
ã«ãªãã¿ãããã¯ãã§ãã ãã®ã¢ãããŒãã«åŸã£ãŠããã§ãŒãº1ããªãªãŒã¹ãããŠãŒã¶ãŒãã£ãŒãããã¯ãååŸããäœæ¥äžã«ããããæ€èšããŠã次ã®ãã§ãŒãºãããã«æ¹åãããã®ãµã€ã¯ã«ãç¹°ãè¿ããŸãã UNETã®å Žåããã§ãŒãº1ã¯Multiplayer FoundationãšåŒã°ãããã®ã«ãªããŸããããã«ã€ããŠã¯åŸã§èª¬æããŸãã ãã§ãŒãº2ã¯ããã§ãŒãº1ã«åºã¥ããŠæ§ç¯ããã以äžã®èšäºã§ã·ãã¥ã¬ãŒã·ã§ã³ãµãŒããŒãšåŒã°ãããµãŒããŒäžã§æ¿èªãããã²ãŒã ãäœæããããã®æè¡ãæäŸããŸãã ãã§ãŒãº3ã§ã¯ããã¹ã¿ãŒã·ãã¥ã¬ãŒã·ã§ã³ãµãŒããŒã·ã¹ãã ã䜿çšããŠè€æ°ã®ã·ãã¥ã¬ãŒã·ã§ã³ãµãŒããŒã調æŽããæ©èœãè¿œå ããŸãã ãã€ãã®ããã«ãç¹ã«ãŠãŒã¶ãŒããã®ãã£ãŒãããã¯ã®éãŸããèãããšãæ£ç¢ºãªãªãªãŒã¹æ¥ãæå®ããããšã¯äžå¯èœã§ãã ãããããã§ãŒãº1ã¯5.xãªãªãŒã¹ãµã€ã¯ã«ã®äžéšã§ããããã§ãŒãº2ã¯çŸåšç 究段éã«ãããšèšããŸãã

Unityã«åå ããåã¯ããããã¯ãŒã¯ããŒã ã®ã¡ã³ããŒã¯äž»ã«ãŠã«ãã£ããªã³ã©ã€ã³ãããŒããªãã¶ãªã³ã°ãªã³ã©ã€ã³ããã³ãžã§ã³ãºã¢ã³ããã©ãŽã³ãºãªã³ã©ã€ã³ãããŒãã«ããŒããŒãºãããŒããã©ãŒã¹ããŒããªã³ã©ã€ã³ãã¯ãŒã«ããªããŠã©ãŒã¯ã©ãããªã©ã®MMOãæ
åœããŠããŸããã ãã«ããã¬ã€ã€ãŒã²ãŒã ããã¯ãããžãŒãã€ã³ãã©ã¹ãã©ã¯ãã£ã®äœæã«ã¯å€ãã®ç±æãšè±å¯ãªçµéšããããŸãã Unityã®äœ¿åœã¯ç§ãã¡å
šå¡ã«ç¥ãããŠãããåžžã«éåžžã«é
åçã§ããã ãã«ããã¬ã€ã€ãŒã®åéã§ãã®å€¢ãå®çŸãããªã©ãæ¬åœã«çŽ æŽãããããšãããæ©äŒãæåŠããããšã¯ã§ããŸããã§ããã ããã§ç§ãã¡ã¯ä»¥åã®ä»äºãèŸããUnityã«åå ããŠãã®å€¢ãå®çŸããŸããã 誰ãããã«ããã¬ã€ã€ãŒã²ãŒã ã®å€¢ãå®çŸã§ããããã«ãçŸåšãããã®ããŒã«ããã¯ãããžãŒããµãŒãã¹ã«äžçæžåœåãçµãã§ããŸãã
ã§ã¯ããã§ãŒãº1ã®ãã«ããã¬ã€ã€ãŒè²¡å£ã¯ã©ãããæå³ã§ããïŒ äž»ãªéšåã¯æ¬¡ã®ãšããã§ãã
-ãã¹ãŠã®ã¿ã€ãã®ã²ãŒã ããµããŒãããé«æ§èœUDPããŒã¹ã®ãã©ã³ã¹ããŒããããã³ã«
-äœã¬ãã«APIïŒäœã¬ãã«API-LLAPIïŒããœã±ããã®ãããªã€ã³ã¿ãŒãã§ãŒã¹ãä»ããå®å
šãªå¶åŸ¡ãæäŸ
-ã·ã³ãã«ã§å®å
šãªã¯ã©ã€ã¢ã³ã/ãµãŒããŒã¢ãã«ãæäŸããé«ã¬ãã«APIïŒHLAPIïŒ
-ãããã¡ãŒã«ãŒãµãŒãã¹ãéšå±ãäœæãããã¬ã€ã€ãŒããäºããèŠã€ããããããã«ããåºæ¬çãªæ©èœãæäŸããŸãã
-ãªã¬ãŒãµãŒããŒããã¡ã€ã¢ãŠã©ãŒã«ãä»ããŠæ¥ç¶ããããšãããã¬ã€ã€ãŒéã®éä¿¡ã®åé¡ã解決
æŽå²çã«ç¢ºç«ãããå¶éãšå£®å€§ãªç®æšãèãããšããŒãããå§ããªããã°ãªããªãããšãæããã«ãªããŸããã ãã¹ãŠã®çš®é¡ã®ã²ãŒã ãšä»»æã®æ°ã®æ¥ç¶ããµããŒãããããšãç®æšã ã£ããããUDPã«åºã¥ãæ°ããé«æ§èœãã©ã³ã¹ããŒãã¬ã€ã€ãŒããå§ããŸããã å€ãã®ã²ãŒã ã«ã¯ååãªTCPããããŸãããTCPã¯æåŸã®ãã±ãããé äžåã§å°çãããšé
延ãããããé«éã®ã²ãŒã ã«ã¯äŸç¶ãšããŠUDPãå¿
èŠã§ãã
ãã®æ°ãããã©ã³ã¹ããŒãå±€ã«åºã¥ããŠã2ã€ã®APIãæ§ç¯ããŸããã é«ã¬ãã«APIïŒHLAPIïŒã¯ãã·ã³ãã«ã§å®å
šãªã¯ã©ã€ã¢ã³ããµãŒããŒã¢ãã«ãæäŸããŸãã ããªãããããã¯ãŒã¯ãšã³ãžãã¢ã§ã¯ãªãããã«ããã¬ã€ã€ãŒã²ãŒã ãäœãããã ããªããHLAPIã«èå³ãããã§ãããã
ãŸããå€ãã·ã¹ãã ã®ã¬ãã¥ãŒãèæ
®ããŸãããäžéšã®ãŠãŒã¶ãŒã¯ããã詳现ãªå¶åŸ¡ã®ããã«äœã¬ãã«ã®ã¢ã¯ã»ã¹ãååŸããããšèããŸããã çŸåšããã©ã³ã¹ããŒãå±€ã«ãããœã±ããã«äŒŒãã€ã³ã¿ãŒãã§ãŒã¹ãæäŸããäœã¬ãã«ã®äœã¬ãã«APIïŒLLAPIïŒããããŸãã ãããã¯ãŒã¯ãšã³ãžãã¢ã§ãããç¬èªã®ãããã¯ãŒã¯ã¢ãã«ãæ§ç¯ãããããããã¯ãŒã¯ããã©ãŒãã³ã¹ã埮調æŽãããå Žåã¯ãLLAPIã圹ç«ã¡ãŸãã
ãããã¡ã€ã«ãŒã®ãããã¡ã€ãã³ã°ãµãŒãã¹ã¯ããã«ããã¬ã€ã€ãŒã²ãŒã ã§ã«ãŒã ãèšå®ãããã¬ã€ã€ãŒããäºããèŠã€ããããããã«ããããã«äœ¿çšãããŸãã Relay Serverã¯ããã¬ãŒã€ãŒãåžžã«çžäºã«æ¥ç¶ã§ããããã«ããŸãã
ç§ãã¡èªèº«ã®çµéšããããã«ããã¬ã€ã€ãŒã²ãŒã ã®äœæã«ã¯å€ãã®èŠçã䌎ãããšãããããŸããã Multiplayer Foundationã¯ããã«ããã¬ã€ã€ãŒã²ãŒã ãç°¡åã«äœæããããã®ã䜿ãããããããã§ãã·ã§ãã«ãããã¯ãŒãã³ã°ãã¯ãããžãŒãããŒã«ãããã³ã€ã³ãã©ã¹ãã©ã¯ãã£ã®æ°ããã»ããã§ãã ãã«ããã¬ã€ã€ãŒã²ãŒã ãäœæããã«ã¯ããããã¯ãŒã¯ãšãããã³ã«ã«ã€ããŠã®ååãªç¥èãå¿
èŠã§ãããšèšããŸãã èŠããã»ã©æ¥ãªåŠç¿æ²ç·ãèªåã§å
æãããããããã¯ãŒã¯ãšã³ãžãã¢ãæ¢ããŠããŸãã ãããçµãŠããã¬ã€ã€ãŒã«ãäºããæ€çŽ¢ããæ段ãæäŸãããšããåé¡ã解決ããå¿
èŠããããŸãã ãã®åé¡ã解決ãããããã¬ãŒã€ãŒãäºãã«æ¥ç¶ããèœåãæäŸããããšã«å¯ŸåŠããå¿
èŠããããŸããããã¯ãNATãã¡ã€ã¢ãŠã©ãŒã«ã®èåŸã«ããå Žåã¯éåžžã«å°é£ã§ãã ããããã¹ãŠã«å¯ŸåŠããã«ã¯ãé©åãªãµã€ãºã®ã€ã³ãã©ã¹ãã©ã¯ãã£ãäœæããå¿
èŠããããŸãããããã¯ç¹ã«å¿«é©ã§ã¯ãªããã²ãŒã éçºãšã¯é¢ä¿ãããŸããã ãã®åŸãã€ã³ãã©ã¹ãã©ã¯ãã£ãåçã«ã¹ã±ãŒãªã³ã°ããããšãæ€èšããå¿
èŠããããŸããéåžžããã®æ£ããå®è£
ã«ã¯ããçšåºŠã®çµéšãå¿
èŠã§ãã
ãã§ãŒãº1ã¯ãããããã¹ãŠã®çã¿ã䌎ãåé¡ããããªããæããŸãã HLAPIã«ããããããã¯ãŒã¯ãã¯ãããžãŒãæ·±ãç解ããå¿
èŠããªããªããŸãã ãã ãããããã¯ãŒã¯ãšã³ãžãã¢ã§ããããã¹ãŠãç¬èªã®æ¹æ³ã§å®è¡ãããå Žåã¯ãLLAPIããã€ã§ãå©çšã§ããŸãã 仲人ã¯ããã¬ã€ã€ãŒã«ãäºããèŠã€ããæ©äŒãæäŸããããšã§ããªãã®åé¡ã解決ããŸãã Relay Serverã¯ããã¬ã€ã€ãŒã«çã«çžäºæ¥ç¶ããèœåãæäŸãããšããåé¡ã解決ããŸãã ãŸããå¿
èŠãªã€ã³ãã©ã¹ãã©ã¯ãã£ã®æ§ç¯ãšãã®åçãªã¹ã±ãŒãªã³ã°ã®åé¡ã解決ããŸãã ãããã¡ãŒã«ãŒãšãªã¬ãŒãµãŒããŒã¯ãUnity Multiplayer Cloudã«ååšããŸãã ãããã£ãŠãç©çãµãŒããŒã ãã§ãªããããã»ã¹ãéèŠã«å¿ããŠã¹ã±ãŒãªã³ã°ãããŸãã
é«ã¬ãã«API UNETããã³SyncVar
ã¯ããã«ãšèŠä»¶
ããã€ãã®èæ¯æ
å ±ã ãããã¯ãŒã¯ã²ãŒã ã§ã¯ããªããžã§ã¯ããææãããµãŒããŒãšããããã®ãªããžã§ã¯ãã®ããŒã¿ãå€æŽãããããšãéç¥ããå¿
èŠãããã¯ã©ã€ã¢ã³ãã䜿çšããããšãäžè¬çã§ãã ããšãã°ãæŠéã²ãŒã ã§ã¯ããã¬ãŒã€ãŒã®äººçã¯ãã¹ãŠã®ãã¬ãŒã€ãŒã«èŠããã¯ãã§ãã ããã«ã¯ãã¹ã¯ãªããã¯ã©ã¹ã®ã¡ã³ããŒå€æ°ãå¿
èŠã§ãããã®å€æ°ã¯ããµãŒããŒäžã§å€æŽããããšãã¹ãŠã®ã¯ã©ã€ã¢ã³ãã«éä¿¡ãããŸãã ç°¡åãªæŠéã¯ã©ã¹ã®äŸã次ã«ç€ºããŸãã
class Combat : MonoBehaviour { public int Health; public bool Alive; public void TakeDamage(int amount) { if (amount >= Health) { Alive = false; Health = 0; } else { Health -= amount; } } }
ãµãŒããŒäžã®ãã¬ã€ã€ãŒããã¡ãŒãžãåããå Žåããã¹ãŠã®ãã¬ã€ã€ãŒã«ãã®ãã¬ã€ã€ãŒã®æ°ããã©ã€ãå€ãéç¥ããå¿
èŠããããŸãã
åçŽã«æããŸãããCPUãã¡ã¢ãªã垯åå¹
ã®ç¹ã§å¹ççã§ãéçºè
ã䜿çšããããã¹ãŠã®ã¿ã€ãããµããŒãããã®ã«ååãªæè»æ§ãåããã³ãŒããäœæããéçºè
ã«ã·ã¹ãã ãèŠããªãããããšãå°é£ã§ãã ãããã£ãŠããã®ã·ã¹ãã ã®å
·äœçãªç®æšã¯æ¬¡ã®ãšããã§ãã
1.å€æ°ã®ã·ã£ããŠã³ããŒãä¿åããªãããšã«ãããã¡ã¢ãªäœ¿çšéãæå°éã«æãã
2.å®éã«å€æŽãããç¶æ
ã®ã¿ãéä¿¡ããããšã«ããã垯åå¹
ã®äœ¿çšãæå°éã«æããŸãïŒå¢åæŽæ°ïŒ
3.ç¶æ
ãå€åãããã©ãããåžžã«ç¢ºèªããªãããšã§ãCPU䜿çšçãæå°éã«æããŸã
4.éçºè
ã«ã·ãªã¢ã«åé¢æ°ãæåã§äœæãããããšãªãããããã³ã«ãšã·ãªã¢ã«åã®ççŸãæå°éã«æãã
5.éçºè
ãå€æ°ãçŽæ¥ããŒãã£ãšããŠãã©ã°ããããšãèŠæ±ããªã
6. UnityããµããŒããããã¹ãŠã®ããã°ã©ãã³ã°èšèªã§äœæ¥ãã
7.çŸåšã®éçºããã»ã¹ãäžæããªãã§ãã ãã
8.éçºè
ãã·ã¹ãã ã䜿çšããããã«å¿
èŠãªæåã®æé ãå
¥åããªãã§ãã ãã
9.ã¡ã¿ããŒã¿ïŒã«ã¹ã¿ã å±æ§ïŒã«ãã£ãŠã·ã¹ãã ãã¬ã€ãã§ããããã«ããŸã
10.åçŽåãšè€ååã®äž¡æ¹ãåŠçãã
11.å®è¡æã«åå°ã䜿çšããªãã§ãã ããã
èŠä»¶ã®éåžžã«éå¿çãªãªã¹ãïŒ
å€ããããã¯ãŒã¯ã·ã¹ãã
æ¢åã®Unityãããã¯ãŒã¯ã·ã¹ãã ã«ã¯ãOnSerializeNetworkViewïŒïŒé¢æ°ãæäŸããŠç¶æ
ã®åæãå®è¡ãããReliableDeltaCompressedãã¿ã€ãã®åæããããŸãã ãã®é¢æ°ã¯ãNetworkViewã³ã³ããŒãã³ãã䜿çšããŠãªããžã§ã¯ãã«åã蟌ãŸããéçºè
ã«ãã£ãŠæžã蟌ãŸããã·ãªã¢ã«åã³ãŒãã¯ãæäŸããããã€ãã¹ããªãŒã ã«æžã蟌ãŸããŸãïŒãŸãã¯èªã¿èŸŒãŸããŸãïŒã ãã®ãã€ãã¹ããªãŒã ã®å
容ã¯ãšã³ãžã³ã«ãã£ãŠãã£ãã·ã¥ããã次åé¢æ°ãåŒã³åºããããšãçµæããã£ãã·ã¥ãããããŒãžã§ã³ãšäžèŽããªãå Žåããªããžã§ã¯ãã¯ããŒãã£ãšèŠãªããããã®ç¶æ
ãã¯ã©ã€ã¢ã³ãã«éä¿¡ãããŸãã å¯èœãªã·ãªã¢ã«åé¢æ°ã®äŸã次ã«ç€ºããŸãã
void OnSerializeNetworkView (Bitstream stream, NetworkMessageInfo info) { float horizontalInput = 0.0f; if (stream.isWriting) { // Sending horizontalInput = Input.GetAxis ("Horizontal"); stream.Serialize (horizontalInput); } else { // Receiving stream.Serialize (horizontalInput); // ... do something meaningful with the received variable } }
ãã®ã¢ãããŒãã¯ãäžèšã®ãªã¹ãã®èŠä»¶ã®äžéšãæºãããŸããããã¹ãŠã§ã¯ãããŸããã OnSerializeNetworkViewïŒïŒã¯ãããã¯ãŒã¯çµç±ã§ããŒã¿ãéä¿¡ããé »åºŠã§ãšã³ãžã³ã«ãã£ãŠåŒã³åºãããéçºè
ã¯å€æ°ãããŒãã£ãšããŠããŒã¯ããå¿
èŠããªããããå®è¡æã«èªåçã«æ©èœããŸãã ã¢ã»ã³ããªããã»ã¹ã«è¿œå ã®æé ãè¿œå ããããçŸåšã®éçºããã»ã¹ãäžæãããããããšã¯ãããŸããã
ãããããã®ããã©ãŒãã³ã¹ã¯ç¹ã«é«ããããŸãã-ç¹ã«å€ãã®ãããã¯ãŒã¯ãªããžã§ã¯ããããå Žåã æ¯èŒã«ã¯CPUæéãèŠãããã€ãã¹ããªãŒã ã®ãã£ãã·ã¥ã³ããŒã¯ã¡ã¢ãªã䜿çšããŸãã ãŸããåæããå¿
èŠãããæ°ããã¡ã³ããŒå€æ°ãè¿œå ãããšãã«æåã§æŽæ°ããå¿
èŠããããããã·ãªã¢ã«åé¢æ°ã®äžäžèŽãšã©ãŒãçºçãããããªããŸãã ã¡ã¿ããŒã¿ã«ãã£ãŠã¬ã€ããããªãããããšãã£ã¿ãŒããã³ãã®ä»ã®ããŒã«ã¯ãåæãããŠããå€æ°ãèŠã€ããããšãã§ããŸããã
SyncVarsã®ã³ãŒãçæ
UNETã§æ°ããç¶æ
åæã·ã¹ãã ã«åãçµãã§ããéãç§ãã¡ã®ããŒã ã¯ã«ã¹ã¿ã å±æ§ã«åºã¥ããŠã³ãŒããçæãããœãªã¥ãŒã·ã§ã³ãèæ¡ããŸããã ãŠãŒã¶ãŒã³ãŒãã§ã¯ã次ã®ããã«ãªããŸãã
using UnityEngine.UNetwork; class Combat : UNetBehaviour { [SyncVar] public int Health; [SyncVar] public bool Alive; }
ãã®æ°ããã«ã¹ã¿ã å±æ§ã¯ãHealthããã³Aliveã€ã³ã¹ã¿ã³ã¹å€æ°ãåæããå¿
èŠãããããšãã·ã¹ãã ã«äŒããŸãã ã³ãŒããžã§ãã¬ãŒã¿ãŒã«ã¯ã«ã¹ã¿ã å±æ§ããã®ããŒã¿ããããããéçºè
ã¯ã·ãªã¢ã«åé¢æ°ãèšè¿°ããå¿
èŠããããŸãããããã«åºã¥ããŠãæ£ããé åºãšåã§åªããã·ãªã¢ã«åããã³éã·ãªã¢ã«åé¢æ°ãçæã§ããŸãã çæãããé¢æ°ã¯æ¬¡ã®ããã«ãªããŸãã
public override void UNetSerializeVars(UWriter writer) { writer.WriteInt(Health); writer.WriteBool(Alive); }
ãã®é¢æ°ã¯UNetBehaviouråºæ¬ã¯ã©ã¹ã®ä»®æ³é¢æ°ãåå®çŸ©ãããããã²ãŒã ãªããžã§ã¯ããã·ãªã¢ã«åãããšãã¹ã¯ãªããå€æ°ã¯èªåçã«ã·ãªã¢ã«åãããŸãã ãã®åŸãé©åãªéã·ãªã¢ã«åæ©èœã䜿çšããŠãããäžæ¹ã®ç«¯ã§å±éãããŸãã æ°ãã[SyncVar]å€æ°ãè¿œå ããããšãã³ãŒããèªåçã«æŽæ°ããããããäžäžèŽã¯çºçããŸããã
ãã®ããŒã¿ã¯ãšãã£ã¿ãŒã§äœ¿çšã§ããããã«ãªã£ããããã€ã³ã¹ãã¯ã¿ãŒãŠã£ã³ããŠã«è©³çŽ°æ
å ±ã衚瀺ã§ããŸãã

ãããããã®ã¢ãããŒãã§ã¯ããŸã å€ãã®åé¡ãæ®ã£ãŠããŸãã ãã®é¢æ°ã¯åžžã«ç¶æ
å
šäœãéä¿¡ããŸããå¢åã§ã¯ãªãããããªããžã§ã¯ãã®1ã€ã®ã¡ã³ããŒãå€æŽããããšããªããžã§ã¯ãå
šäœã®ç¶æ
ãéä¿¡ãããŸãã ãããŠãã·ãªã¢ã«åé¢æ°ããã€åŒã³åºãããã©ã®ããã«ããŠç¥ãã®ã§ããããïŒ äœãå€æŽãããŠããªãå Žåãç¶æ
ãéä¿¡ããããšã¯ããŸãå¹ççã§ã¯ãããŸããã
ããããã£ãšããŒãã£ãã©ã°ã§ãããå
æããŸããã å[SyncVar]å€æ°ã¯ãå€æŽæã«ããŒãã£ã©ãã«ãé
眮ããããããã£ã§ã©ããã§ããã®ã¯èªç¶ãªããšã§ãã ãã®ã¢ãããŒãã¯éšåçã«æåããŠããŸãã ããŒãã£ããŒã¯ã®ããããããã¹ã¯ã®ååšã«ãããã³ãŒããžã§ãã¬ãŒã¿ãŒã¯ã€ã³ã¯ãªã¡ã³ã¿ã«æŽæ°ãå®è¡ã§ããŸããã çæãããã³ãŒãã¯æ¬¡ã®ããã«ãªãå§ããŸããã
public override void UNetSerializeVars(UWriter writer) { Writer.Write(m_DirtyFlags) if (m_DirtyFlags & 0x01) { writer.WriteInt(Health); } if (m_DirtyFlags & 0x02) { writer.WriteBool(Alive); } m_DirtyFlags = 0; }
ããã§ãã·ãªã¢ã«åé¢æ°ã¯ããŒãã£ã©ãã«ã䜿çšããŠãã¹ã¯ãèªã¿åããã¹ããªãŒã ã«æžã蟌ãå¿
èŠãããå€æ°ã®ã¿ãã·ãªã¢ã«åã§ããŸãã 垯åå¹
ãå¹ççã«äœ¿çšãããªããžã§ã¯ããæ±ããŠãããã©ããã確èªã§ããŸãã ãŠãŒã¶ãŒã«ãšã£ãŠã¯ãããã¯ãŸã å®å
šã«èªååãããŠããŸãã ãããããããã®ããããã£ã¯ã©ã®ããã«æ©èœããŸããïŒ
[SyncVar]ã€ã³ã¹ã¿ã³ã¹å€æ°ãã©ããããããšããŠãããšããŸãïŒ
using UnityEngine.UNetwork; class Combat : UNetBehaviour { [SyncVar] public int Health; // generated property public int HealthSync { get { return Health; } set { m_dirtyFlags |= 0x01; Health = value; } } }
ãã®ãããªããããã£ã¯ã¿ã¹ã¯ãå®è¡ããŸãããç¡å¹ãªååããããŸãã äžèšã®äŸã®TakeDamageïŒïŒé¢æ°ã¯ãHealthSyncã§ã¯ãªãHealthã䜿çšãããããããããã£ãç¡èŠããŸãã ã³ãŒãçæãå®è¡ãããåã«ååšããªãããããŠãŒã¶ãŒã¯HealthSyncããããã£ãçŽæ¥äœ¿çšããããšã¯ã§ããŸããã æåã®æ®µéã§èªåã³ãŒããçæããã2çªç®ã®æ®µéã§ãŠãŒã¶ãŒãèªåã®ã³ãŒããæŽæ°ãããšã2段éã§å®è¡ã§ããŸãããããã¯éåžžã«è匱ã§ãã ãã®ã¢ãããŒãã¯ã倧ããªã³ãŒããæžãçŽããªããã°ä¿®æ£ã§ããªãã³ã³ãã€ã«ãšã©ãŒã®åœ±é¿ãåããŸãã
å¥ã®ãªãã·ã§ã³ã¯ãéçºè
ãå[SyncVar]å€æ°ã«å¯ŸããŠäžèšã®ããããã£ãèšè¿°ããããšã§ãã ãã®ã¢ãããŒãã¯ãããã°ã©ãã«äœæ¥ãè¿œå ããæœåšçã«ãšã©ãŒãçºçãããããªããŸãã ãŠãŒã¶ãŒãšçæãããã³ãŒãã®ããããã¹ã¯ã¯æ£ç¢ºã«äžèŽããå¿
èŠãããããã[SyncVar]å€æ°ã®è¿œå ãŸãã¯åé€ã¯éåžžã«ããªã±ãŒããªããã»ã¹ã«ãªããŸãã
ã¢ãã»ã·ã«ã®çŽ¹ä»
ãããã£ãŠãã©ãããŒããããã£ãçæããååšãçãããªãå Žåã§ããœãŒã¹ã³ãŒãã«ãããã䜿çšãããå¿
èŠããããŸãã 幞ããªããšã«ãMonoã«ã¯CecilãšããããŒã«ãããããŸãã«ãããå®è¡ããŸãã Cecilã¯ãECMA CIL圢åŒã§Monoã¢ã»ã³ããªãããŠã³ããŒãããããããå€æŽããŠæžãæ»ãããšãã§ããŸãã
ãã®ç¬éããã¹ãŠãå°ããããããªããŸãã UNETã³ãŒããžã§ãã¬ãŒã¿ãŒã¯ã©ãããŒããããã£ãäœæãããœãŒã¹å€æ°ã䜿çšãããŠããã³ãŒãå
ã®ãã¹ãŠã®å ŽæãèŠã€ãããããã®å€æ°ãžã®åç
§ãã©ãããŒããããã£ãžã®åç
§ã«çœ®ãæããŸãã ãŠãŒã¶ãŒã³ãŒãã¯ããŠãŒã¶ãŒã®äœæ¥ãå¿
èŠãšããã«ãæ°ããäœæãããããããã£ãåŒã³åºãããã«ãªããŸããã
Cecilã¯CILã¬ãã«ã§åäœããããããã¹ãŠã®èšèªã1ã€ã®åœ¢åŒã«ã³ã³ãã€ã«ãããããããã¹ãŠã®èšèªã®ãµããŒããšãã圢ã§è¿œå ã®å©ç¹ããããŸãã
ã¹ã¯ãªããã§ã¢ã»ã³ããªã«æ¿å
¥ãããæçµã·ãªã¢ã«åçšã«çæãããCILã¯ã次ã®ããã«ãªããŸãã
IL_0000: ldarg.2 IL_0001: brfalse IL_000d IL_0006: ldarg.0 IL_0007: ldc.i4.m1 IL_0008: stfld uint32 [UnityEngine]UnityEngine.UNetBehaviour::m_DirtyBits IL_000d: nop IL_000e: ldarg.1 IL_000f: ldarg.0 IL_0010: ldfld uint32 [UnityEngine]UnityEngine.UNetBehaviour::m_DirtyBits IL_0015: callvirt instance void [UnityEngine]UnityEngine.UNetwork.UWriter::UWriteUInt32(uint32) IL_001a: ldarg.0 IL_001b: ldfld uint32 [UnityEngine]UnityEngine.UNetBehaviour::m_DirtyBits IL_0020: ldc.i4 1 IL_0025: and IL_0026: brfalse IL_0037 IL_002b: ldarg.1 IL_002c: ldarg.0 IL_002d: ldfld valuetype Buf/BufType Powerup::mbuf IL_0032: callvirt instance void [mscorlib]System.IO.BinaryWriter::Write(int32) IL_0037: nop IL_0038: ldarg.0 IL_0039: ldc.i4.0 IL_003a: stfld uint32 [UnityEngine]UnityEngine.UNetBehaviour::m_DirtyBits IL_003f: ret
幞ããªããšã«ãILSpyã¯CILãCïŒã«ããŸãã¯ãã®éã«å€æã§ãããããçæãããCILãCïŒãšããŠèŠãããšãã§ããŸãã ILSpyã¯ãåªããMono / .Netãã«ãããŒã«ã§ãã CïŒã¯æ¬¡ã®ããã«ãªããŸãã
public override void UNetSerializeVars(UWriter writer, bool forceAll) { if (forceAll) { this.m_DirtyBits = 4294967295u; } writer.UWriteUInt32(this.m_DirtyBits); if ((this.m_DirtyBits & 1u) != 0u) { writer.Write((int)this.mbuf); } this.m_DirtyBits = 0u; }
ãããèŠä»¶ãæºããæ¹æ³ãèŠãŠã¿ãŸãããã
1.å€æ°ã®ã·ã£ããŠã³ããŒãªã
2.å¢åæŽæ°
3.ã¹ããŒã¿ã¹å€æŽãã§ãã¯ãªã
4.ææžãã®ã·ãªã¢ã«åæ©èœã¯ãããŸãã
5.çŽæ¥ã®ããŒãã£ã³ãŒã«ãªã
6. UnityããµããŒããããã¹ãŠã®ããã°ã©ãã³ã°èšèªã§åäœããŸã
7.䜿ãæ
£ããéçºããã»ã¹ã«ã¯åœ±é¿ããŸãã
8.éçºè
ã«ããæäœæ¥ã¯å¿
èŠãããŸãã
9.ã¡ã¿ããŒã¿ã«åºã¥ã
10.ãã¹ãŠã®ã¿ã€ãã§åäœïŒæ°ããUWriter / UReaderã·ãªã¢ã©ã€ã¶ãŒã䜿çšïŒ
11.å®è¡æã«åå°ã䜿çšããŸãã
ãã¹ãŠå®äºããããã§ãã ã·ã¹ãã ã¯å¹ççã§éçºè
ã«åªãããã®ã«ãªããŸãã Unityã§ã®ãã«ããã¬ã€ã€ãŒã²ãŒã ã®éçºã誰ã«ãšã£ãŠãç°¡åã«ãªããšä¿¡ãããã
ãŸããCecilã䜿çšããŠRPCåŒã³åºããå®è£
ãããªãã¬ã¯ã·ã§ã³ã䜿çšããŠååã§é¢æ°ãæ€çŽ¢ããªãããã«ããŸãã ããã«ã€ããŠã¯ãä»åŸã®èšäºã§èª¬æããŸãã
äœã¬ãã«LLAPIããã³UNETãã©ã³ã¹ããŒãå±€
Unityã®æ°ãããããã¯ãŒã¯ã©ã€ãã©ãªã®èšèšã«çæããçæ³çãªã©ã€ãã©ãªãã©ã®ããã«èŠããããç解ããããšèããŸããã ïŒå€§ãŸãã«èšã£ãŠïŒ2çš®é¡ã®ãŠãŒã¶ãŒãããããšãããããŸããã
1.ãããã¯ãŒã¯ããŒã«ã䜿çšããŠãæå°éã®åŽåã§çæ³çãªçµæãããã«äœ¿çšã§ããããã«ããïŒçæ³çã«ã¯ãŸã£ããåŽåããããªãïŒãŠãŒã¶ãŒã
2.ãããã¯ãŒã¯æåã®ã²ãŒã ãéçºããéåžžã«æè»ã§åŒ·åãªããŒã«ãå¿
èŠãªãŠãŒã¶ãŒã
ãããã®2ã€ã®ã¿ã€ãã«åºã¥ããŠããããã¯ãŒã¯ã©ã€ãã©ãªã2ã€ã®ç°ãªãéšåã«åå²ããŸãããé«ã¬ãã«HLAPIïŒé«ã¬ãã«APIïŒãšäœã¬ãã«LLAPIïŒäœã¬ãã«APIïŒã§ãã
ãã®ããŒãã§ã¯ã次ã®ååã«åºã¥ããäœã¬ãã«APIãšã©ã€ãã©ãªã®æ§é ã«ã€ããŠèª¬æããŸãã
ããã©ãŒãã³ã¹ãçç£æ§ãçç£æ§
LLAPIã¯UDPãœã±ããã®äžã«ããèãå±€ã§ããã»ãšãã©ã®äœæ¥ã¯å¥ã®ã¹ããªãŒã ã§è¡ãããŸãïŒãããã£ãŠãLLAPIã¯ã¡ã€ã³ã¹ããªãŒã ã®ã¿ã䜿çšããããã«æ§æã§ããŸãïŒã åçãªã¡ã¢ãªå²ãåœãŠãé床ã®åæã¯ãããŸããïŒã©ã€ãã©ãªã®ã»ãšãã©ã¯ãå°æ°ã®ã¢ãããã¯ãªã€ã³ã¯ãªã¡ã³ã/ãã¯ãªã¡ã³ãæäœã§ã¡ã¢ãªããªã¢åæã«åºã¥ãåæã䜿çšããŸãïŒã
CïŒã§äœãã§ããå Žåã¯ããããããªããã°ãªããŸãã
ãŠãŒã¶ãŒã«æ¬åœã«å¿
èŠãªãã®ã ãã«ã¢ã¯ã»ã¹ãèš±å¯ããããšã«ããŸããã BSDãœã±ãããšåæ§ã«ãLLAPIã¯1ã€ã®æœè±¡åïŒçã®ãã€ããªã¡ãã»ãŒãžã³ã°ïŒã®ã¿ããµããŒãããŸãã tcpã®ãããªã¹ããªãŒã ãã·ãªã¢ã©ã€ã¶ãŒããŸãã¯RPCåŒã³åºãã¯ãªããäœã¬ãã«ã®ã¡ãã»ãŒãžã®ã¿ããããŸãã
æè»æ§ãšã«ã¹ã¿ãã€ãºæ§ïŒ ã¯ãããé¡ãããŸã...
TCPã§ã®ãœã±ããã®å®è£
ãèŠããšãå€æŽå¯èœãªå€ãã®ãã©ã¡ãŒã¿ãŒïŒã¿ã€ã ã¢ãŠãããããã¡ãŒé·ãªã©ïŒã衚瀺ãããŸãã åæ§ã®ã¢ãããŒããéžæãããŠãŒã¶ãŒãã©ã€ãã©ãªã®ã»ãšãã©ãã¹ãŠã®ãã©ã¡ãŒã¿ãŒãå€æŽããŠãããŒãºã«åãããŠèª¿æŽã§ããããã«ããŸããã ã·ã³ãã«ããã¬ãã·ãã«ãã®éžæã«çŽé¢ããŠãç§ãã¡ã¯æè»æ§ãéžã³ãŸããã
ã·ã³ãã«ããšå¿«é©ã
ã§ããéãBSDãœã±ããAPIã«äŒŒãLLAPIãèšèšããããšããŸããã
ãããã¯ãŒã¯å±€ãšãã©ã³ã¹ããŒãå±€
è«ççã«ã¯ãäœã¬ãã«UNETã©ã€ãã©ãªã¯ãããããã¯ãŒã¯ãå±€ãšããã©ã³ã¹ããŒããå±€ãå«ãUDPäžã«æ§ç¯ããããããã¯ãŒã¯ãããã³ã«ã®ã»ããã§ãã ãããã¯ãŒã¯å±€ã¯ãããŒãéã®æ¥ç¶ããã±ããã®é
ä¿¡ãããã³å¯èœãªãããŒãšèŒ»èŒ³ã®å¶åŸ¡ã«äœ¿çšãããŸãã ãã©ã³ã¹ããŒãå±€ã¯ãããŸããŸãªéä¿¡ãã£ãã«ã«å±ãããã¡ãã»ãŒãžãã§æ©èœããŸãã

ãã£ãã«ã«ã¯2ã€ã®ç®çããããŸããã¡ãã»ãŒãžãè«ççã«åé¢ããç°ãªãé
ä¿¡ä¿èšŒãšãµãŒãã¹å質ïŒé
ä¿¡èš±å¯ãŸãã¯ãµãŒãã¹å質ïŒãæäŸã§ããŸãã
ãã£ãã«ãã¥ãŒãã³ã°ã¯ãã¥ãŒãã³ã°æé ã®äžéšã§ãããä»åŸã®èšäºã§åãäžããŸãã ãšããããããç§ã®ã·ã¹ãã ã«ã¯æ倧10åã®æ¥ç¶ãå«ãŸããåæ¥ç¶ã«ã¯5ã€ã®ãã£ã³ãã«ãããããã£ã³ãã«0ã«ã¯ãã®ã¿ã€ããããããã£ã³ãã«1ã«ã¯ç°ãªãã¿ã€ãããããŸãããšããããã«ãªããŸãã æã®æåŸã®éšåã¯æ¬¡ã®ããã«å®çŸ©ãããŸãïŒ

2çªç®ã®ãã©ã¡ãŒã¿ãŒã¯ãã£ãã«çªå·ãæåŸã¯ãã£ãã«ã®ã¿ã€ããŸãã¯ãã£ãã«ã®ãµãŒãã¹å質ïŒé
ä¿¡èš±å¯ïŒã§ãã
ïŒçŸæç¹ã§ã¯ïŒUNETã¯æ¬¡ã®QOSããµããŒãããŠããŸãã
-ä¿¡é Œæ§ã®äœãïŒUDPãã±ãããšåæ§ã«ããããã¯ãŒã¯ã®åé¡ãŸãã¯å
éšãããã¡ã®ãªãŒããŒãããŒã«ãã倱ãããå¯èœæ§ã®ããä¿¡é Œæ§ã®äœãã¡ãã»ãŒãžã äŸïŒçããã°ãšã³ããªã
-UnreliableFragmentedïŒæ倧ãã±ããé·ã¯å€æŽãããŸããããã倧ããªãã¡ãã»ãŒãžãéä¿¡ãããå ŽåããããŸãã ãã®ã¿ã€ãã®ãã£ãã«ã¯ãéä¿¡åã«ã¡ãã»ãŒãžããã©ã°ã¡ã³ãã«è§£æããåä¿¡ããåã«åéããŸãã ãã®ãããªè³ªã®é«ããµãŒãã¹ã¯ä¿¡é Œã§ããªããããé
ä¿¡ã¯ä¿èšŒãããŸããã äŸïŒé·ãéèªã
-UnreliableSequencedïŒãã£ãã«ã¯é
ä¿¡é åºãæäŸããŸããããã®ãµãŒãã¹å質ã¯ä¿¡é Œã§ããªããããã¡ãã»ãŒãžã倱ãããå¯èœæ§ããããŸãã äŸïŒé³å£°ããããªã
-ä¿¡é Œæ§ïŒãã£ãã«ã¯é
ä¿¡ïŒãŸãã¯åæïŒãä¿èšŒããŸãããé åºã¯ä¿èšŒããŸããã äŸïŒæå·ã®è»¢éã
-ReliableFragmentedïŒ UnreliableFragmentedãšåãã§ãããããã«å ããŠé
ä¿¡ãä¿èšŒããŸãã äŸïŒã°ã«ãŒãæ害ã
-ReliableSequencedïŒ UnreliableSequencedãšåãã§ãããããã«é
ä¿¡ãä¿èšŒããŸãã ãã®QOSã¯TCPã¹ããªãŒã ã«äŒŒãŠããŸãã äŸïŒãã¡ã€ã«ãšãããã®è»¢éã
-StateUpdateïŒä¿¡é Œã§ããªããã£ãã«ã¿ã€ããåä¿¡/éä¿¡ããå€ããã±ããã匷å¶çã«ããããããŸãã éä¿¡äžã«ãããã¡ã«è€æ°ã®ã¡ãã»ãŒãžãå«ãŸããå Žåãææ°ã®ã¡ãã»ãŒãžã®ã¿ãéä¿¡ãããŸãã èªã¿åãäžã«åä¿¡è
ã®ãããã¡ã«è€æ°ã®ã¡ãã»ãŒãžãå«ãŸããŠããå Žåãææ°ã®ã¡ãã»ãŒãžã®ã¿ãé
ä¿¡ãããŸãã äŸïŒãã±ãŒã·ã§ã³è»¢éã
-AllCostDeliveryïŒ Reliableã«éåžžã«äŒŒãŠããŸãããéãããããŸãã ä¿¡é Œã§ãããã£ãã«ã¯ãåçã«æ±ºå®ãããåŸåŸ©æéå€ïŒRTTïŒã«åºã¥ããŠã¡ãã»ãŒãžãåéä¿¡ããŸãããAllCostDeliveryã¯äžå®ã®æéïŒèšå®ã§æå®ïŒåŸã«ã¡ãã»ãŒãžãèªåçã«è»¢éããŸãã ããã¯ãå°ãããªãããéèŠãªã¡ãã»ãŒãžã«åœ¹ç«ã¡ãŸããããã¬ãŒã€ãŒAã®é ãæã¡ãŸããããŸãã¯ãããã²ãŒã ãå§ãŸããŸããã äŸïŒåŒŸäžžãé£ã³æ£ããããªã²ãŒã ã€ãã³ãã
å
žåçãªLLAPIé¢æ°åŒã³åºããèŠãŠã¿ãŸãããïŒ
1.ã©ã€ãã©ãªã®åæå

2.ãããã¯ãŒã¯ã®ã»ããã¢ããïŒããããžããã£ãã«æ°ãã¿ã€ããããŸããŸãªã¿ã€ã ã¢ãŠãããããã¡ãµã€ãºïŒããã«ã€ããŠã¯ä»ã®èšäºã§èª¬æããŸãïŒã
3.ãœã±ããã®äœæ

ãã®é¢æ°ã¯ããã¹ãŠã®ãããã¯ãŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ã§ããŒã5000ã®ãœã±ãããéãããœã±ããã®èª¬æãšããŠæŽæ°å€ãè¿ããŸã
4.å¥ã®ããŒããžã®æ¥ç¶

ãã®é¢æ°ã¯ãæ¥ç¶èŠæ±ã127.0.0.1/6000ã®å¥ã®ããŒãã«éä¿¡ããŸãã ãã®ããŒããžã®æ¥ç¶ã®èª¬æãšããŠæŽæ°å€ãè¿ããŸãã æ¥ç¶ã確ç«ããããšæ¥ç¶ã€ãã³ãããæ¥ç¶ã確ç«ã§ããªãå Žåã¯äžæã€ãã³ããåãåããŸãã
5.ã¡ãã»ãŒãžãéä¿¡ãã

æåŸã®é¢æ°ã¯ããã£ãã«1ã䜿çšããŠconnectionIdããŒããèšè¿°ããããã«hostIdã«èšè¿°ããããœã±ãããä»ããŠãããã¡ã«å«ãŸãããã€ããªããŒã¿ãéä¿¡ããŸãïŒãã®å Žåã¯ãä¿¡é Œã§ãããã£ãã«ãã§ãããããã¡ãã»ãŒãžé
ä¿¡ãä¿èšŒãããŸãïŒ
6.ãããã¯ãŒã¯ã€ãã³ãã®åä¿¡
ãããã¯ãŒã¯ã€ãã³ããåä¿¡ããã«ã¯ã調æ»ã¢ãã«ãéžæããŸãã ãŠãŒã¶ãŒã¯UTransport.ReceiveïŒïŒé¢æ°ãããŒãªã³ã°ããŠããããã¯ãŒã¯ã€ãã³ãã®éç¥ãåä¿¡ããå¿
èŠããããŸãã ãã®ã¢ãã«ã¯ãã¿ã€ã ã¢ãŠãããŒãã®éåžžã®selectïŒïŒåŒã³åºãã«éåžžã«äŒŒãŠããããšã«æ³šæããŠãã ããã ãã®é¢æ°ã¯4ã€ã®ç°ãªãã€ãã³ããåãåããŸãã
UNETEventType.kConnectEvent-誰ããããªãã«æ¥ç¶ããŠããããæ¥ç¶ãæ£åžžã«ç¢ºç«ãããŠãããUTransport.ConnectïŒïŒã«ãã£ãŠç°¡ç¥åãããŠããŸã
UNETEventType.kDisconnectEvent-誰ããããªãããåæãããããšã©ãŒã³ãŒããå ±åããäœããã®çç±ã§UTransport.ConnectïŒïŒã«ãã£ãŠèŠæ±ãããæ¥ç¶ã確ç«ã§ããŸããã
UNETEventType.kDatatEvent-æ°ããããŒã¿ãåä¿¡ããŸãã
UNETEventType.kNothing-èå³æ·±ãããšã¯äœãèµ·ãããŸããã§ãã

7.åæãããªã¯ãšã¹ããéä¿¡ãã
ãã®é¢æ°åŒã³åºãã¯ãconnectionIdããåæããèŠæ±ãhostIdã§ãã¹ãã«éä¿¡ããŸãã æ¥ç¶ã¯ããã«éããããå°æ¥åå©çšãããå¯èœæ§ããããŸãã

泚é
1.ãã®èšäºã¯ãè±èªã®ããã°Unityã®3ã€ã®ãšã³ããªã§æ§æãããŠããŸãã
UNETã®çºè¡š-æ°ããUnityãã«ããã¬ã€ã€ãŒãã¯ãããžãŒUNET SyncVarUnityãããã¯ãŒã¯ãã©ã³ã¹ããŒãã¬ã€ã€ãŒã«ã€ããŠ2.åç圢åŒã®ãœãŒã¹ã³ãŒãã®äŸã¯ãè±èªã®ãªãªãžãã«èšäºã«ãããŸããã