script breaking prefab

So I’m trying to work on an instantiate script that instantiates an object, located at the position of another object and parented to that other object

for testing purposes I’ve just been using a sphere as my test object, so I created the sphere and made a prefab from it, then set the prefab as the object ot be instantiated

the first time I press play, it does seem to be instantiating the prefab, though off screen somewhere, and not parented, so that part isn’t working

also when I end the game my prefab is now broken, and Unity is telling me that the object I have set to instantiate is null

??? not sure what that means, here’s what I’ve got, any help would be much appreciated.

var ideaSphere : GameObject;
var ideaParent : GameObject;

function Start (){
	
	animation.Stop();
	
	   
 }

function Update () {

	
	// triggers animation
	if (Input.GetButtonDown ("Fire2")){
		animation.Play("ideaGrab", PlayMode.StopAll);
		
		ideaSphere.transform.parent = ideaParent.transform;
		Instantiate (ideaSphere);
		
		animation.PlayQueued("reach", QueueMode.CompleteOthers, PlayMode.StopAll);
		
//		BroadcastMessage ("ReachFinished");
	}
}
ideaSphere.transform.parent = ideaParent.transform;
Instantiate (ideaSphere);

What you are doing is setting the parent of you ideaSphere prefab to the ideaParent (thus breaking the connection) and then instantiating a copy of the sphere. What you want to do is instantiating a copy of the sphere and then setting that spheres parent to the ideaParent

var newSphere = Instantiate(ideaParent, ideaParent.transform.position, ideaParent.transform.rotation);
newSphere.transform.parent = ideaParent.transform;

Thanks, that was really helpful, the sphere is instantiating properly now.

So now I’m trying to get fine tune the order in which things happen, only the BroadcastMessage command doesn’t seem to be happening in order. It seems to be happening immediately when the script is triggered. All the other commands, in the “if” statement seem to be playing through sequentially, is this simply because they’re all animations, and I need to do something specific to set the order within the statement?

Thanks

var ideaSphere : GameObject;
var ideaParent : GameObject;

function Start (){
	
	animation.Stop();
	
	   
 }

function Update () {

	
	// triggers animation
	if (Input.GetButtonDown ("Fire2")){
		
		animation.Play("ideaGrab1");
		
		// creates the sphere in the middle of the reach
		var newSphere = Instantiate(ideaSphere, ideaParent.transform.position, ideaParent.transform.rotation);
		newSphere.transform.parent = ideaParent.transform; 
		
		animation.CrossFadeQueued("ideaGrab2");
		
		// begins to place sphere, with sphere still parented to hand
		animation.CrossFadeQueued("reach1");
		
		// triggers sphere to leave parent, when half-way through reach
		BroadcastMessage ("ReachFinished");
		
		// finishes reach
		animation.PlayQueued("reach2");

	}
				
		
}

Your ‘problem’ is that all the statements inside the if are execute in the same frame. This is why the Broadcast happens immediately. The reason the animation works is that the play animation queued methods tell the animation component to play the animation in the specified sequence and it then handles this of it’s own. In summary: you block of code is execute in a single frame.
What you want to do is probably use a coroutine instead. They are brilliant for ordering sequences of stuff you want to happen. E.g.

var ideaSphere : GameObject;
var ideaParent : GameObject;


function Start () {   
   animation.Stop();      
}

function Update () {
	// triggers animation
	if (Input.GetButtonDown ("Fire2")){
		StartCoroutine("DoSpheryStuff");
	}
}

function DoSpheryStuff() {
	animation.Play("ideaGrab1");
	yield WaitForSeconds(animation["idleGrab1"].length);
		
	// creates the sphere in the middle of the reach
	var newSphere = Instantiate(ideaSphere, ideaParent.transform.position, ideaParent.transform.rotation);
	newSphere.transform.parent = ideaParent.transform;
	
	animation.CrossFade("ideaGrab2");
	yield WaitForSeconds(animation["idleGrab2"].length); 
	
	// begins to place sphere, with sphere still parented to hand
	animation.CrossFade("reach1");
	yield WaitForSeconds(animation["reach1"].length); 
	
	// triggers sphere to leave parent, when half-way through reach
	BroadcastMessage ("ReachFinished");
	
	// finishes reach
	animation.Play("reach2");
}

This is, however, not the only way you can do this. You can also use the Invoke command to invoke BroadcastMessage at the right time, but personally I prefer the first method.

var ideaSphere : GameObject;
var ideaParent : GameObject;

function Start () {   
   animation.Stop();      
}

function Update () {
	   
	// triggers animation
	if (Input.GetButtonDown ("Fire2")){
	
		animation.Play("ideaGrab1");
		
		// creates the sphere in the middle of the reach
		var newSphere = Instantiate(ideaSphere, ideaParent.transform.position, ideaParent.transform.rotation);
		newSphere.transform.parent = ideaParent.transform;
		
		animation.CrossFadeQueued("ideaGrab2");
		
		// begins to place sphere, with sphere still parented to hand
		animation.CrossFadeQueued("reach1");
		
		//Compute when the message should be broadcasted
		var timeToInvoke = animation["ideaGrab1"].length + animation["ideaGrab2"].length + animation["reach1"].length;
		
		//Invoke SendReachFinished in timeToInvoke
		Invoke("SendReachFinished", timeToInvoke);
		
		// finishes reach
		animation.PlayQueued("reach2");
	}
}

function SendReachFinished() {
	// triggers sphere to leave parent, when half-way through reach
	BroadcastMessage("ReachFinished");
}

ahh ok, that’s good to know

I’m still kinda learning the basic concepts of scripting, as you probably noticed, so that explanation really helps.

This may be a really basic question, but what is the difference between a Coroutine and a function?

for instance the BroadcastMessage command is calling a function on the sphere, which causes it to leave it’s parent, is it just a different name for basically the same thing?

A coroutine is simply a function capable of stopping it’s execution mid-function so to speak and resume from that position at a later time.
Specifically it returns an IEnumerator which it uses to keep track of where the execution is and so forth (At least this is how C# does it, I assume it’s the same in JS).
In summery: All Coroutines are functions, but a function is not necessarily a Coroutine.

Disclaimer: I have never actually used coroutines in JS (I prefer to write C#) so some of this may or may not be wrong as I’m just inferring from how it is in C#.

that makes sense, thanks