unityで地形自動生成をしようとしてます。
しかし、地形がどうしても有機的になってしまい、なかなかマイクラみたいにリアルに出来ません。
もっとこう・・
滑らかにしたいです。
スクリプトに問題点があると思いますが、ぜひ修正して頂きたいと思っております。
中点変位法を採用しております。
超大まかな手順
・高さを求める
↓
・低い所は海、中位は平地、高い所は山って風に置く
すくりぷと
Unity
1using UnityEngine; 2using System.Collections; 3using System.Collections.Generic; 4using UnityEngine.UI; 5 6public class MapMaker : MonoBehaviour { 7 8 int mapSize=1024; 9 //高度マップ 10 int[,] hightMap = new int[1025, 1025]; 11 //バイオーム生成用 12 //湿度マップ 13 int[,] waterMap = new int[1025, 1025]; 14 //温度マップ 15 int[,] tempMap = new int[1025, 1025]; 16 //バイオームマップ 17 byte[,] bomMap = new byte[1025, 1025]; 18 //空き地マップ 19 public static int[,] monoMap = new int[1025, 1025]; 20 //構造物入れ 21 List<GameObject> monos=new List<GameObject>(); 22 23 //地面プレハブ 24 public GameObject[] zimens; 25 //城とか木とか山とかプレハブ 26 public GameObject[] objects; 27 28 //ロードディングバー。気にしないで下さい。 29 public GameObject Fill; 30 public GameObject Back; 31 public GameObject slider; 32 public Slider bar; 33 34 void Start(){ 35 //カクカクなのでフレーム固定とガベコレ。気にしないで下さい。 36 Application.targetFrameRate = 60; 37 System.GC.Collect (); 38 //生成 39 StartCoroutine (CoStart ()); 40 } 41 // Use this for initialization 42 IEnumerator CoStart () { 43 44 //高度マップ生成。第一問題点。 45 Make (0,0,mapSize,Random.Range(0,100),Random.Range(0,100),Random.Range(0,100),Random.Range(0,100)); 46 bar.value = 0.05f; 47 //ローディングバーのための画面更新。 48 yield return null; 49 //湿度マップ生成。第一問題点。 50 MakeWater (0,0,mapSize,Random.Range(0,100),Random.Range(0,100),Random.Range(0,100),Random.Range(0,100)); 51 bar.value = 0.1f; 52 yield return null; 53 //温度マップ生成。第一問題点。 54 MakeTemp (0,0,mapSize,Random.Range(0,100),Random.Range(0,100),Random.Range(0,100),Random.Range(0,100)); 55 bar.value = 0.15f; 56 yield return null; 57 58 //オブジェクト生成。ここからは問題ないと思われる。 59 for (int x = 0; x < mapSize; x++) { 60 for (int y = 0; y < mapSize; y++) { 61 if (x == 250 && y == 250) { 62 bar.value = 0.3f; 63 yield return null; 64 } 65 if (x == 500 && y == 500) { 66 bar.value = 0.45f; 67 yield return null; 68 } 69 if (x == 750 && y == 750) { 70 bar.value = 0.6f; 71 yield return null; 72 } 73 Instantiate (Myground (hightMap [x, y], waterMap [x, y], tempMap [x, y],x,y), new Vector3 (x * 0.5f, y * 0.5f, 0), new Quaternion (0, 0, 0, 0)); 74 } 75 } 76 bar.value = 0.7f; 77 yield return null; 78 79 //構造物生成 80 Setobj (objects [0], mapSize / 2-1, mapSize / 2-1); 81 for (int x = 0; x < mapSize; x++) { 82 for (int y = 0; y < mapSize; y++) { 83 if (x == 500 && y == 500) { 84 bar.value = 0.8f; 85 yield return null; 86 } 87 //山 88 89 if (forlot(x,y,1,1)) { 90 if (hightMap [x, y] > 75) { 91 Setobj (objects [1], x, y); 92 continue; 93 } 94 } 95 //木 96 switch (bomMap[x,y]) { 97 //ジャングル 98 case 1: 99 if (forlot (x, y, 2, 2) && Random.Range (0, 4) > 2) { 100 Setobj (objects [2], x, y); 101 } 102 break; 103 //森 104 case 2: 105 if (forlot (x, y, 1, 1) && Random.Range (0, 5) > 1) { 106 Setobj (objects [3], x, y); 107 } 108 break; 109 //雪 110 case 3: 111 if (forlot (x, y, 1, 1) && Random.Range (0, 6) > 4) { 112 Setobj (objects [4], x, y); 113 } 114 break; 115 //サバンナ 116 case 4: 117 if (forlot (x, y, 1, 1) && Random.Range (0, 5) > 2) { 118 Setobj (objects [5], x, y); 119 } 120 break; 121 //平原 122 case 5: 123 if (forlot (x, y, 1, 1) && Random.Range (0, 4) > 2) { 124 Setobj (objects [6], x, y); 125 } 126 break; 127 //沼 128 case 6: 129 if (forlot (x, y, 1, 1) && Random.Range (0, 5) > 1) { 130 Setobj (objects [7], x, y); 131 } 132 break; 133 //砂漠 134 case 7: 135 if (forlot (x, y, 1, 1) && Random.Range (0, 6) > 4) { 136 Setobj (objects [8], x, y); 137 } 138 break; 139 //荒地 140 case 8: 141 if (forlot (x, y, 1, 1) && Random.Range (0, 5) > 2) { 142 Setobj (objects [9], x, y); 143 } 144 break; 145 default: 146 break; 147 } 148 } 149 150 } 151 bar.value = 1; 152 //バーの消去アニメーション。木にするな! 153 Image fill = Fill.GetComponent<Image> (); 154 Image back = Back.GetComponent<Image> (); 155 for (float a = 1; a != 0; a -= 0.01f) { 156 fill.color = new Color (1, 1, 1, a); 157 back.color = new Color (0, 0, 0, a); 158 yield return new WaitForSeconds(0.005f); 159 } 160 Destroy (slider); 161 } 162 //温度 163 void MakeTemp(int x,int y,int size,int tl,int tr,int bl,int br){ 164 if (size < 1) { 165 tempMap [x, y] = (tl + tr + bl + br) / 4+Random.Range(-1,2); 166 } else { 167 int t = (tl + tr) / 2; 168 int b = (bl + br) / 2; 169 int l = (tl + tr) / 2; 170 int r = (tr + br) / 2; 171 int mid = (t + b + l + r) / 4+Random.Range(-4,5); 172 173 174 if (size == 1024) 175 mid = 50; 176 177 size /= 2; 178 MakeTemp (x, y, size,tl, t, l, mid); 179 MakeTemp (x + size, y, size, t, tr, mid, r); 180 MakeTemp (x, y + size, size, l, mid, bl, b); 181 MakeTemp (x + size, y + size, size, mid, r, b, br); 182 } 183 } 184 //湿度 185 void MakeWater(int x,int y,int size,int tl,int tr,int bl,int br){ 186 if (size < 1) { 187 waterMap [x, y] = (tl + tr + bl + br) / 4+Random.Range(-1,2); 188 } else { 189 int t = (tl + tr) / 2+Random.Range(-4,5); 190 int b = (bl + br) / 2+Random.Range(-4,5); 191 int l = (tl + tr) / 2+Random.Range(-4,5); 192 int r = (tr + br) / 2+Random.Range(-4,5); 193 int mid = (t + b + l + r) / 4+Random.Range(-4,5); 194 195 if (size == 1024) 196 mid = 50; 197 198 size /= 2; 199 MakeWater (x, y, size,tl, t, l, mid); 200 MakeWater (x + size, y, size, t, tr, mid, r); 201 MakeWater (x, y + size, size, l, mid, bl, b); 202 MakeWater (x + size, y + size, size, mid, r, b, br); 203 } 204 } 205 //高度 206 void Make(int x,int y,int size,int tl,int tr,int bl,int br){ 207 if (size < 1) { 208 hightMap [x, y] = (tl + tr + bl + br) / 4+Random.Range(-4,5); 209 } else { 210 int t = (tl + tr) / 2; 211 int b = (bl + br) / 2; 212 int l = (tl + tr) / 2; 213 int r = (tr + br) / 2; 214 int mid = (t + b + l + r) / 4+Random.Range(-4,5); 215 216 if (size == 1024) { 217 mid = 70; 218 } 219 220 size /= 2; 221 Make (x, y, size,tl, t, l, mid); 222 Make (x + size, y, size, t, tr, mid, r); 223 Make (x, y + size, size, l, mid, bl, b); 224 Make (x + size, y + size, size, mid, r, b, br); 225 } 226 } 227 228 GameObject Myground(int hight,int water,int temp,int x,int y){ 229 //「ジ」「森」「雪」 230 //「サ」「平」「沼」 231 //「砂」「荒」「岩」 232 233 if (water > 66) { //水分:大 234 if (temp > 66) { 235 bomMap [x, y] = 1; 236 if (hight > 60) { 237 return zimens [0]; 238 } else if (60 >= hight && hight > 55) { 239 return zimens [9]; 240 } else if (55 >= hight) { 241 return zimens [10]; 242 } 243 } else if (temp > 33) { 244 bomMap [x, y] = 2; 245 if (hight > 60) { 246 return zimens [1]; 247 } else if (60 >= hight && hight > 55) { 248 return zimens [9]; 249 } else if (55 >= hight) { 250 * 251 * 252 * 253 割愛 254 } 255 256 bool forlot(int bx,int by,int x,int y){ 257 int a = 0; 258 for(int u=bx;u<=bx+x;u++){ 259 for (int v=by; v <= by+y; v++) { 260 if (u <= mapSize+1 && v <= mapSize+1 && u >= 0 && v >= 0) { 261 a += monoMap [u, v]; 262 if (hightMap [u, v] < 61) { 263 return false; 264 } 265 } else { 266 return false; 267 } 268 } 269 } 270 if ((float)a / (x * y) == 0) { 271 return true; 272 } 273 return false; 274 } 275 void Setobj(GameObject o,int x,int y){ 276 GameObject mono = Instantiate (o, new Vector3 (x * 0.5f, y * 0.5f, 0), new Quaternion (0, 0, 0, 0))as GameObject; 277 objBase Base = mono.GetComponent <objBase> (); 278 Base.point.X = x; 279 Base.point.Y = y; 280 monos.Add (mono); 281 Base.id = monos.Count; 282 for(int u=0;u<Base.sizeX;u++){ 283 for (int v=0; v < Base.sizeY; v++) { 284 monoMap [Base.point.X+u, Base.point.Y+v] = Base.id; 285 } 286 } 287 288 } 289 290}
質問点を明確化しました。

回答2件
あなたの回答
tips
プレビュー