Skip to content

Instantly share code, notes, and snippets.

@afjk
Created December 7, 2016 01:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afjk/c02630d5604b63b90900aad9490b1cca to your computer and use it in GitHub Desktop.
Save afjk/c02630d5604b63b90900aad9490b1cca to your computer and use it in GitHub Desktop.
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