- Home /
Use enum value as a index variable of a list
I'm facing some problems when try to get the enum value and use it as the index of a list. Really couldn't think of other reasons why my script doesn't work so I'm guessing there's some problems when using enum values. here's my code I have several gameobjects with the same script. In the script there is a public enum which can be set in the inspector of the gameobject
public myTeam Team;
public enum myTeam
{
Team_A7 = 7, Team_A8 = 8, Team_A9 = 9. //etc, it goes long
}
then I have a List of List of string to store some relationships between teams
private List<List<string>> N = new List<List<string>>();
In the start function, I add a tag which is same as the team name to the gameobject (up to here I am sure it is working), and put in relationships in the List of List
void Start()
{
gameObject.tag = Team.ToString();
//login relations. The first Index correspond to the enum value in myTeam, the first element of that sublist is its own team.
N.Insert(7,new List<string> { "Team_A7", "Team_A8" }); //my intention here is that in sublist7, I store the relations of Team_A7: here N[7][0] is its own team string, N[7][1] is "Team_A8" , meaning that Team_A8 is in relationship with it
N.Insert(8,new List<string> { "Team_A8", "Team_A7", "Team_A9" });
N.Insert(9,new List<string> { "Team_A9", "Team_A8" });
}
ok so now everything is prepared, what I want to do in the update function is, check if the gameobject encounters someone that has relation with itself or is in the same team with itself
void Update()
{
Rigidbody rigidBody = gameObject.GetComponent(typeof(Rigidbody)) as Rigidbody;
Vector3 position = rigidBody.position;
Collider[] sight = Physics.OverlapSphere(position, 0.01f);
float far = 0.00000f;
GameObject furtherest = null;
//check if they have relaions, and find the futtherest one
foreach (Collider unit in sight)
{
if (N[(int)Team].Contains(unit.gameObject.tag))
{
Vector3 diff = unit.transform.position - position;
float curDistance = diff.sqrMagnitude;
if (curDistance > far)
{
furtherest = unit.gameObject;
far = curDistance;
}
}
//foreach (string matetag in N[(int)Team])
//{
// if (unit.gameObject.CompareTag(matetag))
// {
// Vector3 diff = unit.transform.position - position;
// float curDistance = diff.sqrMagnitude;
// if (curDistance > far)
// {
// furtherest = unit.gameObject;
// far = curDistance;
// }
// }
//}
}
//then do something to the with the furtherest one
}
Sorry for the bad formatting. I've tried use list.contain, or use foreach loop to comparetag, also I've tried to directly compare the enum string of the other object to to the list component but none of those method works. So the only problem I can guess is that theres something wrong when building the N list or there is something wrong referring to it with N[(int)Team]. Can someone see where's my problem?
Answer by Anox · Mar 15 at 12:41 PM
I don't know man but this just seems awkward. Cant you use a Dictionary ?
Or even better: create a Class "Team" that has a teamname and a List of relations. You could then instatiate each team and set the relation in your team class like:
public class Team {
public string teamName;
public List<Team> teamRelations = new List<Team>();
public void AddTeamToRelations(Team team) {
teamRelations.Add(team)
}
public bool HasRelationToTeam(string otherTeamName) {
foreach(Team team in teamRelations) {
if(team.teamName == otherTeamName) return true;
}
return false;
}
}
Then create the Teams like this:
Team team_A7 = new Team("Team_A7");
Team team_A8 = new Team("Team_A8");
Team team_A9 = new Team("Team_A9");
team_A7.AddTeamToRelations(team_A8);
team_A7.AddTeamToRelations(team_A9);
team_A8.AddTeamToRelations(team_A7);
team_A8.AddTeamToRelations(team_A9);
(and so on...)
So now instead of N[(int)Team] you could write:
if( myTeam.HasRelationToTeam( unit.gameObject.tag ) ) {
...
}
If you really want to go the List> way i suggest you Log some stuff before you try to access the list:
Debug.Log("N list size:"+N.count());
Debug.Log("(int)team:"+(int)Team);
Debug.Log("N[(int)Team]:"+N[(int)Team]);
This should give you a better understanding of where the problem could occur.
Thank you soo much for your reply! I am trying to learn the second method with Class now, can I ask some beginners question? In this way do I still key the public enum like before? I guess the "myTeam" in your may refers to the Enum, but then I don't know how myTeam.HasRelationToTeam can work bc its a Enum. If you mean not using the enum anymore, could you elaborate more on how to choose team from inspector and then use the string of it later on? Thank you again! (Also bc I'm developing for Oculus Quest on MacBook, I can't use play mode and can only run it in VR so cannot print in the console;( maybe its just I don't know how)
You can keep using the Enums instead of using the string teamName.
Then I would suggest you pass the enum to the Team class in the constructor: Team team_A7 = new Team(myTeam.Team_A7);
Take the Enum in the constructor of Team:
public class Team {
public myTeam teamEnum;
public List<Team> teamRelations = new List<Team>();
public Team(myTeam teamEnum) {
this.teamEnum = teamEnum;
}
}
Then you would still have to compare the enum to the collision tag which is a string. This is done in the function "HasRelationToTeam".
public bool HasRelationToTeam(string otherTeamName) {
foreach(Team team in teamRelations) {
if(team.teamEnum.ToString() == otherTeamName) return true;
}
return false;
}
Notice the ".teamEnum.ToString() "
That should do the trick. Take my code with a grain of salt, I don't have an IDE open so consider everything pseudocode ;)
Oh, and you should really get some kind of game preview mode with console running. Debugging stuff without the console is always going to be a nightmare ;)
Thank you!! Yea so true, I'll try make a simple game to run on computer just to test the algorithm ;)