ã¯ããã«
ãã®èšäºã§ã¯ãUnity3Dã§ã²ãŒã ãéçºããéã®ã¡ãã»ãŒãžã·ã¹ãã ã«åºã¥ããã²ãŒã ããžãã¯ã®ã³ã³ããŒãã³ãã®ããœããã³ãã¥ãã±ãŒã·ã§ã³ãã®å¯èœæ§ã®å®è£ ã«é¢é£ãããããã¯ã«ã€ããŠèª¬æããŸãã
倧éšåã®å Žåããšã³ãžã³ãåºæ¬çãªåœ¢ã§æäŸããããŒã«ã§ã¯ãã²ãŒã ã®ã³ã³ããŒãã³ãéã§ããŒã¿äº€æã·ã¹ãã ãå®å šã«å®è£ ããã«ã¯äžååã§ããããšã¯åšç¥ã®äºå®ã§ãã 誰ããå§ããæãåå§çãªããŒãžã§ã³ã§ã¯ããªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãéããŠæ å ±ãååŸããŸãã ãã®ã€ã³ã¹ã¿ã³ã¹ã¯ãã·ãŒã³ãªããžã§ã¯ããžã®åç §ããé¢æ°ã®æ€çŽ¢ãŸã§ãããŸããŸãªæ¹æ³ã§ååŸã§ããŸãã ããã¯äŸ¿å©ã§ã¯ãªããã³ãŒãã®æè»æ§ã倱ãããããã°ã©ããŒã¯ããªããžã§ã¯ããã·ãŒã³ããæ¶ãããããããªããžã§ã¯ããéã¢ã¯ãã£ãã«ãªãããŸã§ãå€ãã®éæšæºã®ããžãã¯åäœã匷å¶ããããšã«ãªããŸãã ãšããããèšè¿°ãããã³ãŒãã®é床ãäœäžããå¯èœæ§ããããŸãã
åé¡ã®è§£æ±ºæ¹æ³ãæ€èšããåã«ããã®åæãšåºæ¬çãªçšèªã«ã€ããŠè©³ãã説æããŸããããã«ã€ããŠã¯ä»¥äžã§èª¬æããŸãã ããããããœãããªã³ã¯ãšã¯ã©ãããæå³ã§ããã ãã®å Žåãã²ãŒã ããžãã¯ã®ã³ã³ããŒãã³ãéã§ããŒã¿ã亀æãããããããããã®ã³ã³ããŒãã³ãã¯äºãã«ã€ããŠãŸã£ããäœãç¥ããŸããã ããã«åºã¥ããŠãã·ãŒã³ãªããžã§ã¯ããžã®åç §ããŸãã¯ååãŸãã¯ã¿ã€ãã«ããã·ãŒã³å ã®ãªããžã§ã¯ãã®æ€çŽ¢ã¯ããããŒããªã³ã¯ããæäŸããŸãã ãããã®æ¥ç¶ãé£éããŠäžŠãã§ããå Žåãããžãã¯ã®åäœãå€æŽããå¿ èŠãããå Žåãããã°ã©ãã¯ãã¹ãŠãåæ§æããå¿ èŠããããŸãã æšæž¬ããã®ã¯é£ãããªãã®ã§ãæè»æ§ã¯ããã§ã¯èããããŸããã ãã¡ãããèªåçã«ãªã³ã¯ãåãããšãã£ã¿ãŒæ¡åŒµæ©èœãäœæã§ããŸãããããã¯å¥ã®åé¡ãã²ãŒã ããžãã¯ã®ã³ã³ããŒãã³ããã¹ãã解決ããŸããã
äžèšã®èšè¿°ãããæ確ã«ããããã«ãç°¡åãªäŸãèããŠã¿ãŸãããã çäœã²ãŒã ã®ããžãã¯ã«ã¯ãæŠåšãæµã匟䞞ãªã©ãããã€ãã®èŠçŽ ããããŸãã æŠåšãçºå°ããåŸã次ã®æ å ±ãååŸããå¿ èŠããããŸãïŒåŒŸäžžãæµã«åœãã£ããã©ãããåœãã£ãå Žåããããæµã«ã©ãã ãã®ãã¡ãŒãžãäžãããããã¡ãŒãžãäžããå Žåãæµãæ»ãã ãã©ããã ããã«ããã®æ å ±ã®äžéšãä»ã®ã³ã³ããŒãã³ãïŒããšãã°ãäžãããããã¡ãŒãžã®éãæµãæã£ãŠããå¥åº·ã®éãæŠåšã®åŒŸè¬ã®éã衚瀺ããã°ã©ãã£ã«ã«ã€ã³ã¿ãŒãã§ã€ã¹ãªã©ïŒã«è»¢éããå¿ èŠããããŸãã ããã«ã¯ãã·ã§ãããããããã¢ãã¡ãŒã·ã§ã³ãªã©ã®å¯Ÿå¿ãããšãã§ã¯ãã®è¡šç€ºãå«ãŸããŸãã...é¢ä¿ãšéä¿¡ããŒã¿ã®æ°ãæ³åããããšã¯é£ãããããŸããã ãã ããããã¯ãããŒããªã³ã¯ãã«å®è£ ã§ããŸãããã ãã匟䞞ã®ããžãã¯ããã¹ãããå¿ èŠãããå ŽåãæŠåšãæµããŸã ãªãå ŽåããŸãã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®ããžãã¯ããã¹ãã§ããå Žåã¯ã©ããªããŸãããæŠåšã®ããžãã¯ãŸãã¯åŒŸäžžã§ã¯ãªãæµã§ãããã匟䞞ããã±ãã匟ã«çœ®ãæããããšèããŠããŸããã ãã®ãããªåé¡ã®è§£æ±ºçã¯ãããœããã³ãã¥ãã±ãŒã·ã§ã³ãã·ã¹ãã ãäœæããå¿ èŠæ§ã決å®ããããšã§ããããã«ãããååšããªãå Žåã§ãããŸããŸãªã³ã³ããŒãã³ããç°¡åã«ã·ãã¥ã¬ãŒãããé¢é£ããã³ãŒããå€æŽããã«ããããå€æŽã§ããŸãã
ããœããã³ãã¥ãã±ãŒã·ã§ã³ãã®å®è£ ã®åºæ¬ååã«ã€ããŠè©³ãã説æããŸãã åè¿°ã®ããã«ã2ã€ã®ã³ã³ããŒãã³ããããœããã«ãæ¥ç¶ããã«ã¯ãäžæ¹ããä»æ¹ã«ããŒã¿ã転éããå¿ èŠããããŸããããã«ãããã³ã³ããŒãã³ããäºãã«ã€ããŠäœãç¥ããªãããã«ãªããŸãã ããã確å®ã«ããããã«ããªã¯ãšã¹ãã§ã¯ãªãïŒãªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ãæã«æã£ãŠïŒããŒã¿ãåä¿¡ããå¿ èŠããããŸãããéç¥ã¡ã«ããºã ã䜿çšããŸãã å®éãããã¯ããªããžã§ã¯ã/ã³ã³ããŒãã³ãã§ã€ãã³ããçºçãããšãã«ããã®ãªããžã§ã¯ãã«ãã®ç¶æ ãåãåãããããªããžã§ã¯ãèªäœãå€æŽãçºçããããšãéç¥ããããšãæå³ããŸãã ãã®ãããªéç¥ã®ã»ããã¯ã€ã³ã¿ãŒãã§ãŒã¹ã圢æãïŒCïŒã®ã€ã³ã¿ãŒãã§ãŒã¹ãšæ··åããªãã§ãã ããïŒãã²ãŒã ããžãã¯ããªããžã§ã¯ãã«é¢ããããŒã¿ãåä¿¡ããã®ãå©ããŸãã ããã¯æ¬¡ã®ããã«èŠèŠåã§ããŸãã
ãããã£ãŠãéç¥ã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠã·ã¹ãã ã®ã©ã®ã³ã³ããŒãã³ããã²ãŒã ããžãã¯ã®ãªããžã§ã¯ãã«é¢ããå¿ èŠãªããŒã¿ãåä¿¡ã§ããŸããããªããžã§ã¯ãèªäœã®ååšã¯ããã«é¢é£ä»ããããã³ã³ããŒãã³ãããã¹ãããããã«å¿ èŠã§ã¯ãããŸããããã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãããããäœæ¥ã€ã³ã¹ã¿ã³ã¹ã«çœ®ãæããã ãã§ãã
äžèšã®ã¡ã«ããºã ãå®è£ ããæ¹æ³ãããã³ãããã®é·æãšçæããã詳现ã«æ€èšããŠã¿ãŸãããã
UnityEvents / UnityActionã¡ãã»ãŒãžã³ã°ã·ã¹ãã
ãã®ã·ã¹ãã ã¯æ¯èŒçæè¿ç»å ŽããŸããïŒUnity3Dãšã³ãžã³ã®ããŒãžã§ã³5ïŒã ãã®ãªã³ã¯ã§ã¯ãç°¡åãªã¡ãã»ãŒãžã³ã°ã·ã¹ãã ã®å®è£ æ¹æ³ã®äŸãèŠã€ããããšãã§ããŸãã
ãã®æ¹æ³ã䜿çšããé·æïŒ
- çµã¿èŸŒã¿ã®Unityæ©èœã
çæïŒ
- Unityã«çµã¿èŸŒãŸããæ©èœïŒåžžã«ãã€ãã£ãã·ã¹ãã ãåªããŠãããšã¯éããŸããïŒã
- UnityActionã䜿çšããŠããããïŒããã¯åé¿ã§ããŸããïŒããã©ã¡ãŒã¿ãŒã®æ°ã«å¶éããããŸãïŒæ倧4ã€ïŒãããæè»æ§ããããŸããã
- ã³ãŒãã®å€ãã®å Žæã§ã¿ã€ãããã³ãã©ãŒãªã©ãå€æŽããå¿ èŠããããããã¡ãã»ãŒãžã®ãã©ã¡ãŒã¿ãŒãå€æŽããã®ãé£ãããããæè»æ§ããããŸããã
- CïŒã«ã€ãã³ã/ããªã²ãŒããããå Žåã«äœ¿çšããçç±ã¯æ確ã§ã¯ãããŸããã
ã€ãã³ã/ããªã²ãŒãã®ã¯ã©ã·ã«ã«CïŒã·ã¹ãã
éç¥ããŒã¹ã®ã³ã³ããŒãã³ãéä¿¡ãå®è£ ããæãç°¡åã§å¹æçãªæ¹æ³ã¯ãCïŒèšèªã®äžéšã§ããã€ãã³ã/ããªã²ãŒããã¢ã䜿çšããããšã§ãïŒè©³çŽ°ã«ã€ããŠã¯ãhabrãŸãã¯msdnã®èšäºãåç §ããŠãã ããïŒã
ã€ãã³ã/ããªã²ãŒãããŒã¹ã®ã¡ãã»ãŒãžã³ã°ã·ã¹ãã ãå®è£ ããããã®ããŸããŸãªãªãã·ã§ã³ãããããã®äžéšã¯ã€ã³ã¿ãŒãããäžã«ãããŸãã ç§ã®æèŠã§ã¯ãæã䟿å©ãªã·ã¹ãã ã®äŸãæããŸãããæåã«ãã€ãã³ãã®äœ¿çšã«é¢é£ããéèŠãªè©³çŽ°ã«ã€ããŠèšåããŸãã ã€ãã³ãã«ãµãã¹ã¯ã©ã€ãããªãå Žåããã®ã€ãã³ããåŒã³åºããããšãšã©ãŒãçºçããããã䜿çšããåã«nullãã§ãã¯ãå¿ èŠã§ãã ããã¯å®å šã«äŸ¿å©ãšããããã§ã¯ãããŸããã ãã¡ãããnullãã§ãã¯ãå®è¡ãããã€ãã³ãããšã«ã©ãããŒãäœæã§ããŸãããããã¯ããã«äžäŸ¿ã§ãã å®è£ ã«ç§»ããŸãããã
ãŸããããžãã¯ãªããžã§ã¯ãã®ã¡ãã»ãŒãžã€ã³ã¿ãŒãã§ã€ã¹ãå®çŸ©ããŸãã
// Message Interface public partial class GameLogicObject { public delegate void StartEventHandler(); public delegate void ChangeHealthEventHandler(int health); public delegate void DeathEventHandler(); public static event StartEventHandler StartEvent; public static event ChangeHealthEventHandler ChangeHealthEvent; public static event DeathEventHandler DeathEvent; }
éç¥åŒã³åºãã¯æ¬¡ã®ããã«è¡ãããŸãïŒäŸïŒã
public partial class GameLogicObject : MonoBehaviour { public int Health = 100; void Start() { if (StartEvent != null) { StartEvent(); } StartCoroutine(ChangeHealth()); } IEnumerator ChangeHealth() { yield return new WaitForSeconds(1f); Health = Mathf.Clamp(Health - UnityEngine.Random.Range(1, 20), 0, 100); if (ChangeHealthEvent != null) { ChangeHealthEvent(Health); } if (Health == 0) { if (DeathEvent != null) { DeathEvent(); } }else { StartCoroutine(ChangeHealth()); } } }
ã€ã³ã¿ãŒãã§ã€ã¹ãšããžãã¯ã圢æãããŸããããä»ã®å Žæã§äœ¿çšããããå¿
èŠãªéç¥ããµãã¹ã¯ã©ã€ããããããããšã劚ãããã®ã¯äœããããŸããã
public class GUILogic : MonoBehaviour { public Text HealthInfo; public Text StateInfo; void OnEnable() { GameLogicObject.StartEvent += GameLogicObject_StartEventHandler; GameLogicObject.ChangeHealthEvent += GameLogicObject_ChangeHealthEventHandler; GameLogicObject.DeathEvent += GameLogicObject_DeathEventHandler; } private void GameLogicObject_DeathEventHandler() { StateInfo.text = "Im died"; } private void GameLogicObject_ChangeHealthEventHandler(int healthValue) { HealthInfo.text = healthValue.ToString(); } private void GameLogicObject_StartEventHandler() { StateInfo.text = "Im going"; } void OnDisable() { GameLogicObject.StartEvent -= GameLogicObject_StartEventHandler; GameLogicObject.ChangeHealthEvent -= GameLogicObject_ChangeHealthEventHandler; GameLogicObject.DeathEvent -= GameLogicObject_DeathEventHandler; } }
äŸãããããããã«ããµãã¹ã¯ãªãã·ã§ã³ã¯OnEnableã¡ãœããã§çºçãããã®å ŽåãOnDisableã§ã®ãµãã¹ã¯ã©ã€ã解é€ã¯å¿ é ã§ããããããªããšããªããžã§ã¯ããã²ãŒã ããåé€ãããå Žåã«ã¡ã¢ãªãªãŒã¯ãšnullåç §äŸå€ãä¿èšŒãããŸãã ãµãã¹ã¯ãªãã·ã§ã³èªäœã¯å¿ èŠãªãšãã«ãã€ã§ãå®è¡ã§ããŸããOnEnableã§ã®ã¿ãããè¡ãå¿ èŠã¯ãããŸããã
ãã®ã¢ãããŒãã䜿çšãããšãå®éã®GameLogicObjectããžãã¯ããªããŠãã GUILogicã¯ã©ã¹ã®åäœãåé¡ãªããã¹ãã§ããããšã«æ°ä»ãã®ã¯ç°¡åã§ãã éç¥ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšãã GameLogicObject.StartEvent ïŒïŒã®åœ¢åŒã®åŒã³åºãã䜿çšããã·ãã¥ã¬ãŒã¿ãŒãäœæããã ãã§ãã
ãã®å®è£ ã®å©ç¹ã¯äœã§ããïŒ
- CïŒèšèªã®æšæºã¡ã«ããºã ãã¿ã³ããªã³ãšèžããã«100ïŒ ã¯ãã¹ãã©ãããã©ãŒã ã§ããããã
- ã·ã¹ãã å®è£ ã®åçŽãïŒã³ãŒããžã®è¿œå æè³ãªãïŒã
çæïŒ
- ã¡ã¢ãªãç£èŠããå¿ èŠããããŸãïŒéç¥ãããµãã¹ã¯ã©ã€ã解é€ïŒã 倧éã®ã³ãŒãã䜿çšãããšã1ã€ã®ã€ãã³ãã®ãµãã¹ã¯ãªãã·ã§ã³ã解é€ããŠãããé·æéãã°ããã£ããããã®ãå¿ããã¡ã§ãã
- ã·ãŒã³ãªããžã§ã¯ããäžæçã«éã¢ã¯ãã£ãåãããŠããå Žåãã€ãã³ãã®ãµãã¹ã¯ã©ã€ãã解é€ããå¿ èŠããããŸããããã§ãªãå Žåã¯ããã³ãã©ãŒãåŒã³åºãããŸãã
- ã³ãŒãã®å€ãã®å Žæã§ã¿ã€ãããã³ãã©ãŒãåŒã³åºããªã©ãå€æŽããå¿ èŠããããããã¡ãã»ãŒãžãã©ã¡ãŒã¿ãŒã®å€æŽãé£ãããããæè»æ§ããããŸããã
- ã€ãã³ãã«ã¯è³Œèªè ãããªãå Žåãããããšã«æ³šæããŠãã ããã
æååã®èå¥ãåããåå°ã¡ãã»ãŒãžã·ã¹ãã
ã·ã¹ãã ãšãã®å®è£ ã®èª¬æã«é²ãåã«ããã®äœæãæšé²ããåæã«ã€ããŠè©³ãã説æããŸãã ç§ã®ã¢ããªã±ãŒã·ã§ã³ã§ãããã®ããšãèããåã«ãäžèšã®ã€ãã³ã/ããªã²ãŒãããŒã¹ã®ã·ã¹ãã ã䜿çšããŸããã ç§ãåœæéçºããªããã°ãªããªãã£ããããžã§ã¯ãã¯æ¯èŒçåçŽã§ãå®è£ ã®é床ããã¹ãã§ã®ãã°ã®æå°åãã²ãŒã ããžãã¯ã®éçºæ®µéã«ããã人çèŠå ã®æ倧å€ã®äŸå€ãå¿ èŠã§ããã ããã«åºã¥ããŠãã³ã³ããŒãã³ãéã®ããŒã¿äº€æã«é¢ããããã€ãã®èŠä»¶ãçãŸããŸããã
- ã€ãã³ãã®èªåãµãã¹ã¯ãªãã·ã§ã³ã
- ã¡ã¢ãªãç£èŠããå¿ èŠã¯ãããŸããïŒã·ã¹ãã ã®èªåã¯ãªãŒãã³ã°ïŒã
- å å ¥è ãç£èŠããå¿ èŠã¯ãããŸãããããã§ãªãå Žåã§ãã·ã¹ãã ã¯åäœããã¯ãã§ãã
ããã€ãã®èãã®çµæã¯ãã¯ã©ã¹/ã³ã³ããŒãã³ãã¡ãœããã®å±æ§ãéããŠãªãã¬ã¯ã·ã§ã³ã䜿çšãããšããã¢ã€ãã¢ã®èªçã§ããã
ã¯ã©ã¹ã¡ãœãããã€ãã³ããã³ãã©ãšããŠèå¥ããŸãã
[GlobalMessanger.MessageHandler] void OnCustomEvent(int param) { }
GlobalMessanger.MessageHandler-ã¡ãœãããã€ãã³ããã³ãã©ãŒã§ããããšãéç¥ããå±æ§ã ãã®ã¡ãœãããåŠçããã€ãã³ãã®ã¿ã€ããå€å¥ããã«ã¯ã2ã€ã®æ¹æ³ããããŸãïŒå®éã«ã¯ããã«å€ãã®æ¹æ³ããããŸãïŒã
- å±æ§ãã©ã¡ãŒã¿ãŒã§ã€ãã³ãã®ã¿ã€ããæå®ããŸãã
[GlobalMessanger.MessageHandler("CustomEvent")]
- ã¡ãœããåã«ãã¬ãã£ãã¯ã¹ãOnãïŒãŸãã¯ãã®ä»ïŒãä»ããã€ãã³ãã¿ã€ãã䜿çšããŸãã ç§ã¯ãã®ç¹å®ã®ã¡ãœããã䜿çšããŸãã100ïŒ ã®å Žåãæ··ä¹±ããªãããã«ãã¡ãœããã®ååããã®ããã«ãªã£ãŠããããã§ãã
èªåçã«ãµãã¹ã¯ã©ã€ãããã«ã¯ãå床ã2ã€ã®æ¹æ³ããããŸãã
- ãªããžã§ã¯ãäžã®ãã¹ãŠã®ã³ã³ããŒãã³ããæ€çŽ¢ããã¹ã¯ãªããã䜿çšãããªãã¬ã¯ã·ã§ã³ãä»ããŠãå±æ§ãå«ãŸããã¡ãœãããæ¢ããŸãã ãã®ã¹ã¯ãªãããæåã§è¿œå ããªãããã«ããã«ã¯ãå¿
èŠãªãã¹ãŠã®ã³ã³ããŒãã³ãã«é
眮ããã ãã§ååã§ãã
[RequireComponent(typeof(AutoSubsciber))]
å人çã«ã¯ããã®æ¹æ³ã¯äœãåããå¿ èŠãããããã2çªç®ã®æ¹æ³ããã䟿å©ã§ã¯ãããŸããã
- MonoBehaviourã¯ã©ã¹ã®ã©ãããŒãäœæããŸãã
CustomBehaviourpublic class CustomBehaviour : MonoBehaviour { private BindingFlags m_bingingFlags = BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy; protected void Subscribe(string methodName) { var method = this.GetType().GetMethod(methodName, m_bingingFlags); GlobalMessanger.Instance.RegisterMessageHandler(this, method); } protected void Unsubscribe(string methodName) { var method = this.GetType().GetMethod(methodName, m_bingingFlags); GlobalMessanger.Instance.UnregisterMessageHandler(this, method); } protected virtual void Awake() { var methods = this.GetType().GetMethods(m_bingingFlags); foreach(MethodInfo mi in methods) { if(mi.GetCustomAttributes(typeof(GlobalMessanger.MessageHandler), true).Length != 0) { GlobalMessanger.Instance.RegisterMessageHandler(this, mi); } } } }
ã芧ã®ãšããããã®ã©ãããŒã«ã¯ãã€ãã³ãã®ãµãã¹ã¯ã©ã€ããšãµãã¹ã¯ã©ã€ã解é€ãå¯èœã«ãã2ã€ã®ã¡ãœãããå«ãŸããŠããŸãïŒã€ãã³ãã®ã¿ã€ãã¯ã¡ãœããåããååŸãããŸãïŒã ããžãã¯ã®é²è¡ã«åãããŠã€ãã³ãããµãã¹ã¯ã©ã€ãããå¿ èŠãããå Žåã«å¿ èŠã§ãã èªåãµãã¹ã¯ãªãã·ã§ã³ã¯Awakeã¡ãœããã§å®è¡ãããŸãã ã€ãã³ãã®ç»é²è§£é€ã¯èªåçã«å®è¡ãããŸãããããã«ã€ããŠã¯åŸã§è©³ãã説æããŸãã
ãµãã¹ã¯ãªãã·ã§ã³ãšã€ãã³ãã³ãŒã«ã®ç®¡çã·ã¹ãã ãå®çŸ©ããŸãã
public class GlobalMessanger : MonoBehaviour { private static GlobalMessanger m_instance; public static GlobalMessanger Instance { get { if(m_instance == null) { var go = new GameObject("!GlobalMessanger", typeof(GlobalMessanger)); m_instance = go.GetComponent<GlobalMessanger>(); } return m_instance; } } public class MessageHandler : Attribute { } private class MessageHandlerData { public object Container; public MethodInfo Method; } private Hashtable m_handlerHash = new Hashtable(); }
GlobalMessangerã¯ã©ã¹ã¯ãUnityã·ã³ã°ã«ãã³ã«åºã¥ããŠã¢ã¯ã»ã¹ãããéåžžã®Unityã³ã³ããŒãã³ãã§ãã åæã«ããã®ã³ã³ããŒãã³ãçšã«å¥ã®ã·ãŒã³ãªããžã§ã¯ããäœæãããŸãããã®ãªããžã§ã¯ãã¯å éšã«ã®ã¿ååšããã·ãŒã³ãã¢ã³ããŒãããããšåé€ãããŸãã ã€ãã³ãã¯æååã«åºã¥ããŠèå¥ããããããã€ãã³ããšãµãã¹ã¯ã©ã€ããŒã«é¢ããæ å ±ãããã·ã¥ããŒãã«ã«ä¿åããããšã«ããŸããã
ããã§ããµãã¹ã¯ã©ã€ããŒãç»é²/åé€ããã¡ãœãããå¿
èŠã§ãã
public void RegisterMessageHandler(object container, MethodInfo methodInfo) { var methodName = methodInfo.Name; var messageID = methodName.Substring(2); if (!m_handlerHash.ContainsKey(messageID)) { RegisterMessageDefinition(messageID); } var messageHanlders = (List<MessageHandlerData>)m_handlerHash[messageID]; messageHanlders.Add(new MessageHandlerData() { Container = container, Method = methodInfo }); } public void UnregisterMessageHandler(object container, MethodInfo methodInfo) { var methodName = methodInfo.Name; var messageID = methodName.Substring(2); if (m_handlerHash.ContainsKey(messageID)) { var messageHanlders = (List<MessageHandlerData>)m_handlerHash[messageID]; for (var i = 0; i < messageHanlders.Count; i++) { var mhd = messageHanlders[i]; if (mhd.Container == container && mhd.Method == methodInfo) { messageHanlders.Remove(mhd); return; } } } }
次ã«ãã€ãã³ããšã€ãã³ãã®ãµãã¹ã¯ã©ã€ããŒãåŒã³åºãã¡ãœãããå¿
èŠã§ãã
public void Call(string messageID, object[] parameter = null) { if (m_handlerHash.ContainsKey(messageID)) { var hanlderList = (List<MessageHandlerData>) m_handlerHash[messageID]; for(var i = 0; i < hanlderList.Count; i++) { var mhd = hanlderList[i]; var unityObject = (MonoBehaviour)mhd.Container; if (unityObject != null) { if (unityObject.gameObject.activeSelf) { mhd.Method.Invoke(mhd.Container, parameter); } } else { m_removedList.Add(mhd); } } for (var i = 0; i < m_removedList.Count; i++) { hanlderList.Remove(m_removedList[i]); } m_removedList.Clear(); } }
ã芧ã®ãšãããã€ãã³ããåŒã³åºããããšããªããžã§ã¯ãã®ååšãšãªããžã§ã¯ãã®ã¢ã¯ãã£ããã£ããã§ãã¯ãããŸãã æåã®ã±ãŒã¹ã§ã¯ãåé€ããããªããžã§ã¯ãã¯ãµãã¹ã¯ã©ã€ããŒããåé€ãããŸã; 2çªç®ã®ã±ãŒã¹ã§ã¯ãã€ãã³ãåŠçã¡ãœãããåŒã³åºããšãã«ç¡èŠãããŸãã ãããã£ãŠããªã¢ãŒããªããžã§ã¯ãããã®ã€ãã³ãã®ãµãã¹ã¯ã©ã€ã解é€ãç£èŠããå¿ èŠã¯ãªãããã¹ãŠãèªåçã«è¡ãããŸãã ãã®å Žåããªããžã§ã¯ããäžæçã«éã¢ã¯ãã£ãåãããå Žåãã€ãã³ããããµãã¹ã¯ã©ã€ã解é€ããŠåãµãã¹ã¯ã©ã€ãããã ãã§ãªããåŒã³åºãæã«ãã€ãã³ãã®ãµãã¹ã¯ã©ã€ããŒã®ååšã¯å¿ èŠãããŸããã
æåŸã«å¿
èŠãªããšã¯ãã·ãŒã³ãã¢ã³ããŒãããããã«ã¯ãªãŒãã³ã°ãå®è¡ããããšã§ãã
void OnDestroy() { foreach(var handlers in m_handlerHash.Values) { var messageHanlders = (List<MessageHandlerData>)handlers; messageHanlders.Clear(); } m_handlerHash.Clear(); m_handlerHash = null; }
äžèšã®ã·ã¹ãã ã¯ç¹å¥ãªãã®ã§ã¯ãªããå瀺ããããããªãããšã¯å®¹æã«ããããŸãããã·ã³ãã«ã§äŸ¿å©ã§ãããæ¯èŒçå°ããªãããžã§ã¯ãã«é©ããŠããŸãã
ãã®ã·ã¹ãã ã®äœ¿çšäŸïŒ
// Message Interface public partial class GameLogicObject { public static void StartEvent() { GlobalMessanger.Instance.Call("StartEvent"); } public static void ChangeHealthEvent(int value) { GlobalMessanger.Instance.Call("ChangeHealthEvent", new object[] { value }); } public static void DeathEvent() { GlobalMessanger.Instance.Call("DeathEvent"); } } // Event source public partial class GameLogicObject : MonoBehaviour { public int Health = 100; void Start() { StartEvent(); StartCoroutine(ChangeHealth()); } IEnumerator ChangeHealth() { yield return new WaitForSeconds(1f); Health = Mathf.Clamp(Health - UnityEngine.Random.Range(1, 20), 0, 100); ChangeHealthEvent(Health); if (Health == 0) { DeathEvent(); }else { StartCoroutine(ChangeHealth()); } } } // Event subsciber public class GUILogic : MonoBehaviour { public Text HealthInfo; public Text StateInfo; [GlobalMessanger.MessageHandler] private void OnDeathEvent() { StateInfo.text = "Im died"; } [GlobalMessanger.MessageHandler] private void OnChangeHealthEvent(int healthValue) { HealthInfo.text = healthValue.ToString(); } [GlobalMessanger.MessageHandler] private void OnStartEvent() { StateInfo.text = "Im going"; } }
ã€ãã³ã/ããªã²ãŒãã«æ¯ã¹ãŠã³ãŒããã©ãã ãåæžãããŠããããããã«ããããšæããŸãã
ãã®å®è£ ã®å©ç¹ã¯äœã§ããïŒ
- ã€ãã³ãã®èªåãµãã¹ã¯ãªãã·ã§ã³ã
- ã€ãã³ãã®è³Œèªè§£é€ã远跡ããå¿ èŠã¯ãããŸããïŒæå賌èªã®å Žåã§ãïŒã
- æ¯èŒçåçŽãªå®è£ ã
- å±æ§ã«ãããã³ãŒããç°¡åã«èªã¿åãããšãã§ãã誰ãã€ãã³ããã³ãã©ãŒã§ãããã©ã®ãã³ãã©ãŒã§ããããç°¡åã«ç¢ºèªã§ããŸãã
- ã€ãã³ã/ããªã²ãŒãã«æ¯ã¹ãŠå°ãªãã³ãŒã
- ã€ãã³ãã«è³Œèªè ãããªããšèããå¿ èŠã¯ãããŸããã
çæïŒ
- éåžžã«å€§ããªãããžã§ã¯ãã§ã¯ãã€ãã³ãã®ãµãã¹ã¯ã©ã€ã解é€ã¯é 延ã¢ãŒãã§çºçãããããããããäœåãªã¡ã¢ãªãæ¶è²»ããŸãããã€ãã³ã/ããªã²ãŒãã®ã»ã¯ã·ã§ã³ã§ç€ºããæ¹æ³ãšåæ§ã«ãæåã§ã€ãã³ãããµãã¹ã¯ã©ã€ã解é€ããããšã§ç°¡åã«è§£æ±ºã§ããŸãã
- ã€ãã³ãåãããçŸãããããå Žåã¯ãå€ãã®å Žæã§å€æŽããå¿ èŠããããããæååãžã®ãã€ã³ãã
- ãã©ã¡ãŒã¿ãŒãšã€ãã³ãããŒã¿ã®çš®é¡ã«æè»æ§ã¯ãããŸãããå€æŽã«ã¯ã³ãŒãã«å¯Ÿããå€ãã®ã¢ã¯ã·ã§ã³ãå¿ èŠã§ãã
- ãªãã¬ã¯ã·ã§ã³ã®äœ¿çšã«ãããã¯ãã¹ãã©ãããã©ãŒã ã®åé¡ãçºçããå¯èœæ§ããããŸãã
ããŒã¿åã®èå¥ãåãããªãã¬ã¯ã·ã§ã³ã¡ãã»ãŒãžã·ã¹ãã
åã®ã»ã¯ã·ã§ã³ã§ã¯ãã·ã¹ãã ã¯ã€ãã³ã/ããªã²ãŒããšæ¯èŒããŠïŒç§ã®æèŠã§ã¯ïŒãã䟿å©ã§ãããšèª¬æãããŸããããã³ãŒãã®æè»æ§ã«å€§ãã圱é¿ããããã€ãã®æ¬ ç¹ããŸã ããããã次ã®ã¹ãããã¯ãããã®èŠå ãèæ ®ããéçºã§ããã
ãã®ããã以åã®ã·ã¹ãã ã®ãã¹ãŠã®å©ç¹ãç¶æããå¿ èŠããããŸãããã²ãŒã ããžãã¯ã®å€æŽã«å¯Ÿããæè»æ§ãšèæ§ãé«ããå¿ èŠããããŸãã äž»ãªåé¡ã¯ã€ãã³ãã®ååãšéä¿¡ããããã©ã¡ãŒã¿ã®å€æŽã§ããããããããã«ãã£ãŠã€ãã³ããæ£ç¢ºã«èå¥ãããšããã¢ã€ãã¢ãçãŸããŸããã å®éãããã¯ãã³ã³ããŒãã³ãã§çºçããã€ãã³ãã¯ãéä¿¡ããããŒã¿ã®ã¿ã«ãã£ãŠç¹åŸŽä»ããããããšãæå³ããŸãã å€ãã®ã³ã³ããŒãã³ãããã®ãããªããŒã¿ãããžãã¯ã§éä¿¡ã§ãããããåçŽã«æšæºåïŒintãfloatãªã©ïŒã«æ·»ä»ããããšã¯ã§ããªããããè«çã¹ãããã¯ã䟿å©ã§èªã¿ããããæ確ã«è§£éã§ããã©ãããŒãäœæããããšã§ããã€ãã³ãã
ãããã£ãŠãã¡ãã»ãŒãžã€ã³ã¿ãŒãã§ã€ã¹ã¯æ¬¡ã®åœ¢åŒãåããŸããã
public partial class GameObjectLogic { [GEvents.EventDescription(HandlerRequirement = GEvents.HandlerRequirementType.NotRequired)] public sealed class StartEvent : GEvents.BaseEvent<StartEvent> { } [GEvents.EventDescription(HandlerRequirement = GEvents.HandlerRequirementType.Required)] public sealed class ChangeHealthEvent : GEvents.BaseEvent<ChangeHealthEvent> { public int Value { get; private set; } public ChangeHealthEvent(int value) { Value = value; } } [GEvents.EventDescription(HandlerRequirement = GEvents.HandlerRequirementType.Required)] public sealed class DeathEvent : GEvents.BaseEvent<DeathEvent> { } }
ã芧ã®ãšãããã€ãã³ãã«ã¯å±æ§ããããŸãã ããã«ãããã€ãã³ãã«ãµãã¹ã¯ã©ã€ããŒãå¿ èŠãªå Žåã«ãããã°æ å ±ãååŸããæ©äŒãäžããããŸãããäœããã®çç±ã§ã³ãŒãã«å«ãŸããŠããŸããã
以åã«GlobalMessangerã¯ã©ã¹ã®äžéšã§ãã£ãCallã€ãã³ãïŒããã³ãã®ãªãŒããŒããŒãïŒãåŒã³åºãã¡ãœããã¯éçã«ãªãã GEvents.BaseEventã«é 眮ãããã€ãã³ãã®ã¿ã€ããèšè¿°ããã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãåŒæ°ãšããŠåãåããŸãã
éç¥åŒã³åºãã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
public partial class GameLogicObject : MonoBehaviour { public int Health = 100; void Start() { StartEvent.Call(); // StartCoroutine(ChangeHealth()); } IEnumerator ChangeHealth() { yield return new WaitForSeconds(1f); Health = Mathf.Clamp(Health - UnityEngine.Random.Range(1, 20), 0, 100); ChangeHealthEvent.Call(new ChangeHealthEvent(Health)); // if (Health == 0) { DeathEvent.Call(); // }else { StartCoroutine(ChangeHealth()); } } }
ã€ãã³ãã®ãµãã¹ã¯ã©ã€ãããã³ãµãã¹ã¯ã©ã€ã解é€ã¯ãã¡ãœããã®å±æ§ãä»ããŠä»¥åãšåãæ¹æ³ã§å®è¡ãããŸãããã€ãã³ãã®ã¿ã€ãã®èå¥ã¯æååå€ïŒã¡ãœããåãŸãã¯å±æ§ãã©ã¡ãŒã¿ãŒïŒã§ã¯ãªããã¡ãœãããã©ã¡ãŒã¿ãŒã®ã¿ã€ãïŒãã®äŸã§ã¯StartEventã¯ã©ã¹ïŒã«ãã£ãŠè¡ãããŸãChangeHealthEventããã³DeathEventïŒã
ãã³ãã©ãŒã¡ãœããã®äŸïŒ
[GEvents.EventHandler] public void OnDeathEventHandler(GameLogicObject.DeathEvent ev) { // }
ãããã£ãŠãäžèšã®å®è£ ã䜿çšãããšãå€§å¹ ãªã³ã¹ãããããã«ã€ãã³ãã§éä¿¡ããŒã¿ãå€æŽã§ãããããæ°ãããã©ã¡ãŒã¿ãŒã®ãã³ãã©ãŒã®æ¬äœãå€æŽããã ãã§ååã§ãããããã³ãŒãã®æè»æ§ãæ倧éã«é«ããŸããã ã€ãã³ãã®ååïŒã¯ã©ã¹åïŒãå€æŽããå Žåãã³ã³ãã€ã©ã¯å€ãããŒãžã§ã³ã䜿çšãããŠããå Žæãéç¥ããŸãã ãã®å Žåããã³ãã©ãŒã¡ãœããã®ååãå€æŽããå¿ èŠã¯å®å šã«ãªããªããŸãã
ãŸãšã
ãã®èšäºã§ã¯ã䞻芳ã«åºã¥ããŠãéç¥ã«åºã¥ããŠã³ã³ããŒãã³ãéã§ããŒã¿äº€æã·ã¹ãã ãæ§ç¯ããæ¹æ³ããã¹ãŠèª¬æããããšããŸããã ãããã®æ¹æ³ã¯ãã¹ãŠãåçŽãªã¢ãã€ã«ãããžã§ã¯ãããè€éãªPCãŸã§ãããŸããŸãªãããžã§ã¯ããããŸããŸãªè€éãã§äœ¿çšãããŠããŸãã ãããžã§ã¯ãã§äœ¿çšããã·ã¹ãã ã¯ãŠãŒã¶ãŒæ¬¡ç¬¬ã§ãã
PSïŒãã®èšäºã§ã¯ãSendMessageé¢æ°ã«åºã¥ããã¡ãã»ãŒãžã·ã¹ãã ã®æ§ç¯ã«ã€ããŠãæå³çã«èª¬æãå§ããŸããã§ãããä»ã®ã·ã¹ãã ãšæ¯èŒãããšãå©äŸ¿æ§ã ãã§ãªããé床ã®é¢ã§ãæ¹å€ã«èããããªãããã§ãã