Search code examples
c#unity-game-enginepublic

Move 3d models in Unity 3d


In unity 3d, I've create an Empty GameObject that Instanciates a simple 3d model when i click with the mouse ( 3d model imported from blender).

I've written a simple script that moves the EmptyGameObject using

transform.Translate(speed * Time.deltaTime, 0, 0);

But when i run the project, only the Empty Game Object moving but I need that the 3d model moving to x asix. How can i resolve this problem? Thanks for the help.

Moving script (putting on EmptyGameObject):

public float speed = 0f;

    // Start is called before the first frame update
    void Start()
    {
        speed = 0f;
    }

    // Update is called once per frame
    void Update()
    {
        transform.Translate(speed * Time.deltaTime, 0, 0);
        if (Input.GetMouseButtonDown(0)) {
            speed += speed + 0.5f;

        }
    }

Script for instantiated objects:

   public GameObject model;
   public GameObject model1;


public int counter = 0;

    void Start(){
     model=  Instantiate(model, transform.position, Quaternion.identity); //spawn model
    }

    void Update(){
    if (Input.GetMouseButtonDown(0)) {
        ChangeModel();
    }
    }


    void ChangeModel(){
    counter++;
            switch (counter) {

                case 1:
                    Destroy(model);
                    Destroy(model1);
                    model = (GameObject) Instantiate(model, transform.position, Quaternion.identity);
                    break;

                case 2:
                    Destroy(model);
                    model1= (GameObject) Instantiate(model1, transform.position, Quaternion.identity);
                    counter =0;
                    break;


            }
    }

Solution

  • In general all you need to do is spawn the new objects always as children of this EmptyGameObject. Instantiate therefore has an overload taking an additional parent Transform reference to spawn the prefab as child to.

    As I understand the second script is also attached to the EmptyGameObject so your target parent is simply transform (the Transform component of the GameObject this script is attached to):

    //spawn model as child of given Transform
    model = Instantiate(prefab, transform.position, Quaternion.identity, transform); 
    

    Also note that a cast to (GameObject) is redundant since Instantiate anyway returns the type of the given prefab.


    However

    I do not really understand your usage of model, model1 and Instantiate and Destroy here ...

    What do you destroy the model for if you want to directly respawn it anyway?

    In general I think you would be way better also performance wise spawning them both once and only activate and deactivate according models:

    public GameObject prefab;
    public GameObject prefab1;
    
    void Start()
    {
        model =  Instantiate(prefab, transform.position, Quaternion.identity, transform);
        model1 = Instantiate(prefab1, transform.position, Quaternion.identity, transform);
    
        model1.SetActive(false);
    }
    
    void ChangeModel()
    {
        counter = (counter + 1) % 2;
    
        model.SetActive(counter == 0);
        model1.SetActive(counter == 1);
    }
    

    That's it. If you simply already place the two prefabs into the EmptyGameObject right from the beginning you don't need the Instantiate at all ...

    And btw in case you only have two states anyway instead of a counter you could also use a simple bool here:

    bool isModel1;
    
    private void ChangeModel()
    {
        isModel1 = !isModel1;
    
        model.SetActive(!isModel1);
        model1.SetActive(isModel1);
    }
    

    And finally note that from your movement script:

    speed += speed + 0.5f;
    

    this results in

    speed = speed + speed + 0.5f;
    

    but I guess what you rather want is

    speed += 0.5f;
    

    which results in

    speed = speed + 0.5f;