I thought I had was making progress in my understanding of Unity Script, but apparently I was wrong in that assumption.
I am attempting to “spawn”/instance game objects, orient, and scale game objects after clicking on another object in the scene. At the same point, clicking on the same object again will de-instance/remove the object from the scene.
How would I go about doing this? What scripting references should I look at so I can get a pointed in the right direction ?
To spawn new objects use Instantiate (Unity - Scripting API: Object.Instantiate). To destroy objects use Destroy (Unity - Scripting API: Object.Destroy). To react to mouse clicks, use the OnMouseDown function of a MonoBehaviour (Unity - Scripting API: MonoBehaviour.OnMouseDown()).
That should get you started.
I get this error after Clicking on an object in the game. I have no idea what this error means. Any help?
NullReferenceException: Object reference not set to an instance of an object
(wrapper stelemref) object:stelemref (object,intptr,object)
menuMouseActions.OnMouseDown () (at Assets/scripts/menuMouseActions.js:106)
UnityEngine.SendMouseEvents:smile:oSendMouseEvents(Int32, Int32)
The error appears on line 106:
instanceArray[arrayIndex] = Instantiate(linkObject, transform.position,transform.rotation);
At this point in the script, arrayIndex is 0, and I have just created my first object via the Instantiate command.
Here is the OnMouseDown() function in its entirety:
function OnMouseDown()
{
var instanceArray : GameObject[];
var arrayIndex : int = 0;
var tObject : Transform;
var child : int ;
var parentPos : Vector3 = gameObject.transform.position;
if(selected == false)
selected = true;
else if(selected == true)
{
selected = false;
iconQuad.GetComponent.<Renderer>().material.mainTexture = offImage;
GetComponent.<Renderer>().material.color = offColor;
}
GetComponent.<Renderer>().material.color = clickColor;
iconQuad.GetComponent.<Renderer>().material.mainTexture = onClickImage;
for each(Transform in transform)
{
tObject = Transform;
if(Transform != iconQuad.transform)
{
if(selected == true)
{
tObject.gameObject.SetActive(true);
}
else if(selected == false)
{
tObject.gameObject.SetActive(false);
}
// Get Distance to child object
nodeDistance = Vector3.Distance(tObject.position, transform.position);
print(tObject + " distance : " + nodeDistance);
// Instantiate linkObject; object length (z) is 12
instanceArray[arrayIndex] = Instantiate(linkObject, transform.position,transform.rotation);
// Rotate to face child
print(tObject + ".position is : " + tObject.position);
instanceArray[arrayIndex].transform.LookAt(tObject.position);
arrayIndex++;
}
}
}
I added a bit of error check-point code to see where the error as being thrown. I added the code on line 45, but the script errors out before it hits that. Guess this means I’m screwing something up with the line above it.
Is there a better/smarter way to store a list of instantiated objects so I can modify and later destroy them?
instanceArray is null, you can’t access an index of a null array! I’m unsure how to actually declare an array in javascript but I’m guessing that’s your problem. In C# you would say,
instanceArray = new GameObject[10];…which initializes with a size of 10 that array.
For you, if you don’t know how many you will need, I would use the Array class.
http://docs.unity3d.com/ScriptReference/Array.html
Updated code:
#pragma strict
import System.IO;
var onHoverImage : Texture;
var onClickImage : Texture;
var iconQuad : GameObject;
var hoverColor : Color;
var clickColor : Color;
var linkObject : GameObject;
private var parentColor;
private var pTransform : Transform;
private var childCount: int;
private var offColor : Color;
private var offImage : Texture;
private var selected : boolean;
private var objCollider : Collider;
private var numChild : int;
private var segLength : float = 12.00;
private var nodeDistance : float;
function Start ()
{
offImage = iconQuad.GetComponent.<Renderer>().material.mainTexture;
selected = false;
offColor = GetComponent.<Renderer>().material.color;
}
function OnMouseEnter()
{
if(selected == false)
{
GetComponent.<Renderer>().material.color = hoverColor;
iconQuad.GetComponent.<Renderer>().material.mainTexture = onHoverImage;
}
}
function OnMouseExit()
{
if(selected == false)
{
GetComponent.<Renderer>().material.color = offColor;
iconQuad.GetComponent.<Renderer>().material.mainTexture = offImage;
}
}
function OnMouseDown()
{
var instanceArray = new Array ();
var arrayIndex : int = 0;
var tObject : Transform;
var child : int ;
var parentPos : Vector3 = gameObject.transform.position;
if(selected == false)
selected = true;
else if(selected == true)
{
selected = false;
iconQuad.GetComponent.<Renderer>().material.mainTexture = offImage;
GetComponent.<Renderer>().material.color = offColor;
}
GetComponent.<Renderer>().material.color = clickColor;
iconQuad.GetComponent.<Renderer>().material.mainTexture = onClickImage;
for each(Transform in transform)
{
tObject = Transform;
if(Transform != iconQuad.transform)
{
if(selected == true)
{
tObject.gameObject.SetActive(true);
// Get Distance to child object
nodeDistance = Vector3.Distance(tObject.position, transform.position);
instanceArray[arrayIndex] = Instantiate(linkObject, transform.position,transform.rotation);
// Rotate to face child
var tempObj = new GameObject();
tempObj = instanceArray[arrayIndex];
//tempObj.transform.localScale.z = -1;
//tempObj.transform.localScale.x = 0.1;
//tempObj.transform.localScale.y = 0.1;
//tempObj.transform.localScale.z = 0.1;
tempObj.transform.LookAt(tObject.transform.position, Vector3(0,1,0));
arrayIndex++;
}
else if(selected == false)
{
for(var obj : GameObject in instanceArray)
{
Destroy(obj);
print(obj + " destroyed!");
}
tObject.gameObject.SetActive(false);
}
}
}
}
So all the objects are instanced, and now I can manipulate them. The issue I’m running into now is destroying them when I click on the parent object again. For some reason it fails to destroy the instances when “deselecting” the object.