1

I'd like some help with the following issue. I'm making a simple game where you have a character running and he has to jump over obstacles coming at him.

And I'm currently stuck when it comes to creating GameObjects and randomly generating them within the game scene at run time.

I've written a class to help accomplish this:

using UnityEngine;
using System.Collections;

public class randomObstacles : MonoBehaviour {

    public GameObject myCube;
    public Vector3 spawnLocation = new Vector3(0,2,0);

    // Use this for initialization
    void Start () {
        GameObject SpawnLocation = (GameObject)Instantiate(myCube, spawnLocation, Quaternion.identity);
    }

    // Update is called once per frame
    void Update () {

    }
}

The above code is what I wrote to simply create Objects, one after the other. But when I run the game, it comes up empty -_- !

Can anyone please tell me where am going wrong, and from the look of it my code doesn't seem to do what I am hoping to achieve :(

I've attached the above script into an empty GameObject as I saw in a tutorial from the Unity Community forum, but that did not help either. (I've looked around and it seems like no one has come across such an issue - I could bee wrong)

6
  • When do you define the variable "myCube"? Because currently, it's not assigned. Commented Apr 24, 2013 at 4:53
  • If myCube is preset in editor and points to a prefab or an object existing within the scene, the code should work fine. Commented Apr 24, 2013 at 6:00
  • @LightStriker Is "myCube" not assigned? I thought I did with this line of code GameObject SpawnLocation = (GameObject)Instantiate(myCube, spawnLocation, Quaternion.identity); ! Thank you for pointing that out! Though I am not quite sure how nor where I'll assign it!! :( Commented Apr 24, 2013 at 6:16
  • @Kay I tried to assign the script to an existing object within the scene but that didn't work. Commented Apr 24, 2013 at 6:21
  • 1. You have one GameObject, let's call it initial in the scene where you attach randomObstacles. 2. You should have another one that you have to convert into a prefab and call it myCubePrefab. 3. Drag the myCubePrefab on myCube in the randomObstacles component on initial Commented Apr 24, 2013 at 7:59

3 Answers 3

7

It would seem that your myCube variable is the root of your problems, having tested it in a scene of my own. By subsituting

(GameObject)Instantiate(myCube, ... 

with

(GameObject)Instantiate(GameObject.CreatePrimitive(PrimitiveType.Cube), ...

I was able to produce a cube at (0,2,0) with no qualms. Perhaps your myCube GameObject is missing a Mesh Renderer, in which case it would appear in the Hierarchy during runtime even though it would not appear visible in Game View. Perhaps you are not assigning it in the Inspector before you run the game, in which case the myCube variable would refer to null and thus not be created. Additionally, though you may be assigning the GameObject you instantiate to SpawnLocation, it is an unused local variable (something MonoDevelop or your code editor should notify you of). Make sure you either provide a reference to a myCube GameObject in the Inspector before runtime or through script referencing to a loaded prefab/GameObject during runtime. It would also be helpful to provide a fallback (say, to PrimitiveType.Cube perhaps?), which will make your code more robust and able to handle errors in referencing should they arise.

Regardless, in order to achieve the functionality you have described, first make sure yo have properly prepared whatever you would desire myCube to be. Also, for future posterity, you may want to initialize your spawnLocation in the Start routine, and assign the variable coordinates by substituting Random.value * yourValueCeiling in for each random coordinate you would like myCube to spawn on. You could even go as far to make a helper method externalized and thus independent from the start routine, such that you will not have to have a hundred instances of a single script to create a hundred instances of what you need; rather, you can call the method through a single script, and save yourself trouble in this way. If you would so appreciate it, here is my implementation of your objective, hope this helps!

using UnityEngine;
using System.Collections;

public class randomObstacles : MonoBehaviour {

    public Vector3 spawnLocation;
    public GameObject myCube;

    // Use this for initialization
    void Start () {
        if (myCube != true) {
            Debug.Log("myCube not set");
            myCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        }
        if (myCube.renderer.enabled == false) {
            Debug.Log("myCube not rendered");
            myCube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        }
        CreateCube();
    }

    // Update is called once per frame
    void Update () {  
    }

    void CreateCube() {
        spawnLocation = new Vector3(0, Random.value * 10, 0);
        Instantiate(myCube, spawnLocation, Quaternion.identity);
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

I've just tried the sample you've given me, unfortunately, nothing appears. I'm not so sure as to why nothing appears!
What messages are given in the log? Does myCube not set or myCube not rendered appear? You might want to place another Debug.Log in CreateCube().
I've attached the script to an empty gameObject first then I tried doing the same with cube, but either way it still says that there's no objects linked to the script and nothing appear on the screen at runtime.
I've figured it out, I mean how and where to place the code and objects so that that it appears. Though now, I have a few 100s of cubes bouncing all over the game scene...haha!! Any suggestions on how to fix that? I was thinking to adjust the spawnLocation = new Vector3(0, Random.value * 10, 0); to spawnLocation = new Vector3(0, Random.value * 5, 0); ! Lastly, is there a way to keep every object in the same location - as in on the ground level for example...!
You may want to try tweaking spawnLocation as you've suggested; for example, you may want to try spawnLocation = new Vector3(Random.value * 5, Random.value * 5, Random.value * 5); to spread out your cubes in 3D space. It is likely you have Rigidbody/Mesh Collider attatched to your myCube, in which case spawning too many of them close together will cause the problems you've described. Lastly, you can add a plane or a floor at y = 0 and a dd a collider to it to ensure that the cubes settle there.
7

It may be worth pointing out that you're creating your object in the Start method, which means your code will only run once: from the name of your class, I'd assume you want to create more than one object using this code.

If you move the code into Update you'll create one object per frame, which is most likely too many. My guess would be that you want something like a coroutine that will run on a random interval, and then spawn cubes repeatedly over time, something like this:

void Start () {
    StartCoroutine("SpawnObjects");
}

IEnumerator SpawnObjects()
{
    while (keepAddingObjects) // a boolean - could just be "true" or could be controlled elsewhere
    {
        GameObject SpawnLocation = (GameObject)Instantiate(myCube, spawnLocation, Quaternion.identity);
        float delay = Random.Range(1f, 5f); // adjust this to set frequency of obstacles
        yield return new WaitForSeconds(delay);
    }
}

1 Comment

this runs only once. not repeated. you should surround SpawnObjects() inner codes to while(true)
2

Taken from my own code in a game that auto generate mazes:

public class Cell
{
    private GameObject instance;

    public void CreateVisual()
    {
        // Load a GameObject that exist inside the "Resources" folder.
        GameObject prefab = (GameObject)Resources.Load("Models/Walls/3W1"); 

        // Create an instance of the prefab
        instance = (GameObject)GameObject.Instantiate(prefab);
        instance.transform.position = myPosition;
    }
}

I think the part you are missing is the Resources.Load() method.

3 Comments

I would separate the prefab loading code into a method called once only. In the current version the prefab is loaded everytime when calling CreateVisualmore than once.
I don't think this is correct - the prefab is being set through the inspector using the myCube field.
@Kay It's only an example. In the real code, the loading is part of the Start() method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.