どうも、萬朶櫻(@wanduoying)、179朶目の記事です。

前囘の記事で言つた通り、ゲームを作つてゐます。ジャンルはトルネコやシレンみたいなローグライク。
キャラクターが動くためのマップが無いと始まらない。
といふことで、まづはマップから作らうと思ひます。
原點に壁(キューブ)を1つだけ生成
とりあへず原點に壁を1つだけ生成することに
生成するオブジェクトはこちら。
なんの變哲も無いキューブに「壁」のテクスチャを貼り付けただけのオブジェクト。プレハブ化は濟ませてあります。
そしてこれを生成するためのコードがこちら。
1 2 3 4 5 6 7 8 9 10 11 12 |
using UnityEngine; using System.Collections; public class DungeonGenerator: MonoBehaviour { public GameObject wallPrefab; private void Start() { GameObject wall = Instantiate(wallPrefab) as GameObject; wall.transform.position = new Vector3(0, 0, 0); } } |
忘れずにインスペクターで壁のプレハブを指定して、いざ實行。
はい。シュールな光景ですが、できました。
1次元の配列を用ゐて壁(キューブ)を生成
いちいち手動で壁などを配置するのはキツイので、配列を使ふことにしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DungeonGenerator : MonoBehaviour { //オブジェクトを宣言 public GameObject wallPrefab; void Start() { //1次元の配列を置く int[] field = new int[3]; //手動で各インデックスに1もしくは0を代入 field[0] = 1; field[1] = 0; field[2] = 1; //各インデックスに代入された値を基に、壁の生成、不生成を判別 for (int i = 0; i < 3; i++) { //インデックスの値が1の時、wallPrefabを生成 if (field[i] == 1) { GameObject wall = Instantiate(wallPrefab) as GameObject; wall.transform.position = new Vector3(i, 0, 0); } Debug.Log(field[i]); } } } |
横一列で要素數3の配列、0番目と3番目に壁が生成されるやうにしてゐます。
そして實行
意圖通りに生成されました。
29行目の所、
- 正:
wall.transform.position = new Vector3(i, 0, 0);
- 誤:
wall.transform.position = new Vector3(field[i], 0, 0);
最初、上記のやうに間違へてゐて、戸惑ひました。
これだと全ての壁が(1,0,0)の所に生成されてしまひます。
1次元の配列にランダムな變數を用ゐて壁(キューブ)を生成
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DungeonGenerator: MonoBehaviour { //オブジェクトを宣言 public GameObject wallPrefab; //ランダム數値の制禦 private int randomMin = 0; private int randomMax = 2; void Start() { //1次元の配列を置く int[] field = new int[3]; //手動で各インデックスに1もしくは0を代入 field[0] = Random.Range(randomMin, randomMax); field[1] = Random.Range(randomMin, randomMax); field[2] = Random.Range(randomMin, randomMax); //各インデックスに代入された値を基に、壁の生成、不生成を判別 for (int i = 0; i < 3; i++) { //インデックスの値が1の時、wallPrefabを生成 if (field[i] == 1) { GameObject wall = Instantiate(wallPrefab) as GameObject; wall.transform.position = new Vector3(i, 0, 0); } Debug.Log(field[i]); } } } |
これでランダムに壁が生成されるやうになります。
さらに配列を長くしても大丈夫なやうにする
これまでは各インデックスに手動でRandom.Rangeを充ててゐました。
1 2 3 |
field[0] = Random.Range(randomMin, randomMax); field[1] = Random.Range(randomMin, randomMax); field[2] = Random.Range(randomMin, randomMax); |
しかしそれでは大きなダンジョンを生成する時に大變なので、どうにかします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DungeonGenerator: MonoBehaviour { //オブジェクトを宣言 public GameObject wallPrefab; //ランダム數値の制禦 private int randomMin = 0; private int randomMax = 2; //配列の幅 public int m_width = 10; void Start() { //1次元の配列を置く int[] map = new int[m_width]; //for文を用ゐて各インデックスに1もしくは0を代入 for (int i = 0; i < map.GetLength(0); i++) { map[i] = Random.Range(randomMin, randomMax); } //各インデックスに代入された値を基に、壁の生成、不生成を判別 for (int i = 0; i < map.GetLength(0); i++) { //インデックスの値が1の時、wallPrefabを生成 if (map[i] == 1) { GameObject wall = Instantiate(wallPrefab) as GameObject; wall.transform.position = new Vector3(i, 0, 0); Debug.Log("壁" + i); } } } } |
15行目で變數m_widthを宣言し、これを配列の幅とします。
あと24行目と30行目のfor文でGetLengthを使つてみました。これは配列の幅(要素數)を取得するものです。
實行すると、ちやんと生成されてゐます。
コンソールを確かめても大丈夫みたいです。
配列を2次元に擴張
いよいよ2次元のマップにしていきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class DungeonGenerator: MonoBehaviour { //オブジェクトを宣言 public GameObject wallPrefab; //ランダム數値の制禦 private int randomMin = 0; private int randomMax = 2; //配列の幅 public int m_width = 10; //x軸方向 public int m_heigt = 10; //y軸方向 // Use this for initialization void Start () { //2次元の配列にする int[,] map = new int[m_width, m_heigt]; //for文を用ゐて各インデックスに1もしくは0を代入 for (int i = 0; i < map.GetLength(0); i++) { for(int j = 0; j < map.GetLength(1); j++) { map[i, j] = Random.Range(randomMin, randomMax); } } //各インデックスに代入された値を基に、壁の生成、不生成を判別 for (int i = 0; i < map.GetLength(0); i++) { for (int j = 0; j < map.GetLength(1); j++) { //インデックスの値が1の時、wallPrefabを生成 if (map[i, j] == 1) { GameObject go = Instantiate(wallPrefab); go.transform.position = new Vector3(i, 0, j); } } } } |
基本的にはZ軸用の變數を追加したり、for文を入れ子にして次元を擴張してゐます。
ちやんと10×10の範圍内に、壁がランダムで生成されてゐます。
しかしここで氣附いたのですが、このやり方だとローグライクの部屋+通路の形にできませんね。

後日作つたマップ。こんな感じに壁や床を配置したい
敵、アイテム、罠などの生成には使へさうだから、無駄と云ふわけでは無ささうだけど…
とりあへず氣を取り直して良い感じのマップが作れるやうに頑張ります。
コメントを残す