0
\$\begingroup\$

I would like to create an object dynamically when the player presses Q and use this object in Instantiate and in transform.Translate.

The problem is that the translation must be outside the if that checks for the Q press, but it applies to the cube that I created inside the if.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class instancier_new_object : MonoBehaviour {

    public float moveSpeed=5f;

    void Update () {
        if (Input.GetKeyDown (KeyCode.Q)) {
            GameObject objet = new GameObject ("objet");            
            GameObject cube = new GameObject ("cube");

            cube = Instantiate(
                       objet,
                       new Vector3(1, 2, 3),
                       Quaternion.identity
            );
        } 

        cube.transform.Translate(
                 Time.deltaTime*moveSpeed,
                 0,
                -Time.deltaTime*moveSpeed,
                 Space.Self
        );
    }
}
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

If you want to refer to the object outside of the if so that it moves even on frames when you're not pressing Q, then you need to store it in a member variable that can remember it between frames, from one invocation of Update to another.

While we're at it, we can also remove some redundant instantiation:

public class CreateObject : MonoBehaviour {

    public float moveSpeed = 5f;

    // Member variable to hold onto our spawned object.
    Transform _spawnedObject;

    void Update () {
        if (Input.GetKeyDown (KeyCode.Q)) {          
            GameObject myObject = new GameObject("object");

            // Store the transform of the object to refer to it again later.
            _spawnedObject = myObject.transform;
            _spawnedObject.position = new Vector3(1, 2, 3);
        } 

        // Check that we have a spawned object before trying to move it.
        if(_spawnedObject != null) {
            Vector3 step = new Vector3(1, 0, -1) * moveSpeed * Time.deltaTime;
            _spawnedObject.Translate(step, Space.Self);
        }
    }
}

This is very much the same as I've shown you in previous answers, so I encourage you to study them in more detail.

We can make this even cleaner though, by doing as I've recommended to you previously and separating the spawning logic from the moving logic.

Our movement logic can be very simple then:

public class TranslateOverTime : MonoBehaviour {

    public Vector3 velocity = new Vector3(1, 0, -1);

    void Update() {
        transform.Translate(velocity * Time.deltaTime, Space.Self);
    }
}

And our spawner stays simple too:

public class CreateMovingObject : MonoBehaviour {

    public float moveSpeed = 5f;

    void Update () {
        if (Input.GetKeyDown (KeyCode.Q)) {   
            // Create the new object where we want it to be.       
            GameObject myObject = new GameObject("object");
            myObject.transform.position = new Vector3(1, 2, 3);

            // Attach the movement behaviour to it, and configure its motion.
            var mover = myObject.AddComponent<TranslateOverTime>();
            mover.velocity = new Vector3(1, 0, -1) * moveSpeed;
        }
    }
}
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .