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

mixi tech note #06

mixi tech note #06

#技術書典11 に出典されたミクシィグループエンジニア有志による技術書です。

<< 目次 >>
1章:Haskell でいじる Dockerfile
2章:きれいなコードを書くための 3 つの C とその組み合わせ
3章:Web Components の基礎と開発時の設計考察
4章:できるよ Unity DOTS
5章:ゲームのための経路探索
6章:Unity の Navigation の活用
7章:70 個くらいのシェーダーをまとめた話

<< TECH NOTE 一覧 >>
mixi tech note #01
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-01

mixi tech note #02
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-02

mixi tech note #03
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-03

mixi tech note #04
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-04

mixi tech note #05
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-05

mixi tech note #06
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-06

mixi tech note #07
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-07

MIXI TECH NOTE #08
https://speakerdeck.com/mixi_engineers/mixi-tech-note-number-08

XFLAG Tech Note Vol.01
https://speakerdeck.com/mixi_engineers/xflag-tech-note-vol-dot-01

XFLAG Tech Note vol.02
https://speakerdeck.com/mixi_engineers/xflag-tech-note-vol-dot-02

MIXI ENGINEERS

July 10, 2021
Tweet

More Decks by MIXI ENGINEERS

Other Decks in Technology

Transcript

  1. ·͕͖͑ ຊॻʮmixi tech note #06ʯ͸ɺϛΫγΟάϧʔϓʹॴଐ͢Δ༗ࢤୡʹΑͬͯࣥචɾ੍࡞͞Εͨ ٕज़ॻͰ͢ɻ঺հͳΜͱ͔ɻͦͷͨΊɺ֤ষͦΕͧΕͰ׬͍݁ͯ͠Δ಺༰ʹͳ͍ͬͯ·͢ͷͰɺ޷͖ ͳষ͔Β޷͖ͳॱ൪Ͱָ͓͠Έ͍ͩ͘͞ɻ ·ͨɺຊॻ͸ɺϛΫγΟάϧʔϓʹ͋Δٕज़త஌ݟ΍ΞΠσΞΛੵۃతʹڞ༗ɾެ։͍ͯ͘͜͠ͱ ͰɺੈͷதʹΑΓྑ͍αʔϏε͕ҲΕग़͢͜ͱΛئͬͯץߦ͞Ε͍ͯ·͢ɻܝࡌ͞Ε͍ͯΔ৘ใ͸ɺ ࣥචऀࣗ਎ͷ؀ڥͰݕূࣥ͠ච͞Εͨ΋ͷͰ͢ͷͰɺ͝ࢀߟʹ͞ΕΔࡍ͸ɺࣗ͝਎ͷ੹೚Ͱ൑அ͠

    ͝׆༻͍ͩ͘͞ɻͳ͓ɺจষදݱʹ͖ͭ·ͯ͠΋ɺࣥචऀࣗ਎ͷݴ༿Ͱ఻͑ͨ͘ɺϑϥϯΫͳදݱͱ ͳ͓ͬͯΓ·͢͜ͱ͝ཧղ͍͚ͨͩΕ͹ͱࢥ͍·͢ɻ σΟϕϩούʔϦϨʔγϣϯζνʔϜҰಉ ˗ຊॻʹؔ͢Δ͓໰͍߹Θͤઌ ɹ https://twitter.com/mixi_engineers ˗ϛΫγΟάϧʔϓʹ͍ͭͯ ɹ https://mixi.co.jp/ ˞ʠϛΫγΟʡ ɺ ʠmixiʡ ɺ ʠmixi ϩΰʡ ͸ɺגࣜձࣾϛΫγΟͷ঎ඪ·ͨ͸ొ࿥঎ඪͰ͢ɻ·ͨɺ֤ ࣾͷձ໊ࣾɺαʔϏεٴͼ੡඼ͷ໊শ͸ɺͦΕͧΕͷॴ༗͢Δ঎ඪ·ͨ͸ొ࿥঎ඪͰ͢ɻ iii
  2. ໨࣍ ·͕͖͑ iii ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1

    1.1 language-docker . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 1.2 Haskell Ͱ Dockerfile Λهड़͢Δ . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.3 ऴΘΓʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 11 2.1 ͖Ε͍ͳίʔυͷҐஔ෇͚ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.2 Project:CCC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 2.4 ͓ΘΓʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.5 ͋ͱ͕͖: ͦͷίʔυɺΫϦʔϯͳඞཁ͕͋Γ·͔͢ʁ . . . . . . . . . . . . . . . 26 ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 27 3.1 Web Components ͷجૅ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.2 એݴత UI ͱࠩ෼ϨϯμϦϯά . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 3.3 ։ൃ؀ڥߏங . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 3.4 ࠷ޙʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 41 4.1 Unity DOTS ࣗࣾݕূࣄྫ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 4.2 Unity DOTS / NetCode ͰϚϧνϓϨΠήʔϜ։ൃ . . . . . . . . . . . . . . . . . 44 4.3 DOTS ͱ͸ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 4.4 Ͳͷ͘Β͍ྑ͘ͳΔͷ͔ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4.5 Ͱ͖Δ͜ͱ/Ͱ͖ͳ͍͜ͱ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54 4.6 मಘ೉қ౓͸ߴ͍ͷ͔ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.7 Ͳ͔͜ΒखΛ͚ͭΕ͹ྑ͍ͷ͔ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 4.9 ࠷ޙʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 v
  3. ໨࣍ ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 69 5.1 ήʔϜͷܦ࿏୳ࡧ . .

    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 5.2 ܦ࿏୳ࡧΞϧΰϦζϜ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.3 ܦ࿏୳ࡧͷԠ༻ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.4 ·ͱΊ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.5 ͓·͚ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.6 ࢀߟ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76 ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 77 6.1 ࢝Ίʹ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 6.2 Navigation ͷجຊ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 6.3 Navigation ͷԠ༻ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79 ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 87 7.1 ΠϯτϩμΫγϣϯ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 7.2 γΣʔμʔόϦΞϯτ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 7.3 ςΫενϟͷϛϥʔϦϯά . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 7.4 ৚݅෼ذ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ . . . . . . . . . . . . . . . . . . . . . . . . 95 7.6 γΣʔμʔΛॻ͖΍͘͢͢Δ޻෉ . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 7.7 ·ͱΊ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 ஶऀ঺հ 105 vi
  4. ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile hadolint*1 ͱ͍͏πʔϧΛ஌͍ͬͯ·͔͢ʁ Dockerfile ʹର͢Δ

    lint πʔϧͰ͢ɻͨͱ͑͹ɺ࣍ ͷΑ͏ͳܯࠂΛग़ͯ͘͠Ε·͢ɻ $ cat Dockerfile FROM ubuntu RUN cd /tmp && echo "hello!" $ hadolint Dockerfile Dockerfile:1 DL3006 warning: Always tag the version of an image explicitly Dockerfile:2 DL3003 warning: Use WORKDIR to switch to a directory ࣮͸͜ͷπʔϧ͸ Haskell Ͱॻ͔Ε͍ͯ·͢ɻ·ͨɺhadolint ͷ࡞ऀ͸ hadolint Λ࣮૷͢ΔͨΊ ͷ֤छػೳʢߏจఆٛ΍ύʔαʔʣΛผύοέʔδ language-docker*2 ͱͯ͠ެ։ͯ͘͠Ε͍ͯ· ͢ɻຊߘͰ͸ɺ͜ͷύοέʔδΛར༻ͯ͠ Haskell ʹΑͬͯϓϩάϥϚϒϧʹ Dockerfile Λهड़͢ Δํ๏Λ঺հ͠·͢ɻ 1.1 language-docker ·ͣ͸ɺlanguage-docker ύοέʔδʹ͍ͭͯ঺հ͠·͢ʢݱࡏͷ࠷৽όʔδϣϯͰ͋Δ 10.0.1 Λର৅ʹ͠·͢ʣ ɻlanguage-docker ͕ఏڙ͢Δػೳ͸େ͖͘෼͚ͯ 3 ͭͰ͢ɻ 1. Haskell Ͱͷ Dockerfile ͷߏจఆٛ 2. Dockerfile ͷύʔαʔʢDockerfile Λදͨ͠จࣈྻΛ (1) ʹม׵ʣ 3. (1) ͷϓϦςΟϓϦϯλʢ(1) Λ Dockerfile ͱͯ͠ग़ྗʣ ॱ൪ʹ঺հ͠·͢ɻ *1 https://github.com/hadolint/hadolint *2 https://hackage.haskell.org/package/language-docker 1
  5. ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.1 language-docker 1. Dockerfile

    ͷߏจఆٛ ·ͣ͸ࠜͬ͜ʹͳΔߏจఆٛʢந৅ߏจ໦ɺASTʣΛΈͯΈ·͢ɻLanguage.Docker.Syntax Ϟ δϡʔϧͷ Dockerfile ܕ͕ͦΕʹ͋ͨΓ·͢ɻ Ϧετ 1.1: Dockerfile ͷߏจఆٛܕ type Dockerfile = [InstructionPos Text] data InstructionPos args = InstructionPos { instruction :: !(Instruction args), sourcename :: !Filename, lineNumber :: !Linenumber } data Instruction args = From !BaseImage | Add !AddArgs | Label !Pairs | Copy !CopyArgs | Run !(RunArgs args) | Cmd !(Arguments args) | Workdir !Directory | Volume !Text | Entrypoint !(Arguments args) | Comment !Text ... -- ׂѪ Instruction ܕ͕ Dockerfile ͷ RUN ΍ ADD ͳͲͷ໋ྩʹ͋ͨΓ·͢ɻׂͱͦͷ·Μ·ͷܕఆٛ Ͱ͢ͶɻInstructionPos ͸ Instruction ʹίʔυ্ͷߦ൪߸ͳͲΛՃ͑ͨΑ͏ͳσʔλܕͰ͢ɻ hadolint ͳͲͰܯࠂϝοηʔδΛग़ͨ͠Γ͢Δͷʹར༻͞Εͯ·͢ɻ args ͱ͍͏ܕύϥϝʔλ͸ͳΜͰ͠ΐ͏͔ʁ Dockerfile ܕͰ͸ Text ܕ*3Λద༻͍ͯ͠ΔͨΊ Ұݟ͋Μ·Γҙຯ͸ͳͦ͞͏Ͱ͢ɻargs ͱ͍͏ܕύϥϝʔλ͸ Arguments ܕͰར༻͞Εͯ·͢ɻ ࣮͸ɺ͜ͷύϥϝʔλ͸ hadolint ͷͨΊʹόʔδϣϯ 6.0.0 ͔Βಋೖ͞Ε·ͨ͠ɻhadolint Ͱ͸ R UN ͳͲͰઃఆ͞ΕͨγΣϧεΫϦϓτ΋νΣοΫ͞Ε·͢ɻ͜ͷνΣοΫʹ͸ shellcheck*4 Λར༻ ͍ͯ͠·͢ɻ࣮͸ shellcheck ΋ Haskell Ͱॻ͔Ε͍ͯΔͨΊɺ૊Έ߹ΘͤΔͷ͕༰қͳͷͰ͢ɻ͜ ͷࡍʹɺshellcheck ͷ݁ՌΛऔΓճ͠΍͍͢Α͏ʹܕύϥϝʔλʹͨ͠Α͏Ͱ͢*5ɻ Dockerfile ͷߏจ͸ൺֱతγϯϓϧͳͨΊɼ͜ͷ AST Λ௚઀ར༻ͯ͠΋ͦ͜·ͰࠔΒͳ͍Ͱ ͠ΐ͏ɻͨͩ hadolint ͷ࡞ऀ͸ɺ΋ͬͱ Dockerfile ͷه๏ʹ͍ۙܗͰهड़͢ΔͨΊͷผύοέʔδ *3 Haskell ͷจࣈྻܕͷҰͭͰɺϚϧνόΠτͳจࣈྻΛ͏·͘ѻ͑·͢ɻ *4 https://www.shellcheck.net/ *5 https://github.com/hadolint/language-docker/pull/34/commits/abaeed6d0037b8b500064cccb66b8df05c939fb0 2
  6. ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.1 language-docker dockerfile-creator*6 Λ༻ҙͯ͘͠Ε͍ͯ·͢ɻޙ൒ͷʮ1.2

    Haskell Ͱ Dockerfile Λهड़͢ΔʯͰ͸ dockerfile-creator Λར༻ͯ͠ΞϓϦέʔγϣϯΛ࣮ࡍʹ࡞ͬͯΈ·͢ɻ 2. Dockerfile ͷύʔαʔ language-docker ύοέʔδʹ͸ Dockerfile Λจࣈྻͱͯ͠ड͚औΓɺલड़ͨ͠ Dockerfile ܕ ͷ஋΁ม׵͢Δؔ਺͕͍͔ͭ͘༻ҙ͞Ε͍ͯ·͢ɻؔ਺͸ Language.Docker.Parser Ϟδϡʔϧ ʹఆٛ͞Ε͓ͯΓɺͨͱ͑͹࣍ͷΑ͏ͳؔ਺͕͋Γ·͢ɻ Ϧετ 1.2: Dockerfile ͷύʔαʔ parseText :: Text -> Either Error Dockerfile parseFile :: FilePath -> IO (Either Error Dockerfile) ಺෦తʹ͸ megaparsec ύοέʔδ*7Λར༻͍ͯ͠·͢ɻ໋ྩҰͭҰͭ͸ಠཱ͍ͯ͠ΔͨΊɺύʔ αʔͷ࣮૷͸ൺֱతʹγϯϓϧͰ͢*8ɻڵຯ͕͋Δํ͸ಡΜͰΈΔͱྑ͍Ͱ͠ΐ͏ɻύʔαʔͷ࣮૷ ͷࢀߟʹͳΔ͔΋͠Ε·ͤΜɻ ࠓճ͸ಛʹར༻͠·ͤΜ͕ɺͨͱ͑͹ Dockerfile ΛಡΈࠐΜͰॻ͖׵͑Δ৔߹ʹ͸্هͷؔ਺Λ ࢖͏ͱྑ͍Ͱ͠ΐ͏ɻ 3. ߏจఆٛͷϓϦςΟϓϦϯλ language-docker ύοέʔδͷ࠷ޙͷػೳ͸ϓϦςΟϓϦϯλͰ͢ɻલड़ͨ͠ AST Λ Dockerfile ͷจࣈྻͱͯ͠ग़ྗ͢ΔػೳͰɺLanguage.Docker.PrettyPrint Ϟδϡʔϧʹ࣍ͷΑ͏ͳؔ਺͕ ͋Γ·͢ɻ Ϧετ 1.3: Dockerfile ͷϓϦςΟϓϦϯλ prettyPrint :: Dockerfile -> Text ಺෦తʹ͸ prettyprinter ύοέʔδ*9Λར༻͍ͯ͠·͢ɻͦͷͨΊɺجຊతʹ͸ prettyprinter ύοέʔδͷ͘͠ΈΛར༻͍ͯ͠Δ͚ͩͰ͕͢ɺύοέʔδΛݟͯΈΔͱ EscapeAccumSource ܕͱ *6 https://hackage.haskell.org/package/dockerfile-creator : ΋ͱ΋ͱ͸ language-docker ʹؚ·Ε͍ͯ· ͕ͨ͠ɺhadolint ຊମʹ͸ෆཁͩͬͨͷͰ੾Γ෼͚ͨͦ͏Ͱ͢ɻ *7 https://hackage.haskell.org/package/megaparsec *8 ύʔαʔͷෳࡶ͞͸໋ྩʹΑΓ·͢ɻENV ΍ LABEL ͸͔ͳΓγϯϓϧͰ͕͢ FROM ΍ RUN ͸ΦϓγϣϯͷΑ͏ͳه๏ ͕͍͔ͭ͋͘Δ͍ͤͰൺֱతෳࡶͰ͢ɻͦΕͰ΋ɺී௨ͷϓϩάϥϛϯάݴޠͱൺ΂Ε͹͔ͳΓγϯϓϧͳํͰ͸͋Γ ·͕͢ɻ *9 https://hackage.haskell.org/package/prettyprinter 3
  7. ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.1 language-docker ͍͏ͷ͕ఆٛ͞Ε͍ͯ·͢ɻ͜Ε͸ɺescape directive*10

    ʹରԠ͢ΔͨΊͷ͘͠ΈͰ͢ɻDockerfile Ͱ # escape=‘ ͳͲͱهड़͢Δ͜ͱͰɺΤεέʔϓจࣈΛมߋͰ͖·͢ʢσϑΥϧτͰ͸ \ Ͱ͢ʣ ɻ language-docker ͷύʔαʔ͸ɺ͜ͷ directive ΋ղऍͯ͠ AST ʹอଘ͠·͢ɻͦͯ͠ύʔε͢ Δࡍ͸΋ͪΖΜɺϓϦςΟϓϦϯτ͢Δࡍʹ΋ directive Ͱࢦఆͨ͠ΤεέʔϓจࣈΛར༻͠·͢ɻ ͔ͤͬ͘ͳͷͰ࣮૷ΛݟͯΈ·͠ΐ͏*11ɻ Ϧετ 1.4: ϓϦςΟϓϦϯλͷ࣮૷ import Data.Text (Text) import qualified Data.Text.Lazy as L import Data.Text.Prettyprint.Doc import Data.Text.Prettyprint.Doc.Internal (Doc (Empty)) import Data.Text.Prettyprint.Doc.Render.Text (renderLazy) import Language.Docker.Syntax import Prelude hiding ((<>), (>>)) prettyPrint :: Dockerfile -> L.Text prettyPrint = renderLazy . layoutPretty opts . prettyPrintDockerfile where opts = LayoutOptions Unbounded prettyPrintDockerfile :: [InstructionPos Text] -> Doc ann prettyPrintDockerfile instr = doPrint instr <> "\n" where doPrint ips = let ?esc = findEscapeChar ips in (vsep . fmap prettyPrintInstructionPos) ips prettyPrintInstructionPos :: (?esc :: Char) => InstructionPos Text -> Doc ann prettyPrintInstructionPos (InstructionPos i _ _) = ... ?enc ͱ͍͏ͷ͕͋Γ·͢ɻ͜Ε͸ ImplicitParams ֦ு*12Ͱར༻Ͱ͖ΔػೳͰɺؔ਺ͷҾ਺Λ ҉໧తʹ౉͢͜ͱ͕Ͱ͖·͢ɻ҉໧తͳҾ਺͕͋Δ͔Ͳ͏͔͸ɺܕΫϥεͷΑ͏ʹ੍໿Λ෇͚·͢ ʢ?esc :: Char ͷ෦෼ʣ ɻҾ਺Λଋറ͢Δʹ͸ let ߏจΛར༻ͯ͠ߦ͍ͬͯ·͢ʢlet ?esc = fi ndEscapeChar ips ͷ෦෼ʣ ɻ͜ΕʹΑΓɺόέπϦϨʔͷΑ͏ʹҾ਺Λ౉͠ଓ͚Δඞཁ͕ͳ͘ͳΓ ·͢ɻ΋ͪΖΜɺReader ϞφυͰಉ༷ͷ͜ͱΛ࣮ݱͰ͖·͢ɻ·ͨɺReader Ϟφυʹൺ΂Δͱ΄ ͱΜͲར༻͞Ε͍ͯΔͷΛݟͳ͍௝͍͠ػೳͰ͢ɻ *10 https://docs.docker.com/engine/reference/builder/#escape *11 https://github.com/hadolint/language-docker/blob/e35d1f3a/src/Language/Docker/PrettyPrint.hs ΑΓൈਮ *12 https://downloads.haskell.org/~ghc/9.0.1/docs/html/users_guide/exts/implicit_parameters. html#extension-ImplicitParams 4
  8. ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.2 Haskell Ͱ Dockerfile

    Λهड़͢Δ 1.2 Haskell Ͱ Dockerfile Λهड़͢Δ ͯ͞ɺ͔͜͜Β͸͍Α͍Α࣮ࡍʹ language-docker ύοέʔδΛར༻ͯ͠؆୯ͳΞϓϦέʔγϣ ϯΛ࡞ͬͯΈ·͢ɻ ࡞ΔΞϓϦέʔγϣϯ Hamler*13 ͱ͍͏ϓϩάϥϛϯάݴޠΛ࣮ߦͰ͖Δ Docker Πϝʔδͷ Dockerfile Λ࡞੒͢Δ CLI πʔϧΛ࡞Δ͜ͱʹ͠·͢ɻHamler ͸ Erlang VM ্Ͱಈ࡞͢Δ Haskell ελΠϧͷϓϩάϥ ϛϯάݴޠͰ͢ɻErlang VM ্Ͱಈ࡞͢Δϓϩάϥϛϯάݴޠͱ͍͑͹ɺ͓ͦΒ͘ Elixir ͕࠷΋༗ ໊Ͱ͕͢ɺHamler ͸ Elixir ͱ͸ҟͳΓ੩తܕݕ͕ࠪ͋Γ·͢ɻ༨ஊͰ͕͢ɺHamler ͷίϯύΠϥ ͸ PureScript ͔ΒϑΥʔΫ͞Ε͍ͯ·͢ɻ ࠓճͷ୊ࡐʹ Hamler ΛબΜͩͷ͸ɺHamler ͷ Docker ΠϝʔδΛ࡞Δʹ͸ Hamler ͷόʔδϣ ϯͷ΄͔ʹ Erlang VM ͷόʔδϣϯΛࢦఆ͢Δඞཁ͕͋Δ͔ΒͰ͢ɻࠓճ࡞Δ؆қతͳΞϓϦέʔ γϣϯ͸ɺ͜ͷ 2 ͭͷόʔδϣϯΛࢦఆ͢Δͱɺͦͷόʔδϣϯͷ༗ແΛνΣοΫ͠໰୊ͳ͚Ε͹ Dockerfile Λग़ྗ͢ΔΑ͏ͳ΋ͷΛ࡞Δ͜ͱʹ͠·͢ɻ ׬੒඼͸ https://github.com/matsubara0507/hamler-dockerfile-creator ϦϙδτϦʹ ͋Γ·͢ɻ όʔδϣϯͷ༗ແͷνΣοΫ Dockerfile ͷ࿩ͱ͸௚઀ؔ܎ͳ͍Ͱ͕͢ɺHamler ͱ Erlang VM ͷόʔδϣϯͷνΣοΫͷ͔͠ ͨΛઌʹߟ͑·͢ɻ͍Ζ͍Ζߟ͑ͨ݁ՌɺͲͪΒ΋ GitHub Ͱެ։͞Ε͍ͯΔͷͰ GitHub Release ͷλάͰνΣοΫ͠Α͏ͱࢥ͍·͢ɻGitHub ͷ API Λ Haskell Ͱར༻͢Δʹ͸ɺgithub ύοέʔ δ*14Λར༻͠·͢ɻ ͍ͭͰʹɺόʔδϣϯΛࢦఆ͠ͳ͔ͬͨ৔߹ʹ͸ latest ͳϦϦʔεΛࢀর͢ΔΑ͏ʹϥοϓͨ͠ ؔ਺Λ༻ҙ͠·͢ɻ Ϧετ 1.5: GitHub Release Λऔಘ͢Δؔ਺ import Control.Monad.IO.Class (MonadIO, liftIO) import Data.String (fromString) import GitHub (github’) import qualified GitHub fetchRelease :: MonadIO m => GitHub.Name GitHub.Owner -> GitHub.Name GitHub.Repo *13 https://www.hamler-lang.org/ *14 https://hackage.haskell.org/package/github 5
  9. ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.2 Haskell Ͱ Dockerfile

    Λهड़͢Δ -> Maybe String -> m (Maybe GitHub.Release) fetchRelease owner repo tag = do r <- liftIO $ case tag of Nothing -> github’ $ GitHub.latestReleaseR owner repo Just t -> github’ $ GitHub.releaseByTagNameR owner repo (fromString t) case r of Left _ -> pure Nothing Right r -> pure (Just r) Erlang VM ͷ৔߹ɺ"OTP-" ͱ͍͏઀಄͕ࣙϦϦʔελάʹ͍͍ͭͯ·͢ɻͰ͢ͷͰɺ͜ΕΒΛ Α͠ͳʹ֎ͯ͠όʔδϣϯΛฦͯ͋͛͠Δؔ਺Λɺઌ΄Ͳఆٛͨ͠ fetchRelease ؔ਺Λར༻ͯ͠ ఆٛ͠·͢ɻ Ϧετ 1.6: Erlang VM ͷόʔδϣϯΛνΣοΫ͢Δؔ਺ import qualified Data.Text as Text import qualified GitHub validateVersionOTP :: MonadIO m => Maybe String -> m (Maybe String) validateVersionOTP version = do release <- fetchRelease "erlang" "otp" $ fmap (tagPrefix <>) version pure $ fmap (Text.unpack . Text.drop (length tagPrefix) . GitHub.releaseTagName) release where tagPrefix = "OTP-" Hamler ͷΠϯετʔϧํ๏ Hamler ͷެࣜυΩϡϝϯτʹԊͬͯɺdpkg Λར༻ͯ͠ΠϯετʔϧΛͯ͠Έ·͢ɻdeb ϑΝΠ ϧ͸ GitHub Release ͷΞηοτʹ͋Γ·͢ɻͰ͢ͷͰɺGitHub Release Λऔಘͯ͠ deb ϑΝΠϧ ͷΞηοτΛ୳ͯ͠μ΢ϯϩʔυ URL Λฦؔ͢਺Λఆٛ͠·͢ɻ Ϧετ 1.7: Hamler ͷ deb ϑΝΠϧͷμ΢ϯϩʔυ URL Λऔಘ͢Δؔ਺ import qualified Data.List as List import qualified Data.Text as Text import qualified GitHub fetchHamlerDebUrl :: MonadIO m => Maybe String -> m (Maybe String) fetchHamlerDebUrl version = do release <- fetchRelease "hamler-lang" "hamler" version pure $ do -- Maybe Ϟφυͷ Do ه๏Ͱ͢ assets <- GitHub.releaseAssets <$> release 6
  10. ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.2 Haskell Ͱ Dockerfile

    Λهड़͢Δ asset <- List.find (isHamlerDeb . GitHub.releaseAssetName) assets pure $ Text.unpack (GitHub.releaseAssetBrowserDownloadUrl asset) where -- hamler_{version}.deb ͱ͍͏Ξηοτ໊ͳͷͰ isHamlerDeb txt = "hamler_" ‘Text.isPrefixOf‘ txt && ".deb" ‘Text.isSuffixOf‘ txt Dockerfile Λߏங͢Δ ࠷ޙʹɺ2 ͭͷόʔδϣϯΛ༩͑ͨΒɺͦΕʹଈͨ͠ Dockerfile Λੜ੒͢Δؔ਺Λ࡞Γ·͢ɻ Ϧετ 1.8: Hamler ͷ deb ϑΝΠϧͷμ΢ϯϩʔυ URL Λऔಘ͢Δؔ਺ import Control.Monad.IO.Class (MonadIO) import qualified Data.List as List import Data.Maybe (fromMaybe) import Data.String (fromString) import qualified Data.Text.Lazy as L import GHC.Exts (fromList) import Language.Docker.EDSL data Config = Config { versionHamler :: Maybe String , versionOTP :: Maybe String } buildDockerfile :: MonadIO m => Config -> m (Either String L.Text) buildDockerfile Config{..} = do r1 <- fetchHamlerDebUrl versionHamler r2 <- validateVersionOTP versionOTP case (r1, r2) of (Nothing, _) -> pure (Left $ "hamler version is not found: " ++ fromMaybe "latest" versionHamler) (_, Nothing) -> pure (Left $ "Erlang/OTP version is not found: " ++ fromMaybe "latest" versionOTP) (Just url, Just v) -> pure $ Right $ toDockerfileText $ do from $ "erlang" ‘tagged‘ fromString v run $ fromString $ concat [ "apt-get update && apt-get install -y libtinfo5" -- hamler ʹඞཁ , " && apt-get clean" , " && rm -rf /var/lib/apt/lists/*" ] run $ fromString $ concat [ "wget -q -O /tmp/hamler.deb " ++ url , " && dpkg -i /tmp/hamler.deb" , " && rm /tmp/hamler.deb" ] entrypoint $ fromList ["hamler"] 7
  11. ୈ1ষ HaskellͰ͍͡ΔDockerfile 1.2 Haskell Ͱ Dockerfile Λهड़͢Δ Config{..} ͸ RecordWildCards

    ֦ு*15Λར༻ͨ͠ه๏ͰɺϑΟʔϧυͷ஋ΛϑΟʔϧυ໊ͷ ม਺΁ͱউखʹଋറͯ͘͠Ε·͢ɻͲͪΒ͔͕ Nothing Λฦͨ͠৔߹͸ΤϥʔϝοηʔδΛ Left Ͱฦ͢Α͏ʹ͠·ͨ͠ɻ Dockerfile Λهड़͸ dockerfile-creator ύοέʔδͷؔ਺Λར༻͠·͢ɻLanguage.Docker.EDS L.toDockerfileText ؔ਺Λར༻͢Δ͜ͱͰɺDo ه๏Λར༻ͯ͠ Dockerfile ෩ʹهड़Ͱ͖·͢ɻf rom ΍ run ͳͲɺׂͱ௚ײతʹಡΊ·͢ͶɻErlang VM ΛϕʔεΠϝʔδʹ͍ͨ͠ͷͰɺvalida teVersionOTP ؔ਺Ͱऔಘͨ͠όʔδϣϯΛϕʔεΠϝʔδλάͱͯ͠ར༻͍ͯ͠·͢ɻlibtinfo 5 ͸ Hamler ΛΠϯετʔϧ͢ΔͷʹඞཁͰ͢ͷͰɺapt-get ͍ͯ͠·͢ɻHamler ࣗମ͸ fetchH amlerDebUrl ؔ਺Ͱऔಘͨ͠μ΢ϯϩʔυ URL Λར༻ͯ͠ deb ϑΝΠϧΛ wget Ͱμ΢ϯϩʔυ ͖ͯͯ͠ɺdpkg ͯ͠Πϯετʔϧ͍ͯ͠·͢ɻ Docker ΠϝʔδΛ࡞ͬͯΈΔ ͯ͞ɺࢼ͠ʹ࡞ͬͨ CLI πʔϧΛར༻ͯ͠·͢ɻͪͳΈʹɺbuildDockerfile ؔ਺ͱ main ؔ ਺ͷͭͳ͗͜Έ͸ຊ࣭త͡Όͳ͍ͷͰׂѪ͠·ͨ͠ɻ $ stack exec -- hdc --hamler=0.4 > Dockerfile $ cat Dockerfile FROM erlang:24.0.3 RUN apt-get update \ && apt-get install -y libtinfo5 \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* RUN wget -q -O /tmp/hamler.deb \ https://github.com/hamler-lang/hamler/releases/download/0.4/hamler_0.4_amd64.deb \ && dpkg -i /tmp/hamler.deb \ && rm /tmp/hamler.deb ENTRYPOINT ["hamler"] /tmp/hamler.deb ͷ͋ͱͷվߦ͸ɺຊߘͰ͏·͘දࣔ͢ΔͨΊʹखಈͰೖΕͨվߦͰ͕͢ɺͦΕ Ҏ֎ͷվߦ͸શ෦ language-docker ͕΍͍ͬͯΔ͜ͱͰ͢ɻHamler ͷόʔδϣϯΛࢦఆ͍ͯ͠Δͷ ͸ɺHamler ͕ͳ͔ͥ Prerelease ͔͓ͯ͠͠Βͣɺlatest Ͱ͸࠷৽ͷόʔδϣϯΛऔಘͰ͖ͳ͍͔Β Ͱ͢ɻ૝ఆͲ͓Γͷ Dockerfile ͕Ͱ͖͕͋Γ·ͨ͠ɻ΋ͪΖΜɺͪΌΜͱϏϧυ࣮ͯ͠ߦͰ͖·͢ɻ $ docker build -t hamler . *15 https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/record_wildcards.html 8
  12. ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.3 ऴΘΓʹ [+] Building

    2.4s (7/7) FINISHED ... $ docker run -it --rm hamler repl Hamler REPL, version 0.4 Type :? for help > 1 + 1 2 > :q See ya! 1.3 ऴΘΓʹ ࠓճ͸ Haskell ͱ Dockerfile ʹ͍ͭͯऔΓ্͛ͯΈ·ͨ͠ɻࠓճ࡞ͬͨπʔϧ͙Β͍Ͱ͸ɺΘ͟ Θ͟ϓϩάϥϚϒϧʹ͠ͳͯ͘΋γΣϧεΫϦϓτͰͳΜͱͰ΋ͳΔͱࢥ͍·͢ɻ͔͠͠ɺͨͱ͑͹ Πϯετʔϧ͍ͨ͠πʔϧͷόʔδϣϯʹΑͬͯΠϯετʔϧํ๏Λม͔͑ͨͬͨΓɺΑΓෳࡶͳ ґଘؔ܎͕͋ͬͨΓ͢Δ৔߹͸ɺϓϩάϥϚϒϧʹ Dockerfile ΛߏஙͰ͖Δͱศར͔΋͠Ε·ͤΜɻ ࢲͷ৔߹͸ɺ֎෦ͷπʔϧͷόʔδϣϯΞοϓΛࣗಈݕ஌ͯ͠ Dockerfile Λߏங͠ɺDocker Πϝʔ δΛϓογϡ͢ΔΑ͏ͳπʔϧΛ࡞Δͷʹར༻͍ͯ͠·ͨ͠ɻ ·ͨɺhadolint ΍ shellcheck ͸ Haskell ੡ͱ஌Βͣʹར༻͍ͯ͠Δਓ͕·͊·͍͊Δศརπʔϧ ͡Όͳ͍Ͱ͠ΐ͏͔ɻ࣮͸ Haskell ͳΜͩΑʂ ͍ͬͯ͏ͨΊʹॻ͍ͨͷ΋࣮͸গ͚ͩ͋͠Γ·͢সɻ Pandoc ΍ GitHub ͕࡞͍ͬͯΔ semantics ͷ͜ͱΛߟ͑Δͱɺύʔεͯ͠ந৅ߏจ໦ʹ͍ͯ͠Ζ Μͳ͜ͱΛ͢Δͷ͸ Haskell ͷಘҙ෼໺ͳͷ͔΋͠Εͳ͍Ͱ͢Ͷɻ 9
  13. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 21 ৽ଔͷߐാͰ͢ɻ಺ఆऀݚम

    (ೖࣾલݚम) ʹͯɺνʔϜ։ൃΛ͢ΔͨΊʹඞཁͳϓϩδΣΫτ ߏ଄ʹ͍ͭͯษڧ͠ɺΞ΢τϓοτͰ͖ͦ͏ͳ஌ݟΛੵΉ͜ͱ͕Ͱ͖ͨͷͰɺڞ༗͍͚ͤͯͨͩ͞͹ ͱࢥ͍·͢ɻ ΑΓৄࡉʹ͸ (αʔόدΓͷ) ίʔυʹΑͬͯੜ͡Δ໰୊ʹয఺Λ౰͓ͯͨ࿩Λ঺հ͠·͢ɻ ݚमͷಈػͱͯ͠͸ɺͨͱ͑͹ Golang ͱ Java, Lisp Ͱ͸ಉҰઃܭࢥ૝Λద༻͠Α͏ͱͯ͠΋݁ ߏͳࠩ෼͕ग़ͯ͠·͏͜ͱʹରͯ͠ɺ͜ͷ ίʔυతࠩ෼ Λҙࣝͯ͠ɺ Ͳ͏ॻ͘͜ͱ͕Ͱ͖Ε͹νʔ Ϝϝϯόʔͱҙࣝڞ༗͕Ͱ͖Δ͔ʁ ͱ͍͏ٙ໰ͷ౴͕͑஌Γ͍ͨɺͱ͍͏΋ͷ͕͋Γ·ͨ͠ɻ 2.1 ͖Ε͍ͳίʔυͷҐஔ෇͚ ࡢࠓ͞·͟·ͳϑϨʔϜϫʔΫ΍ɺઃܭࢥ૝ɺ։ൃख๏͕ຮԆ͍ͬͯΔ͜ͱ͸օ͞Μ΋͝प஌ͷ͜ ͱͱ͸ࢥ͍·͢ɻͨͱ͑͹Ұੲલ *1 ʹ͸ Ruby on Rails ։ൃ͕ओྲྀͰ͕ͨ͠ɺ࠷ۙͰ͸ϚΠΫϩ αʔϏε΍ςετۦಈ։ൃɺΞδϟΠϧ։ൃͳͲʹ஫໨͕ू·͍ͬͯ·͢ *2 ɻ ࠓճ͸ಛʹϞμϯͳ։ൃΛҙࣝ͠ɺ࣍ͷ 4 ͭͷ؍఺Λຬͨ͢ϓϩδΣΫτ / ίʔυΛ͖Ε͍ͳίʔ υͱҐஔ෇͚·͢ɻ *1 େֶͷΧϦΩϡϥϜ΁ੵۃతʹऔΓೖΕΒΕΔͳͲͷಈ͖ (https://www.enpit.jp/) ͔Βɺ2017~2020 ೥͝Ζ͕ϐʔ ΫͩͬͨΑ͏ͳΠϝʔδͰ࿩͍ͯ͠·͢ɻࣾձਓʹͳͬͯ (2021) ͔Βੈք͕ Rails ͰͰ͖͍ͯͳ͍ͱײ࢝͡ΊͨόΠ Ξε͕͋Δ͔΋͠Ε·ͤΜɻ *2 ΑΓ࠷৽ͷ࿩Ͱ͸ɺϚΠΫϩαʔϏε΋ݹ୅ͷٕज़ʹͳ͍ͬͯΔͱ͔ݴΘΕ͍ͯ·͢ɻIT ෼໺ͷٕज़ͷਐา͸ૣ͍Ͱ ͢Ͷɻ 11
  14. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.1 ͖Ε͍ͳίʔυͷҐஔ෇͚

    อकੑ͕ߴ͍͜ͱ ͜͜Ͱ͍͏อकੑͱ͸ɺͦͷϓϩάϥϜʹ͍ͭͯ੔උɺҡ࣋ɺ؅ཧ͕͠΍͍͢͜ͱΛࣔ͠·͢ɻͨ ͱ͑͹ɺΧελϚʔαʔϏε͔Βґཔ͕དྷͨͱ͖ʹݪҼಛఆ΍ͦͷमਖ਼͕༰қͰ͋Δ͜ͱɺΠϯϑϥ ͷόʔδϣϯΞοϓσʔτʹڧ͍͜ͱͳͲ͕۩ମతͳཁ݅ͱͳΓ·͢ɻ ςετઃܭ͕༰қͰ͋Δ͜ͱ ։ൃνʔϜ/؀ڥʹΑͬͯ͸ɺςετΛॻ͍͍ͯΔ͜ͱ͕͖Ε͍ͳίʔυɺͱΈͳ͞ΕΔ͜ͱ΋͋ Γ·͢ɻ͔͠͠ͳ͕ΒɺςετΛॻ͖΍͍͢؀ڥ੔උ΋͖Ε͍ͳίʔυΛॻͨ͘Ίͷཁૉͱͯ͠਺͑ Δ͜ͱ͕Ͱ͖·͢ɻͨͱ͑͹ɺϏδωεϩδοΫ಺Ͱ O/RM Λݺͼग़ͯ͠σʔλϕʔεͱͷऔҾΛ ߦ͍ͬͯΔΑ͏ͳίʔυ͸ɺςετΛॻ͘ͷ΋༰қͰ͸͋Γ·ͤΜɻΑͬͯɺςετΛॻ͖΍͍͢Α ͏ͳઃܭ͕Ͱ͖͍ͯΔ͜ͱ΋ɺ͖Ε͍ͳίʔυΛߏ੒͢ΔҰһͰ͋Δݴ͑·͢ɻ ػೳͷ֦ு͕༰қͰ͋Δ͜ͱ ҰൠʹΞδϟΠϧ։ൃΛϕʔεʹϓϩδΣΫτΛਐΊ͍ͯ͘ͱɺػೳͷ֦ுΛٻΊΒΕΔέʔε͕ ଟ͘ଘࡏ͠·͢ɻػೳͷ֦ுΛߦ͏ࡍʹɺಉ͡ϓϩηεΛطଘͷػೳ͔ΒҾ༻͠૊Έ߹ΘͤΒΕΔ͜ ͱ͸ɺϓϩάϥϚʔͷଵଦͳಛੑΛ׆͔ͨ͢Ίʹඞཁͳಛ௃Ͱ͢ɻͦͷͨΊɺ֦ு͢ΔະདྷΛݟӽ͞ ͳ͍ػೳ࣮૷͸ɺ࣍ͷ։ൃʹର͢Δେ͖ͳ؞ͱͳͬͯ͠·͏Մೳੑ͕ߴ͘ͳΓ·͢ɻ εέʔϥϏϦςΟ͕ߴ͍͜ͱ ۙ೥Ͱ͢ͱɺΫϥ΢υϦιʔεΛ׆༻ͯ͠ෛՙ෼ࢄ΍৑௕ੑͷ֬อͳͲΛߦ͏έʔε͕૿͖͑ͯͯ ͍·͢ɻͨͱ͑͹ Google ΍ Amazon Ͱ͸ɺKubernates ΍ Docker Λ༻͍ͯαʔόϦιʔεͷಈ తͳ࠷దԽΛ࣮ݱ͢ΔαʔϏεΛల։͍ͯ͠·͢ɻ *3͜ΕΒͷαʔϏεΛར༻͢ΔͨΊʹ͸ɺαʔό Ϧιʔε͕ಈతʹมԽͯ͠΋ఏڙ͢ΔαʔϏεʹҰ؏ੑΛ࣋ͨͤΒΕΔઃܭ͕ඞཁͩͱݴ͑·͢ɻ *3 ϛΫγΟͰ͸͜ΕΒͷαʔϏεΛੵۃతʹ࠾༻͍ͯ͠·͢ɻ 12
  15. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.2 Project:CCC

    2.2 Project:CCC ࠓճ͖Ε͍ͳίʔυͷͨΊͷཁૉͱͯ͠ɺ1) Clean Architecture 2) Clean Code 3) Cloud Native ͷ 3 ͭΛऔΓ্͛ௐࠪ͠·ͨ͠ɻຊষͰ͸લఏͷڞ༗ͱͯ͠ɺ͜ͷ 3 ཁૉʹ͍ͭͯ৘ใͷ੔ཧΛߦ͍ ·͢ɻ Clean Architecture Clean Architecture ͱ͸ɺίʔυͷ࠶ར༻ੑ΍֦ுੑΛߴΊΔͨΊͷɺϓϩδΣΫτͷઃܭࢥ૝ Ͱ͢ɻ۩ମతʹ͸ɺΦχΦϯΞʔΩςΫνϟͱݺ͹ΕΔԼͷਤ *4 ͕༗໊Ͱ͢ɻ͔͠͠ͳ͕Β Clean Architecture Ͱॏཁͳͷ͸ɺ ؔ৺ͷ෼཭ ΍ ґଘੑͷϧʔϧ ͱ͍͏Ωʔϫʔυʹ͋Γ·͢ɻ ਤ 2.1: Clean Architecture ͷΠϝʔδਤ ؔ৺ͷ෼཭ ؔ৺ͷ෼཭ͱ͍͏ͷ͸ɺ͋ΔಛఆͷॲཧΛѻ͍΍͍͢Ϟδϡʔϧʹ෼ׂ͢ΔͨΊͷઃܭํ਑Λࢦ͠ ·͢ɻ ͨͱ͑͹ɺ ͋Δ਺ࣈΛೖྗ͠ ̍Λ଍ͯ݁͠ՌΛอଘ͢Δ ॲཧΛߟ͑·͢ɻ͜ͷͱ͖ͷϞδϡʔ ϧͷྫͱͯ͠͸ɺ 1) WebϑΥʔϜ͔Β਺ࣈΛೖྗ͢Δ 2) ̍Λ଍͢ 3) ݁ՌΛ PostgreSQL ΁อଘ ͢Δ ͷ̏ͭΛߟ͑Δ͜ͱ͕Ͱ͖·͢ɻ ؔ৺ͷ෼཭Λߦ͏ͱɺຊ౰ʹඞཁͳαʔϏεͷϩδοΫ (2) Λͦͷ··ʹɺ΄͔ͷ௿͍ؔ৺ࣄ (1, 3) ΛೖΕସ͑ͨΓɺ࢓༷ʹଈͨ͠ςετΛॻ͘͜ͱ͕Ͱ͖·͢ɻ *4 https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html 13
  16. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.2 Project:CCC

    ͜ͷྫͰ͸ɺೖྗπʔϧ͸ CLI ΍ Unity UI Ͱ΋͔·͍·ͤΜ͠ɺܭࢉ݁Ռͷอଘઌ͸ Google Cloud Spanner Ͱ΋͔·͍·ͤΜɻؔ৺ͷ෼཭ʹΑͬͯαʔϏεͷن໛Λ֦େ͠΍͘͢ͳΔ͜ͱ͸ɺ ༰қʹ૝૾Ͱ͖Δͱࢥ͍·͢ɻ ґଘੑͷϧʔϧ ґଘੑͷϧʔϧͱ͍͏ͷ͸ɺϞδϡʔϧؒͰͷґଘؔ܎Λॏཁ౓ʹͦΖ͑Α͏ɺͱ͍͏͜ͱͰ͢ɻ ઌఔͷྫͰݴ͑͹ɺೖྗπʔϧͷ࣮૷͕ 1 Λ଍͢ ͱ͍͏ϩδοΫͷ࣮૷ʹӨڹΛ༩͑Δ΂͖Ͱ͸ ͳ͍ɺͱ͍͏͜ͱʹͳΓ·͢ɻந৅౓Λ্͛ͯݴ͍௚ͤ͹ɺϏδωεϩδοΫ͸ɺϑϨʔϜϫʔΫ΍ ֎෦ API ͷ࣮૷ʹৼΓճ͞Εͯ͸͍͚·ͤΜɻ ͜ͷϧʔϧ͸ɺϋʔυͳϑϨʔϜϫʔΫ (Ruby on Rails ΍ Django ɺSpring ) ͷΑ͏ͳɺXXX ͷػೳ͸ A Ͱ࣮૷͢΂͠ ͱ͍͏ิॿπʔϧͱ͸૬ੑ͕Α͋͘Γ·ͤΜɻ࣮ࡍ Clean Architecture Ͱ͸ɺϑϨʔϜϫʔΫΛϞδϡʔϧͷґଘؔ܎తʹ࠷΋֎ଆʹ͋Δ΂͖Ϟδϡʔϧͱ͍ͯ͠·͢ɻ Clean Code Clean Code ͱ͸͖Ε͍ͰಡΈ΍͍͢ίʔυΛॻͨ͘ΊͷنଇͰ͢ɻઌఔͷ Clean Architecture ͕ࢥ૝Ͱ͋Δͷʹରͯ͠ɺ Clean Code ͸ΑΓڧ੍ྗͷ͋ΔʮͲ͏͢Δ΂͖ʯ͕ଟࣔ͘͞Ε͍ͯ·͢ɻ ͔͠͠ͳ͕Β໋໊نଇ΍ίʔυͷॻ͖ํͳͲ͸ݴޠ΍ύϥμΠϜʹΑͬͯେ͖͘ҟͳΔͨΊɺࢲ͸ ͜ͷڲਖ਼ʹൺֱత൷൑తͳཱ৔Λऔ͍ͬͯ·͢ *5 ɻ Αͬͯຊ߲໨Ͱ͸ɺClean Code ʹ͓͚Δ ԿΛҙࣝ͢Ε͹ίʔυ͕ಡΈ΍͘͢ͳΔ͔ Λ͍͔ͭ͘ ঺հ͠·͢ɻ ໋໊ʹҙຯ͕͋Δ͜ͱ ୹ॖ໊΍ಉ྅ͷதͰ͔͠௨͡ͳ͍ಛघ༻ޠΛ༻͍ΔͱɺίʔυͷՄಡੑ͕Լ͕Γ·͢ɻ ؔ਺ͷڽूੑɺ݁߹ੑ͕ద੾Ͱ͋Δ͜ͱ Ұͭͷؔ਺ʹෳ਺ͷػೳ͕ݻ·ͬͯ͠·͏ͱɺςετ΍σόοάΛࠔ೉ʹ͠·͢ɻ·ͨಛఆͷؔ਺ ʹґଘͨؔ͠਺΍Ϟδϡʔϧ͸ɺҰ෦ͷ΄͜ΖͼͰ༰қʹյΕͯ͠·͍·͢ɻ ద੾ͳίϝϯτ͕͋Δ͜ͱ *5 ͢΂ͯͷϓϩδΣΫτʹରͯ͠ A Ͱ͋Δ΂͖ɺͱ͍͏نଇ͸ద༻͢Δ͜ͱ͕೉͍͠Ͱ͢ɻಛʹۙ೥Ͱ͸ Web ։ൃ΍ αʔόαΠυ։ൃɺήʔϜ։ൃɺAI ։ൃͳͲɺߟ͑ํ΍धཁ͕·ͬͨ͘ҟͳΔ։ൃ͕͋ΔͨΊɺ൚༻తͳϓϩάϥϛϯ άϧʔϧΛߟ͑Δ͜ͱ͸ࠔ೉Ͱ͋Δͱݴ͑·͢ɻ 14
  17. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.2 Project:CCC

    ࣮૷ͷҙਤ͸࣮૷ίʔυͷΈͰ఻ΘΒͳ͍͜ͱ͕͋ΔͷͰɺίʔυ಺ͳ͍͠ίʔυ֎Ͱ࢓༷Λ৘ใ ڞ༗͢Δඞཁ͕͋Γ·͢ɻؒҧͬͯ΋ ςετ͕͋Δ͔Β࢓༷΍υΩϡϝϯτ͸͍Βͳ͍ ͳͲͱߟ͑ ͯ͸͍͚·ͤΜɻ ςετίʔυ͕ॻ͖΍͍͢͜ͱ ෳࡶͳґଘͷ͋Δؔ਺ͳͲ͸ɺςετίʔυ͕ॻ͖ʹ্͍͘ʹɺ࢓༷ͱͷ͢Γ߹Θ͕ͤࠔ೉ͱͳΔ ͜ͱ͕ଟ͍Ͱ͢ɻςετίʔυ͕ॻ͖΍͘͢ͳΔ͜ͱͰ࢓༷Λ֬ೝͰ͖ͨΓɺอकੑ΍ՄಡੑΛ্͛ ͨΓ͢Δ͜ͱ͕๬Ί·͢ɻ Cloud Native Cloud Native ͱ͸ɺίϯςφ΍Ϋϥ΢υϦιʔεΛ༻͍ͨɺো֐͔Βͷճ෮ྗɺΠϯϑϥ؅ཧͷ ༰қ͞ɺͦΕͧΕͷϦιʔεͷՄࢹੑͷ޲্ΛਤΔͨΊͷٕज़ɺ·ͨͦͷٕज़Λద༻ͨ͠αʔϏεΛ ࢦ͠·͢ɻCloud Native ͸ɺࠓ·Ͱͷࢥ૝΍نଇɺͱ͍͏ΑΓ͔͸ɺ݁Ռʹॏ͖͕͋Γ·͢ɻ ผͷݴ͍ํΛ͢Ε͹ɺCloud Native Ͱ͋ΔͨΊʹ͸ɺΫϥ΢υͳؾ࣋ͪʹͳΔඞཁ΋ɺGoogle Cloud ্ʹ Docker ͳϚγϯΛ৐͚ͬΔඞཁ΋ͳ͍Ͱ͢ɻ࣮ࡍʹϦΫΤετͷ૿ݮʹରͯ͠αʔϏ εϦιʔε͕εέʔϧͨ͠ͱ͍͏݁Ռ͕ॏཁࢹ͞Ε·͢ɻ Ͱ͢ͷͰɺGoogle Cloud Engine ʹϞϊϦγοΫͳϚγϯΛ৐͚͔ͬͨΒ Cloud Native ʹͳΔ Θ͚Ͱ͸ͳ͍Ͱ͢ɻ ͜͜·ͰΛಡΜͰͩͬͨ͘͞ํͷதʹ͸ɺClean Architecture ΍ Clean Code Λक͍ͬͯΕ͹ɺ Cloud Native ΁ͷҠߦ͸؆୯ʹͳΔͱࢥΘΕΔํ΋͍Δ͔΋͠Ε·ͤΜɻ ͔͠͠ͳ͕Βɺ্ड़ͷ Clean ๭͸΄ͱΜͲͷέʔεͰ׬ᘳͰ͸ͳ͘ɺͦΕͧΕͰߦΘΕΔখ͞ͳ ଥڠͷੵΈॏͶʹΑͬͯ Cloud Native ͕ࠔ೉ʹͳͬͯ͠·͏͜ͱ͕͋Γ·͢ɻ ͨͱ͑͹ɺҰൠʹσʔλϕʔεͱͷ΍ΓͱΓΛந৅Խ͢Δͷ͸೉͘͠ɺͲ͏ͯ͠΋Ϗδωεϩδο ΫʹӨڹΛ༩͑ͯ͠·͏͜ͱ͕͋Γ·͢ɻ·ͨɺϋʔυͳϑϨʔϜϫʔΫ΍؆୯ͳϥΠϒϥϦΛར༻ ͨͨ͠ΊʹɺͦΕΒ΁ͷґଘ౓ͷߴ͍࣮૷Λߦͬͯ͠·͏͜ͱ΋ܦݧ͕͋Δͱࢥ͍·͢ɻ ͜ΕΒͷྫ͸ɺ࣮૷্࢓ํ͕ͳ͔ͬͨΓɺՄಡੑΛ޲্ͤ͞ΔͨΊʹඞཁͳख๏Ͱ͋Δͱݴ͑·͢ ͕ɺCloud Native ΁ରԠͤ͞Δࡍʹੜ͡ΔΠϯϑϥͷҠߦͳͲʹ੬ऑʹͳΔ͜ͱ͕͋Γ·͢ɻ 15
  18. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ ͜͜·Ͱɺ͖Ε͍ͳίʔυͷͨΊʹඞཁͳཁૉΛ͍͔ͭ͘঺հͯ͠དྷ·ͨ͠ɻ ࢲ͸ຊ୊ͷݚमʹͯɺ͜ΕΒͷ஌ݟΛ΋ͱʹ͍͔ͭ͘ͷαʔϏε΍ࢼ࡞ͷ࣮૷Λߦ͍·ͨ͠ɻͦͷ தͰɺ(΋ͪΖΜΘ͟ͱϛεΛى͜͢Α͏ͳ࣮૷Λͨ͠Θ͚Ͱ͸ͳ͍Ͱ͕͢) ͍͔࣮ͭ͘૷ʹ٧·Δ ෦෼͕͋Γ·ͨ͠ɻຊষͰ͸ɺͦΜͳ͖Ε͍ͳίʔυͷҰൠ࿦ͷΈͰ͸ղܾͰ͖ͦ͏ʹͳ͔ͬͨ෦෼ Λɺ۩ମతͳࣄҊͱͱ΋ʹ঺հ͍ͨ͠ͱࢥ͍·͢ɻ ͳ͓ɺར༻ͨ͠ݴޠ͸ Clojure ͱݺ͹ΕΔ೔ຊਓ͸΄ͱΜͲ஌Βͳ͍ະ஌ͷݴޠͷͨΊɺৄ͍࣮͠ ૷ͳͲʹ͍ͭͯ͸লུ͠·͢ɻ ࣄҊ 1 : Transaction ͸ϏδωεϩδοΫ͔ʁ ঢ়گ ༬ۚςʔϒϧ bank_accounts ʹ͍ͭͯɺϢʔβʔ Harry, Ron ؒͷૹۚ (remittance) Λߟ͑ ·͢ɻ 1. Harry ͷ༬͔ۚΒ amount ԁࠩ͠Ҿ͘ 2. Ron ͷ༬ۚΛ amount ԁ૿΍͢ ͜ͷͱ͖ɺ্ͷ 1., 2. ͸ ACID ʹѻΘΕΔඞཁ͕͋ΓɺTransaction Λઃ͚Δඞཁ͕͋Γ·͢ɻ ࠓճ͸୯Ұσʔλϕʔεʹରͯ͠ͷ Transaction Ͱ͢ͷͰɺҰൠతͳϩοΫΛ༻͍ͨ Transaction Λ࢖͏͜ͱ͕Ͱ͖·͢ɻ Ұൠʹ Transaction ͸σʔλϕʔε΍σʔλϕʔεͷϥούϥΠϒϥϦʹґଘ͍ͯ͠·͢ɻͦͷ ͨΊɺClean Architecture ͷཧ૝ͱͯ͠͸ɺ͜ͷґଘΛϩδοΫͷ֎෦΁ԡ͠ग़͓͖͍ͯͨ͠ͱߟ͑ ·͢ɻ ͔͠͠ͳ͕Βɺ࣮༻ͱͯ͠τϥϯβΫγϣϯ಺ͷॲཧࣗମ͸ϩδοΫ಺ͰฤूͰ͖ͨ΄͏͕֦ ுੑ͕ߴ͍ͷ΋ࣄ࣮Ͱ͢ɻͨͱ͑͹ɺ্͔࢘Βૹۚʹରͯ͠ख਺ྉΛऔΓ͍ͨͱݴΘΕͨͱ͖ɺ Transaction ͷத਎͸ϏδωεϩδοΫͷதʹ͋ͬͨ΄͏͕ศར͔΋͠Ε·ͤΜɻ ͯ͞ɺ͜͜Ͱ 1., 2. ͷ࣮૷͸ͲͷΑ͏ʹॻ͔ΕΔ΂͖Ͱ͠ΐ͏͔ʁ Ϧετ 2.1: ༬ۚςʔϒϧͷ࣮૷ 1: /* 001_bank_accounts.up.sql */ 2: 3: CREATE TABLE bank_accounts ( 4: user_uid VARCHAR(255) REFERENCES users(uid), 5: deposit bigint, 6: created_at TIMESTAMP default CURRENT_TIMESTAMP, 7: updated_at TIMESTAMP, 8: is_active BOOLEAN NOT NULL default TRUE, 9: is_deleted BOOLEAN NOT NULL default FALSE 16
  19. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    10: ); ࣮૷ྫ ࠓճ͸γϯϓϧʹΦχΦϯͳΠϥετ ʮClean Architectureʯ Λࢀߟʹ࣍ͷΑ͏ʹ࣮૷͍ͯ͠· ͢ (Infrastructureɺೖग़ྗपΓͷ Interface ͸লུ)ɻͳ͓ɺ Clojure Ͱॻ͍͍ͯΔͷͰɺৄࡉΛল ͍͍ͯ·͢ɻ Domain Ϧετ 2.2: ./domain/bank-example.clj 1: (ns bank-example.domain.bank_account 2: (:require [clojure.spec.alpha :as s] 3: [bank_example.domain.user :as user-domain])) 4: 5: ;; deposit ͸ 0 Ҏ্ͷ਺ࣈͰ͋Δ ͱ͍͏࢓༷ 6: (s/def ::deposit (s/and number? #(<= 0 %))) 7: (s/def ::created-at pos-int?) 8: (s/def ::updated-at pos-int?) 9: (s/def ::is-active boolean?) 10: (s/def ::is-deleted boolean?) 11: 12: ;; bank_account ͸ 13: ;; uid, deposit, created-at, updated-at, is-active, is-deleted Ͱߏ੒͞ΕΔͱ͍͏࢓༷ 14: (s/def ::bank_account 15: (s/keys :req-un 16: [::user-domain/uid ::deposit 17: ::created-at ::updated-at 18: ::is-active ::is-deleted])) Usecase ΤϥʔϋϯυϦϯάपΓ͸লུ Ϧετ 2.3: ./usecase/remittance-post 1: (ns bank-example.usecase.remittance-post) 2: 3: ;; ৄࡉ͸লུ 4: (defn check-user 5: "Ϣʔβ͕ਖ਼͍͔͠νΣοΫ͢Δ" 6: [{:keys [input-model db]}] 17
  20. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    7: ;; ৄࡉ͸লུ 8: ) 9: 10: (defn check-accounts 11: "ޱ࠲͕༗ޮͰ͋Δ͔νΣοΫ͢Δ" 12: [{:keys [sender receiver db]}] 13: ;; ৄࡉ͸লུ 14: ) 15: 16: (defn transfer-deposit 17: "sender ͱ receiver ͷ༬ۚΛ΍ΓऔΓ͢Δ" 18: [{:keys [input-model sender receiver db]}] 19: ;; ͜͜ʹ transaction ॲཧΛॻ͘΂͖ʁ 20: ) 21: 22: (defn ->output-model 23: "ग़ྗͷϞσϧΛ࡞Δ" 24: [{:keys [result]}] 25: ;; ৄࡉ͸লུ 26: ) 27: 28: (defn post-remittance 29: "ଏʹݴ͏ϝΠϯؔ਺" 30: [input-model db] 31: (-> 32: {:input-model input-model 33: :db db} 34: check-user 35: check-accounts 36: transfer-deposit 37: ->output-model)) Interface Ϧετ 2.4: ./interface/gateway/database/bank_account_repository.clj 1: (ns bank-example.interface.gateway.database.bank-account-repository) 2: 3: ;; defprotocol ͸͍ΘΏΔΠϯλʔϑΣʔε 4: (defprotocol BankAccount 5: ;; transaction Λ࢖Θͳ͍ํ๏ 6: (transfer [db sender-uid receiver-uid amount]) 7: 8: ;; transaction Λ֎෦΁ు͖ग़͢΍Γํ 9: ;; -> transaction Ͱॲཧ͢ΔͳΒ͹ɺ4ͭΊͷҾ਺ʹ transaction ΦϒδΣΫτΛ౉͢ 10: (get-transaction [db options]) 11: (credit [db user-uid amount transaction?]) 12: (deposit [db user-uid amount transaction?])) 18
  21. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    ͦΕͧΕͷҙݟ ˙ཱ৔ A: Transaction ͸ϏδωεϩδοΫͰ͋Δ ɹɹɹɹɹɹ ૹۚϓϩηε͸ɺ • ૹۚऀ͔Β༬ۚΛҾ͘ • डۚऀ͕༬ۚΛड͚औΔ ͷ̎ͭʹ෼ׂͰ͖·͢ɻ ͦͷͨΊ Usecase ಺ͷίʔυͷڽूੑΛԼ͛ΔͷͰ͋Ε͹ɺ෼ׂ͢Δͷ͕ཧʹ͔ͳ͍ͬͯ·͢ɻ ͔͠͠ Transaction ͷ࣮૷͸σʔλϕʔεͷ࣮૷ʹґଘ͢Δέʔε͕ଟ͘ *6 ɺClean Architecture ͷؔ৺ͷ෼཭Λద੾ʹߦ͑ͳ͍Մೳੑ͕͋Γ·͢ɻ ˙ཱ৔ B: Transaction ͸ϏδωεϩδοΫͰ͸ͳ͍ ɹɹɹɹɹ Transaction ͸ ACID ʹѻΘΕΔ΂͖ॲཧͰ͢ͷͰɺ͜Ε͸୯Ұͷॲཧͱͯ͠ѻͬͯྑ͍ɺͱߟ͑ Δཱ৔Ͱ͢ɻ͜ͷཱ৔Ͱ͸ૹۚॲཧ͸ Interface ಺Ͱந৅Խ͞Ε্ͨͰɺUsecase Ͱݺͼग़͞Ε·͢ɻ ͜ͷ࣮૷ํ๏Ͱ͸ɺ ෭࡞༻ ɺͱ͍͏؍఺͔Β Usecase ͕༏Ε࣮ͨ૷ʹͳΓ·͢ɻ෭࡞༻ͱ͸ɺ I/O ॲཧɺTransaction ॲཧͳͲɺ಺෦ʹঢ়ଶΛ࣋ͪɺͦͷঢ়ଶΛมԽͤ͞ΔॲཧΛࢦ͠·͢ *7 ɻ Ұൠʹ෭࡞༻ͷͳ͍ॲཧ͸ɺಉ͡ೖྗΛ༩͑Ε͹ඞͣಉ͡ग़ྗ͕ಘΒΕΔ͜ͱ͕อূ͞ΕΔͨΊɺς ετͷ࣮૷͕༰қͰ͢ɻ ·ͨτϥϯβΫγϣϯॲཧΛ Interface ಺ʹམͱ͠ࠐΜͩ͜ͱͰɺཱ৔ A ʹൺ΂ͯɺUsecase ʹ ͓͚Δσʔλϕʔεͷ࣮૷ґଘ౓ΛݮΒ͢͜ͱ͕Ͱ͖·͢ɻ ͔͠͠৽نػೳͷ௥Ճʹࡍͯ͠ɺUsecase ͱ Interface ͷ࣮૷Λ྆ํมߋ͠ͳ͚Ε͹ͳΒͳ͍έʔ ε͕૿͑Δ͜ͱ͕͋Γ·͢ɻ ˙ཱ৔ C: Transaction ͸ಠཱͨ͠ϨΠϠͱͯ͠ந৅Խ͞Ε্ͨͰར༻͞ΕΔ΂͖Ͱ͋Δ ɹɹɹɹ ɹ ཱ৔ Aɺ B ͷதؒ఺Λ୳Δ΋ͷͰ͢ɻ ͨͱ͑͹ Transaction Λߦ͏ॲཧΛ Service ͱͯ͠ Repository (Interface) ͱ Usecase ͷؒʹڬ Ήख๏͕ߟ͑ΒΕ·͢ɻ͜ͷϨΠϠΛڬΉ͜ͱͰɺ Usecase ಺Ͱ͸ Clean Code Λɺ Service ಺Ͱ ෭࡞༻ϚγϚγͳίʔυΛॻ͘ɺͱ͍͏Θ͚Ͱ͢ɻ ͜ͷ࣮૷ํ਑ͷܽ఺͸ɺ࣮૷ίετ͕ߴ͘ͳΔՄೳੑ͕͋Δ఺ɺTransaction Λ࢖Θͳ͍ॲཧΛ Repository ͔Βݺͼग़ͨ͠ࡍʹґଘؔ܎͕Ԛ͘ͳΔ఺Ͱ͢ɻ *6 ҰԠ Java Ͱ͋Ε͹ JDBC ͱ͍͏υϥΠό͕ଟ͘ͷσʔλϕʔεͷϥούͱͯ͠ػೳ͠·͢ɻ͔͠͠ JDBC ͷα ϙʔτ֎Ͱ͋Δέʔε΍ɺผͷυϥΠόʹ࣮૷Λม͍͑ͨέʔεͰ͸ɺཱ৔ A ͸࠷ྑͱ͸ݴ͍ͮΒ͍Ͱ͢ɻ *7 ݫີͳ෭࡞༻ͷఆٛ͸ Land of Lisp (ISBN-13:978-4873115870) ΍ɺ Haskell ͷυΩϡϝϯτΛࢀর͍ͩ͘͞ɻ 19
  22. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    ਤ 2.2: ཱ৔ C ʹ͓͚Δґଘؔ܎άϥϑͷมԽ ࠾୒࣮ͨ͠૷ํ਑ͱͦͷબఆཧ༝ ཱ৔ B Λ࠾༻࣮͠૷͠·ͨ͠ɻཧ༝͸̏ͭ͋Γ·͢ɻ • Clojure (Lisp) ͸ؔ਺ܕݴޠϕʔεͳͨΊɺ෭࡞༻ʹݫ͍͠จԽ͕͋Δ ͜͜Ͱ༻͍Δؔ਺ͱ͸ y = f(x) ͕ৗʹ੒ཱ͢ΔΑ͏ͳ f Λࢦ͠·͢ɻ಺෦ঢ়ଶΛ࣋ͨͳ͍͜ͱΛ ݪଇͱ͢Δؔ਺ʹରͯ͠ɺTransaction ͸΍΍ෆద੾ͳߏ੒ཁૉͰ͢ɻ ରͯ͠ɺGolang ΍ PythonɺRuby ͳͲଟ͘ͷϓϩάϥϛϯάݴޠͰ͸ɺσʔλͷഁյతมߋ΍ ಺෦ঢ়ଶͷอ͕࣋ৗࣝͰ͋ΔͨΊɺ͜ͷཧ༝Λߟྀ͢Δඞཁ͕͋Γ·ͤΜɻ • Cloud Spannerɺ Cloud SQL Ͱ next.jdbc ͕࢖͑Δ ࠓճ Cloud Native ͷͨΊʹೖΕସ͑Δ SQL σʔλϕʔεͷީิͱͯ͠ɺGoogle Cloud Spannerɺ Cloud SQL Λ૝ఆ͍ͯ͠·ͨ͠ɻՃ͑ͯɺࠓճ͸ SQL ϥούϥΠϒϥϦʹɺ্ड़ͨ͠σʔλϕʔ εͷ࣮ߦΛαϙʔτ͢Δ next.jdbc ͱ͍͏ϥΠϒϥϦΛར༻͠·ͨ͠ɻΑͬͯɺཱ৔ C ΄Ͳஸೡ ʹ Transaction Λ੾Γग़ͣ͞ͱ΋ Repository ಺෦ͰղܾͰ͖Δͱߟ͑·ͨ͠ɻ ରͯ͠ɺࣗ࡞ͷσʔλϕʔεͷར༻Λ૝ఆ͍ͯ͠ΔέʔεͰ͸ ཱ৔ B ΑΓ΋ ཱ৔ C ͷํ͕ద੾ Ͱ͋ΔՄೳੑ͕͋Γ·͢ɻ ·ͨɺଞݴޠɺϥΠϒϥϦΛ༻͍ΔέʔεͰ΋ɺকདྷతʹͲͷσʔλϕʔεΛ࢖͏ͷ͔ɺͦΕΒͷ σʔλϕʔε͕ར༻ՄೳͰ͋Δ͔Λߟྀ͠ͳ͚Ε͹ͳΓ·ͤΜɻ • Interface ಺෦Ͱ Transaction पΓͷΫΤϦ࠷దԽΛߦ͍͍ͨ O/RM ͳͲଟ͘ͷΞϯν SQL ͳπʔϧΛ࢖ͬͨଟ͘ͷέʔεͰɺΫΤϦॲཧͷ࠷దԽ͕ࠔ೉Ͱ͋ Δ͜ͱ͕஌ΒΕ͍ͯ·͢ɻͨͱ͑͹ N + 1 ໰୊ͳͲ͸ɺSQL ͱͯ͠ JOIN ۟Λ௚઀ॻ͘͜ͱ͕Ͱ ͖Ε͹ (΄ͱΜͲͷέʔεͰ) ղܾ͠·͢ɻࠓճ͸Ϋϥ΢υ΁σϓϩΠ͢Δʹ͋ͨΓɺ՝ۚྉۚΛέ 20
  23. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    νΓ͍ͨͨΊʹɺInterface ಺ͰΑΓ௿ϨΠϠͳ࣮૷Λߦ͏ͱ͍͏ํ਑ΛऔΓ·ͨ͠ɻ ରͯ͠ɺϓϩδΣΫτن໛͕େ͖͘ͳΔ͜ͱ͕༧ଌͰ͖ɺۚમతͳϦιʔε͕े෼ʹ֬อͰ͖Δ৔ ߹Ͱ͸ɺ Interface ಺෦Ͱੜʹ͍ۙ SQL จΛൃߦ͢Δ͜ͱ͸ɺอकੑ΍֦ுੑͷ໘͔Β͓קΊͰ͖ ·ͤΜɻ ৼΓฦΓ: खଓ͖తϓϩηε͔ɺΞϯν෭࡞༻͔ ຊ࣮૷ʹ͋ͨΓɺ (ઌྫ͕গͳ͔ͬͨͷͰ) Golangɺ C#ɺ Java ͱ͍ͬͨ Clean Architecture ͷ ࣮૷ྫΛൺֱ࣮ͭͭ͠૷Λߦ͍·ͨ͠ɻ ͨͱ͑͹ɺGolang Ͱ Usecase Λ࣮૷͢Δͱɺ࣍ͷΑ͏ͳܗʹͳΓ·͢ɻ Ϧετ 2.5: usecase/remittance.go 1: type RemittanceInputPort interface { 2: Execute(context.Context, *model.Remittance) error 3: } 4: 5: type RemittanceInteractor struct { 6: UserRepository repository.UserRepository 7: AccountRepository repository.AccountRepository 8: } 9: 10: func NewRemittanceUsecase( 11: userRepository repository.User, 12: accountRepository repository.Account, 13: ) RemittanceInputPort { 14: return &RemittanceInteractor{ 15: UserRepository: usersRepository, 16: AccountRepository: accountRepository, 17: } 18: } 19: 20: func (i *RemittanceInteractor) Execute( 21: ctx context.Context, remittance *model.Remittance) error { 22: 23: // Ϣʔβʔ͕ਖ਼͍͔͠νΣοΫ͢Δ 24: sender, err := i.UserRepository.FindActiveUserByUserID(ctx, remittance.sender) 25: if err != nil { 26: return err 27: } 28: receiver, err := i.UserRepository.FindActiveUserByUserID( 29: ctx, remittance.receiver) 30: if err != nil { 31: return err 32: } 33: // ޱ࠲͕༗ޮͰ͋Δ͔νΣοΫ͢Δ 34: if _, err := i.AccountRepository.FindAccountByUser(ctx, sender); err != nil { 35: return err 36: } 37: 38: if _, err := i.AccountRepository.FindAccountByUser(ctx, receiver); err != nil { 21
  24. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    39: return err 40: } 41: 42: // sender ͱ receiver ͷ༬ۚΛ΍ΓऔΓ͢Δ 43: err = i.AccountRepository.Transaction(ctx, func(ctx context.Context) error { 44: if err := i.AccountRepository.UpdateDeposit( 45: ctx, sender, receiver, -1*remittance.amount); err != nil { 46: return err 47: } 48: if err := i.AccountRepository.UpdateDeposit( 49: ctx, receiver, sender, remitance.amount); err != nil { 50: return err 51: } 52: return nil 53: }) 54: if err != nil { 55: return err 56: } 57: return nil 58: } ಛʹ Golang ͷΑ͏ͳखଓ͖తͳهड़Λಘҙͱ͢ΔݴޠΛ༻͍ͯهड़͢Δ৔߹ɺ্هͷΑ͏ʹ Usecase ಺ʹ Transaction Λॻ͍ͯ͠·ͬͯ΋ϓϩάϥϜͷྲྀΕ͸͖Ε͍ʹݟΔ͜ͱ͕Ͱ͖·͢ɻ ·ͨɺ్தͰ return จΛॻ͘͜ͱ͕Ͱ͖ΔͨΊɺ৑௕ͳ if ෼ذ͕ෆཁͱͳΓɺωετͷઙ͍ίʔ υ͕ॻ͚·͢ɻ ͦ΋ͦ΋എܠͱͯ͠ɺMVC ΞʔΩςΫνϟΛ༻͍ͯϓϩάϥϜΛॻ͍͖ٕͯͨज़ऀ͔Β͢Ε͹ɺ Usecase ಺Ͱ O/RM Λհͯ͠ deposit.save *8 ͳͲͱॻ͘͜ͱ͕೔ৗ஡൧ࣄͱݴͬͯ΋͔·Θͳ ͍Ͱ͠ΐ͏ɻ ରͯ͠ Clojure Λ͸͡Ίͱ͢Δؔ਺ܕݴޠ͸ɺϏδωεϩδοΫͱͯ͠෭࡞༻ͷ͋ΔػೳΛߟ͑ͨ ͘ͳ͍ɺͱ͍͏ಛ௃Λ͍࣋ͬͯ·͢ɻͨͱ͑͹ Common Lisp ͷೖ໳ॻͰ͋Δ Land of Lisp *9 Ͱ ͸ɺ෭࡞༻ͷ͋Δཁૉͱ෭࡞༻ͷͳ͍ཁૉΛؔ਺୯ҐͰ໌֬ʹ෼཭͠ɺ෭࡞༻ͷ͋Δ෦෼Λੵۃతʹ ഉআ͢Δ࢟੎Λ؏͍͍ͯ·͢ɻ·ͨॻ੶ʮςετۦಈ։ൃʯ *10 ʹ͓͍ͯ΋ɺίʔυͷՄಡੑ޲্ͷ ͨΊɺϩδοΫͷؔ਺ʹ͍ͭͯɺ෭࡞༻ͷ͋Δؔ਺͔Β෭࡞༻ͷͳ͍ؔ਺΁ͷϦϑΝΫλϦϯάΛק Ί͍ͯ·͢ɻ *11 Ҏ্ΑΓɺͦΕͧΕͷ։ൃऀͷഎܠʹΑͬͯɺϏδωεϩδοΫ΍෭࡞༻΁ͷཧղɺղऍ͕ҟͳͬ ͍ͯΔՄೳੑ͕͋Δͱݴ͑·͢ɻ ͭ·Γ෭࡞༻ʹ͍ͭͯߟ͑Δͱ͖ɺClean Architecture ͷϕʔεΞΠσΞͰ͋Δɺ ґଘੑͷϧʔ *8 Ruby on Rails ͸ಛʹ O/RM Λੵۃతʹ׆༻ͨ͠ີ݁߹ͳϓϩάϥϜΛॻ͘͜ͱ͕Ͱ͖·͢ɻ *9 Conrad Barski, M.D.(ஶ), ઒ ߹ ࢙ ࿕ (༁) "Land Of Lisp". O’Reily 2013, ISBN-13:978-4873115870, https://www.oreilly.co.jp/books/9784873115870/ *10 Kent Beck(ஶ), ࿨ ా ୎ ਓ (༁) "ς ε τ ۦ ಈ ։ ൃ". Φ ʔ Ϝ ࣾ 2017, ISBN-13:978-4274217883, https://shop.ohmsha.co.jp/shopdetail/000000004967/ *11 ຊߘΛॻ͍ͨਓ͸ɺςετίʔυΛॻͨ͘ΊʹϓϩδΣΫτΛڲਖ਼͢Δඞཁ͕͋Δͱ·Ͱ͸ݴ͍·ͤΜɻ 22
  25. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    ϧΛकΔ͜ͱ͕ग़དྷͳ͍Θ͚Ͱ͢ *12ɻ ࣄҊ 2 : (Local) Docker-composed αʔϏε ͔Β Google Cloud Platform ͳ αʔϏε΁ ঢ়گ ؆қతͳը૾౤ߘػೳΛ࣋ͭαʔϏεΛߟ͑·͢ɻ ࠓ·Ͱ docker-compose Λ༻͍ͯ App αʔόɺSQL αʔόɺLocal File Storage Λ؅ཧ͠ɺγϯ άϧϚγϯ্Ͱಈ͘ API αʔόΛཱ͍ͯͯ·ͨ͠ɻ ͜ΕΛɺҎԼͷΑ͏ʹҠߦ͍ͨ͠ͱߟ͑·͢ɻ • App αʔό ˠ Google Cloud Run • SQL αʔό ˠ Cloud SQL • Local File Storage ˠ Cloud Storage App αʔόΛॻ͍ͨਓ͸ Clean Architecture ΛษڧதͰɺը૾ʹ͍ͭͯ࣍ͷΑ͏ͳ Domain Λ ઃܭ͠·ͨ͠ɻ Ϧετ 2.6: domain/topic.go 1: (s/def ::title string?) 2: (s/def ::caption string?) 3: ;; ! ը૾͸ java.io.File ͷΠϯελϯεͰ͋Δ 4: (s/def ::image #(instance? java.io.File %)) 5: 6: (s/def ::image-creation-payload (s/keys :req-un [::title ::caption ::image])) ͜ͷͱ͖ɺCloud ΁Ҡߦ͢Δࡍʹൃੜ͠͏Δ໰୊Λߟ͑ͯΈ͍ͯͩ͘͞ɻ݁࿦͔Βݴ͏ͱɺίϝϯ τʹॻ͔Ε͍ͯΔΑ͏ʹɺ ::image ͷ࢓༷͕໰୊ʹͳΓ·͢ɻ *12 ͡Ό͋ͲͪΒ͕ਖ਼ٛͳͷ͔ɺͳͲͱՐʹ༉Λ஫͙Α͏ͳਅࣅ͸ɺࠓճ͸ѻ͍·ͤΜɻ೩͑ͨ͘ͳ͍ͷͰ 23
  26. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    ਤ 2.3: ࠓ·ͰͷΞʔΩςΫνϟ ਤ 2.4: ҠߦઌͷΞʔΩςΫνϟ 24
  27. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷ͸ͣͳͷʹ

    Infrastructure ґଘͳ Domain લఏ஌ࣝͱͯ͠ɺ java.io.File ͸ύε໊Λද͢ URL ͕ඞཁͰ͢ɻͦͷͨΊɺϩʔΧϧϑΝΠϧ ετϨʔδ΍ɺϚ΢ϯτͨ͠ετϨʔδͳͲɺύε໊Λ֫ಘͰ͖ΔϑΝΠϧʹ͍ͭͯར༻Ͱ͖·͢ɻ ͱ͜ΖͰɺGoogle Cloud Storage ͷ Java API Ͱ͸ɺ Cloud Storage ্ͷϑΝΠϧΛऔಘ͢Δ ͱɺ java.io.InputStream ͷΦϒδΣΫτΛฦ͠·͢ɻ java.io.InputStream ͷΦϒδΣΫτ͸ɺ java.io.File ΁Ҡ͢͜ͱ΋Ͱ͖·͕͢ɺͦ͏͢Δ ͨΊʹ͸Ұ౓ϩʔΧϧ΁ॻ͖ग़͞ͳ͚Ε͹ͳΒͣɺख͕͔͔ؒΓ·͢͠ɺ࡟আλΠϛϯάͳͲͷ੍ޚ ͕೉͘͠ͳΓ·͢ɻ ·ͨɺ HTTP Response ͱͯ͠ը૾ϑΝΠϧΛు͖ग़͢ Interface Ͱ͸ɺϑΝΠϧΛ java.io.I nputStream ΦϒδΣΫτͱͯ͠ѻ͍ͬͯ·͢ɻ Αͬͯ͜ͷࣄҊͰ͸ɺ Domain ͷ ::image ͷ࢓༷Λɺ (s/def ::image #(instance? java. io.InputStream %) ͱͨ͠΄͏͕ద੾Ͱ͋Δͱݴ͑·͢ɻ ਤ 2.5: ࠓ·ͰͷϑΝΠϧͷѻ͍ ਤ 2.6: ҠߦઌͷϑΝΠϧͷѻ͍ ৼΓฦΓ: ෭࡞༻ͱςετɺͦͯ͠ ଥڠత Clean Architecture ͯ͞ɺ͜͜··Ͱ Infrastructure ʹΑͬͯ Domain Λมߋ͢Δͱ͍͏ Clean Architecture ʹ͋ Δ·͖͡ઃܭมߋ͖ͯ͠·ͨ͠ɻ ͔͠͠ɺຊࣄҊͰ͸ɺҠߦʹࡍͯ͠ Usecase ͸มߋΛ໔Εɺςετͷมߋ΋ܰඍͰࡁΈ·ͨ͠ɻ͜ Ε͸ɺ Usecase ʹ ෭࡞༻Λؚ·ͤͳ͍ͱ͍͏ɺ Lisp ͷओٛʹैͬͨͨΊͰ͢ɻ΋͠ Usecase ಺෦ Ͱ java.io.File ͱ java.io.InputStream ͷΩϟετΛߦ͍ͬͯͨ৔߹ɺ Usecase ͷςετΛ େ෯ʹॻ͖௚͢ඞཁ͕͋ͬͨͰ͠ΐ͏ɻ͜ͷΑ͏ʹϏδωεϩδοΫ͔Β෭࡞༻Λഉআ͢Δ͜ͱͰɺ ςετΛͦͷ··ʹৄࡉͳ࣮૷Λमਖ਼Ͱ͖·͢ɻ 25
  28. ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷ૊Έ߹Θͤ 2.4 ͓ΘΓʹ

    ࿩Λ໭ͯ͠ɺࠓճ͸ετϨʔδͷબ୒ࢶΛ Local File Storage ͱ Cloud Storage ʹߜΔ͜ͱͰɺ ࣮૷ͷํ਑ΛఆΊ·ͨ͠ɻͪ͜Β΋ɺ Clean Architecture ͷ ґଘੑͷϧʔϧΛकΔ͜ͱ͕Ͱ͖͍ͯ ·ͤΜɻ ࣮༻্ɺཧ૝తͳίʔυ͸ඞͣॻ͚ΔΘ͚Ͱ͸ͳ͍ͷͰɺͲ͏ͯ͠΋͜ͷΑ͏ͳଥڠΛߦ͏ඞཁ͕ ͋Γ·͢ɻ͜͜Ͱେࣄͳͷ͸ɺଥڠͨ͠ͱ͖ͷӨڹൣғͷ༧ଌΛ͢Δ͜ͱͰ͢ɻͨͱ͑͹ࠓճͷέʔ εͰ͸ɺઌʹ Cloud Storage ͷϑΝΠϧ΍ΓͱΓΛษڧͰ͖͍ͯΕ͹ɺઌʹ Domain ͷ࣮૷Λݟ௚ ͢͜ͱ͕Ͱ͖·ͨ͠ɻ ຊࣄҊ͔Βɺ࠷ॳʹ׬ᘳͳ࣮૷ΛٻΊΔΑΓ΋ɺॊೈͳมߋ͕Ͱ͖ΔΑ͏ͳ࣮૷Λߦ͍ɺϦϑΝΫ λϦϯάΛ͢Δश׳Λ͚ͭΔ΂͖ͩͱݴ͑ΔͰ͠ΐ͏ɻ 2.4 ͓ΘΓʹ ͜͜·Ͱɺ Clean ArchitectureɺClean CodeɺCloud Native Λ೦಄ʹ ( Clojure Ͱ ) ϓϩδΣΫ τΛॻ͍ͯΈͨΒ͜ΜͳࣄҊ͕͋Γɺ͜Μͳ஌ݟ͕ಘΒΕ·ͨ͠ΑɺΛ঺հ͍͖ͤͯͨͩ͞·ͨ͠ɻ લ൒ͷ஌ࣝ෦෼͸ࠓޙ΋Έͳ͞Μ͕͓෇͖߹͍͍ͯ͘͜͠ͱͱ͸ࢥ͍·͕͢ɺ͓ͦΒ͘ Clojure Λ ݟΔ͜ͱ͸ۚྠࡍͳ͍Ͱ͠ΐ͏ɻͰ͸ͳΜͰΘ͟Θ͟ Clojure Λબ୒͔ͨ͠ͱ͍͏ͱɺଟ֯తʹαʔ Ϗε։ൃͷߟ͑ํΛٵऩ͢Δ͜ͱͰɺࣗ෼ͷؔΘ͍ͬͯΔϓϩδΣΫτΛ࠶ߟ͢ΔҰॿʹͳΔ͔΋͠ Εͳ͍ɺͱߟ͑ͨͨΊͰ͢ɻ ͨͱ͑͹ Clean Architecture ͸ɺݴޠ΍ϑϨʔϜϫʔΫΛ֎෦ཁҼͱͯ͠ϏδωεϩδοΫͷ֎ ଆʹͱΒ͍͑ͯ·͢ɻಛఆͷݴޠ΍ϑϨʔϜϫʔΫ্Ͱ։ൃख๏ΛࡲΔͷ΋ྑ͍Ͱ͕͢ɺଟݴޠͷ࣮ ૷΍ߟ͑ํͱൺֱ͢Δ͜ͱͰɺ࣮͸ඞཁͳ͔ͬͨґଘؔ܎΍ར༻͍ͯ͠ΔπʔϧͷڧΈ͕ݟ͑ͯ͘Δ ͔΋͠Ε·ͤΜɻ ͜ͷػձʹɺͦΕͧΕͷϓϩδΣΫτ͕ؔΘ͍ͬͯΔϓϩδΣΫτΛߴ͍ࢹ఺͔ΒݟͭΊ௚ͯ͠Έ ͯ͸͍͔͕Ͱ͠ΐ͏͔ɻ 2.5 ͋ͱ͕͖: ͦͷίʔυɺΫϦʔϯͳඞཁ͕͋Γ·͔͢ʁ ஫ҙ: ຊষ͸׬શʹ༨ஊͰ͢ɻ ࠓ·Ͱ Clean Architecture ΍ Clean Codeɺ Cloud Native ͳͲͷ៉ྷࣄΛ঺հ͖ͯ͠·͕ͨ͠ɺ ͜ΕΒ͸͋͘·Ͱ ៉ྷʹॻ͚ΔݟࠐΈͷ͋ΔϓϩδΣΫτ ʹͷΈద༻͕ՄೳͰ͢ɻͨͱ͑͹ɺػց ֶशͰ GPU ΛϞϦϞϦ࢖͏Α͏ͳίʔυʹ Clean Architecture ΍ Cloud Native Λڧ੍͢Δඞཁ ͸͋Γ·ͤΜ (API ͱͯ͠៉ྷʹ੔͑Δͷ͸ͦͷ֎ଆʹҕ೚͢Δ΂͖Ͱ͢) ɻ ·ͨαʔόϦιʔεΛ͢΂ͯ WebSocket ΍ HLS ʹ࢖͍͍ͨϓϩδΣΫτʹςετ༰қੑͱ͍ͬ ͯ෭࡞༻Λল͍ۭͨؒܭࢉྔ͕͋Γ͑ΜͰ͔͍ίʔυΛॻ͘΂͖Ͱ͸͋Γ·ͤΜɻ നՏͰਫ༡ͼ͢Δ͜ͱͱɺటপʹనΕΔ͜ͱ͸ɺͲͪΒ΋ϓϩμΫτ։ൃͰ͸ඞཁʹͳͬͯ͘Δ͜ ͱͩͱࢥΘΕ·͢ͷͰɺαʔϏεͷ੾Γ෼͚Λͯͦ͠ΕͧΕʹద੾ͳ։ൃํ਑Λద༻͍ͯ͘͠ඞཁ͕ ͋ΔͰ͠ΐ͏ɻ 26
  29. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷ ઃܭߟ࡯ Web Components ͱ͸ɺJavaScript

    ΍ HTML Ͱ৽͘͠ΧελϜλάΛఆٛ͠࠶ར༻Մೳͳ UI ίϯϙʔωϯτΛߏஙͰ͖ΔΑ͏ʹ͢Δ API ܈ͷ૯শͰ͢ɻWeb ͷඪ४ API ͷΈΛ࢖ͬͯ UI ίϯϙʔωϯτΛߏஙͰ͖ΔͷͰ͕͢ɺϞμϯϒϥ΢βͷରԠঢ়گ͕௕Β͘੔ΘͣɺPolyfill Λ ࢖༻͢Δඞཁ͕͋Γ·ͨ͠ɻ͔͠͠ɺEdge ͷϨϯμϦϯάΤϯδϯ͕ chromium ϕʔεʹͳΓɺ InternetExplorer ͕ഇࢭ͞ΕΔ͜ͱ͕Ξφ΢ϯε͞ΕͨͷͰɺ͍Α͍Αຊ֨తʹ࢖͏͜ͱ͕Ͱ͖ΔΑ ͏ʹͳ͖ͬͯ·ͨ͠ɻຊষͰ͸ɺWeb Components Λ࢖͏͜ͱʹΑΔϝϦοτ΍ɺWeb ΞϓϦΛߏ ங͢Δࡍͷઃܭʹ͍ͭͯͷߟ࡯Λ঺հ͠·͢ɻ 3.1 Web Components ͷجૅ Web Components ͸̏ͭͷ Web ඪ४ API ʹΑ࣮ͬͯݱ͞Ε͍ͯ·͢ɻ ʢ΋ͱ΋ͱ͸̐ͭʣ custom elements ಠࣗͷ HTML λάΛ࡞੒Ͱ͖Δ΋ͷɻ shadow dom shadow dom tree ͱ͍͏ಠࣗͷ DOM πϦʔΛੜ੒͠ɺ಺෦ߏ଄ΛӅณͰ͖·͢ɻEle- ment.attachShadow() ϝιουΛ࢖ͬͯΧελϜཁૉʹ shadow dom Λඥ෇͚Δ͜ͱ͕Ͱ͖ ·͢ɻ HTML templates <template>λάͱ<slot>λάʹΑͬͯߏ੒͞Ε͓ͯΓɺ<template>͸ϚʔΫΞοϓߏ଄Λςϯ ϓϨʔτԽΛՄೳʹ͠ɺ<slot>͸೚ҙͷࢠཁૉΛૠೖ͢Δ৔ॴΛએݴͰ͖Δ໾ׂΛ୲͍ͬͯ·͢ɻ 27
  30. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.1 Web Components ͷجૅ

    HTML imports Ϟδϡʔϧͱͯ͠ html ΛಈతʹΠϯϙʔτͰ͖Δػೳɻ͔͠͠ɺωοτϫʔΫύϑΥʔϚϯεత ͳ໰୊͔Βɺݱࡏ͸ഇࢭ͞Ε͍ͯ·͢ɻ Web Components ͕΋ͨΒ͢ϝϦοτͱैདྷͷ Web ϑϩϯτ։ൃͷҧ͍ Web ΞϓϦͳͲΛߏங͢Δࡍʹ࢖ΘΕΔ UI ϥΠϒϥϦ͸ React ΍ Vue ͳͲ͕Α͘࢖ΘΕΔ͔ ͱࢥ͍·͢ɻWeb Components Ͱ΋͜ΕΒͷίϯϙʔωϯτࢦ޲ͷ UI ϥΠϒϥϦͱಉ༷ʹϥΠϑ αΠΫϧ͕ଘࡏ͠ɺUI ΍ͦΕʹ෇ਵ͢ΔॲཧΛίϯϙʔωϯτͱͯ͠ڞ௨ԽͰ͖·͢ɻ·ͨɺWeb Components ͸جຊతʹ Web ͷඪ४ API ͷΈΛ࢖ͬͯߏங͞ΕΔͷͰɺUI ͸ Web Components Ͱ࡞ΓɺReact ΍ Vue Ͱ࡞ΒΕͨϓϩδΣΫτʹ૊ΈࠐΉΑ͏ͳϋΠϒϦοτͳ։ൃ΋ՄೳͰ͢ɻ UI Λ Web Components Ͱ࡞ΔϝϦοτͱͯ͠͸ɺ࠶ར༻ੑͱελΠϧ؅ཧͷ҆શੑ͕ڍ͛ΒΕ ·͢ɻ࠶ར༻ੑʹ͍ͭͯ͸ɺWeb Components ͸ར༻ʹτϥϯεύΠϧ͕ඞཁͳ UI ϥΠϒϥϦ ͳͲʹґଘ͠ͳ͍ͷͰɺWeb ͷτϨϯυͷҠΓมΘΓʹࠨӈ͞Εͣӡ༻͠ଓ͚Δ͜ͱ͕Ͱ͖· ͢ɻCSS ʹΑΔελΠϦϯάʹ͍ͭͯ΋ɺࠓ·Ͱ class ໊ͷॏෳΛආ͚ΔͨΊʹ CSS Modules ΍ styled-components ͳͲͷ CSS in JS ͱ͍ٕͬͨज़ʹΑͬͯϋογϡ஋ΛׂΓ౰ͯͨΓͯ͠Ϣχʔ Ϋͳ஋Λอূ͢ΔΑ͏ʹ͍ͯ͠·ͨ͠ɻWeb Components ʹؚ·ΕΔ shadow dom ͱ͍͏ٕज़ʹ Αͬͯ Web Components ಺ͷ class ໊͸άϩʔόϧͳ஋Ͱ͸ͳ͘ɺϩʔΧϧʹ؅ཧ͞ΕΔ΋ͷʹͳ Γ·͢ɻͭ·ΓɺWeb Components Ͱ͋Ε͹ UI ίϯϙʔωϯτ΍ class ໊ͷ໊લۭؒ؅ཧͷͨΊʹ ϥΠϒϥϦΛ࢖Θͳͯ͘΋Α͘ͳΔՄೳੑ͕͋Γ·͢ɻ͜ΕʹΑͬͯɺϏϧυαΠζΛ཈͑ͯΦʔ όʔϔουΛ͞Βʹখ͘͞Ͱ͖·͢ɻ Ͱ͸ɺ࣮ࡍʹ Web Components ͱ͸ͲͷΑ͏ʹ࣮૷͢Δͷ͔Λݟ͍͖ͯ·͢ɻ Ϧετ 3.1: CounterButton.ts 1: class CounterButton extends HTMLElement { 2: count = 0; 3: 4: static get observedAttributes() { 5: return ["label"] 6: } 7: 8: constructor() { 9: super(); 10: 11: const shadow = this.attachShadow({mode: "open"}); 12: 13: const button = document.createElement("button"); 14: button.textContent = ‘ 15: ${this.getAttribute("label")}: ${this.count} 16: ‘; 17: 28
  31. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.1 Web Components ͷجૅ

    18: const style = document.createElement("style"); 19: style.textContent = ‘ 20: button { 21: color: red; 22: } 23: ‘; 24: 25: shadow.appendChild(button); 26: shadow.appendChild(style); 27: 28: console.log("ॳظԽ͞Ε·ͨ͠ɻ") 29: } 30: 31: onCount() { 32: this.count++; 33: this.updateButton(this); 34: new CustomEvent("oncount", this.count); 35: } 36: 37: updateButton(element) { 38: const shadow = element.shadowRoot; 39: shadow.querySelector("button").textContent = ‘ 40: ${element.getAttribute("label")}: ${this.count}} 41: ‘; 42: } 43: 44: connectedCallback() { 45: console.log("counter-button element ͕Ϛ΢ϯτ͠·ͨ͠ɻ") 46: } 47: 48: disconnectedCallback() { 49: console.log("counter-button element ͕ΞϯϚ΢ϯτ͠·ͨ͠ɻ") 50: } 51: 52: adoptedCallback() { 53: console.log("counter-button element ͕ผϖʔδʹҠಈ͠·ͨ͠ɻ") 54: } 55: 56: attributeChangedCallback(name, oldValue, newValue) { 57: console.log(‘${name}ଐੑ͕${newValue}ʹมߋ͞Ε·ͨ͠ɻ‘) 58: 59: if (name === "label") { 60: const shadow = element.shadowRoot; 61: shadow.querySelector("button").textContent = ‘ 62: ${element.getAttribute("label")}: ${this.count}} 63: ‘; 64: } 65: } 66: } 67: 68: customElements.define("counter-button", CounterButton); 29
  32. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.1 Web Components ͷجૅ

    Web Components Ͱ͸͜ͷΑ͏ʹ Class ܕͷίϯϙʔωϯτΛఆٛ͠·͢ɻHTMLElement Λܧ ঝ͢Δ͜ͱͰɺίϯϙʔωϯτ಺ͰϥΠϑαΠΫϧʹΞΫηεͰ͖·͢ɻίϯϙʔωϯτΛఆٛ͠ ͨΒ customElements.define ϝιουΛ࢖͏͜ͱͰ৽͘͠ΧελϜλάΛάϩʔόϧʹొ࿥Ͱ͖ ·͢ɻ Ϧετ 3.2: counter.html 1: <html lang="ja"> 2: <head> 3: <script type="module" src="path/to/CounterButton.js" /> 4: </head> 5: <body> 6: <counter-button label="ΫϦοΫ਺"></counter-button> 7: </body> 8: </html> άϩʔόϧʹొ࿥ͨ͠ΧελϜλά͸ HTML ಺Ͱఆٛͨ͠ίϯϙʔωϯτΛؚΉ JS ϑΝΠϧΛ import ͯ͠ඪ४ͷλάͱಉ͡Α͏ʹ࢖༻Ͱ͖·͢ɻ ϥΠϑαΠΫϧ ίϯϙʔωϯτ಺ͰΞΫηεͰ͖ΔϥΠϑαΠΫϧʹ͍ͭͯ঺հ͠·͢ɻ connectedCallback • ίϯϙʔωϯτ͕Ϛ΢ϯτͨ࣌͠ʹݺͼग़͞ΕΔϝιου • eventListener Λൃߦ͢Δ࣌ͳͲʹ࢖͏ disconnectedCallback • ίϯϙʔωϯτ͕ΞϯϚ΢ϯτ͞Εͨ࣌ʹݺͼग़͞ΕΔϝιου • removeEventListener Λൃߦ͢Δ࣌ͳͲʹ࢖͏ adoptedCallback • ίϯϙʔωϯτ͕ผͷϖʔδʹҠಈͨ࣌͠ʹݺͼग़͞ΕΔϝιου attributeChangedCallback • html ଐੑͷೖྗ஋͕ߋ৽͞Εͨ࣌ʹݺͼग़͞ΕΔϝιου • static get observedAttributes ʹొ࿥ͨ͠ଐੑͷΈ͕มߋݕ஌͞ΕΔɻ • ϝιουͷҾ਺͔Β͸ɺଐੑ໊ʗ̍ͭલͷଐੑ஋ʗ৽͍͠ଐੑ஋ΛऔಘͰ͖Δɻ 30
  33. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.1 Web Components ͷجૅ

    ΞΫηγϏϦςΟ ΧελϜλά͸ͦͷ··ϨϯμϦϯά͞ΕΔͷͰจॻߏ଄ͷ੔߹ੑ่͕Εͯ͠·͏͜ͱ͕͋Γ· ͢ɻͨͱ͑͹Ϧετ 3.3 ͷΑ͏ͳϦετߏ଄ͩͬͨ৔߹ ul λάͱ li λάͷؒʹ custom-list λά͕ ೖͬͯ͠·͍ͬͯΔͷͰηϚϯςΟΫεతʹ໰୊͕͋Γ·͢ɻ Ϧετ 3.3: index.html 1: <body> 2: <ul> 3: <custom-list> 4: <li>item1</li> 5: </custom-list> 6: <custom-list> 7: <li>item2</li> 8: </custom-list> 9: </ul> 10: </body> ͜ͷ৔߹ role ଐੑΛઃఆ͢Δ͜ͱͰղܾͰ͖·͢ɻ Ϧετ 3.4: index.html 1: <body> 2: <div role="list"> 3: <custom-list> 4: <div role="listitem">item1</div> 5: </custom-list> 6: </div> 7: <custom-list> 8: <div role="listitem">item2</div> 9: </custom-list> 10: </div> 11: </body> ·ͨɺผͷํ๏ͱͯ͠ΧελϜλάࣗମʹ΋ΞΫηγϏϦςΟͷ৘ใΛ෇༩Ͱ͖Δ Accessibility Object ModelʢAOMʣͱ͍͏࢓༷ͷࡦఆ͕ݱࡏਐΜͰ͍·͢ɻAOM ͸ JavaScript Ͱऔಘͨ͠ Element ʹରͯ͠खଓ͖తʹ role ଐੑͳͲͷΞΫηγϏϦςΟ৘ใΛઃఆͰ͖Δ΋ͷͰ͢ɻ࢒೦ͳ ͕Β·ͩࡦఆதͰ࣮ࡍʹ࢖༻͢Δ͜ͱ͸Ͱ͖·ͤΜ͕ɺ͍͔ͭϞμϯϒϥ΢βͰීٴ͢ΔͱΑ͍ͳͱ ࢥ͍·͢ɻ 31
  34. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.2 એݴత UI ͱࠩ෼ϨϯμϦϯά

    shadow dom ͷߏ଄ shadow dom ʹ͸ shadow dom tree ͱ͍͏ dom ͷ tree ߏ଄͕ಠࣗʹ࡞ΒΕ͓ͯΓɺߏ଄ͷͦΕ ͧΕͷ෦෼ʹ໊લ͕͋Γ·͢ɻ shadow tree shadow dom ͷதʹ͋Δ DOM πϦʔ shadow host shadow dom ͕௥Ճ͞Εͨɺ௨ৗͷ DOM ϊʔυ shadow boundary shadow dom ͱ௨ৗͷ DOM ͷڥք shadow root shadow tree ͷࠜϊʔυ shadowRoot mode Φϓγϣϯ shadowRoot ͸ίϯϙʔωϯτͷ֎ଆ͔ΒΞΫηεͰ͖ΔΑ͏ʹ͢Δ͔Ͳ͏͔ΛࢦఆͰ͖Δػ ೳ͕͋Γ·͢ɻshadowRoot ͷ mode ΦϓγϣϯͰ open ͔ close Λࢦఆ͢Δ͜ͱͰ੾Γସ͑ Δ͜ͱ͕Ͱ͖·͢ɻ ಺෦ CSS :host shadow dom ಺ͷ CSS Ͱ͸:host ٖࣅΫϥεΛ࢖༻Ͱ͖·͢ɻ͜ΕʹΑͬͯ shadow host ͷ ελΠϧΛࢦఆͰ͖·͢ɻ data ଐੑ shadow dom ಺ͷελΠϧ͸جຊతʹάϩʔόϧͷελΠϧ͕ద༻͞Ε·ͤΜɻίϯϙʔω ϯτ֎͔ΒελΠϧͷࢦఆΛ͍ͨ࣌͠ʹ͸ɺCSS ΧελϜϓϩύςΟΛ࢖͏͜ͱʹΑͬͯ஋ ͷड͚౉͠ΛͰ͖·͢ɻ 3.2 એݴత UI ͱࠩ෼ϨϯμϦϯά Web Components ͷ UI Λखଓ͖తʹॻ͘ͷ͸ɺπϦʔߏ଄͕ෳࡶʹͳ͍ͬͯ͘ͱͱ΋ʹͱͯ΋ ݟͮΒ͘ͳΔݒ೦͕͋Γ·͢ɻ·ͨɺShadow dom ಺ͷ HTML ͷߋ৽ʹ͸ɺͬͦ͝Γ͢΂ͯΛ࠶Ϩ ϯμϦϯά͢ΔͷͰෆඞཁʹඳըίετ͕͔͔Γ·͢ɻReact ΍ Vue ͷΑ͏ʹએݴతʹॻ͚ͯɺ࠷ খݶͷ࠶ϨϯμϦϯάͰࡁΉΑ͏ͳࠩ෼ݕ஌ॲཧ͕ඞཁʹͳΓ·͢ɻͦ͜ͰɺWeb Components ͷ ߏஙΛิॿ͢Δπʔϧ΍ϥΠϒϥϦΛ࢖͍͖ͬͯ·͢ɻ୅දతͳ Web Components ઐ༻ͷ։ൃπʔ ϧ͸̎ͭ͋Γ·͢ɻ 32
  35. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.2 એݴత UI ͱࠩ෼ϨϯμϦϯά

    Stencil Stencil ͸ ionic νʔϜ͕։ൃ͍ͯ͠Δ Web Components ͷΧελϜཁૉ΍ Web ΞϓϦΛੜ੒ Ͱ͖ΔίϯύΠϥͰ͢ɻίϯϙʔωϯτΛ JSX ه๏Λ࢖ͬͯߏஙͰ͖ɺԾ૝ DOM Ͱࠩ෼ݕ஌Λ ߦ͍·͢ɻϧʔλ΍ϓϦϨϯμϦϯάͷػߏ΋༻ҙ͞Ε͓ͯΓɺSPA Λߏங͢Δ͜ͱ΋Ͱ͖·͢ɻ Stencil ίϯύΠϥΛ௨ͯ͠τϥϯεύΠϧ͢Δ͜ͱͰ७ਮͳ JavaScript ͷ Web Component Λੜ ੒Ͱ͖·͢ɻ Lit Lit ͸ςϯϓϨʔτλάΛ࢖ͬͯએݴత UI ͰߏஙͰ͖ΔΑ͏ʹ͢ΔϥΠϒϥϦͰ͢ɻGoogle ͕ࠓ ·Ͱ Polymer ͱ͍͏໊લͰ։ൃ͍ͯ͠·͕ͨ͠ɺ໊લ͕มΘΓ Lit ʹͳΓ·ͨ͠ɻࠩ෼ݕ஌ʹԾ૝ DOM Λ࢖Θͣʹɺࠩ෼͕ൃੜͨ͠ DOM ͷΈΛߋ৽͢ΔͷͰԾ૝ DOM ΑΓ΋ߴ଎ͩͱݴΘΕͯ ͍·͢ɻLit ͷύοέʔδʹؚ·ΕΔ lit-html ͸ React ʹൺ΂ͯ࠷௿Ͱ΋ 8%~10% ߴ଎ͩͱ͍͏ϕ ϯνϚʔΫςετͷ݁Ռ͕ग़͍ͯ·͢ɻJavaScript ͷඪ४ API ͷΈΛ࢖༻ͯ͠ߏங͢ΔͷͰɺτϥ ϯεύΠϧ΋ෆཁͰͦͷ··΄͔ͷϑϨʔϜϫʔΫ΍ϥΠϒϥϦͷதͰ΋࢖༻Ͱ͖·͢ɻ·ͨɺύο έʔδͷαΠζ΋ͱͯ΋খ͘͞ɺReact ͱ React DOM Λ࢖༻͢ΔͱϏϧυαΠζ͕ 50KB Λ௒͑ Δͷʹରͯ͠ɺLit ͸ϏϧυαΠζ͕ 5KB ఔ౓ͰࡁΈ·͢ɻ͜͜Ͱ͸ɺࠩ෼ݕ஌͕Ծ૝ DOM ΑΓ ΋ߴ଎ɺτϥϯεύΠϧෆཁͱ͍͏ϝϦοτ͔Β Lit Λ࠾༻ͯ͠Έ·͢ɻLit ͰίϯϙʔωϯτΛ࡞ ΔͱϦετ 3.5 ͷΑ͏ʹͳΓ·͢ɻ Ϧετ 3.5: CounterButton.ts 1: import { LitElement, css, html } from "lit"; 2: import { customElement, property, state } from "lit/decorators.js"; 3: 4: @customElement("counter-button") 5: export class CounterButton extends LitElement { 6: static styles = css‘ 7: button { 8: color: red; 9: } 10: ‘; 11: 12: constructor() { 13: super(); 14: console.log("ॳظԽ͞Ε·ͨ͠ɻ") 15: } 16: 17: connectedCallback() { 18: console.log("counter-button element ͕Ϛ΢ϯτ͠·ͨ͠ɻ") 19: } 20: 21: disconnectedCallback() { 22: console.log("counter-button element ͕ΞϯϚ΢ϯτ͠·ͨ͠ɻ") 33
  36. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.2 એݴత UI ͱࠩ෼ϨϯμϦϯά

    23: } 24: 25: adoptedCallback() { 26: console.log("counter-button element ͕ผϖʔδʹҠಈ͠·ͨ͠ɻ") 27: } 28: 29: @property() 30: label?: string; 31: 32: @state() 33: count = 0; 34: 35: onCount() { 36: this.count++; 37: const countEvent = new CustomEvent("oncount", { detail: this.count }); 38: this.dispatchEvent(countEvent); 39: } 40: 41: render() { 42: return html‘ 43: <button @click="${() => this.onCount()}"> 44: ${this.label}: ${this.count} 45: </button> 46: ‘; 47: } 48: } Lit ͸ɺσίϨʔλʔΛ࢖͏͜ͱͰɺૉͷ Web Componets ΑΓ΋͖ͬ͢Γॻ͘͜ͱ͕Ͱ͖·͢ɻ html ςϯϓϨʔτΛ࢖༻ͯ͠ HTML ΍ CSS Λهड़͠ɺproperty ΛຒΊࠐΉͱΧελϜίϯϙʔω ϯτΛϚ΢ϯτ͢Δͱ͖ʹɺ֘౰Օॴʹϋογϡ id ΛؚΜͩίϝϯτ͕ҰॹʹϨϯμϦϯά͞Ε· ͢ɻproperty ͱϋογϡ id ͕ඥ͍ͮͯ؅ཧ͞Ε͍ͯͯɺ͜ͷϋογϡ id Λ໨ҹʹɺproperty ͷ஋ ͕มߋ͞Εͨͱ͖ʹ࠶ϨϯμϦϯά͢Δ৔ॴΛ࠷খݶʹ཈͑Δ͜ͱ͕Ͱ͖·͢ɻ σΟϨΫςΟϒ σΟϨΫςΟϒͱ͸ɺදࣔͨ͠σʔλʹՃ޻͢ΔॲཧΛ੾Γग़͢͜ͱ͕Ͱ͖ΔػೳͰ͢ɻΑ͘࢖Θ ΕΔΑ͏ͳ൚༻తͳσΟϨΫςΟϒ͕͋Β͔͡Ί͍͔ͭ͘༻ҙ͞Ε͍ͯ·͢ɻ·ͨɺΧελϜσΟϨ ΫςΟϒͱͯ͠ಠࣗʹσΟϨΫςΟϒΛఆٛ͢Δ͜ͱ΋Ͱ͖·͢ɻ • classMap – class Λಈతʹద༻Ͱ͖ΔσΟϨΫςΟϒ • repeat – map ͳͲͰϨϯμϦϯάͨ͠഑ྻͷཁૉ͕ߋ৽͞Εͨͱ͖ʹɺޮ཰తʹ࠶ϨϯμʔΛ͢ ΔσΟϨΫςΟϒ • Ωϟογϡ 34
  37. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.3 ։ൃ؀ڥߏங – ৚݅ϨϯμϦϯά͢ΔίϯϙʔωϯτΛΩϟογϡ͢Δ͜ͱͰɺ࠶Ϛ΢ϯτ͢Δͱ͖ʹඳ

    ըίετΛ཈͑ΔσΟϨΫςΟϒ • guard – ೚ҙͷ property ͕ߋ৽͞ΕΔ·Ͱ࠶Ϩϯμʔ͠ͳ͍Α͏ʹ͢ΔσΟϨΫςΟϒɻ • ref – ೚ҙͷ DOM ͷࢀরΛऔಘ͢ΔσΟϨΫςΟϒɻϦετ 3.9 ͷ࣮૷Ͱ΋࢖༻͠·͢ɻ • until – ඇಉظॲཧ͕׬ྃ͢Δ·Ͱͱ׬ྃ࣌ʹίϯϙʔωϯτΛग़͠෼͚ΒΕΔσΟϨΫςΟϒɻ React Ͱݴ͏ Suspense ͷΑ͏ͳ΋ͷɻ ίϯτϩʔϥ ίϯτϩʔϥͱ͸ϥΠϑαΠΫϧ΁ͷΞΫηε͕ඞཁͳϏδωεϩδοΫΛ੾Γग़͢͜ͱ͕Ͱ͖Δ Lit ͷػೳͰ͢ɻReact ΍ Vue Ͱݴ͏ΧελϜ hook ͷΑ͏ͳ΋ͷͰ͢ɻ 3.3 ։ൃ؀ڥߏங Lit Ͱ SPA ͷઃܭΛߟ͑ͯΈ·͢ɻ։ൃ؀ڥʹ Web Components ༻ʹ͸ҎԼͷπʔϧΛಋೖ͠ ·͢ɻ • lit-plugin – vscode ༻ͷ Lit ͷίʔυิ׬ϓϥάΠϯ • eslint-plugin-lit – eslint Ͱ Lit ͷߏจΛνΣοΫ͢ΔϓϥάΠϯ • prettier – ίʔυ੔ܗπʔϧ • ts-lit-plugin – TypeScript Ͱ Lit ͷܕิ׬Λαϙʔτͤ͞ΔϓϥάΠϯ • vite – ES Modules Λ࢖༻͢Δ͜ͱͰɺߴ଎ʹಈ͘։ൃ༻ HMR αʔόΛఏڙͯ͘͠ΕͨΓɺϓ ϩδΣΫτͷϏϧυΛͯ͘͠ΕΔπʔϧ – npm init @vitejs/app ͰϓϩδΣΫτͷϕʔεΛੜ੒Ͱ͖Δɻ άϩʔόϧঢ়ଶ؅ཧ άϩʔόϧঢ়ଶ؅ཧͷϥΠϒϥϦͱͯ͠༗໊ͳ Redux Λಋೖͯ͠Έ·͢ɻRedux ͷॲཧΛൺֱత ୯७ʹॻ͚ΔΑ͏ʹͳΔ redux-tool-kit Λ࢖ͬͯ store Λ࡞੒͠·͢ɻ 35
  38. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.3 ։ൃ؀ڥߏங Ϧετ 3.6:

    store.ts 1: import { configureStore } from "@reduxjs/toolkit"; 2: import { todoSlice } from "./modules/todoSlice"; 3: 4: export const store = configureStore({ 5: reducer: { 6: todo: todoSlice.reducer, 7: }, 8: }); 9: 10: export type RootState = ReturnType<typeof store.getState>; 11: 12: export type AppDispatch = typeof store.dispatch; ίϯϙʔωϯτ ͔Β store ͷݺͼग़͠ store Λ࡞੒ͨ͠Βɺstore ͷ஋Λݺͼग़͢ίϯτϩʔϥΛ࡞੒͠·͢ɻ Ϧετ 3.7: StoreSelector.ts 1: import { ReactiveController, ReactiveControllerHost } from "lit"; 2: import { store, RootState } from "../store"; 3: 4: export class StoreSelector<TSelector = unknown> implements ReactiveController { 5: private store: TSelector; 6: private unsubscriber: ReturnType<typeof store.subscribe>; 7: 8: constructor( 9: _host: ReactiveControllerHost, 10: selector: (state: RootState) => TSelector 11: ) { 12: this.store = selector(store.getState()); 13: this.unsubscriber = store.subscribe( 14: () => (this.store = selector(store.getState())) 15: ); 16: } 17: 18: public hostDisconnected() { 19: this.unsubscriber(); 20: } 21: 22: get state() { 23: return this.store; 24: } 25: } constructor ͰඞཁͳσʔλΛऔΓग़͠ɺstore ͷมߋݕ஌Λ։࢝͠·͢ɻhostDisconnected ϝ 36
  39. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.3 ։ൃ؀ڥߏங ιουͰίϯϙʔωϯτ͕ΞϯϚ΢ϯτͨ͠ͱ͖ʹ store

    ͷมߋݕ஌Λఀࢭ͠·͢ɻ·ͨɺTSelector ͷΑ͏ͳδΣωϦΫεΛ࢖͏͜ͱͰ໭Γ஋ͷܕิ׬͕ޮ͘Α͏ʹ͠·͢ɻ Ϧετ 3.8: AppRoot.ts 1: import { LitElement, css, html } from "lit"; 2: import { customElement, state } from "lit/decorators.js"; 3: import { StoreSelector } from "./utils/StoreSelector"; 4: 5: @customElement("app-root") 6: export class App extends LitElement { 7: @state() 8: private todoSelector = new StoreSelector(this, (state) => state.todo); 9: 10: public render() { 11: return html‘ 12: <div> 13: ${JSON.stringify(this.todoSelector.state.todo)} 14: </div> 15: ‘; 16: } 17: } Ϧετ 3.8 ͷΑ͏ʹ StoreSelector ίϯτϩʔϥͰ store ͷ஋Λݺͼग़͠·͢ɻ ϖʔδϧʔςΟϯά SPA Λ࡞Δ্ͰඞཁͳΫϥΠΞϯτͷϖʔδϧʔςΟϯάॲཧΛ࣮૷͠·͢ɻϧʔλʹ͸ɺWeb Components ϑϨϯυϦʔʹઃܭ͞Ε͍ͯΔ@vaadin/router ͱ͍͏ϧʔςΟϯάͷϥΠϒϥϦΛ࢖ ͍·͢ɻ Ϧετ 3.9: AppRoot.ts 1: import { LitElement, html } from "lit"; 2: import { ref, createRef, Ref } from "lit/directives/ref.js"; 3: import { customElement } from "lit/decorators.js"; 4: import { Router } from "@vaadin/router"; 5: 6: @customElement("app-root") 7: export class App extends LitElement { 8: private routerRef: Ref<HTMLDivElement> = createRef(); 9: 10: public firstUpdated() { 11: const router = new Router(this.routerRef.value); 12: router.setRoutes([ 13: { 14: path: "/", 15: action: async () => { 37
  40. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.3 ։ൃ؀ڥߏங 16: await

    import("./pages/index"); 17: }, 18: component: "page-top", 19: }, 20: { 21: path: "/detail", 22: action: async () => { 23: await import("./pages/todoDetail"); 24: }, 25: component: "ToDo-detail", 26: }, 27: ]); 28: } 29: 30: public render() { 31: return html‘ 32: <div ${ref(this.routerRef)}></div> 33: ‘; 34: } 35: } Lit ͷ ref σΟϨΫςΟϒͰ SPA ͷ root ͱͳΔ Element ͷ ref Λऔಘͯ͠ɺfirstUpdated ϝ ιουͰϧʔςΟϯάͷఆٛΛ͠·͢ɻϖʔδίϯϙʔωϯτ͸μΠφϛοΫΠϯϙʔτͯ͠ code splitting ͢Δ͜ͱ΋Ͱ͖·͢ɻfirstUpdated ϝιου͸࠷ॳʹ updated ϝιουΛݺ͹Εͨޙʹݺ ͹ΕΔ Lit ಠࣗͷϥΠϑαΠΫϧͰ͢ɻ Ϧετ 3.10: PageTop.ts 1: import { LitElement, css, html } from "lit"; 2: import { customElement } from "lit/decorators.js"; 3: 4: @customElement("page-top") 5: export class PageTop extends LitElement { 6: static styles = css‘ 7: :host { 8: color: red; 9: } 10: 11: p { 12: margin: 0; 13: } 14: ‘; 15: 16: render() { 17: return html‘ 18: <h1>this is top page</h1> 19: <a href="./detail">to detail</a> 20: ‘; 21: } 38
  41. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.3 ։ൃ؀ڥߏங 22: }

    ϖʔδͷϦϯΫ͸ΞϯΧʔλάʹύεΛࢦఆͯ͠ɺϦϯΫΛΫϦοΫ͢Ε͹ɺ֘౰ͷϖʔδίϯ ϙʔωϯτʹΫϥΠΞϯτଆͰϧʔςΟϯά͞Ε·͢ɻ Storybook ࡞੒ͨ͠ίϯϙʔωϯτΛ Storybook ʹొ࿥ͯ͠ΧλϩάԽͯ͠Έ·͢ɻ Ϧετ 3.11: DemoComponent.story.ts 1: import { html } from "lit"; 2: import "./demo-component"; 3: 4: export default { 5: title: "Components/DemoComponent", 6: }; 7: 8: export const Default = () => html‘<demo-component></demo-component>‘; Storybook ͸ඪ४Ͱ Web Components ʹରԠ͍ͯ͠ΔͷͰɺ ಛʹ Storybook ʹ Web Components ༻ͷϓϥάΠϯΛೖΕͣʹίϯϙʔωϯτΛొ࿥Ͱ͖·͢ɻϦετ 3.11 ͷΑ͏ʹ lit-html Λ࢖͏͜ ͱͰΧλϩάʹొ࿥͠·͢ɻ ίϯϙʔωϯτͷςετ ࡞ͬͨίϯϙʔωϯτͷςετίʔυΛॻ͍ͯΈ·͢ɻWeb-test-runnner Λ࢖͏͜ͱͰɺLit Ͱ ߏஙͨ͠ίϯϙʔωϯτΛԼهʹΑ͏ʹςετͰ͖·͢ɻ Ϧετ 3.12: DemoComponent.test.ts 1: import { DemoComponent } from "../demo-component"; 2: import { fixture, html } from "@open-wc/testing"; 3: 4: const assert = chai.assert; 5: 6: suite("demo-component", () => { 7: test("ίϯϙʔωϯτͷॳظԽ", () => { 8: const el = document.createElement("demo-component"); 9: assert.instanceOf(el, DemoComponent); 10: }); 11: 12: test("ίϯϙʔωϯτͷϨϯμϦϯά", async () => { 39
  42. ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ࡯ 3.4 ࠷ޙʹ 13: const

    el = await fixture(html‘<demo-component></demo-component>‘); 14: assert.shadowDom.equal( 15: el, 16: ‘ 17: <h1>͜Ε͸ DemoComponent Ͱ͢ɻ</h1> 18: ‘ 19: ); 20: }); 21: }); Lit ͸ϒϥ΢βͰಈ͔͢Α͏ʹઃܭ͞Ε͍ͯΔͷͰɺϨϯμϦϯάΤϯδϯΛؚΜͩςετϥΠϒ ϥϦΛ࢖͏͜ͱͰςετ͠΍͘͢ͳΓ·͢ɻ meta ͱ OGP Web αΠτͷ meta ৘ใͱ OGP Λઃఆ͍͖ͯ͠·͢ɻϖʔδ͝ͱͷಈతͳ head ͷ಺༰ͷߋ৽ ͸ɺpwa-helper ͱ͍͏ύοέʔδͷதͷ metadata util Λ࢖͍·͢ɻ͔͠͠ɺTwitter ΍ Facebook ͳͲͰڞ༗͞Εͨͱ͖ʹ OGP Λ JavaScript ͔Βಈతʹઃఆͯ͠΋൓ө͞Εͳ͍ͷͰɺΫϩʔϥ͔ ΒͷΞΫηεͷΈ Prerender.io ͳͲͷࣄલϨϯμϦϯάαʔϏεʹϦμΠϨΫτͯ͠ meta data ৘ ใΛಡΈऔΕΔΑ͏ʹ͠·͢ɻ ଞͷࣄલϨϯμϦϯάͷํ๏ͱͯ͠͸ SSG ͳͲ͕͋Γ·͕͢ɺݱࡏ Lit Ͱ͸ Web Component ͷ SSR ͷରԠΛਐΊ͍ͯΔͱ͜ΖͰ͋ΓɺखܰʹಋೖͰ͖ΔϑΣʔζͰ͸͋Γ·ͤΜɻshadow dom ͷ SSR ʹ͸ template λάʹ shadowroot ϑϥάΛ෇͚Δએݴܕ shadow dom ͱ͍͏࢓༷ʹϒϥ΢ β͕ରԠ͍ͯ͠Δඞཁ͕͋Γ·͢ɻ͔͠͠ɺݱࡏ͸·ͩ Chrome ͱ Edge ͷΈͰ͔͠αϙʔτ͞Εͯ ͍ͳ͍ͷͰɺSafari ͳͲͰ͸ Polyfill Λ࢖༻͢Δඞཁ͕͋Γ·͢ɻ΋͠։ൃཁ݅ͱͯ͠ SSRɺSSG ͕ϚετͰؚ·Ε͍ͯΔͷͰ͋Ε͹ɺStencil ͕ඪ४Ͱ SSG ϏϧυʹରԠ͍ͯ͠ΔͷͰͪ͜ΒΛ࢖͏ ͜ͱΛ͓קΊ͠·͢ɻ 3.4 ࠷ޙʹ Web Components ͸ React ΍ Vue ͷΑ͏ͳ UI ϥΠϒϥϦΛഉআͯ͠औͬͯ୅ΘΔΑ͏ͳ΋ͷͰ ͸ͳ͍ͱߟ͍͑ͯ·͢ɻWeb Components ͕࣋ͭ࠶ར༻ੑͱґଘ͢Δ΋ͷ͕ۃΊͯগͳ͍ಛ௃͸ɺ ࠓ·ͰੵΈ্͛ΒΕ͖ͯͨϥΠϒϥϦͷࢿ࢈Λ׆༻͠ɺΑΓॊೈͳ։ൃΛՄೳʹ͢Δٕज़Ͱ͢ɻٕज़ τϨϯυ͕ҠΓมΘͬͯ΋࣋ଓతʹӡ༻Ͱ͖ɺϝϯςφϯείετΛ࠷খݶʹ཈͑Δ͜ͱ͕Ͱ͖ΔՄ ೳੑ͕͋Δ͜ͱ͔ΒɺWeb ։ൃऀΛΑΓ޾ͤʹͯ͘͠ΕΔૉఢͳٕज़ͩͱࢥ͍·͢ɻͨ͘͞Μͷ։ ൃऀ͕ Web Components Λಋೖ͠มԽʹڧ͍ Web ʹͳ͍ͬͯ͘ͱΑ͍ͳͱࢥ͍·͢ɻ 40
  43. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS ʙDOTS ʗ NetCode ͰΞϓϦઃܭϓϩτλΠϐϯάʙ

    ͓͠ͳॻ͖ 1. Unity DOTS ࣗࣾݕূࣄྫ 2. Unity DOTS / NetCode ͰϚϧνϓϨΠήʔϜ։ൃ~ ͦΖͦΖ DOTS Ͱ։ൃͯ͠Α͍ͷ͔ 3. DOTS ͱ͸ 4. Ͳͷ͘Β͍ྑ͘ͳΔͷ͔ 5. Ͱ͖Δ͜ͱ/Ͱ͖ͳ͍͜ͱ~ طଘϓϩμΫτΛ DOTS ʹҠߦͰ͖Δͷ͔/ MonoBehaviour ͸ աڈͷҨ෺ͳͷ͔ 6. मಘ೉қ౓͸ߴ͍ͷ͔ 7. Ͳ͔͜ΒखΛ͚ͭΕ͹ྑ͍ͷ͔ 8. Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔~ ECS σʔλͷ࡞Γํͱ஫ҙ఺ 9. ࠷ޙʹ 41
  44. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS ಡΜͰ΄͍͠ਓ • Unity ͰήʔϜΛ࡞͍͖͍ͬͯͨํ

    • DOTS ͱ͍͏ςΫϊϩδ͕͋Δ͜ͱΛ·ͩΑ͘஌Βͳ͍ํ • ΫϥΠΞϯταΠυ͔͠΍͍ͬͯͳ͍ํ ຊষͰΘ͔Δ͜ͱ • Unity DOTS ςΫϊϩδ͕ͲͷΑ͏ʹ͓΋͠Ζ͍͔ • ήʔϜΤϯδχΞͱͯ͠ DOTS ςΫϊϩδʹͲͷ͘Β͍ظ଴Ͱ͖Δ͔ • ΫϥΠΞϯτΤϯδχΞ͕αʔόαΠυ΋Ұ؏ͯ͠ήʔϜ։ൃͰ͖׆༂ͷ෯͕޿͕Δ͞· • DOTS ͷ࢖͍ํ΍࢖͍উखɺ্खʹ෇͖߹͏ίπ ʙͦΕͰ͸ॱΛ௥͓ͬͯ࿩͍͖ͯ͠·͠ΐ͏ɻ ͝஫ҙࣄ߲ • ຊষ͸ 2021 ೥ 6 ݄࣌఺Ͱ Unity Technologies ࣾͷఏڙ͢Δٕज़΍৘ใʹج͍ͮͯͦΕΛ࢖ ༻͠ݕূͨ͠ॴײ౳Λड़΂ͨ΋ͷͰ͢ɻ • ຊॻͷग़൛ޙʹಉࣾͷఏڙ಺༰΍ݟղͷมߋ·ͨ͸۩ମతʹͳΔ͜ͱʹΑΓɺهड़ͱࠩҟ͕ੜ ͣΔڪΕ͕͋Γ·͕͋͢Β͔͡Ίྃ͝ঝ͍ͩ͘͞ɻ ˙චऀͷ࠷ۙͷ׆ಈ࣮੷ • ϓϩδΣΫτ – ήʔϜιϑτʗΞϓϦ։ൃӡӦ (~2019) – ΦϦδφϧϓϩάϥϛϯάֶशιϑτ։ൃ (2019) – [KidsVALLEY] ौ୩۠ެཱதֶߍतۀࢧԉ (2019~) *1 – [mixi اۀ๚໰] ΤϯδχΞ৬ߨ࠲ߨࢣ (2019~) *2 ʙਵ࣌ड͚෇͚தʙ – [mixi νϟϨϯδΠϕϯτ] Unity Engine Challenge by mixi GROUP (2019~) *3 – Unity DOTS ݕূήʔϜΞϓϦ։ൃ (2021) • ϝσΟΞ / ࿐ग़ – ϝσΟΞ֤ࢴʹͯ ϓϩάϥϛϯάतۀࢧԉऔࡐଟ਺ – KidsVALLEY ϓϩάϥϛϯάαϚʔΩϟϯϓ (2019~) 2021 ೥*4 | Ϩϙʔτ*5 – ϛΫγΟίʔϙϨʔταΠτ ESG ϖʔδɹ (׆ಈϨϙʔτ, ࣍ੈ୅ҭ੒) *6 *1 தֶߍतۀࢧԉ ʛ https://mixi.co.jp/esg/2021/0604/4036/ *2 mixi اۀ๚໰ ʛ https://mixi.co.jp/esg/social/nextgen/ *3 Unity Engine Challenge by mixi GROUP ʛ https://mixil.mixi.co.jp/people/6788 *4 αϚʔΩϟϯϓ 2021 ʛ https://coeteco.jp/kidsvalley_2021 *5 αϚʔΩϟϯϓ 2020 ϨϏϡʔ ʛ https://mixil.mixi.co.jp/report/8974 *6 ϛΫγΟίʔϙϨʔταΠτ ESG ϖʔδ ʛ https://mixi.co.jp/esg/ 42
  45. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.1 Unity DOTS ࣗࣾݕূࣄྫ

    ਤ: ˞ܝࡌαΠτ QR ίʔυ 4.1 Unity DOTS ࣗࣾݕূࣄྫ ࠷େ 64 ਓಉ࣌ࢀՃՄೳͳϦΞϧλΠϜΞΫγϣϯ෺ཧήʔϜΛςετ։ൃ ޙड़͢Δ DOTS ςΫϊϩδݕূϓϩδΣΫτͱ্ཱͯͪ͛ͨ͠ R&D νʔϜʹΑͬͯɺDOTS ͷ ྑ͞΍࢖͍উखΛݕূ͢Δ΂͘ɺ1 ຊͷήʔϜΛΞ΢τήʔϜΠϯήʔϜࠐΈͰ։ൃ͠·ͨ͠ɻචऀ ͸ Unity ྺɺήʔϜΤϯδχΞྺ΋͋Δఔ౓͋Δ͜ͱ͔Βɺ͞·͟·ͳࢹ఺ͰΞϓϦέʔγϣϯ։ൃ ʹඞཁͳ DOTS ͷ࢟Λे෼ʹ࣮ײݕূͰ͖·ͨ͠ɻ ιϑτ΢ΣΞ֓ཁ • ։ൃ Unity version : 2021.1.3f1 macOS • ओͳ package – "com.unity.netcode": "0.6.0-preview.7" – "com.unity.physics": "0.6.0-preview.3" – "com.unity.render-pipelines.universal": "11.0.0" – "com.unity.rendering.hybrid": "0.11.0-preview.42" • platform: macOS (ͱΓ͍ͦ͗) 43
  46. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.2 Unity DOTS /

    NetCode ͰϚϧνϓϨΠήʔϜ։ൃ • ήʔϜઆ໌: ෺ཧγϛϡϨʔγϣϯԼʹ͋Δۭؒʹ͍ΔϓϨΠϠʔୡ͸͋Β͔͡Ί 2 νʔϜʹ ෼͔Εɺग़ݱ͢ΔΦϑδΣΫτΛ੍ݶ࣌ؒ಺ʹ૬खͷΰʔϧʹ౤͛ೖΕɺଟ͘ೖΕͨνʔϜ͕ উͪͱͳΓ·͢ɻ • ϓϨΠਓ਺: 2~64 ਓʢΞϓϦέʔγϣϯ 1 ͭʹ͖ͭ 1 ਓ·Ͱʣ • ήʔϜδϟϯϧ: ϚϧνϓϨΠϦΞϧλΠϜΞΫγϣϯ෺ཧήʔϜ • ඳը fps: 30fps / 60fps • ௨৴ rate: 30fps ૬౰ • ՄࢹಉظΦϒδΣΫτ: ͓Αͦ 500 ݅ʢϓϨΠϠʔؚΉʣ ΦϯϥΠϯͰࣾ಺ϓϨϏϡʔΛ࣮ࢪ චऀͨͪνʔϜ͕ॴଐ͍ͯ͠ΔϛΫγΟ։ൃຊ෦ʹ͸ಥ೗࣮ࢪΛ఻͑ɺσϞήʔϜͷϓϨΠձʹΦ ϯϥΠϯͰू·ͬͯ͘Εͨ 20 ਓऑͷϝϯόʔʹ͜ͷήʔϜόΠφϦΛ഑෍͠ɺҰ੪ʹϓϨΠΛͯ͠ ࣮ূςετମݧձΛߦ͍·ͨ͠ɻ͜͏͍ͬͨϓϩτλΠϓʹ੍࡞աఔஈ֊Ͱ৮ΕΒΕΔͷ͸ɺίϯς ϯπ੍࡞ձࣾͳΒͰ͸ͷ୉ޣຯͰ΋͋Γ·͢ɻຊήʔϜʹ͸ϘΠενϟοτ΋౥ࡌ͞Ε͍ͯΔ͜ͱ΋ ͋ΓɺςΩετνϟοτͱϘΠενϟοτΛۦ࢖ͯ͠ू߹͔Βղࢄ·ͰΦϯϥΠϯͷ··௨͠੾Δ͜ ͱ͕Ͱ͖·ͨ͠ɻϓϨΠձ಺༰ʹ͍ͭͯ͸τϥϒϧ΋ͳ্͘ʑɺͱ͍ͬͨͱ͜ΖͰ͢Ͷɻ ݚڀ։ൃνʔϜͨΜΆΆ G ։ൃͨ͠νʔϜ͸ʮϛΫγΟ։ൃຊ෦ CTO ࣨͨΜΆΆάϧʔϓʯͱ͍͏ϢχʔΫͳνʔϜͰ͢ɻ R&D ΍৽͍ٕ͠ज़Λݕূ։ൃࣾ͠಺ʹൃ৴͠ࢧԉ͢Δ෦ୂͰ͢ɻͥͻυΞΛୟ͍ͯΈͯ͸͍͔͕Ͱ ͠ΐ͏͔ɻ 4.2 Unity DOTS / NetCode ͰϚϧνϓϨΠήʔϜ։ൃ ϞόΠϧήʔϜ։ൃʹ Unity Ұڧ͸·͢·͢ਐΉ ಡऀͷΈͳ͞Μ͸ήʔϜ։ൃͰɺͱΓΘ͚ϞόΠϧήʔϜ։ൃʹ͓͍ͯͲΜͳ։ൃΤϯδϯʗϑ ϨʔϜϫʔΫͰ։ൃ͞Ε͍ͯ·͔͢ʁ ͍͔ͭ͘ͷબ୒ࢶͷதɺܝ୊ͷͱ͓Γ Unity ͸෯޿͍σϕ ϩούʔʹड͚ೖΕΒΕ΍͍͢؀ڥ΍ྉۚମ੍Ͱ͋Δ͜ͱ͔Βڧ͍ਓؾΛूΊɺಛʹϞόΠϧήʔϜ ʹ͓͚ΔγΣΞ͸ 50 ˋҎ্ɺVR/AR ίϯςϯπͰ΋ 60% Λ௒͍͑ͯΔͱͷ͜ͱɻ͜ͷ੎͍ΛݟΔ ʹࠓޙ΋·͢·͢ Unity ੡ίϯςϯπʹ੮ר͞Ε͍ͯ͘ʹҧ͍ͳ͍ͷͰ͠ΐ͏ɻ UnityEngine ͷϘτϧωοΫ Unity ͷചΓͷҰͭͰ͋Δखܰ͞Ώ͑ͱʹ͔͘ಈ͘΋ͷΛ࡞Δ͜ͱ͕ۃΊͯ༰қͰ͢ɻ͔͠͠൓ ໘ɺ಺༰ʹझ޲ΛڽΒ͠͞·͟·ͳΦϒδΣΫτΛѻ͏ʹͭΕϓϩδΣΫτ͸ංେ͠ࢢ৔ʹग़ճͬͯ ͍ΔΞϓϦͱಉ౳ͷ಺༰ʹͳ͍ͬͯ͘ʹैͬͯɺͦͷ࡞Γํ΍؅ཧɺ੍ޚํ๏ʹ͸େ͖ͳ஫ҙͱ஌ܙ ͕ٻΊΒΕΔΑ͏ʹ΋ͳΓ·͢ɻͦͷํ๏ΛݟޡΔͱͱͨΜʹ... 44
  47. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.2 Unity DOTS /

    NetCode ͰϚϧνϓϨΠήʔϜ։ൃ • ڍಈ͕ۃ୺ʹॏ͍ • ి஑ফඅ͕ܹ͍͠ • ൃ೤͕େ͖͍ • ಡΈࠐΈ͕௕͍ • μ΢ϯϩʔυίϯςϯπαΠζ͕େ͖͍ • ΞϓϦ͕མͪΔ ͱ͍ͬͨ͞·͟·ͳۤ೉ʹݟ෣ΘΕ͍͖ͯ·͢ɻͦͷཧ༝΍஫ҙ఺ʹ͍ͭͯ͸ੲ͔Β͞·͟·ͳ Hack ͕ग़ճ͍ͬͯͯΤϯδχΞͨͪ͸ڝ͏Α͏ʹߴ଎ԽܰྔԽςΫχοΫΛݟ͚ͭ൸࿐͍ͯ͠·͢ɻ ࠷దԽΛ͍ͯ͠ΔதͿ͔ͭΔนͱͯ࣍͠ͷΑ͏ͳͱ͜Ζͷ໰୊ʹͨͲΓண͖·͢ɻ • UnityEngine ͷϝΠϯεϨουϓϩηε • ComponentʢMonoBehaviourʣͷॲཧίετ ͜͏͍ͬͨͱ͜Ζ͸ͨͼͨͼ্͕ΔϘτϧωοΫͱͯ͠େ͖ͳཁҼΛ͠Ί͖ͯ·ͨ͠ɻͦΕΒڞ௨ ͍͔ͨͭ͘͠ͷࠜຊݪҼ͕ᖰΓग़͞Ε Unity Technologies ࣾͰ΋࣍ੈ୅ͷ Roadmap ͱͯ͠վम͢ Δ΂͖ର৅ͱͯ͠ڍ͍͛ͯ·ͨ͠ɻ ৽ͨʹఏএ͞Εͨ DOTS ͱ͍͏બ୒ࢶ Unity Technologies ࣾ͸ͦͷޙɺECS architectureʢΞʔΩςΫνϟʣͱͯ͠ Unit 2016 ʗ Unite 2017 ʗͦͯͦ͠ͷޙຖ೥ɺ΋ͬͱҎલʹ΋৘ใ͸͋Δ͔΋͠Ε·ͤΜ͕͓ೃછΈͷ UnityEngine ͷ GameObject ͱ Component Ͱ࡞ΒΕΔ Data ˍ BehaviourʢߦಈʣͷγεςϜͱ͸ผʹɺEntity ͱ Component ʹΑΔύϑΥʔϚϯεੑͷߴ͍ Data only ͳγεςϜΛఏڙ͢Δબ୒ࢶΛࣔ͠ɺ͞ Βʹซ༻Ͱ͖Δߴ଎Խٕज़Λ·ͱΊɺDOTSʢData - Oriented Technology Stack ʣͱͯ͠ఏ এ͠ɺࢲͨͪ։ൃऀୡΛڻ͔ͤظ଴ΛूΊ͖ͯ·ͨ͠ɻ͜ΕͰ͢΂ͯͷ೰Έ͕ফ͑ΔͷͰ͸ͳ͍͔ɺ ଴͍ͬͯͨͧͱɺߨԋΛ͖͍ͨ΄ͱΜͲͷΤϯδχΞͨͪ͸ࢥͬͨʹҧ͍͋Γ·ͤΜɻࢲ΋ͦͷҰਓ Ͱ͢ɻͩͨ།Ұɺ2021 ೥ݱࡏ͍·ͩ preview package Ͱ͋Δͱ͍͏͜ͱΛআ͍ͯɻ DOTS ͳΒ NetCode ͱ͍͏બ୒ࢶ λΠτϧʹ͋ΔΑ͏ʹɺDOTS ʹͯϚϧνϓϨΠͷήʔϜΛ࡞ΕΔΑ͏ఏڙ͞Ε͍͍ͯΔ package ʹʮNetCodeʯ͕͋Γ·͢ɻNetoCode Ͱ͸ ECSɺJob γεςϜɺBurst ίϯύΠϧͱɺDOTS ςΫ ϊϩδͷྑ͍ͱ͜ΖΛ࢖͏ϚϧνϓϨΠήʔϜʹඞཁͳ package ͕ఏڙ͞Ε·͢ɻ͜ΕΛ࢖͏͜ͱ ͰΫϥΠΞϯτʗαʔόͱ΋ʹ Unity ͷ DOTS ϓϩδΣΫτͰόΠφϦΛ࡞੒Ͱ͖ΔΑ͏ʹͳΔɺ ͱ͍͏͜ͱͰϦϦʔε͞ΕΕ͹ Unity ΤϯδχΞୡͷ஫໨ͷతͷඞਢεΩϧʹͳΔ͜ͱ͕ؒҧ͍ͳ ͍Ͱ͠ΐ͏ɻ 45
  48. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.3 DOTS ͱ͸ ͦΖͦΖ

    DOTS Ͱ։ൃͯ͠Α͍ͷ͔ 2021/7/1 ݱࡏɺECS ຊମ͸ɺEntities 0.17.0-preview.42 ͱͳ͓ͬͯΓɺ ʮpreviewʯͭ·Γ ༧ࠂ൛ͱͳ͍ͬͯ·͢ɻॾʑͷϦεΫΛঝ஌ͷ্Ͱ͋Ε͹࢖͑ΔΑ͏Ͱ͢ɻUnity όʔδϣϯʹΑͬ ͯ͸ରԠ͍ͯ͠ͳ͍Մೳੑ͕͋ΔͷͰ஫ҙͯ͠औΓ૊ΜͰ͍ͩ͘͞ɻ ϚϧνϓϨΠͷை໨͕ GameServer ϞσϧʹมΘΓग़͢ ·ͨࡢࠓͷ࣌୅ͷมԽʹ৐ͯ͡ɺϚϧνϓϨΠήʔϜͷ࣮ߦ؀ڥελΠϧͷཧ૝ܕ͕ҠΓมΘΓͭ ͭ͋ΔΑ͏Ͱ͢ɻ͜Ε·ͰɺϞόΠϧήʔϜ؀ڥͱͯ͠ಛʹओྲྀͰ͋ͬͨ Client-Server Ϟσϧͱ͍ ͏΋ͷͰߏ੒͞ΕΔ͜ͱ͕ଟ͘ɺϚϧνϓϨΠͰෳ਺ਓಉ࣌௨৴Ͱ༡΂ΔϥΠτήʔϜ΍λʔϯ੍ ήʔϜʹͨͼͨͼ༻͍ΒΕ͍ͯ·͢ɻߏ੒͸ɺ઀ଓ͍ͯ͠Δ୺຤ͷ͏ͪϗετ໾Λ 1 ୆ఆΊɺશ୺຤ ͸தܧαʔόΛܦ༝ͯ͠ϗετʹ৘ใΛू໿͠ɺϗετͰॲཧͨ݁͠ՌΛ·ͨதܧαʔόΛܦ༝ͯ͠ શ୺຤ʹ໭͢ͱ͍͏΋ͷͰ͢ɻ࠷େͷϝϦοτ͸αʔόෛ୲͕খ͘͞ࡁΉͱ͍͏͜ͱʹ͋Γ·͢ɻ· ͨαʔόαΠυͷήʔϜϩδοΫΛ։ൃ͢ΔίετΛ͔͚ͣʹ࣮ݱͰ͖Δ͜ͱʹັྗ͕͋Γ·͢ɻσ ϝϦοτ͸ϗετΫϥΠΞϯτʹ൑ఆ΍඼࣭ΛҕͶΔ͜ͱʹͳΓɺҰఆͷج४Λຬͨ͞ͳ͍͜ͱ΋ঢ় گʹΑͬͯ͸ൃੜ͍ͯ͠·ͨ͠ɻ·ͨ௨৴ԟ෮଎౓ʹᶃ୺຤ˠαʔόɺᶄαʔόˠϗετ୺຤ɺᶅϗ ετ୺຤ˠαʔόɺᶆαʔόˠ୺຤ɺͱܦ࿏͕ԕ͍ͨΊԠ౴଎౓͕ͦ͜·Ͱૣ͘͢Δ͜ͱ͕೉͍͠ͱ ͍͏͜ͱ͕ڍ͛ΒΕ·ͨ͠ɻͦΕ͔Βಉ࣌઀ଓͷ੍ݶ͕͋ΓɺҰൠతʹ͸ 8 ୺຤ಉ࣌઀ଓఔ౓·Ͱ͕ շదͳϓϨΠͷ໨҆Ͱ͋Δ͜ͱ͕ଟ͍Ͱ͠ΐ͏ɻ ผͷΞϓϩʔνͱͯ͠͸ɺGameServer ͷϞσϧ͕͋Γ·͢ɻલ్ͷ Client-Server Ͱڍ͕ͬͨ໰ ୊఺Λղফ͢Δૂ͍ͱͯ͠࠶஫໨͞Ε͍ͯ·͕͢ɺαʔόͰήʔϜͦͷ΋ͷΛಈ͔ͯ͠ɺ୺຤ଆͰ͸ ൑ఆॲཧΛ͠ͳ͍ͱ͍͏΋ͷʹͳΓ·͢ɻ͜ͷ৔߹ϝϦοτ͸ಈ࡞ͷ৴པੑ͕ߴ͍ͱ͍͏͜ͱɻ൑ఆ ͦͷ΋ͷ͕αʔό಺ͰߦΘΕΔͨΊਖ਼͘͠ߏங͍ͯ͠Ε͹νʔτ͕ىͤ͜ͳ͍ঢ়گʹͳΓ·͢ɻ·ͨ Ԡ౴଎౓ʹ΋ظ଴͕͋Γ·͢ɻલ్ͨ͠ܦ࿏ͷ൒෼ɺᶃ୺຤ˠαʔόɺᶆαʔόˠ୺຤ɺ͚ͩͰඞཁ ͳ݁Ռ͕ಘΒΕΔͷͰ͔͢Β౰વૢ࡞ੑ΍Ϩεϙϯε͕޲্͠·͢ɻ ൓໘ɺσϝϦοτ͸ͦͷӡ༻අ༻ʹ͋Γ·͢ɻC ΍ C++ ؀ڥ౳ͰࣗࣾΤϯδϯ։ൃ͍ͯ͠Δ৔߹ Λআ͖ɺαʔόͰήʔϜࣗମΛಈ͔͢͜ͱʹίετతͳݒ೦͕ͳ͍͜ͱ͸·ΕͰ͠ΐ͏ɻͦͷͨΊɺ Ͱ͖ΔݶΓܰྔͳαʔόαΠυήʔϜϩδοΫΛߏங͢Δํ๏͕ٻΊΒΕ͍ͯΔɺͱ͍͏ঢ়گ͕͋Γ ·͢ɻಉ࣌઀ଓͷ੍ݶ͸ Client-Server ϞσϧΑΓͳ͘ɺαʔόͷωοτϫʔΫରԠঢ়گ࣍ୈͰଟ͍ ΋ͷͰ͸ 64 ୺຤ಉ࣌઀ଓɺͱ͍͏΋ͷ΋ग़͖͍ͯͯΔΑ͏Ͱ͢ɻ 4.3 DOTS ͱ͸ DOTS ͷ Data-Oriented Technology Stack ͦ΋ͦ΋ιϑτ΢ΣΞքͰ ECS ͱ͍͏ 2000 ೥ॳ಄͜Ζ͔Βఏএ͞Ε͍ͯΔσʔλۦಈήʔϜ ։ൃͷ֓೦͕͋ΓɺUnity Technologies ͕ࣾಠࣗʹൃలԠ༻ͤͨ͞΋ͷʹͳ͍ͬͯ·͢ɻͦͷ΄͔ 46
  49. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.3 DOTS ͱ͸ Unity

    ͷ࣍ੈ୅ߏ੒ͱͳΔ DOTS ϥϯλΠϜύοέʔδ܊Ͱߏ੒͞Εɺ΄΅΄΅ґଘؔ܎ʹ Entit ies, Job, Burst ؚ͕·Ε͍ͯ·͢ɻ ʢґଘؔ܎ʹ͍ͭͯޙड़ʣDOTS ͱ Entities ͷৄ͍͘͠͠Έ ͸ຊՈαΠτʢ֤ϦϯΫ͸ຊষ-7ʣͷهड़͔Βֶश͍͖͍ͨͩͨͱࢥ͍·͢ɻ ˙DOTS ύοέʔδ ओͳߏ੒ package ͸࣍ͷ௨Γ • Entities (preview) • C# Job System • Burst ίϯύΠϥʔ • Unity Physics (preview) • Unity NetCode (preview) • DSPGraph (experimental) • Unity Animation (experimental) • DOTS ϥϯλΠϜ (preview) ͜ͷΑ͏ʹ΄ͱΜͲ͢΂ͯਖ਼نϦϦʔε͸͞Ε͍ͯ·ͤΜɻͨͩ෺ʹΑͬͯ࡞Εͳ͍Θ͚Ͱ΋ͳ͍ ͨΊɺ͏·࣮͘ݱͰ͖Ε͹௨ৗͷ UnityEngine Ͱ͸౸ୡͰ͖ͳ͍඼࣭ͷίϯςϯπΛ֞ؒݟΔ͜ͱ ͕Ͱ͖·͢ɻ ˙ओͳ package ܊ͱґଘؔ܎ 2021/6/29 ݱࡏɺPackageManager ൈਮ "com.unity.rendering.hybrid" dependency: Entities "com.unity.netcode" dependency: Custom NUnit Unity Transport Burst Entities "com.unity.physics" dependency: Burst Collections Entities Jobs Mathematics Test Framework Performance testing API IMGUI JSONSerialize "com.unity.platforms" dependency: Properties 47
  50. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.3 DOTS ͱ͸ Properties

    UI Scriptable Build Pipeline Serialization "com.unity.animation" dependency: Mathematics Entities Collections Jobs Burst Test Framework Data Flow Graph Graph Tools Foundation Performance testing API "com.unity.entities" dependency: Burst Properties Serialization Collections Mathematics Asset Bundle Performance testing API Mono Cecil Jobs Scriptable Build Pipeline Platforms "com.unity.burst" dependency: Mathematics ECS ECSʢEntity Component Systemʣͱ͸ίϯϙδγϣϯͷݪଇʹै͏ΞʔΩςΫνϟύλʔϯͷ ҰͭͰ͢ɻ2002 ೥ͷήʔϜͰ࢖༻͞Εಉ೥ͷ GDC ʹͯߨԋ͕ߦΘΕͨͱ͍͏ه࿥͕͋ͬͯɺͦͷ ख๏͸ҙ֎ͱྺ࢙͕͋Δ෺Ͱͨ͠ɻ͜ͷΞϓϩʔνͰ͸ɺσʔλࢦ޲ઃܭͷख๏ͷҰͭͰ͋ΓΦϒ δΣΫτͰ͋ΔΤϯςΟςΟͷৼΔ෣͍͸෇Ճ͢ΔίϯϙʔωϯτΛૢ࡞͢Δ͜ͱͰมߋ͠·͢ɻΦ ϒδΣΫτࢦ޲ʹ͓͍ͯத৺ͱͳΔܧঝؔ܎Λআڈ͠ɺཧղɾอकɾ֦ுͷ೉͠͞Λղফ͢Δ໨త͕ ͋Γ·͢ɻUnity ͕Ҏલ͔Β࠾༻͍ͯ͠Δίϯϙʔωϯτࢦ޲ͷ࣍ͷஈ֊ͱݴ͏ҙຯͰ͸ಉ͡ͱ͜Ζ ΛΈ͍ͯΔͱݴ͑ΔͰ͠ΐ͏ɻ 48
  51. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.3 DOTS ͱ͸ DOTS

    Ͱͷ ECS Ͱ΋ Entity , Component , System Λ࣮૷͠ Entity ʹ෇Ճ͞Εͨ Component σʔλ܈ʹΑͬͯۦಈ ͢ΔσʔλυϦϒϯʢۦಈʣͷΞʔΩςΫνϟ͕ ECS Ͱ͋ΓɺUnity ͷ DOTS ςΫϊϩδʹ͓͚ Δ Entities Ͱ΋ͦͷߟ͑ํ͸ಉ͡Ͱ͢ɻEntity ΦϒδΣΫτࣗମ͸ͨͩͷ Struct Ͱ͢ɻ͢΂ͯͷ ΋ͷ΍ࣄฑʹ 1 ͭͣͭ Entity Λ࡞Γ༩͑·͢ɻͨͱ͑͹஄ؙ 1 ͭɺഁย 1 ͭɺϝογϡϊʔυ֊ ૚ 1 ͭɺΦϒδΣΫτͲ͏͠ͷ࿈ܞϝοηʔδʹ 1 ͭɻͦ͜΁ IComponent Interface ͷ͍ͭͨ೚ ҙͷ Struct Λ࡞Γ෇༩͠ɺ࣌ʹ஋Λઃఆ͠·͢ɻSystem ͸ͦΕΛ ArchetypeʢΞʔΩλΠϓʣͱ ͍͏૊Έ߹Θͤผʹड͚෇͚ɺଘࡏͨ͠ Entity ʹରͯ͠ॱʹ͢΂ͯॲཧΛࢪ͍͖ͯ͠·͢ɻͭ·Γ ԿΛͲ͏ॲཧ͢Δ͔ͷ൑ผʹ Archetypeʢ·ͨ͸ Component ͷ૊Έ߹Θͤʣ͕༻͍ΒΕ·͢ɻͲͷ Component Λ෇͚͍ͯΔ͔͕ϑϥάͰ͋Γɺ໨ҹͰ͋ΓɺύϥϝʔλͰ΋͋Δͱ͍͏ͷͰ͢ɻ ECS ͷைྲྀ͸Ͳ͜΁޲͔͏ͷ͔ʔ Shader ݴޠ API ͷ࠾༻͔Β֞ؒݟΔʔ ECS ؀ڥԼʹҠߦ͢Δ͜ͱͰΞʔΩςΫνϟҎ֎ʹ΋ܶతʹมΘΔ͜ͱ͕͍ͭ͘΋͋Γ·͢ɻ· ͣैདྷͷ UnityVector3 ΍ Quaternion ͸ར༻͞Ε·ͤΜɻMathf ؔ਺΋࢖༻͞Ε·ͤΜɻ৽ͨʹఏ ڙ͞ΕΔ਺ֶϥΠϒϥϦʹҠߦ͠ɺͦΕʹ൐͍ vector ΍ quaternion ͕ผ namespace Ͱ͔ͭҟ࣭ͷ ΋ͷʹஔ͖׵ΘΓ·͢ɻ਺ֶϥΠϒϥϦ Unity.Mathematics ؔ਺هड़͸ɺSIMD ͓ΑͼάϥϑΟο ΫʗγΣʔμʔͷ։ൃऀʹೃછΈͷ਺ֶ API ʹ͍ۙ΋ͷ͕औΓೖΕΒΕɺγΣʔμʔݴޠͰ͋Δ HLSL ʗ GLSL ͷ਺ֶϥΠϒϥϦͱҰ؏ੑ͕͋ΔελΠϧΛ࠾༻͍ͯ͠Δͱͷ͜ͱͰ͢ɻͦΕʹΑ ΓγΣʔμʔίʔυͱͷޓ׵ੑΛߴΊ 2 ͭͷίʔυؒͰҠ২ڞ༗͢Δࡍͷ఍߅ΛݮΒ͢ར఺Λ࣋ͨͤ ͍ͯΔͱ͍͏͜ͱͰ͢ɻ ʢhttps://github.com/Unity-Technologies/Unity.Mathematics/blob/master/readme.md ΑΓʣ DOTS ͸ Unity ͕ ECS ٕज़ΛϕʔεʹήʔϜΤϯδϯΛθϩ͔Β࡞Γସ͑Α͏ͱ ͍ͯ͠Δ DOTS ʹݶͬͨ͜ͱͰ͸ͳ͍Α͏Ͱ͕͢ɺ౰ॳΑΓ࢖ΘΕ͍ͯΔطଘٕज़ɺͨͱ͑͹ΤϑΣΫτ΍ ΦʔσΟΦɺUIɺ௨৴ͳͲ͸೔ʑͷਐาʹΑͬͯ͞Βʹ༗ޮͳςΫϊϩδͰஔ͖׵͑ΒΕ·͢ɻීஈ ͦΕ͸ϛυϧ΢ΣΞͱ͍͏ܗͩͬͨΓ AssetStore ͱ͍͏ܗͰ Unity Technologies ࣾҎ֎ͷ֤͔ࣾΒ ΋௥Ճ͞Ε͖ͯ·ͨ͠ɻͦ͜΁ࡢࠓ Unity Technologies ࣾࣗ਎΋େվֵΛଧͬͯग़͖͍ͯͯΔΘ͚ Ͱ͢ɻDOTS ʹݶͬͨ͜ͱͰݴ͑͹ Unity ͷΤϯδϯ͔Βม͑ͯ͠·͓͏ͱݴ͏Θ͚Ͱ͔͢Βͨͩ ͜ͱͰ͸͋Γ·ͤΜɻฒߦ্ͯ͠ྫͷΑ͏ͳϦιʔε΍πʔϧ΋ஔ͖׵Θ͍͖ͬͯɺ৽ςΫϊϩδͷ ্Ͱಈ͘Α͏ఏڙ͞Ε͍ͯ͘͜ͱʹͳΓ·͢ɻUnityEngine Ϣʔβʔ͸ৗʹ࠷৽ʹ௥ै͍͔ͯ͠ͳ ͚Ε͹͋ͬͱ͍͏ؒʹ৐Γ஗Εͯ͠·͏ͱݴ͏Θ͚Ͱ͢ɻͱΓΘ͚͜͜਺೥ͷ Unity Technologies ࣾͷ֦େϖʔε͸ѹ౗తʹૣ͘ɺ࣍ʑʹॏཁͳٕज़Λ࣋ͬͨاۀΛങऩ͠ Unity ެࣜ package Խ͠ ͍ͯΔ͜ͱ΋͋ΓɺՃ଎౓తʹਐԽ͍ͯ͠ΔͷͰ͢ɻ 49
  52. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.3 DOTS ͱ͸ DOTS

    ͷະདྷ͸ 2020 ൃදͷ Roadmap Ͱ VisualScriptingɺ͍ΘΏΔϊʔυΤσΟλϓϩάϥϛϯάʹରԠ͍ͯ͠ ͘ͱ͍͏͜ͱͰͨ͠ɻࠓճઃܭ࣮૷ͯ͠Έͯ೺Ѳͨ͠಺༰ͱͯ͠΋σʔλͷྲྀΕɺετϦʔϜͱ͍͏ ͜ͱΛڧ͘ҙࣝͤ͞ΒΕ·͢ɻ͜Ε͸ VisualEditor Ͱϊʔυ؅ཧ͢Δܗͦͷ΋ͷͰ͋ΔͨΊɺॲཧ ෦෼Λআ͘σʔλ઀ଓʹؔͯ͠ɺखݩͷߏ੒಺༰Λ೺Ѳฤू͢Δ͜ͱʹେ͍ʹߩݙ͢Δ΋ͷʹͳΔͷ Ͱ͸ͳ͍͔ɺͱࢥΘΕ·͢ɻ ͜Ε·Ͱͷ͢΂͕ͯ৽͍͠ςΫϊϩδͰݸʑͰஔ͖׵͑ΒΕΔ Roadmap ͕ࣔ͞ΕɺॱԠ͠ͳ͚Ε ͹ͦͷԸܙ͕ಘΒΕͳ͍Ͱ͠ΐ͏ɻ MonoBehaviour ͱ DOTS ͷؔ܎ ͜Ε·Ͱͷ Unity Ͱ࡞ΒΕͨ MonoBehaviour ͷੈքΛϨΨγʔͱ͠ɺ͋ΒͨʹผྖҬʹ ECS ۭ ؒͷ World ͕࡞ΒΕ·͢ɻ͜͜ʹ͋Δ͜Ε·Ͱͷ MonoBehaviour ίϯϙʔωϯτ΍ GameObject ΍ UnityEngine.Object ͸ଘࡏͤͣɺECS ͷ Class ΍ Struct Λ৽ͨʹ࡞੒͠ొ࿥͍͖ͯ͠·͢ɻ ͦΕ͔ΒɺUnity ΤϯδχΞͷߟ͑ํͰ͋Ε͹ɺ৔໘ͷߏஙʹ͋ͨͬͯ͸ Scene ͷϩʔυͱΠϯ εϖΫλͷઃఆɺඥͮ͘ Prefab ͷ Instantiate ΍ ScriptableObject ͷࢀরɺͱ͍ͬͨ͜ͱΛى఺ʹ γʔϯΛ࡞͍ͬͯ͘͸ͣͰ͢ɻDOTS ͚ͩͰߟ͑ͨ৔߹Ͳ͏ͳΔͰ͠ΐ͏ɻ DOTS ʹ͓͍ͯ͸ۭͬΆͷ World ͔͠·ͩ͋Γ·ͤΜɻUnityEngine.Object ྨͷࢀর΋͋Γ ·ͤΜɻAssets σΟϨΫτϦΛࢀরͯ͠ίʔυͰॻ͍ͯ৔໘Λ࡞͍ͬͯ͘ͷ͸͋·Γʹඇޮ཰ Ͱ͢ɻECS ͷՔಇʹ Component Λ༩͑Δඞཁ͕͋Γ·͢ɻͦ͜Ͱ΍͸ΓϨΨγʔͷ Scene ΍ GameObject ͕·ͩ·ͩ׆༂͢Δݱঢ়͕͋Γ·ͨ͠ɻ ɹ 50
  53. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.4 Ͳͷ͘Β͍ྑ͘ͳΔͷ͔ 4.4 Ͳͷ͘Β͍ྑ͘ͳΔͷ͔

    ॲཧෛՙΛܰݮ͢ΔͱόοςϦʔফඅ΋ݮ ECSɺJob γεςϜɺBURSTɺͦͯ͠ URP Λซ༻͍ͯ͘͜͠ͱͰॲཧྔ͕େ෯ʹݮΓεϨο υ෼ׂ͕࣮ݱ͞Ε·͢ɻUnityEngine.MonoBehaviour ΍ UnityEngine.Component Λ࢖༻͠ͳ͍ ͜ͱʹΑͬͯ༨ܭͳॳظԽܭࢉίετΛ͔͚ͣϝΠϯεϨοτͷ࢖༻΋߆ଋ͢Δඞཁ͕ͳ͘ɺ UnityEngine.Object ΍ Generic ͳ List Λ༻͍ͳ͍͜ͱͰ Burst ίϯύΠϧʹΑΓεϨουʹ෼ׂ ͯ͠ฒྻॲཧΛଅ͢͜ͱ͕Ͱ͖ɺϘτϧωοΫͱͳ͍ͬͯͨཁҼ͕ղফ͞Ε·͢ɻ Entities.ForEach Ͱهड़͕؆୯ Ϧετ 4.1: foreach ྫ 1: using Unity.Entities; 2: using Unity.Jobs; 3: using Unity.Mathematics; 4: using Unity.Transforms; 5: public partial class MyRotationSystem : SystemBase 6: { 7: protected override void OnUpdate() 8: { 9: float deltaTime = Time.DeltaTime; 10: Entities 11: .ForEach(( 12: ref Rotation rotation, 13: in RotationComponent setting) => 14: { 15: rotation.Value = math.mul( 16: math.normalize(rotation.Value), 17: quaternion.AxisAngle(math.up(), 18: setting.RadiansPerSecond * deltaTime)); 19: }) 20: .ScheduleParallel(); 21: } 22: } Entities.ForEach ͸ɺΤϯςΟςΟΫΤϦͰબ୒͞Εͨ͢΂ͯͷΤϯςΟςΟʹରͯ͠ఆٛ͠ ͨϥϜμؔ਺Λ࣮ߦ͠·͢ɻ ΫΤϦʹΑΔهड़ʹؔͯ͠͸ C#Ͱ͍͏ Linq ͷ࢖͍উखͱ΋ۙ͘ɺߜΓࠐΈநग़͠ϝΠϯεϨο υ͔αϒεϨου΁બ୒తʹϥϜμؔ਺Λઃఆ͢Δͱ͍͏ྲྀΕͱͳΓ·͢ɻ͢Δͱ͜ͷ World શମ ͷ Entity ͔ΒΫΤϦʹ߹க͢Δ Component ߏ੒ͷ Entity ʹରͯ͠ຖϑϨʔϜॲཧ͕࣮ߦ͞Ε· ͢ɻॲཧʹྲྀ͠ࠐΜͰ͍͘ͱ͍͏هड़ํ๏ʹΑͬͯɺ͓͓Αͦ 1 ΞΫγϣϯ͚ͩهड़͓ͯ͘͜͠ͱͱ ͳΓ·͢ɻ 51
  54. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.4 Ͳͷ͘Β͍ྑ͘ͳΔͷ͔ ͨͱ͑͹ɺComponentAɾComponentB ͕ͲͪΒ΋෇༩͞Εͨ

    Entity Λ 10 ౓ӈճస͠ଓ͚Δɻ ComponentAɾComponentC ͕ͲͪΒ΋෇༩͞Εͨͱ͖ɺEntity ͱͦͷϝογϡΛഁغ͢Δɻ͜ͷ Α͏ͳཻ౓ͱͳΓ·͢ɻ ܶతʹܰݮ͞ΕΔ CPU ॲཧΛ͍ͭ࢖͍͔ͬͯͨ ඞͣ͠΋ɺ͜Ε·Ͱͷ։ൃελΠϧͰϘτϧωοΫΛײͯ͡࢓༷ͷݶքΛײ͍ͯͨ͡Θ͚Ͱ͸͋Γ ·ͤΜɻࠓݱࡏͷ Unity ʹΑͬͯྑ࡞͸਺ʑϦϦʔε͞Ε͓ͯΓɺDOT ϦϦʔεҎલͱҎޙͰήʔ ϜͷΫΦϦςΟ͕ஈҧ͍ʹͳΔΘ͚Ͱ͸͋Γ·ͤΜɻྫࣔ͢Δͱ CPU ফඅ͕େ͖͍ॲཧ͸࣍ͷΑ͏ ͳ΋ͷͰ͢ɻ CPU ফඅ͕େ͖͍ 5 બ • Physics/Rigidbody ෺ཧԋࢉॲཧ • transform ࠲ඪܭࢉ • ϨΨγʔ Component Πϯελϯε΍ GameObject ͷେྔͷੜ੒΍อ࣋ɺUpdate ౳ݺͼग़͠ • େ͖ͳσʔλʹର͢Δԋࢉʢͨͩ͜͠Ε·Ͱ΋ Thread ΍ Task ͕࢖͑Δʣ • Assetbundle ΍ Scene ಡΈࠐΈͱ Prefeab ͷ Instantiate ॳظԽ CPU ফඅʹؔͯ͠͸͍ͣΕʹͯ͠΋ϝΠϯεϨουͷ߆ଋͱ͍͏͜ͱʹ΄͔ͳΓ·ͤΜɻUni- tyEngine ͷσʔλ΍ Component ʹର͢Δϓϩηε͸ϝΠϯεϨουͰ͔͠ߦ͑ͳ͍ɺͱ͍͏੍໿ ͷӨڹ͕ڧ͍͜ͱͰɺ෺ྔ͕͋Δ੍ޚ΍؅ཧ͕͋Δ࣮૷͸ආ͚Δඞཁ͕͋ͬͨͷ͕͜Ε·ͰͷྲྀΕ Ͱͨ͠ɻͭ·ΓͦͷݶΓͰ͸ͳ͍෦෼ʹ͓͍ͯ͸ɺޮՌ͸ײ͡ʹ͍͘ͱݴ͑ΔͰ͠ΐ͏ɻ͜ͷΑ͏ʹ DOTS ͷ࠾༻ޮՌΛ࣮ײ͠΍͍͢اըͱͦ͏Ͱͳ͍اը͕͋Δɺͱ͍͏͜ͱ͸ཧղ͓ͯ͘͠ඞཁ͕ ͋ΔͰ͠ΐ͏ɻ DOTS ࠾༻ޮՌ͕ظ଴Ͱ͖Δ 5 બ • Prefab ੜ੒͕ଟ༻͞ΕΔ΋ͷʗ Mesh Λେྔʹ؅ཧ͠ඳը͢Δ΋ͷ • Physics/Rigidbody Λେྔʹ࢖༻͢Δ΋ͷʢPhysics Ͱ࠶ݱੑ͕͋Δ෺ཧγϛϡϨʔγϣϯ͕ Ͱ͖ΔΑ͏ʹͳͬͨ෇ՃՁ஋ʣ • Transform ܭࢉΛଟ༻͠࠲ඪܭࢉͱ੍ޚ΍઀৮൑ఆΛ͢Δ΋ͷ • ܈ूͷཱࣗࢥߟͳͲେྔͷ Object Ͱͷ Update ϓϩηε • NetCode Λ࢖༻ͨ͠ϚϧνϓϨΠήʔϜʢ૯߹ྗʣ ϨΨγʔγεςϜͰ LoadScene ΍ Instantiate ͢Δͱ෼͔Δॲཧෛՙ લهͨ͠ CPU ෛՙ͕େ͖͍ͱ͍͏෦෼͕ͦͷ·· DOTS ࠾༻ʹΑ͓͓ͬͯΑͦରࡦͰ͖Δͱ ͍ͬͯΑ͘ɺprefab ੜ੒΍ Gameobject ͷ Update Ͱॲཧ͕ඞཁͩͬͨ΋ͷ͸ݢฒΈܰྔԽͰ͖ɺ ͔ͭ job γεςϜʹΑͬͯ Thread ૹΓʹͰ͖·͢ɻ·ͨ Unity ͕ఏڙ͢Δ৽͍͠ϚϧνϓϨΠ 52
  55. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.4 Ͳͷ͘Β͍ྑ͘ͳΔͷ͔ Package ͷ

    NetCode Λར༻͢Δ͜ͱͰɺDOTS Լʹ͓͍ͯ ECS Ͱ Physics ͱ௨৴ Transport ͕ॲ ཧͰ͖ඇৗʹ௿ෛՙͰϚϧνϓϨΠήʔϜͷ࣮૷͕Ͱ͖·͢ɻͳ͓େྔͷ Object ੍ޚʹର͢ΔΩϟ ύγςΟ͸Ҿ্͖͕Δͱ͸͍͑΋ͪΖΜ্ݶ͸͋Γ·͢ɻ CPU ফඅΛඞཁͱͨ͠اը͕࣮ݱͰ͖ΔΑ͏ʹͳΔ ͦ͏͍͏ҙຯͰ͸ DOTS ͕׆گʹͳΔͱҎલΑΓΦϒδΣΫτྔ͕ଟ͍ήʔϜ͕ͨͼͨͼϦϦʔ ε͞ΕΔͷ͔΋͠Ε·ͤΜɻ·ͨ͋Δ͍͸୯७ʹɺ͜Ε·ͰΑΓൃ೤͕ݮͬͨͶɺͱ͍͏͜ͱʹͳΔ ͔΋͠Ε·ͤΜɻ͜ͷ؀ڥͰήʔϜاըΛٻΊΒΕΕ͹ɺ෺ཧγϛϡϨʔγϣϯܥɺ܈ू੍ޚܥɺ౎ ࢢγϛϡϨʔγϣϯ౳ɺ͋͑ͯܭࢉίετ͕ߴ͍اըΛ࠾༻ͨ͘͠΋ͳΔ΋ͷͰ͢Ͷɻ·ͨɺϞόΠ ϧ؀ڥͰίϯγϡʔϚεϖοΫͷ޿େͳ MMORPG...UE4 ੡Ͱ΋΋͏͋Γ·͢ΑͶɻ αʔόϏϧυͱ͍͏େ͖ͳ׆࿏ ॲཧෛՙʹྉۚͱ͍͏ੈքͰظ଴͕େ͖͍ Unity ͷϏϧυ Platform ʹ ServerBuild ͱ͍͏બ୒ࢶ͕͋ΔͷΛ͝ଘ͡Ͱ͠ΐ͏͔ɻServer ্ Ͱ Build ͢Δ CloudBuild ͱ͸ҟͳΓ·͢ɻ͜Ε͸ Unity Ͱ Build ͨ͠όΠφϦ࣮ߦϑΝΠϧΛ Linux αʔό΍ Windows αʔόͰ࣮ߦ͢ΔͨΊͷ Build Λࢦ͠ɺαʔόαΠυͰ͸ඳը͕ͳ͘ɺ୺ ຤͔Β͸௨৴઀ଓʹΑͬͯϨεϙϯεͷΈΛಘΔɺͱ͍͏΋ͷͰ͢ɻ͜ͷ Build Πϝʔδ࡞੒ํ๏͸ headless ϞʔυͱݺͼɺҎલΑΓଘࡏ͍ͯͯ͠αʔόϓϩάϥϜͷ Unity Խ͕ՄೳͰͨ͠ɻͨͩ͠ ϨΨγʔͷ Physics ʹ͸ܭࢉ݁Ռͷ࠶ݱੑ͕ͳ͘ɺαʔόͱΫϥΠΞϯτ୺຤Ͱ Physics Λซ༻ͯ͠ ͍Δͱ͖ʹ૬ޓʹҧ͏݁Ռ͕ඳը͞Εͯ͠·͏ͨΊ༻͍Δ͜ͱ͕Ͱ͖·ͤΜͰͨ͠ɻ·ͨ͜ͷ໰୊Λ ղফ͢ΔͨΊʹ NVIDIA PhysX ͳͲϛυϧ΢ΣΞ੡෺ཧΤϯδϯ΋ Unity ʹఏڙ͞Ε͓ͯΓબ୒ Ͱ͖·ͨ͠ɻ͔͠͠࠷దͳύϑΥʔϚϯε͕ಘΒΕΔ؀ڥ͸ϞόΠϧͰ͸ͳ͘ίϯγϡʔϚ޲͚ͱ͍ ͏΋ͷͰͨ͠ɻ͜ͷΑ͏ʹैདྷͷ MonoBehaviour Ͱѻ͏ ServerBuild ίϯςϯπͰ͸ύϑΥʔϚϯ εͷ໘Ͱෛ୲͕େ͖͘ɺ࠾༻ʹ৻ॏʹͳΒ͟ΔΛಘͳ͍ͱ͏ঢ়گ͕͋Γ·ͨ͠ɻ DOTS ʹ༻͍Δ Physics Ͱ͸͜ͷ఺Λߟྀͯ͠࠶ઃܭ͞Ε͍ͯΔͨΊ෺ཧԋࢉ݁Ռʹ͸࠶ݱੑ͕ ͋Γ·͢ɻ͜ΕʹΑΓଟ؀ڥͰ Physics Λ࢖༻͠ͳ͕ΒΩʔೖྗಉظͷΈΛߦͬͰ΋ঢ়گʹҰ؏ੑ͕ อͨΕΔͱ͍͏͜ͱʹͳΓ·͢ɻ·ͨͦͷ΄͔ͷॾʑͷॲཧྔ͕ݮͬͨͱ͍͏͜ͱͳΒαʔόίετ ͦͷ΋ͷ͕Լ͕Γɺҡ࣋අ͕͜Ε·Ͱͷ ServerBuild ΑΓ௿͘཈͑Δ͜ͱ͕ՄೳʹͳΓɺωοτϫʔ ΫήʔϜͷ GameSerer Ϟσϧͷ࣮ݱΛ Unity ͷ sereverBuild όΠφϦʹΑ࣮ͬͯݱͰ͖ΔՄೳੑ ͕ߴ·ͬͨͱ͍͏͜ͱʹͳΓ·͢ɻ UnityC#ΤϯδχΞ͚ͩͰωοτϫʔΫήʔϜ͕ 1 ϓϩδΣΫτͰ࡞ΕΔ޾ͤ Unity Ͱ ServerBuild ͕ग़ྗͰ͖Δͱ͍͏͜ͱͷϝϦοτ͸αʔόྉ͚ۚͩͰ͸͋Γ·ͤΜɻ1 ਓ ͷΤϯδχΞ͕ಉҰϓϩδΣΫτͷதͰαʔόϓϩάϥϜͱΫϥΠΞϯτϓϩάϥϜΛಉ࣌ʹ࡞ۀͰ ͖ɺ࣮૷ͷ଎౓޲্͕ਤΕɺಉҰϓϩηε΍ಉҰߏ଄ମͷ࢖༻͕Ͱ͖ΔͨΊෆ۩߹ͷൃੜ͢ΔՄೳੑ ͕ݮΓɺ໰୊͕Ͳ͜ʹ͋Δͷ͔ͷൃݟ·Ͱͷϓϩηε͕୹ॖ͞ΕΔ͜ͱ͕ڍ͛ΒΕΔͰ͠ΐ͏ɻͦͷ 53
  56. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.5 Ͱ͖Δ͜ͱ/Ͱ͖ͳ͍͜ͱ ͨΊখ͞ͳϓϩμΫτ΍ݸਓɺϓϩτλΠϓͳͲͰ΋͢͹΍͘ϚϧνϓϨΠήʔϜΛ࣮૷Ͱ͖ɺήʔ Ϝࣗମͷ͓΋͠Ζ͞Λߟ͑Δ༨༟͕ੜ·ΕΔͷ͸͍ͨ΁Μ޾ͤͳ͜ͱͰ͢ɻ

    4.5 Ͱ͖Δ͜ͱ/Ͱ͖ͳ͍͜ͱ ϨΨγʔγεςϜ͕͢΂ͯ DOTS ʹҠߦͰ͖Δͱ͏͜ͱͰ͸ͳ͍ʢ·ͩʣ DOTS ؀ڥʹҠߦ͠Α͏ͱͯ͠΋·ͩҠߦ͖͠Εͳ͍෦෼͕͋Δఔ౓͋Δ͜ͱΛ೺Ѳ͓ͯ͘͠ඞ ཁ͕͋Γ·͢ɻͦΕʹΑͬͯ MonoBehaviour ͱ GameObject ੍ޚ΋ฒߦ͢Δඞཁ͕͋Γ·͢ɻ· ͨ UI ʹ͢ΔࡍͦΕ͸ݦஶͰ͕͢ɺECS ͷ World ͔Β஋ΛϨΨγʔγεςϜʹ໭ͯ͠ UI ग़ྗ͢Δ ͜ͱʹͳΓ·͢ɻ DOTS Խ͕·ͩࡁΜͰ͍ͳ͍ओͳ΋ͷ • Camera • Light • UI • Audio • Particle ͍ͣΕ΋ DOTS ԽΛظ଴͍ͨ͠෦෼Ͱ΋͋ΔͷͰɺࠓͷ࣌఺Ͱ͏·͘ DOTS ԽʹΑΔԸܙΛ͏͚ ΒΕͨͱͨ͠ͱ͖ʹͦͷ͞Βʹ্ʹ͍͚Δͱ͍͏झࢫʹͳΓ·͢ɻϙδςΟϒʹͱΒ͑Δͱɻ DOTS Ҡߦʹઌۦ͚ͯݱΕͨ Tiny ϓϩδΣΫτ Tiny ͸·ͩ WebGL ൛ɺࠓޙϞόΠϧల։͕એݴ͞Ε͍ͯΔ͕ Tiny ϓϩδΣΫτࣗମͷ࢝·Γ͸ Web ޿ࠂதͰ Unity ίϯςϯπ͕௚઀ϓϨΠͰ͖Δ͜ͱΛ ૂͬͯ༰ྔతʹ࠷ܰྔͰ͋Δ͜ͱΛ໨తͱ͍ͯ͠Δ΋ͷͱͷ͜ͱͰͨ͠ɻ͔͠͠ DOTS Λݚڀͯ͠ ͍͘ʹͭΕɺϨΨγʔʹ્·Εڞଘ͍ͯ͠Δঢ়گ͕ղܾͷஹ͠Λ·ͩΈ͍ͤͯͳ͍ঢ়گʹ͋Δͳ͔ɺ ͜ͷ Tiny Ͱ͸ Camera ΋ Light ΋ Audio ΋ DOTS ʹҠߦ͍ͯ͠ΔͰ͸ͳ͍Ͱ͔͢ɻTiny Ͱߏங ͢Δ΋ͷ͸͢΂ͯ ECS ͷ Entity ʹΑͬͯߏ੒͞Ε͍ͯͯɺϨΨγʔͷγεςϜΛੵΜͰ͍ͳ͍͜ͱ ͰΤϯδϯͦͷ΋ͷͷ Player ͕ܰྔʹͳΔͱ͍͏΋ͷͰ͢ɻ͞Βʹɺ࢖༻ Package Λݶఆͯ͠ඞཁ ͳ΋ͷ͚ͩΛ౥ࡌͰ͖Δͱ͍͏͜ͱͰ͢ͷͰ package ࣗମͷαΠζ΋͜Ε·ͰΑΓ֨ஈʹݮ͓ͬͯ Γɺ࣮ଌϏϧυαΠζͰ͸ɺͪΐͬͱͨ͠ήʔϜͰςΫενϟ΍ΦʔσΟΦྨΛখ͘͞·ͱΊͯ͋Δ ϓϩδΣΫτʹ͓͍ͯ 8MB લޙͰग़ྗ͞Ε͍ͯ·ͨ͠ɻ·ͩ Build ʹଟ͘ͷ੍ݶ͕͋ΔΑ͏Ͱ࣮༻ ஈ֊Ͱ͸ͳ͍Α͏Ͱ͕͢ɺ͜ͷ Tiny ͕ͦ͜ DOTS ͷຊྲྀͰ͢ͷͰ͸ͳ͍͔ͱɺີ͔ʹචऀࣗ਎͸ ࢥ͍ͬͯ·͢ɻ 54
  57. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.5 Ͱ͖Δ͜ͱ/Ͱ͖ͳ͍͜ͱ طଘϓϩμΫτΛ DOTS

    ʹҠߦͰ͖Δͷ͔ ಋೖ͢ΔͨΊʹ͞Βʹ஌͓ͬͯ͘͜ͱ •ʮطଘϓϩμΫτΛ DOTS ʹҠߦͰ͖·͔͢ʁʯ͍͍͑ɺ׬શʹผͷγεςϜʗΞʔΩςΫτ Ͱ͋Γ͢΂ͯ࠶ઃܭ͕ඞཁ ߟ͑Δ΂͖͸ม׵࡞ۀͰ͸ͳ͘ɺύϥμΠϜγϑτؚ͕·Ε͍ͯΔͱ͍͏͜ͱͰ͢ɻطଘͷ΋ͷΛ ผͷΞʔΩςΫτʹஔ͖׵͑ͨ࣌ɺಉ͡໾ׂ͸ଘࡏͰ͖ͳ͍Մೳੑ͕͋Γ·͢ɻͦͷͨΊɺඞཁͳೳ ྗ͸૑଄ྗʹͳΔͰ͠ΐ͏ɻ Unity Ϣʔβʔ͸ΦϒδΣΫτࢦ޲ੜ·Εɺίϯϙʔωϯτࢦ޲ҭͪ ͦͯ͠σʔλۦಈࢦ޲ʹ ͦͷੲɺखଓ͖ܕϓϩάϥϛϯάΛத৺ʹ͍ͯͨ࣌͠୅ʹɺ͜ΕͰ͸؅ཧ͕Ͱ͖ͳ͍ͱɺΦϒδΣ Ϋτࢦ޲ʢObject-Oriented Programmingʣ͕ੜ·Ε·ͨ͠ɻͦͷޙɺ೿ੜ֊૚ߏ଄͕ෳࡶͰ͜Ε Ͱ͸֦ு͕Ͱ͖ͳ͍ͱɺಉ͡ॲཧΛίϯϙʔωϯτͰ·ͱΊϞδϡʔϧԽ͢Δίϯϙʔωϯτࢦ޲ʹ ޲͔͍·ͨ͠ɻϞδϡʔϧ͕ෳࡶʹͳͬͯ͘Δͱɺσʔλࢀর͕෼ࢄ͠ύϑΥʔϚϯε͕٘ਜ਼ʹͳΔ ͱɺσʔλۦಈʹΑΔ EntityComponentSystemʢECSʣΛ໨ࢦ͠·ͨ͠ɻσʔλ͸ɺ·ΔͰཻࢠ΍ ੜ͖෺ͷΑ͏ͳଘࡏͰɺͦͷ৔ʹͱͲ·Βͣු༡͍͔ͯͯͭ͠ΈͲ͜Ζ͕ͳ͘ɺͲͷ͘Β͍͋Δͷ͔ ΋ั·͑ͯΈͳ͚Ε͹Θ͔Βͳ͍ɺͱ͍ͬͨಛੑΛ͍࣋ͬͯ·͢ɻ ͦ͏ଊ͑ͯΈΔͱਆൿతͳؾ͑͞͠·͢ɻ ͩΜͩΜͱΠϝʔδ͕͔ͭΊ͖ͯ·ͤΜ͔ʁ ˞ ॾઆ͋ΓಠࣗͷݟղͰ͢ɻ MonoBehaviour ͸աڈͷҨ෺ͳͷ͔ طଘϢʔβʔʹͱͬͯ࢖͍উख͸े෼ MonoBehaviour ʹΑͬͯ͜Ε·Ͱ Unity ੡໊࡞ΞϓϦ͕਺ʑϦϦʔε͞Ε͖͍ͯͯΔࣄ࣮͕͋ Γ·͢ɻֶशͷ͠΍͢͞΍࣮ݱ·Ͱͷγϯϓϧ͕͞ Unity ਓؾΛ͜͜·ͰҾ͖د͍ͤͯΔɺͱ͍ ͏͜ͱ΋๨Εͯ͸ͳΒͳ͍ॏཁͳཁૉͰ͢ɻΤϯδϯͷύϑΥʔϚϯεͱ։ൃ؀ڥͷϢʔβϏϦ ςΟ͸ผͷ͜ͱͰ͸͋ΓɺDOTS ͸ͦΕ͸ͦΕͰड͚ೖΕ৆ࢍ͢Δ΋ͷͰ͕͢ɺMonoBehaviour ͱ GameObject ͷʮख๏ʯ͕ফ໓ͯ͠͠·͏͜ͱ͸ Unity ͷྑ͞Λࣦͬͯ͠·͏ͱ΋ߟ͍͑ͯ·͢ɻ զʑ DOTS ҠߦલͷΤϯδχΞʹͱͬͯ޾͍ͳ͜ͱʹɺUnity Technologies ࣾͷݟղ͸͜͜ʹ͍ͭ ͯ͸͍͋·͍ͳ··ͱͳ͍ͬͯ·͢ɻDOTS ͸ਐΊ͍ͯΔ͕׬શʹҠߦ͢Δͱ͍͏झࢫͰ͸ൃද͠ ͍ͯͳ͍ͷͰ͢ɻDOTS ϓϩμΫτશମͱͯ͠͸͍ͨ΁Μ௕ظʹͦͯ͠େن໛ͳ౤ࢿͰ͋Δʹ΋͔ ͔ΒΘͣɻΠν Unity ϑΝϯͱͯ͠͸ɺ͜ͷղܾͱͯ͠ົҊ͕ఏࣔ͞ΕΔ͜ͱΛظ଴ͯ͠ݟक͍ͬͯ ·͢ɻ 55
  58. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.6 मಘ೉қ౓͸ߴ͍ͷ͔ 4.6 मಘ೉қ౓͸ߴ͍ͷ͔

    DOTS ରԠ͕೉͍͠ͱ͜Ζ 1. World ؅ཧͱ System ؅ཧ 2. ECS ىಈ 3. ઀৮Πϕϯτ ͜Ε͸͍ͣΕ΋ϕετϓϥΫςΟε͕ෆ଍͍ͯ͠Δ͜ͱ͸େ͖ͳཁҼͰ͢ɻͦͷ͏͑Ͱɺڍ͕ͬͯ ͍ΔެࣜαϯϓϧͰࣔ͞Ε͍ͯͳ͍෦෼͕ଟ͍ͨΊɺࠓͷͱ͜Ζ஍ಓʹରࡦ͢Δ͔ͦͷ෦෼Λਂ͘࢖ Θͳ͍ͱ͍͏ରॲʹͳ͍ͬͯ͘͜ͱʹͳΓ͕ͪͰ͢ɻ͞Βʹɺpackage ͷ಺༰Λ Library/Package Cache ֊૚͔ΒιʔείʔυΛಡΈֶश͢Δɺͱ͍͏खஈͰղੳ͍ͯ͘͜͠ͱ΋ඞཁͰ͢ɻ 1. World ͱ ECS ؅ཧ World ͕೚ҙʹ࡞੒Ͱ͖·͢ɻ·ͨσϑΥϧτͷ NetCode Ͱ͸ ServerWorld ͱ ClientWorld0 ͱ ͍ͬͨ΋ͷ͕࡞੒͞Ε·͢ɻͨͩ World ҡ࣋ίετ΋͔͔ΔͷͰ࠷খ਺Ͱߏஙͨ͠ํ͕ྑ͍Α͏Ͱ ͢ɻ೉͍͠Օॴͱͯ͠͸ɺConvert ͷॳظঢ়ଶ͸σϑΥϧτ World ʹରͯ͠ Entity ੜ੒Λߦ͍· ͢ɻSystem ͸ɺAttribute ʹΑͬͯ World Λࢦఆͯ͠ɺ΋͘͠͸ະࢦఆͰશ World ʹ͓͍ͯՔಇ͠ ·͢ɻ஫ҙ͢΂͖͸ɺͲ͜ʹͲͷ Entity ͱ System Λஔ͍͍ͯΔ͔ίʔυϕʔεͱ͍͏ͱ͜ΖͰ͢ɻ ͦͷͨΊࢄͬͯ͠·͏ɺߦํ͕Θ͔Βͳ͘ͳΔɺະ࢖༻ System ͕ొ࿥͞Ε͍ͯΔɺͱͳΓ͕ͪͰ͢ɻ ΋ͪΖΜ EntityDebugger ͸͍͍ͭͯ·͢ͷͰௐ΂ͯ஍ಓʹରԠͰ͖·͢ɻ ͦΕ͔Βɺ͕͜͜࠷େͷݒ೦఺Ͱ͸͋Γ·͕͢ɺSystem ͷొ࿥͕σϑΥϧτͰશొ࿥ͱ͍͏ͱ͜ ΖͰ͢ɻબผͯ͠ొ࿥͢ΔͱͳΔ৔߹ɺNetCode ౳ͷ֎෦ Package Ͱ࢖͍ͬͯΔ΋ͷ΋ਓྗͰొ࿥ ͢Δ͜ͱʹͳΓϝϯςφϯε໰୊ʹͿ͔ͭΓ·͢ɻͦͷͨΊશ System ొ࿥Λड͚ೖΕͯ System ͷ ্ཱ͕ͪΓͷͱ͜ΖͰਐ·ͤͳ͍൑ఆΛҰͭҰͭೖΕΔ࣮૷Λࢪ͠·͢ɻ͜ͷͨΊɺେن໛։ൃʹର ͯ͠͸ݱ࣌఺Ͱ͸ରԠͰ͖ͳ͍ͱݴΘ͟ΔΛಘ·ͤΜɻ 2. ECS ىಈ ECS ͷ System ͸σϑΥϧτͰ Application ͷىಈͱͱ΋ʹՔಇ͢Δ͔ɺdefine ఆٛʹΑͬͯఀࢭ ͤ͞೚ҙʹ্ཱͪ͛·͢ɻ͢΂ͯͷཁૉ͕ DOTS ʹͰ͖ͳ͍͜ͱΛ౿·͑ΔͱΠϯήʔϜʢϝΠϯ ͷήʔϜʣ෦෼ͷΈ DOTS Խ͠ɺͦΕҎ֎͸ఀࢭͤ͞Δબ୒ࢶ͕༗ޮͰ͠ΐ͏ɻ·ͨ Convert ݺͼ ग़͠ʹΑͬͯ೚ҙσʔλͷ ECS ౉͠Λߦ͏͜ͱ͕༧ݟ͞Ε·͢ɻผͰ͢Ͱʹड़΂͍ͯΔΑ͏ɺScene ભҠલʹ World Λ্ཱͪ͛ ECS Λ༗ޮʹ͔ͯ͠ΒભҠΛ͢Δͱ͍͏ɺECS ͷఀࢭʗՔಇΛભҠΛ ൐੍ͬͯޚ͍ͯ͘͠࡞ΓΛ͢Δඞཁ͕͋Γ·͢ɻ 3. ઀৮Πϕϯτ ैདྷͷ Unity ͷ͓΋͠Ζ͍ͱ͜Ζ͸ɺΠϯεϖΫλͱίϯϙʔωϯτͰπϧπϧͱઃఆ͍ͯ͘͠ͱ ಈ͘΋ͷ͕࡞Εͨ͜ͱʹ͋Γ·͢ɻݱگͷ DOTS ؀ڥʹ͓͍ͯͦΕ͸ਅٯʹ͋Γ·͢ɻࡉ͔͘نଇ 56
  59. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.7 Ͳ͔͜ΒखΛ͚ͭΕ͹ྑ͍ͷ͔ ʹԊͬͨ ClassɺStruct

    Λ࡞੒͠ͳ͚Ε͹ಈ͖·ͤΜɻܝ୊ͷʮ઀৮Πϕϯτʯ൑ఆपΓʹ͍ͭͯͦ Ε͸ಛʹݦஶͳͨΊڍ͍͛ͯ·͢ɻ઀৮Λ൑ఆ͢ΔͨΊʹ Job Ͱ௕จΛهड़͠ͳ͚Ε͹ͳΒͣɺΠϕ ϯτͱ͍͏΄ͲͦΕ͸डಈతͳ΋ͷͰ͸ͳ͘ɺITriggerEventsJob Λ࣮૷ͨ͠ Job ͷ Execute(Tr iggerEvent triggerEvent) ʹಧ͘ Entity ͕ A ͱ B ͷ 1 ૊Έ͚ͩ֨ೲ͞Ε͓ͯΓɺ1 ϑϨʔϜ಺ Ͱ઀৮͢Δ͢΂ͯͷ૊Έ߹Θ͕ͤ Execute ʹೖ͍ͬͯΔͷͰ΄͍͠ Entity ͕དྷΔ·Ͱௐ΂ɺࣗ෼Ͱ ಛఆ͢Δɺͱ͍͏͜ͱʹͳΓ·͢ɻௐ΂Δʹ͋ͨͬͯ͸ Entity ͷΈͰ͸൑ผ͕Ͱ͖ͣɺೖͬͯ͘Δ Entity ΛΩʔʹͨ͠ Chunk ͱ͍͏σʔληοτΛࢀরͯ͠ Component ΛऔΓग़͍͖ͯ͠·͢ɻ͜ Ε͸ϨΨγʔͰ͍͏ͱ͜ΖͷɺCollider ίϯϙʔωϯτͱ MonoBehaviour ͷ OnCollider() ͱ͍͏ ͱ͜Ζͱͷରൺ෦෼ʹͳΓ·͢ɻ ಋೖ͢ΔͨΊʹ஌͓ͬͯ͘͜ͱ 5 બ •ʮpackage ΛೖΕΔ͘Β͍ͷෛ୲Ͱ͔͢ʁʯ͍͍͑ɺҧ͍·͢ •ʮMonoBehaviour ͷ Component Λ DOTS ༻ʹஔ͖׵͑Δײ֮Ͱ͔͢ʁʯ͍͍͑ɺҧ͍·͢ •ʮαϯϓϧίʔυͷίϐʔ&ϖʔετͰ΍Ε͹ࡁΈ·͔͢ʁʯݶఆతʹ͔͠αϯϓϧ͕͋Γ· ͤΜ •ʮDocument Λ͔ͬ͠ΓಡΊ͹ͳΜͱ͔ͳΓ·͔͢ʁʯ͍͍͑ɺެࣜυΩϡϝϯτ͸গྔͷݹ ͍΋ͷ͔ GitHub ͷ sample ϦϙδτϦʹஔ͔Εͨ୹͍ ReadMe จ͔͋͠Γ·ͤΜ •ʮಋೖͷোน͸ߴ͍Ͱ͔͢ʁʯ͸͍ɺ࢒೦ͳ͕Β೉͍͠͏࣮͑༻ํ๏͸΄ͱΜͲग़ճ͍ͬͯ· ͤΜ ɹ ϐϦοͱਏͯ͘ඒຯ͍͠ɺ ͱ͍ͬͨ۩߹ʹͱΒ͍͑ͯͨͩ͘ͷ͕ྑ͍͔ͱࢥ͍·͢ɻ 4.7 Ͳ͔͜ΒखΛ͚ͭΕ͹ྑ͍ͷ͔ ͋·ΓʹมΘͬͯ͠·͏ͷͰɺͲ͔͜Β࢝Ίֶͯश͍͚ͯ͠͹ྑ͍ͷ͔໎͍·͢ɻͱ͋Δ࣮૷هࣄ Λݟश͓͏ʹ΋Ұ෦෼ͷٕज़͔͠࢖ΘΕ͍ͯͳ͍͜ͱ͕ଟ͘ɺ·ͨ͋ΔαϯϓϧΛΈͯ΋ඥղ͘ʹલ ఏ͕ݟ౉ͤͳ͍͜ͱ͕ͨͼͨͼى͜Γ·͢ɻͦͷͨΊ໎Θֶͣश͢ΔͨΊʹ͜ͷ͋ͨΓΛݟΔͱΑ ͔ͬͨɺͱ͍͏෦෼Λநग़͓͖ͯ͠·͢ɻ ܝࡌͷ URL ͸Լํ΁ QR ίʔυΛܝࡌ͠·ͨ͠ͷͰΞΫηεͷࡍʹ͝ར༻͍ͩ͘͞ɻ ·ͣ͸ొஃ಺༰΍ಈըղઆΛҰ௨ΓΈͯ֓೦Λڞ༗͢΂͠ • جຊཧղ – *7 https://learning.unity3d.jp/tag/dots/ ∗ ެࣜͷղઆಈը͕๛෋ʹܝࡌ͞Ε͍ͯ·͢ɻ 57
  60. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.7 Ͳ͔͜ΒखΛ͚ͭΕ͹ྑ͍ͷ͔ • DOTS

    ύοέʔδ֓ཁ – *8 https://unity.com/ja/dots/packages GitHub ެࣜαϯϓϧͷ script ΛಡΈτϨʔε ެࣜ GitHub ͔ΒαϯϓϧΛऔಘͯ͠શγʔϯͷ script ΛಡΈ͢΂ͯτϨʔεͯ͠ΈΔͱྑ͍Ͱ ͠ΐ͏ɻ • ESC جຊςΫχοΫαϯϓϧ – *9 https://github.com/Unity-Technologies/EntityComponentSystemSamples ∗ ECSSamples ɹ... Ұ൪ॳڃαϯϓϧɺscene ๛෋ ∗ HybridHDRPSamples ɹ...scene ๛෋ ∗ HybridURPSamples ɹ...scene ๛෋ ∗ UnityPhysicsSamples ɹ... Ұ൪ॳڃαϯϓϧɺscene ๛෋ɺ઀৮൑ఆʹඞਢ • Document ֓ཁઆ໌͋Γ package ϖʔδ – *10 https://docs.unity3d.com/Packages/[email protected] – *11 https://docs.unity3d.com/Packages/[email protected] ∗ ...NetCode ͸ϑΝʔετಋೖΨΠυ͕͋ΔͷͰ࣮ફ͠·͠ΐ͏ – *12 https://docs.unity3d.com/Packages/[email protected] • Animation – *13 https://github.com/Unity-Technologies/Unity.Animation.Samples ∗ UnityAnimationHDRPExamples · ...HDRP ൛ɺscene ๛෋ɺURP Ͱ΋࢖͑Δ sample ͋Γ ∗ UnityAnimationURPExamples · ...URP ൛ɺHDRP ΑΓͪΐͬͱগͳ͍ • DataFlowGraph ...Animator ΍ Mecanim ૬౰ʢpackage ʹؚ·ΕΔ Sampeʣ – *14 https://docs.unity3d.com/Packages/com.unity.datafl[email protected] • FPS ΞΫγϣϯσϞʢ݁ߏݹ͍࣌ظͷ΋ͷʣ – *15 https://github.com/Unity-Technologies/DOTSSample ∗ ... ࠓͷςΫχοΫʹ౰ͯ͸·Βͳ͍෦෼΋͋Δ • Project Tiny – *16 https://github.com/Unity-Technologies/ProjectTinySamples ∗ ... શ DOTS Խͷੈք؍ͷ೺Ѳʹ໾ཱͭɺ഑෍༻Ϗϧυ͸·ͩग़ྗͰ͖ͳ͍໛༷ɺα ϯϓϧগͳ͍ • DOTS & Tiny ಋೖΨΠυ 58
  61. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ – DOTS

    Runtime & Project Tiny: Getting Started [Public] ∗ *17 https://docs.google.com/document/d/1A8hen2hLFY5FLkC5gd3JP2Z- IpHfnAX-CpYLK3aOdwA · ... શ DOTS Խͷࠓޙͷ೺Ѳʹ໾ཱͭɺ།Ұ BuildConfigure ͷهड़͕͋Γ ਤ: ˞ܝࡌϦϯΫ QR ίʔυ 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ ECS ͰσʔλϑϩʔΛ͍͔ʹ࡞Δ͔ Entity ͱ͍͏ശΛ࡞Γ Component ͱ͍͏৘ใΛࡌͤͯ System ͱ͍͏ॲཧ૷ஔͰड͚औΔɺͱ͍ ͏͜ͱ͕جຊతͳྲྀΕͰ͢ɻͱ͸͍͑ήʔϜΛ։ൃ͢Δ࣌ʹͦͷࢹ఺Ͱडಈతʹσʔλ͚ͩΛΈΔͱ ͍͏ߟ͑ํ͸͜Ε·Ͱͷ։ൃελΠϧʹ͸͋·Γͳ͘ɺ࣮຿ϨϕϧͰͲͷΑ͏ͳ͜ͱΛߟ͑Δඞཁ͕ ͋Δͷ͔͸࣮ࡍʹମݧ͍͔ͯ͠ͳ͚Ε͹Πϝʔδ͠ʹ͍͘ͱ͜Ζ΋͋Γ·͢ɻ 59
  62. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ ΦϒδΣΫτ࿈ܞʹ͸ͻͱ޻෉ඞཁ ·ͨ

    ECS ͷಛੑ͔ΒɺEntity ୯ମΛͻͨ͢Βॲཧ͠ଓ͚Δ͜ͱΛಘҙͱ͢Δ൓໘ɺEntity Ͳ͏͠ ͷ࿈ܞ΍ System Ͳ͏͠ͷ࿈ܞʹ޻෉͕ඞཁʹͳΓ·͢ɻผͷ System ʹͱ͋Δ௨஌Λ͍ͨ͠ͱ͖ɺ ଟ͘͸৽͍͠ 1 ͭͷ Entity Λ࡞Γ௨஌༻ Component Λ౉͢ςΫχοΫΛ࢖͍·͢ɻϚϧνϓϨΠ ͷ NetCoded ؀ڥʹ͓͍ͯ΋αʔό΁௨஌ΛૹΔํ๏͕ಉ༷ʹ Entity ͱ௨஌༻ͷ Command ͱ͍ ͏ Struct ͳͲΛ࢖͍·͢ɻ Πϯελϯεࢀর͸࢖Θͳ͍ ΦϒδΣΫτࢦ޲Ͱසग़͢ΔΠϯελϯεࢀরʹΑͬͯϑϥά౳ΛݟΔͱ͍͏΍Γํ͸ݪଇߦΘ ͣʹ࣮૷͍͖ͯ͠·͢ɻσʔλࢦ޲ͱ͍͏͜ͱ΋͋ΓΦϒδΣΫτ͕ Update ؂ࢹͯ͠ɺͱ͍͏ߏ ଄Ͱ͸ͳ͘ͳΓɺSystem ͕ಛఆͷ Archetype ΛͦΕ͕ 1 ͔ͭ͠ͳ͍ͱͯ͠΋ड͚ଓ͚ System ͷ update ͱͯ͠؂ࢹ͢Δ͜ͱͰ Burst ίϯύΠϧ΍ Job ౳ͷ࠷దԽ͕దԠͰ͖ΔΑ͏ʹͳΓɺ͜Ε͕ DOTS ͷੑೳΛҾ͖ग़࣮͢૷ͱͳ͍ͬͯ͘Θ͚Ͱ͢ɻ Entity Entity ͸ Component Λ࣋ͭ͜ͱ͚ͩ ECS Ͱ͍͏ EɺEntity ͸ Component ͕ೖΔ͚ͩͷߏ଄ମͰ͢ɻEntity ͷ Index ͕ൃߦॱʹൃ൪ ͞Ε·͢ɻIndex ͸ϢχʔΫ৘ใͰ͢ͷͰલճͱಉ͡σʔλ͔Λ൑ผ͢Δࡍʹ༻͍·͢ɻname ͸ઃ ఆͰ͖·͕͢ UNITY_EDITOR Ͱ͔͠࢖͑·ͤΜɻ#if ΛೖΕ͓͔ͯͳ͚Ε͹ϏϧυΤϥʔʹͳͬͯ ͠·͍·͢ɻ Component Component ͷσʔλλΠϓ͸ݶΒΕͨσʔλλΠϓ͔͠࢖༻Ͱ͖ͳ͍ ECS Ͱ͍͏ CɺEntity ʹ෇͚Δ Component ͕ struct σʔλͰ͢ɻ஋Λ࣋ͨͤΔ͜ͱ͕த৺ʹͳ Γ·͕͢ܕ੍ݶ͕ڧ͍ʢBlittable ܕͷΈʣͷͰ஫ҙ͕ඞཁͰ͢ɻ·ͨσʔλϦετʹ͓͍ͯ΋ैདྷ ͷ࣮૷Ͱ Generic ͷ List ΍ DictionaryɺHashtableɺͦͯ͠഑ྻΛ͔ͳΓ࢖͖ͬͯͨͱࢥ͍·͕͢ ͢΂ͯ࢖͑·ͤΜɻωΠςΟϒίʔυͰѻ͑Δ Blittable ܕͱͯ͠ɺ࢖͍׳Εͳ͍ NativeArray<T> ܕͰϦετΛ࣋ͪ·͢ɻࣗࡏʹ࢖͑ΔΑ͏ʹ͍͖ͯ͠·͠ΐ͏ɻ Component ͷ࢖༻ঢ়گ Component ͸༗ແ͚ͩΛݟͯϑϥάͱͯ͠ѻ͍·͢ɻ͍͔ͭ͘ͷ Component ͷ૊Έ߹Θͤ΋ϑ ϥάͱͯ͠ػೳ͠·͢ɻঢ়گ͕มԽ͢Δʹैͬͯ Entity ͷ Component Λ௥Ճ࡟আ͠ଓ͚ͯίϯτ ϩʔϧ͠·͢ɻSystem ͷ update தͰ஋มߋ͢Δ৔߹͕͋Γ·͢ɻ͋Β͔͡Ίมߋ͢Δ Component ͱมߋ͠ͳ͍ Component Λ໌ࣔతʹ ref in Ͱࢦఆͯ͠࢖͍·͢ɻJob γεςϜͰฒྻॲཧΛࢪ͢ ৔߹͸ Component ͷσʔλॻ͖׵͕͑ڝ߹ͯ͠ยํ͔͠อଘ͞Εͳ͍Մೳੑ͕͋Γ·͢ɻNetCode ࢖༻࣌ʹ͸ Component ͷಛఆͷ field Λಉظର৅ʹ͢Δ [GhostField] ଐੑΛ࢖͍·͢ɻ 60
  63. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ System System

    ͸ SystemBase ͔ ComponentSystem ͔ System ͷ OnCreate ʹ RequireSingletonForUpdate ͷՔಇ൑ఆΛهड़্ཱ͕ͯͪ͠ΓͰఀࢭ ͤ͞Δ͜ͱ͕Ͱ͖·͢ɻSystemBase ͷ৔߹ɺOnUpdate ʹಉظॲཧͳΒ Entities.ForEach(...) .Run() ͱ͍ͬͨϝκοτνΣΠϯΛهड़ͯ͠ΫΤϦΛॲཧ͠·͢ɻ·ͨ͸ฒྻॲཧʹରͯ͠͸ Ent ities.ForEach(...).Schedule() ͱ͍ͬͨ۩߹ʹએݴΛม͑ͯݺͼग़͠·͢ɻͳ͓ ComponentS ystem ͷ৔߹ɺOnUpdate ͳΒ Entities.ForEach(...) ͱɺएׯҧ͏هड़ʹͳΓ·͢ɻ Hybrid Renderer package ʹؚ·Ε͓ͯΓಉ࣌ظʹऔΓೖΕΔલఏͰ͋Δ͜ͱΛ౿·͑ͯϨϯμϦϯάύΠϓϥΠϯ ʹ͍ͭͯ΋ݴٴ͠·͢ɻ Renderer ʹ͸૊ࠐΈϨϯμϦϯάύΠϓϥΠϯɺHDRPɺURP ͷ 3 छྨؚ͕·Ε·͕͢ɺ͞Β ʹɺ։ൃͷऴྃͨ͠ V1 ͱੵۃతʹߋ৽͍ͯ͘͠ V2 ͷ 2 όʔδϣϯؚ͕·Ε͍ͯ·͢ɻͳ͓ V2 Ͱ ͸૊ࠐϨϯμϦϯάύΠϓϥΠϯʢϨΨγʔʣ͸αϙʔτ͍ͯ͠·ͤΜɻV2 ༗ޮԽʹ͸ ENABLE_HY BRID_RENDERER_V2 ɹͷ Define Λ player ઃఆʹ͓͍ͯ༗ޮʹ͠·͢ɻ ϋΠϒϦουΤϯςΟςΟ ϋΠϒϦουΤϯςΟςΟʢHybridComponentʣΛ࢖༻͢ΔͱɺMonoBehaviour ίϯϙʔωϯ τΛ IComponentData ʹม׵ͤͣʹ DOTS ΤϯςΟςΟʹΞλον͠·͢ɻม׵γεςϜ͸ AddH ybridComponent Λݺͼग़ͯ͠ɺ؅ཧର৅ίϯϙʔωϯτΛ DOTS ΤϯςΟςΟʹ઀ଓ͠·͢ɻͭ ·Γ MonoBehaviour ͷ·· ECS ʹྲྀ͢खஈͱͳΓ·͢ɻγʔϯϝΠϯ camera ͸௨ৗ Entity ʹ͢ Δ͜ͱ͸Ͱ͖ͳ͍ͨΊ Hybrid ม׵Λ༗ޮʹ͢Δʹ͸ HYBRID_ENTITIES_CAMERA_CONVERSION Λ ఆٛ͠·͢ɻͨͩ͠ Light/ TextMesh / ύʔςΟΫϧ/ Camera ౳ͷ؅ཧର৅ίϯϙʔωϯτ͸ε ϨουηʔϑͰ͸ͳ͍ͨΊɺ͜ΕΒͷΫΤϦ͸όʔετίϯύΠϧͰ͖ͣɺϝΠϯεϨουͰ࣮ߦ͢ Δඞཁ͕͋Γ·͢ɻ DOTS αϙʔτ֎ϨΨγʔ Component Λ DOTS ʹ౉͍ͨ͠৔߹ɺGameObjectConversionSy stem.OnUpdate() ɹΛ࣮૷͠ GameObjectConversionSystem.AddHybridComponent ʹର৅ͷϨ Ψγʔ Component Λ༩͑Δ͜ͱͰ ECS ؀ڥͰ஋ͷมߋ͕Ͱ͖ΔΑ͏ʹͳΔͱ͍͏΋ͷͰ͢ɻ ECS ͷݺͼग़͠ํ Unity ࣮ߦ࣌ʹ System ΛಡΈࠐΉ৔߹ͷ System ࢦఆͷબ୒ࢶ • ࣗಈతʹશ ECS ͷ System Λ্ཱͪ͛Δ • ໌ࣔతʹࢦఆ System ͷΈΛࢦఆ্ཱͪ͛͢Δ͜ͱ΋Մೳʢ͕ͩ namespace റΓ΍ assemble ఆٛറΓͳͲͰબ୒తʹ։͘͜ͱ͕೉͍͠ʣ 61
  64. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ ໌ࣔతʹ্ཱͪ͛Δͱͨ͠৔߹ʹ֤छ package

    ͷશߏ଄Λ೺Ѳ͠ଓ͚ΔΘ͚ʹ΋͍͔ͣɺݱ࣮త ʹݱঢ়͸શಡΈࠐΈʹ଱͑ΒΕΔن໛ߏ଄Ͱ։ൃ͢Δ͜ͱʹͳΓ·͢ɻ Unity ࣮ߦ࣌ʹ World ΛಡΈࠐ·ͳ͍৔߹ͷ World ࡞੒εςοϓ • ໌ࣔతʹͱ͋ΔભҠͷஈ֊Ͱ World ͷੜ੒Λݺͼग़͢ • Convert ͷ࣮ߦΛ૸ΒͤΔͨΊ World Λੜ੒ͨ͠ͷͪ Scene ಡΈࠐΈΛ͢Δ • Convert ݺͼग़͞Ε͸֤ scene ಡΈࠐΈˍ Awake ޙͷ 1 ճͰ͋Δ͜ͱʹ஫ҙͯ͠ Entity ੜ ੒Λ࣮૷͢Δ • ήʔϜΛग़Δࡍʹ World Λ͢΂ͯഁغ͢Δʗ NetCode ͷ੾அΛ͢Δ System ୯ମ͕ World ʹొ࿥͞Εͯ΋ػೳ͠ͳ͍ઃܭͰ͸Δ͸ͣͰ͢ͷͰɺWorld ʹొ࿥͞Εͨ͋ ͱ Convert ͰҾ͖ۚͱͳΔ Entity ͱ Component Λొ࿥͍ͨ͠ɻެࣜαϯϓϧͰ͍͏ͱ͜Ζͷ Ini tGameComponent ͱ͍ͬͨϑϥάͷ໾ׂΛ͢Δ΋ͷΛੜ੒ͯ͠ System Λஈ֊తʹղ์ͤ͞·͢ɻ NetCode Ͱ͸ IRpcCommand ߏ଄ମͷσʔλΛ࡞ͬͯ௨஌ΛૹΔ SendRpcCommandRequestComponent ͱ೚ҙ IRpcCommand Λ Entity ʹ༩͓͑ͯ͘ͱ NetCode ͷ System ͕ऩू͠ɺϑϨʔϜͷऴΘΓʹૹ৴ͯ͘͠ΕΔΑ͏ʹͳ͍ͬͯ·͢ɻड৴ଆ΋ࣅͨΑ͏ ʹɺReceiveRpcCommandRequestComponent ίϯϙʔωϯτΛ؂ࢹ͢Δ͜ͱͰड৴σʔλΛνΣο Ϋ͍͖ͯ͠·͢ɻ·֤ͨΫϥΠΞϯτ 1 ਓʹ͖ͭ NetworkIdComponent ͕ 1 ͭ෇༩͞Ε͍ͯ· ͢ɻReceiveRpcCommandRequestComponent.SourceConnection ͷ Entity Λ GetSingleton() Ͱ Component ݕࡧ͢Ε͹ NetworkIdComponent ͕औಘͰ͖ΔͷͰ NetworkIdComponent.Value ͷϢʔβʔࣝผ ID ΛΈͯ୭ͷ௨৴͔Λ൑அ͍ͯ͘͠ͷͰ͢ɻ ߴ଎ԽΛૂͬͨฒྻॲཧΛಋೖ͢Δ ฒྻॲཧ͸͔ͬ͠Γܭըͯ͠ॲཧϑϩʔΛߟ͑ͳ͚Ε͹มߋ͕ফ໓͠·͢ɻ ϚϧνεϨουϓϩάϥϛϯά͸΍͍ͬͯ·͔͢ʁ DOTS ͱ JOB γεςϜͰ͍ͩͿΧδϡΞϧʹϚϧνεϨουͷϓϩάϥϛϯά͕Ͱ͖ΔΘ͚Ͱ͢ ͕ɺ͏·͘ઃܭ͓͔ͯ͠ͳ͚Ε͹σʔλͷڝ߹͕ىͬͯ͜σʔλͷୣ͍߹͍ʹΑͬͯยํͷεϨου Ͱͷ݁Ռ͔͠࢒Γ·ͤΜɻϚϧνεϨουͰϝΠϯεϨουҎ֎ͷ 1 εϨουʹಀͤ͹ྑ͍৔߹ͱɺ ฒྻʹෳ਺εϨουΛ࢖༻ͨ͠ํ͕ྑ͍৔߹ͱ 2 ௨Γ͋Γ·͢ɻͲͪΒͷॲཧ͕ద੾͔Λঢ়گΛݟͯ બ୒͠ɺޙऀͰ͋Ε͹ͦͷεϨουʹΑΔߋ৽தʹผεϨουͰಉҰ Component ͕ߋ৽͞Εͳ͍֬ ূ͕͋Δͷ͔Λݟ௚ͯ͠ݟ·͠ΐ͏ɻటপʹͳͬͨ৔߹ʹ͸ DOTS ͸͍ͭͰ΋ϝΠϯεϨουͰॲ ཧ͢Δ Enities.WithoutBurst().ForEach(...).Run() ʹॻ͖׵͑ͯಉظॲཧʹ͢Δબ୒ࢶΛ༩ ͑ͯ͘ΕΔͰ͠ΐ͏ɻ଎౓ͱҾ͖׵͑ʹɻ 62
  65. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ σʔλϑϩʔਤΛ࡞Δ͜ͱ͸ѹ౗తʹ࡞ۀઃܭίετΛԼ͛Δ ܁Γฦ͠ड़΂͖ͯͨΑ͏ɺͲ͜ͷ

    World ͰͲͷ Entity ͕Ͳ͜ͷ System ʹͳ͕Εͯʙ... ͱ͍͏͜ ͱ͕ෳࡶʹͳΓ΍͍͢ঢ়ଶͰ͢ɻࣗΒ͏·͘ࢥߟΛ੔ཧ͠ଓ͚Δ͜ͱ͕εϜʔζͳ։ൃʹ௚݁͠· ͢ɻͦͷͨΊৗʹɺύϫʔϙΠϯτͷΑ͏ͳ΋ͷͰɺͲͷ System ͕Կ Component Λϑϥάͱͯ͠ ݟ͍ͯΔͷ͔ʙͱ͍ͬͨ͜ͱΛਤղͰॻ͖ཹΊΔ͜ͱ͕ඞཁͰ͢ɻ ͱʹ͔͘ࢀরؔ܎͕ෳࡶʹͳΓ΍͍͢ ͱʹ͔͘ࢀরؔ܎͕ෳࡶʹͳΓ΍͍͢ͷͰɺECS ʹ༗ޮͳྑ͍ਤΛॻ͘ํ๏͕͋Ε͹ͥͻൃ৴͠ ͍͖͍ͯͨͩͨ΋ͷͰ͢ɻࢀߟͱͯ͠ࠓճͷ։ൃʹ͋ͨͬͯ࡞ͬͨϑϩʔਤΛܝࡌ͠·͢ɻ ਤ 4.1: ه๏ ʮه๏ʯͷ௨ΓɺMonoBehaviour ͱ ECS ͷ Client ͱ ECS ͷ Server ͷ 3 ΤϦΞͰ࣮૷͍ͯͨ͠ ͷͰ͜͏͍͏ܗͱͳ͍ͬͯ·͢ɻWorld ͕΋ͬͱଟ͍ͷͰ͋Ε͹֦ு͢Δ͜ͱʹͳΓ·͢ɻ ਤ 4.2: ࣮૷ྫ ʮ࣮૷ྫʯྫͷಡΈํ͸͋͑ͯઆ໌͠·ͤΜ͕ɺͶ͑... 63
  66. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ ͍͖ͳΓݟ౉ͯ͠࡞Εͳ͍ͷͰԿ౓͔࡞ΓࣺͯΑ͏ ·ͣ͸લهͷνϡʔτϦΞϧͱɺࣺͯϓϩδΣΫτΛ͍ͭ͘΋্ཱͪ͛ɺ࿅श։ൃʹணखͯ͠

    DOTS ࣮૷ײ֮ΛੵΉͷ͕݁ہޮՌతͰ͠ΐ͏ɻ͍·͞ΒجຊͳΘ͚Ͱ͕͢ɺ։ൃظؒͷ 6 ׂҎ্ Λαϯϓϧमಘ࣌ؒʹׂΓ౰ͯΔ͜ͱͰ༧ఆظؒ಺ʹֶश։͔࢝ΒϓϨΠձ·Ͱ౸ୡͰ͖ͨɺͱ͍͏ ͜ͱ͕࣮ࡍʹࢲ͕औΓ૊ΜͰಘΒΕͨޮՌతͳऔΓ૊ΈํͰͨ͠ɻ ECS σʔλͷ࡞Γํͱ஫ҙ఺ ˙1. Component Λ࡞੒͢Δ Entities.IComponentData Interface ͕ ECS ͷ Component Ͱ ͢ɻ೚ҙ Component Λ࡞੒͢Δ͜ͱ͔Β࢝·Γ·͢ɻ[GenerateAuthoringComponent] ଐੑΛ಄ ʹ͚ͭΔ͜ͱͰࣗಈతʹ ECS ʹ Convert ͯ͘͠ΕΔ MonoBehaviour ͕ੜ੒͞ΕɺϨΨγʔۭؒ ͷ GameObject ΠϯεϖΫλͰ AddComponent Ͱ͖ΔΑ͏ʹͳΓ ECS ͷ Component ͕ొ࿥Ͱ͖ ·͢ɻ Ϧετ 4.2: SampleComponent.cs 1: using Unity.Entities; 2: [GenerateAuthoringComponent] 3: public struct SampleComponent : IComponentData{} ˙2. Entity ม׵ͷ४උ ্هͰ࡞੒ͨ͠ ECS ͷ Component ͕͍ͭͨ GameoObject Λ ECS ม׵ ͢Δίϯόʔλʔ MonoBehaviour ͕ඞཁͰ͢ɻ͋ΔγʔϯʹͯಡΈࠐ·͍ͤͨ GameObject Λ഑ ஔ͠ɺECS ͷ Converter ͱͯ͠Քಇ͢Δ MonoBehaviour ίϯϙʔωϯτ Convert To Entity ΍ Sub Scene Λ GameObject ʹ෇͚Δ͜ͱͰͦͷ Object ҎԼ͕ࣗಈతʹ Entity ʹมΘΓ·͢ɻSub Scene Ͱ͸ͦͷ໊ͷࣔ͢௨ΓɺUnity ͷ Scene Λ Entity ʹ͠ࢠ֊૚ʹϩʔυ͢Δख๏Ͱɺผ Scene ্ʹ૊ΈཱͯͨҰ࿈ͷ GameObject ܊Λ͋Β͔͡Ί Entity ΁γϦΞϥΠζ͓͖ͯ͠ಡΈࠐ·ͤΔ΋ ͷͰ͢ɻSubScene ༻ʹผͷϓϩηεͰ࡞੒ͨ͠ Scene Ͱ͋Δඞཁ͕͋Γ·͢ɻ ਤ 4.3: Convert To Entity 64
  67. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ ਤ 4.4:

    Sub Scene ˙3. ΧελϚΠζͯ͠ Entity ม׵͢Δ ͋Δ͍͸ࣗ਎Ͱ࣮૷ͨ͠ Converter ͷ MonoBehaviour Λ ෇͚ͯม׵͢Δ৔߹΋͋Γ·͢ɻEntities.IConvertGameObjectToEntity Interface Λ࢖ͬͯ Co nvert Λ࣮૷͢Δ͜ͱͰίϯόʔτ࣌ʹͦΕҎ֎ͷม׵ɺͨͱ͑͹Α͘࢖͏΋ͷͱͯ͠ΠϯεϖΫλ ʹࢦఆ͢Δ Prefab ͱ Mesh ͷ Entity ม׵͕Ͱ͖·͢ɻ ޙड़ͷϦετ 4.3 ͸ɺConvert ͱ AwakeɺECS ͷ System ͰϩάΛు͘ςετίʔυͰ͢ͷͰࢀ ߟʹͯ͠Έ͍ͯͩ͘͞ɻ ਤ 4.5: convert tester ˙4. Convert ࣮ߦλΠϛϯάΛ͔ͭΉ Converter ͕࣮ߦ͞ΕΔλΠϛϯά͸ Scene ͕ݺͼग़ ͞Εͨ௚ޙɺAwake ͷޙͰ͢ɻىಈ Scene Ͱ͋Ε͹ىಈ௚ޙͰ͢ɻͦ͜Ͱ༗ޮͳ GameObject ͷ Converter ͕͋Ε͹ॳΊͯՔಇ͢Δɺͱ͍͏΋ͷͰ͢ɻ͜ͷλΠϛϯάΛཧղ͢Δͱશମͷܭը͕ε ϜʔζʹͳΓ·͢ɻ 65
  68. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ ਤ 4.6:

    ࣮ߦϩά ˙5. Convert λΠϛϯάΛίϯτϩʔϧ͢Δ ·ͨɺUNITY_DISABLE_AUTOMATIC_SYSTEM_BOOTS TRAP Λ playersetting Ͱ define ఆٛ͢Δͱ ECS ͷ Defalt World ͕࡞੒͞Εͳ͘ͳΓ·͢ɻͦͷ৔ ߹ Converter ΋Քಇ͠ͳ͘ͳΓ·͢ɻͦͷޙ Converter Λಈ͔͢ʹ͸खಈͰɺDefaultWorldInit ialization.Initialize(worldname, editorworld) Λݺͼग़ͯ͠ World Λ࡞੒ͨ͠ޙɺScene ΛಡΈࠐ·ͤΔඞཁ͕͋Γ·͢ɻ ˙6. SubScene Ͱ Convet ࡁΈ Entity Λݺͼग़͢ Sub Scene ͩͱ·ͨࣄ৘͕มΘΓ Convert ͕ݺ͹Ε·ͤΜɻEditor ্Ͱ SubScene Λ Edit ͷͨΊՄࢹʹ͍ͯ͠Δͱ౎౓ม׵͞Ε Convert ͕ ࣮ߦ͞Ε·͕͢ดͯ͡͠·͑͹ Convert ͠ऴΘͬͨঢ়ଶ͕γϦΞϥΠζ͞Εɺݺ͹Εͳ͘ͳͬͯ͠ ·͍·͢ɻConvert ʹ൐͍ GameObject ͱ MonoBehaviour ͸௨ৗഁغ͞Ε·͢ͷͰɺAwake ౳ͷ Monobehaviour ؔ਺΋࣮ߦ͞Ε·ͤΜɻ ਤ 4.7: ࣮ߦϩά Unity ͷ DOTS քʹ͸༻ޠͰϨΨγʔͱ ECS ͕ࠞಉ͠΍͍͢෦෼͕ଟ͘஫ҙ͕ඞཁͰ͢ɻ Component ͸ɺMonoBehaviour Ͱ΋ಉ໊Ͱ͢ͷͰɺECS ͷɺ΋͘͠͸ Entity ͷɺͱ෇͚͍ͯΔํ ͷΈ͕ DOTS ͷ΋ͷΛࢦ͠·͢ɻScene ͸ɺ Scene ͦͷ··ͩͱϨΨγʔͷ Scene Ͱ͕͢ɺ SubScene ͱ͍͏΋ͷ͸ɺผͷखଓ͖ʹΑͬͯ࡞੒͠γϦΞϥΠζͨ͠ Scene Λ Sub Scene MonoBehaviour ίϯϙʔωϯτͰࢀরͤͨ͞ಡΈࠐΈํ๏ɺ·ͨ͸γϦΞϥΠζͨ͠ SceneʢSubSceneʣͦͷ΋ͷΛ 66
  69. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Ε͹ྑ͍ͷ͔ ࢦ͠·͢ɻ ਤ

    4.8: New Sub Scene Ϧετ 4.3: ConverterTester.cs(Entity Converter αϯϓϧ) 1: // Converter 2: // SceneͷGameObjectʹ͋Β͔͡ΊAddComponent͍ͯͩ͘͠͞ 3: public class ConverterTester : MonoBehaviour, 4: IConvertGameObjectToEntity,IDeclareReferencedPrefabs 5: { 6: public void Convert(Entity entity, 7: EntityManager dstManager, 8: GameObjectConversionSystem conversionSystem) 9: { 10: Debug.Log($"ConverterTester / world name @" 11: +$"{dstManager.World.Name} {entity.Index} " 12: +$"{this.GetHashCode()}ɹ{this.GetType().Name}"); 13: dstManager.AddComponent<ConverterTesterComponent>(entity); 14: } 15: private void Awake() 16: { 17: Debug.Log("ConverterTester awake"); 18: } 19: } 20: // Component 21: public struct ConverterTesterComponent : IComponentData { } 22: // System 23: public class ConverterTesterSystem : SystemBase 67
  70. ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.9 ࠷ޙʹ 24: {

    25: protected override void OnUpdate() 26: { 27: Entities 28: .WithoutBurst() 29: .ForEach((Entity e, ConverterTesterComponent tester) => 30: { 31: Debug.Log($"tester {World.Name} {e.Index}"); 32: }).Run(); 33: } 34: } Converter ͸ MonoBehaviour ͔Β ECS ͷ World ʹσʔλΛૹΓࠐΉॲཧ Entity To Convert Ͱ͸ม׵࣌ʹ MonoBehaviour Λഁغ͢Δ͔ҡ࣋͢Δ͔બ୒Ͱ͖·͢ɻ௨ৗ ഁغΛߦ͍ɺ͢΂ͯͷ GameObject ͸ফ໓͠ ECS ͷ Entity ʹஔ͖׵࣮͑ͯ૷Λ͍ͯ͘͠΋ͷʹͳ Γ·͢ɻͨͩ͠ UnityEngine Ͱ͸͢΂͕ͯ DOTS ͰॲཧͰ͖ͳ͍ஈ֊Ͱ͢ͷͰɺϨΨγʔۭؒͰ࢖ ༻͢Δ΋ͷ͸࢒͞ͳ͚Ε͹ͳΓ·ͤΜɻCameraɺLightɺUIɺAudioɺParticle ͸௨ৗม׵͠·ͤΜɻ 4.9 ࠷ޙʹ ͋͞ DOTS ͱ ECS ͕͓͓ΑͦͲ͏͍͏Ґஔ෇͚ͰͲ͏ߟ͑Δ΋ͷͳͷ͔͕ݟ౉ͤͨͰ͠ΐ͏͔ɻ ޙ൒͸೉͕͠͞໨ཱͭهड़ʹͳ͍ͬͯ·͕ͨ͠ɺެࣜͷղઆಈըΛΈΔʹ Unity Technologies ࣾͷ ਓ͕ͨͪ͜ͷ DOTS ʹ͍ͨ΁ΜΤΩαΠςΟϯάͯ͠औΓ૊ΜͰ͍Δͷ͕ݟͯऔΕ·ͨ͠ɻචऀࣗ ਎΋ DOTS ςΫϊϩδͰߏஙͰ͖ͨޙɺΠςϨʔγϣϯͷྑ͞ɺ࣮૷ͷ෼཭ੑɺ଎౓ʹ͍ͭͯɺ͜ Ε·Ͱʹͳ͍ັྗͱ͓΋͠Ζ͞Λײ͍ͯ͡·͢ɻશମͷਖ਼ࣜϦϦʔε·Ͱ͸·ͩ౰෼͔͔ΔΑ͏Ͱ͢ ͕ɺऔΓ૊ΜͰͦͷҰ෦Λମײͯ͠ΈΔͱΤϯδχΞͱͯ͠΋ੈք͕·ͨ޿͕ΔΑ͏ͳؾ͕ͯ͠΍· ͳ͍ͷͰ͢ɻ ࢀߟ • Unity DOTS Technology – https://unity.com/ja/dots/packages – https://github.com/Unity-Technologies • ECS wikipedia – https://ja.wikipedia.org/wiki/ΤϯςΟςΟɾίϯϙʔωϯτɾγεςϜ 68
  71. ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ ຊষ͸ܦ࿏୳ࡧ͕ςʔϚͰ͢ɻܦ࿏୳ࡧ͸ɺ͋Δ஍఺͔Β͋Δ஍఺·ͰͷಓॱΛ୳͢ΞϧΰϦζϜ Ͱ͢ɻܦ࿏୳ࡧ͸͍Ζ͍Ζͳ෼໺ͰԠ༻͞Ε͍ͯ·͕͢ɺຊষͰ͸ήʔϜͷΩϟϥ΁ͷԠ༻͠·͢ɻ ࢲ͸ɺେઓུɺϑΝϛίϯ΢ΥʔζͳͲΛ༡ͼͳ͕ΒɺҠಈίετΛߟྀͨ͠ɺҠಈՄೳྖҬͷಛ ఆ͸Ͳ͏΍͍ͬͯΔΜͩΖ͏ʁ ͱࢥ͍ͬͯ·ͨ͠ɻࠓͳΒΘ͔Γ·͢ɺܦ࿏୳ࡧΞϧΰϦζϜͰٻ ΊΒΕ·͢ɻ

    ܦ࿏୳ࡧ͸ɺͪΐͬͱݡ͍ఢΩϟϥΛ࡞Δ࣌ʹศརͰ͢ɻ·ͨɺઓུήʔϜʹ͓͍ͯ͸ࠜװػೳͰ ͢ɻຊষ͕ɺܦ࿏୳ࡧͷཧղͷҰॿʹͳΕ͹޾͍Ͱ͢ɻ λʔήοτಡऀ ήʔϜΛ͍͔ͭ͘࡞ͬͨܦݧ͕͋ΓɺͦΖͦΖݡ͍ఢͷಈ͖Λ࡞ͬͯΈ͍ͨਓɻԿΒ͔ͷཧ༝Ͱ Unity ͷφϏϝογϡҎ֎ͷํ๏Λ୳͍ͯ͠Δਓɻ ॻ͘͜ͱ ܦ࿏୳ࡧͷجૅͰ͋ΔμΠΫετϥ๏ͱ A*Λઆ໌͠·͢ɻͦͷ͋ͱɺܦ࿏୳ࡧΛগ͠Ԡ༻͠·͢ɻ ΄΅ʮήʔϜ։ൃऀͷͨΊͷ AI ೖ໳ʯͷ 7 ষʮA*ΞϧΰϦζϜʹΑΔܦ࿏୳ࡧʯΛࢲ͕ Unity Ͱ ίʔυΛॻ͖ͳ͕Βֶशɺݕূͨ͠಺༰ʹͳΓ·͢ɻ ॻ͔ͳ͍͜ͱ ॲཧෛՙܰݮͳͲͷ࠷దԽʹ͍ͭͯ͸ॻ͖·ͤΜɻ 5.1 ήʔϜͷܦ࿏୳ࡧ ήʔϜͰ͸ఢΩϟϥ͕ಈ͖·͢ɻఢ͕ಈ͘ͱ͍͏͜ͱ͸ɺ޿͍ҙຯͰఢͷ AI Λ࡞ͬͨ͜ͱʹͳΓ ·͢ɻఢͷ AI Λ࡞ΔͱҰݴͰݴͬͯ΋ɺήʔϜʹΑͬͯͦͷ AI ͸ผ෺ʹͳΓ·͢ɻ֨ಆήʔϜɺ RTSɺFPSɺRPGɺΞΫγϣϯήʔϜ...ɺͦΕͧΕήʔϜͷϧʔϧͱ؀ڥ͕ҧ͍·͢ɻͦΕΒΛಉ 69
  72. ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.2 ܦ࿏୳ࡧΞϧΰϦζϜ ͡ AI Ͱಈ͔͢͜ͱ͸ɺݱঢ়ࠔ೉Ͱ͢ͷͰɺήʔϜʹ߹Θͤͨ AI

    Λ࡞੒͠·͢ɻ΋ͪΖΜɺۙ೥ͷ σΟʔϓϥʔχϯά΍ը૾ೝࣝͳͲ͕ͱͯ΋ൃల͍ͯ͠ΔͷͰɺকདྷ͸ͻͱͭͷ AI Ͱ࣮ݱ͞ΕΔ͔ ΋͠Ε·ͤΜɻήʔϜͰ͢ͷͰɺAI ͸ݱ࣮తͳ࣌ؒͰॲཧ͕ऴྃ͢Δඞཁ͕͋Γ·͢ɻ ࠷ۙͷήʔϜ͸ͱ΋͔͘ɺੲ͸ AI ͱ͍͏ʹ͸େ͛͞ͳ͘͝୯७ͳ͔͚͠Ͱಈ࡞͍ͯ͠·ͨ͠ɻ· ͨɺݱࡏͰ΋ɺఢΩϟϥ͸੡࡞ऀͷҙਤ௨Γʹಈ͘͜ͱ͕ୈҰͰ͢ɻͰ͖Δ͚ͩγεςϜΛγϯϓϧ ʹอͬͯɺҙਤΛදݱ͠΍͘͢ௐ੔͠΍͘͢࡞Δඞཁ͕͋Γ·͢ɻ Unity ͷܦ࿏୳ࡧ ۙ೥ɺݸਓͰ΋ձࣾͰ΋ήʔϜΛ࡞Δͱ͖ʹ͸ Unity Λ࢖༻͍ͯ͠·͢ɻUnity ʹ͸ܦ࿏୳ࡧͷػ ೳͰ͋ΔφϏήʔγϣϯγεςϜؚ͕·Ε͍ͯ·͢ɻͦΕ͸ɺ3D ͷΦϒδΣΫτΛ഑ஔͨ͠΋ͷ͔ ΒɺࣗಈతʹφϏϝογϡΛੜ੒͠·͢ɻ·ͨɺΤʔδΣϯτ͕φϏϝογϡΛ࢖༻ͯ͠ɺ໨త஍· Ͱ࠷୹ܦ࿏ͰҠಈ͠·͢ɻΤʔδΣϯτ͸ɺͦΕͧΕ͕ॏͳΒͳ͍Α͏ʹҠಈ͠·͢ɻ·ͨɺಈతʹ ো֐෺ͷ௥Ճ΍࡟আ΋Ͱ͖·͢ɻܦ࿏୳ࡧ͸ෛՙͷߴ͍ॲཧͳͷͰ͕͢ɺඇಉظͰܭࢉͯ͘͠ΕΔͷ ͰɺήʔϜ͕ݻ·Δ͜ͱ͸͋Γ·ͤΜɻ ͳͥɺܦ࿏୳ࡧΛࣗ࡞͍ͨ͠ͷ͔ Unity ͷφϏϝογϡͷ།Ұʹͯ͠࠷େͷܽ఺͸ɺϒϥοΫϘοΫεͰ͋Γ༥௨͕ޮ͔ͳ͍͜ͱ Ͱ͢ɻΩϟϥͷҠಈܦ࿏͕௨ৗͷ࠷୹ܦ࿏͚ͩͳΒϒϥοΫϘοΫεͰ΋໰୊͋Γ·ͤΜɻ͔͠͠ɺ ΩϟϥͷҠಈܦ࿏͕ΩϟϥͷݸੑͰ͋Γɺࡉ͔ͳΧελϚΠζ͕ඞཁͳ৔߹ɺϒϥοΫϘοΫεͰ͸ ߦ͖٧·ͬͯ͠·͍·͢ɻ ·ͨɺۙ೥αʔόαΠυͰΩϟϥͷ AI ΍ήʔϜͷਐߦΛ੍ޚ͍ͤͨ͞৔߹͕૿͍͑ͯ·͢ɻαʔ όαΠυͰήʔϜͷϩδοΫΛಈ࡞ͤ͞Δͱɺνʔτߦҝʹڧ͘ͳΔ͜ͱ΍ɺ௨৴ͷϥάΛܰݮͰ͖ Δ͜ͱ͕ظ଴Ͱ͖·͢ɻ աڈͷϓϩδΣΫτͰɺࢼ࡞ஈ֊Ͱ Unity ͷφϏήʔγϣϯΛ࢖༻ͯ͠ಈ͍͍ͯͨΩϟϥͷ AI ΛɺαʔόͰಈ࡞ͤ͞Δ͜ͱʹ͠·ͨ͠ɻͦͷͱ͖ʹɺαʔόαΠυͰ AI ͷҰ෦Ͱ͋Δܦ࿏୳ࡧ΋ ࣮ߦ͔ͤͨͬͨ͞ͷͰ͕͢ɺεέδϡʔϧͷ౎߹΋͋Γɺ݁ہΫϥΠϯτͰܦ࿏୳ࡧΛߦͬͯͦͷ݁ ՌΛ֤୺຤ʹૹ৴͠·ͨ͠ɻۤ೑ͷࡦͩͬͨͷͰɺઃܭͱͯ͠͸͍ͼͭͳܗͰͨ͠ɻͦ͏͍͏ܦݧ΋ ͋Γܦ࿏୳ࡧΛ਎ʹ͚ͭΑ͏ͱࢥ͍·ͨ͠ɻ 5.2 ܦ࿏୳ࡧΞϧΰϦζϜ ܦ࿏୳ࡧͰ༗໊ͳͷ͸μΠΫετϥ๏ͱ A*(Τʔελʔ) Ͱ͢ɻμΠΫετϥ๏͸઀ଓ఺Λ૯౰ͨ ΓͰ୳ࡧ͠·͢ɻA*͸μΠΫετϥ๏Λվྑͨ͠΋ͷͰɺώϡʔϦεςΟοΫؔ਺ͱ͍͏ίϯύε ͷΑ͏ͳ΋ͷΛ࢖ͬͯɺྑͦ͞͏ͳ఺͔Βॱʹ୳ࡧ͠·͢ɻWikipedia ͷμΠΫετϥ๏*1ͱɺA**2 *1 http://ja.wikipedia.org/w/index.php?curid=28019 *2 http://ja.wikipedia.org/w/index.php?curid=157096 70
  73. ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.2 ܦ࿏୳ࡧΞϧΰϦζϜ ʹΞϧΰϦζϜ͕ࡌ͍ͬͯ·͢ɻਖ਼௚ɺࢲ͸ͦΕΒΛಡΜͰ΋ҿΈࠐΊͣɺίʔυʹམͱ͠ࠐΊ·ͤ ΜͰͨ͠ɻͦͷޙɺ ʮήʔϜ։ൃऀͷͨΊͷ AI

    ೖ໳ʯ ʢҎԼ AI ೖ໳ʣͷ 7 ষʮA*ΞϧΰϦζϜʹΑ Δܦ࿏୳ࡧʯΛಡΜͰཧղͰ͖·ͨ͠ɻ ཁૉͷઆ໌ ΞϧΰϦζϜͷઆ໌ʹೖΔલʹཁૉͷ໊લͱҙຯΛఆٛ͠·͢ɻ • ϑΟʔϧυ – ελʔτ:୳ࡧͷ։࢝఺Ͱ͢ɻ – ΰʔϧ:୳ࡧͷऴྃ఺Ͱ͢ɻ – น:௨Εͳ͍఺Ͱ͢ɻ – ಓ:௨ΕΔ఺Ͱ͢ɻίετΛ࣋ͪ·͢ɻ – ఢ:ڴҖ஋Λܭࢉ͢Δͱ͖ͷى఺ͱͳΓ·͢ɻ ਤ 5.1 ͸ɺ୳ࡧͷର৅Ͱ͋ΔϑΟʔϧυϚοϓͰ͢ɻࠨԼʹελʔτ͕͋Γɺӈ্ʹΰʔϧ͕͋Γ ·͢ɻͦͷؒʹϒϩοΫ͕͋Γ·͢ɻ ਤ 5.1: ϑΟʔϧυϚοϓ ௖఺ͱล ຊདྷɺμΠΫετϥ๏΍ A*͕ର৅ͱ͢Δͷ͸άϥϑͰ͢ɻάϥϑ͸ɺ௖఺ͱลͰఆٛ͞Ε·͢ɻ ลʹ͸ϚΠφεͰ͸ͳ͍ॏΈΛ΋ͨͤΒΕ·͢ɻϚΠφεΛ࣋ͭ৔߹͸ผͷΞϧΰϦζϜ (ϕϧϚϯ rϑΥʔυ๏ ) Λ࢖༻͢Δඞཁ͕͋Γ·͢ɻ ࠓճͷ୳ࡧର৅Ͱ͋ΔϑΟʔϧυ͸ɺήʔϜʹ࢖͍΍͍͢Α͏ʹάϦουϚοϓΛ 2 ࣍ݩ഑ྻͰද ݱ͠·͢ɻ௖఺͸ɺ͜ͷάϦουϚοϓͷηϧͰ͢ɻล͸ɺηϧʹྡ઀͢Δ 8 ݸͷηϧͷؒʹ͋Δͱ ఆٛ͠·͢ɻลͷॏΈ͸ɺྡ઀͢Δηϧʹίετͱͯ͠΋ͨͤ·͢ɻ 71
  74. ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.2 ܦ࿏୳ࡧΞϧΰϦζϜ μΠΫετϥ๏ ͬ͘͟Γ͍͏ͱɺ։࢝఺͔Βͦͷपғ΁ͷҠಈίετΛܭࢉͯ͠ɺͦͷίετͷ࠷খͷ఺ΛબΜ Ͱɺͦͷ఺͔ΒͦͷपғͷίετΛܭࢉͯ͠ɺͦΕΒΛΰʔϧ͕ݟ͔ͭΔ·Ͱ܁Γฦ͠·͢ɻΰʔϧ ͕ݟ͔ͭͬͨΒɺΰʔϧ͔Βٯॱʹελʔτ·ͰͨͲͬͯɺܦ࿏ʹ͠·͢ɻ͢΂ͯͷ఺Λܭࢉͭ͘͠

    ͨ͠Βΰʔϧͳ͠ͱͯ͠ऴྃ͠·͢ɻ μΠΫετϥ๏ͷৄࡉΛઆ໌͢Δલʹɺਤ 5.2 Λݟ͍ͯͩ͘͞ɻ ਤ 5.2: μΠΫετϥ๏ ͜Ε͸ɺਤ 5.1 ͷϑΟʔϧυϚοϓΛμΠΫετϥ๏Ͱܦ࿏୳ࡧͨ݁͠ՌͰ͢ɻͦΕͧΕͷάϦο υϚοϓΛઆ໌͠·͢ɻ • State : ௖఺ͷঢ়ଶͰ͢ɻৄࡉ͸ޙड़͠·͢ɻ • Cost : ελʔτ͔Βͦͷ఺ʹ౸ୡ͢Δ·ͰͷҠಈίετͰ͢ɻڑ཭ͷ߹ܭ஋Ͱ͢ɻ • Before : ͦ͜ʹࢸΔ௚લͷҐஔͰ͢ɻࠨԼ͕ (0,0) Ͱ͢ɻ͜Ε͸ܦ࿏Λ࡞Δͱ͖ٯॱ͢Δͱ͖ ʹ࢖༻͠·͢ɻ • Path : ελʔτ͔Βΰʔϧ·Ͱͷܦ࿏Ͱ͢ɻ ௖఺ (ηϧ) ͷঢ়ଶʹ͍ͭͯઆ໌͠·͢ɻ௖఺ͷঢ়ଶ͸ 4 ͭ͋Γ·͢ɻ • ॳظঢ়ଶ (Init) : ܭࢉલͷॳظঢ়ଶͰ͢ɻ৘ใ͸͋Γ·ͤΜɻ • Φʔϓϯ (Open) : ܭࢉͷ్தͰ͢ɻޙͷܭࢉͰ஋্͕ॻ͖͞ΕΔ৔߹͕͋Γ·͢ɻ • Ϋϩʔζ (Close) : ܭࢉࡁΈͰ͢ɻ֤छ৘ใ͸֬ఆ͍ͯ͠·͢ɻ • ϒϩοΫ (Block) : ௨Εͳ͍ͷͰܭࢉ͠·ͤΜɻ ลͷॏΈͰ͋ΔҠಈίετ͸ɺڑ཭ͱ͠·͢ɻ্ԼࠨӈΛ 1 ͱ͠ɺࣼΊΛ 1.4(˺˽ 2) ʹ͠·͢ɻ ͦΕͰ͸ɺμΠΫετϥ๏ͷΞϧΰϦζϜΛઆ໌͠·͢ɻ 1. ͢΂ͯͷ௖఺Λॳظঢ়ଶʹ͠·͢ɻ[State = Init, Cost = 0, Before = (0,0)] 2. ελʔτΛର৅఺ͱ͠·͢ɻ 3. ର৅఺ΛΫϩʔζʹ͠·͢ɻ 4. ର৅఺ͷपғ 8 ݸͷ఺Λ઀ଓ఺ͱ͠·͢ɻ 72
  75. ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.2 ܦ࿏୳ࡧΞϧΰϦζϜ 5. ઀ଓ఺ͷঢ়ଶΛΦʔϓϯʹ͠·͢ɻ 6. ઀ଓ఺ͷίετΛܭࢉͯ͠ɺه࿥͠·͢ɻ(઀ଓ఺ͷίετ=ର৅఺ͷίετ

    + Ҡಈίετ) 7. ઀ଓ఺ͷ௚લͷҐஔ (Before) ʹର৅఺Λه࿥͠·͢ɻ 8. Φʔϓϯͷ఺͔Βɺίετ͕࠷খͷ఺ΛબΜͰର৅఺ʹ͠·͢ɻ 9. ର৅఺͕ΰʔϧʹͳΔ͔ɺΦʔϓϯ఺͕ͳ͘ͳΔ·Ͱɺ3 ʹ໭ͬͯ܁Γฦ͠·͢ɻ 10. ΰʔϧʹ౸ୡͨ͠Βɺ௚લͷҐஔ (Before) Λٯॱʹελʔτ·ͰͨͲͬͯܦ࿏ (Path) ͱ͠ ·͢ɻ 11. Φʔϓϯ఺͕ͳ͘ͳͬͨ৔߹͸ɺ౸ୡෆՄೳͳͷͰܦ࿏͸͋Γ·ͤΜɻ A*(A-Star, Τʔελʔ) A*͸μΠΫετϥ๏ͷܭࢉྔΛݮΒͨ͢Ίʹվྑͨ͠΋ͷͰ͢ɻܭࢉྔΛݮΒͨ͢Ίʹɺίϯύ εͷΑ͏ʹਐΉ΂͖ํ޲Λࣔ͢ʮώϡʔϦεςΟοΫؔ਺ʯΛ࢖༻͠·͢ɻώϡʔϦεςΟοΫؔ਺ ͕ର৅ͱ͏·͘טΈ߹͍ͬͯΕ͹ɺܭࢉྔ͕͙ͬͱݮΓ·͢ɻ͜ͷྫͰ࢖༻͢ΔώϡʔϦεςΟο Ϋؔ਺͸ɺҾ਺ͷ఺͔Βΰʔϧ΁ͷڑ཭Λฦ͠·͢ɻ͜ͷ৔߹ɺΰʔϧͱͷڑ཭͕খ͘͞ͳΔํ޲ʹ ʮ࠷୹ܦ࿏͕͋Γͦ͏ʯͱ͍͏ҙຯʹͳΓ·͢ɻ ΋͠ɺώϡʔϦεςΟοΫؔ਺͕୳ࡧର৅ͱטΈ߹͍ͬͯͳ͍৔߹ɺܭࢉྔ͸ɺμΠΫετϥ๏ʹ ώϡʔϦεςΟοΫؔ਺ͷܭࢉ෼௥Ճͨ͠΋ͷʹͳΓ·͢ɻ A*ͷΞϧΰϦζϜ͸ɺઌͷμΠΫετϥ๏ͷ 8 ൪໨Λॻ͖׵͑ͨ΋ͷʹͳΓ·͢ɻ ʮΦʔϓϯͷ఺ ͔ΒɺίετͱώϡʔϦεςΟοΫؔ਺ͷ߹ܭ஋͕࠷খͷ఺ΛબΜͰର৅఺ʹ͠·͢ɻ ʯ ਤ 5.1 Λ A*Ͱ୳ࡧͨ݁͠Ռ͕ਤ 5.3 ʹͳΓ·͢ɻ • Huristic : ώϡʔϦεςΟοΫؔ਺ͷ஋Ͱ͢ɻ ਤ 5.3: A* μΠΫετϥ͸΄΅ϚοϓશମΛ୳ࡧ͍ͯͨ͠ͷʹൺ΂ͯɺA*͸ϒϩοΫΛආ͚Δ෼͚ͩܭࢉΛ ͓ͯ͠Γɺܭࢉྔ͕ݮ͍ͬͯΔͷ͕Θ͔Γ·͢ɻݫີʹ͸ϓϩϑΝΠϧΛͱΔඞཁ͕͋Γ·͢ɻ΋͠ ͔͢ΔͱɺώϡʔϦεςΟοΫؔ਺͕ॏ͍͔΋͠Ε·ͤΜ͕ɺA*͸ɺͦΕ͸े෼͍ܰͱ͍͏લఏ͕ ͋Γ·͢ɻ 73
  76. ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.3 ܦ࿏୳ࡧͷԠ༻ 5.3 ܦ࿏୳ࡧͷԠ༻ ࠷୹ܦ࿏ΛٻΊΔ͜ͱ͕Ͱ͖ͨͷͰɺԠ༻͠·͢ɻμΠΫετϥ๏΋ A*΋ɺ࠷୹ܦ࿏Λݟ͚ͭ·

    ͢ɻ ʮ࠷୹ʯͰ͢ͷͰɺ͍ۙҐஔʹ͍ΔΩϟϥ͸΄΅ಉ͡ܦ࿏ΛͨͲΓ·͢ɻଟগඇޮ཰ͳܦ࿏Ͱ΋ɺ όϦΤʔγϣϯ͕๛͔ʹ͍ͨ͠৔߹Λߟ͑·͢ɻ ΞϧΰϦζϜͰ͸ͳ͘ೖྗΛม͑Δ ܦ࿏ͷόϦΤʔγϣϯΛ࡞Ζ͏ͱߟ͑ͨͱ͖ɺ࠷ॳ͸ΞϧΰϦζϜΛमਖ਼͠Α͏ͱ͠·ͨ͠ɻ͔͠ ͠ɺͦͷΞϓϩʔνͰ͸Կ΋࣮ݱͰ͖·ͤΜͰͨ͠ɻ ͋Δͱ͖ɺೖྗΛมԽͤ͞Ε͹͓ͷͣͱ݁Ռ͕มΘΔ͜ͱʹؾ෇͖·ͨ͠ɻΞϧΰϦζϜ͸࠷୹ܦ ࿏Λ୳͢··Ͱ͕͢ɺ࠷୹Λఆٛ͢ΔίετϚοϓΛมԽͤ͞·͢ɻ ϥϯμϜ஋ΛίετʹՃࢉ ͜͜·Ͱͷίετ͸ڑ཭Ͱ͋Γɺ্Լࠨӈ͸ 1ɺࣼΊ͸ 1.4 ͱ͍ͯ͠·ͨ͠ɻ͜ΕʹΏΒ͗Λ΋ͨ ͤ·͢ɻ·ͣϑΟʔϧυίετϚοϓΛ௥Ճ͠·͢ɻ͜ͷϚοϓʹ 1ʙ3 ͷϥϯμϜ஋Λ͍Ε·͢ɻ ͦͯ͠ɺίετͷܭࢉ࣌ʹͦͷ஋Λ্Լ͸ʷ 1 ഒɺࣼΊ͸ʷ 1.4 ഒʹͯ͠ɺA*ΛదԠ͠·͢ɻͦͷ ݁Ռ͸ɺਤ 5.4 Ͱ͢ɻܦ࿏ʹόϦΤʔγϣϯ͕Ͱ͖·ͨ͠ɻΞϧΰϦζϜ͸࠷୹ܦ࿏ΛٻΊ͍ͯ·͢ ͕ɺͦͷίετ͕༳Β͙͜ͱͰܦ࿏ʹհೖͰ͖·ͨ͠ɻ ਤ 5.4: ج४ίετʹΏΒ͗Λ༩͑Δ 74
  77. ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.4 ·ͱΊ ڴҖ஋ΛίετʹՃࢉ ΋͏গ͠ݡ͍ܦ࿏ΛٻΊ·͢ɻةͳ͍৔ॴ͔Βڑ཭ΛͱΔ͜ͱͰɺ࠷୹Ͱ͸ͳ͍͚ΕͲ΋ɺ҆શͳ ܦ࿏ͰҠಈ͢ΔఢΛߟ͑·͢ɻઌ΄ͲϥϯμϜͷ஋ΛೖΕ͍ͯͨϑΟʔϧυίετϚοϓʹɺࠓ౓͸ ڴҖ౓ΛೖΕ·͢ɻڴҖ౓͸ఢ

    (Enemy) ʹ͍ۙ΄Ͳ஋͕େ͖͘ (2) ͳΓɺ཭ΕΔ΄Ͳখ͘͞ (1) ͳ Γ·͢ɻ ͜ͷܭࢉ݁Ռ͕ਤ 5.5 Ͱ͢ɻڴҖ (Enemy) Λආ͚ͨܦ࿏ʹͳΓ·ͨ͠ɻ ਤ 5.5: ڴҖϚοϓΛߟྀͨ͠ܦ࿏ 5.4 ·ͱΊ ༗໊ͳܦ࿏୳ࡧͰ͋ΔɺμΠΫετϥ๏ͱɺA*Λ࣮૷ͯ͠ɺͦͷڍಈΛ֬ೝ͠·ͨ͠ɻAI ೖ໳Λ ಡΜͰཧղͨͭ͠΋Γʹͳ͍ͬͯͯ΋ɺ͍͟ίʔυΛॻ͜͏ͱࢥ͏ͱཧղͷ଍Γͳ͍ͱ͜Ζ͕ු͖ூ ΓʹͳΓ·͢ɻ౰વͰ͕͢ɺࡉ͔͍఺·Ͱཧղ͠ͳ͍ͱίʔυ͸׬੒͠·ͤΜɻखΛಈ͔͢ॏཁੑΛ ࠶֬ೝ͢Δ͜ͱʹͳΓ·ͨ͠ɻ·ͨɺUnity Ͱखܰʹ݁ՌΛදࣔͰ͖ͨͷͰɺΞϧΰϦζϜͷݕূ͕ ༧૝Ҏ্ʹεϜʔζʹߦ͑·ͨ͠ɻ ຊষͰܦ࿏୳ࡧΛςʔϚʹબΜͩͷ͸ɺݸਓతʹ RTS Λ࡞Ζ͏ͱاը͍ͯ͠Δ͔ΒͰ͢ɻܦ࿏୳ ࡧ͸ήʔϜͷࠜװ෦෼ʹͳΔͷͰɺҰ౓͔ͬ͠Γͱֶश͠Α͏ͱࢥ͍·ͨ͠ɻͰ͖Ε͹ɺήʔϜͷϓ ϩτλΠϓͷ࡞੒·ͰͨͲΓண͖͔ͨͬͨͷͰ͕͢ɺ࢒೦ͳ͕Βؒʹ߹͍·ͤΜͰͨ͠ɻ 5.5 ͓·͚ ࢥ͍͍ͭͨ΋ͷͷݕূ͕ؒʹ߹Θͳ͔ͬͨΞΠσΞͰ͢ɻ ෳ਺ͷλʔήοτ ະݕূͰ͢ɻ ʮෳ਺ͷఢ͕͍ͯɺ͍ۙఢʹ޲͔͏ʯ৔߹ɺA*͸࢖͑ͳ͍͜ͱʹؾ෇͖·ͨ͠ɻෳ਺ ͷ໨త஍͕͋Δͱɺ͏·͘ώϡʔϦεςΟοΫؔ਺ΛఆٛͰ͖ͳ͍͔ΒͰ͢ɻͲ͏΍Βɺ۪௚ʹμΠ 75
  78. ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.6 ࢀߟ Ϋετϥ๏Ͱൃݟͨ͠ఢʹ޲͔͏͔͠ͳͦ͞͏Ͱ͢ɻ ؒ઀߈ܸΩϟϥͷܦ࿏ ະݕূͰ͢ɻؒ઀߈ܸͱ͸ɺͨͱ͑͹์෺ઢʹඈͿٷ໼ͷΑ͏ʹɺࣗ෼ͱఢͷؒʹো֐෺͕͋ͬͯ ΋౰ͨΔ߈ܸͰ͢ɻૉ௚ʹఢͷҐஔʹ޲͔͏ͱɺো֐෺ΛڬΜͰ҆શͳҐஔ͔Β߈ܸՄೳͱ͍͏༏Ґ

    ੑ͕ࣦΘΕ·͢ɻͦͷͨΊ໨త஍Λɺఢʹؒ઀߈ܸ͕ಧ͘શ஍఺ʹઃఆ͠·͢ɻো֐෺ΛڬΜͩํ͕ ༗རͰ͢ͷͰɺઌʹͷ໨త஍ͱఢͷؒʹো֐෺͕͋Δू߹Λ୳ࡧ͠·͢ɻݟ͔ͭΒͳ͚Ε͹ɺো֐෺ ͕ͳ͍ํ΋ௐ΂·͢ɻ 5.6 ࢀߟ •ʮήʔϜ։ൃऀͷͨΊͷ AI ೖ໳ʯ *3 • WikipediaʮμΠΫετϥ๏ʯ *4 • WikipediaʮA*ʯ *5 *3 https://www.oreilly.co.jp/books/4873112168/ *4 http://ja.wikipedia.org/w/index.php?curid=28019 *5 http://ja.wikipedia.org/w/index.php?curid=157096 76
  79. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.1 ࢝Ίʹ ຊষͰ͸ɺUnity

    Λ༻͍ͯήʔϜ։ൃΛ͍ͯ͠ΔํΛର৅ʹɺUnity ͷ Navigation Λར༻͢Δ্ Ͱߟ͑Δ΂͖͜ͱ΍׆༻ྫʹ͍ͭͯड़΂·͢ɻNavigation ͸࣮ࡍʹ࢖ͬͯॳΊͯؾ෇͘ཁૉ͕͋ͬ ͨͷͰɺͦΕ΋ަ͓͑ͭͭ఻͑͠·͢ɻ લ൒Ͱ͸ Navigation ͷجຊతͳ৘ใ΍஫ҙ఺Λɺޙ൒Ͱ͸ϑϩοΩϯάΞϧΰϦζϜΛ૊Έ߹Θ ͤͨԠ༻ྫΛ঺հ͠·͢ɻ 6.2 Navigation ͷجຊ ֓ཁ Unity ʹ͸ Navigation ͱ͍͏ܦ࿏Ϛοϓͷ࡞੒ͱܦ࿏୳ࡧͷͨΊͷػೳ͕͋ΓɺΩϟϥΫλΛ໨ త஍ʹ༠ಋ͍ͤͨ͞৔߹ʹ࢖༻͠·͢ɻNavigation ͷओཁͳ༻ޠʹ NavMesh ͱ NavMeshAgent ͕ ͋Γ·͢ɻ NavMesh ͸ɺγʔϯ্ʹ͋ΔΦϒδΣΫτͷচ໘ʹ߹Θͤͯੜ੒͞ΕΔϝογϡͰ͢ɻೋ఺ؒͷ ࠷୹ܦ࿏ͷܭࢉ΍ɺNavMeshAgent ͷҠಈʹ࢖༻͞Ε·͢ɻ NavMeshAgent ͸ɺΦϒδΣΫτΛ NavMesh ͷද໘ʹԊͬͯҠಈͤ͞ΔͨΊͷίϯϙʔωϯτ Ͱ͢ɻSetDestination() Ͱ໨ඪ஍఺Λࢦఆ͢ΔͱࣗಈͰ࠷୹ܦ࿏ΛҠಈ͠·͢ɻ NavMesh ͷ࡞੒΍جຊతͳૢ࡞ͳͲ͸ Unity ͷϚχϡΞϧ*1Λ͝ཡ͍ͩ͘͞ɻ ΦϒδΣΫτͷҠಈํ๏ΛܾΊΔ Unity ʹ͸ Rigidbody ΍ Animator ͳͲɺΦϒδΣΫτΛҠಈͤ͞Δػೳ͸͍͔ͭ͋͘Γ·͕͢ɺ NavMeshAgent ΋ͦͷͻͱͭͰ͢ɻUnity ͷϚχϡΞϧʹهࡌ͞Ε͍ͯΔΑ͏ʹ*2ɺҠಈΛߦ͏ػ ೳ͕ෳ਺͋Δͱڝ߹ͯ͠ҙਤ͠ͳ͍ಈ͖ʹͳΔͨΊɺ஫ҙ͕ඞཁͰ͢ɻ *1 https://docs.unity3d.com/ja/current/Manual/Navigation.html *2 https://docs.unity3d.com/ja/current/Manual/nav-MixingComponents.html 77
  80. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.2 Navigation ͷجຊ

    ͨͱ͑͹ɺNavMeshAgent ͱ Rigidbody Λ༗ޮʹ͢Δͱɺ྆ํ͕ҠಈॲཧΛߦͬͯ͠·͍ਖ਼͘͠ ಈ͖·ͤΜɻͦͷͨΊɺͲͪΒͷίϯϙʔωϯτͰҠಈͤ͞Δ͔ΛܾΊ͓ͯ͘ඞཁ͕͋Γ·͢ɻ ෺ཧతͳಈ͖͕ෆཁͳήʔϜͷ৔߹͸ɺNavMeshAgent ͷΈΛΞλον͢Δͱྑ͍Ͱ͢ɻຊॻͰ ͸ͪ͜Βͷํ਑ͰਐΊ·͢ɻܦ࿏୳ࡧΛͭͭ͠෺ཧతͳڍಈ΋͍ͤͨ͞ήʔϜͷ৔߹͸޻෉͕ඞཁͰ ͢ɻͨͱ͑͹ɺҎԼͷΑ͏ͳํ๏͕ߟ͑ΒΕ·͢ɻ • NavMeshAgent ͱ Rigidbody ΛΞλον͠ɺRigidbody ͷ isKinematic Λ true ʹ͠·͢ɻ ʢ΄͔ͷ෺ମΛԡ͠ͷ͚ͳ͕ΒਐΈ·͕͢ɺຊਓ͸෺ཧతʹඈΜͩΓ௓ͶͨΓ͢Δ͜ͱ͸Ͱ͖ ·ͤΜɻ ʣ • Rigidbody ͷΈΛΞλον͠ɺNavMesh.CalculatePath() Ͱܦ࿏Λऔಘ͠·͢ɻܦ࿏ʹԊͬ ͯ Rigidbody Λಈ͔͠·͢ɻ • NavMeshAgent ͱ Rigidbody ΛΞλον͠ɺNavMeshAgent ͷ isStop Λ true ʹ͠·͢ɻ steeringTarget ʹ޲͔ͬͯ Rigidbody Λಈ͔͠·͢ɻ ҎԼ͸ 3 ൪໨ͷྫͷ؆୯ͳ࣮૷Ͱ͢ɻ Ϧετ 6.1: AgentWithRigidbody.cs public class AgentWithRigidbody : MonoBehaviour { private NavMeshAgent _agent; private Rigidbody _rigidbody; private void Start() { _agent = GetComponent<NavMeshAgent>(); _agent.isStopped = true; _agent.SetDestination(new Vector3(0, 0, 0)); _rigidbody = GetComponent<Rigidbody>(); } private void FixedUpdate() { var direction = (_agent.steeringTarget - _rigidbody.position).normalized; _rigidbody.AddForce(direction * 5.0f); } } ܦ࿏୳ࡧͷ͘͠Έ A*ͱ͍͏୳ࡧΞϧΰϦζϜΛ࢖༻͠ɺNavMesh ্ͷྡ઀͢ΔϙϦΰϯΛͨͲͬͯ࠷୹ܦ࿏ΛٻΊ ͍ͯΔΑ͏Ͱ͢*3ɻ͢΂ͯͷϙϦΰϯΛௐࠪ͢ΔΘ͚Ͱ͸͋Γ·ͤΜ͕ɺNavMesh ͷܗঢ়ʹΑͬͯ *3 https://docs.unity3d.com/ja/Manual/nav-InnerWorkings.html 78
  81. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻

    ͸ଟ͘ͷௐ͕ࠪඞཁʹͳΔ৔߹΋͋Γ·͢ɻ NavMeshAgent ͷ SetDestination() ͸ඇಉظͰ࣮ߦ͞Εɺ1 ϑϨʔϜ͋ͨΓʹௐࠪͰ͖Δճ਺͸ NavMesh.pathfindingIterationsPerFrame ͰઃఆͰ͖·͢*4ɻ NavMeshAgent Λܦ࿏୳ࡧҎ֎Ͱ΋࢖͏ ࣮͸ NavMsehAgent ͷ velocity ͸֎෦͔ΒมߋͰ͖·͢ɻϢʔβʔͷೖྗͳͲʹΑͬͯ velocity Λมߋ͢Ε͹ɺεςʔδͷ֎ʹམͪΔ৺഑ͳࣗ͘༝ʹҠಈͰ͖·͢ɻ ن໛͕େ͖͘ͳͬͨࡍʹൃੜ͢Δ໰୊ͱͦͷղܾࡦ NavMesh ͕େ͖͘ͳͬͨΓ NavMeshAgent ͕ଟ͘ͳΔͱɺશମͷܦ࿏୳ࡧͷܭࢉྔ͕૿͑ͯ͠ ·͍·͢ɻ͜ͷͱ͖ɺҎԼͷΑ͏ͳ໰୊͕૝ఆ͞Ε·͢ɻ • NavMeshAgent.SetDestination() Λ࣮ߦ͔ͯ͠ΒΤʔδΣϯτ͕ಈ͖ग़͢·Ͱʹ͕࣌ؒ૿Ճ ͠·͢ɻ(ϑϨʔϜϨʔτ͸௿Լ͠·ͤΜ) • NavMesh.CalculatePath() ͷෛՙ্͕͕ΓɺϑϨʔϜϨʔτ͕௿Լ͠·͢ɻ ؆୯ͳղܾࡦ͸ɺSetDestination() ΍ CalculatePath() Λݺͼग़͢ස౓ΛݮΒ͢͜ͱͰ͢ɻͨͱ͑ ͹ɺ໨ඪ஍఺͔Β͍ۙΤʔδΣϯτ͸ස౓Λଟ͘ɺԕ͍ΤʔδΣϯτ͸ස౓Λগͳ͘͠·͢ɻ SetDestination() Λ࢖༻͍ͯ͠Δ৔߹͸ NavMesh.pathfindingIterationsPerFrame Λߴ͘ௐ੔͢ Δํ๏͕͋Γ·͢ɻϑϨʔϜ͋ͨΓͷෛՙ͕ߴ·ΓϑϨʔϜϨʔτ͕௿Լ͢ΔڪΕ͕͋Δ͜ͱʹ஫ҙ ͍ͯͩ͘͠͞ɻ ήʔϜʹΑͬͯ͸ Navigation Λར༻ͤͣผͷΞϧΰϦζϜʹஔ͖׵͑Δͱෛՙ͕ܰݮ͞ΕΔ͔΋ ͠Ε·ͤΜɻͨͱ͑͹ɺ໨ඪ஍఺΍ো֐෺͕੩ࢭ͍ͯ͠ΔλϫʔσΟϑΣϯεͳͲͷήʔϜ͸ɺ୳ࡧ ͰٻΊ֤ͨ஍఺ͷڑ཭ΛશΤʔδΣϯτʹڞ༗͢Δ͜ͱͰɺͦΕҎ߱ͷ୳ࡧॲཧΛলུͰ͖·͢ɻ Navigation ͱผͷΞϧΰϦζϜΛซ༻ͯ͠શମͷܭࢉྔΛݮΒ͢ํ๏΋͋Γͦ͏Ͱ͢ɻ߲࣍Ͱ͸ ͦΕʹ͍ͭͯߟ͑ɺ࣮ݧͨ͠ྫΛड़΂·͢ɻ 6.3 Navigation ͷԠ༻ ผͷΞϧΰϦζϜͱซ༻͢ΔҊ ࢲ͸ɺҰ෦ͷΤʔδΣϯτ͚͕ͩܦ࿏୳ࡧΛߦ͍ɺ΄͔ͷΤʔδΣϯτ͸ͦΕʹ௥ैͯ͠͸Ͳ͏ ͔ɺͱߟ͑·ͨ͠ɻ௥ै͢ΔͨΊʹϑϩοΩϯάΞϧΰϦζϜ (Boids) ͕࢖͑ͦ͏Ͱ͢ɻNavigation ͱϑϩοΩϯάΛ૊Έ߹ΘͤͨΤʔδΣϯτΛ࣮૷ͯ͠Έ·͢ɻ *4 https://docs.unity3d.com/ja/ScriptReference/AI.NavMesh-pathfindingIterationsPerFrame.html 79
  82. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻

    ϑϩοΩϯάΞϧΰϦζϜΛ࣮૷͢Δ ·ͣ͸ϑϩοΩϯάΞϧΰϦζϜͷΈΛ࣮૷͠·͢ɻήʔϜ։ൃऀͷͨΊͷ AI ೖ໳*5Λࢀߟʹ͠ ·ͨ͠ɻ ·ͣ͸पғͷΤʔδΣϯτΛऩू͠·͢ɻࠓճ͸؆୯ʹ͢ΔͨΊऩूͰ͖Δ֯౓͸ 360˃ͱ͠ ·͢ɻ Ϧετ 6.2: FlockingAgent.cs [SerializeField] private float _radius = 5.0f; [SerializeField] private float _separationRadius = 2.0f; [SerializeField] private float _steeringForce = 250.0f; private NavMeshAgent _navMeshAgent; private List<NavMeshAgent> _nearbyAgents = new List<NavMeshAgent>(); private void Start() { _navMeshAgent = GetComponent<NavMeshAgent>(); } private void Update() { CollectNearbyAgents(); var steering = 0f; if (_nearbyAgents.Count > 0) { steering += CalculateCohesionSteering(); // ݁߹ steering += CalculateAlignmentSteering(); // ੔ྻ steering += CalculateSeparationSteering(); // ෼཭ } transform.Rotate(0, steering * Time.deltaTime, 0); _navMeshAgent.velocity = transform.forward * _navMeshAgent.speed; } private void CollectNearbyAgents() { var colliders = Physics.OverlapSphere(transform.position, _radius); _nearbyAgents.Clear(); for (int i = 0; i < colliders.Length; i++) { *5 https://www.oreilly.co.jp/books/4873112168 80
  83. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻

    if (colliders[i].TryGetComponent<NavMeshAgent>(out var agent) && agent != _navMeshAgent) { _nearbyAgents.Add(agent); } } } ࣍ʹɺ݁߹ɾ੔ྻɾ෼཭ͱ͍͏؍఺͔Βૢ଩ྗΛٻΊɺΤʔδΣϯτΛҠಈͤ͞·͢ɻ ݁߹ʹΑΔૢ଩ྗΛٻΊΔؔ਺͸ҎԼͷ௨ΓͰ͢ɻपғͷΤʔδΣϯτͷฏۉతͳҐஔʹ޲͔͏ྗ Ͱ͢ɻ Ϧετ 6.3: FlockingAgent.cs private float CalculateCohesionSteering() { var averagePosition = Vector3.zero; for (int i = 0; i < _nearbyAgents.Count; i++) { averagePosition += _nearbyAgents[i].transform.position; } averagePosition /= _nearbyAgents.Count; var direction = (averagePosition - transform.position).normalized; return GetSteeringFromDirection(direction); } ੔ྻʹΑΔૢ଩ྗΛٻΊΔؔ਺͸ҎԼͷ௨ΓͰ͢ɻपғͷΤʔδΣϯτͷฏۉతͳํ޲Λ޲͘ྗ Ͱ͢ɻ Ϧετ 6.5: FlockingAgent.cs private float CalculateAlignmentSteering() { var averageDirection = Vector3.zero; for (int i = 0; i < _nearbyAgents.Count; i++) { averageDirection += _nearbyAgents[i].transform.forward; } averageDirection /= _nearbyAgents.Count; return GetSteeringFromDirection(averageDirection.normalized); } ݁߹ͱ੔ྻͰ༻͍ͨɺ໨ඪํ޲͔Βૢ଩ྗΛٻΊΔؔ਺ GetSteeringFromDirection() ͸ҎԼͷ௨ ΓͰ͢ɻ 81
  84. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻

    Ϧετ 6.5: FlockingAgent.cs private float GetSteeringFromDirection(Vector3 direction) { var w = transform.InverseTransformDirection(direction); var m = w.x < 0 ? -1 : 1; var dot = Vector3.Dot(transform.forward, direction); if (Mathf.Abs(dot) > 1) { return 0; } return m * _steeringForce * Mathf.Acos(dot) / Mathf.PI; } ෼཭ʹΑΔૢ଩ྗΛٻΊΔؔ਺͸ҎԼͷ௨ΓͰ͢ɻۙ͗͢ΔΤʔδΣϯτ͔Β཭ΕΔྗͰ͢ɻ Ϧετ 6.5: FlockingAgent.cs private float CalculateSeparationSteering() { var totalSteering = 0f; for (int i = 0; i < _nearbyAgents.Count; i++) { var agent = _nearbyAgents[i]; var distance = Vector3.Distance(transform.position, agent.transform.position); if (distance < _separationRadius) { var w = transform.InverseTransformPoint(agent.transform.position).normalized; var m = w.x < 0 ? 1 : -1; totalSteering += m * _steeringForce * _separationRadius / distance; } } return totalSteering; } ࣮૷ͨ͠ΤʔδΣϯτΛେྔʹ഑ஔ࣮ͯ͠ߦ͢ΔͱɺूஂΛܗ੒ͯ͠Ҡಈ͠·͢ɻ 82
  85. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻

    ਤ 6.1: ϑϩοΩϯάͰಈ༷͘ࢠ Ұ෦ͷΤʔδΣϯτ͚ͩܦ࿏Λܭࢉ͢Δ Ұ෦ͷΤʔδΣϯτ͕໨ඪ·Ͱͷܦ࿏Λ࣋ͭΑ͏มߋΛՃ͍͖͑ͯ·͢ɻ ·ͣɺҠಈ໨ඪͱͯ͠ɺTarget ͱ͍͏໊લͷ GameObject Λγʔϯʹ࡞੒͓͖ͯ͠·͢ɻΤʔ δΣϯτ͸ Start() ؔ਺಺Ͱ͜ͷ໨ඪΛऔಘ͠·͢*6ɻ Ϧετ 6.7: FlockingAgent.cs _target = GameObject.Find("Target").transform; ۙ͘ʹܦ࿏࣋ͪΤʔδΣϯτ͕͍ͳ͍৔߹͸ɺNavMesh.CalculatePath() Ͱ࠷୹ܦ࿏Λܭࢉ͠· ͢ɻܭࢉͨ͠ܦ࿏Λ SetPath() Ͱઃఆ͢ΔͱɺΤʔδΣϯτ͕ܦ࿏ʹԊͬͯࣗಈͰҠಈ͠·͢ɻ Ϧετ 6.7: FlockingAgent.cs private void Update() { if (_navMeshAgent.hasPath) { // ܦ࿏Λ͍࣋ͬͯΔ৔߹ɺҠಈ͸NavMeshAgentʹ೚ͤΔ return; *6 Find() ͸ෛՙ͕ߴ͍Ͱ͕͢ɺࠓճ͸؆୯ʹ͢ΔͨΊʹ࢖༻͍ͯ͠·͢ɻ 83
  86. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻

    } CollectNearbyAgents(); // पғʹܦ࿏࣋ͪΤʔδΣϯτ͕͍ͳ͚Ε͹ɺࣗ਎͕ܦ࿏Λ࣋ͭ if (!HasPathAnyAgent()) { var path = new NavMeshPath(); var complete = NavMesh.CalculatePath( transform.position, _target.position, NavMesh.AllAreas, path); if (complete) { _navMeshAgent.SetPath(path); return; } } ˞ ϑϩοΩϯάͷ࣮૷͸লུ } private bool HasPathAnyAgent() { for (int i = 0; i < _nearbyAgents.Count; i++) { if (_nearbyAgents[i].hasPath) { return true; } } return false; } ࣮ߦ͢Δͱɺܦ࿏࣋ͪΤʔδΣϯτʹ΄͔ͷΤʔδΣϯτ͕௥ै͠·ͨ͠ɻܦ࿏࣋ͪΤʔδΣϯτ ʹ͸നؙΛද͍ࣔͯ͠·͢ɻ 84
  87. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻

    ਤ 6.2: ܦ࿏࣋ͪΤʔδΣϯτʹ௥ै͍ͯ͠Δ༷ࢠ ͔͠͠ɺܦ࿏࣋ͪΤʔδΣϯτ͕ूஂʹແࢹ͞ΕΔ͜ͱ΋ଟ͋͘Γ·ͨ͠ɻ ਤ 6.3: ࠷ॳͷܦ࿏࣋ͪΤʔδΣϯτ͕ແࢹ͞Ε༷ͨࢠ 85
  88. ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻

    ߟ࡯ ظ଴௨Γʹूஂ͕Ҡಈͨ͠৔߹΋͋Ε͹ɺूஂ͕ܦ࿏࣋ͪΤʔδΣϯτΛແࢹͯ͠Ͳ͔͜ʹߦͬͯ ͠·͏͜ͱ΋ଟ͋͘Γ·ͨ͠ɻϑϩοΩϯά͸पғͷΤʔδΣϯτʹ߹ΘͤΔ͜ͱͰूஂΛܗ੒͢Δ ͨΊɺ1 ମͷΤʔδΣϯτ͕ผͷಈ͖Λͯ͠΋ूஂʹӨڹΛ༩͑ͮΒ͍ͷͩͱߟ͑ΒΕ·͢ɻ ·ͨɺࠓճ͸นΛߟྀ͍ͯ͠·ͤΜͰ͕ͨ͠ɺ࣮ࡍ͸นͷճආͳͲ΋ߦ͏ඞཁ͕͋ΔͨΊɺΑΓ෼ அ͕ൃੜ͠΍͘͢ͳΓ·͢ɻ ಛఆͷΤʔδΣϯτͷಈ͖ʹपΓ͕ڧ͘ै͏Α͏ʹ͢Δʹ͸ɺΤʔδΣϯτ͝ͱʹӨڹ౓ (ॏΈ) ΛઃఆͰ͖ΔΑ͏ʹ͢ΔͳͲͷௐ੔͕ඞཁͦ͏Ͱ͢ɻ 86
  89. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.1 ΠϯτϩμΫγϣϯ ຊষͰ͸ɺUnity Ͱ͍ΘΏΔ౷ҰγΣʔμʔΛ։ൃ͍ͯ͘͠ʹ͋ͨͬͯɺ͞·͟·ͳόϦΤʔγϣ ϯΛ͍͔ʹ੍ޚ͢Δ͔ʹ͍ͭͯ

    Tips తʹ঺հ͠·͢ɻ ର৅ಡऀ ຊষ͸ɺUnity ͰγΣʔμʔΛॻ͍ͨ͜ͱ͕͋Δਓ޲͚ͷ಺༰ͱͳ͍ͬͯ·͢ɻUnity ͷγΣʔ μʔ͸͍Ζ͍Ζ͋Γ·͕͢ɺதͰ΋ ShaderLab, HLSL/Cg ʹΑΔ௖఺γΣʔμʔɾϑϥάϝϯτ γΣʔμʔΛલఏͱ͍ͯ͠·͢ɻҰํͰɺαʔϑΣεγΣʔμʔ͓Αͼ Shader Graph ʹ͍ͭͯ͸ѻ ͍·ͤΜɻ·ͨɺϞόΠϧɾϩʔΤϯυ (Universal Render Pipeline) Λ૝ఆ͍ͯ͠·͢ɻڞ௨͢Δ ෦෼΋͋Δͱࢥ͍·͕͢ɺϋΠΤϯυ޲͚ͩͱ·ͨࣄ৘͕ҟͳΔ͔΋͠Ε·ͤΜɻ େྔͷγΣʔμʔ ϓϩδΣΫτʹΑΓ͚Γͩͱࢥ͍·͕͢ɺϞσϧ΍ΤϑΣΫτͷදݱΛ࣮ݱ͢ΔͨΊʹΑΓଟػೳ ͳγΣʔμʔΛ։ൃ͍ͯ͘͜͠ͱʹͳΔͱࢥ͍·͢ɻฐࣾʹ͓͍ͯ΋͍Ζ͍ΖͳϓϩδΣΫτͰͦΕ ͧΕͷ࡞ΓํͰγΣʔμʔͷ։ൃ͕ߦΘΕ͖ͯ·ͨ͠ɻͦͷதͷϓϩδΣΫτͷҰͭ͸ɺଟ༷ͳཁ݅ ʹରԠ͢ΔͨΊʹ਺ଟ͘ͷγΣʔμʔ͕࡞ΒΕɺͦͷ਺͸࠷ऴతʹ 70 Ҏ্ʹ͓Αͼ·ͨ͠ʢਤ 7.1ʣ ɻ 87
  90. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.1 ΠϯτϩμΫγϣϯ ਤ 7.1: େྔͷγΣʔμʔ*1

    ͜ΕΒ͸ͦΕͧΕ͕·ͬͨ͘ผ෺ͱ͍͏Θ͚Ͱ͸ͳ͘ɺҎԼͷػೳੑͷҧ͍ʹΑͬͯগͣͭ͠ҟͳ Δͱ͍͏΋ͷͰ͢ɻ • ෆಁ໌ɾ൒ಁ໌ͷ੾Γସ͑ • ϒϨϯυϞʔυͷ੾Γସ͑ • ֤छػೳͷ༗ޮɾແޮ – ςΫενϟϛϥʔϦϯά – ϥϯϓςΫενϟ – ϑΥʔϧΦϑ – etc. ࢲ͕ݱࡏܞΘΔϓϩδΣΫτͰ͸ɺ౰ॳ͜ΕΒͷγΣʔμʔΛࢿ࢈ͱͯ͠׆༻͢Δ࿩͕ग़͍ͯ·͠ ͕ͨɺࠓޙͷվम΍͞ΒͳΔཁ݅ରԠɺύϑΥʔϚϯε౳ͷ؍఺͔Βɺ͜ΕΒΛࢀߟʹͭͭ͠΋৽ن ʹ౷ҰతͳγΣʔμʔΛ։ൃ͢Δ͜ͱʹͳΓ·ͨ͠ɻ γΣʔμʔΛڞ௨Խ͢ΔϞνϕʔγϣϯ ίʔυత؍఺Ͱ͸ɺڞ௨෦෼ͷ࣮૷ʹมߋ͕ੜͨ͡ࡍʹमਖ਼͠ͳ͚Ε͹ͳΒͳ͍Օॴ͕ݮΓɺϝϯ ςφϯείετ͕Լ͕Δ఺͕͋Γ·͢ɻγΣʔμʔϑΝΠϧ͕෼͔Ε͍ͯͯ΋#include Λ࢖༻ͯ͠ ίʔυͷڞ௨ԽΛਤΔ͜ͱ͸ՄೳͰ͕͢ɺґଘؔ܎΍هड़͕ෳࡶԽͯ͠͠·͏͜ͱͱɺShaderLab ଆ ͷύϥϝʔλΛڞ௨؅ཧͰ͖ͳ͍ͱ͍͏఺Ͱɺ΍͸Γϝϯςφϯείετ͸ߴ͍ͱײ͡·͢ɻ ύϑΥʔϚϯε؍఺Ͱ΋Ըܙ͕͋Γ·͢ɻUnity 2018 ͔Β͸ैདྷͷඳըγεςϜʹ୅ΘΔ֦ுՄ *1 ໊લ͸࣮ࡍͷ΋ͷ͔Βएׯมߋ͍ͯ͠·͢ 88
  91. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.2 γΣʔμʔόϦΞϯτ ೳͳඳըγεςϜͰ͋Δ Scriptable Render

    Pipeline (SRP) ͕ొ৔͠ɺSRP Batcher*2ͱ͍͏৽ͨ ͳόονϯάγεςϜ͕࢖༻Ͱ͖ΔΑ͏ʹͳΓ·ͨ͠ɻSRP Batcher ͸ҟͳΔϚςϦΞϧͰ͋ͬͯ ΋γΣʔμʔόϦΞϯτ͕ಉҰͰ͋Ε͹ޮ཰Խ͕ظ଴Ͱ͖Δͱ͍͏΋ͷͰ͢ɻٯʹݴ͑͹ɺγΣʔ μʔόϦΞϯτҎલʹɺγΣʔμʔͦͷ΋ͷ͕ࡉ͔͘෼͔Ε͍ͯΔͱ SRP Batcher ͕ద༻Ͱ͖Δػ ձ͸ۃΊͯগͳ͘ͳͬͯ͠·͍·͢ɻ 7.2 γΣʔμʔόϦΞϯτ ػೳ͕෦෼తʹҟͳΔ͚ͩͰେ·͔ʹ͸ಉ͡Α͏ͳγΣʔμʔ͸ɺγΣʔμʔόϦΞϯτͱ࣮ͯ͠ ૷͢Δͱ؅ཧ͠΍͍͢Ͱ͢ɻ ҎԼͷγΣʔμʔ͸ɺγΣʔμʔΩʔϫʔυ MULTIPLY_VERTEX_COLOR ͕ఆٛ͞Ε͍ͯΔ͔Ͳ͏ ͔ʹΑͬͯ 2 ͭͷγΣʔμʔόϦΞϯτ͕ੜ੒͞Ε·͢ɻMULTIPLY_VERTEX_COLOR ͕ఆٛ͞Εͯ ͍Δͱɺ௖఺γΣʔμʔ͔Β౉͞ΕͨΧϥʔΛςΫενϟΧϥʔʹ৐ࢉ͢Δɺͱ͍͏ػೳ͕ՃΘΓ ·͢ɻ #pragma shader_feature _ MULTIPLY_VERTEX_COLOR float4 frag(v2f i) : SV_Target { float4 color = tex2D(_MainTex, i.uv); #ifdef MULTIPLY_VERTEX_COLOR color.rgb *= i.color.rgb; #endif return color; } ShaderLab ଆͷ Properties Ͱ͸ɺҎԼͷΑ͏ʹ Toggle ଐੑʹΑͬͯϓϩύςΟͱγΣʔμʔ ΩʔϫʔυΛؔ࿈෇͚·͢ɻ *2 https://docs.unity3d.com/Manual/SRPBatcher.html 89
  92. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.2 γΣʔμʔόϦΞϯτ Properties { [Toggle(MULTIPLY_VERTEX_COLOR)]

    _MultiplyVertexColor("Multiply Vertex Color", Float) = 0 } shader_feature ͱ multi_compile shader_feature ʹΑΔγΣʔμʔόϦΞϯτ͸ɺϏϧυ࣌ʹ࢖༻͞Ε͍ͯΔ΋ͷͷΈؚ͕·Ε· ͢ɻ࣮ߦ࣌ʹಈతʹόϦΞϯτΛ੾Γସ͍͑ͨ৔߹͸ɺmulti_compile Λ࢖༻͠·͢ɻmulti_com pile Λ࢖༻͢Δͱɺ͢΂ͯͷόϦΞϯτ͕Ϗϧυʹؚ·Ε·͢ɻ multi_compile Λෳ਺࢖͍ͬͯΔ৔߹ɺͦΕͧΕͷγΣʔμʔΩʔϫʔυͷ௚ੵͰόϦΞϯτͷ ύλʔϯ͕૿͍͖͑ͯ·͢ɻγΣʔμʔͷίϯύΠϧ࣌ؒ૿ՃͱΞηοταΠζͷ૿Ճʹͭͳ͕Δͷ Ͱɺmulti_compile ͸ඞཁͳ෦෼͚ͩͰ༻͍ΔΑ͏ʹ஫ҙ͕ඞཁͰ͢ɻ ·ͨɺmulti_compile Λ૊Έ߹Θͤͨ৔߹ɺͦΕΒ͢΂ͯͷγΣʔμʔΩʔϫʔυͷ૊Έ߹Θͤ ͝ͱͷόϦΞϯτ͕ੜ੒͞ΕΔͨΊɺരൃతʹόϦΞϯτ਺͕૿Ճ͠·͢ɻҎԼͷΑ͏ʹɺ5 छྨͷ Ωʔϫʔυͱ 3 छྨͷΩʔϫʔυͷ૊Έ߹ΘͤͰ͸ɺ5 × 3 = 15 ௨ΓͷόϦΞϯτ͕ੜ੒͞Ε·͢ɻ #pragma multi_compile A B C D E #pragma multi_compile F G H ਤ 7.2 ͷΑ͏ʹɺϏϧυʹؚ·ΕΔόϦΞϯτ਺͓ΑͼΩʔϫʔυͷ૊Έ߹Θͤ͸γΣʔμʔͷΠ ϯεϖΫλ্Ͱ֬ೝͰ͖·͢ɻ͜͜ʹ͸ɺshader_feature Ͱએݴ͞Ε͍͔͍ͯͯͭͣΕ͔ͷϚςϦ Ξϧʹؚ·Ε͍ͯΔγΣʔμʔΩʔϫʔυ΋ܭ্͞Ε͍ͯ·͢ɻ 90
  93. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.3 ςΫενϟͷϛϥʔϦϯά ਤ 7.2 7.3

    ςΫενϟͷϛϥʔϦϯά ΤϑΣΫτʹ࢖ΘΕΔςΫενϟ͸ԁܗͷૉࡐ΋ଟ͘ɺ࢛෼ԁͷςΫενϟΛॎԣʹ UV ϛϥʔ Ϧϯάͯ͠࢖༻͢Δ͜ͱͰɺ඼࣭ΛԼ͛Δ͜ͱͳ͘ςΫενϟͷղ૾౓Λ 1/4 ʹ཈͑Δ͜ͱ͕Ͱ͖ ·͢ɻ ͜͜Ͱ UV ϛϥʔϦϯάͱ͸ɺ0.5 ΑΓେ͖͍ UV ࠲ඪΛંΓฦ͢͜ͱΛࢦ͠·͢ɻςΫενϟ͔ ΒαϯϓϦϯά͢Δ࣮ࡍͷ UV ࠲ඪ (u′, v′) ͸ u′ v′ = 1 − 2 u v − 1 ͱͳΓ·͢ɻ ࣮͸ɺUnity 2017 ͰςΫενϟΠϯϙʔλʔͷ Wrap Mode ʹ Mirror Φϓγϣϯ͕௥Ճ͞Εɺ γΣʔμʔଆͰͷ UV ϛϥʔϦϯάܭࢉ͕ͦ΋ͦ΋ෆཁʹͳΓ·ͨ͠ɻ͜ͷ৔߹ɺςΫενϟͷλΠ ϦϯάΛ 2 ʹ͢Δ͜ͱͰਤ 7.3 ͷΑ͏ʹඳըͰ͖·͢ɻ 91
  94. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.4 ৚݅෼ذ ਤ 7.3: Wrap

    Mode Λ Mirror ʹ༷ͨ͠ࢠ 7.4 ৚݅෼ذ ࢝ΊʹγΣʔμʔόϦΞϯτʹΑͬͯػೳΛ੾Γସ͑ΔྫΛࣔ͠·͕ͨ͠ɺ෼ذ΍ԋࢉʹΑͬͯڍ ಈΛ੍ޚ͢Δํ͕Α͍৔߹΋͋Γ·͢ɻ ͨͱ͑͹ɺγΣʔμʔόϦΞϯτͷྫͷ #ifdef MULTIPLY_VERTEX_COLOR color.rgb *= i.color.rgb; #endif ͱ͍͏෦෼͸ɺ if (_MultiplyVertexColor != 0) { color.rgb *= i.color.rgb; } ͱͯ͠΋ػೳੑ͸มΘΓ·ͤΜɻ͋Δ͍͸ɺ color.rgb *= lerp(float3(1, 1, 1), i.color.rgb, _MultiplyVertexColor); 92
  95. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.4 ৚݅෼ذ ΍ color.rgb =

    lerp(color.rgb, color.rgb * i.color.rgb, _MultiplyVertexColor); ͷΑ͏ʹɺ৚݅෼ذͰ͸ͳ͘ܭࢉʹΑ੍ͬͯޚ͢Δ͜ͱ΋Ͱ͖·͢ɻಛʹϑϥάϝϯτγΣʔμʔʹ ͓͍ͯ͸ɺ৚݅෼ذͷίετ͕͔ͳΓେ͖͘ͳΔ͜ͱ͕͋ΔͷͰɺܭࢉʹΑ੍ͬͯޚ͢Δ͜ͱ͸Π σΟΦϜతʹΑ͘ݟ͔͚Δҹ৅Ͱ͢ɻ ͜͏࣮ͨ͠૷Ͱ͸γΣʔμʔόϦΞϯτ͸ੜ੒͞Εͳ͍ͷͰɺ୯ҰͷγΣʔμʔͰ͜ͷػೳͷ༗ແ Λ࢖͍෼͚Δ͜ͱ͕Ͱ͖·͢ɻ ͨͩ͜͠ͷํ๏͸ɺ݁Ռతʹ࢖༻͞Εͳ͍෦෼ͷܭࢉ΋࣮ߦ͞ΕΔͱ͍͏͜ͱʹ஫ҙ͕ඞཁͰ͢ɻ ͨͱ͑͹ɺ color = lerp(tex2D(_TexA, uv), tex2D(_TexB, uv), _TextureSwitch); ͜ͷίʔυ͸ɺ_TexA ͱ_TexB ͷ 2 ͭͷςΫενϟͷͲͪΒͷ৭Λ࢖༻͢Δ͔Λ_TextureSwitc h ʹΑͬͯ੾Γସ͍͑ͯ·͢*3ɻ͔͠͠ɺςΫενϟͷϑΣονࣗମ͸ৗʹ 2 ͭ෼͕࣮ߦ͞Ε·͢ɻ ίετͷ͔͔ΔॲཧΛ੾Γସ͑Δ৔߹͸γΣʔμʔόϦΞϯτʹͨ͠ํ͕Α͍Ͱ͠ΐ͏ɻ Toggle vs MaterialToggle, or ToggleUI? Float ͷϓϩύςΟΛ 0,1 ͷΦϯʗΦϑτάϧͱͯ͠࢖༻͍ͨ͠৔߹ɺToggle ଐੑΛ࢖͍ͬͯΔ ํ͸ଟ͍ͷͰ͸ͳ͍Ͱ͠ΐ͏͔ɻ࣮͸͋·Γ஌ΒΕ͍ͯͳ͍͔΋͠Εͳ͍Ͱ͕͢ɺToggleUI ଐੑͱ ͍͏΋ͷ͕͋Γ·͢ɻ ҎԼͷΑ͏ʹϓϩύςΟΛఆٛͯ͠Έ·͢ɻ Properties { [Toggle] _ToggleA("Toggle A", Float) = 0 [ToggleUI] _ToggleB("Toggle B", Float) = 0 } *3 _TextureSwitch ͕ 0,1 ͷτάϧ஋Ͱ͋Δ͜ͱΛߟ͑ͳ͚Ε͹ɺ2 ͭͷςΫενϟΛϒϨϯυ͍ͯ͠Δʹա͗·ͤΜɻ 93
  96. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.4 ৚݅෼ذ ਤ 7.4: τάϧͷදࣔ

    ϚςϦΞϧͷΠϯεϖΫλ্Ͱ͸ͲͪΒ΋νΣοΫϘοΫεʹͳ͓ͬͯΓɺ஋΋໰୊ͳ͘Φϯͷ৔ ߹͸ 1ɺΦϑͷ৔߹͸ 0 ʹͳΓ·͢ɻ͜͜Ͱɺ྆ํͷτάϧʹνΣοΫΛೖΕͨঢ়ଶͰɺΠϯεϖΫ λΛ Debug Ϟʔυʹͯ͠Έ·͠ΐ͏ɻ ਤ 7.5: ϚςϦΞϧΠϯεϖΫλͷ Debug දࣔ Shader Keywords ʹ_TOGGLEA_ON ͕௥Ճ͞Ε͍ͯ·͢ʢਤ 7.5ʣ ɻ࣮͸ Toggle ଐੑΛ࢖༻͢Δͱ ʮϓϩύςΟ໊ʢ͜ͷྫͰ͸_ToggleAʣΛ͢΂ͯେจࣈʹͨ͠΋ͷʹ_ON Λ෇Ճͨ͠γΣʔμʔΩʔ ϫʔυʯͷ༗ޮແޮ͕࿈ಈ͠·͢ɻγΣʔμʔΩʔϫʔυΛ໌ࣔ͢Δ৔߹͸ [Toggle(_MY_KEYWORD )] ͷΑ͏ʹهड़͠·͢ɻ ҰํͰ ToggleUI ଐੑ͸୯ʹ UI ΛνΣοΫϘοΫεʹมߋ͢Δ΋ͷͰ͢ɻγΣʔμʔΩʔϫʔυ Ͱ͸ͳ͘஋ͱͯ͠࢖༻͍ͨ͠༻్Ͱ͸ ToggleUI ଐੑͷํ͕ద͍ͯ͠·͢ɻ ࢖༻͠ͳ͍γΣʔμʔΩʔϫʔυ͕ҙਤͤͣఆٛ͞Εͯ͠·͏ͱ͍͔ͭ͘ෆ౎߹ͳ͜ͱ͕ੜ͡ ·͢ɻ • άϩʔόϧͳγΣʔμʔΩʔϫʔυͷ্ݶ਺Ͱ͋Δ 255 ݸʢ͏ͪ Unity ଆͰ 60 ݸ΄Ͳ࢖༻͞ ΕΔʣʹୡͯ͠͠·͏ • ͨͱ͑࢖༻͍ͯ͠ͳ͍γΣʔμʔΩʔϫʔυͰ͋ͬͯ΋ɺͦͷ༗ແʹΑͬͯ SRP Batching ͕ ્֐͞ΕΔ _TOGGLEA_ON ͕༗ޮʹͳͬͯ͠·͍ͬͯΔঢ়ଶͰ Frame Debugger Λ֬ೝ͢Δͱɺਤ 7.6 ͷΑ͏ ʹ SRP Batch ͕෼཭ͯ͠͠·͍ͬͯΔ͜ͱ͕෼͔Γ·͢ɻ·ͨɺshader_feature ΍ multi_comp ile Ͱએݴ͍ͯ͠ͳ͍γΣʔμʔΩʔϫʔυʹ͍ͭͯ͸ Frame Debugger ্Ͱ Keywords ͱͯ͠ද 94
  97. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ ࣔ͞Εͳ͍ͨΊɺԿ͕ೖͬͯ͠·͍ͬͯΔͷ͔͕෼͔ΓͮΒ͘ɺ͜͏ͳΒͳ͍Α͏ʹؾΛ෇͚͍ͨͱ ͜ΖͰ͢ɻ

    ਤ 7.6: Frame Debugger ͷදࣔ ͱ͜ΖͰɺMaterialToggle ଐੑͰ͕͢ɺ࣮ͷͱ͜Ζ͸͜Ε͸ Toggle ଐੑͱಉҰͰ͢ɻ͜Εʹͭ ͍ͯ͸ɺMaterialPropertyDrawer Ϋϥεͷ GetShaderPropertyDrawer ϝιουͷ࣮૷*4ΛݟΔͱ ෼͔Γ·͕͢ɺଐੑͱͯ͠هड़͞ΕͨΫϥε໊͕ม਺ className ʹೖ͍ͬͯΔͱͯ͠ • className • className + "Drawer" • "Material" + className + "Drawer" • etc. ͱ͍ͬͨจࣈྻύλʔϯͰ࣮ࡍͷΫϥε໊ͱϚονϯά͞ΕΔͷͰɺToggle ΋ MaterialToggle ΋ MaterialToggleDrawer ʹϚον͠·͢ɻ΋ͪΖΜɺToggleUI, MaterialToggleUI ౳΋ಉ༷ Ͱ͢ɻ 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ γΣʔμʔͷඳըઃఆʹؔ͢Δ಺༰͸ HLSL/Cg ʹΑΔ࣮૷ଆͰ͸ͳ͘ɺShaderLab ଆͰઃఆ͠ ·͢ɻͨͱ͑͹ɺҎԼͷΑ͏ͳ߲໨͸Α͘໨ʹ͢Δ͔ͱࢥ͍·͢ɻ • Cull: ΧϦϯάϞʔυ *4 https://github.com/Unity-Technologies/UnityCsReference/tree/61f92bd (2021/07/02 ݱࡏ) 95
  98. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ • ZTest:

    ਂ౓ςετͷํ๏ • ZWrite: ਂ౓ॻ͖ࠐΈͷ༗ແ • Blend: ϒϨϯυϞʔυ ·ͨɺ৔߹ʹΑͬͯ͸ Tags ͷهड़΋͍Ζ͍Ζͱม͑Δඞཁ͕͋ΔͰ͠ΐ͏ɻ • RenderType • Queue ύϥϝʔλԽͷجຊ ShaderLab ଆͰઃఆ͢Δύϥϝʔλʹ͸ɺProperties ͷ஋Λ༻͍Δ͜ͱ͕Ͱ͖·͢ɻͨͱ͑͹ɺ Properties { _Cull("Cull Mode", Float) = 0 _ZTest("Z Test Mode", Float) = 0 _ZWrite("Z Write", Float) = 0 } ͱ͍͏Α͏ͳϓϩύςΟΛఆٛ͠ɺ࣮ࡍͷύϥϝʔλ෦෼ʹ͸஋ͷ୅ΘΓʹ [] ͰғΜͩϓϩύςΟ ໊Λهड़͠·͢ɻ Pass { Cull [_Cull] ZTest [_ZTest] ZWrite [_ZWrite] } ToggleUI ଐੑ΍ Enum ଐੑ*5Λ࢖༻͢ΔͱɺΠϯεϖΫλͷද͕ࣔΑΓ෼͔Γ΍͘͢ͳΓ·͢ɻ Properties { [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull Mode", Float) = 0 [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("Z Test Mode", Float) = 0 [ToggleUI] _ZWrite("Z Write", Float) = 0 *5 ϚςϦΞϧϓϩύςΟͷ Enum ଐੑʹهड़͢ΔΫϥε໊͸ System.Type ͷ Name ·ͨ͸ FullName ͱͷҰகͰ୳ࡧ͞ ΕΔͨΊɺ໊લۭؒΛؚΊͨϑϧωʔϜͰهड़͢ΔͱΑ͍Ͱ͢ɻ 96
  99. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ } ਤ

    7.7 ϒϨϯυϞʔυͷύϥϝʔλԽ ϒϨϯυϞʔυͷجຊ ൒ಁ໌ͷඳըʹ͸ɺՃࢉ߹੒΍৐ࢉ߹੒ɺΞϧϑΝϒϨϯυͳͲɺ߹੒ͷํ๏͕͍Ζ͍Ζͱ͋Γ ·͢ɻ Unity ͷγΣʔμʔͰ͸ɺ͜ΕΛܾఆ͢Δͷ͸ओʹ࣍ͷύϥϝʔλͰ͢ɻ *6 • BlendOp Op • Blend SrcFactor DstFactor ϒϨϯυͷܭࢉ͸ɺલܠ৭ʢϒϨϯυ͢Δ৭ʣΛഎܠ৭ʢϒϨϯυઌͷ৭ʣʹͲͷΑ͏ʹ߹੒͢Δ ͔ΛͦΕͧΕʹର͢Δ܎਺ͱೋ߲ԋࢉʹΑͬͯදݱ͠·͢ɻલܠ৭Λ Cs , എܠ৭Λ Cd ͱ͢Δͱɺϒ Ϩϯυ͸ҎԼͷࣜͰද͞Ε·͢ɻ SrcFactor · Cs ⟨Op⟩ DstFactor · Cd ͜ΕΒͷύϥϝʔλͷ૊Έ߹ΘͤʹΑͬͯ͞·͟·ͳϒϨϯυΛදݱՄೳͰ͕͢ɺΑΓ൚༻తʹѻ ͏ͨΊʹ͸͍͔ͭ͘޻෉΋ඞཁͰ͢ɻ࣍અ͔Β͍͔ͭ͘ͷϒϨϯυํ๏ʹ͍ͭͯݟͯΈ·͠ΐ͏ɻ ΞϧϑΝϒϨϯυɺՃࢉ߹੒ ΞϧϑΝϒϨϯυͷܭࢉࣜ͸ҎԼͷΑ͏ʹͳΓ·͢ɻ As Cs + (1 − As )Cd ͜Εʹ૬౰͢Δ ShaderLab ͷهड़͸ BlendOp Add Blend SrcAlpha OneMinusSrcAlpha *6 ΑΓৄ͘͠͸ϚχϡΞϧ (https://docs.unity3d.com/ja/current/Manual/SL-Blend.html) Λࢀর͍ͯͩ͘͠͞ɻ 97
  100. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ ͱͳΓ·͢ɻ ҰํͰɺՃࢉ߹੒͸ҎԼͷΑ͏ʹͳΓ·͢ɻ

    As Cs + 1 · Cd ͜Ε͸ɺΞϧϑΝϒϨϯυʹ͓͚Δ DstFactor ͕ OneMinusSrcAlpha ͔Β One ʹมΘ͚ͬͨͩͱ ͍͏͜ͱ͕෼͔Γ·͢ɻ BlendOp Add Blend SrcAlpha One ͜ΕΒ 2 ͭͷϒϨϯυํࣜ͸ϒϨϯυ܎਺ͷઃఆ͚ͩͰ੾Γସ͑Δ͜ͱͷͰ͖Δγϯϓϧͳ΋ͷͰ ͢ɻͰ͸ɺ΄͔ͷϒϨϯυํࣜ͸Ͳ͏Ͱ͠ΐ͏͔ɻ εΫϦʔϯ߹੒ εΫϦʔϯ߹੒Λߟ͑ͯΈ·͠ΐ͏ɻ ·ͣɺЋ஋Λߟྀ͠ͳ͍εΫϦʔϯ߹੒͸ҎԼͷΑ͏ͳࣜʹͳΓ·͢ɻ *7 Cs + (1 − Cs )Cd ͜Ε͸ Blend One OneMinusSrcColor Ͱ࣮ݱͰ͖·͢ɻ Ћ஋Λߟྀ͍ͨ͠৔߹͸Ͳ͏͢Ε͹Α͍Ͱ͠ΐ͏͔ɻЋ஋͕ 1 ͷ৔߹͸্هͷࣜͩͱͯ͠ɺЋ஋͕ 0 ͷ৔߹͸ Cd ͱͳͬͯ΄͍͠Ͱ͢ɻ͜ΕΛຬͨ͢߹੒ࣜ͸ɺલܠ৭ͷЋ஋Λ As ͱͯ͠ As Cs + (1 − As Cs )Cd ͱ͍͏΋ͷΛߟ͑Δ͜ͱ͕Ͱ͖·͢ɻͯ͞ɺCd ͷ܎਺Ͱ͕͢ɺ͜Ε͸ Blend ύϥϝʔλͰ͸දݱͰ ͖·ͤΜɻͦ͜ͰɺAs Cs ΛϑϥάϝϯτγΣʔμʔͷग़ྗͱ͠ɺϒϨϯυ܎਺͸લड़ͷЋ஋Λߟྀ ͠ͳ͍εΫϦʔϯ߹੒ͷ΋ͷΛ࢖͍·͢ɻ float4 color; ... return color.rgb * color.a; // ϑϥάϝϯτγΣʔμʔͷग़ྗ ͜ͷΑ͏ʹɺϒϨϯυํࣜʹΑͬͯ͸ϑϥάϝϯτγΣʔμʔ্ͰЋ஋Λ৐ࢉͨ͠ΧϥʔΛग़ྗ͢ Δඞཁ͕͋Γ·͢ɻ *7 εΫϦʔϯ߹੒͸ʮഎܠ৭ͱલܠ৭Λ൓స͠ɺ৐ࢉ߹੒ͨ݁͠ՌΛ൓సʯ ɺ͢ͳΘͪ 1 − (1 − Cs)(1 − Cd) ͱઆ໌͞Ε Δ͜ͱ΋͋Γ·͢ɻ 98
  101. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ ৐ࢉ߹੒ ಉ༷ʹɺ৐ࢉ߹੒ʹ͍ͭͯ΋ߟ͑ͯΈ·͠ΐ͏ɻ

    ·ͣɺЋ஋Λߟྀ͠ͳ͍৔߹ͷ৐ࢉ߹੒͸ 0 · Cs + Cs · Cd ͢ͳΘͪ Blend Zero SrcColor ͱͳΓ·͢ɻ ͯ͞ɺ͜ͷ৐ࢉ߹੒ʹ͓͍ͯʮЋ஋Λߟྀ͢Δʯͱ͸Ͳ͏͍͏͜ͱͰ͠ΐ͏͔ɻ͜͜Ͱ͸ɺલܠ৭ ͷЋ஋͕ 0 ͷ৔߹͸എܠ৭͕ͦͷ··ʹͳΔͱ͠·͠ΐ͏ɻ 0 · Cs + ((1 − As ) + As Cs ) · Cd εΫϦʔϯ߹੒ͷͱ͖ͱಉ༷ʹɺϑϥάϝϯτγΣʔμʔͷ࣌఺ͰЋ஋Λ൓ө͓ͤͯ͘͞ඞཁ͕͋ Γͦ͏Ͱ͢ɻͨͩ͠εΫϦʔϯ߹੒ͷͱ͖ͱ͸ҧ͍ɺЋ஋͸৐ࢉͰ͸ͳ͘നͱ Cs ͷؒͷิؒ܎਺ͱ ͯ͠͸ͨΒ͖·͢ɻ float4 color; ... return lerp(1, color.rgb, color.a); // ϑϥάϝϯτγΣʔμʔͷग़ྗ Ћ஋ద༻෦෼ͷڞ௨Խ εΫϦʔϯ߹੒ͱ৐ࢉ߹੒ͷͦΕͧΕͰɺࣅ͍ͯΔΑ͏ͰҟͳΔЋ஋ͷॲཧ͕ग़͖ͯ·ͨ͠ɻ • εΫϦʔϯ߹੒: color.rgb * color.a • ৐ࢉ߹੒: lerp(1, color.rgb, color.a) ͨͩɺεΫϦʔϯ߹੒ͷํ΋ lerp ؔ਺Λ࢖ͬͯ lerp(0, color.rgb, color.a) ͱͯ͠΋ಉ஋ Ͱ͢ɻΑͬͯ͜ΕΒ 2 ͭ͸ʮЋ஋͕ 0 ͷͱ͖ʹϑϥάϝϯτγΣʔμʔ͕ग़ྗ͢Δ৭ʯ͚͕ͩҟͳͬ ͍ͯΔͱ͍͑·͢ɻ float4 _BlendBaseColor; // γΣʔμʔϓϩύςΟܦ༝ 99
  102. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ lerp(_BlendBaseColor.rgb, color.rgb,

    color.a); // Ћ஋൓ө ϒϨϯυڞ௨Խͷ·ͱΊ ͜Ε·Ͱͷ͜ͱ͔Βɺ1 ͭͷγΣʔμʔͰ͞·͟·ͳϒϨϯυϞʔυʹରԠ͢ΔͨΊʹ͸ҎԼͷཁ ૉΛ֎෦͔ΒઃఆͰ͖ΔΑ͏ʹ͢Δඞཁ͕͋Γ·͢ɻ • _BlendOp: ϒϨϯυԋࢉࢠ • _BlendSrc: લܠ৭ʹର͢Δ܎਺ • _BlendDst: എܠ৭ʹର͢Δ܎਺ • _BlendApplyAlpha: ϑϥάϝϯτγΣʔμʔଆͰЋ஋Λద༻͢Δ͔ • _BlendBaseColor: Ћ஋͕ 0 ͷͱ͖ʹϑϥάϝϯτγΣʔμʔ͕ग़ྗ͢Δ৭ ·ͣɺϓϩύςΟΛఆٛ͠·͢ɻ Properties { [Enum(UnityEngine.Rendering.BlendOp)] _BlendOp("Blend Op", Float) = 0 [Enum(UnityEngine.Rendering.BlendMode)] _BlendSrc("Blend Src", Float) = 0 [Enum(UnityEngine.Rendering.BlendMode)] _BlendDst("Blend Dst", Float) = 0 [Toggle(_BLEND_APPLY_ALPHA)] // #pragma shader_feature _BLEND_APPLY_ALPHA _BlendApplyAlpha("Blend Apply Alpha", Float) = 0 _BlendBaseColor("Blend Base Color", Color) = (1, 1, 1, 1) } ϒϨϯυϞʔυʹؔ͢Δύϥϝʔλ͸ ShaderLab ଆͷ Pass ಺౳ʹهड़͠·͢ɻ BlendOp [_BlendOp] Blend [_BlendSrc] [_BlendDst] Ћ஋ͷద༻෦෼͸ϑϥάϝϯτγΣʔμʔଆͰ࣮૷͠·͢ɻ 100
  103. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.5 ShaderLab ύϥϝʔλͷϓϩύςΟԽ half4 _BlendBaseColor;

    half4 frag(v2f i) : SV_Target { half4 color; ... #if _BLEND_APPLY_ALPHA color.rgb = lerp(_BlendBaseColor.rgb, color.rgb, color.a); #endif return color; } ਤ 7.8 ͸ɺಉҰͷςΫενϟΛࠨ͔ΒͦΕͧΕΞϧϑΝϒϨϯυɺՃࢉ߹੒ɺεΫϦʔϯ߹੒ɺ৐ ࢉ߹੒Ͱඳըͨ͠΋ͷͰ͢ɻ͢΂ͯಉҰͷγΣʔμʔΛ࢖༻͓ͯ͠ΓɺϚςϦΞϧͷϓϩύςΟΛͦ ΕͧΕͷඳը޲͚ʹઃఆͯ͋͠Γ·͢ɻ ਤ 7.8: छʑͷϒϨϯυඳը λάͷ಺༰Λద੾ʹઃఆ͢Δ γΣʔμʔΛهड़͢Δͱ͖ɺSubShader ΍ Pass ʹҎԼͷΑ͏ͳ Tags Λهड़͢Δͱࢥ͍·͢ɻ Tags { "RenderType" = "Opaque" "Queue" = "Geometry" } 1 ͭͷγΣʔμʔͰෆಁ໌Ϟʔυͱ൒ಁ໌ϞʔυΛ੾Γସ͑ΒΕΔΑ͏ʹ͍ͨ͠৔߹ɺ͜ͷ෦෼΋ ద੾ʹઃఆ͢Δඞཁ͕͋Γ·͢ɻ Tags ͷ಺༰Λมߋ͢Δʹ͸ɺMaterial.SetOverrideTag ϝιουΛ࢖༻͠·͢ɻ 101
  104. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.6 γΣʔμʔΛॻ͖΍͘͢͢Δ޻෉ material.SetOverrideTag("RenderType", "Transparent"); Queue

    ʹ͍ͭͯ͸ SetOverrideTag ϝιουͰ͸ͳ͘ɺMaterial.renderQueue ϓϩύςΟΛม ߋ͠·͢ɻ material.renderQueue = (int)RenderQueue.Transparent; Tags ʹ͍ͭͯ͸ɺඪ४ͷϚςϦΞϧΠϯεϖΫλͰ͸ૢ࡞͢Δ͜ͱ͕೉͍͠ͷͰɺෆಁ໌ɾ൒ಁ ໌ͷઃఆ಺༰ʹ߹ΘͤͯγΣʔμʔΤσΟλ౳Ͱ੍ޚ͢Δඞཁ͕͋Γ·͢ɻ 7.6 γΣʔμʔΛॻ͖΍͘͢͢Δ޻෉ Unity ͷγΣʔμʔ͸ ShaderLab ͱ͍͏ߏจͷதʹ HLSL/Cg ͷߏจ͕಺แ͞ΕΔߏ଄ͱͳͬͯ ͍·͢ɻ Shader "Example" { Properties { _MainTex("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType" = "Opaque" } Pass { HLSLPROGRAM // <-- ͔͜͜ΒHLSL #pragma vertex vert #pragma fragment frag sampler2D _MainTex; ... half4 frag(v2f i) : SV_Target { return tex2D(_MainTex, i.uv); } ENDHLSL // <-- ͜͜·ͰHLSL } } } 2 ͭͷҟͳΔߏจ͕ࠞࡏ͍ͯ͠Δ͔Β͔ɺଟ͘ͷΤσΟλͰΠϯσϯτ΍ϑΥʔϚολͷڍಈ͕͓ 102
  105. ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ࿩ 7.7 ·ͱΊ ͔͘͠ͳΓ͕ͪͰ͢ɻ·ͨɺHLSL ෦෼ͷΠϯσϯτ͕શମతʹਂ͘ͳͬͯ͠·͍ಡΈͮΒ͍ҹ৅ Ͱ͢ɻ

    γΣʔμʔΛຊ֨తʹॻ͖࢝ΊͨΒɺૣΊͷஈ֊Ͱ HLSL ෦෼Λ#include Ͱ෼ׂ͢Δͱݟ௨͕͠ ྑ͘ͳΓ·͢ɻ *8 Example.shader Shader "Example" { Properties { _MainTex("Texture", 2D) = "white" {} } SubShader { Tags { "RenderType" = "Opaque" } Pass { HLSLPROGRAM #pragma vertex vert #pragma fragment frag #include "Includes/Example.hlsl" ENDHLSL } } } Includes/Example.hlsl sampler2D _MainTex; ... half4 frag(v2f i) : SV_Target { return tex2D(_MainTex, i.uv); } ͜ͷΑ͏ʹ͢ΔͱɺExample.hlsl ͸௨ৗͷ HLSL ϑΝΠϧͱͯ͠ѻ͑ΔͨΊɺಡΈ΍͘͢ΤσΟ λͷαϙʔτ΋ظ଴Ͱ͖·͢ɻ 7.7 ·ͱΊ γΣʔμʔΛ·ͱΊ͍͍ͯ͘Ζ͍Ζͳํ๏ʹ͍ͭͯ঺հ͠·ͨ͠ɻ࣮ࡍʹ͸ɺطଘͷγΣʔμʔΛ ·ͱΊͨͱ͍͏ΑΓ͸ɺࢀߟʹͭͭ͠৽ͨʹ౷ҰγΣʔμʔΛ։ൃ͢Δܗʹͳ͍ͬͯ·͢ɻݱঢ়ͷϓ ϩδΣΫτͰ͸ɺ౷ҰγΣʔμʔͱͯ͠؅ཧ͢Δ͜ͱͰɺ։ൃ΍ϝϯςφϯείετΛ཈͑ͭͭ͞Β *8 #pragma σΟϨΫςΟϒ͸ ShaderLab ଆͰهड़͢Δඞཁ͕͋Γ·͢ɻ 103
  106. ஶऀ঺հ দݪ ৴஧ (ୈ 1 ষ୲౰) ॴଐ͸ϞϯεταʔόνʔϜͰ Ruby ΍ Go

    Λॻ͍ͯΔɻϓϩάϥϛϯά͕޷͖Ͱɺීஈ͸ਪ ͠ݴޠͷ Haskell Ͱ༡ΜͩΓɺ৽͍͠ϓϩάϥϛϯάݴޠΛษڧͨ͠Γ͍ͯ͠ΔɻHaskell-jp Ͱ΋ͪΐͪ͜ΐ͜׆ಈ΋͍ͯ͠Δɻ ɹ ߐാ୓࠸ (ୈ 2 ষ୲౰, Github: MokkeMeguru, Twitter: @MeguruMokke) ֆΛඳ͖ͳ͕ΒαʔόϝΠϯʹίʔυॻ͖͓͡͞Μ͍ͯ͠Δ Lisp ͷຽͰ͢ɻશ଎લਐ DA! ɹ ٢઒༐ଠ࿠ (ୈ 3 ষ୲౰, Github: yutaroyoshikawa) ࣍ੈ୅ΤϯλʔςΠϯϝϯτࣄۀຊ෦ ϥΠϒಈըϓϩμΫτ։ൃࣨॴଐ ΠϯυΧϨʔͱ Web ͕޷͖Ͱ͢ ɹ ాಹลً (ୈ 4 ষ୲౰) ։ൃຊ෦ CTO ࣨॴଐɻιϑτ΢ΣΞΤϯδχΞͱͯ͠ήʔϜ։ൃͱӡӦɺͦΕ͔Βऩӹੑ΍ ήʔϜੑͱ UX ໘౳ʑΫϦΤΠςΟϒʹ΋ܞΘ͖ͬͯ·ͨ͠ɻϓϩάϥϛϯάڭҭʹ͍ͭͯ ͷֶशιϑτͱΧϦΩϡϥϜΛࣗࣾ಺Ͱ࡞Γɺதɾߴߍੜʹ޲͚ͯϓϩάϥϛϯάߨ࠲ͷߨࢣ Ͱ΋׆ಈதɻ΄͔ࣾ಺ R&D ۀ຿΋ࢀՃɻ ɹ ϠϚϠλέγ (ୈ 5 ষ୲౰) ໘ന͍ήʔϜΛ࡞Δ࢓ࣄΛ͍ͯ͠·͢ɻݸਓͰίϯϐϡʔλΛ࢖Θͳ͍ήʔϜ΋࡞͍ͬͯ· ͢ɻೝΊ͍ͯ·ͤΜ͕ߦಈΛ෼ੳ͢ΔͱɺͲ͏΍Β͓ञ͕େ޷͖Ͱ͢ɻ ɹ ਌઒େथ (ୈ 6 ষ୲౰, GitHub: eviltwo, Twitter: @daiki_all) Unity ੡ήʔϜͷ։ൃΛ͍ͯ͠·͢ɻझຯͰ΋ήʔϜΛ࡞͓ͬͯΓɺ#unity1week ʹ΋࣌ʑ ࢀՃ͍ͯ͠·͢ɻ 105
  107. ෇࿥ ஶऀ঺հ ɹ YuukiARIA (ୈ 7 ষ୲౰) ։ൃຊ෦ CTO ࣨॴଐɻٕज़ॻయ

    6 ҎདྷͷࣥචʹͳΓ·͢ɻ࠷ۙ͸γΣʔμʔͷษڧதͰ͢ɻ ɹ ౢࣇ ະདྷ (Graphic designer / Art director) ϛΫγΟ σβΠϯຊ෦ ΫϦΤΠςΟϒࣨ ૊৫։ൃάϧʔϓॴଐࠓճɺΞΠίϯΠϥετ΍ද ࢴσβΠϯ౳Λ୲౰ɻ༻ޠͳͲษڧʹͳΓ·ͨ͠ʂ ײँɻ ɹ ਿా ֆඒ (੍࡞ਐߦ, GitHub: esugita, Twitter: @semisemi7) ݩʑ͸ΤϯδχΞͰɺαʔόαΠυ͔ΒεϚϗΞϓϦ·Ͱ෯޿͘ܦݧ͍ͯ͠·͕͢ɺࠓ͸ɺ DevRel ͱͯ͠ɺࣾ಺֎ͷٕज़ऀίϛϡχςΟͷࢧԉΛߦͬͨΓɺٕज़޿ใΛ͍ͯ͠·͢ɻ ɹ تଟ ޭ࣍ (੍࡞Ξγετ, GitHub: kojikita, Twitter: @kojikita) DevRel νʔϜͰษڧձ΍ΠϕϯτͷӡӦΛ͍ͯ͠·͢ɻ࠷ۙ͸࢓ࣄ΋ݟͨ໨΋ YouTuber Խ ͍ͯ͠·͢ɻ 106
  108. mixi tech note #06 2021 ೥ 7 ݄ 10 ೔ɹॳ൛ୈ

    1 ࡮ɹൃߦ ஶɹऀ גࣜձࣾϛΫγΟ ༗ࢤ ൃߦॴ גࣜձࣾϛΫγΟ ҹ࡮ॴ ೔ޫاը ɹ ˜ mixi, Inc.