Heramb
Heramb

Reputation: 45

Dynamically adding 3d objects to a scene in Unity3d

I am working on an Unity3d project in which I want to dynamically add 3d objects to the scene, at the same position, orientation, upon a keyPress. For doing so, I imported these objects and made a prefab for all of these.. I am using the following script to do so.. bt it doesn't do the needfull.. The new object gets instantiated and gets added to the scene but the old objects don't get destroyed. And also ,the position of the new objects is not always the same. The scene consists of a Cube initially. After I press '1' ,'2' etc .. I want a new Object to replace the 1 being displayed (at the same position).

script :

var myCar : GameObject;
var Cube : GameObject;
var Globe: GameObject;
var Clock : GameObject;
var Pistol : GameObject;
var LCD : GameObject;
var prev : int;
var temp: GameObject; 
function Start ()
{
    prev =0;
    temp=null;

}

function Update () 
{
    if(prev==0)
        temp=Cube;
    else if(prev==1)
        temp=myCar;
    else if(prev==2)
        temp=Globe;
    else if(prev==3)
        temp=Pistol;
    else if(prev==4)
        temp=Clock;
    else if(prev==5)
        temp=LCD;       

    if(Input.GetKey(KeyCode.Alpha1 || KeyCode.Keypad1))
    {
        if(prev!=1)
        {
            Instantiate(myCar,temp.transform.position ,temp.transform.rotation);
            myCar.transform.localScale = Vector3(0.06,0.06,0.06);
            Destroy(temp);
            prev=1;
        }     
    }
    else if(Input.GetKey(KeyCode.Alpha2 || KeyCode.Keypad2))
    {
     if(prev!=2)
     {
        Instantiate(Globe,temp.transform.position ,temp.transform.rotation);
        Globe.transform.localScale = Vector3(0.04,0.04,0.04);
        Destroy(temp);
        prev=2;
     }

    }
    else if(Input.GetKey(KeyCode.Alpha3 || KeyCode.Keypad3))
    {
     if(prev!=3)
     {
        Instantiate(Pistol,temp.transform.position ,temp.transform.rotation);
        Pistol.transform.localScale = Vector3(0.03,0.03,0.03);
        Destroy(temp);
        prev =3;
     }
    }
    else if(Input.GetKey(KeyCode.Alpha4 || KeyCode.Keypad4))
    {
     if(prev!=4)
     {
          Instantiate(Clock,temp.transform.position ,temp.transform.rotation);
          Clock.transform.localScale = Vector3(0.08,0.08,0.08);
            Destroy(temp);
            prev=4;
     }

    }
    else if(Input.GetKey(KeyCode.Alpha5 || KeyCode.Keypad5))
    {
     if(prev!=5)
     {
        Instantiate(LCD,temp.transform.position ,temp.transform.rotation);
        LCD.transform.localScale = Vector3(0.04,0.04,0.04);
        Destroy(temp);
        prev=5;
     }
    }
}

Upvotes: 3

Views: 2683

Answers (1)

Kay
Kay

Reputation: 13146

There are several things to consider:

  1. It would be better to store a reference to the currently active object intead of the if-else-if part.
  2. Destroy is called on the prefab objects but not on the existing GameObject instance and thus doesn't do anything.
  3. The same for all manipulations of transform. They affect the prefabs only.
  4. Not really a bug but really an enhancement: Scale your models in our 3D software so that they can be instantiated without localScale adjusting.
    UPDATE: If you don't have access to the original models of the 3D software like Blender, Maya, ... you can easily define the appropriate scale in the prefab. The keypoint is to minimise repeating stuff in your code and to put all kind of property settings into the prefab.

Putting this altogether, my suggestions:

  1. Refine your original models like in 4.
  2. Introduce a member variable to store a reference to the current object.
    UPDATE: If you want a special object for example Cube initialised on start, you first drag it into the scene, and then drag the newly created Cube from hierarchy view to the varable current. So you see the cube first when starting the scene and your script knows that this is current when it has to replace it.
  3. Create a method for object instantiation

I'm working in C# but it should be something like

var current : GameObject;  

...

function ReplaceObject (prefab : GameObject, newKey : int) {
    if (newKey != prev) {
        GameObject newObject = Instantiate(prefab, current.transform.position, 
            current.transform.rotation);
        Destroy(current);
        current = newObject;
        prev = newKey;
    }
}  

...

function Update () 
{
    if(Input.GetKey(KeyCode.Alpha1 || KeyCode.Keypad1)) {
        ReplaceObject (myCar, 1);
    } else if(Input.GetKey(KeyCode.Alpha2 || KeyCode.Keypad2))
        ReplaceObject (Globe, 2);

Upvotes: 4

Related Questions