泚ïŒãã®ãã¥ãŒããªã¢ã«ã¯Unity 2017.1.0åãã«æžãããŠãããäžçŽãŠãŒã¶ãŒã察象ãšããŠããŸãã Unityã§ã®ã²ãŒã ã®ããã°ã©ãã³ã°ã«ãã§ã«æ
£ããŠããããšã¯çè§£ã§ããŸãã
Unityéçºè
ã¯ãããããæåã§ã¬ãã«ãäœæããååãªçµéšãæã£ãŠããŸãã ãããããã®å Žã§ã¬ãã«ãçæããããšæã£ãããšã¯ãããŸããïŒ ä»¥åã«äœæãããã¢ãã«ã®åçŽãªé
眮ãšã¯å¯Ÿç
§çã«ãåºãšå£ã®ã¡ãã·ã¥ã®æé çæã¯ãã²ãŒã ã®ã¯ããã«é«ãæè»æ§ãšåçŸæ§ãæäŸããŸãã
ãã®ãã¥ãŒããªã¢ã«ã§ã¯ã次ã®ããšãåŠã³ãŸãã
- è¿·è·¯ãèµ°ãã²ãŒã ãäœæããäŸã䜿çšããŠãæç¶ãçã«ã¬ãã«ãçæããŸãã
- è¿·è·¯ããŒã¿ãçæããŸãã
- è¿·è·¯ããŒã¿ã䜿çšããŠã¡ãã·ã¥ãæ§ç¯ããŸãã
ä»äºãå§ãã
ã»ãšãã©ã®ã¢ã«ãŽãªãºã ïŒ
ãã®ã¢ã«ãŽãªãºã ã
ãã®ã¢ã«ãŽãªãºã ãªã©ïŒã¯ããçæ³çãªãå¯ãªè¿·è·¯ãã€ãŸã1ã€ã®æ£ãããã¹ã®ã¿ãæã¡ãã«ãŒããæããªããã®ãäœæããŸãã ããºã«ã®æ°èã»ã¯ã·ã§ã³ã«æ²èŒãããŠããè¿·å®®ã®ããã«èŠããŸãã
ãã ããè¿·è·¯ãäžå®å
šã§ã«ãŒããããå Žåãã»ãšãã©ã®ã²ãŒã ã®æ¹ããã¬ã€ããããã§ãã ãããã¯åºå€§ã§ãçãæ²ããããã£ãå»äžã§ã¯ãªãããªãŒãã³ã¹ããŒã¹ã§æ§æãããŠããå¿
èŠããããŸãã ããã¯ãæç¶ãã¬ãã«ãããã»ã©ãè¿·å®®ãã§ã¯ãªãããã³ãžã§ã³ã§ãããªããè
ã®ãããªãžã£ã³ã«ã«ç¹ã«åœãŠã¯ãŸããŸãã
ãã®ãã¥ãŒããªã¢ã«ã§ã¯ã
ããã§èª¬æããæãåçŽãªè¿·è·¯ã¢ã«ãŽãªãºã ã®1ã€ãå®è£
ã
ãŸã ã æå°éã®åŽåã§ã²ãŒã å
ã®è¿·è·¯ãå®çŸããããã«éžæããŸããã ãã®åçŽãªã¢ãããŒãã¯ãããã«ãªã¹ããããŠããå€å
žçãªã²ãŒã ã§ããŸãæ©èœããããã
Speedy Treasure ThiefãšåŒã°ããã²ãŒã ã§è¿·è·¯ãäœæããããã«äœ¿çšã§ããŸãã
ãã®ã²ãŒã ã§ã¯ãåã¬ãã«ã¯å®ç®±ãé ãããæ°ããè¿·è·¯ã§ãã ããããèŠåå¡ãæ»ãåã«åœŒãæçŽ¢ããŠéããæéã¯ããŸããããŸããïŒ åã¬ãã«ã«ã¯æéå¶éããããæãŸããŸã§ãã¬ã€ã§ããŸãã ç²åŸãããã€ã³ãã¯ãçãã å®ç©ã®éã«ãã£ãŠç°ãªããŸãã
ãŸããUnityã§æ°ãã空ã®ãããžã§ã¯ããäœæããŸãã
空çœã®
ãããžã§ã¯ããããŠã³ããŒãããŠè§£åããæ°ãããããžã§ã¯ã** proc-mazes-starter.unitypackage **ã«ã€ã³ããŒãããŸãã ãã©ããã³ã³ãã³ãã«ã¯æ¬¡ã®ã³ã³ãã³ããå«ãŸããŸãã
- ã°ã©ãã£ãã¯ãã©ã«ããŒãã²ãŒã ã«å¿
èŠãªãã¹ãŠã®ã°ã©ãã£ãã¯ãå«ãŸããŠããŸãã
- ã·ãŒã³ã·ãŒã³ã¯ããã¬ãŒã€ãŒãšUIãå«ããã®ãã¥ãŒããªã¢ã«ã®ãœãŒã¹ã·ãŒã³ã§ãã
- 2ã€ã®ãã«ããŒã¹ã¯ãªãããå«ãScriptsãã©ã«ããŒã ãã¥ãŒããªã¢ã«ã®å®è¡äžã«æ®ãã®ã¹ã¯ãªãããäœæããŸãã
ä»äºãå§ããã«ã¯ããã§ååã§ãã ãããã®åãã€ã³ãã«ã€ããŠã¯ãåŸã§è©³ããæ€èšããŸãã
ã³ãŒãã¢ãŒããã¯ãã£ã®å®çŸ©
空ã®ãããžã§ã¯ããã·ãŒã³ã«è¿œå ããããšããå§ããŸãããã
GameObjectâžCreate Emptyãéžæãã
Controllerãšããååãä»ããŠïŒXïŒ0ãYïŒ0ãZïŒ0ïŒã«é
眮ããŸãã ãã®ãªããžã§ã¯ãã¯ãã²ãŒã ãå¶åŸ¡ããã¹ã¯ãªããã®æ¥ç¶ç¹ã«ãããŸããã
ãããžã§ã¯ãã®
Scriptsãã©ã«ããŒã§ã
GameControllerãšããCïŒã¹ã¯ãªãããäœæããå¥ã®ã¹ã¯ãªãããäœæããŠ
MazeConstructorãšããååã
ä»ããŸãã æåã®ã¹ã¯ãªããã¯ã²ãŒã å
šäœãå¶åŸ¡ãã2çªç®ã®ã¹ã¯ãªããã¯è¿·è·¯ãçæããŸãã
GameControllerã®ãã¹ãŠã®è¡ã次ã®ã³ãŒãã«çœ®ãæããŸãã
using System; using UnityEngine; [RequireComponent(typeof(MazeConstructor))]
äœæãããã®ãç°¡åã«èª¬æããŸãã
RequireComponent
屿§ã¯ããã®ã¹ã¯ãªãããGameObjectã«è¿œå ãããšãã«MazeConstructorã³ã³ããŒãã³ãã远å ããŸãã- ãã©ã€ããŒã倿°ã¯ã
GetComponent()
ã«ãã£ãŠè¿ããããªã³ã¯ãä¿æããŸãã
ãã®ã¹ã¯ãªãããã·ãŒã³ã«è¿œå ããŸã
ãProjectãŠã£ã³ããŠãã
GameControllerã¹ã¯ãªããã
HierarchyãŠã£ã³ããŠã®
GameObject Controllerã«ãã©ãã°ããŸãã
MazeConstructorã
Controllerã«è¿œå ãããŠããããšã«æ³šæããŠãã ããã ããã¯ã
RequireComponent
屿§ã®ãããã§èªåçã«
RequireComponent
ãŸãã
次ã«ã
MazeConstructorã®ãã¹ãŠã次ã®ã³ãŒãã«çœ®ãæããŸãã
using UnityEngine; public class MazeConstructor : MonoBehaviour {
ããã§äœãèµ·ãããã§ãïŒ
- ããããã¹ãŠã®ãã£ãŒã«ãã¯ã ã€ã³ã¹ãã¯ã¿ãŒã§å©çšã§ããŸãã
showDebug
ã¯ãããã°è¡šç€ºãåãæ¿ããããŸããŸãªãããªã¢ã«ãªã³ã¯ã¯çæãããã¢ãã«ã®ãããªã¢ã«ã§ãã ãšããã§ã倿°ãprivate
ã§ãã£ãŠãã SerializeField
屿§ã¯Inspectorã«ãã£ãŒã«ãã衚瀺ããŸãã - 次ã¯
data
ããããã£ã§ãã ã¢ã¯ã»ã¹å®£èšïŒããšãã°ãããããã£ãpublic
ãšããŠå®£èšããåŸã private set
å²ãåœãŠãïŒã¯ãã¯ã©ã¹å€ã§èªã¿åãå°çšã«ããŸãã ãããã£ãŠãè¿·è·¯ã®ããŒã¿ãå€éšãã倿Žããããšã¯ã§ããŸããã - è峿·±ãã³ãŒãã®æåŸã®éšåã¯
Awake()
ãŸãã ãã®é¢æ°ã¯ããŒããå²ã3 x 3ã®ãŠãããé
åã§data
ãåæåããŸãã 1ã¯å£ãæå³ãã0ã¯ç©ºãã¹ããŒã¹ãæå³ããŸããã€ãŸããã°ãªããã¯ããã©ã«ãã§ã¯å£ã®ããéšå±ã®ããã«èŠããŸãã
ããã¯ãã§ã«ã³ãŒãã®åªããåºç€ã§ãããä»ã®ãšããã¯äœã衚瀺ããŸããïŒ
è¿·è·¯ããŒã¿ã衚瀺ããŠãã®å€èгã確èªããã«ã¯ã次ã®ã¡ãœããã
MazeConstructorã«è¿œå ããŸãã
void OnGUI() {
ã³ã¡ã³ããããåã»ã¯ã·ã§ã³ãæ€èšããŠãã ããã
- ãã®ã³ãŒãã¯ããããã°è¡šç€ºããªã³ã«ãªã£ãŠãããã©ããã確èªããŸãã
- ããã€ãã®ããŒã«ã«å€æ°ã®åæåïŒä¿åãããè¿·è·¯ã®ããŒã«ã«ã³ããŒãæå€§ã®è¡ãšåãããã³è¡ã
- 2ã€ã®ãã¹ããããã«ãŒãã¯ã2次å
é
åã®è¡ãšåãééããŸãã é
åã®åè¡/åã«å¯ŸããŠãã³ãŒãã¯ä¿åãããå€ããã§ãã¯ããå€ããŒããã©ããã«å¿ããŠã....ããŸãã¯ã==ãã远å ããŸãã ãŸããè¡ã®ãã¹ãŠã®åã調ã¹ãåŸãã³ãŒãã¯æ°ããè¡ã远å ããŠãé
åã®åè¡ãæ°ããè¡ã§å§ãŸãããã«ããŸãã
- æåŸã«ã
GUI.Label()
ã¯äœæãããæååã衚瀺ããŸãã ãã®ãããžã§ã¯ãã¯æ°ãããã¬ãŒã€ãŒåºåGUIã·ã¹ãã ã䜿çšããŸãããå€ãã·ã¹ãã ã¯é«éãããã°ã¡ãã»ãŒãžãäœæããã®ãç°¡åã§ãã
MazeConstructorã³ã³ããŒãã³ãã®
Show Debugãå¿
ãæå¹ã«ããŠãã ããã [
åç]ãã¯ãªãã¯ãããšãä¿åãããè¿·è·¯ããŒã¿ãç»é¢ã«è¡šç€ºãããŸãïŒçŸåšã¯ããã©ã«ãã®è¿·è·¯ã§ãïŒã
ããã¹ã¿ãŒãã§ãïŒ ãã ããã³ãŒãã¯ãŸã è¿·è·¯èªäœãçæããŸããã æ¬¡ã®ã»ã¯ã·ã§ã³ã§ã¯ããã®åé¡ã解決ããæ¹æ³ã説æããŸãã
è¿·è·¯ããŒã¿çæ
ãããŸã§ã®ãšããã
MazeConstructor.GenerateNewMaze()
ã¯ç©ºã§ãã ããã¯ç©ºçœã§ãåŸã§å
¥åããŸãã
GameControllerã¹ã¯ãªããã®
Start()
ã¡ãœããã®æåŸã«ã次ã®è¡ã远å ããŸãã 圌女ã¯ãã®ã¹ã¿ãã¡ãœãããåŒã³åºããŸãã
generator.GenerateNewMaze(13, 15);
ãããžãã¯ãçªå·13ãš15ã¯ãè¿·è·¯ã®ãµã€ãºã決å®ããã¡ãœããã®ãã©ã¡ãŒã¿ãŒã§ãã ãŸã 䜿çšããŠããŸãããããããã®ãµã€ãºãªãã·ã§ã³ã¯ãã°ãªããã®è¡ãšåã®æ°ãæå®ããŸãã
ãã®æç¹ã§ãè¿·è·¯ã®ããŒã¿ã®çæãéå§ã§ããŸãã æ°ãã
MazeDataGeneratorã¹ã¯ãªãããäœæããŸãã ãã®ã¯ã©ã¹ã¯ããŒã¿çæããžãã¯ãã«ãã»ã«åãã
MazeConstructorã§äœ¿çšãããŸãã æ°ããã¹ã¯ãªãããéãããã¹ãŠã次ã®ã³ãŒãã«çœ®ãæããŸãã
using System.Collections.Generic; using UnityEngine; public class MazeDataGenerator { public float placementThreshold;
ãã®ã¯ã©ã¹ã¯MonoBehaviourãç¶æ¿ããªãããšã«æ³šæããŠãã ããã ã³ã³ããŒãã³ããšããŠçŽæ¥äœ¿çšãããã®ã§ã¯ãªãã
MazeConstructorå
ã§ã®ã¿äœ¿çšãããããã
MonoBehaviourã®æ©èœãæã€å¿
èŠã¯ãããŸããã
- ã¹ããŒã¹ã空ã§ãããã©ãããæ±ºå®ããããã«ã
placementThreshold
ã¯ããŒã¿çæã¢ã«ãŽãªãºã ã«ãã£ãŠäœ¿çšãããŸãã ããã©ã«ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ãŒã§ãã®å€æ°ã«å²ãåœãŠãããŸãããä»ã®ã³ãŒããçæãããè¿·è·¯ã®èšå®ãå¶åŸ¡ã§ããããã«public
ãããŸãã - ã¡ãœããã®1ã€ïŒãã®å Žåã¯
FromDimensions()
ïŒãåã³ç©ºã«ãªãã空çœãæ®ããŸããããã¯åŸã§å
¥åããŸãã
次ã«ã
MazeConstructorã«ã³ãŒãã®ããã€ãã®ã»ã¯ã·ã§ã³ã远å ããŠã
ã¹ã¿ãã¡ãœããã
åŒã³åºããããã«ããŸãã ãŸããããŒã¿ãžã§ãã¬ãŒã¿ãŒãæ ŒçŽãããã©ã€ããŒã倿°ã远å ããŸãã
private MazeDataGenerator dataGenerator;
次ã«ã
Awake()
ã§ã€ã³ã¹ã¿ã³ã¹ãäœæãã
Awake()
ã¡ãœããã®å
é ã«æ¬¡ã®è¡ã远å ããŠããžã§ãã¬ãŒã¿ãŒãæ°ãã倿°ã«ä¿åããŸãã
dataGenerator = new MazeDataGenerator();
æåŸã«ã
GenerateNewMaze()
FromDimensions()
ã§
FromDimensions()
ãåŒã³åºããã°ãªãããµã€ãºãæž¡ããçµæã®ããŒã¿ãä¿åããŸãã
GenerateNewMaze()
// stub to fill in
ãšèšãè¡ãèŠã€ããŠã次ã®è¡ã«çœ®ãæããŸãã
if (sizeRows % 2 == 0 && sizeCols % 2 == 0) { Debug.LogError("Odd numbers work better for dungeon size."); } data = dataGenerator.FromDimensions(sizeRows, sizeCols);
çæãããè¿·è·¯ã¯å£ã«å²ãŸããããããµã€ãºã«å¥æ°ã䜿çšããæ¹ããããšããèŠåãããã«è¿œå ãããŸããã
ã²ãŒã ãå®è¡ããŠã空ã®è¿·è·¯ããŒã¿ã衚瀺ããŸãããæ£ãã寞æ³ã§ïŒ
ãããïŒ ãã¹ãŠãè¿·è·¯ããŒã¿ãä¿åããŠè¡šç€ºããæºåãã§ããŸããïŒ
FromDimensions()
ããè¿·è·¯çæã¢ã«ãŽãªãºã ãå®è£
ããæãæ¥
FromDimensions()
ã
äžèšã®ã¢ã«ãŽãªãºã ã¯ãå£ãé
眮ãããããã¯ãã飿¥ã¹ããŒã¹ãéžæããããšã«ãããã°ãªããå
ã®ãã¹ãŠã®ã»ã«ããã€ãã¹ããŸãïŒã€ãŸãããã¹ãŠã®ã»ã«ã§ã¯ãããŸããïŒïŒã ããã§ããã°ã©ã ãããã¢ã«ãŽãªãºã ã¯ãããšã¯å°ãç°ãªããŸãããŸããã¹ããŒã¹ãã¹ããããããã©ãããæ±ºå®ããŸããããã«ãããè¿·è·¯ã«ç©ºãã¹ããŒã¹ãåºçŸããå¯èœæ§ããããŸãã ã¢ã«ãŽãªãºã ã¯å€ãã®æ
å ±ãä¿åããããè¿·è·¯ã®æ®ãã®éšåãããšãã°ééããå¿
èŠã®ããåå²ç¹ã«ã€ããŠå€ããç¥ãå¿
èŠããªããããã³ãŒãã¯éåžžã«åçŽã«ãªããŸãã
ãã®è¿·è·¯çæã¢ã«ãŽãªãºã ãå®è£
ããã«ã¯ã
FromDimensions()
ãã
FromDimensions()
次ã®ã³ãŒãã远å ããè¡ã
// stub to fill in
眮ãæããŠå
¥å
// stub to fill in
ãŸãã
int rMax = maze.GetUpperBound(0); int cMax = maze.GetUpperBound(1); for (int i = 0; i <= rMax; i++) { for (int j = 0; j <= cMax; j++) {
ã芧ã®ãšãããã³ãŒãã¯2Dé
åã®å¢çãååŸããããããã€ãã¹ããŸãã
- åã°ãªããã»ã«ã«ã€ããŠãçŸåšã®ã»ã«ãã°ãªãããè¶
ããŠãããã©ããïŒã€ãŸããã€ã³ããã¯ã¹ã®ãããããé
åã®å¢çäžã«ãããã©ããïŒãæåã«ç¢ºèªããŸãã ãããããªãã圌ã¯1ãå²ãåœãŠãå£ãèšå®ããŸãã
- 次ã«ãã³ãŒãã¯ã 2çªç®ã®ã»ã«ããšã«ã¢ã¯ã·ã§ã³ãå®è¡ããããã«ã座æšãå®å
šã«2ã§é€ç®ããããã©ããã確èªããŸãã ãŸãããã®ã»ã«ãã©ã³ãã ã«ã¹ãããããŠã¢ã¬ã€ãèµ°æ»ãç¶ããããã«ãäžèšã®
placementThreshold
å€ã®è¿œå ãã§ãã¯ããããŸãã - æåŸã«ãã³ãŒãã¯çŸåšã®ã»ã«ãšã©ã³ãã ã«éžæããã飿¥ã»ã«ã«å€1ãå²ãåœãŠãŸãã ãã®ã³ãŒãã¯ãããã€ãã®3é
æŒç®ã䜿çšããŠ0ã1ããŸãã¯-1ãé
åã€ã³ããã¯ã¹ã«è¿œå ãã飿¥ã»ã«ã®ã€ã³ããã¯ã¹ãååŸããŸãã
è¿·è·¯ããŒã¿ãå床衚瀺ããŠãçæãããè¿·è·¯ãã©ã®ããã«èŠãããã確èªããŸãã
ã²ãŒã ãåèµ·åããŠãè¿·è·¯ããŒã¿ãæ¯åæ°ããããšã確èªããŸãã ãããïŒ
次ã®å€§ããªèª²é¡ã¯ã2Dè¿·è·¯ããŒã¿ãã3Dã¡ãã·ã¥ãçæããããšã§ãã
ã©ããªã³ã¹ã¡ãã·ã¥çæ
è¿·è·¯ã®ãã¹ãŠã®ããŒã¿ãçæããåŸããããã®ããŒã¿ã«åºã¥ããŠã¡ãã·ã¥ãæ§ç¯ã§ããŸãã
å¥ã®æ°ãã
MazeMeshGeneratorã¹ã¯ãªãããäœæããŸãã
MazeDataGeneratorãè¿·è·¯çæããžãã¯ãã«ãã»ã«åããããã«ã
MazeMeshGeneratorã¯ã¡ãã·ã¥çæããžãã¯ãå«ã¿ããã®è¿·è·¯çæã¹ããããå®äºããããã«
MazeConstructorã«ãã£ãŠäœ¿çšãããŸãã
ããæ£ç¢ºã«ã¯ã
åŸã§ã¡ãã·ã¥çæããžãã¯ãå«ãŸããŸãã æåã«ããã¢çšã®ãã¯ã¹ãã£ä»ãåè§åœ¢ãäœæããæ¬¡ã«ãã®ã³ãŒãã倿ŽããŠè¿·è·¯å
šäœãçæããŸãã ãããè¡ãã«ã¯ãUnityãšãã£ã¿ãŒã«å°ããªå€æŽãå ããŠãããã³ãŒããæãäžããå¿
èŠããããŸãã
ãŸããçæãããã¡ãã·ã¥ã«é©çšããããããªã¢ã«ããã€ã³ãããå¿
èŠããããŸãã
[
ãããžã§ã¯ã]ãŠã£ã³ããŠã§[
ã°ã©ãã£ãã¯ã¹ ]ãã©ã«ããŒãéžæãããŠã£ã³ããŠã§[
éå±€ã³ã³ãããŒã©ãŒ]ãéžæããŠã
ã€ã³ã¹ãã¯ã¿ãŒã«ãã®
Maze Constructorã³ã³ããŒãã³ãã衚瀺ããŸãã
ãããªã¢ã«ã
Graphicsãã©ã«ããã
Maze Constructorãããªã¢ã«ã¹ãããã«ãã©ãã°ããŸãã ãããªã¢ã«1ã«
ãã㢠ãããã ããããªã¢ã«2ã«
ãŠã©ãŒã« ãããã䜿çšãã
éå§ãš
å®ãé©åãªã¹ãããã«ãã©ãã°ããŸãã
ãã§ã«
ã€ã³ã¹ãã¯ã¿ãŒã§äœæ¥ããŠããããã
çæãããã¿ã°ã远å ããŸãã
ã€ã³ã¹ãã¯ã¿ãŒã®äžéšã«ãã[ã¿ã°]ã¡ãã¥ãŒãã¯ãªãã¯ãã[ã¿ã°ã远å ]ãéžæããŸãã ã¡ãã·ã¥ãçæãããšããããããèŠã€ããããã«ãã®ã¿ã°ãå²ãåœãŠãŸãã
Unityãšãã£ã¿ãŒã§å¿
èŠãªå€æŽããã¹ãŠè¡ã£ãåŸãæ°ããã¹ã¯ãªãããéãããã¹ãŠããã®ã³ãŒãã§çœ®ãæããŸãã
using System.Collections.Generic; using UnityEngine; public class MazeMeshGenerator {
ã¯ã©ã¹ã®æäžéšã«ãã2ã€ã®ãã£ãŒã«ã
width
ãš
height
ã
MazeDataGeneratorã®
placementThreshold
䌌ãŠã
placementThreshold
ããããã¯ãã³ã³ã¹ãã©ã¯ã¿ãŒã§ããã©ã«ãã§èšå®ãããã¡ãã·ã¥çæã³ãŒãã§äœ¿çšãããå€ã§ãã
è峿·±ãã³ãŒãã®å€§éšåã¯
FromData()
ãŸãã ããã¯ã
MazeConstructorãã¡ãã·ã¥ãçæããããã«åŒã³åºãã¡ãœããã§ãã çŸæç¹ã§ã¯ããã®ã³ãŒãã¯åçŽã«åè§åœ¢ãäœæããŠãã®åäœã瀺ããŠããŸãã ããã«å
šäœã¬ãã«ã«æ¡åŒµããŸãã
ãã®å³ã¯ãåè§åœ¢ã®æ§æèŠçŽ ã瀺ããŠããŸãã
ã³ãŒãã¯é·ããªããŸããããããã«å€åããŠéåžžã«åŒ·ãç¹°ãè¿ãããŸãã
- ã¡ãã·ã¥ã¯ãé ç¹ãUV座æšãããã³äžè§åœ¢ã®3ã€ã®ãªã¹ãã§æ§æãããŸãã
- é ç¹ã®ãªã¹ãã«ã¯ãåé ç¹ã®äœçœ®ãæ ŒçŽãããŠããŸã...
- ãªã¹ããããUV座æšã¯ããã®ãªã¹ãã®é ç¹ã«å¯Ÿå¿ããŠããŸã...
- ãããŠãäžè§åœ¢ã¯é ç¹ã®ãªã¹ãå
ã®ã€ã³ããã¯ã¹ã§ãïŒã€ãŸããããã®äžè§åœ¢ã¯é ç¹0ã1ã2ã§æ§æãããŠããŸããïŒã
- 2ã€ã®äžè§åœ¢ãäœæãããŠããããšã«æ³šæããŠãã ããã åè§åœ¢ã¯2ã€ã®äžè§åœ¢ã§æ§æãããŸãã ãŸãã
List
ããŒã¿åãïŒãªã¹ãã«åå ããããã«ïŒäœ¿çšãããŸãããæçµçã«ã¯Mesh
ã¯Arrays
ãå¿
èŠã§ãã
MazeConstructorã¯
MazeMeshGeneratorã®ã€ã³ã¹ã¿ã³ã¹ãäœæããã¡ãã·ã¥çæã¡ãœãããåŒã³åºãå¿
èŠããããŸãã ãŸããã¡ãã·ã¥ã
衚瀺ãããã¯ããªã®ã§ã次ã®ã³ãŒããã©ã°ã¡ã³ãã远å ããŸãã
ãŸããã¡ãã·ã¥ãžã§ãã¬ãŒã¿ãŒãæ ŒçŽãããã©ã€ããŒããã£ãŒã«ãã远å ããŸãã
private MazeMeshGenerator meshGenerator;
AwakeïŒïŒã§ãã®ã€ã³ã¹ã¿ã³ã¹ãäœæãã
AwakeïŒïŒã¡ãœããã®å
é ã«æ¬¡ã®è¡ã远å ããŠãã¡ãã·ã¥ãžã§ãã¬ãŒã¿ãŒãæ°ãããã£ãŒã«ãã«ä¿åããŸãã
meshGenerator = new MazeMeshGenerator();
次ã«ã
DisplayMazeïŒïŒã¡ãœããã远å ããŸãã
private void DisplayMaze() { GameObject go = new GameObject(); go.transform.position = Vector3.zero; go.name = "Procedural Maze"; go.tag = "Generated"; MeshFilter mf = go.AddComponent<MeshFilter>(); mf.mesh = meshGenerator.FromData(data); MeshCollider mc = go.AddComponent<MeshCollider>(); mc.sharedMesh = mf.mesh; MeshRenderer mr = go.AddComponent<MeshRenderer>(); mr.materials = new Material[2] {mazeMat1, mazeMat2}; }
æåŸã«ã
DisplayMazeïŒïŒãåŒã³åºãã«ã¯ã
GenerateNewMazeïŒïŒã®æåŸã«æ¬¡ã®è¡ã远å ããŸãã
DisplayMaze();
Mesh
èªäœã¯åãªãããŒã¿ã§ãã ã·ãŒã³å
ã®ãªããžã§ã¯ãïŒããå
·äœçã«
MeshFilter
ãªããžã§ã¯ãã®
MeshFilter
ïŒã«å²ãåœãŠããããŸã§è¡šç€ºãã
MeshFilter
ã ãããã£ãŠã
DisplayMaze()
ã¯
MazeMeshGenerator.FromData()
åŒã³åºãã ãã§ãªãããã®åŒã³åºããæ°ãã
MeshFilter
ã€ã³ã¹ã¿ã³ã¹ã®äœæäžã«æ¿å
¥ãã
çæã¿ã°ãèšå®ãã
MeshFilter
ãšçæã¡ãã·ã¥ã远å ããã¡ãã·ã¥ãšã®è¡çªã®ããã®
MeshCollider
ã远å ããæåŸã«
MeshRenderer
ãšãããªã¢ã«ã远å ããŸãã
MazeMeshGenerator
ã¯ã©ã¹ãäœæãã
MazeConstructorã§ã€ã³ã¹ã¿ã³ã¹åããã®ã§ã[
åç ]ãã¯ãªãã¯ããŸãã
ãã¯ã¹ãã£ä»ãåè§åœ¢ãå®å
šã«ã³ãŒãã§æ§ç¯ããŸããïŒ ããã¯è峿·±ãéèŠãªåºçºç¹ãªã®ã§ããã®æ®µéã§äŒæ©ãåã£ãŠäœæ¥ãåæããã³ãŒããã©ã®ããã«æ©èœããããçè§£ããŠãã ããã
次ã«ã
FromData()
ãªãã¡ã¯ã¿ãªã³ã°ãããã®ãããªã³ãŒãã§å®å
šã«çœ®ãæããŸãïŒ
public Mesh FromData(int[,] data) { Mesh maze = new Mesh();
ãããŒããªããŠ
é·ãã³ãŒãã§ãããïŒ ããããããã§ãã»ãšãã©åãããšãç¹°ãè¿ãããŸããäžéšã®æ°å€ã®ã¿ã倿ŽãããŸãã ç¹ã«ãã¯ã¢ããçæã³ãŒãã¯å¥ã®
AddQuad()
ã¡ãœããã«ç§»åãããåã°ãªããã»ã«ã®åºã倩äºãå£ã«å¯ŸããŠå床åŒã³åºãããŸãã
AddQuad()
ã®æåŸã®3ã€ã®ãã©ã¡ãŒã¿ãŒã¯ãé ç¹ãUVãããã³äžè§åœ¢ã®åããªã¹ãã§ãã ã¡ãœããã®æåã®è¡ã¯ãéå§ããã€ã³ããã¯ã¹ãååŸããŸãã æ°ããåè§åœ¢ã远å ãããšãã€ã³ããã¯ã¹ãå¢å ããŸãã- ãã ãã
AddQuad()
æåã®ãã©ã¡ãŒã¿ãŒã¯å€æè¡åã§ããããã®éšåãçè§£ããã®ã¯é£ããå ŽåããããŸãã å®éãäœçœ®/å転/ã¹ã±ãŒã«ã¯è¡åãšããŠä¿åããé ç¹ã«é©çšã§ããŸãã ããã¯ããŸãã«MultiplyPoint3x4()
ã³ãŒã«ãè¡ãããšã§ãã ãããã£ãŠãåè§åœ¢çæã³ãŒãã¯ãåºã倩äºãå£ãªã©ã«äœ¿çšã§ããŸãã 䜿çšãã倿è¡åã倿Žããã ãã§ãïŒ FromData()
ã«FromData()
ãŸãã UVé ç¹ãšäžè§åœ¢ã®ãªã¹ããäžéšã«äœæãããŸãã ä»åã¯ãäžè§åœ¢ã®2ã€ã®ãªã¹ãããããŸãã Mesh
Unityãªããžã§ã¯ãã«ã¯ãããããã«ç°ãªããããªã¢ã«ãæã€å€ãã®ãµãããã¯ã¹ãå«ããããšãã§ããŸããã€ãŸããäžè§åœ¢ã®åãªã¹ãã¯åå¥ã®ãµãããã¯ã¹ã§ãã ããã¢ãšå£ã«ç°ãªããããªã¢ã«ãå²ãåœãŠãããšãã§ããããã«ã2ã€ã®ããã¯ã¹ãçºè¡šããŸãã- ãã®åŸã2Dé
åã調ã¹ãŠãåã°ãªããã»ã«ã®åºã倩äºãå£ã®åè§åœ¢ãäœæããŸãã åã»ã«ã«ã¯åºãšå€©äºãå¿
èŠã§ããããã«ãå£ã®å¿
èŠæ§ã«ã€ããŠé£æ¥ã»ã«ã®ãã§ãã¯ãè¡ãããŸãã
AddQuad()
ã¯è€æ°ååŒã³åºãããŸããããã®ãã³ã«ç°ãªã倿ãããªãã¯ã¹ãšãåºãšå£ã«äœ¿çšãããäžè§åœ¢ã®ç°ãªããªã¹ããåŒã³åºãããããšã«æ³šæããŠãã ããã ãŸããåè§åœ¢ã®äœçœ®ãšãµã€ãºã決å®ããããã«width
ãšheight
ã䜿çšãããããšã«æ³šæããŠãã ããã - ããããã1ã€å°ããªè¿œå ïŒ
RecalculateNormals()
ã¯ãã¡ãã·ã¥ãã©ã€ãã£ã³ã°çšã«æºåããŸãã
[åç]ãã¯ãªãã¯ããŠãã¡ãã·ã¥å
šäœãã©ã®ããã«çæããããã確èªããŸãã
ããã§ãšããããã§è¿·è·¯ãš
Speedy Treasure Thiefã«å¿
èŠãªããã°ã©ãã³ã°ã®äž»èŠéšåãçæãããŸããïŒ æ¬¡ã®ã»ã¯ã·ã§ã³ã§ã¯ãã²ãŒã ã®æ®ãã®éšåãèŠãŠãããŸãã
ã²ãŒã ãçµäºãã
ã³ãŒãã«ä»ã®è¿œå ã倿Žãå ããå¿
èŠããããŸããããŸãããã©ãããããžã§ã¯ãã«ãã£ããã®ã䜿çšããŸãããã å°å
¥éšã§è¿°ã¹ãããã«ããã©ãããããžã§ã¯ãã«ã¯2ã€ã®ã¹ã¯ãªããããããŸãããã¬ãŒã€ãŒãšUIã®ããã·ãŒã³ãšãè¿·è·¯ã§éã¶ããã®ãã¹ãŠã®ã°ã©ãã£ãã¯ã§ãã
FpsMovementã¹ã¯ãªããã¯ã
ç§ã®æ¬ã®ãã£ã©ã¯ã¿ãŒã³ã³ãããŒã©ãŒã®ã·ã³ã°ã«ã¹ã¯ãªããããŒãžã§ã³ã§ããã
TriggerEventRouterã¯ãã²ãŒã ããªã¬ãŒã®æäœã«äŸ¿å©ãªè£å©ã³ãŒãã§ãã
ãã¬ãŒã€ãŒã¯ã
FpsMovementã³ã³ããŒãã³ããš
æåæ§å
æºãã«ã¡ã©ã«åãä»ããããŠããŸãã ããã«ãã¹ã«ã€ããã¯ã¹ãšã¢ã³ããšã³ãç
§æã¯ã
ç
§æèšå®ãŠã£ã³ããŠã§ç¡å¹ã«ãªã£ãŠããŸãã æåŸã«ãã·ãŒã³ã«ã¯ãã€ã³ããšæéã®ããŒã¯ãä»ããUIãã£ã³ãã¹ããããŸãã
ãããŠãããããã©ãããããžã§ã¯ãã«ãããŸãã æ¬¡ã«ãã²ãŒã ã®æ®ãã®ã³ãŒããèšè¿°ããŸãã
MazeConstructorããå§ããŸãããã ãŸããæ¬¡ã®ããããã£ã远å ããŠã寞æ³ãšåº§æšãä¿åããŸãã
public float hallWidth { get; private set; } public float hallHeight { get; private set; } public int startRow { get; private set; } public int startCol { get; private set; } public int goalRow { get; private set; } public int goalCol { get; private set; }
次ã«ãæ°ããã¡ãœããã远å ããå¿
èŠããããŸãã æåã¯
DisposeOldMaze()
ã§ãã ååã瀺ãããã«ãæ¢åã®è¿·è·¯ãåé€ããŸãã ãã®ã³ãŒãã¯ã
çæãããã¿ã°ãæã€ãã¹ãŠã®ãªããžã§ã¯ããèŠã€ããŠç Žæ£ããŸãã
public void DisposeOldMaze() { GameObject[] objects = GameObject.FindGameObjectsWithTag("Generated"); foreach (GameObject go in objects) { Destroy(go); } }
次ã«ã
FindStartPosition()
ã¡ãœããã远å ããŸãã ãã®ã³ãŒãã¯0,0ããå§ãŸãã空ãã¹ããŒã¹ãèŠã€ãããŸã§è¿·è·¯å
ã®ãã¹ãŠã®ããŒã¿ã調ã¹ãŸãã æ¬¡ã«ããããã®åº§æšãè¿·è·¯ã®åæäœçœ®ãšããŠä¿åãããŸãã
private void FindStartPosition() { int[,] maze = data; int rMax = maze.GetUpperBound(0); int cMax = maze.GetUpperBound(1); for (int i = 0; i <= rMax; i++) { for (int j = 0; j <= cMax; j++) { if (maze[i, j] == 0) { startRow = i; startCol = j; return; } } } }
åæ§ã«ã
FindGoalPosition()
åºæ¬çã«åãããšãè¡ããæå€§å€ããéå§ããŠã«ãŠã³ãããŠã³ããŸãã ãã®ã¡ãœããã远å ããŸãã
private void FindGoalPosition() { int[,] maze = data; int rMax = maze.GetUpperBound(0); int cMax = maze.GetUpperBound(1);
PlaceStartTrigger()
ããã³
PlaceGoalTrigger()
ã¯ããªããžã§ã¯ããã·ãŒã³å
ã®éå§äœçœ®ãšã¿ãŒã²ããäœçœ®ã«é
眮ããŸãã ãããã®ã³ã©ã€ããŒã¯ããªã¬ãŒã§ããã察å¿ãããããªã¢ã«ãé©çšãããŠããã
TriggerEventRouterã远å ãããŸãïŒãããžã§ã¯ããã©ã³ã¯ããïŒã
ãã®ã³ã³ããŒãã³ãã¯ãããªã¬ãŒã®ã¹ã³ãŒãã«å
¥ã£ããšãã«åŒã³åºãããã€ãã³ãåŠç颿°ãåãåããŸããããã2ã€ã®ã¡ãœããã远å ããŸãã private void PlaceStartTrigger(TriggerEventHandler callback) { GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube); go.transform.position = new Vector3(startCol * hallWidth, .5f, startRow * hallWidth); go.name = "Start Trigger"; go.tag = "Generated"; go.GetComponent<BoxCollider>().isTrigger = true; go.GetComponent<MeshRenderer>().sharedMaterial = startMat; TriggerEventRouter tc = go.AddComponent<TriggerEventRouter>(); tc.callback = callback; } private void PlaceGoalTrigger(TriggerEventHandler callback) { GameObject go = GameObject.CreatePrimitive(PrimitiveType.Cube); go.transform.position = new Vector3(goalCol * hallWidth, .5f, goalRow * hallWidth); go.name = "Treasure"; go.tag = "Generated"; go.GetComponent<BoxCollider>().isTrigger = true; go.GetComponent<MeshRenderer>().sharedMaterial = treasureMat; TriggerEventRouter tc = go.AddComponent<TriggerEventRouter>(); tc.callback = callback; }
æåŸã«ãã¡ãœããå
šäœãGenerateNewMaze()
次ã®ã³ãŒãã«çœ®ãæããŸãã public void GenerateNewMaze(int sizeRows, int sizeCols, TriggerEventHandler startCallback=null, TriggerEventHandler goalCallback=null) { if (sizeRows % 2 == 0 && sizeCols % 2 == 0) { Debug.LogError("Odd numbers work better for dungeon size."); } DisposeOldMaze(); data = dataGenerator.FromDimensions(sizeRows, sizeCols); FindStartPosition(); FindGoalPosition();
æžãæããããGenerateNewMaze()
ã¡ãœããã¯ãå€ãã¡ãã·ã¥ã®åé€ãããªã¬ãŒã®é
眮ãªã©ã®æäœã®ããã«è¿œå ããã°ããã®æ°ããã¡ãœãããåŒã³åºããŸããMazeConstructorã«ã¯ãã§ã«å€ãã®æ©èœã远å ãããŠããŸãã幞ãããã®ã¯ã©ã¹ã¯ããã§å®äºã§ãããã1ã€ã³ãŒããæ®ã£ãŠããŸããæ¬¡ã«ãæ°ããã³ãŒããGameControllerã«è¿œå ããŸãããã¡ã€ã«ã®å
容å
šäœã次ã®ãã®ã«çœ®ãæããŸãã using System; using UnityEngine; using UnityEngine.UI; [RequireComponent(typeof(MazeConstructor))] public class GameController : MonoBehaviour {
- æåã«è¿œå ããã®ã¯ãã·ãŒã³å
ã®ãªããžã§ã¯ãã®ãã£ãŒã«ããã·ãªã¢ã«åããããšã§ããã
- ã¿ã€ããŒãšã²ãŒã ãã€ã³ãã远跡ããããã®ããã€ãã®ãã©ã€ããŒã倿°ãšãã¿ãŒã²ãããè¿·è·¯ã§èŠã€ãã£ããã©ããã远å ããŸããã
MazeConstructor
, , Start()
, GenerateNewMaze()
.StartNewGame()
, . , , .StartNewMaze()
, . , , .Update()
, , , . .OnGoalTrigger()
OnStartTrigger()
â , TriggerEventRouter MazeConstructor . OnGoalTrigger()
, , . OnStartTrigger()
, , , .
ãããŠãããããã¹ãŠã®ã³ãŒãã§ããUnityã®ã·ãŒã³ã«æ»ããŸããããéå§ããã«ã¯ã[ éå±€]ãŠã£ã³ããŠã§[ ãã£ã³ãã¹]ãéžæããã€ã³ã¹ãã¯ã¿ãŒã§æå¹ã«ããŸããè¿·è·¯ã³ãŒãã®äœææã«ãããã°ã®è¡šç€ºã劚ããªãããã«ãCanvasã¯ç¡å¹ã«ãªã£ãŠããŸããã·ãªã¢ã«åããããã£ãŒã«ãã远å ãããŠããããšãå¿ããªãã§ãã ããããã®ãããã·ãŒã³ãªããžã§ã¯ãïŒPlayerãCanvasã®Timeã©ãã«ãããã³Scoreã©ãã«ïŒãã€ã³ã¹ãã¯ã¿ãŒã®ã¹ãããã«ãã©ãã°ããŸãã[ ãããã°ã®è¡šç€º ]ããªãã«ããŠã[åç]ãã¯ãªãã¯ããããšãã§ããŸããçŽ æŽãããä»äºã§ãïŒæç¶ãçã«è¿·è·¯ãçæããã®ã¯å€§å€ãªäœæ¥ã§ããããã®çµæãåºæ¿çã§ãã€ãããã¯ãªã²ãŒã ãã¬ã€ãåŸãããŸããæ¬¡ã¯ã©ããžè¡ããŸããïŒ
ç§ã®åŸã«ç¹°ãè¿ããå Žåãããªãã¯ãã§ã«å®æããã²ãŒã ãäœæããŠããŸããå¿
èŠã«å¿ããŠã宿ããUnityãããžã§ã¯ããããããããŠã³ããŒãã§ããŸããæ¬¡ã«ãã®ã³ãŒãã眮ãæããããšã«ãããä»ã®è¿·è·¯çæã¢ã«ãŽãªãºã ã調ã¹ãããšãã§ããŸãFromDimensions()
ãä»ã®ç°å¢ãçæããããšãã§ããŸããã»ã«ãªãŒãããã³ã§æŽçªã®çæãæ¢çŽ¢ããããšããå§ããŸãããããäžã®ãªããžã§ã¯ããšæµã®ã©ã³ãã ãªçæã¯ãéåžžã«è峿·±ãã¢ã¯ãã£ããã£ã§ãã