Instantiating a gameOject then referencing it?

Hi.

I need to keep track of the start position of a object, rather than use a variable I’ve decided to use a empty gameObject to reference the position.

I’ve chosen to do this because I need to know the position relative to its parent, which moves. So the gameObject would be a child of the parent meaning that its position would remain constant relative to the movement of the parent.

Its a way of me being able to return the original object back to its startpoint inside of the parent.

I’m having trouble setting this up. I want to instantiate the object and then create a reference to it so I can return its position every so often.

I’ve tried instantiating it as a transform and a gameObject and I’ve had no luck, was hoping I could get some help with this.

public GameObject midPointMarker;
private GameObject midPoint;

// Use this for initialization
    void Start () {

        //Set dir and altDir to contain the translate.direction for movement.
        setDirections ();
        //Set maxDistance and minDistance relative from midPoint in the specified directions.
        setLimits ();
        //Instantiates a transform at the obstacles oirgin and sets a midPoint to hold the gameObject.
        midPoint = Instantiate(midPointMarker, transform.position, transform.rotation);


   
    }

This is one method I tried, with it set as a gameObject. This instantly gives me the error:
“Assets/Scripts/ObstacleScript.cs(39,17): error CS0266: Cannot implicitly convert type UnityEngine.Object' to UnityEngine.GameObject’. An explicit conversion exists (are you missing a cast?)”

While when I set them as transforms I only get an error at startup.

The instantiate function will give you a object and not a GameObject.
You have to cast it so that it fits into your variable.
midPoint = (GameObject) Instantiate…

Casting in that way doesn’t appear to work at all.

public GameObject midPointMarker;
private GameObject midPoint;

midPoint = (GameObject)Instantiate(midPointMarker, transform.position, transform.rotation);

Gives:
“NullReferenceException: Object reference not set to an instance of an object
ObstacleScript.Start () (at Assets/Scripts/ObstacleScript.cs:41)”

I was reading this thread: Casting Object to GameObject - Unity Engine - Unity Discussions

I tried doing what spree said:

My current lines looks like this:

public GameObject midPointMarker;
private GameObject midPoint;
private Transform newTransform;

newTransform = Instantiate(midPointMarker, transform.position, transform.rotation) as Transform;

        midPoint = newTransform.gameObject;

Unity has the same problem as the other method with the second line stating: "
NullReferenceException: Object reference not set to an instance of an object
ObstacleScript.Start () (at Assets/Scripts/ObstacleScript.cs:41)"

The answers in the other thread seem very confused.

What I need to be able to do is to instantiate an GameObject and then be able to use .transform on it to return its transform.position and to transform.translate it.

I don’t know if it means anything but all of this is currently going in the Start () {} function.

Your heading down the wrong path here, the issue is not that your casting it to a GameObject(which will work), it is you are trying to use an object that is null.
Look at line 41 of your ObstacleScript, something there is null.
Have you assigned anything to your public variable midPointMarker?

Apologies, the casting is working I was just getting the previous error for some reason even though I was sure I had saved the script.

I believe I’ve managed to get everything I needed to work in the end, thank you for the help with the casting! :slight_smile:

void SetMidPoint () {

        midPoint = (GameObject)Instantiate(midPointMarker, transform.position, transform.rotation);
       
        midPoint.transform.SetParent (gameBoard);


    }

One more thing, that code I just posted about SetMidPoint. Will the reference held by midPoint refer to that particular clone of midPointMarker and no others? There are a few instances of the code in my scene so lots of clones of MidPointMarker being instantiated. I’m getting a few stange behaviours so I’m wondering whether or not they could be referencing clones I didn’t intend them to?

midPoint will reference a new GameObject(clone), so it should not interfere with other midPoints. But without seeing the rest of your code its hard to say for sure.

Thanks for the help guys!

I’ve been having an issue that actually caused me to try and use the reference to gameObject in the first place as an attempt to fix it.

I’m making a game where you there’s a board open box suspended in the air. The player tilts the box using the axis controls, an example of the box:

Imgur
Imgur

The board tilt maximum is currently set to 45.

The box tilts using this code:

using UnityEngine;
using System.Collections;

public class WorldController : MonoBehaviour {
    public float tiltAngle;
    public float smooth;
    // Use this for initialization
    void Start () {

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

        //Get the input values.
        float tiltX = Input.GetAxis ("Vertical") * tiltAngle;
        float tiltZ = (Input.GetAxis ("Horizontal") * tiltAngle) * -1;

   
        Quaternion target = Quaternion.Euler (tiltX, 0, tiltZ);



        transform.rotation = Quaternion.Slerp (transform.rotation, target, Time.deltaTime * smooth);
        

    }
}

I wanted to make obstacles that I can place in the world, which then move between two points in a single direction at a set speed.

My original scripts suceeded at this but I hit a problem. The obstacles would move outside of their set barriers when the gameboard tilted. All the obstacles were childs of the board so moved with it, but when they were at an angle, they would suddenly decide that instead of stopping where they usually would, they would instead shift further in one direction before returning.

My new script tried to tackle this by creating an empty gameObject on the starting position of the obstacle to store its location. This is because I thought that maybe the obstacle was moving along its axis as it rotated therefore limits set to its transform.position would be invalid.

The new script hasn’t fixed the problem, the changes seem less extreme now, but they are still there.

I created an object that moved forward and then back, the limit in each direction set to 2. If the object starting at z 10 it would move to z12 then back to z8 then repeat. This works fine when the board isn’t moving, however when it does it changes. For example it will start moving forward to z14 then back to z 10.

This is my full obstacle code, I’ve tried lots of different things and can’t figure out how to stop this shifting from happening. I’m hoping someone can help.

using UnityEngine;
using System.Collections;


public class ObstacleScript : MonoBehaviour {



    private Transform gameBoard;
    public GameObject midPointMarker;
    private GameObject midPoint;


    public string direction1;
    public string direction2;
    private Vector3 dir;
    private Vector3 altDir;


    public float direction1Limit;
    public float direction2Limit;
    private Vector3 maxDistance;
    private Vector3 minDistance;

    public float speed;
    private Vector3 currentPos;
    private bool onReturn = false;





    // Use this for initialization
    void Start () {

        //Set dir and altDir to contain the translate.direction for movement.
        SetDirections ();

        //Instantiates a transform at the obstacles oirgin and sets a midPoint to hold the gameObject. The midPoint keeps aligned with the parent.
        SetMidPoint ();

        //Set maxDistance and minDistance relative from midPoint in the specified directions.
        SetLimits ();



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

        if (onReturn == false) {
       
            if (direction1 == "forward") {
                StartCoroutine ("MoveForward");
            } else if (direction1 == "back") {
                StartCoroutine ("MoveBack");
            } else if (direction1 == "left") {
                StartCoroutine ("MoveLeft");
            } else if (direction1 == "right") {
                StartCoroutine ("MoveRight");
            } else if (direction1 == "down") {
                StartCoroutine ("MoveDown");
            } else if (direction1 == "up") {
                StartCoroutine ("MoveUp");
            }
       
        }

        if (onReturn == true) {

            if (direction2 == "forward") {
                StartCoroutine ("MoveForward");
            } else if (direction2 == "back") {
                StartCoroutine ("MoveBack");
            } else if (direction2 == "left") {
                StartCoroutine ("MoveLeft");
            } else if (direction2 == "right") {
                StartCoroutine ("MoveRight");
            } else if (direction2 == "down") {
                StartCoroutine ("MoveDown");
            } else if (direction2 == "up") {
                StartCoroutine ("MoveUp");
            }

        }


    }

    //Functions//

        void SetDirections () {

        if (direction1 == "forward") {
            dir = Vector3.forward;
        } else if (direction1 == "back") {
            dir = Vector3.back;
        }  else if (direction1 == "up") {
            dir = Vector3.up;
        } else if (direction1 == "down") {
            dir = Vector3.down;
        } else if (direction1 == "left") {
            dir = Vector3.left;
        } else if (direction1 == "right") {
            dir = Vector3.right;
        }
       
        if (direction2 == "forward") {
            altDir = Vector3.forward;
        } else if (direction2 == "back") {
            altDir = Vector3.back;
        }  else if (direction2 == "up") {
            altDir = Vector3.up;
        } else if (direction2 == "down") {
            altDir = Vector3.down;
        } else if (direction2 == "left") {
            altDir = Vector3.left;
        } else if (direction2 == "right") {
            altDir = Vector3.right;
        }

    }

    void SetMidPoint () {

        midPoint = (GameObject)Instantiate(midPointMarker, transform.position, transform.rotation);
       
        gameBoard = transform.parent;
        midPoint.transform.SetParent (gameBoard);


    }

    void SetLimits () {
   
        if (direction1 == "forward") {
            maxDistance.z = (midPoint.transform.position.z + direction1Limit);
        } else if (direction1 == "back") {
            maxDistance.z = (midPoint.transform.position.z - direction1Limit);
        } else if (direction1 == "left") {
            maxDistance.x = (midPoint.transform.position.x - direction1Limit);
        } else if (direction1 == "right") {
            maxDistance.x = (midPoint.transform.position.x + direction1Limit);
        } else if (direction1 == "up") {
            maxDistance.y = (midPoint.transform.position.y + direction1Limit);
        } else if (direction1 == "down") {
            maxDistance.y = (midPoint.transform.position.y - direction1Limit);
        }
       
        if (direction2 == "forward") {
            minDistance.z = (midPoint.transform.position.z + direction2Limit);
        } else if (direction2 == "back") {
            minDistance.z = (midPoint.transform.position.z - direction2Limit);
        } else if (direction2 == "left") {
            minDistance.x = (midPoint.transform.position.x - direction2Limit);
        } else if (direction2 == "right") {
            minDistance.x = (midPoint.transform.position.x + direction2Limit);
        } else if (direction2 == "up") {
            minDistance.y = (midPoint.transform.position.y + direction2Limit);
        } else if (direction2 == "down") {
            minDistance.y = (midPoint.transform.position.y - direction2Limit);
        }
   
    }

    //Coroutines//
   
    IEnumerator MoveForward () {

        //Determine whether or not to use dir or altDir.

        if (direction1 == "forward") {

            while ((transform.position.z) < maxDistance.z) {
                transform.Translate (dir * (Time.deltaTime * speed));
                maxDistance.z = midPoint.transform.position.z + direction1Limit;
                yield return null;
            }
        } else {
            while ((transform.position.z) < minDistance.z) {
                transform.Translate (altDir * (Time.deltaTime * speed));
                minDistance.z = midPoint.transform.position.z + direction2Limit;
                yield return null;
            }
        }
            //Detect whether or not this direction was its first or second move.
            if (direction1 == "forward") {
            onReturn = true;
        }     else {
            onReturn = false;
        }

    }

    IEnumerator MoveBack () {
       
        //Determine whether or not to use dir or altDir.
       
        if (direction1 == "back") {
           
            while ((transform.position.z) > maxDistance.z) {
                transform.Translate (dir * (Time.deltaTime * speed));
                maxDistance.z = midPoint.transform.position.z - direction1Limit;
                Debug.Log ("test1");
                yield return null;
            }
        } else {
            while ((transform.position.z) > minDistance.z) {
                transform.Translate (altDir * (Time.deltaTime * speed));
                minDistance.z = midPoint.transform.position.z - direction2Limit;
                yield return null;
            }
           
            //Detect whether or not this direction was its first or second move.

        }

        if (direction1 == "back") {
            onReturn = true;
        } else {
            onReturn = false;
        }

    }

    IEnumerator MoveLeft () {
       
        //Determine whether or not to use dir or altDir.
       
        if (direction1 == "left") {
           
            while ((transform.position.x) > maxDistance.x) {
                transform.Translate (dir * (Time.deltaTime * speed));
                maxDistance.x = midPoint.transform.position.x - direction1Limit;
                yield return null;
            }
        } else {
            while ((transform.position.x) > minDistance.x) {
                transform.Translate (altDir * (Time.deltaTime * speed));
                minDistance.x = midPoint.transform.position.x - direction2Limit;
                yield return null;
            }
        }
        //Detect whether or not this direction was its first or second move.
        if (direction1 == "left") {
            onReturn = true;
        }     else {
            onReturn = false;
        }
       
    }

    IEnumerator MoveRight () {
       
        //Determine whether or not to use dir or altDir.
       
        if (direction1 == "right") {
           
            while ((transform.position.x) < maxDistance.x) {
                transform.Translate (dir * (Time.deltaTime * speed));
                maxDistance.x = midPoint.transform.position.x + direction1Limit;
                yield return null;
            }
        } else {
            while ((transform.position.x) < minDistance.x) {
                transform.Translate (altDir * (Time.deltaTime * speed));
                minDistance.x = midPoint.transform.position.x + direction2Limit;
                yield return null;
            }
        }
        //Detect whether or not this direction was its first or second move.
        if (direction1 == "right") {
            onReturn = true;
        }     else {
            onReturn = false;
        }
       
    }

    IEnumerator MoveDown() {
       
        //Determine whether or not to use dir or altDir.
       
        if (direction1 == "down") {
           
            while ((transform.position.y) > maxDistance.y) {
                transform.Translate (dir * (Time.deltaTime * speed));
                maxDistance.y = midPoint.transform.position.y - direction1Limit;
                yield return null;
            }
        } else {
            while ((transform.position.y) > minDistance.y) {
                transform.Translate (altDir * (Time.deltaTime * speed));
                minDistance.y = midPoint.transform.position.y - direction2Limit;
                yield return null;
            }
        }
        //Detect whether or not this direction was its first or second move.
        if (direction1 == "down") {
            onReturn = true;
        }     else {
            onReturn = false;
        }
       
    }

    IEnumerator MoveUp () {
       
        //Determine whether or not to use dir or altDir.
       
        if (direction1 == "up") {
           
            while ((transform.position.y) < maxDistance.y) {
                transform.Translate (dir * (Time.deltaTime * speed));
                maxDistance.y = midPoint.transform.position.y + direction1Limit;
                yield return null;
            }
        } else {
            while ((transform.position.y) < minDistance.y) {
                transform.Translate (altDir * (Time.deltaTime * speed));
                minDistance.y = midPoint.transform.position.y + direction2Limit;
                yield return null;
            }
        }
        //Detect whether or not this direction was its first or second move.
        if (direction1 == "up") {
            onReturn = true;
        }     else {
            onReturn = false;
        }
    }



}

I think you want to use transform.localPosition so that rotating the board has no impact.

1 Like

You’re officially my hero, that line just fixed the wall I’ve been hitting for the last 4 days! :slight_smile: It even allowed me to omit all the gameObject midPoint stuff. One simple execution of the SetLimits () function where instead of midPoint.transform.position it was transform.localPosition was all it needed! I can move onto the next obstacle now, no pun intended… :smile:

1 Like