The question is answered by comment, right answer was accepted
Having troubles using List
Hello everyone, I am learning Unity, been trying to setup an RTS game.
I am using a static class that contains global functions for the units.
One of the function is using an overlapsphere to get objects, works well, putting everything in a collider[] as expected. Then I retrieve thoses values and for each of them I check if entities' player IDs are different, if they are, I wish to add them to a List of transform items, in order to check for the distance, as you may have seen hundreds of time ;)...
public static GameObject FindTargets( GameObject castingUnit, Vector3 casterPos, float range){
scanResult = ScanForGameObjects (casterPos, range/*, AICore.neutralLayer*/);
BestTarget = null;
if (scanResult.Length != 0) {
Debug.Log ( "detected unit number " + scanResult.Length);
Debug.Log ("Unit transform list " + unitTransform);
foreach (Collider pointedCollider in scanResult) {
if (pointedCollider.gameObject != null) {
opponentPlayer = pointedCollider.gameObject.transform.root.GetComponent<Player> ().playerInt;
unitTransform = new List<Transform> ();
Debug.Log ("Collider is property of player " + opponentPlayer + " Caster is property of player " + actionPlayer);
if (actionPlayer != opponentPlayer) {
Debug.Log (pointedCollider.name + " " + pointedCollider.gameObject);
Debug.Log ("Get component " + pointedCollider.gameObject.GetComponent<Transform> ());
//unitTransform.Add (pointedCollider.gameObject.GetComponent<Transform>());
//tempList.Add (pointedCollider.gameObject.GetComponent<Transform> ());
unitTransform.Add ( pointedCollider.gameObject.GetComponent<Transform> ());
}
unitTransform = tempList;
Debug.Log (unitTransform);
}
}
Debug.Log ("Total number of valid detected entities was " + scanResult.Length);
Debug.Log ("Number of possible target is : " + unitTransform.Count);
minDist = Mathf.Infinity;
foreach (Transform T in unitTransform) {
Debug.Log (T);
if ((T.position - casterPos).magnitude < minDist) {
BestTarget = T;
}
}
return BestTarget.gameObject;
}
Debug.Log("Nothing to shoot :( ");
return null;
}
Sorry if the code is not really clean, I have been searching for solutions on the forum, googled several different things to get it working... I tried much things that people suggested to others, still not able to get what is wrong with this script. I get error :
NullReferenceException: Object reference not set to an instance of an object
AIDecisions.FindTargets (UnityEngine.GameObject castingUnit, Vector3 casterPos, Single range) (at Assets/AIDecisions.cs:29)
Turret.AcquireTarget () (at Assets/Turret.cs:115)
I have logged values entering the function, they all are not null, the list is not null : System.Collections.Generic.List'1[UnityEngine.Transform]
but still no progress.
I just pasted the code like it is right now, so sorry if it is a mess, I am starting to get lost with every modification I tried to make...
initializing the list in start function
Writing " new " List of transform items on variable declaration",
Using a temporary list to add my items, and then making the main list getting values from temp list
and so on, i don't even remember everything people wrote on forums/web
Sorry if this precise problem was already mentionned anywhere. Didn't find a proper explanation to my problem for 4 hours of search. I can't debug more because it get stuck at the list...
I know this is most likely a stupid like beginner error, need help figuring out :/ To whoever can help me, I can send you a digital cookie :DD
EDIT : I added some more debugs, I was able to find that in some case, there was no player component on the root object, I think this is related to the Overlap, which I am unable to use the masklayer for now, But it seems the error is happening when it is validated, so it must be in the scope.
Here is the full code, with more debug steps, kind of cleaned it a bit.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AI;
public static class AIDecisions {
public static Collider[] scanResult;
public static List<Transform> unitTransform = new List<Transform>();
private static float minDist;
private static float Dist;
private static Transform BestTarget;
private static int actionPlayer;
private static int opponentPlayer;
public static GameObject FindTargets( GameObject castingUnit, Vector3 casterPos, float range){
actionPlayer = castingUnit.transform.root.GetComponentInParent<Player> ().playerInt;
scanResult = ScanForGameObjects (casterPos, range);
BestTarget = null;
if (scanResult.Length != 0) {
foreach (Collider pointedCollider in scanResult) {
if (pointedCollider.gameObject != null) {
if (unitTransform != null) {
if (pointedCollider.gameObject.transform.root.GetComponent<Player> () != null) {
opponentPlayer = pointedCollider.gameObject.transform.root.GetComponent<Player> ().playerInt;
unitTransform = new List<Transform> ();
if (actionPlayer != opponentPlayer) {
unitTransform.Add (pointedCollider.gameObject.GetComponent<Transform> ());
} else {
Debug.Log ("Collider of GameObject " + pointedCollider.gameObject.name + "owner is the same as Unit owner");
}
} else {
Debug.Log ("No player component was found on root of collider of object : " + pointedCollider.gameObject.name);
}
}
else {
Debug.Log ("Unit transform list not found");
}
}
else {
Debug.Log ("No collider was found in scanResult");
}
}
Debug.Log ("Total number of valid detected entities was " + scanResult.Length);
Debug.Log ("Number of possible target is : " + unitTransform.Count);
minDist = Mathf.Infinity;
foreach (Transform T in unitTransform) {
Debug.Log (T);
if ((T.position - casterPos).magnitude < minDist) {
BestTarget = T;
}
}
return BestTarget.gameObject;
}
Debug.Log("Nothing to shoot :( ");
return null;
}
public static Collider[] ScanForGameObjects(Vector3 center, float range){
Collider[] hitColliders = Physics.OverlapSphere (center, range);
foreach (Collider overlap in hitColliders) {
}
return hitColliders;
}
}
Answer by Pengocat · Dec 22, 2016 at 05:22 PM
I guess one of the problems is that you are creating a new list within the foreach loop.
unitTransform = new List<Transform>();
Didn't you already make a list in a Start() method?
You are right it is a bit of a mess and you didn't include the "ScanForGameObjects" method which could be the problem.
I did already made a list in the start method,
but I couldnt make it work, so I removed it and tried desperately to put it where it was at the end, I am going to remove it from the loop, retrying to make it from start() method.
PS : I edited the post, added more details. for the overlap function, I used the loop inside of it, just to check if there was something happening, removed what was inside, but forgot to remove the loop itself :)
PS 2 : Thanks man, as i thought it was really stupid mistake, I don't get why the list wasn't working at this time, but I removed the list from the loop and now it is working ! thanks very much for helping me see clear !
Follow this Question
Related Questions
Getting "object reference not set" error when creating a list dictionary. 1 Answer
NullReferenceException: Object reference not set to an instance of an object 0 Answers
NullReferenceException: Object reference not set to an instance of an object error ? 1 Answer
Null reference exception in an if statement that checks for it. 1 Answer