- Home /
Name-fetching script working but with error.
I'm attempting to make a script that controls all the detection of friend and foe for everyone.
I got the code to work as far as adding the object to a list when it enters detection radius and removing it when it leaves. However I will have many variables to pass back and forth, checking the threat level of each enemy etc so the AI can prioritize threats. Because of this I attempted to bring through the names of the characters and add them to a seperate 'name' list.
var inRangeList : List.< GameObject > = new List.< GameObject >();
var visibleCloseAgents = new ArrayList();
var agentNameScript : nameGenerator;
var agentName : String;
var agentNames : List.<String> = new List.<String>();
var target : GameObject;
function OnTriggerEnter(other : Collider)
{
//Detect character layer agents that enter radius.
//store object that entered
target = other.gameObject;
//store the object's name generator script so we can take the name
agentNameScript = other.GetComponent("nameGenerator");
//find the name from the name generator script
agentName = agentNameScript.characterName;
//add the name to the name list
agentNames.Add(agentName);
//add the gameObject to the list for storing the game objects
inRangeList.Add(target);
//reset the target and name vars after adding them to the lists so that we can
//add new target and name when a new object enters
target = null;
agentName = null;
}
function OnTriggerExit(other : Collider)
{
Debug.Log("gone");
agentNames.Remove(agentName);
inRangeList.Remove(other.gameObject);
}
The code does in fact pick up the name of the new enemy and stores it as hoped but it fails to remove it from the list when it leaves the radius. Which is annoying as more or less the same code works for the gameObject.
I also get this error which no doubt is a clue as to what's gone wrong but I don't understand. As far as I can see (I'm wrong, I know) the variable does (or did for a moment) exist otherwise I wouldn't have been able to bring through the names.
NullReferenceException: Object reference not set to an instance of an object detectionScript.OnTriggerEnter (UnityEngine.Collider other) (at Assets/Scripts/detectionScript.js:38)
which is this part:
//find the name from the name generator script
agentName = agentNameScript.characterName;
I hope someone could shed some light on this problem as I feel close to breaking the back of this vital part of my game. Thank you.
I am still new to unity, so I might be wrong. But the problem could be that gameObjects get passed by reference and strings by value, meaning when you set "agentName" to null, the copy in "agentNames" is still intact. using agentNames.remove(agentName);
should work. I would also advice to do the same for the inRange list, as it should still hold a gameObject, at the point where the agentObject was, it just "null" now.
Thanks for the response. I actually already used that code in the onExit lol! Now, I just added my onTriggerExit code so you can see it. When the object leaves the trigger area I want it to remove all traces of itself from both lists. As it stands the actual target does just that and I'm happy with it. However the names do not. They just stay there.
I know you suggested putting that removal code (agentNames.remove(agentName)) in the onEnter function BUT that would mean it would detect the object and name, add them to lists, then remove them from the lists straight after. But all I want to do in the onEnter is detect the object, store it in a var so we can add that var to a list, THEN clear the var so we can pick up the next thing to put into the list but leave the list entry intact.
Only when the object leaves the trigger do I want it to be obliterated from the lists :)
Just thought I'd mention this in detail in case either of us have misinterpreted the other!
As I've said in response to Spectre it's all working as intended apart from the name removal and the persistent null reference error! Confused!
Ah, the removal code obviously belongs into the onExit routine. One question, if you print the agentName you use in onExit to delete the name, what does it say? If it is an empty string, then that is the problem for the faulty removal. $$anonymous$$aybe
agentNames.Remove(other.GetComponent<nameGenerator>().characterName);
would work then. Using the typseafe GetComponent miiiight also solve the problem you have with the wrong reference, but that would probably be hoping for too much.
I managed to get rid of the null reference by removing the agentName = null. Presumably that was clearing the variable before it had a chance to be removed. It seems to work now but I still have a few things to iron out (at the moment it struggles with multiple agents: It detects them but on exit it only removes one of them! But that's a question for another time!)
Thanks again for your time.
Have you tried putting the line in my last comment ins$$anonymous$$d of
agentNames.Remove(agentName);
in OnTriggerExit? It would solve the problem with multiple enemies leaving I think.
Answer by spectre1989 · Aug 11, 2013 at 01:40 PM
It looks like agentNameScript is null, you can double check this by putting Debug.Log( agentNameScript ) after the call to other.GetComponent( "nameGenerator" ).
If you're sure nameGenerator is the correct spelling, then it seems that the collider doesn't have that script attached to it. This can be the case if for example, you have a GameObject with a nameGenerator script attached to it, and then a few child GameObjects which have the colliders on them. If this is the case, then you can try other.transform.root.GetComponent( "nameGenerator" );
Yes, this is the case. I have the 'human' with a child consisting of a cylinder + collider. They have no scripts. I will try out your suggestion!
I thought this had solved my problem but sadly I just tested it again and it's back.
As it stands the code picks up the game object and adds it to the objects list fine, takes the name and adds it to the name list fine. It still gives the same error though (despite it working).
Perhaps a clue could be the fact that the name list doesn't delete the agentName when it leaves? The object is removed from the object list but the name stays on the name list and then adds again every time it comes into range. So you have duplicates of the name on the list.
Have you tried putting in a Debug.Log statement to see what is returned by GetComponent?
Apologies, I got so caught up in the last part of your advice that I forgot about the first bit! I just did it and it returned Human (nameGenerator) which sounds right to me...