Adds infinite # of components, using GameObject.AddComponent.

The title speeks for itself, i use `GameObject.AddComponent` to add a script to a object, but i adds infinite numbers of that script, and it starts lagging and the editor stops answering. Here's the code (AI.js):

var speed = 3.0;
var rotationSpeed = 5.0;
var shootRange = 15.0;
var attackRange = 30.0;
var shootAngle = 4.0;
var dontComeCloserRange = 5.0;
var delayShootTime = 0.35;
var pickNextWaypointDistance = 2.0;
var target : Transform;
var objektnamn : GameObject;
private var lastShot = -10.0;

// Make sure there is always a character controller
@script RequireComponent (CharacterController)

function Update ()
{
   if ( Input.GetMouseButtonDown(1) )
   {
      var gunnar : RaycastHit;
      var ivar : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
      if (Physics.Raycast (ivar, gunnar, 1000.0))
      {
        Debug.Log(gunnar.collider.gameObject.name);
        objektnamn = gunnar.collider.gameObject;
      }
   }

   if (this.gameObject.name != objektnamn.name) 
   {
     gameObject.AddComponent (AI);
   }
   else if (this.gameObject.name==objektnamn.name)
   {
    //GetComponent(AI).enabled = false; 
     Destroy (GetComponent (AI));
   } 
}

It's supposed to deactivate the AI script, when the object the script is attached to, is selected (Using raycast), the objektnamn is the variable containg the name of the currently selected object. Then, when a other object is selected, i want the AI script to activate again. Whats the problem here guys? Thanks in advance!

your code is fine, but you are just missing an if statement. try this:

   if (this.gameObject.name==objektnamn)
   {
    //GetComponent(AI).enabled = false; 
     Destroy (GetComponent (AI));
   } 
   else if (this.gameObject.name!=objektnamn) 
   {
    if(!objektnamn.AI)
    {
         gameObject.AddComponent (AI);
    }
   }

The code:

    if (this.gameObject.name==objektnamn)
   {
    //GetComponent(AI).enabled = false; 
     Destroy (GetComponent (AI));
   } 
   else if(this.gameObject.name != objektnamn.name) 
   {
     gameObject.AddComponent (AI);
   }

That looks a bit weird. Where do you execute this code? in `Awake`, `Start` or `Update`? And in what script do you use this code? The AI script itself? What is "`objektnamn`" a string? or an object reference?

And finally the most important question: What do you want to achieve?

To me it looks like you do that in the AI script itself but that means that it have to be attached to an object and it adds itself to the object. The new instance you’ve just added will do the same and add another instance…

If you have new information edit your question and don't post an answer if it's not an answer to the question. You should at least include the function that contains this code snippet and what's the type of your "`objektnamn`" variable.


edit

Ok, I still can’t figure out what’s your setup in your scene. You just talk about objects that should be selected. Do they have also an AI script?

Anyways, I guess that will never come to an end. Just some hints:

  • You execute either Destroy(GetComponent(AI)) or AddComponent(AI) every frame because you used it in Update(). That means it would add infinite AI Components or will throw endless errors after the last one is deleted.
  • The AI script add itself to the gameobject so every new added instance will do the same.
  • The Raycast selection code should be there only once. Normally such code is attached to the camera. In your case if you have 3 objects in the scene with the AI script attached all 3 will execute the raycast.
  • Your condition `else if(this.gameObject.name == objektnamn.name)` is useless since it's just the opposite of `(this.gameObject.name != objektnamn.name)`. The `else` would be enough.
  • If you want to activate/deactivate a script you don't need to destroy the script. You just can deactivate it via `enable`.

Here's an example script that should be attached to the camera which do the selection stuff.

(Note: that’s a seperate script. This script can only select objects that have an AI script attached)

var curentSelection : AI = null;

function Update ()
{
    if ( Input.GetMouseButtonDown(1) )
    {
        var hit : RaycastHit;
        var ray : Ray = Camera.main.ScreenPointToRay (Input.mousePosition);
        if (Physics.Raycast (ray, hit, 1000.0))
        {
            // Try to get the AI script of the new selection
            var tempAI : AI = hit.collider.gameObject.GetComponent.<AI>();

            // If we selected a new one, deactivate the script.
            if (tempAI != null)
            {
                // first reactivate the last selected object if there is one
                if (curentSelection != null)
                    curentSelection.enabled = true;

                // make the new selected one the current selected.
                curentSelection = tempAI;
                // deactivate the script
                curentSelection.enabled = false;
            }
        }
    }
}

if (this.gameObject.name!=objektnamn) 
{
 if(!objektnamn.AI)
 {
  gameObject.AddComponent (AI);
 }
}