#技術書典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 tech note #06
גࣜձࣾϛΫγΟ ༗ࢤɹஶ
2021-07-10 ൛ גࣜձࣾϛΫγΟ ൃߦ
·͕͖͑
ຊॻʮmixi tech note #06ʯɺϛΫγΟάϧʔϓʹॴଐ͢Δ༗ࢤୡʹΑͬͯࣥචɾ੍࡞͞Εͨ
ٕज़ॻͰ͢ɻհͳΜͱ͔ɻͦͷͨΊɺ֤ষͦΕͧΕͰ͍݁ͯ͠Δ༰ʹͳ͍ͬͯ·͢ͷͰɺ͖
ͳষ͔Β͖ͳॱ൪Ͱָ͓͠Έ͍ͩ͘͞ɻ
·ͨɺຊॻɺϛΫγΟάϧʔϓʹ͋Δٕज़తݟΞΠσΞΛੵۃతʹڞ༗ɾެ։͍ͯ͘͜͠ͱ
ͰɺੈͷதʹΑΓྑ͍αʔϏε͕ҲΕग़͢͜ͱΛئͬͯץߦ͞Ε͍ͯ·͢ɻܝࡌ͞Ε͍ͯΔใɺ
ࣥචऀࣗͷڥͰݕূࣥ͠ච͞ΕͨͷͰ͢ͷͰɺ͝ࢀߟʹ͞ΕΔࡍɺࣗ͝ͷͰஅ͠
͝׆༻͍ͩ͘͞ɻͳ͓ɺจষදݱʹ͖ͭ·ͯ͠ɺࣥචऀࣗͷݴ༿Ͱ͑ͨ͘ɺϑϥϯΫͳදݱͱ
ͳ͓ͬͯΓ·͢͜ͱ͝ཧղ͍͚ͨͩΕͱࢥ͍·͢ɻ
σΟϕϩούʔϦϨʔγϣϯζνʔϜҰಉ
˗ຊॻʹؔ͢Δ͓͍߹Θͤઌ
ɹ https://twitter.com/mixi_engineers
˗ϛΫγΟάϧʔϓʹ͍ͭͯ
ɹ https://mixi.co.jp/
˞ʠϛΫγΟʡ
ɺ
ʠmixiʡ
ɺ
ʠmixi ϩΰʡ ɺגࣜձࣾϛΫγΟͷඪ·ͨొඪͰ͢ɻ·ͨɺ֤
ࣾͷձ໊ࣾɺαʔϏεٴͼͷ໊শɺͦΕͧΕͷॴ༗͢Δඪ·ͨొඪͰ͢ɻ
iii
࣍
·͕͖͑ 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
࣍
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.2 Haskell Ͱ Dockerfile Λهड़͢Δ
-> Maybe String
-> m (Maybe GitHub.Release)
fetchRelease owner repo tag = do
r 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 ) 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 pure $ do -- Maybe Ϟφυͷ Do ه๏Ͱ͢
assets release
6
ୈ 1 ষ Haskell Ͱ͍͡Δ Dockerfile 1.2 Haskell Ͱ Dockerfile Λهड़͢Δ
asset 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 r2 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
ୈ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
ୈ 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
ୈ 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
ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷΈ߹Θͤ 2.1 ͖Ε͍ͳίʔυͷҐஔ͚
อकੑ͕ߴ͍͜ͱ
͜͜Ͱ͍͏อकੑͱɺͦͷϓϩάϥϜʹ͍ͭͯඋɺҡ࣋ɺཧ͕͍͢͜͠ͱΛࣔ͠·͢ɻͨ
ͱ͑ɺΧελϚʔαʔϏε͔Βґཔ͕དྷͨͱ͖ʹݪҼಛఆͦͷमਖ਼͕༰қͰ͋Δ͜ͱɺΠϯϑϥ
ͷόʔδϣϯΞοϓσʔτʹڧ͍͜ͱͳͲ͕۩ମతͳཁ݅ͱͳΓ·͢ɻ
ςετઃܭ͕༰қͰ͋Δ͜ͱ
։ൃνʔϜ/ڥʹΑͬͯɺςετΛॻ͍͍ͯΔ͜ͱ͕͖Ε͍ͳίʔυɺͱΈͳ͞ΕΔ͜ͱ͋
Γ·͢ɻ͔͠͠ͳ͕ΒɺςετΛॻ͖͍͢ڥඋ͖Ε͍ͳίʔυΛॻͨ͘Ίͷཁૉͱͯ͑͠
Δ͜ͱ͕Ͱ͖·͢ɻͨͱ͑ɺϏδωεϩδοΫͰ O/RM Λݺͼग़ͯ͠σʔλϕʔεͱͷऔҾΛ
ߦ͍ͬͯΔΑ͏ͳίʔυɺςετΛॻ͘ͷ༰қͰ͋Γ·ͤΜɻΑͬͯɺςετΛॻ͖͍͢Α
͏ͳઃܭ͕Ͱ͖͍ͯΔ͜ͱɺ͖Ε͍ͳίʔυΛߏ͢ΔҰһͰ͋Δݴ͑·͢ɻ
ػೳͷ֦ு͕༰қͰ͋Δ͜ͱ
ҰൠʹΞδϟΠϧ։ൃΛϕʔεʹϓϩδΣΫτΛਐΊ͍ͯ͘ͱɺػೳͷ֦ுΛٻΊΒΕΔέʔε͕
ଟ͘ଘࡏ͠·͢ɻػೳͷ֦ுΛߦ͏ࡍʹɺಉ͡ϓϩηεΛطଘͷػೳ͔ΒҾ༻͠Έ߹ΘͤΒΕΔ͜
ͱɺϓϩάϥϚʔͷଵଦͳಛੑΛ׆͔ͨ͢ΊʹඞཁͳಛͰ͢ɻͦͷͨΊɺ֦ு͢ΔະདྷΛݟӽ͞
ͳ͍ػೳ࣮ɺ࣍ͷ։ൃʹର͢Δେ͖ͳ؞ͱͳͬͯ͠·͏Մೳੑ͕ߴ͘ͳΓ·͢ɻ
εέʔϥϏϦςΟ͕ߴ͍͜ͱ
ۙͰ͢ͱɺΫϥυϦιʔεΛ׆༻ͯ͠ෛՙࢄੑͷ֬อͳͲΛߦ͏έʔε͕૿͖͑ͯͯ
͍·͢ɻͨͱ͑ Google Amazon ͰɺKubernates Docker Λ༻͍ͯαʔόϦιʔεͷಈ
తͳ࠷దԽΛ࣮ݱ͢ΔαʔϏεΛల։͍ͯ͠·͢ɻ
*3͜ΕΒͷαʔϏεΛར༻͢ΔͨΊʹɺαʔό
Ϧιʔε͕ಈతʹมԽͯ͠ఏڙ͢ΔαʔϏεʹҰ؏ੑΛ࣋ͨͤΒΕΔઃܭ͕ඞཁͩͱݴ͑·͢ɻ
*3 ϛΫγΟͰ͜ΕΒͷαʔϏεΛੵۃతʹ࠾༻͍ͯ͠·͢ɻ
12
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 2 ষ ͖Ε͍ͳίʔυΛॻͨ͘Ίͷ 3 ͭͷ C ͱͦͷΈ߹Θͤ 2.3 ͖Ε͍ͳίʔυͷͣͳͷʹ
ਤ 2.3: ࠓ·ͰͷΞʔΩςΫνϟ
ਤ 2.4: ҠߦઌͷΞʔΩςΫνϟ
24
ୈ 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
ୈ 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
ୈ 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
λάͱλάʹΑͬͯߏ͞Ε͓ͯΓɺϚʔΫΞοϓߏΛςϯ
ϓϨʔτԽΛՄೳʹ͠ɺҙͷࢠཁૉΛૠೖ͢ΔॴΛએݴͰ͖ΔׂΛ୲͍ͬͯ·͢ɻ
27
ୈ 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
ୈ 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
ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ 3.1 Web Components ͷجૅ
Web Components Ͱ͜ͷΑ͏ʹ Class ܕͷίϯϙʔωϯτΛఆٛ͠·͢ɻHTMLElement Λܧ
ঝ͢Δ͜ͱͰɺίϯϙʔωϯτͰϥΠϑαΠΫϧʹΞΫηεͰ͖·͢ɻίϯϙʔωϯτΛఆٛ͠
ͨΒ customElements.define ϝιουΛ͏͜ͱͰ৽͘͠ΧελϜλάΛάϩʔόϧʹొͰ͖
·͢ɻ
Ϧετ 3.2: counter.html
1:
2:
3:
4:
5:
6:
7:
8:
άϩʔόϧʹొͨ͠ΧελϜλά HTML Ͱఆٛͨ͠ίϯϙʔωϯτΛؚΉ JS ϑΝΠϧΛ
import ͯ͠ඪ४ͷλάͱಉ͡Α͏ʹ༻Ͱ͖·͢ɻ
ϥΠϑαΠΫϧ
ίϯϙʔωϯτͰΞΫηεͰ͖ΔϥΠϑαΠΫϧʹ͍ͭͯհ͠·͢ɻ
connectedCallback
• ίϯϙʔωϯτ͕Ϛϯτͨ࣌͠ʹݺͼग़͞ΕΔϝιου
• eventListener Λൃߦ͢Δ࣌ͳͲʹ͏
disconnectedCallback
• ίϯϙʔωϯτ͕ΞϯϚϯτ͞Εͨ࣌ʹݺͼग़͞ΕΔϝιου
• removeEventListener Λൃߦ͢Δ࣌ͳͲʹ͏
adoptedCallback
• ίϯϙʔωϯτ͕ผͷϖʔδʹҠಈͨ࣌͠ʹݺͼग़͞ΕΔϝιου
attributeChangedCallback
• html ଐੑͷೖྗ͕ߋ৽͞Εͨ࣌ʹݺͼग़͞ΕΔϝιου
• static get observedAttributes ʹొͨ͠ଐੑͷΈ͕มߋݕ͞ΕΔɻ
• ϝιουͷҾ͔Βɺଐੑ໊ʗ̍ͭલͷଐੑʗ৽͍͠ଐੑΛऔಘͰ͖Δɻ
30
ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ 3.1 Web Components ͷجૅ
ΞΫηγϏϦςΟ
ΧελϜλάͦͷ··ϨϯμϦϯά͞ΕΔͷͰจॻߏͷ߹ੑ่͕Εͯ͠·͏͜ͱ͕͋Γ·
͢ɻͨͱ͑Ϧετ 3.3 ͷΑ͏ͳϦετߏͩͬͨ߹ ul λάͱ li λάͷؒʹ custom-list λά͕
ೖͬͯ͠·͍ͬͯΔͷͰηϚϯςΟΫεతʹ͕͋Γ·͢ɻ
Ϧετ 3.3: index.html
1:
2:
3:
4: item1
5:
6:
7: item2
8:
9:
10:
͜ͷ߹ role ଐੑΛઃఆ͢Δ͜ͱͰղܾͰ͖·͢ɻ
Ϧετ 3.4: index.html
1:
2:
3:
4: item1
5:
6:
7:
8: item2
9:
10:
11:
·ͨɺผͷํ๏ͱͯ͠ΧελϜλάࣗମʹΞΫηγϏϦςΟͷใΛ༩Ͱ͖Δ Accessibility
Object ModelʢAOMʣͱ͍͏༷ͷࡦఆ͕ݱࡏਐΜͰ͍·͢ɻAOM JavaScript Ͱऔಘͨ͠
Element ʹରͯ͠खଓ͖తʹ role ଐੑͳͲͷΞΫηγϏϦςΟใΛઃఆͰ͖ΔͷͰ͢ɻ೦ͳ
͕Β·ͩࡦఆதͰ࣮ࡍʹ༻͢Δ͜ͱͰ͖·ͤΜ͕ɺ͍͔ͭϞμϯϒϥβͰීٴ͢ΔͱΑ͍ͳͱ
ࢥ͍·͢ɻ
31
ୈ 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
ୈ 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
ୈ 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: this.onCount()}">
44: ${this.label}: ${this.count}
45:
46: ‘;
47: }
48: }
Lit ɺσίϨʔλʔΛ͏͜ͱͰɺૉͷ Web Componets ΑΓ͖ͬ͢Γॻ͘͜ͱ͕Ͱ͖·͢ɻ
html ςϯϓϨʔτΛ༻ͯ͠ HTML CSS Λهड़͠ɺproperty ΛຒΊࠐΉͱΧελϜίϯϙʔω
ϯτΛϚϯτ͢Δͱ͖ʹɺ֘Օॴʹϋογϡ id ΛؚΜͩίϝϯτ͕ҰॹʹϨϯμϦϯά͞Ε·
͢ɻproperty ͱϋογϡ id ͕ඥ͍ͮͯཧ͞Ε͍ͯͯɺ͜ͷϋογϡ id Λҹʹɺproperty ͷ
͕มߋ͞Εͨͱ͖ʹ࠶ϨϯμϦϯά͢ΔॴΛ࠷খݶʹ͑Δ͜ͱ͕Ͱ͖·͢ɻ
σΟϨΫςΟϒ
σΟϨΫςΟϒͱɺදࣔͨ͠σʔλʹՃ͢ΔॲཧΛΓग़͢͜ͱ͕Ͱ͖ΔػೳͰ͢ɻΑ͘Θ
ΕΔΑ͏ͳ൚༻తͳσΟϨΫςΟϒ͕͋Β͔͡Ί͍͔ͭ͘༻ҙ͞Ε͍ͯ·͢ɻ·ͨɺΧελϜσΟϨ
ΫςΟϒͱͯ͠ಠࣗʹσΟϨΫςΟϒΛఆٛ͢Δ͜ͱͰ͖·͢ɻ
• classMap
– class Λಈతʹద༻Ͱ͖ΔσΟϨΫςΟϒ
• repeat
– map ͳͲͰϨϯμϦϯάͨ͠ྻͷཁૉ͕ߋ৽͞Εͨͱ͖ʹɺޮతʹ࠶ϨϯμʔΛ͢
ΔσΟϨΫςΟϒ
• Ωϟογϡ
34
ୈ 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
ୈ 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;
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 implements ReactiveController {
5: private store: TSelector;
6: private unsubscriber: ReturnType;
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
ୈ 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:
13: ${JSON.stringify(this.todoSelector.state.todo)}
14:
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 = createRef();
9:
10: public firstUpdated() {
11: const router = new Router(this.routerRef.value);
12: router.setRoutes([
13: {
14: path: "/",
15: action: async () => {
37
ୈ 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:
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: this is top page
19: to detail
20: ‘;
21: }
38
ୈ 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‘‘;
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
ୈ 3 ষ Web Components ͷجૅͱ։ൃ࣌ͷઃܭߟ 3.4 ࠷ޙʹ
13: const el = await fixture(html‘‘);
14: assert.shadowDom.equal(
15: el,
16: ‘
17: ͜Ε DemoComponent Ͱ͢ɻ
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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ܕͰϦετΛ࣋ͪ·͢ɻࣗࡏʹ͑ΔΑ͏ʹ͍͖ͯ͠·͠ΐ͏ɻ
Component ͷ༻ঢ়گ
Component ༗ແ͚ͩΛݟͯϑϥάͱͯ͠ѻ͍·͢ɻ͍͔ͭ͘ͷ Component ͷΈ߹Θͤϑ
ϥάͱͯ͠ػೳ͠·͢ɻঢ়گ͕มԽ͢Δʹैͬͯ Entity ͷ Component ΛՃআ͠ଓ͚ͯίϯτ
ϩʔϧ͠·͢ɻSystem ͷ update தͰมߋ͢Δ߹͕͋Γ·͢ɻ͋Β͔͡Ίมߋ͢Δ Component
ͱมߋ͠ͳ͍ Component Λ໌ࣔతʹ ref in Ͱࢦఆ͍ͯ͠·͢ɻJob γεςϜͰฒྻॲཧΛࢪ͢
߹ Component ͷσʔλॻ͖͕͑ڝ߹ͯ͠ยํ͔͠อଘ͞Εͳ͍Մೳੑ͕͋Γ·͢ɻNetCode
༻࣌ʹ Component ͷಛఆͷ field Λಉظରʹ͢Δ [GhostField] ଐੑΛ͍·͢ɻ
60
ୈ 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
ୈ 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
ୈ 4 ষ Ͱ͖ΔΑ Unity DOTS 4.8 Ͳ͏ߏங͢Εྑ͍ͷ͔
σʔλϑϩʔਤΛ࡞Δ͜ͱѹతʹ࡞ۀઃܭίετΛԼ͛Δ
܁Γฦ͠ड़͖ͯͨΑ͏ɺͲ͜ͷ World ͰͲͷ Entity ͕Ͳ͜ͷ System ʹͳ͕Εͯʙ... ͱ͍͏͜
ͱ͕ෳࡶʹͳΓ͍͢ঢ়ଶͰ͢ɻࣗΒ͏·͘ࢥߟΛཧ͠ଓ͚Δ͜ͱ͕εϜʔζͳ։ൃʹ݁͠·
͢ɻͦͷͨΊৗʹɺύϫʔϙΠϯτͷΑ͏ͳͷͰɺͲͷ System ͕Կ Component Λϑϥάͱͯ͠
ݟ͍ͯΔͷ͔ʙͱ͍ͬͨ͜ͱΛਤղͰॻ͖ཹΊΔ͜ͱ͕ඞཁͰ͢ɻ
ͱʹ͔͘ࢀর͕ؔෳࡶʹͳΓ͍͢
ͱʹ͔͘ࢀর͕ؔෳࡶʹͳΓ͍͢ͷͰɺECS ʹ༗ޮͳྑ͍ਤΛॻ͘ํ๏͕͋Εͥͻൃ৴͠
͍͖͍ͯͨͩͨͷͰ͢ɻࢀߟͱͯ͠ࠓճͷ։ൃʹ͋ͨͬͯ࡞ͬͨϑϩʔਤΛܝࡌ͠·͢ɻ
ਤ 4.1: ه๏
ʮه๏ʯͷ௨ΓɺMonoBehaviour ͱ ECS ͷ Client ͱ ECS ͷ Server ͷ 3 ΤϦΞͰ࣮͍ͯͨ͠
ͷͰ͜͏͍͏ܗͱͳ͍ͬͯ·͢ɻWorld ͕ͬͱଟ͍ͷͰ͋Ε֦ு͢Δ͜ͱʹͳΓ·͢ɻ
ਤ 4.2: ࣮ྫ
ʮ࣮ྫʯྫͷಡΈํ͋͑ͯઆ໌͠·ͤΜ͕ɺͶ͑...
63
ୈ 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
ୈ 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
ୈ 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
ୈ 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(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
ୈ 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
ୈ 5 ষ
ήʔϜͷͨΊͷܦ࿏୳ࡧ
ຊষܦ࿏୳ࡧ͕ςʔϚͰ͢ɻܦ࿏୳ࡧɺ͋Δ͔Β͋Δ·ͰͷಓॱΛ୳͢ΞϧΰϦζϜ
Ͱ͢ɻܦ࿏୳ࡧ͍Ζ͍ΖͳͰԠ༻͞Ε͍ͯ·͕͢ɺຊষͰήʔϜͷΩϟϥͷԠ༻͠·͢ɻ
ࢲɺେઓུɺϑΝϛίϯΥʔζͳͲΛ༡ͼͳ͕ΒɺҠಈίετΛߟྀͨ͠ɺҠಈՄೳྖҬͷಛ
ఆͲ͏͍ͬͯΔΜͩΖ͏ʁ ͱࢥ͍ͬͯ·ͨ͠ɻࠓͳΒΘ͔Γ·͢ɺܦ࿏୳ࡧΞϧΰϦζϜͰٻ
ΊΒΕ·͢ɻ
ܦ࿏୳ࡧɺͪΐͬͱݡ͍ఢΩϟϥΛ࡞Δ࣌ʹศརͰ͢ɻ·ͨɺઓུήʔϜʹ͓͍ͯࠜװػೳͰ
͢ɻຊষ͕ɺܦ࿏୳ࡧͷཧղͷҰॿʹͳΕ͍Ͱ͢ɻ
λʔήοτಡऀ
ήʔϜΛ͍͔ͭ͘࡞ͬͨܦݧ͕͋ΓɺͦΖͦΖݡ͍ఢͷಈ͖Λ࡞ͬͯΈ͍ͨਓɻԿΒ͔ͷཧ༝Ͱ
Unity ͷφϏϝογϡҎ֎ͷํ๏Λ୳͍ͯ͠Δਓɻ
ॻ͘͜ͱ
ܦ࿏୳ࡧͷجૅͰ͋ΔμΠΫετϥ๏ͱ A*Λઆ໌͠·͢ɻͦͷ͋ͱɺܦ࿏୳ࡧΛগ͠Ԡ༻͠·͢ɻ
΄΅ʮήʔϜ։ൃऀͷͨΊͷ AI ೖʯͷ 7 ষʮA*ΞϧΰϦζϜʹΑΔܦ࿏୳ࡧʯΛࢲ͕ Unity Ͱ
ίʔυΛॻ͖ͳ͕Βֶशɺݕূͨ͠༰ʹͳΓ·͢ɻ
ॻ͔ͳ͍͜ͱ
ॲཧෛՙܰݮͳͲͷ࠷దԽʹ͍ͭͯॻ͖·ͤΜɻ
5.1 ήʔϜͷܦ࿏୳ࡧ
ήʔϜͰఢΩϟϥ͕ಈ͖·͢ɻఢ͕ಈ͘ͱ͍͏͜ͱɺ͍ҙຯͰఢͷ AI Λ࡞ͬͨ͜ͱʹͳΓ
·͢ɻఢͷ AI Λ࡞ΔͱҰݴͰݴͬͯɺήʔϜʹΑͬͯͦͷ AI ผʹͳΓ·͢ɻ֨ಆήʔϜɺ
RTSɺFPSɺRPGɺΞΫγϣϯήʔϜ...ɺͦΕͧΕήʔϜͷϧʔϧͱڥ͕ҧ͍·͢ɻͦΕΒΛಉ
69
ୈ 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
ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.2 ܦ࿏୳ࡧΞϧΰϦζϜ
ʹΞϧΰϦζϜ͕ࡌ͍ͬͯ·͢ɻਖ਼ɺࢲͦΕΒΛಡΜͰҿΈࠐΊͣɺίʔυʹམͱ͠ࠐΊ·ͤ
ΜͰͨ͠ɻͦͷޙɺ
ʮήʔϜ։ൃऀͷͨΊͷ AI ೖʯ
ʢҎԼ AI ೖʣͷ 7 ষʮA*ΞϧΰϦζϜʹΑ
Δܦ࿏୳ࡧʯΛಡΜͰཧղͰ͖·ͨ͠ɻ
ཁૉͷઆ໌
ΞϧΰϦζϜͷઆ໌ʹೖΔલʹཁૉͷ໊લͱҙຯΛఆٛ͠·͢ɻ
• ϑΟʔϧυ
– ελʔτ:୳ࡧͷ։࢝Ͱ͢ɻ
– ΰʔϧ:୳ࡧͷऴྃͰ͢ɻ
– น:௨Εͳ͍Ͱ͢ɻ
– ಓ:௨ΕΔͰ͢ɻίετΛ࣋ͪ·͢ɻ
– ఢ:ڴҖΛܭࢉ͢Δͱ͖ͷىͱͳΓ·͢ɻ
ਤ 5.1 ɺ୳ࡧͷରͰ͋ΔϑΟʔϧυϚοϓͰ͢ɻࠨԼʹελʔτ͕͋Γɺӈ্ʹΰʔϧ͕͋Γ
·͢ɻͦͷؒʹϒϩοΫ͕͋Γ·͢ɻ
ਤ 5.1: ϑΟʔϧυϚοϓ
ͱล
ຊདྷɺμΠΫετϥ๏ A*͕ରͱ͢ΔͷάϥϑͰ͢ɻάϥϑɺͱลͰఆٛ͞Ε·͢ɻ
ลʹϚΠφεͰͳ͍ॏΈΛͨͤΒΕ·͢ɻϚΠφεΛ࣋ͭ߹ผͷΞϧΰϦζϜ (ϕϧϚϯ
rϑΥʔυ๏ ) Λ༻͢Δඞཁ͕͋Γ·͢ɻ
ࠓճͷ୳ࡧରͰ͋ΔϑΟʔϧυɺήʔϜʹ͍͍͢Α͏ʹάϦουϚοϓΛ 2 ࣍ݩྻͰද
ݱ͠·͢ɻɺ͜ͷάϦουϚοϓͷηϧͰ͢ɻลɺηϧʹྡ͢Δ 8 ݸͷηϧͷؒʹ͋Δͱ
ఆٛ͠·͢ɻลͷॏΈɺྡ͢Δηϧʹίετͱͯͨͤ͠·͢ɻ
71
ୈ 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
ୈ 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
ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.3 ܦ࿏୳ࡧͷԠ༻
5.3 ܦ࿏୳ࡧͷԠ༻
࠷ܦ࿏ΛٻΊΔ͜ͱ͕Ͱ͖ͨͷͰɺԠ༻͠·͢ɻμΠΫετϥ๏ A*ɺ࠷ܦ࿏Λݟ͚ͭ·
͢ɻ
ʮ࠷ʯͰ͢ͷͰɺ͍ۙҐஔʹ͍ΔΩϟϥ΄΅ಉ͡ܦ࿏ΛͨͲΓ·͢ɻଟগඇޮͳܦ࿏Ͱɺ
όϦΤʔγϣϯ͕๛͔ʹ͍ͨ͠߹Λߟ͑·͢ɻ
ΞϧΰϦζϜͰͳ͘ೖྗΛม͑Δ
ܦ࿏ͷόϦΤʔγϣϯΛ࡞Ζ͏ͱߟ͑ͨͱ͖ɺ࠷ॳΞϧΰϦζϜΛमਖ਼͠Α͏ͱ͠·ͨ͠ɻ͔͠
͠ɺͦͷΞϓϩʔνͰԿ࣮ݱͰ͖·ͤΜͰͨ͠ɻ
͋Δͱ͖ɺೖྗΛมԽͤ͞Ε͓ͷͣͱ݁Ռ͕มΘΔ͜ͱʹؾ͖·ͨ͠ɻΞϧΰϦζϜ࠷ܦ
࿏Λ୳͢··Ͱ͕͢ɺ࠷Λఆٛ͢ΔίετϚοϓΛมԽͤ͞·͢ɻ
ϥϯμϜΛίετʹՃࢉ
͜͜·ͰͷίετڑͰ͋Γɺ্Լࠨӈ 1ɺࣼΊ 1.4 ͱ͍ͯ͠·ͨ͠ɻ͜ΕʹΏΒ͗Λͨ
ͤ·͢ɻ·ͣϑΟʔϧυίετϚοϓΛՃ͠·͢ɻ͜ͷϚοϓʹ 1ʙ3 ͷϥϯμϜΛ͍Ε·͢ɻ
ͦͯ͠ɺίετͷܭࢉ࣌ʹͦͷΛ্Լʷ 1 ഒɺࣼΊʷ 1.4 ഒʹͯ͠ɺA*ΛదԠ͠·͢ɻͦͷ
݁Ռɺਤ 5.4 Ͱ͢ɻܦ࿏ʹόϦΤʔγϣϯ͕Ͱ͖·ͨ͠ɻΞϧΰϦζϜ࠷ܦ࿏ΛٻΊ͍ͯ·͢
͕ɺͦͷίετ͕༳Β͙͜ͱͰܦ࿏ʹհೖͰ͖·ͨ͠ɻ
ਤ 5.4: ج४ίετʹΏΒ͗Λ༩͑Δ
74
ୈ 5 ষ ήʔϜͷͨΊͷܦ࿏୳ࡧ 5.4 ·ͱΊ
ڴҖΛίετʹՃࢉ
͏গ͠ݡ͍ܦ࿏ΛٻΊ·͢ɻةͳ͍ॴ͔ΒڑΛͱΔ͜ͱͰɺ࠷Ͱͳ͍͚ΕͲɺ҆શͳ
ܦ࿏ͰҠಈ͢ΔఢΛߟ͑·͢ɻઌ΄ͲϥϯμϜͷΛೖΕ͍ͯͨϑΟʔϧυίετϚοϓʹɺࠓ
ڴҖΛೖΕ·͢ɻڴҖఢ (Enemy) ʹ͍ۙ΄Ͳ͕େ͖͘ (2) ͳΓɺΕΔ΄Ͳখ͘͞ (1) ͳ
Γ·͢ɻ
͜ͷܭࢉ݁Ռ͕ਤ 5.5 Ͱ͢ɻڴҖ (Enemy) Λආ͚ͨܦ࿏ʹͳΓ·ͨ͠ɻ
ਤ 5.5: ڴҖϚοϓΛߟྀͨ͠ܦ࿏
5.4 ·ͱΊ
༗໊ͳܦ࿏୳ࡧͰ͋ΔɺμΠΫετϥ๏ͱɺA*Λ࣮ͯ͠ɺͦͷڍಈΛ֬ೝ͠·ͨ͠ɻAI ೖΛ
ಡΜͰཧղͨͭ͠Γʹͳ͍ͬͯͯɺ͍͟ίʔυΛॻ͜͏ͱࢥ͏ͱཧղͷΓͳ͍ͱ͜Ζ͕ු͖ூ
ΓʹͳΓ·͢ɻવͰ͕͢ɺࡉ͔͍·Ͱཧղ͠ͳ͍ͱίʔυ͠·ͤΜɻखΛಈ͔͢ॏཁੑΛ
࠶֬ೝ͢Δ͜ͱʹͳΓ·ͨ͠ɻ·ͨɺUnity Ͱखܰʹ݁ՌΛදࣔͰ͖ͨͷͰɺΞϧΰϦζϜͷݕূ͕
༧Ҏ্ʹεϜʔζʹߦ͑·ͨ͠ɻ
ຊষͰܦ࿏୳ࡧΛςʔϚʹબΜͩͷɺݸਓతʹ RTS Λ࡞Ζ͏ͱاը͍ͯ͠Δ͔ΒͰ͢ɻܦ࿏୳
ࡧήʔϜͷࠜװ෦ʹͳΔͷͰɺҰ͔ͬ͠Γͱֶश͠Α͏ͱࢥ͍·ͨ͠ɻͰ͖ΕɺήʔϜͷϓ
ϩτλΠϓͷ࡞·ͰͨͲΓண͖͔ͨͬͨͷͰ͕͢ɺ೦ͳ͕Βؒʹ߹͍·ͤΜͰͨ͠ɻ
5.5 ͓·͚
ࢥ͍͍ͭͨͷͷݕূ͕ؒʹ߹Θͳ͔ͬͨΞΠσΞͰ͢ɻ
ෳͷλʔήοτ
ະݕূͰ͢ɻ
ʮෳͷఢ͕͍ͯɺ͍ۙఢʹ͔͏ʯ߹ɺA*͑ͳ͍͜ͱʹؾ͖·ͨ͠ɻෳ
ͷత͕͋Δͱɺ͏·͘ώϡʔϦεςΟοΫؔΛఆٛͰ͖ͳ͍͔ΒͰ͢ɻͲ͏Βɺ۪ʹμΠ
75
ୈ 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
ୈ 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
ୈ 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();
_agent.isStopped = true;
_agent.SetDestination(new Vector3(0, 0, 0));
_rigidbody = GetComponent();
}
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
ୈ 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
ୈ 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 _nearbyAgents = new List();
private void Start()
{
_navMeshAgent = GetComponent();
}
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
ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻
if (colliders[i].TryGetComponent(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
ୈ 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
ୈ 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
ୈ 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
ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻
ਤ 6.2: ܦ࿏࣋ͪΤʔδΣϯτʹै͍ͯ͠Δ༷ࢠ
͔͠͠ɺܦ࿏࣋ͪΤʔδΣϯτ͕ूஂʹແࢹ͞ΕΔ͜ͱଟ͋͘Γ·ͨ͠ɻ
ਤ 6.3: ࠷ॳͷܦ࿏࣋ͪΤʔδΣϯτ͕ແࢹ͞Ε༷ͨࢠ
85
ୈ 6 ষ Unity ͷ Navigation ͷ׆༻ 6.3 Navigation ͷԠ༻
ߟ
ظ௨Γʹूஂ͕Ҡಈͨ͠߹͋Εɺूஂ͕ܦ࿏࣋ͪΤʔδΣϯτΛແࢹͯ͠Ͳ͔͜ʹߦͬͯ
͠·͏͜ͱଟ͋͘Γ·ͨ͠ɻϑϩοΩϯάपғͷΤʔδΣϯτʹ߹ΘͤΔ͜ͱͰूஂΛܗ͢Δ
ͨΊɺ1 ମͷΤʔδΣϯτ͕ผͷಈ͖Λͯ͠ूஂʹӨڹΛ༩͑ͮΒ͍ͷͩͱߟ͑ΒΕ·͢ɻ
·ͨɺࠓճนΛߟྀ͍ͯ͠·ͤΜͰ͕ͨ͠ɺ࣮ࡍนͷճආͳͲߦ͏ඞཁ͕͋ΔͨΊɺΑΓ
அ͕ൃੜ͘͢͠ͳΓ·͢ɻ
ಛఆͷΤʔδΣϯτͷಈ͖ʹपΓ͕ڧ͘ै͏Α͏ʹ͢ΔʹɺΤʔδΣϯτ͝ͱʹӨڹ (ॏΈ)
ΛઃఆͰ͖ΔΑ͏ʹ͢ΔͳͲͷௐ͕ඞཁͦ͏Ͱ͢ɻ
86
ୈ 7 ষ
70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ
7.1 ΠϯτϩμΫγϣϯ
ຊষͰɺUnity Ͱ͍ΘΏΔ౷ҰγΣʔμʔΛ։ൃ͍ͯ͘͠ʹ͋ͨͬͯɺ͞·͟·ͳόϦΤʔγϣ
ϯΛ͍͔ʹ੍ޚ͢Δ͔ʹ͍ͭͯ Tips తʹհ͠·͢ɻ
ରಡऀ
ຊষɺUnity ͰγΣʔμʔΛॻ͍ͨ͜ͱ͕͋Δਓ͚ͷ༰ͱͳ͍ͬͯ·͢ɻUnity ͷγΣʔ
μʔ͍Ζ͍Ζ͋Γ·͕͢ɺதͰ ShaderLab, HLSL/Cg ʹΑΔγΣʔμʔɾϑϥάϝϯτ
γΣʔμʔΛલఏͱ͍ͯ͠·͢ɻҰํͰɺαʔϑΣεγΣʔμʔ͓Αͼ Shader Graph ʹ͍ͭͯѻ
͍·ͤΜɻ·ͨɺϞόΠϧɾϩʔΤϯυ (Universal Render Pipeline) Λఆ͍ͯ͠·͢ɻڞ௨͢Δ
෦͋Δͱࢥ͍·͕͢ɺϋΠΤϯυ͚ͩͱ·ͨࣄ͕ҟͳΔ͔͠Ε·ͤΜɻ
େྔͷγΣʔμʔ
ϓϩδΣΫτʹΑΓ͚Γͩͱࢥ͍·͕͢ɺϞσϧΤϑΣΫτͷදݱΛ࣮ݱ͢ΔͨΊʹΑΓଟػೳ
ͳγΣʔμʔΛ։ൃ͍ͯ͘͜͠ͱʹͳΔͱࢥ͍·͢ɻฐࣾʹ͓͍͍ͯΖ͍ΖͳϓϩδΣΫτͰͦΕ
ͧΕͷ࡞ΓํͰγΣʔμʔͷ։ൃ͕ߦΘΕ͖ͯ·ͨ͠ɻͦͷதͷϓϩδΣΫτͷҰͭɺଟ༷ͳཁ݅
ʹରԠ͢ΔͨΊʹଟ͘ͷγΣʔμʔ͕࡞ΒΕɺͦͷ࠷ऴతʹ 70 Ҏ্ʹ͓Αͼ·ͨ͠ʢਤ 7.1ʣ
ɻ
87
ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ 7.1 ΠϯτϩμΫγϣϯ
ਤ 7.1: େྔͷγΣʔμʔ*1
͜ΕΒͦΕͧΕ͕·ͬͨ͘ผͱ͍͏Θ͚Ͱͳ͘ɺҎԼͷػೳੑͷҧ͍ʹΑͬͯগͣͭ͠ҟͳ
Δͱ͍͏ͷͰ͢ɻ
• ෆಁ໌ɾಁ໌ͷΓସ͑
• ϒϨϯυϞʔυͷΓସ͑
• ֤छػೳͷ༗ޮɾແޮ
– ςΫενϟϛϥʔϦϯά
– ϥϯϓςΫενϟ
– ϑΥʔϧΦϑ
– etc.
ࢲ͕ݱࡏܞΘΔϓϩδΣΫτͰɺॳ͜ΕΒͷγΣʔμʔΛࢿ࢈ͱͯ͠׆༻͢Δ͕ग़͍ͯ·͠
͕ͨɺࠓޙͷվम͞ΒͳΔཁ݅ରԠɺύϑΥʔϚϯεͷ؍͔Βɺ͜ΕΒΛࢀߟʹͭͭ͠৽ن
ʹ౷ҰతͳγΣʔμʔΛ։ൃ͢Δ͜ͱʹͳΓ·ͨ͠ɻ
γΣʔμʔΛڞ௨Խ͢ΔϞνϕʔγϣϯ
ίʔυత؍Ͱɺڞ௨෦ͷ࣮ʹมߋ͕ੜͨ͡ࡍʹमਖ਼͠ͳ͚ΕͳΒͳ͍Օॴ͕ݮΓɺϝϯ
ςφϯείετ͕Լ͕Δ͕͋Γ·͢ɻγΣʔμʔϑΝΠϧ͕͔Ε͍ͯͯ#include Λ༻ͯ͠
ίʔυͷڞ௨ԽΛਤΔ͜ͱՄೳͰ͕͢ɺґଘؔهड़͕ෳࡶԽͯ͠͠·͏͜ͱͱɺShaderLab ଆ
ͷύϥϝʔλΛڞ௨ཧͰ͖ͳ͍ͱ͍͏ͰɺΓϝϯςφϯείετߴ͍ͱײ͡·͢ɻ
ύϑΥʔϚϯε؍ͰԸܙ͕͋Γ·͢ɻUnity 2018 ͔ΒैདྷͷඳըγεςϜʹΘΔ֦ுՄ
*1 ໊લ࣮ࡍͷͷ͔Βएׯมߋ͍ͯ͠·͢
88
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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
ୈ 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 // #pragma vertex vert
#pragma fragment frag
sampler2D _MainTex;
...
half4 frag(v2f i) : SV_Target {
return tex2D(_MainTex, i.uv);
}
ENDHLSL // }
}
}
2 ͭͷҟͳΔߏจ͕ࠞࡏ͍ͯ͠Δ͔Β͔ɺଟ͘ͷΤσΟλͰΠϯσϯτϑΥʔϚολͷڍಈ͕͓
102
ୈ 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
ୈ 7 ষ 70 ݸ͘Β͍ͷγΣʔμʔΛ·ͱΊͨ 7.7 ·ͱΊ
ʹଟذʹΔػೳͷՃ͕ՄೳʹͳΓ·ͨ͠ɻγΣʔμʔͱ͍͏ͱදݱΛ͍͔ʹ࣮͢Δ͔ͱ͍͏
͕·ͣ͋Δͱࢥ͍·͕͢ɺಛʹܧଓӡ༻Λࢦ͢ήʔϜʹ͓͍ͯίʔυͷڞ௨Խϝϯςφϯε
ίετɺγΣʔμʔίʔυͷϨϏϡʔͱ͍ͬͨ։ൃख๏ʹ͍ͭͯ͏·͘ӡ༻͍͖͍ͯͨ͠ͱ͜Ζ
Ͱ͢ɻ
104
ஶऀհ
দݪ ৴ (ୈ 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
ஶऀհ
ɹ
YuukiARIA (ୈ 7 ষ୲)
։ൃຊ෦ CTO ࣨॴଐɻٕज़ॻయ 6 ҎདྷͷࣥචʹͳΓ·͢ɻ࠷ۙγΣʔμʔͷษڧதͰ͢ɻ
ɹ
ౢࣇ ະདྷ (Graphic designer / Art director)
ϛΫγΟ σβΠϯຊ෦ ΫϦΤΠςΟϒࣨ ৫։ൃάϧʔϓॴଐࠓճɺΞΠίϯΠϥετද
ࢴσβΠϯΛ୲ɻ༻ޠͳͲษڧʹͳΓ·ͨ͠ʂ ײँɻ
ɹ
ਿా ֆඒ (੍࡞ਐߦ, GitHub: esugita, Twitter: @semisemi7)
ݩʑΤϯδχΞͰɺαʔόαΠυ͔ΒεϚϗΞϓϦ·Ͱ෯͘ܦݧ͍ͯ͠·͕͢ɺࠓɺ
DevRel ͱͯ͠ɺࣾ֎ͷٕज़ऀίϛϡχςΟͷࢧԉΛߦͬͨΓɺٕज़ใΛ͍ͯ͠·͢ɻ
ɹ
تଟ ޭ࣍ (੍࡞Ξγετ, GitHub: kojikita, Twitter: @kojikita)
DevRel νʔϜͰษڧձΠϕϯτͷӡӦΛ͍ͯ͠·͢ɻ࠷ۙࣄݟͨ YouTuber Խ
͍ͯ͠·͢ɻ
106
mixi tech note #06
2021 7 ݄ 10 ɹॳ൛ୈ 1 ɹൃߦ
ஶɹऀ גࣜձࣾϛΫγΟ ༗ࢤ
ൃߦॴ גࣜձࣾϛΫγΟ
ҹॴ ޫاը
ɹ
mixi, Inc.