この記事は
『プログラミング完全未経験からUnityでの開発現場に迎え入れてもらえた世界一の幸せ者』
の記事です。そのつもりでお読みください。
ランダムではない
毎回違う場所に配置すると書きましたが、
ランダムとは少しだけ違います。
私がやりたかったことは2回連続で同じ場所には絶対に出ないという実装です。
なのでちょっと面倒でした。
↓↓↓補足(2019.3/11)↓↓↓
同じエリアに連続出現しないだけで座標は毎回ランダムにしたい
これです!まさにこれ!
コメントありがとうございます!
考え方
上のとてもわかりやすい図のように分けた場合、
もし0に出現したら次は必ず1、2、3のどこかに出現するようにします。
もっと効率の良い方法があるのかもしれませんが、ちょっと急いでたのでこのやり方で実装しました。
値を返すメソッドを用意
ランダムな値を渡すとその値と同じ値を返すメソッドを用意しました。
これにより、一度出現したエリアの番号を記録できます。
int? RandomArea(int patternNum)
{
if (patternNum == 0)
{
holeParentPosition = new Vector3(randomX_A, holeParentPosition.y, randomZ_A);
this.gameObject.transform.localPosition = holeParentPosition;
return 0;
}
if (patternNum == 1)
{
holeParentPosition = new Vector3(randomX_B, holeParentPosition.y, randomZ_B);
this.gameObject.transform.localPosition = holeParentPosition;
return 1;
}
if (patternNum == 2)
{
holeParentPosition = new Vector3(randomX_C, holeParentPosition.y, randomZ_C);
this.gameObject.transform.localPosition = holeParentPosition;
return 2;
}
if (patternNum == 3)
{
holeParentPosition = new Vector3(randomX_D, holeParentPosition.y, randomZ_D);
this.gameObject.transform.localPosition = holeParentPosition;
return 3;
}
return null;
}
最終的なコード
public GameObject hole;
Vector3 holeParentPosition;
int[] patternNumber = { 0, 1, 2, 3 };
int patternArray;
float randomX_A;
float randomZ_A;
float randomX_B;
float randomZ_B;
float randomX_C;
float randomZ_C;
float randomX_D;
float randomZ_D;
void Start()
{
holeParentPosition = this.gameObject.transform.localPosition;
}
void Update()
{
patternArray = Random.Range(0, patternNumber.Length);
randomX_A = Random.Range(0.5f, 4.0f);
randomZ_A = Random.Range(-5f, -1.5f);
randomX_B = Random.Range(0.5f, 4.0f);
randomZ_B = Random.Range(-9f, -5.5f);
randomX_C = Random.Range(-4.0f, -0.5f);
randomZ_C = Random.Range(-9f, -5.5f);
randomX_D = Random.Range(-4.0f, -0.5f);
randomZ_D = Random.Range(-5f, -1.5f);
//コルーチン開始(一回で抜ける)
if (ThisProjectSingleton.Instance.isGameStart)
{
StartCoroutine(HoleRandomCoroutine());
ThisProjectSingleton.Instance.isGameStart = false;
}
}
int? RandomArea(int patternNum)
{
if (patternNum == 0)
{
holeParentPosition = new Vector3(randomX_A, holeParentPosition.y, randomZ_A);
this.gameObject.transform.localPosition = holeParentPosition;
return 0;
}
if (patternNum == 1)
{
holeParentPosition = new Vector3(randomX_B, holeParentPosition.y, randomZ_B);
this.gameObject.transform.localPosition = holeParentPosition;
return 1;
}
if (patternNum == 2)
{
holeParentPosition = new Vector3(randomX_C, holeParentPosition.y, randomZ_C);
this.gameObject.transform.localPosition = holeParentPosition;
return 2;
}
if (patternNum == 3)
{
holeParentPosition = new Vector3(randomX_D, holeParentPosition.y, randomZ_D);
this.gameObject.transform.localPosition = holeParentPosition;
return 3;
}
return null;
}
IEnumerator HoleRandomCoroutine()
{
int? tmpNum = 0;
int? memoryNum = 0;
while (/*ゲームオーバーの条件を記述*/)
{
yield return new WaitForSeconds(0.5f);
tmpNum= RandomArea(patternNumber[patternArray]);
//もしランダムな数字( tmpNum)が前回(memoryNum)と一致したら通過。別の数字をtmpNumに代入して抜ける
while (tmpNum == memoryNum)
{
yield return new WaitForEndOfFrame();
tmpNum = RandomArea(patternNumber[patternArray]);
}
memoryNum = tmpNum;
hole.SetActive(true);
//ホールにボールが入るまで待つ
yield return new WaitUntil(() => ThisProjectSingleton.Instance.isHoleEnter);
ScoreText.ScoreAdd();
//ホールが消える
yield return new WaitForSeconds(0.5f);
hole.SetActive(false);
ThisProjectSingleton.Instance.isHoleEnter = false;
}
}
いま自分で読み返しても読みづらいしもっといい方法がありそうです。
こんな方法もあるよ~って方、コメントください。
unity1week
unity1weekという企画がありまして、
その名の通りUnityを用いて一週間でゲームを作ろうというおもしろい企画です。
私も参加するつもりなのですが、
そこで作るのはWebGLというブラウザ上で起動する形式です。
せっかく作ったのにビルドとかアップロードの仕方がわからない!
と本番でならないようにunity1dayと称して、
簡単なゲームを作りunityroomにテストアップロードしました。
今回紹介したゲームオブジェクトを毎回違う場所に配置する方法も用いているので
よかったら覗いてみてください。↓
人のコード見た後にそのゲームをプレイするの結構おもしろいです。