Return Transform by String Parameter

Hello everyone, I have a singleton class called WorldManager. I want this class to hold some transforms. In the awake function, I create some gameobjects, and also reach some transforms by tags and store them, as a result, after the awake call has finished, I have some Transforms stored in the class. What I would like to do is, I want to reach these transforms whenever I want from another script, this should be easy since the class uses singleton. I know I can do something like this:

void Awake()
{
// storing all transforms like camera,player,light

}
public Transform GetObject(string objectName)
{
if(objectName == "Player")
return Player;
if(objectName == "Camera")
return CameraTransform;
if(objectName == "Light")
return Light;
else
return null;
}

I know this works, but I do not want to write an if statement for every object that I want it to be reached, so is there any way like this :

public Transform GetObject(string objectName)
{
return the transform which named objectName ? 
}

Thanks :slight_smile:

Yes, you would do this by using a HashMap. The built-in one in C# is Dictionary<>, which you’ll get hold of by putting “using System.Collections.Generic” in the top of your script.

It works like an array, but you index stuff by a custom property - in your case a string - instead of an int. So you’d do:

Dictionary<string, Transform> itemDict;

void Awake() {
    itemDict = new Dictionary<string, Transform>();

    itemDict["Player"] = GameObject.FindWithTag("Player").transform;
    ...
}

public Transform GetObject(string objectName)
{
    //Will cause an error if you haven't stored an item with the name objectName
    return itemDict[objectName]; 

    //If you want to be safe, do this instead:
    if(itemDict.ContainsKey(objectName))
        return itemDict[objectName];
    else {
        //handle the objectName key not existing. Like, print an error, return null. 
    }    
}

Nice and easy. If you’re interested, I could tell you why what you’re doing is wrong, and is basically something you should never, ever do. Seriously, it’s a horrible idea. But if you just want a solution, that’s it.

Use an enum and dictionary. A dictionary can’t have duplicate keys, so keep that in mind.

an example

Dictionary<ObjectTransformName, Transform> objectDic;

public Awake()
{
	objectDic = new Dictionary<ObjectTransformName, Transform>();

	objectDic.Add(ObjectTransformName.Player, GameObject.FindGameObjectByTag("Player").transform);
	objectDic.Add(ObjectTransformName.Camera, Camera.mainCamera.transform);
	// etc etc
}

public enum ObjectTransformName
{
	Player,
	Camera,
	Light,
	// others
}

public Transform GetObjectTransform(ObjectTransformName otn)
{
	// Do some checking here for null and objectDic.Count > 0 or even the key existing
	return objectDic[otn]
}