Upgrade to Pro — share decks privately, control downloads, hide ads and more …

さらば💩コード!Clean Architecture をマスターして次世代の Unity エンジニアになろう!/Let's master the Clean Architecture

さらば💩コード!Clean Architecture をマスターして次世代の Unity エンジニアになろう!/Let's master the Clean Architecture

2018/06/09 (Sat) に ABC 2018s (Unity Track 2) にて登壇した資料になります。

7b13f432547b92d04c79b749adb535e0?s=128

Tetsuya Mori

June 09, 2018
Tweet

Transcript

  1. גࣜձࣾΩοζελʔ CTO ৿ɹ఩࠸ ͞Β͹ίʔυʂ Clean Architecture Λ
 Ϛελʔͯ࣍͠ੈ୅ͷ
 Unity ΤϯδχΞʹͳΖ͏ʂ

    ABC 2018s @ 2018/06/09
  2. 2 ͜Μʹͪ͸ʂ

  3. 3 ಥવͰ͕͢ɺ ͜Μͳίʔυॻ͍ͯ·ͤΜ͔ʁ

  4. 4 ωετͷਂ͍ Update(), FixedUpdate()

  5. 5 1,000ߦΛ௒͑Δ GameManager.cs

  6. 6 SingletonMonoBehaviour Λ ܧঝͨ͠େྔͷ Manager Ϋϥε

  7. 7 ςετίʔυ͕1ߦ΋ ଘࡏ͠ͳ͍ϓϩδΣΫτ

  8. 8 ࠓ೔͸

  9. 9 ͜Μͳ…

  10. 10 ͳϓϩδΣΫτΛ ͳϓϩδΣΫτ΁ ੜ·ΕมΘΒͤΔํ๏

  11. 11 ʹ͍͓ͭͯ࿩͠͠·͢

  12. ࣗݾ঺հ 12

  13. w৿ɹ఩࠸ʢBLB΋ΜΓ͌ઌੜʣ w೥࡛ۄݝ࢈ wגࣜձࣾΩοζελʔ$50 wࡀϲ݄ͷ່ʹκοίϯ-07& w͓ञͱ߹এͱϓϩάϥϛϯά͕झຯ w5XJUUFS!NPOSZ(JU)VC!NPOSZ 13 Who am I

    ?
  14. w ࢠͲ΋޲͚εϚϗΞϓϦ
 ։ൃͳͲ w ೥͋ͨΓ͔Β
 6OJUZΨοπϦ w ͬ͜͝ϥϯυ
 ྦྷܭສ%- w

    "QQ4UPSF(PPHMF1MBZ
 ʹͯࢠͲ΋޲͚ΧςΰϦ
 ϥϯΩϯά501 14 ͓͠͝ͱ
  15. ΞδΣϯμ 15

  16. w6OJUZ։ൃ͋Δ͋Δ wີ݁߹ˠૄ݁߹ w$MFBO"SDIJUFDUVSFʹ͍ͭͯ w$"'6ʹ͍ͭͯ 16 ͓͠ͳ͕͖

  17. w6OJUZ։ൃ͋Δ͋Δ wີ݁߹ˠૄ݁߹ w$MFBO"SDIJUFDUVSFʹ͍ͭͯ w$"'6ʹ͍ͭͯ 17 ͓͠ͳ͕͖

  18. Unity ։ൃ͋Δ͋Δ 18

  19. wʮ͜ͷίϯϙʔωϯτमਖ਼͠Αʯ wʮ͑ͬͱɺ͜ͷJGͷதͷGPSFBDI
 ͷதͷFMTFJGͷதͷʜʯ wʮ͜ͷதׅހɺͲ͜ͷ৚݅ͩʜʁʯ wˠ௒ωετ͕ਂ͍6QEBUF 19 ͋Δ͋Δݴ͍͍ͨ Unity ։ൃ͋Δ͋Δ

  20. wʮήʔϜͷϩδοΫΛڞ௨Խ͢ΔͰʯ wʮ͜ͷॲཧ΋ڞ௨Խ͢ΔͰʯ wʮ͜Ε΋ɺ͋Ε΋ʜɻʯ wˠ ߦΛ௒͢(BNF.BOBHFSDT 20 ͋Δ͋Δݴ͍͍ͨ Unity ։ൃ͋Δ͋Δ

  21. wʮ͜ͷίϯϙʔωϯτ͸ɺͲ͜ͷγʔ ϯ͔ΒͰ΋ࢀর͍ͨ͠ʯ wʮ΄͏ɺDontDestroyOnLoadͱͳʯ wˠ4JOHMFUPO.POP#FIBWJPVSྔ࢈ 21 ͋Δ͋Δݴ͍͍ͨ Unity ։ൃ͋Δ͋Δ

  22. wʮ6OJUZ5FTU5PPMT࢖͏ͧʔʯ wʮ͜ͷϝιουςετ͢Δʹ͸ɺ
 ͜ͷΫϥεΛॳظԽͯ͠ɺ͜ͷΫϥεΛ
 ॳظԽ͢Δʹ͸ผͷγʔϯͷΫϥε͕
 ඞཁͰʜɻʯ wˠςετಋೖ࠳ં 22 ͋Δ͋Δݴ͍͍ͨ Unity ։ൃ͋Δ͋Δ

  23. wQVCMJDͱ͔<4FSJBMJ[F'JFME>ʹΑΓ
 ෳࡶʹབྷΈ߹͏.POP#FIBWJPVS wαʔόଆͷσʔλߏ଄มߋͷ
 Өڹൣғ͕ਙେ w4DSJQUBCMF0CKFDU࿔ͬͨΒϩʔΧϧʹ
 อଘͯ͠ΔσʔλϑΝΠϧ͕յΕͨ 23 ଞʹ΋… Unity ։ൃ͋Δ͋Δ

  24. wϩδοΫͷڞ௨ԽΛਤΖ͏ͱ͢Δ͕
 γʔϯຖͷඍົͳࠩҟΛٵऩ͖͠Εͣ
 େྔͷҾ਺ͱ৚݅෼ذ͕ൃੜ wσʔλͷఏڙݩຖʹσʔλߏ଄ఆٛ
 Ϋϥε͕ྔ࢈͞ΕΔ 24 ଞʹ΋… Unity ։ൃ͋Δ͋Δ

  25. 25 ͜͏͍͏ঢ়ଶ

  26. 26 is

  27. 27 ີ݁߹

  28. 28 ີ݁߹

  29. 29 ີ݁߹

  30. 30

  31. w6OJUZ։ൃ͋Δ͋Δ wີ݁߹ˠૄ݁߹ w$MFBO"SDIJUFDUVSFʹ͍ͭͯ w$"'6ʹ͍ͭͯ 31 ͓͠ͳ͕͖

  32. ີ݁߹→ૄ݁߹ 32

  33. wมߋʹରͯ͠੬ऑ wͦ΋ͦ΋มߋ͠ਏ͍ wӨڹൣғɾ੹೚ൣғ͕ෆ໌ྎ wଞਓ͕ಡΈਏ͍ wϲ݄લͷࣗ෼͸ଞਓͰ͢ 33 ີ݁߹͸Կނʁ ີ݁߹→ૄ݁߹

  34. w૯ͯ͡ɺϝϯςφϯεੑ͕௿͍ wٯʹϝϯςφϯεΛཁ͠ͳ͍
 ϓϩμΫτͰ͋Ε͹ɺΨοͱ
 ີ݁߹ͳίʔυͰૉૣ͘ॻ͘ͷ΋ΞϦ 34 ີ݁߹͸Կނʁ ີ݁߹→ૄ݁߹

  35. w͋ΔΫϥεͷमਖ਼͕ଞͷΫϥεʹٴ͹ ͳ͍ wΫϥεͷ੹೚͕໌֬Ͱςετ͕ॻ͖΍ ͍͢ w֦ு͕͠қ͍ 35 ૄ݁߹͸Կނʁ ີ݁߹→ૄ݁߹

  36. w૯ͯ͡ɺϝϯςφϯεੑ͕ߴ͍ wճҎ্ϝϯςφϯεʢमਖ਼ʣΛ
 ߦ͏ϓϩμΫτͰ͋Ε͹ɺ
 ϝϯςφϯεੑͷߴ͕͞Ձ஋ʹܨ͕Δ 36 ૄ݁߹͸Կނʁ ີ݁߹→ૄ݁߹

  37. 37 How to ૄ݁߹ʁ

  38. 38

  39. 39 Ҏ্ɻ

  40. 40 ͱ͍͏ͷ΋ΞϨͳͷͰ

  41. 41 ૄ݁߹ͷͨΊͷ
 ςΫχοΫΛʢࡶʹʣ঺հ

  42. w4JOHMF3FTQPOTJCJMJUZ1SJODJQMF w0QFODMPTFEQSJODJQMF w-JTLPWTVCTUJUVUJPOQSJODJQMF w*OUFSGBDFTFHSFHBUJPOQSJODJQMF w%FQFOEFODZJOWFSTJPOQSJODJQMF 42 SOLID ݪଇ ີ݁߹→ૄ݁߹

  43. w୯Ұ੹೚ͷݪଇ w։์ด࠯ͷݪଇ wϦείϑͷஔ׵ݪଇ wΠϯλϑΣʔε෼཭ͷݪଇ wґଘੑٯసͷ๏ଇ 43 SOLID ݪଇ ີ݁߹→ૄ݁߹

  44. 44

  45. w40-*%ݪଇ͕कΒΕ͍ͯΔίʔυ͸
 ͦͷҰͭҰͭʹ͍ͭͯɺؔ৺ͷ෼཭͕
 ߦΘΕ͍ͯΔͱݴ͑Δ w͢ͳΘͪɺݸʑͷίʔυʹ͓͚Δ
 ؔ৺ࣄ͕গͳ͍ w͢ͳΘͪɺૄ݁߹ͩͱݴ͑Δ 45 SOLID ݪଇ ີ݁߹→ૄ݁߹

  46. wૄ݁߹ͳγεςϜʹର͢Δςετ͸
 ͭͷςετίʔυ͕ෛ͏੹຿͕ڱ͍ wςετΛ࣮ࢪ͢Δࡍͷ४උॲཧ͕
 গͳ͘ͳΔέʔε͕ଟ͍ 46 ૄ݁߹ × ςετ ີ݁߹→ૄ݁߹

  47. wۃ࿦ͱͯ͠͸ɺ֤ཁૉʹର͢Δ65͕
 ॻ͔Ε͍ͯΕ͹*5͸ͦ͜·Ͱ
 ؤுΒͳͯ͘΋ࡁΉ 47 ૄ݁߹ × ςετ ີ݁߹→ૄ݁߹

  48. 48 ͰʁHow to ૄ݁߹ʁ

  49. w6OJUZ։ൃ͋Δ͋Δ wີ݁߹ˠૄ݁߹ w$MFBO"SDIJUFDUVSFʹ͍ͭͯ w$"'6ʹ͍ͭͯ 49 ͓͠ͳ͕͖

  50. Clean Architecture ʹ͍ͭͯ 50

  51. 51 ͷɺલʹ

  52. w͜͜·Ͱ͸୯ҰͷΫϥεʹؔ͢Δ
 ؔ৺ͷ෼཭ʹ͍ͭͯ wҰͭࢹ࠲Λ֦͛ͯϨΠϠʔʹؔ͢Δ
 ؔ৺ͷ෼཭ʹ͍ͭͯߟ͑Δ 52 ؔ৺ͷ෼཭ Clean Architecture ʹ͍ͭͯ

  53. wιϑτ΢ΣΞΞʔΩςΫνϟ ʹԙ͍ͯɺҰൠʹҎԼͷ
 Α͏ʹϨΠϠʔΛ෼͚Δ
 ʢίτ͕ଟ͍ʣ w1SFTFOUBUJPO ݟͨ໨  w%PNBJO ϩδοΫ 

    w%BUB σʔλ 53 ؔ৺ͷ෼཭ for ϨΠϠʔ Presentation Domain Data Clean Architecture ʹ͍ͭͯ
  54. w.7$΍.71ͳͲͷ
 ΞʔΩςΫνϟʹΑΓ
 1SFTFOUBUJPOͱ%PNBJO
 ͷ෼཭͕࣮ݱ͞ΕΔ w֤ΞʔΩςΫνϟͰ
 ෼཭ͷ۩ମతͳखஈ͸
 ༷ʑ w.71΍.77.ͩͱ
 3YΛ࢖͏ͷ͕Ұൠతʁ 54

    ؔ৺ͷ෼཭ for ϨΠϠʔ Presentation Domain Data Clean Architecture ʹ͍ͭͯ
  55. w%PNBJOͱ%BUBͷ෼཭͸
 ֤छσβΠϯύλʔϯ͕
 ୲͏͜ͱ͕ଟ͔ͬͨ wͱ͍͏͔ɺ.7 Ͱ͸
 %PNBJO૚Ҏ߱ʹ͍ͭͯͷ
 ੹຿ΛΞʔΩςΫνϟ
 ͱͯ͠͸ෛ͍ͬͯͳ͍ײ͡ 55 ؔ৺ͷ෼཭

    for ϨΠϠʔ Presentation Domain Data Clean Architecture ʹ͍ͭͯ
  56. wͰɺͦͷล΋ఆٛͨ͠
 ΞʔΩςΫνϟ͕ొ৔͢Δ w)FYBHPOBM"SDIJUFDUVSF w0OJPO"SDIJUFDUVSF w$MFBO"SDIJUFDUVSF 56 ؔ৺ͷ෼཭ for ϨΠϠʔ Presentation

    Domain Data Clean Architecture ʹ͍ͭͯ
  57. 57 Α͏΍͘ຊ୊

  58. w6ODMF#PC 3PCFSU$.BSUJO ࢯ͕ ೥݄ʹఏҊ wJ04ͷ7*1&3ͳΜ͔΋ίϨ͕ݯྲྀ 58 Clean Architecture Clean Architecture

    ʹ͍ͭͯ
  59. 59 Clean Architecture Clean Architecture ʹ͍ͭͯ

  60. 60 ͳΔ΄ͲɺΘ͔ΒΜɻ

  61. 61 ࢲͳΓʹղऍͯ͠Έͨ

  62. wϨΠϠʔͷ໾ׂΛఆٛ͢Δ wϨΠϠͷ੹຿Λ໌֬Խ wOBNFTQBDFͳͲͰ
 ෼͔Γ΍͘͢͢Δ 62 Clean Architecture Clean Architecture ʹ͍ͭͯ

  63. wґଘͷϧʔϧΛकΔ wؔ৺ͷ޲͖͸Ұํ޲ wݪଇతʹಉϨΠϠʔؒ͸
 ґଘͤ͞ͳ͍ wϨΠϠʔΛඈͼӽ͑ͳ͍ 63 Clean Architecture Clean Architecture

    ʹ͍ͭͯ
  64. wϨΠϠʔఆٛ͸ࣗ༝ w਺ͱ͔͸ෆఆ wϓϩμΫτຖʹॊೈʹ w଍Γͳ͖Ό૿΍͢ 64 Clean Architecture Clean Architecture ʹ͍ͭͯ

  65. wϨΠϠʔؒͷؔ৺Λ෼཭ w40-*%ݪଇ wJOUFSGBDFΛ༻͍ͯ
 ۩৅Ϋϥε΁ͷґଘഉআ w%FQFOEFODZ*OKFDUJPOT 65 Clean Architecture Clean Architecture

    ʹ͍ͭͯ
  66. wಉ৺ԁͷਤ͸ؔ৺ͷ޲͖ w಺ଆ͸֎ଆΛ஌Βͳ͍ w(BUFXBZT͸%#͕
 Ͳ͏΍ͬͯσʔλΛ
 ѻ͏͔͸஌Βͳ͍ɺͱ͔ wσʔλͷྲྀΕ͸ผͷ͓࿩ wӈԼͷਤ͕ιϨ 66 Clean Architecture

    Clean Architecture ʹ͍ͭͯ
  67. 67 ΜͰ

  68. 68 ͜ΕΛ Unity ʢ͔ͬͯ C#ʣ
 Ͱ࣮૷ͯ͠Έͨ

  69. w6OJUZ։ൃ͋Δ͋Δ wີ݁߹ˠૄ݁߹ w$MFBO"SDIJUFDUVSFʹ͍ͭͯ w$"'6ʹ͍ͭͯ 69 ͓͠ͳ͕͖

  70. CAFU ʹ͍ͭͯ 70

  71. w$MFBO"SDIJUFDUVSF'PS6OJUZͷུ wʮ͔;ʔʯͱಡΉ wώωϦ͕ͳ͍ͱ͔ݴΘͳ͍ɻ w.*5-JDFOTFͳ044 wIUUQTHJUIVCDPNVNNQSPKFDUTDBGV@DPSF 71 CAFU is Կʁ CAFU

    ʹ͍ͭͯ
  72. wجຊతʹ͸JOUFSGBDFͷΈΛఏڙ w6OJUZͱର࿩͢Δ্ͰඞཁʹͳΔ
 ΫϥεΛఏڙ wΩοζελʔͷΞϓϦ։ൃͰ
 ௒ઈ࢖ͬͯΔ 72 CAFU is Կʁ CAFU

    ʹ͍ͭͯ
  73. 73 ϨΠϠʔఆٛ

  74. 74 ϨΠϠʔఆٛ CAFU ʹ͍ͭͯ

  75. 75 ґଘؔ܎ CAFU ʹ͍ͭͯ

  76. w.POP#FIBWJPVSͱର࿩͠
 ݟͨ໨Λ࢘ΔϨΠϠʔ w1SFTFOUFSͷΈґଘՄ 76 Presentation / View CAFU ʹ͍ͭͯ

  77. w7JFXͱ6TF$BTFΛܨ͙ϨΠϠʔ w6TF$BTF͸ޙड़ wঢ়ଶΛ࣋ͨͳ͍ 77 Presentation / Presenter CAFU ʹ͍ͭͯ

  78. wϏδωεϩδοΫͷ࣮૷ͦͷ΋ͷ wܭࢉॲཧͳͲΛ୲͏ wޙड़ͷ.PEFMͱͯ͠දݱ͞ΕΔ
 ঢ়ଶΛอ࣋ͨ͠Γ͢Δ 78 Domain / UseCase CAFU ʹ͍ͭͯ

  79. wओʹ7JFXͰͷར༻Λ໨తͱͨ͠
 σʔλͷߏ଄ w6OJ3YΛ௨ͯ͡7JFXʹૹΒΕΔ w3YετϦʔϜΛؚΊͨঢ়ଶΛ؅ཧ 79 Domain / Model CAFU ʹ͍ͭͯ

  80. wޙड़ͷ&OUJUZͱ.PEFMͱΛ૬ޓม׵ ͢ΔͨΊͷTranslate()ϝιουΛ
 උ͑Δ w֎෦࢓༷ͷมߋΛ6TF$BTF΍7JFX ʹ఻೻ͤ͞ͳ͍ͨΊʹఆٛ 80 Domain / Translator CAFU

    ʹ͍ͭͯ
  81. w%BUBϨΠϠʔͱର࿩͢ΔͨΊͷ
 ϨΠϠʔ wσʔλΛಡΈॻ͖͢ΔͨΊͷ
 ΠϯλϑΣʔεΛ࣋ͭ 81 Domain / Repository CAFU ʹ͍ͭͯ

  82. wσʔλͷߏ଄Λఆٛͨ͠ϨΠϠʔ wσʔλͷ࣮ମ͕ԿͰ͋Εɺ
 ߏ଄දݱͱͯ͠͸ҰͭͷΫϥεͰද͢ w4DSJQUBCMF0CKFDU͕ϝϯυΠʜɻ 82 Data / Entity CAFU ʹ͍ͭͯ

  83. wσʔλͷऔΓѻ͍Λ࣮૷ͨ͠ϨΠϠʔ w4DSJQUBCMF0CKFDUͱ͔ɺ
 8FC"1*ܦ༝ͷ+40/ͱ͔ɺ
 42-JUFܦ༝ͷσʔλͱ͔ɺFUD 83 Data / DataStore CAFU ʹ͍ͭͯ

  84. wFOVNͱ͔DPOTUతͳ஋Λ؅ཧ͢Δ ͨΊͷ"QQMJDBUJPOϨΠϠʔ w%*༻ͷ'BDUPSZΫϥεͱ͔Λ
 ֨ೲ͢Δ6UJMJUZϨΠϠʔ 84 ͦͷଞ CAFU ʹ͍ͭͯ

  85. wམͪϞϊήʔϜΛྫʹղઆ wʙ৭ͷάϛ͕
 ݸηοτͰམԼ wͭἧ͏ͱফ͑Δ wළͷ࠷্ஈ·Ͱୡͨ͠Β
 ήʔϜΦʔόʔ wͦͷ࣌఺ͷείΞΛه࿥ 85 ྫ͑͹ CAFU

    ʹ͍ͭͯ
  86. • Controller w γʔϯ੍ޚ w 1SFTFOUFSॳظԽ • Gummi w ߱ͬͯ͘Δάϛ


    •Floor wϘτϧͷচ •Ceil wϘτϧͷఱҪ •Wall wϘτϧͷน 86 Presentation / View CAFU ʹ͍ͭͯ
  87. •StagePresenter wγʔϯैଐ1SFTFOUFS 87 Presentation / Presenter CAFU ʹ͍ͭͯ

  88. •GummiStateUseCase wεςʔδதͷάϛͷঢ়ଶ Λ؅ཧɾܭࢉ wάϛண஍ˠ࠶ܭࢉͱ͔ wͪ͗Ε൑ఆͱ͔ •ScoreUseCase wಘ఺Λ؅ཧɾܭࢉ •StageUseCase wεςʔδͷߏ੒Λ؅ཧ wԿ৭ͷάϛΛग़͢ʁ

    wམԼεϐʔυ͸ʁ 88 Domain / UseCase CAFU ʹ͍ͭͯ
  89. •GummiModel wάϛҰͭ෼Λදݱ w৭ͱ͔4UBUFͱ͔ •GummiMapModel wεςʔδ಺ͷશάϛ৘ใ
 •ForecastGummiModel w༧ࠂάϛͷঢ়ଶ •ScoreModel wݱࡏͷಘ఺ •PointModel

    wάϛফڈʹΑΔ֫ಘಘ఺ 89 Domain / Model CAFU ʹ͍ͭͯ
  90. •GummiTranslator w4UBHF-FWFM&OUJUZͱ
 Ґஔ͔Β4DPSF.PEFM Λੜ੒ •ScoreEntityTranslator w4DPSF.PEFMΛ 4DPSF&OUJUZʹม׵ 90 Domain /

    Translator CAFU ʹ͍ͭͯ
  91. •ScoreRepository wείΞΛಡΈॻ͖ •StageLevelRepository wεςʔδͷάϛ৭ߏ੒
 ͳͲͷϚελΛऔಘ 91 Domain / Repository CAFU

    ʹ͍ͭͯ
  92. •ScoreEntity wεςʔδ෼ͷείΞ •ScoreMapEntity wશεςʔδ෼ͷείΞ
 •GummiPointMapEntity w࿈࠯ຖͷ֫ಘ఺਺Ϛελ •StageLevelEntity wεςʔδ೉қ౓ఆٛ •StageLevelMapEntity wશεςʔδ෼ͷ೉қ౓

    92 Data / Entity CAFU ʹ͍ͭͯ
  93. •ScriptableObjectDataStore wγʔϯதͷ೚ҙͷ
 ίϯϙʔωϯτ͔Β
 ࢀর͞ΕΔ 4DSJQUBCMF0CKFDU͔Β
 &OUJUZΛऔಘ
 •LocalStorageDataStore wϩʔΧϧετϨʔδʹ
 +40/ͱ͔Ͱ&OUJUZΛ
 อଘͨ͠ΓಡΜͩΓ

    93 Data / DataStore CAFU ʹ͍ͭͯ
  94. 94 σʔλͷྲྀΕ

  95. wϘλϯ͕ΫϦοΫ͞ΕͯԿ͔ॲཧ͢Δ 95 σʔλͷྲྀΕ CAFU ʹ͍ͭͯ

  96. wԿΒ͔ͷτϦΨʔͰঢ়ଶ͕มԽ 96 σʔλͷྲྀΕ CAFU ʹ͍ͭͯ

  97. wλΠϚʔతͳ࣮૷ 97 σʔλͷྲྀΕ CAFU ʹ͍ͭͯ

  98. wόφʔը૾Λαʔό͔Βऔಘ 98 σʔλͷྲྀΕ CAFU ʹ͍ͭͯ

  99. wόφʔը૾Λ୺຤ʹΩϟογϡ 99 σʔλͷྲྀΕ CAFU ʹ͍ͭͯ

  100. wϚελσʔλΛ4DSJQUBCMF0CKFDU͔Βऔಘ 100 σʔλͷྲྀΕ CAFU ʹ͍ͭͯ

  101. wϚελσʔλΛ4DSJQUBCMF0CKFDU͔Βऔಘ
 ʢϥΠτ൛ʣ 101 σʔλͷྲྀΕ CAFU ʹ͍ͭͯ

  102. ·ͱΊ 102

  103. wૄ݁߹ͳΞϓϦέʔγϣϯΛ
 ߏங͢Δͱϝϯςφϯεੑ w$MFBO"SDIJUFDUVSF͕Φεεϝ w$"'6࢖ͬͯΈͯͶʂ 103 ·ͱΊ

  104. ͓·͚ 104

  105. 105 ͪΐͬͱऄ଍

  106. wʮґଘੑ஫ೖʯͱ͔೔ຊޠ༁͞ΕΔ wʮґଘʯͱ͔ݴ͏͔Β෼͔Γਏ͍ wࡶʹݴ͑͹ʮΠϯελϯεΛઃఆ͢Δ
 ʢड͚౉͢ʣʯͬͯίτ 106 Dependency Injections ͓·͚

  107. 107 Dependency Injections using UnityEngine; public class Player : MonoBehaviour

    { private void Update() { MovePosition(); } private void MovePosition() { var horizontal = Input.GetAxis("Horizontal"); var vertical = Input.GetAxis("Vertical"); transform.position = new Vector3( transform.position.x + horizontal, transform.position.y, transform.position.z + vertical ); } } ͓·͚ ྫ͑͹͜Μͳίʔυ
  108. 108 Dependency Injections var horizontal = Input.GetAxis("Horizontal"); var vertical =

    Input.GetAxis("Vertical"); transform.position = new Vector3( transform.position.x + horizontal, transform.position.y, transform.position.z + vertical ); ͓·͚ ֦େ
  109. w.PWF1PTJUJPO Λςετ͍ͨ͠ wॎԣೖྗͷऔಘॲཧΛந৅Խ͢Δඞཁ ͕͋Δ w6OJUZ&OHJOF*OQVUΛந৅Խ͠Α͏ 109 Dependency Injections ͓·͚

  110. 110 Dependency Injections using UnityEngine; public class Player : MonoBehaviour

    { private IInput Input { get; set; } public void SetInput(IInput input) { Input = input; } private void Update() { MovePosition(); } private void MovePosition() { var horizontal = Input.GetHorizontalAxis(); var vertical = Input.GetVerticalAxis(); transform.position = new Vector3( transform.position.x + horizontal, transform.position.y, transform.position.z + vertical ); } } public class Installer : MonoBehaviour { [SerializeField] private Player player; private void Start() { player.SetInput(new UnityInput()); } } public interface IInput { float GetHorizontalAxis(); float GetVerticalAxis(); } public class UnityInput : IInput { public float GetHorizontalAxis() { return Input.GetAxis("Horizontal"); } public float GetVerticalAxis() { return Input.GetAxis("Vertical"); } } public class TestInput : IInput { public float GetHorizontalAxis() { return 1.0f; } public float GetVerticalAxis() { return 1.0f; } } ͓·͚ ͜͏ͳΔ
  111. 111 Dependency Injections public class PlayerTest { [UnityTest] public IEnumerator

    MovePositionTest() { var go = new GameObject(); var player = go.AddComponent<Player>(); yield return new WaitForEndOfFrame(); // 初期化待ち player.transform.position = Vector3.zero; player.SetInput(new TestInput()); // Dependency Injection yield return new WaitForEndOfFrame(); Assert.AreEqual(new Vector3(1f, 0f, 1f), player.transform.position); } } ͓·͚ ςετίʔυ͸ͪ͜Β
  112. 112 Dependency Injections public interface IInput { float GetHorizontalAxis(); float

    GetVerticalAxis(); } ͓·͚ ֦େʢJOUFSGBDFʣ
  113. 113 Dependency Injections public class UnityInput : IInput { public

    float GetHorizontalAxis() { return Input.GetAxis("Horizontal"); } public float GetVerticalAxis() { return Input.GetAxis("Vertical"); } } ͓·͚ ֦େʢ۩৅Ϋϥεʣ
  114. 114 Dependency Injections private IInput Input { get; set; }

    ... var horizontal = Input.GetHorizontalAxis(); var vertical = Input.GetVerticalAxis(); ͓·͚ ֦େʢར༻Ϋϥεʣ
  115. 115 Dependency Injections public void SetInput(IInput input) { Input =

    input; } ... public class Installer : MonoBehaviour { [SerializeField] private Player player; private void Start() { player.SetInput(new UnityInput()); } } ͓·͚ ֦େʢར༻Ϋϥεʣ
  116. Dependency Injections ͓·͚ ֦େʢςετίʔυʣ 116 public class PlayerTest { [UnityTest]

    public IEnumerator MovePositionTest() { var go = new GameObject(); var player = go.AddComponent<Player>(); yield return new WaitForEndOfFrame(); // 初期化待ち player.transform.position = Vector3.zero; player.SetInput(new TestInput()); // Dependency Injection yield return new WaitForEndOfFrame(); Assert.AreEqual( new Vector3(1f, 0f, 1f), player.transform.position ); } }
  117. w*OTUBMMFSΛ೚ҙͷ(BNF0CKFDUʹ
 Ξλονͯ͠1MBZFSΛઃఆ wςετͷ࣌͸1MBZFSͷΠϯελϯεʹ
 4FU*OQVU OFX5FTU*OQVU ͱ͔ w1MBZ.PEFςετͰGޙʹ࠲ඪ͕
   

    ʹͳͬͯΔ͔ʁΛ"TTFSU 117 Dependency Injections ͓·͚
  118. 118 Dependency Injections ʢΞϯνύλʔϯʣ using UnityEngine; public static class InputManager

    { private static IInput Input { get; set; } public static IInput GetInstance() { return Input ?? (Input = new UnityInput()); } public static void SetInstance(IInput input) { Input = input; } } public class Player : MonoBehaviour { private void Update() { MovePosition(); } private void MovePosition() { var horizontal = InputManager.GetInstance().GetHorizontalAxis(); var vertical = InputManager.GetInstance().GetVerticalAxis(); transform.position = new Vector3( transform.position.x + horizontal, transform.position.y, transform.position.z + vertical ); } } ͓·͚ Ұํɺ͜Μͳίʔυ
  119. 119 Dependency Injections ʢΞϯνύλʔϯʣ public static class InputManager { private

    static IInput Input { get; set; } public static IInput GetInstance() { return Input ?? (Input = new UnityInput()); } public static void SetInstance(IInput input) { Input = input; } } ͓·͚ ֦େʢ*OQVU.BOBHFSʣ
  120. 120 Dependency Injections ʢΞϯνύλʔϯʣ var horizontal = InputManager.GetInstance().GetHorizontalAxis(); var vertical

    = InputManager.GetInstance().GetVerticalAxis(); ͓·͚ ֦େʢར༻Ϋϥεʣ
  121. w͜Ε͸ɺαʔϏεϩέʔλύλʔϯͱ ͍͏%*ʹ͓͚ΔΞϯνύλʔϯͰ͢ w*OQVU.BOBHFS΁ͷґଘ͕૿͑ͯ
 ͠·͍ɺґଘؔ܎ͷݟ௨͕͠ѱ͍ wςετ͢Δ࣌ʹ*OQVU.BOBHFS΁ͷ
 Πϯελϯεઃఆ͕௥ՃͰඞཁʹͳΔ 121 Dependency Injections ʢΞϯνύλʔϯʣ

    ͓·͚
  122. 122 ऄ଍͓ΘΓ

  123. 123 Thank you for your attention!!