Created
December 7, 2016 01:06
-
-
Save afjk/c02630d5604b63b90900aad9490b1cca to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System.Collections; | |
public class MazeMaker : MonoBehaviour { | |
public delegate void MazeMakerEventHandler(object sender ); | |
public event MazeMakerEventHandler MakeComplete; | |
public int randomSeed = -1; | |
public int xMax; | |
public int yMax; | |
public int zMax; | |
public GameObject cubeObject; | |
public GameObject spaceObject; | |
public GameObject nowPosObject; | |
public GameObject itemObject; | |
public GameObject GoalObject; | |
public int scale; | |
public int itemNum; | |
private GameObject mMazeBase; | |
private int[,,] mCells; // 迷路データ | |
private int[,,] mWkCells; // 作業用。 | |
private tPosition mStartPos; // 開始位置 | |
private tPosition mNowPos; // 穴掘り人の位置。 | |
private int mDirection; // 方向:0=上 1:右 2:下 3:左 4:z上 5:z下 | |
private bool makeMazeComplete = false; | |
private bool mStartFlag; | |
public struct tPosition | |
{ | |
public int x, y,z; | |
public tPosition(int _x, int _y, int _z) | |
{ | |
x = _x; | |
y = _y; | |
z = _z; | |
} | |
} | |
// Use this for initialization | |
void Start() | |
{ | |
mStartFlag = false; | |
/* | |
if(randomSeed != -1 ) | |
{ | |
Random.seed = randomSeed; | |
} | |
mMazeBase = new GameObject(); | |
mMazeBase.name = "MazeBase"; | |
makeMazeComplete = false; | |
MakeMazeData(); | |
// GenerateMaze(); //一括生成処理 | |
*/ | |
// StartMakeMaze(randomSeed, xMax, yMax, zMax, scale, itemNum ); | |
} | |
float learpCount = 90; | |
public void StartMakeMaze(int _seed, int _xMax, int _yMax, int _zMax, int _scale, int _itemNum) | |
{ | |
randomSeed = _seed; | |
xMax = _xMax; | |
yMax = _yMax; | |
zMax = _zMax; | |
scale = _scale; | |
itemNum = _itemNum; | |
learpCount = 90; | |
if (randomSeed != -1) | |
{ | |
Random.seed = randomSeed; | |
} | |
mMazeBase = new GameObject(); | |
mMazeBase.name = "MazeBase"; | |
makeMazeComplete = false; | |
MakeMazeData(); | |
mStartFlag = true; | |
} | |
void Update() | |
{ | |
if(mStartFlag == true ) | |
{ | |
if (makeMazeComplete == false) | |
{ | |
{ | |
MakeMazeDataStep(); | |
if (nowPosObject != null) | |
{ | |
nowPosObject.transform.position = new Vector3(mNowPos.x, mNowPos.y, mNowPos.z); | |
} | |
} | |
} | |
else | |
{ | |
if(learpCount > 0) | |
{ | |
float newScale = Mathf.Lerp(mMazeBase.transform.localScale.x, scale, 1 / learpCount--); | |
mMazeBase.transform.localScale = new Vector3(newScale, newScale, newScale); | |
} | |
} | |
} | |
} | |
/** | |
* 迷路データ生成 | |
*/ | |
void MakeMazeData() | |
{ | |
Debug.Log("MakeMazeData"); | |
mCells = new int[xMax, yMax, zMax]; | |
mWkCells = new int[xMax, yMax, zMax]; | |
// 外周を道として、内側を壁で埋める。 | |
for (int x = 0; x < xMax; x++) | |
{ | |
for (int y = 0; y < yMax; y++) | |
{ | |
for (int z = 0; z < zMax; z++) | |
{ | |
if ((0 < x) && (0 < y) && (0 < z) && (x < xMax - 1) && (y < yMax - 1) && (z < zMax - 1)) | |
{ | |
mCells[x, y, z] = 1; | |
} | |
else | |
{ | |
mCells[x, y, z] = 0; | |
} | |
mWkCells[x, y, z] = 0; | |
} | |
} | |
} | |
// (2,2,2をスタートとする) | |
mStartPos = new tPosition(2, 2, 2); | |
mNowPos = new tPosition(mStartPos.x, mStartPos.y, mStartPos.z); | |
mWkCells[mStartPos.x, mStartPos.y, mStartPos.z] = -1; | |
mCells[mStartPos.x, mStartPos.y, mStartPos.z] = 0; | |
CopyGameObject(spaceObject, mStartPos); | |
} | |
void MakeMazeDataStep() | |
{ | |
// 進行可能な方向を得る | |
int direction = GetGoDirection(mNowPos); | |
if (direction == -1) | |
{ | |
// 進行方向が見つからない場合 | |
// 2セル戻る | |
// スタート地点なら生成終了 | |
if (mNowPos.x == mStartPos.x && mNowPos.y == mStartPos.y && mNowPos.z == mStartPos.z) | |
{ | |
Debug.Log("Maze Generate Complete!"); | |
makeMazeComplete = true; | |
// mMazeBase.transform.localScale = new Vector3(scale, scale, scale); | |
// GenerateMaze(); | |
// アイテムを配置する。 | |
SetItems(); | |
// ゴールを配置する。 | |
CopyGameObject(GoalObject, new tPosition(xMax-3,yMax-2,zMax-3)); | |
// 完了通知 | |
OnMakeComplete(); | |
return; | |
} | |
else | |
{ | |
GoBack(); | |
} | |
} | |
else | |
{ | |
// 進行可能な方向に2セル進む | |
GoAhead(direction); | |
} | |
} | |
void GoBack() | |
{ | |
int direction = mWkCells[mNowPos.x, mNowPos.y, mNowPos.z]; | |
switch (direction) | |
{ | |
case 0: // 上 | |
mNowPos.y -= 2; | |
break; | |
case 1: // 右 | |
mNowPos.x -= 2; | |
break; | |
case 2: // 下 | |
mNowPos.y += 2; | |
break; | |
case 3: // 左 | |
mNowPos.x += 2; | |
break; | |
case 4: // z上 | |
mNowPos.z -= 2; | |
break; | |
case 5: // z下 | |
mNowPos.z += 2; | |
break; | |
} | |
// Debug.Log("goBack to:x" + mNowPos.x + " y:" + mNowPos.y + " z:" + mNowPos.z); | |
} | |
int GetGoDirection( tPosition nowPos) | |
{ | |
int dir = -1; | |
bool canGo = false; | |
// 進行方向チェック | |
for( int i = 0;i<6;i++) | |
{ | |
switch( i ) | |
{ | |
case 0: // 上 | |
{ | |
if (mCells[nowPos.x, nowPos.y + 2, nowPos.z] == 1) | |
{ | |
canGo = true; | |
} | |
} | |
break; | |
case 1: // 右 | |
{ | |
if (mCells[nowPos.x + 2, nowPos.y, nowPos.z] == 1) | |
{ | |
canGo = true; | |
} | |
} | |
break; | |
case 2: // 下 | |
{ | |
if (mCells[nowPos.x, nowPos.y - 2, nowPos.z] == 1) | |
{ | |
canGo = true; | |
} | |
} | |
break; | |
case 3: // 左 | |
{ | |
if (mCells[nowPos.x - 2, nowPos.y, nowPos.z] == 1) | |
{ | |
canGo = true; | |
} | |
} | |
break; | |
case 4: // z上 | |
{ | |
if (mCells[nowPos.x, nowPos.y, nowPos.z + 2] == 1) | |
{ | |
canGo = true; | |
} | |
} | |
break; | |
case 5: // z下 | |
{ | |
if (mCells[nowPos.x, nowPos.y, nowPos.z - 2] == 1) | |
{ | |
canGo = true; | |
} | |
} | |
break; | |
} | |
} | |
if(canGo ) | |
{ | |
while (true) | |
{ | |
int i = Random.Range(0, 6); | |
switch (i) | |
{ | |
case 0: // 上 | |
if (mCells[nowPos.x, nowPos.y + 2, nowPos.z] == 1) | |
{ | |
dir = i; | |
} | |
break; | |
case 1: // 右 | |
if (mCells[nowPos.x + 2, nowPos.y, nowPos.z] == 1) | |
{ | |
dir = i; | |
} | |
break; | |
case 2: // 下 | |
if (mCells[nowPos.x, nowPos.y - 2, nowPos.z] == 1) | |
{ | |
dir = i; | |
} | |
break; | |
case 3: // 左 | |
if (mCells[nowPos.x - 2, nowPos.y, nowPos.z] == 1) | |
{ | |
dir = i; | |
} | |
break; | |
case 4: // z上 | |
if (mCells[nowPos.x, nowPos.y, nowPos.z + 2] == 1) | |
{ | |
dir = i; | |
} | |
break; | |
case 5: // z下 | |
if (mCells[nowPos.x, nowPos.y, nowPos.z - 2] == 1) | |
{ | |
dir = i; | |
} | |
break; | |
} | |
if( dir != -1 ) | |
{ | |
break; | |
} | |
} | |
} | |
// Debug.Log("go direction:" + dir); | |
return dir; | |
} | |
void GoAhead(int direction) | |
{ | |
tPosition goPos1 = new tPosition(0, 0, 0); | |
tPosition goPos2 = new tPosition(0, 0, 0); | |
switch (direction) | |
{ | |
case 0: // 上 | |
mCells[mNowPos.x, mNowPos.y + 1, mNowPos.z] = 0; | |
mCells[mNowPos.x, mNowPos.y + 2, mNowPos.z] = 0; | |
goPos1 = new tPosition(mNowPos.x, mNowPos.y + 1, mNowPos.z); | |
goPos2 = new tPosition(mNowPos.x, mNowPos.y + 2, mNowPos.z); | |
mNowPos.y += 2; | |
break; | |
case 1: // 右 | |
mCells[mNowPos.x + 1, mNowPos.y, mNowPos.z] = 0; | |
mCells[mNowPos.x + 2, mNowPos.y, mNowPos.z] = 0; | |
goPos1 = new tPosition(mNowPos.x + 1, mNowPos.y, mNowPos.z); | |
goPos2 = new tPosition(mNowPos.x + 2, mNowPos.y, mNowPos.z); | |
mNowPos.x += 2; | |
break; | |
case 2: // 下 | |
mCells[mNowPos.x, mNowPos.y - 1, mNowPos.z] = 0; | |
mCells[mNowPos.x, mNowPos.y - 2, mNowPos.z] = 0; | |
goPos1 = new tPosition(mNowPos.x, mNowPos.y - 1, mNowPos.z); | |
goPos2 = new tPosition(mNowPos.x, mNowPos.y - 2, mNowPos.z); | |
mNowPos.y -= 2; | |
break; | |
case 3: // 左 | |
mCells[mNowPos.x - 1, mNowPos.y, mNowPos.z] = 0; | |
mCells[mNowPos.x - 2, mNowPos.y, mNowPos.z] = 0; | |
goPos1 = new tPosition(mNowPos.x - 1, mNowPos.y, mNowPos.z); | |
goPos2 = new tPosition(mNowPos.x - 2, mNowPos.y, mNowPos.z); | |
mNowPos.x -= 2; | |
break; | |
case 4: // z上 | |
mCells[mNowPos.x, mNowPos.y, mNowPos.z + 1] = 0; | |
mCells[mNowPos.x, mNowPos.y, mNowPos.z + 2] = 0; | |
goPos1 = new tPosition(mNowPos.x, mNowPos.y, mNowPos.z + 1); | |
goPos2 = new tPosition(mNowPos.x, mNowPos.y, mNowPos.z + 2); | |
mNowPos.z += 2; | |
break; | |
case 5: // z下 | |
mCells[mNowPos.x, mNowPos.y, mNowPos.z - 1] = 0; | |
mCells[mNowPos.x, mNowPos.y, mNowPos.z - 2] = 0; | |
goPos1 = new tPosition(mNowPos.x, mNowPos.y, mNowPos.z - 1); | |
goPos2 = new tPosition(mNowPos.x, mNowPos.y, mNowPos.z - 2); | |
mNowPos.z -= 2; | |
break; | |
} | |
mWkCells[mNowPos.x, mNowPos.y, mNowPos.z] = direction; | |
if (mNowPos.x == mStartPos.x && mNowPos.y == mStartPos.y && mNowPos.z == mStartPos.z) | |
{ | |
Debug.Log("★★★Error!!!!! go to Start Point"); | |
} | |
CopyGameObject(spaceObject, goPos1); | |
CopyGameObject(spaceObject, goPos2); | |
// Debug.Log("goAhead to:x" + mNowPos.x + " y:" + mNowPos.y + " z:" + mNowPos.z + " direction:" + direction); | |
} | |
/** | |
* 一括迷路生成処理 | |
*/ | |
void GenerateMaze() | |
{ | |
for (int x = 1; x < xMax-1; x++) | |
{ | |
for (int y = 1; y < yMax-1; y++) | |
{ | |
for (int z = 1; z < zMax-1; z++) | |
{ | |
if (mCells[x, y, z] == 1) | |
{ | |
// 壁の描画 | |
// CopyGameObject(cubeObject, new tPosition(x, y, z)); | |
} | |
else | |
{ | |
// 道の描画 | |
CopyGameObject(spaceObject, new tPosition(x,y,z)); | |
} | |
} | |
} | |
} | |
mMazeBase.transform.localScale = new Vector3(scale, scale, scale); | |
} | |
void SetItems() | |
{ | |
Debug.Log("SetItems()"); | |
int items = itemNum; | |
while( items > 0 ) | |
{ | |
int randX = Random.Range(2, xMax - 2); | |
int randY = Random.Range(2, yMax - 2); | |
int randZ = Random.Range(2, zMax - 2); | |
if( ( (mCells[randX, randY, randZ] == 1) && (mCells[randX, randY - 1, randZ] == 0) ) || | |
((mCells[randX, randY, randZ] == 1) && (mCells[randX, randY + 1, randZ] == 0)) || | |
((mCells[randX, randY, randZ] == 1) && (mCells[randX - 1, randY, randZ] == 0)) || | |
((mCells[randX, randY, randZ] == 1) && (mCells[randX + 1, randY, randZ] == 0)) || | |
((mCells[randX, randY, randZ] == 1) && (mCells[randX, randY, randZ - 1] == 0)) || | |
((mCells[randX, randY, randZ] == 1) && (mCells[randX, randY, randZ + 1] == 0)) | |
) | |
{ | |
CopyGameObject(itemObject, new tPosition(randX, randY, randZ)); | |
mCells[randX, randY, randZ] = 2; | |
items--; | |
} | |
} | |
} | |
void CopyGameObject(GameObject gameObject, tPosition pos) | |
{ | |
GameObject copySpaceCube = Object.Instantiate(gameObject) as GameObject; | |
copySpaceCube.transform.position = new Vector3(pos.x, pos.y, pos.z); | |
copySpaceCube.transform.parent = mMazeBase.transform; | |
} | |
/* 迷路生成完了通知 */ | |
public virtual void OnMakeComplete() | |
{ | |
if (MakeComplete != null) | |
{ | |
MakeComplete(this); | |
} | |
} | |
// マップ表示処理 | |
public GameObject playerObject; | |
public float mapScale; | |
public GameObject mapAnchor; | |
private GameObject mapMazeBase = null; | |
public void ToggleMiniMapDisplay(float destroyTime) | |
{ | |
if (mapMazeBase != null) | |
{ | |
HideMiniMap(); | |
} | |
else | |
{ | |
DisplayMiniMap(destroyTime); | |
} | |
} | |
public void DisplayMiniMap(float destroyTime) | |
{ | |
HideMiniMap(); | |
GameObject mazeBase = GameObject.Find("MazeBase"); | |
if (mazeBase) | |
{ | |
GameObject copyMazeBase = Object.Instantiate(mazeBase) as GameObject; | |
copyMazeBase.name = "MapMazeBase"; | |
mapMazeBase = copyMazeBase; | |
// VRTK_InteractableObjectを削除する。 | |
foreach (Transform child in mapMazeBase.transform) | |
{ | |
//child is your child transform | |
// VRTK_InteractableObject vrtkcmpo = child.GetComponent<VRTK_InteractableObject>(); | |
// Destroy(vrtkcmpo); | |
} | |
GameObject copyPlayer = Object.Instantiate(playerObject) as GameObject; | |
copyPlayer.transform.position = mapAnchor.transform.position; | |
copyPlayer.transform.localScale = new Vector3(scale, scale, scale); | |
copyPlayer.transform.parent = copyMazeBase.transform; | |
float diff = 0.15f; | |
// マップ表示 | |
Vector3 pos = mapAnchor.transform.position - new Vector3(diff, diff, diff); | |
copyMazeBase.transform.localScale = new Vector3(mapScale, mapScale, mapScale); | |
copyMazeBase.transform.position = pos; | |
CancelInvoke(); | |
Invoke("DeleteMiniMapLater", destroyTime); | |
} | |
} | |
private void DeleteMiniMapLater() | |
{ | |
HideMiniMap(); | |
} | |
public void HideMiniMap() | |
{ | |
if(mapMazeBase!=null) | |
{ | |
Destroy(mapMazeBase); | |
mapMazeBase = null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment