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#.