Unity3D: Instantiate creates NullReferenceException - unity3d

Transform child = GameObject.FindWithTag("state").transform;
child.name = first_guy+""; child.tag = first_guy+"";
GameObject child_dup = Instantiate( child, new Vector3(0,0,0),Quaternion.identity) as GameObject;
Debug.Log (child_dup.name);
The above code gives me error, "NullReferenceException: Object reference not set to an instance of an object".
Is this because I am trying to instantiate a local variable? How to duplicate a gameobject in run time?

Your problem is that you are trying to instantiate a Transform which is a component and cannot be instantiated, as it must be attached to a GameObject.
Instantiate( child.gameObject, ...)

Related

Passing Gameobject throught class in Unity

im trying to make a card game. There is something I can't understand:
I have a class named HandManagement that has a list of GameObject and a method AddToHand that add to a list (the hand) a gameobject passed through variable (bringing in hand)
I have a Tile GameObject on the screen with a script that, when collides with mousedown:
the variable hand of HandManagement type is called with method AddToHand to add that gameobject to hand (AddToHand(this.gameobject)
When I try unity tells me that the object doesnt exist..
Why?
Thank you
Tile Class:
{
m_ObjectCollider.isTrigger = true;
tileInHand.PickTile (tileName);
HandManagement Class:
public GameObject tile;
public List<GameObject> hand = new List<GameObject>();
public void PickTile(string pickedTile)
{
Debug.Log ("picked");
tile = Instantiate (tile);
tile.transform.SetParent (transform, false); //i put it in a grid of hand card
hand.Add (tile); //I add it to the list of card in hand
}}
first of all, change the string to a GameObject, then Instantiate it
public void PickTile(GameObject pickedTile)//change it from string to gameobject
{
Debug.Log ("picked");
tile = Instantiate (pickedTile);//instantiate the picked tile.
tile.transform.SetParent (transform, false);
hand.Add (tile);
}}
now tile holds the GameObject "pickedTile" so it will be added to the grid and to the hand.
Next, you need to change the referenced object from a string to a GameObject
tileInHand.PickTile(tileGameObject);
The Instantiate function copies the object tile into tile, this is empty to begin with. Try instantiating a prefab gameobject into the tile, or make sure gameobject tile is never empty (eg. by setting it in the Start()).
https://docs.unity3d.com/ScriptReference/Object.Instantiate.html

Prefab instantiated as an object with my methods

I have an idea that there must be a way to attach a class to a prefab - basically to add my own methods to the code. Then, when I instantiate my prefab in runtime I want it to be an instance of this class.
Now, I can attach a script to a prefab and it's Start and Update works, but my idea is something like this:
public class PowerupWidget : MonoBehaviour {
void Start() {
Debug.Log("PowerupWidget created!!!");
}
void SetTitle(string title) {
// ... set the prefab's title widget text ...
}
}
When I instantiate my prefab, the Start method is called. But the instance is of course the GameObject type.
// in my scene script:
// prefab is my PowerupWidget
GameObject p = Instantiate(prefab, transform.position, Quaternion.identity, this.transform);
// here p is GameObject of course
Is there a way how to get to the instance of the PowerupWidget class, or am I completely wrong in my assuptions?
Structure in unity :
Things are divided into entities and component, when entities are gameobject and components are classes(Script) that are attached to this gameobject.
You just need to do this
PowerupWidget yourWidget = p.GetComponent<PowerupWidget>();

Is there a way to specify where a game object spawns in the hierarchy in unity?

I have set up a random spawner that creates new game objects but they are being created outside of my canvas and therefore can't be seen when play the game. Is there any way to fix this? The objects 'neg thoughts' are UI Buttons and are being created outside of the canvas even though I need them to appear on screen so they can be used.
I did see a similar question but the suggestions didn't work for my problem.
this is very frustrating for me and any help would be awesome!
You can simply pass the parent into Instantiate
parent Parent that will be assigned to the new object
var newObj = Instantiate(prefab, parentTransform);
or with additional transforms
var newObj = Instantiate (prefab, position, rotation, parentTransform);
Or as others already said you can still do it afterwards at any time either by simply assigning a new transform.parent
newObj.transform.parent = parentTransform;
or using transform.SetParent
newObj.transform.SetParent(parentTransform, worldPositionStays);
The advantage of the later is that you have an optional parameter worldPositionStays
worldPositionStays If true, the parent-relative position, scale and rotation are modified such that the object keeps the same world space position, rotation and scale as before.
assigning a new
transform.parent = parentTransform;`
will always act the same way as
transform.SetParent(parentTransform);
since the default value for worldPositionStays (so if you don't explicitly pass it) is true.
So for the specific case of UI in a Canvas you could use
public TheSpawnComponent : MonoBehaviour
{
// Via the Inspector drag&drop any object here that is inside the canvas
// or the canvas itself
[SerializeField] private GameObject parentInCanvas;
[SerializeField] private Button buttonPrefab;
public void DoInstantiate()
{
var newButton = Instantiate (buttonPrefab, parentInCanvas);
//Todo Position and callback
}
}
Or if the spawner script is attached to an object inside the canvas anyway you could also spawn as child of this one directly using
var newButton = Instantiate(buttonPrefab, transform);
You can specify the transforms parent after you have created the game object.
spawnedObject.transform.parent = canvas.transform;
You have to use below code
public GameObject Prefab; // Object to Create
public Transform ParentOfObj;// Must Be inside the canvas or canvas it self
void Start()
{
GameObject g = Instantiate(Prefab) as GameObject;
g.transform.SetParent(ParentOfObj);
g.transform.localScale = Vector3.one;
}

Unity: GameObject always at center regardless of position changes

I am working on a 2D game and have created a game object using C# script as below. I also set my camera to orthogonal and have adjusted my sprite based on the width of the screen. Regardless of the position I set, the object is always at the center of the screen. How can I solve this?
using UnityEngine;
using System.Collections;
public class TestingPositions : MonoBehaviour {
GameObject hero;
Sprite heroSprite;
Vector3 heroPosition;
// Use this for initialization
void Start () {
hero = new GameObject ();
Instantiate (hero, heroPosition, Quaternion.identity);
Camera camera = GameObject.FindGameObjectWithTag ("MainCamera").GetComponent<Camera> ();
heroPosition = camera.ScreenToWorldPoint(new Vector3(Screen.width/4, Screen.height/4, camera.nearClipPlane));
heroSprite = Resources.Load <Sprite> ("Sprites/heroImage");
SpriteRenderer renderer = hero.AddComponent<SpriteRenderer>(); renderer.sprite = heroSprite;
}
}
when you use Instantiate you have to use it on
an existing model.
Instantiate means "duplicate this model" or "copy this model", or "make a new one, using this model as an example".
What you are doing, is creating a brand new empty "hero" game object - and then "instantiating" it. That is meaningless and does nothing.
What you must do whenever you want to use "Instantiate" is this:
public GameObject modelPerson;
Note that the name must be "modelSomething".
first put that in your code. LOOK at the Inspector. MAKE your actual model hero (or whatever it is)
Sit it somewhere off camera where it is not seen.
Now, drag that thing to the "modelPerson" slot in the Inspector.
If you are not familiar with the basics of using Inspector-dragging in Unity, review basic Unity tutorials https://unity3d.com/learn/tutorials/topics/scripting
Next in your code, perhaps in Start, try this
GameObject newHero = Instantiate( modelPerson );
newHero.transform.position = .. whatever you want
newHero.transform.rotation = .. whatever you want
newHero.name = "Dynamically created";
newHero.transform.parent = .. whatever you want
once you understand these basics, there is very much more to learn about Instantiate. You can ask that in separate questions. Good luck.
Your need to save the reference to your gameObject that is created with Instantiate, because Instantiate makes a copy not modifies the original.
To modify a gameobjects position after instantiation, you need to use gameobject.transform.position = newPosition; To modify it before instantiation, you would need to do the "heroPosition" line before using heroPosition in Instantiate.
So like this:
using UnityEngine;
using System.Collections;
public class TestingPositions : MonoBehaviour
{
GameObject hero;
SpriteRenderer heroSprite;
// Use this for initialization
void Start()
{
Camera camera = GameObject.FindGameObjectWithTag("MainCamera").GetComponent<Camera>();
//Save the reference to the instantiated object into a variable
//Since you are creating an object from scratch, you don't even need Instantiate, which means copy - not create.
hero = new GameObject();
//Set its position
hero.transform.position = camera.ScreenToWorldPoint(new Vector3(Screen.width / 4, Screen.height / 4, camera.nearClipPlane));
//Set its rotation
hero.transform.rotation = Quaternion.identity;
//Add sprite renderer, save the reference
heroSprite = hero.AddComponent<SpriteRenderer>();
//Assign the sprite
heroSprite.sprite = Resources.Load<Sprite>("Sprites/heroImage");
}
}

Shooting a projectile in unity always return null exception

So I'm currently working on my game project using unity3D and I came across this weird error.
I'm trying to instantiate and shoot a projectile forward. here's my Update code:
if (Input.GetButtonUp("Fire1")){
Vector3 frontDir = transform.TransformDirection(Vector3.forward * arrowShotForce);
if (chosenProj){
Rigidbody shotProj = Instantiate(chosenProj, transform.position, transform.rotation) as Rigidbody;
shotProj.AddForce(frontDir);
}
}
when I tried to play the script, it gets error at shotProj.AddForce(frontDir) saying
NullReferenceException: Object reference not set to an instance of an object
I've checked the 'chosenProj' gameobject and have assigned it with a projectile model and I still got this error. the projectile won't fly forward and I feel so dumb because I've worked with unity for a month now
any idea why?
THX b4
Your code, where you get a NullReferenceException in the last line:
Rigidbody shotProj = Instantiate(
chosenProj, transform.position, transform.rotation)
as Rigidbody;
shotProj.AddForce(frontDir);
In the last line something must be null, or otherwise you wouldn't get the exception. Since frontDir is a Vector3 value type, the only reference type that can be null is shotProj.
How could it be null? Well, when the return value of Instantiate() cannot be cast to a Rigidbody, the as Rigidbody expression will return null.
So, I conclude that your chosenProj is not a RigidBody. It is actually a GameObject that has a rigid body component on it. To get the RigidBody, use this:
GameObject shotProj = (GameObject)Instantiate(chosenProj, transform.position, transform.rotation);
shotProj.rigidbody.AddForce(frontDir);
GameObject class documentation has more info on how to get components from game objects.