How can I make my gameobject instantiate and translate along the axis it was spawned at?

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

public class MoveAndRotateAsteroidTrap : MonoBehaviour {

    public float moveSpeed = 10f;
    public float rotateSpeed = 10f;

    // Use this for initialization
    void Start () {
 
    }
 
    // Update is called once per frame
    void Update () {

        transform.Translate ( transform.right * moveSpeed, Space.World  );

        transform.Rotate ( 0, 0, 1 * rotateSpeed * Time.deltaTime );
 
    }
}

I’m in a situation where I know what the problem is and why it’s happening in the code but I don’t know how to fix it. I’ve decided that I want my gameobject when it instantiates to move and continue along the direction it spawned at. The reason I’m doing it this way is because I want the gameobject to spawn and move in fairly random direction and I am rotating an empty in order to do this.

However this is where everything falls apart, because translate it is in the update function the gameobject I’ve instantiated is now following along the X axis as the empty rotates which makes sense because that’s what I’ve told it to do. I’ve accidentally made a great effect here but I want the gameobject to be travelling along the axis in a straight line where it spawned rather than following my empty like it’s in a vortex.

I just double checked and I haven’t done anything silly with the gameobject being parented to the empty so I’ve run out of ideas on why this is happening. To get an idea of what I’m aiming for it’s the same sort of idea as a rotating turret in one of those simple platform shooters like Contra where you’ve got the turret rotating and spawning bullets that travel in a straight line.

See the turret at the bottom right? That’s what I’m thinking of, my code is even simpler than that though and it’s just rotating all the way around.

have you tried “Vector3.right” rather than “transform.right”, you might have told it to do the translate in world coordinate system, but you’re still reading the local “right”.

That sort of fixed it, but now instead of spawning and going in the direction of the axis it’s now just moving left again and nothing else, back to square one. I just had a thought, is it perhaps that I need to get the current rotation of the empty at the time of it spawning? Trying to think.

Why not put it in an empty gameobject, rotate that empty object so it’s forward is the direction you want to go. Then move that object along it’s transform forward and then rotate the sprite which is a child object.

can you explain what you are referring to as “the axis”? did you mean “forward in the direction they were spawned in”?

generally I’d read “axis” as the world x/y/z or local x/y/z, which is what transform.forward, vector3.right, etc. are tied to

Okay, I hope this diagram makes sense, I’ll try a better explanation this time around and yes I did mean axis as in the world x/y/z and so on :stuck_out_tongue: What’s happening is the gameobject I’m spawning in is following the empty in an arc along the axis that I want the gameobject. What I want is for the gameobject to spawn in go along the axis at the current time of spawning and not follow the arc but go in a straight line.

Does that make sense? Let me know if the little diagram helps, for the record, the reason I’m not using forward is because I’m on a 2D project and only have the x and y axis, the little dashes show where axis rotation.

I don’t totally follow everything you’ve said, but in case it’s helpful, store the direction you want to go in start and use that as you travel, whether you rotate or not, it shouldn’t matter. If that’s simple enough for your current situation.

If I’m understanding you properly, your object is rotating (for visual effect) but it’s moving along the currently updated axis rather than the one you spawned at. In that case, store a reference to the starting direction and then move along that axis rather than the current one.

Vector3 movementDirection;

void Start()
{
    movementDirection = transform.right; // store the value when we spawn
}

void Update()
{
    transform.Translate(movementDirection * speed * Time.deltaTime, Space.World);
    transform.Rotate ( 0, 0, 1f * rotateSpeed * Time.deltaTime );
}

Huh, well I put in a Debug.Log just to be sure I’m not doing anything stupid, for whatever reason my gameobject is simply translating right which is weird because the log is definitely detecting and storing the rotation of the axis when I press play.

Edit: Oh wait! I think I may have worked it out could it be that I need to grab the position of the empty? Ohh, going to have to think about this, but I think I’ll be able to fix it.

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

public class MoveAndRotateAsteroidTrap : MonoBehaviour {

    public float moveSpeed = 15f;
    public float rotateSpeed = 10f;

    Vector3 movementDirection;

    // Use this for initialization
    void Start () {

        movementDirection = GameObject.Find ("AsteroidTrapEmpty").transform.right;

        Debug.Log ("Axis direction stored");
    
    }
 
    // Update is called once per frame
    void Update () {

        transform.Translate ( movementDirection * moveSpeed * Time.deltaTime, Space.World  );

        transform.Rotate ( 0, 0, 1f * rotateSpeed * Time.deltaTime );
    
    }
}

I’m proud of myself! Got the problem fixed! :smile:

I don’t know whether it was my explanation guys, but I wanted to get the axis of the empty spawn not the gameobject that was being spawned in, now it’s working absolutely perfectly. I’m going to have to test it to make sure that it can work with multiple empties but I’ve got everything figured out now.

It’s actually really nice to watch it all working now because there’s so much I’ll be able to do with it level design wise.

1 Like

Cool. Glad you got it working. :slight_smile:

Just thinking out loud here, but if you spawn the new object with the rotation of the empty spawn area, you can then get its own ‘.right’.

Here’s a video of the code in action by the way, you’ll see what I was on about if you check it out. I don’t know why I didn’t think about this before, but it’s just like the technique used for when you make a gun shoot in Unity, I just had to apply it to my game with the idea I was thinking of.

Ya, cool… I understood. Poor character at the end of the video got obliterated :slight_smile:

So I’ve shot myself in the foot a bit using this method, it all works for one empty, but now I have a new problem when I try to duplicate my spawns. Since it’s searching for a name specifically the moment the name changes through duplication my gameobjects still only spawn on one empty.

I’ve thought a bit about this already, the best solution I can think of right now is maybe re-using a trick @methos5k taught me where you can use GetComponent in reverse and grab the gameObject.position and the rotation for both my trap spawning script and my trap movement script.

I’m not convinced that will work though as the more experienced programmers have probably already figured out reading this, because in the end it’s just blindly reading off wherever the script is attached. It might work a bit, but I think I’m trying to work out something a bit more sophisticated.

Anyone got any ideas? I’ll have a think about it today.

Right, well the launcher is responsible for spawning the asteroids/rocks that leave it, yes? Use that direction (of the launcher at the time of spawn)?

Sorry if I’ve misread something here… that happens. :slight_smile:

It’s not as easy to explain as I thought, I think I was thinking about this problem even in my sleep lol :stuck_out_tongue: no, that’s what I’m doing right now, where it just reads off the axis of the name. What I need is something like public gameobject where you can click and drag specific empties into the asteroids.

Now this will work the opposite way, so for instance if I want to have the asteroids spawn on a specific empty, that’s easily fixed but with the transform.right line I can’t do that because the asteroids have to be instantiated in from the resources folder or whichever place they’re coming from.

The problem happens where as you call it there are multiple duplicates of the same launcher.

Okay, well my question is this: does the empty game object spawn the asteroid?
If so, use that… I’m not talking about the string name.

If it doesn’t then the spawning script must know where to put the asteroid, ie: its position (at/in/near the empty), and again you could use that.

By ‘that’ , I mean the empty (empty’s “.right” direction).

Can you just post a bit of the spawn/instantiate code, if that didn’t make sense? :slight_smile:

It did make sense but that’s not what I’m after, I may need to think about just how to explain this if I’m going to get it fixed, I’ll post the code up for you. The empty isn’t the issue, the asteroid is the issue because I need the asteroid to grab the axis of the empties and spawn at all of them rather than just one.

Looking at the code again I’ve just realised it doesn’t really need fixing on this bit, bahhh, now I know why I was procrastinating so much on this problem.

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

public class InstantiateAsteroidTrap : MonoBehaviour {

    private Coroutine _spawnCoroutine = null;

    // Use this for initialization



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

            if (_spawnCoroutine == null)

            {
                _spawnCoroutine = StartCoroutine ("TrapDelayAsteroidX");
                Debug.Log ("Asteroid Trap Activated");
            }
    }


    IEnumerator TrapDelayAsteroidX ()
    {
        while (true)

        {
            yield return new WaitForSeconds (5);
            Instantiate (Resources.Load ("AsteroidTrap1EmptyX"), GameObject.Find ("AsteroidTrapEmpty").transform.position, Quaternion.identity);
        }
    }





}

Well, what I was thinking was that you reference the empty from this spawner script, and then pass that along to the newly instantiate asteroid itself. :slight_smile:

Yeah I was wondering about that, but the problem is it needs to work across multiple duplicates of the empties.