- Home /
How do I dynamically generate scenes?
All the tutorials seem to involve attaching scripts to manually placed game objects, forcing a particular starting state for the scene.
I am interested in programmatically generating the world and placing the assets. I might use the graphical editor to experiment, but it is of paramount importance that I understand:
Where start-up code is configured (i.e. code that happens before the default scene is loaded)
How to spawn objects
Best practices for game architecture
I don't want to create levels myself in the editor. I'd like to have an abstraction of the game environment and then 'build' the world from that. For example, I can't see how I'd randomly generate a world.
Based on the price tag and impressive examples such as Kerbal, I'm certain that a rich and powerful development environment hides beneath the beginner's drag 'n' drop experience.
$$anonymous$$erbal = the game $$anonymous$$erbal Space Program
I don't agree with the duplicate question assertion - the linked questions seem different in scope. I'm asking about design practices in Unity specifically, and how one actually writes proper code, rather than all this flashy 'let's drag a cube from a library containing 20,000 hours of artist time'.
@rba - it's simply not clear what you're asking.
Do you want to build mesh in real time to make new, custom objects in real time?
It is simple confusion how unity3d works and how to do all stuff by code, ins$$anonymous$$d placeing by editor. Whatever,, he accepted an answer. For me, question was end.
Answer by Stormizin · Oct 02, 2013 at 08:24 PM
Start-up config: You can use the Awake and Start functions in your script to start every method or config you need before the player can play the game. Spawn objects its simple that you think just use Instantiate(object, position, rotation) and boom! it will spawn. Also see: Instantiate
About the best pratices for game architecture see this link it will be useful for you: StackOverFlow Arch Question
If you really want to go deep using only code, you must fully understand the component lifecycle.
http://docs.unity3d.com/Documentation/$$anonymous$$anual/ExecutionOrder.html
guys, I believe he's asking "how do I use AI to create scenes from scratch"
he's not "merely" asking how to instantiate and run a pool.
Answer by fafase · Oct 02, 2013 at 08:24 PM
Well, your idea is honorable but goes against the whole engine principle. Unity is trying to make your work easier. by adding visual aspect and more drag and drop than code.
What you are looking for is more of Conventional DirectX approach where you code it all from A to Z (and still DirectX is an API so uít has some helpers).
But well.
You can have a game manager object. Unfortunately, this one has to be added to an object. From there, you can start creating your scene in the Awake or Start method, Awake is run on creation of the object, Start is run once before the first Update, in your case they both run one after the other and won't make big difference.
So you could have:
GameObject objectA = (GameObject)Resources.Load(path,typeof(GameObject));
GameObject obj = (GameObject)Instantiate(objectA, position, rotation);
obj.AddComponent<ComponentName>();
this will fetch a prefab in the resources folder see here: http://docs.unity3d.com/Documentation/ScriptReference/Resources.html
Then you instantiate a clone of that prefab see here: http://docs.unity3d.com/Documentation/ScriptReference/Object.Instantiate.html
Note the cast on each step as C# requires it.
Then AddComponent is the method that adds script by code. This is equivalent of dropping scripts onto an object.
That is already a beginning. If you need more go ahead.
The problem to write a long answer is that there is always someone faster :)
Answer by Sisso · Oct 02, 2013 at 08:40 PM
I have understood that you have come from another environment (like server side) or another engine. There is a unity3d way to do the things, and if you don't understand and try to do it different you will be fighting against the wall.
To work better you need truly understand about Scene, Prefabs and Component based development. I said truly because they are not what appear to be. You can see a scene like a Configuration set of code that is executed when load, could be a nice scene like 3dmax, or a simple bunch of script that compute stuff before send to game scene. For example, in kerbal. Probably the ingame is a single scene, empty, without planets or ships, but a lot of prefabs with every rules configured and reference for assets.
You will become very angry sometimes. But when you take the gotchas, it is a great way to work. Expecially when you use the full power of Editor
http://docs.unity3d.com/Documentation/ScriptReference/Editor.html.
There is some nice things here how to organize your project and use prefabs:
http://devmag.org.za/2012/07/12/50-tips-for-working-with-unity-best-practices/
How to instantiate dynamically:
http://docs.unity3d.com/Documentation/Manual/InstantiatingPrefabs.html
Answer by clooper · Jul 17, 2014 at 12:23 AM
Building a scene entirely in code is a good way to get one's head around scripting.
In the Unity Editor create an empty scene and delete it's default camera. Add an empty game object. Add the following script to that empty game object.
using UnityEngine;
using System.Collections;
/// <summary>
/// Create a scene from scratch
/// </summary>
public class SceneFromScratch : MonoBehaviour {
// Use this for initialization
void Start () {
// create a camera
GameObject cam = new GameObject();
cam.name = "Generated Camera";
cam.transform.parent = this.gameObject.transform;
cam.AddComponent<Camera>();
cam.transform.position = new Vector3(2.5f, 2, -3);
cam.transform.localEulerAngles = new Vector3(20, 325, 5);
// create a light
GameObject lightGameObject = new GameObject("Generated Light");
lightGameObject.transform.parent = this.gameObject.transform;
lightGameObject.AddComponent<Light>();
lightGameObject.light.color = Color.white;
lightGameObject.transform.position = new Vector3(-0.8f, 1.3f, -1.4f);
// create a generic cube
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = "Generated Cube";
cube.transform.parent = this.gameObject.transform;
// create a custom square
GameObject g = GetSquareGameObject("Generated Square");
g.transform.parent = this.gameObject.transform;
g.transform.localScale = new Vector3(2, 2, 2);
}
// Update is called once per frame
void Update () {
}
GameObject GetSquareGameObject(string name)
{
GameObject g;
g = new GameObject(name);
g.AddComponent<MeshFilter>();
g.AddComponent<MeshRenderer>();
// assign a mesh
g.GetComponent<MeshFilter>().mesh = GetSquareMesh();
// modify material (and shader)
g.renderer.material.color = Color.red;
Shader shader = Shader.Find("Diffuse");
g.renderer.material.shader = shader;
return g;
}
Mesh GetSquareMesh()
{
Vector3[] newVertices = new Vector3[4];
Vector3[] newNormals = new Vector3[4];
Vector2[] newUV = new Vector2[4];
int[] newTriangles = new int[6];
Mesh mesh = new Mesh();
// vertices
newVertices[0] = new Vector3(0, 0, 0);
newVertices[1] = new Vector3(0, 1, 0);
newVertices[2] = new Vector3(1, 0, 0);
newVertices[3] = new Vector3(1, 1, 0);
// normals
newNormals[0] = -Vector3.forward;
newNormals[1] = -Vector3.forward;
newNormals[2] = -Vector3.forward;
newNormals[3] = -Vector3.forward;
// uv
newUV[0] = new Vector2(0, 0);
newUV[1] = new Vector2(0, 1);
newUV[2] = new Vector2(1, 0);
newUV[3] = new Vector2(1, 1);
// triangles
// first triangle
newTriangles[0] = 0;
newTriangles[1] = 1;
newTriangles[2] = 2;
// second triangle
newTriangles[3] = 1;
newTriangles[4] = 3;
newTriangles[5] = 2;
// assign to mesh
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.normals = newNormals;
mesh.triangles = newTriangles;
return mesh;
}
}
Answer by clooper · Jul 17, 2014 at 12:33 AM
You can write an Editor script, which becomes selectable in the toolbar, which will do the initial boot up for you: ie. when selected it will create a new empty scene, delete the default camera, add a root game object, and attach your scene generating script to it, and play the result.
Make sure you save any current scene before selecting this Editor script in the toolbar.
Editor script (goes into Editor folder):
using UnityEngine;
using UnityEditor;
using System.Collections;
public class EditorTest : EditorWindow
{
bool isCreated = false;
[MenuItem("Window/Scene From Scratch")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(EditorTest));
}
void OnGUI()
{
if (!isCreated)
{
if ( EditorApplication.isPlaying == true )
{
EditorApplication.isPlaying = false;
}
EditorApplication.NewScene();
GameObject c = GameObject.Find("Main Camera");
if(c != null)
DestroyImmediate(c);
GameObject g = new GameObject("Scene From Scratch");
g.AddComponent<SceneFromScratch>(); // a scene generating script
EditorApplication.isPlaying = true;
isCreated = true;
EditorWindow.GetWindow(typeof(EditorTest)).Close();
}
}
}
And the scene generating script (referenced by above):
using UnityEngine;
using System.Collections;
/// <summary>
/// Create a scene from scratch
/// </summary>
public class SceneFromScratch : MonoBehaviour {
// Use this for initialization
void Start () {
// create a camera
GameObject cam = new GameObject();
cam.name = "Generated Camera";
cam.transform.parent = this.gameObject.transform;
cam.AddComponent<Camera>();
cam.transform.position = new Vector3(2.5f, 2, -3);
cam.transform.localEulerAngles = new Vector3(20, 325, 5);
// create a light
GameObject lightGameObject = new GameObject("Generated Light");
lightGameObject.transform.parent = this.gameObject.transform;
lightGameObject.AddComponent<Light>();
lightGameObject.light.color = Color.white;
lightGameObject.transform.position = new Vector3(-0.8f, 1.3f, -1.4f);
// create a generic cube
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = "Generated Cube";
cube.transform.parent = this.gameObject.transform;
// create a custom square
GameObject g = GetSquareGameObject("Generated Square");
g.transform.parent = this.gameObject.transform;
g.transform.localScale = new Vector3(2, 2, 2);
}
// Update is called once per frame
void Update () {
}
GameObject GetSquareGameObject(string name)
{
GameObject g;
g = new GameObject(name);
g.AddComponent<MeshFilter>();
g.AddComponent<MeshRenderer>();
// assign a mesh
g.GetComponent<MeshFilter>().mesh = GetSquareMesh();
// modify material (and shader)
g.renderer.material.color = Color.red;
Shader shader = Shader.Find("Diffuse");
g.renderer.material.shader = shader;
return g;
}
Mesh GetSquareMesh()
{
Vector3[] newVertices = new Vector3[4];
Vector3[] newNormals = new Vector3[4];
Vector2[] newUV = new Vector2[4];
int[] newTriangles = new int[6];
Mesh mesh = new Mesh();
// vertices
newVertices[0] = new Vector3(0, 0, 0);
newVertices[1] = new Vector3(0, 1, 0);
newVertices[2] = new Vector3(1, 0, 0);
newVertices[3] = new Vector3(1, 1, 0);
// normals
newNormals[0] = -Vector3.forward;
newNormals[1] = -Vector3.forward;
newNormals[2] = -Vector3.forward;
newNormals[3] = -Vector3.forward;
// uv
newUV[0] = new Vector2(0, 0);
newUV[1] = new Vector2(0, 1);
newUV[2] = new Vector2(1, 0);
newUV[3] = new Vector2(1, 1);
// triangles
// first triangle
newTriangles[0] = 0;
newTriangles[1] = 1;
newTriangles[2] = 2;
// second triangle
newTriangles[3] = 1;
newTriangles[4] = 3;
newTriangles[5] = 2;
// assign to mesh
mesh.vertices = newVertices;
mesh.uv = newUV;
mesh.normals = newNormals;
mesh.triangles = newTriangles;
return mesh;
}
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
is there a diffrence between unity C# and normal C# 1 Answer
Distribute terrain in zones 3 Answers
Object Oriented Programming and Interactble Objects 1 Answer
Cant Make C# Use waitforseconds Command 3 Answers