patterncsharpMinor
Procedural World in Unity3D
Viewed 0 times
proceduralunity3dworld
Problem
The idea here is that rather than placing objects directly into the scene, these building objects are instantiated at run time and placed in the correct locations. This gives me full control over where and how to place the buildings.
The workflow is still a little involved. I have to import the model and texture image, drag it out into the scene, scale it, add a Mesh collider to it, and then add all of that to a prefab object that I also need to create. Then I need to add the name of that prefab to the script below. This must be done for each model that I want to use in the game. This approach is still a whole lot better than having to manually place and position each object in the Unity scene though.
GameModelScript.cs
My plan is to use this foundation to build some kind of superhero city exploration g
The workflow is still a little involved. I have to import the model and texture image, drag it out into the scene, scale it, add a Mesh collider to it, and then add all of that to a prefab object that I also need to create. Then I need to add the name of that prefab to the script below. This must be done for each model that I want to use in the game. This approach is still a whole lot better than having to manually place and position each object in the Unity scene though.
GameModelScript.cs
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public class GameModelScript : MonoBehaviour {
public int worldSize;
private System.Random random = new System.Random();
void Start () {
List names = new List ();
names.Add ("arco01_2_prefab");
names.Add ("arco03_prefab");
names.Add ("arco04_prefab");
names.Add ("arco05_prefab");
names.Add ("ballTower01_prefab");
names.Add ("bank01_prefab");
names.Add ("barn01_prefab");
names.Add ("bigApartments05_prefab");
names.Add ("bigFactory06_prefab");
names.Add ("bigMatterCube01_prefab");
names.Add ("busDepot01_prefab");
names.Add ("casino01_prefab");
for (int y = 0; y < worldSize; y+=30) {
for (int x = 0; x < worldSize; x+=30) {
int randomNumber = random.Next(0, names.Count);
GameObject tileObject = (GameObject)GameObject.Instantiate (Resources.Load (names[randomNumber]));
tileObject.transform.position = new Vector3(x, 10, y);
}
}
}
void Update () {
}
}My plan is to use this foundation to build some kind of superhero city exploration g
Solution
Unlike Java
This eliminates the need to call
In the future as well, if you ever plan to add more buildings, it'll be a pain to edit this script to include the new building names. Instead, you could declare a public variable which allows you to drag and drop the model prefabs instead:
This also eliminates the need to call
In addition, the namespace
Other than that, there are just a few things I want to nitpick.
-
In addition, the accepted Unity style for storing an instantiated
-
If you're feeling up to dynamic typing, this also works as well (Thanks @Kroltan):
-
You can also remove the
Lists, C# lists can be pre-initialized with values, like this:List names = new List()
{
"arco01_2_prefab",
...
};This eliminates the need to call
.Add, and improves code readability as well.In the future as well, if you ever plan to add more buildings, it'll be a pain to edit this script to include the new building names. Instead, you could declare a public variable which allows you to drag and drop the model prefabs instead:
public List buildings;This also eliminates the need to call
Resources.Load.In addition, the namespace
UnityEngine provides a class Random which can be used over the default System.Random. Unlike System.Random, UnityEngine.Random is a static class doesn't need to be instantiated, and you can just call Random.Range like this:int randomNumber = (int)Random.Range(0, names.Count);Other than that, there are just a few things I want to nitpick.
- You don't need to call
Instantiatefrom theGameObjectclass. It can just be called with out theGameObject.prefix.
-
In addition, the accepted Unity style for storing an instantiated
GameObject is like this: GameObject gameObject = Instantiate( ... ) as GameObject;-
If you're feeling up to dynamic typing, this also works as well (Thanks @Kroltan):
var gameObject = Instantiate( ... ) as GameObject;-
You can also remove the
Update function. It doesn't do anything, and can decrease performance, due to the fact that it's running many times per frame.- The general style for braces in C# is to put them on the next line, not like Java braces.
- You aren't using
System.Collections, so you can remove theusing System.Collections;.
Code Snippets
List<string> names = new List<string>()
{
"arco01_2_prefab",
...
};public List<GameObject> buildings;int randomNumber = (int)Random.Range(0, names.Count);GameObject gameObject = Instantiate( ... ) as GameObject;var gameObject = Instantiate( ... ) as GameObject;Context
StackExchange Code Review Q#100854, answer score: 8
Revisions (0)
No revisions yet.