Target next instant

Hey all

Perhaps someone can suggest a way to target an instantiated object.

I have a button, that when it’s pressed, instantiates a prefab of a small cube which emits a stream of particles. On this prefab is included a small script which allows me to direct the particle stream towards another object’s transform, by drag and dropping it into the inspector…

What I would like to do is for that transform to be the next instance of the cube, and the transform for that instance to be the following instance, etc…

In this way I can create a particle stream from one cube to the next, to the next.

But how do I pass the instantiated transform info to the previously instantiated one???

Any ideas?

Thanks

Two possibilities :

  • You simply store the last created object created with the button in a variable, and you give its value to the next created object, before storing the new object in the variable. You repeat this to your heart’s content.

Pros : the easiest.
Cons : if you decide to REMOVE some objets while playing, it will cause troubles.

  • You make an array which stores every object created, starting from the oldest to the youngest. Each object will find his position in the array, and look at the next position in the array.

Pros : even if some gameObjets were to be destroyed, it wouldn’t harm the game.
Cons : more complex.

If you decide to go for the second option (which is the safest in my opinion), here is some code I wrote quickly for you (syntax may be wrong but having the general idea is already good) :

Component StreamManager

var emittersList : Array;

function addEmitter (emitterToAdd : GameObject) {
	emittersList.Push (emitterToAdd);
}

Component StreamObject (your cubes or whatever form it might have)

private var streamTarget : GameObject;
private var listToCheck : Array = GameObject.Find ("StreamManager").GetComponent (StreamManager).emittersList;

function FindTarget () {
	// Find the StreamObject in the StreamManager list and return his position
	for (i = 0; i < listToCheck.length; i++) {
		// Should not return a value if his index is the last in the list (lenght -1)
		if (listToCheck [i] == gameObject  i != listToCheck.length - 1) {
			// Return the next value then
			streamTarget = listToCheck [i+1];
			break;
		}
	}
}

Hi AkilaeTribe

Thank you. I tried your code but can’t really make heads or tails of it, probably because of the structure of my project.

My instantiation is working fine now. I am thinking that maybe renaming each cube to have a unique suffix and then making the previous cube target the next would be quite simple.

But renaming prefabs seems to be very difficult. I have searched the forums and tried out a few things, but none seem to work for me.

The code below creates 10 cubes with sequential numbers, but it does them all at once. I want to create one cube at a time, with each subsequent cube getting a sequential number.

Any thoughts?

var cube : GameObject;
function Update () 
{ 
   if (Input.GetKey ("m")  Input.GetButtonDown ("Fire1")) 
   { 
      var ray = Camera.main.ScreenPointToRay (Input.mousePosition);
      var hit : RaycastHit; 
      if (Physics.Raycast (ray, hit)) 
       { 
       if(hit.collider.gameObject.name.Contains("colider")) {
	   for (i = 0; i < 10; i++) { 
       var cube = Instantiate(cuben, hit.point, transform.rotation); 
       cube.name = "cube" + i.ToString(); 
                } 
   			} 
		}
  	}
}

Do you really need to use toString ? What’s wrong with the code ? It doesn’t work ? What’s the error message ?

No error messages.

I’m guessing I just don’t know how to use your snippets. Or the structure of my projects and other scripts are interfering with the way they work.

I have now managed to create sequential boxes, all I need to do is for the first box to target the second, second to target third, third to fourth etc…

I need to check the current objects name: cube1 and then make the target cube1+1 = cube2. Not sure how to do that though.

var receiver: Transform;
var i = 1;
function Update () {
   receiver = GameObject.Find("name"+i).transform;
   transform.LookAt(receiver.transform); 
   var distance = Vector3.Distance(transform.position, receiver.transform.position); 
   var timeToTarget = distance/particleEmitter.localVelocity.z;
   particleEmitter.minEnergy = timeToTarget;
   particleEmitter.maxEnergy = timeToTarget; 
   particleEmitter.rndVelocity.x = receiver.transform.localScale.x/timeToTarget; 
   particleEmitter.rndVelocity.y = receiver.transform.localScale.y/timeToTarget;
}

This is probably the most roundabout, longwinded method of doing this… but after a few hours, this the only way that I can make it work. So for anyone who is interested, or would like to suggest a more concise method, here it is…

var receiver: Transform;
var myname : String;
var number : String;
var mynumber : int;

function Update () { 
//The game objects name are sequential as they get instantiated.
   myname = this.gameObject.name;
//This strips the name part, leaving us only with the sequential number.
   number = myname.Replace("name","");
//This changes the number string into a number int and adds a one.
   mynumber = parseInt(number) +1;
//This finds the target named the same as this go +1
   receiver = GameObject.Find("name" + mynumber).transform;
//This makes the go loo towards it's target and emit particles etc... Hooray!
   transform.LookAt(receiver.transform); 
   var distance = Vector3.Distance(transform.position, receiver.transform.position); 
   var timeToTarget = distance/particleEmitter.localVelocity.z;
   particleEmitter.minEnergy = timeToTarget;
   particleEmitter.maxEnergy = timeToTarget; 
   particleEmitter.rndVelocity.x = receiver.transform.localScale.x/timeToTarget; 
   particleEmitter.rndVelocity.y = receiver.transform.localScale.y/timeToTarget;
}

Trying to adapt this code now, so when I hit a key the last instance stops emitting and I can start a new chain.

Mathematically it seems quite easy. Find the largest number and stop that instance emitting. The rest of the code would be the same. But as soon as I create the next instance, the previous one wants to target it and starts emitting again. Would someone have any advice?

var receiver: Transform;
var myname : String;
var number : String;
var mynumber : int;

function Update () { 
   myname = this.gameObject.name;
   number = myname.Replace("name","");
   mynumber = parseInt(number) +1;

   receiver = GameObject.Find("name" + mynumber).transform;
   transform.LookAt(receiver.transform); 
   var distance = Vector3.Distance(transform.position, receiver.transform.position); 
   var timeToTarget = distance/particleEmitter.localVelocity.z;
   particleEmitter.minEnergy = timeToTarget;
   particleEmitter.maxEnergy = timeToTarget; 
   particleEmitter.rndVelocity.x = receiver.transform.localScale.x/timeToTarget; 
   particleEmitter.rndVelocity.y = receiver.transform.localScale.y/timeToTarget;
   
   if (Input.GetKey("s")) {
   	receiver.particleEmitter.maxEnergy = 0;
   	receiver.particleEmitter.minEnergy = 0;
   }
}