TL; DR
Unity-
GitHubã§ãã¬ã€ã€ãŒã®èº«äœã®åãã®ã¯ã©ã€ã¢ã³ãåŽã®äºæž¬ãå®è£
ããæ¹æ³ã瀺ããã¢ãäœæããŸããã
ã¯ããã«
2012幎ã®åãã«ãUnityã§ã®ãã¬ãŒã€ãŒã®ç©ççãªåãã®ã¯ã©ã€ã¢ã³ãåŽã§ã®äºæž¬ã®å®è£
æ¹æ³ã«é¢ãã
æçš¿ãæžããŸããã
Physics.SimulateïŒïŒã®ãããã§ãç§ã説æããäžåšçšãªåé¿çã¯äžèŠã«ãªããŸããã å€ãæçš¿ã¯ä»ã§ãç§ã®ããã°ã§æã人æ°ã®ãããã®ã®1ã€ã§ãããçŸä»£ã®Unityã§ã¯ãã®æ
å ±ã¯ãã§ã«ééã£ãŠããŸãã ãããã£ãŠã2018幎çããªãªãŒã¹ããŠããŸãã
ã¯ã©ã€ã¢ã³ãåŽã«ã¯äœããããŸããïŒ
ç«¶äºåã®ãããã«ããã¬ã€ã€ãŒã²ãŒã ã§ã¯ãå¯èœãªéãäžæ£è¡çºã¯é¿ããŠãã ããã éåžžãããã¯ãæš©åšäž»çŸ©çãªãµãŒããŒãåãããããã¯ãŒã¯ã¢ãã«ã䜿çšãããããšãæå³ããŸããã¯ã©ã€ã¢ã³ãã¯å
¥åãããæ
å ±ããµãŒããŒã«éä¿¡ãããµãŒããŒã¯ãã®æ
å ±ããã¬ãŒã€ãŒã®åãã«å€æãããã¬ãŒã€ãŒã®ã¹ããŒã¿ã¹ã®ã¹ãããã·ã§ãããã¯ã©ã€ã¢ã³ãã«éä¿¡ããŸãã ãã®å ŽåãããŒãæŒããŠããçµæã衚瀺ããããŸã§ã«é
å»¶ããããã¢ã¯ãã£ããªã²ãŒã ã§ã¯åãå
¥ããããŸããã ã¯ã©ã€ã¢ã³ãåŽã®äºæž¬ã¯éåžžã«äžè¬çãªææ³ã§ãããé
å»¶ãé ããçµæã®åããäºæž¬ããããã«ãã¬ãŒã€ãŒã«è¡šç€ºããŸãã ã¯ã©ã€ã¢ã³ãã¯ãµãŒããŒããçµæãåä¿¡ãããšãã¯ã©ã€ã¢ã³ããäºæž¬ããçµæãšæ¯èŒããŸããçµæãç°ãªãå Žåãäºæž¬ã¯èª€ã£ãŠããããä¿®æ£ããå¿
èŠããããŸãã
ãµãŒããŒããåä¿¡ããã¹ãããã·ã§ããã¯ãåžžã«ã¯ã©ã€ã¢ã³ãã®äºæž¬ç¶æ
ã«é¢ããŠéå»ã®ãã®ã§ãïŒããšãã°ãã¯ã©ã€ã¢ã³ããããµãŒããŒã«ããŒã¿ã転éããŠãã150ããªç§ãããå Žåãåã¹ãããã·ã§ããã¯å°ãªããšã150ããªç§é
ããŸãïŒã ãã®çµæãã¯ã©ã€ã¢ã³ããééã£ãäºæž¬ãä¿®æ£ããå¿
èŠãããå Žåãéå»ã®ãã®æç¹ãŸã§ããŒã«ããã¯ããã®ã£ããã«å
¥åããããã¹ãŠã®æ
å ±ãåçŸããŠãçŸåšã®å Žæã«æ»ãå¿
èŠããããŸãã ã²ãŒã å
ã®ãã¬ã€ã€ãŒã®åããç©çåŠã«åºã¥ããŠããå Žåã1ãã¬ãŒã ã§è€æ°ã®ãµã€ã¯ã«ãã·ãã¥ã¬ãŒãããã«ã¯Physics.SimulateïŒïŒãå¿
èŠã§ãã ãã¬ã€ã€ãŒãç§»åãããšãã«ãã£ã©ã¯ã¿ãŒã³ã³ãããŒã©ãŒïŒãŸãã¯ã«ãã»ã«ãã£ã¹ããªã©ïŒã®ã¿ã䜿çšããå Žåã¯ãPhysics.SimulateïŒïŒã䜿çšããã«å®è¡ã§ããŸããããã©ãŒãã³ã¹ãåäžãããšæããŸãã
Unityã䜿çšããŠã
Glenn Fiedlerã«
ãããZen of Networked PhysicsããšåŒã°ãããããã¯ãŒã¯ãã¢ãåçŸããŸãã ãã¬ã€ã€ãŒã¯ç©ççãªç«æ¹äœãæã£ãŠãããããã«åãå ããŠã·ãŒã³ã«æŒã蟌ãããšãã§ããŸãã ãã¢ã§ã¯ãé
å»¶ããã±ããæå€±ãªã©ãããŸããŸãªãããã¯ãŒã¯ç¶æ
ãã·ãã¥ã¬ãŒãããŸãã
ä»äºãå§ãã
æåã«è¡ãããšã¯ãèªåç©çã·ãã¥ã¬ãŒã·ã§ã³ããªãã«ããããšã§ãã Physics.SimulateïŒïŒã䜿çšãããšããã€ç©çã·ã¹ãã ã«ã·ãã¥ã¬ãŒã·ã§ã³ãéå§ããããäŒããããšãã§ããŸãããããã©ã«ãã§ã¯ãåºå®ãããžã§ã¯ãæéãã«ã¿ã«åºã¥ããŠã·ãã¥ã¬ãŒã·ã§ã³ãèªåçã«å®è¡ããŸãã ãããã£ãŠã
[ èªåã·ãã¥ã¬ãŒã·ã§ã³ ]ããã¯ã¹ã®ãã§ãã¯ãå€ããŠã
[ç·šé
]-> [ãããžã§ã¯ãèšå®]-> [ç©ç]ã§ç¡å¹ã«ããŸãã
å§ããããã«ãåçŽãªã·ã³ã°ã«ãŠãŒã¶ãŒå®è£
ãäœæããŸãã å
¥åã¯ãµã³ããªã³ã°ããïŒç§»åããå Žåã¯wãaãsãdããžã£ã³ãããå Žåã¯ã¹ããŒã¹ïŒããã¹ãŠAddForceïŒïŒã䜿çšããŠãªãžããããã£ã«é©çšãããåçŽãªåã«ãªããŸãã
public class Logic : MonoBehaviour { public GameObject player; private float timer; private void Start() { this.timer = 0.0f; } private void Update() { this.timer += Time.deltaTime; while (this.timer >= Time.fixedDeltaTime) { this.timer -= Time.fixedDeltaTime; Inputs inputs; inputs.up = Input.GetKey(KeyCode.W); inputs.down = Input.GetKey(KeyCode.S); inputs.left = Input.GetKey(KeyCode.A); inputs.right = Input.GetKey(KeyCode.D); inputs.jump = Input.GetKey(KeyCode.Space); this.AddForcesToPlayer(player.GetComponent<Rigidbody>(), inputs); Physics.Simulate(Time.fixedDeltaTime); } } }
ãããã¯ãŒã¯ã䜿çšãããŠããªããšãã«ãã¬ãŒã€ãŒãç§»åãããµãŒããŒãžã®å
¥åã®éä¿¡
次ã«ãå
¥åããµãŒããŒã«éä¿¡ããå¿
èŠããããŸãããµãŒããŒã¯ããã®ã¢ãŒã·ã§ã³ã³ãŒããå®è¡ãããã¥ãŒãç¶æ
ã®ã¹ãããã·ã§ãããäœæããŠãã¯ã©ã€ã¢ã³ãã«éãè¿ããŸãã
ãããŸã§ç¹å¥ãªããšã¯äœããããŸãããæ³šæãããã®ã¯tick_number倿°ã远å ããããšã ãã§ãã ãµãŒããŒããã¥ãŒãã®ç¶æ
ã®ã¹ãããã·ã§ãããã¯ã©ã€ã¢ã³ãã«éä¿¡ãããšãã«ããã®ç¶æ
ã«å¯Ÿå¿ããã¯ã©ã€ã¢ã³ãã®ã¿ã¯ãã確èªã§ããããã«ããå¿
èŠããããŸããããã«ããããã®ç¶æ
ãäºæž¬ã¯ã©ã€ã¢ã³ããšæ¯èŒã§ããŸãïŒå°ãåŸã§è¿œå ããŸãïŒã
ç°¡åã§ã-ãµãŒããŒã¯å
¥åã¡ãã»ãŒãžãåŸ
æ©ãããããåä¿¡ãããšã¯ããã¯ãã·ãã¥ã¬ãŒãããŸãã æ¬¡ã«ãçµæã®ãã¥ãŒãã®ç¶æ
ã®ã¹ãããã·ã§ãããäœæããã¯ã©ã€ã¢ã³ãã«éãè¿ããŸãã ã¹ããŒã¿ã¹ã¡ãã»ãŒãžã®tick_numberãå
¥åã¡ãã»ãŒãžã®tick_numberããã1ã€å€ãããšã«æ°ä»ããããããŸããã ããã¯ããã¿ã¯ã100ã®ãã¬ãŒã€ãŒã®ç¶æ
ãããã¿ã¯ã100ã®
æåã®ãã¬ãŒã€ãŒã®ç¶æ
ããšèããæ¹ãå人çã«çŽæçã«äŸ¿å©ã ããã§ãã ãããã£ãŠãã¡ãžã£ãŒ100ã®ãã¬ãŒã€ãŒã®ç¶æ
ãšã¡ãžã£ãŒ100ã®ãã¬ãŒã€ãŒã®å
¥åã¯ãã¡ãžã£ãŒ101ã®ãã¬ãŒã€ãŒã®æ°ããç¶æ
ãäœæããŸãã
ç¶æ
n +å
¥ån =ç¶æ
n + 1
ç§ã¯ããªãããããåãããã«ãšãã¹ãã ãšèšã£ãŠããã®ã§ã¯ãªããäž»ãªããšã¯ã¢ãããŒãã®äžå€æ§ã§ãã
ãŸã
ããããã®ã¡ãã»ãŒãžãå®éã®ãœã±ãããä»ããŠ
éä¿¡ããã®ã§ã¯ãªãããã±ããããã¥ãŒã«æžã蟌ãã§ãã±ããã®é
å»¶ãšæå€±ãã·ãã¥ã¬ãŒãããããšã§æš¡å£ããããšãèšããªããã°ãªããŸããã ã·ãŒã³ã«ã¯2ã€ã®ç©çãã¥ãŒããå«ãŸããŠããŸãã1ã€ã¯ã¯ã©ã€ã¢ã³ãçšã§ããã1ã€ã¯ãµãŒããŒçšã§ãã ã¯ã©ã€ã¢ã³ããã¥ãŒããæŽæ°ãããšãããµãŒããŒãã¥ãŒãã®GameObjectãç¡å¹ã«ããŸããéãåæ§ã§ãã
ãã ãããããã¯ãŒã¯ããŠã³ã¹ãšãã±ããé
ä¿¡ãééã£ãé åºã§ã·ãã¥ã¬ãŒãããããšã¯ãããŸããããã®ãããåä¿¡ããåå
¥åã¡ãã»ãŒãžã¯åã®ãã®ãããæ°ãããšä»®å®ããŸãã ãã®ã·ãã¥ã¬ãŒã·ã§ã³ã¯ã1ã€ã®Unityã€ã³ã¹ã¿ã³ã¹ã§ãã¯ã©ã€ã¢ã³ãããšããµãŒããŒããéåžžã«ç°¡åã«å®è¡ãã1ã€ã®ã·ãŒã³ã§ãµãŒããŒãã¥ãŒããšã¯ã©ã€ã¢ã³ããã¥ãŒããçµã¿åãããããã«å¿
èŠã§ãã
ãŸããå
¥åã¡ãã»ãŒãžããªã»ãããããŠãµãŒããŒã«å°éããªãå ŽåããµãŒããŒã¯ã¯ã©ã€ã¢ã³ããããå°ãªãã¯ããã¯ãµã€ã¯ã«ãã·ãã¥ã¬ãŒããããããç°ãªãç¶æ
ãäœæãããããšã«æ³šæããŠãã ããã ããã¯äºå®ã§ããããããã®çç¥ãã·ãã¥ã¬ãŒããããšããŠããå
¥åã¯äŸç¶ãšããŠæ£ãããªãå¯èœæ§ããããããã¯ç°ãªãç¶æ
ã«ã€ãªããå¯èœæ§ããããŸãã ãã®åé¡ã¯åŸã§å¯ŸåŠããŸãã
ãŸãããã®äŸã§ã¯ã¯ã©ã€ã¢ã³ãã1ã€ãããªããããäœæ¥ãç°¡åã«ãªãããšã远å ããå¿
èŠããããŸãã è€æ°ã®ã¯ã©ã€ã¢ã³ããããå ŽåãaïŒPhysics.SimulateïŒïŒãåŒã³åºããšãã«ããµãŒããŒã§1人ã®ãã¬ã€ã€ãŒã®ãã¥ãŒãã®ã¿ãæå¹ã«ãªã£ãŠããããšã確èªããããbïŒãµãŒããŒãè€æ°ã®ãã¥ãŒãããå
¥åãåãåãå Žåããããããã¹ãŠã·ãã¥ã¬ãŒãããå¿
èŠããããŸã
75 msã®é
å»¶ïŒ150 msã®åŸåŸ©ïŒ
0ïŒ
ã®çŽå€±ããã±ãŒãž
é»è²ã®ãã¥ãŒã-ãµãŒããŒãã¬ãŒã€ãŒ
éãç«æ¹äœ-ã¯ã©ã€ã¢ã³ããåãåã£ãæåŸã®ã¹ãããã·ã§ãããããŸã§ã®ãšãããã¹ãŠãè¯ãããã«èŠããŸããããããªã«èšé²ãããã®ãå°ãå³éžããŠãããªãæ·±å»ãªåé¡ãé ããŸããã
決å®ã®å€±æ
ãããèŠãŠã¿ãŸãããïŒ
çã...ãã®ãããªã¯ããã±ãŒãžã倱ãããšãªãèšé²ãããŸããããã·ãã¥ã¬ãŒã·ã§ã³ã¯ãŸã£ããåãå
¥åã§ãå€ãããŸãã ãªããããèµ·ããã®ãã¯ããããããŸãã-PhysXã¯ååã«æ±ºå®è«çã§ãªããã°ãªããªãã®ã§ãã·ãã¥ã¬ãŒã·ã§ã³ãéåžžã«é »ç¹ã«åå²ããããšã¯å°è±¡çã§ãã ããã¯ãGameObjectãã¥ãŒããåžžã«æå¹ãŸãã¯ç¡å¹ã«ããŠããããã§ããå¯èœæ§ããããŸããã€ãŸãã2ã€ã®ç°ãªãUnityã€ã³ã¹ã¿ã³ã¹ã䜿çšãããšãåé¡ãæžå°ããå¯èœæ§ããããŸãã GitHubã®ã³ãŒãã§èŠãå Žåããã°ã«ãªãå¯èœæ§ããããŸãã
ããã¯ãããããããŸããããã¯ã©ã€ã¢ã³ãåŽã§ã®äºæž¬ã§ã¯äžæ£ç¢ºãªäºæž¬ãäžå¯æ¬ ãªäºå®ãªã®ã§ããããã«å¯ŸåŠããŸãããã
å·»ãæ»ãã§ããŸããïŒ
ããã»ã¹ã¯éåžžã«ç°¡åã§ã-ã¯ã©ã€ã¢ã³ããåããäºæž¬ãããšãã圌ã¯ã¹ããŒã¿ã¹ãããã¡ïŒäœçœ®ãšå転ïŒãšå
¥åãä¿åããŸãã ãµãŒããŒããã¹ããŒã¿ã¹ã¡ãã»ãŒãžãåä¿¡ããåŸãåä¿¡ããç¶æ
ããããã¡ããäºæž¬ãããç¶æ
ãšæ¯èŒããŸãã å·®ã倧ããããå Žåã¯ãéå»ã®ã¯ã©ã€ã¢ã³ããã¥ãŒãã®ç¶æ
ãåå®çŸ©ãããã¹ãŠã®äžéã¡ãžã£ãŒãå床ã·ãã¥ã¬ãŒãããŸãã
ãããã¡ãããå
¥åãšã¹ããŒã¿ã¹ã¯ãã¡ãžã£ãŒèå¥åãã€ã³ããã¯ã¹ãšããŠäœ¿çšãããéåžžã«åçŽãªåŸªç°ãããã¡ã«æ ŒçŽãããŸãã ãããŠãç©çåŠã®ã¯ããã¯åšæ³¢æ°ã«64 Hzã®å€ãéžæããŸãããã€ãŸãã1024èŠçŽ ã®ãããã¡ãŒã¯16ç§éã®ã¹ããŒã¹ãæäŸããŸãããããã¯å¿
èŠãªãã®ãããã¯ããã«å€ããªããŸãã
èšæ£äžã§ãïŒåé·å
¥å転é
éåžžãå
¥åã¡ãã»ãŒãžã¯éåžžã«å°ãããæŒããããã¿ã³ãçµã¿åãããŠæ°ãã€ãã®ããããã£ãŒã«ãã«ããããšãã§ããŸãã ã¡ãã»ãŒãžã«ã¯ãŸã 4ãã€ããå ããã¡ãžã£ãŒçªå·ããããŸããããã£ãªãŒä»ãã®8ãããå€ã䜿çšããŠç°¡åã«å§çž®ã§ããŸãïŒãããã0-255ã®ééã¯å°ããããã®ã§ãå®å
šã«9ãŸãã¯10ãããã«å¢ããããšãã§ããŸãïŒã å Žåã«ãã£ãŠã¯ããããã®ã¡ãã»ãŒãžã¯éåžžã«å°ãããããåã¡ãã»ãŒãžã§å€§éã®å
¥åããŒã¿ãéä¿¡ã§ããŸãïŒä»¥åã®å
¥åããŒã¿ã倱ãããå ŽåïŒã ã©ã®ãããåã«æ»ããŸããïŒ ããŠãã¯ã©ã€ã¢ã³ãã¯ãµãŒããŒããåãåã£ãæåŸã®ã¹ããŒã¿ã¹ã¡ãã»ãŒãžã®æž¬å®çªå·ãç¥ã£ãŠããã®ã§ããã®æž¬å®å€ããå
ã«æ»ãããšã¯æå³ããããŸããã ãŸããã¯ã©ã€ã¢ã³ãã«ãã£ãŠéä¿¡ãããåé·ãªå
¥åããŒã¿ã®éã«å¶éã課ãå¿
èŠããããŸãã ãã¢ã§ã¯ãããè¡ããŸããã§ãããã宿ããã³ãŒãã«å®è£
ããå¿
èŠããããŸãã
while (this.HasAvailableStateMessage()) { StateMessage state_msg = this.GetStateMessage(); this.client_last_received_state_tick = state_msg.tick_number;
ããã¯åçŽãªå€æŽã§ãããã¯ã©ã€ã¢ã³ãã¯æåŸã«åä¿¡ããã¹ããŒã¿ã¹ã¡ãã»ãŒãžã®æž¬å®çªå·ãæžã蟌ãã ãã§ãã
Inputs inputs = this.SampleInputs(); InputMessage input_msg; input_msg.start_tick_number = this.client_last_received_state_tick; input_msg.inputs = new List<Inputs>(); for (uint tick = this.client_last_received_state_tick; tick <= this.tick_number; ++tick) { input_msg.inputs.Add(this.client_input_buffer[tick % 1024]); } this.SendToServer(input_msg);
ã¯ã©ã€ã¢ã³ãããéä¿¡ãããå
¥åã¡ãã»ãŒãžã«ã¯ã1ã€ã®ã¢ã€ãã ã ãã§ãªããå
¥åããŒã¿ã®ãªã¹ããå«ãŸããããã«ãªããŸããã å°ç¯çªå·ã®ããéšåã¯æ°ããå€ãååŸããŸã-ããããã®ãªã¹ãã®æåã®å
¥åã®å°ç¯çªå·ã§ãã
while (this.HasAvailableInputMessages()) { InputMessage input_msg = this.GetInputMessage();
ãµãŒããŒã¯ãå
¥åã¡ãã»ãŒãžãåä¿¡ãããšãæåã®å
¥åã®æž¬å®çªå·ãšã¡ãã»ãŒãžå
ã®å
¥åããŒã¿ã®éãèªèããŸãã ãããã£ãŠãã¡ãã»ãŒãžã®æåŸã®å
¥åã®ããŒããèšç®ã§ããŸãã ãã®æåŸã®æž¬å®å€ããµãŒããŒæž¬å®å€ä»¥äžã§ããå ŽåããµãŒããŒããŸã èŠãŠããªãå
¥åãå°ãªããšã1ã€å«ãŸããŠããããšãããããŸãã ãããããªããããã¯ãã¹ãŠã®æ°ããå
¥åããŒã¿ãã·ãã¥ã¬ãŒãããŸãã
å
¥åã¡ãã»ãŒãžã®åé·ãªå
¥åããŒã¿ã®éãå¶éãããšãååãªæ°ã®å
¥åã¡ãã»ãŒãžã倱ããããšããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®éã«ã·ãã¥ã¬ãŒã·ã§ã³ã®ã®ã£ãããçããããšã«æ°ã¥ãããããããŸããã ã€ãŸãããµãŒããŒã¯ã¡ãžã£ãŒ100ãã·ãã¥ã¬ãŒãããã¹ããŒã¿ã¹ã¡ãã»ãŒãžãéä¿¡ããŠã¡ãžã£ãŒ101ãéå§ããŠãããã¡ãžã£ãŒ105ããå§ãŸãå
¥åã¡ãã»ãŒãžãåä¿¡ã§ããŸããäžèšã®ã³ãŒãã§ã¯ããµãŒããŒã¯105ã«é²ã¿ãææ°ã®æ¢ç¥ã®å
¥åããŒã¿ã«åºã¥ããŠäžéã¡ãžã£ãŒãã·ãã¥ã¬ãŒãããŸããã ããªãããããå¿
èŠãšãããã©ããã¯ããªãã®æ±ºå®ãšã²ãŒã ãã©ãããã¹ããã«äŸåããŸãã å人çã«ã¯ããããã¯ãŒã¯ã®ç¶æ
ãæªãããããµãŒããŒããããäžã§ãã¬ãŒã€ãŒãæšæž¬ããŠç§»åããããšã匷å¶ããŸããã æ¥ç¶ãå埩ãããŸã§ããã¬ãŒã€ãŒããã®ãŸãŸã«ããŠããæ¹ãè¯ããšèããŠããŸãã
Zen of Networked Physicsãã¢ã«ã¯ãã¯ã©ã€ã¢ã³ãã«ãããéèŠãªåãããéä¿¡ããæ©èœããããŸããã€ãŸãã以åã«éä¿¡ãããå
¥åãšç°ãªãå Žåã«ã®ã¿ãåé·ãªå
¥åããŒã¿ãéä¿¡ããŸãã ããã¯å
¥åãã«ã¿å§çž®ãšåŒã°ããããã䜿çšããŠå
¥åã¡ãã»ãŒãžã®ãµã€ãºãããã«åæžã§ããŸãã ãã ãããã®ãã¢ã§ã¯ãããã¯ãŒã¯è² è·ã®æé©åããªãããããããŸã§ã®ãšãããããè¡ã£ãŠããŸããã
åé·ãªå
¥åããŒã¿ãéä¿¡ããåïŒãã±ããã®25ïŒ
ã倱ãããå Žåããã¥ãŒãã®åãã¯é
ããŠçæ£ããåŒãç¶ãã¹ããŒããã¯ãããŸããåé·ãªå
¥åããŒã¿ãéä¿¡ããåŸïŒãã±ããã®25ïŒ
ã倱ãããå Žåã§ããè£æ£ã¯åŒãããããŸããããã¥ãŒãã¯èš±å®¹å¯èœãªé床ã§ç§»åããŸããå¯å€ã¹ãããã·ã§ããé »åºŠ
ãã®ãã¢ã§ã¯ããµãŒããŒãã¯ã©ã€ã¢ã³ãã«ã¹ãããã·ã§ãããéä¿¡ããé »åºŠãç°ãªããŸãã é »åºŠãæžãããšãã¯ã©ã€ã¢ã³ãã¯ãµãŒããŒããä¿®æ£ãåä¿¡ããã®ã«ããå€ãã®æéãå¿
èŠã«ãªããŸãã ãããã£ãŠãã¯ã©ã€ã¢ã³ããäºæž¬ãééããå Žåãã¹ããŒã¿ã¹ã¡ãã»ãŒãžãåä¿¡ããåã«ãã¯ã©ã€ã¢ã³ãã¯ããã«éžè±ããå¯èœæ§ããããããã«ãããããé¡èãªä¿®æ£ãããããããŸãã ã¹ãããã·ã§ããã®é »åºŠãé«ãå Žåããã±ããæå€±ã¯ããã»ã©éèŠã§ã¯ãªããããã¯ã©ã€ã¢ã³ãã¯æ¬¡ã®ã¹ãããã·ã§ãããåä¿¡ããããã«é·ãåŸ
ã€å¿
èŠã¯ãããŸããã
ã¹ãããã·ã§ããåšæ³¢æ°64 Hzã¹ãããã·ã§ããåšæ³¢æ°16 Hzã¹ãããã·ã§ããåšæ³¢æ°2 Hzæããã«ãã¹ãããã·ã§ããã®é »åºŠã¯é«ãã»ã©è¯ãã®ã§ãã§ããã ãé »ç¹ã«éä¿¡ããå¿
èŠããããŸãã ãã ãã远å ã®ãã©ãã£ãã¯ã®éããã®ã³ã¹ããå°çšãµãŒããŒã®å¯çšæ§ããµãŒããŒã®ã³ã³ãã¥ãŒãã£ã³ã°ã³ã¹ããªã©ã«äŸåããŸãã
å¹³æ»åè£æ£
äžæ£ç¢ºãªäºæž¬ãäœæããå¿
èŠä»¥äžã«ãããããããä¿®æ£ãååŸããŸãã Unity / PhysXçµ±åãžã®é©åãªã¢ã¯ã»ã¹ãªãã§ã¯ããããã®èª€ã£ãäºæž¬ããããã°ããããšã¯ã»ãšãã©ã§ããŸããã ç§ã¯ãããåã«èšã£ãããç§ã¯åã³ç¹°ãè¿ã-ããªããç§ãééã£ãŠããç©çåŠã«é¢é£ããäœããèŠã€ããããããã«ã€ããŠç§ã«ç¥ãããŠãã ããã
å€ãè¯ãã¹ã ãŒãžã³ã°ã§äºè£ãå
æ²¢åããããšã§ããã®åé¡ã®è§£æ±ºçãåé¿ããŸããïŒ ä¿®æ£ãè¡ããããšãã¯ã©ã€ã¢ã³ãã¯ãã¬ãŒã€ãŒã®äœçœ®ãšå転ãããã€ãã®ãã¬ãŒã ã®æ£ããç¶æ
ã®æ¹åã«åçŽã«æ»ããã«ããŸãã ç©çãã¥ãŒãèªäœã¯å³åº§ã«ä¿®æ£ãããŸãïŒé衚瀺ïŒãã衚瀺å°çšã®2çªç®ã®ãã¥ãŒãããããã¹ã ãŒãžã³ã°ãå¯èœã§ãã
Vector3 position_error = state_msg.position - predicted_state.position; float rotation_error = 1.f - Quaternion.Dot(state_msg.rotation, predicted_state.rotation); if (position_error.sqrMagnitude > 0.0000001f || rotation_error > 0.00001f) { Rigidbody player_rigidbody = player.GetComponent<Rigidbody>();
誀ã£ãäºæž¬ãçºçãããšãã¯ã©ã€ã¢ã³ãã¯ä¿®æ£åŸã®äœçœ®/å転差ãç£èŠããŸãã äœçœ®è£æ£ã®åèšè·é¢ã2ã¡ãŒãã«ãè¶
ããå Žåãç«æ¹äœã¯åçŽã«åããŸã-ã¹ã ãŒãžã³ã°ã¯ââäŸç¶ãšããŠæªãèŠããã®ã§ãå°ãªããšãã§ããã ãæ©ãæ£ããç¶æ
ã«æ»ããŸãã
this.client_pos_error *= 0.9f; this.client_rot_error = Quaternion.Slerp(this.client_rot_error, Quaternion.identity, 0.1f); this.smoothed_client_player.transform.position = player_rigidbody.position + this.client_pos_error; this.smoothed_client_player.transform.rotation = player_rigidbody.rotation * this.client_rot_error;
åãã¬ãŒã ã§ãã¯ã©ã€ã¢ã³ãã¯lerp / slerpãæ£ããäœçœ®/å転ã«åããŠ10ïŒ
å®è¡ããŸããããã¯ãåããå¹³ååããããã®æšæºã®ã¹ãä¹åã¢ãããŒãã§ãã ãã¬ãŒã ã¬ãŒãã«ãã£ãŠç°ãªããŸããããã¢ã®ç®çã«ã¯ããã§ååã§ãã
250ããªç§ã®é
å»¶
ããã±ãŒãžã®10ïŒ
ã倱ã£ã
ã¹ã ãŒãžã³ã°ãªãã§ã¯ãè£æ£ã¯éåžžã«é¡èã§ã250ããªç§ã®é
å»¶
ããã±ãŒãžã®10ïŒ
ã倱ã£ã
ã¹ã ãŒãžã³ã°ã䜿çšãããšãä¿®æ£ãèªèãã«ãããªããŸããæçµçµæã¯ããªãããŸããããŸãããã±ãããæš¡å£ããã®ã§ã¯ãªããå®éã«ãã±ãããéä¿¡ããããŒãžã§ã³ãäœæããããšæããŸãã ããããå°ãªããšãããã¯ãç©ççãªãã©ã°ã€ã³ãªã©ãå¿
èŠãšããã«Unityã§å®éã®ç©çãªããžã§ã¯ãã䜿çšããã¯ã©ã€ã¢ã³ãåŽäºæž¬ã·ã¹ãã ã®æŠå¿µå®èšŒã§ãã