Defining an int name from a string?

So here’s what I want to do. I have a game object with this code on it. I want to be able to define an integer name from the value of a string. I think the comments I put in the code will make what I want to do clearer.

Is this possible and how would I go about doing it?

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerSpawnController : MonoBehaviour
{
    GameObject player;
    [SerializeField] GameObject gameManager;
    [SerializeField] int spawnLocationInt;
    [SerializeField] string myIntString; // I want to use this strings input from the inspector to define the name of myStringInt


    void Start() 
    {
        gameManager.GetComponent<GameManagerScript>();
        int myStringInt = spawnLocationInt; // this is the int that I want to name from the inspector that will then use it's value to set the spawnLocationInt
    }
    void Update() 
    {
        Debug.Log("spawn Location Int = " + spawnLocationInt);
    }
    
    private void OnTriggerEnter(Collider other) {
        if (other.gameObject.tag == "Player")
        {
            GameManagerScript.simpleOverSpawnLocationInt = spawnLocationInt;
            Debug.Log("I touched the player and I liked it");
        }
    }
}

Hi Joshua,

Do you have an example? TryParse could be what you are looking for. For further information, please see the official C# API.

1 Like

I think I wasn’t clear. I do not want to get a number value from the string. I want to dynamically name the integer from the strings value.

I think the short answer is no. C# is a compiled language similar to Java and C as opposed to an interpreted language like Javascript. Therefore the variables need to be defined before the application starts.

It’s not 100% clear what you are trying to accomplish but you may want to look into enums or Dictionary. A Dictionary you can populate with key, value pairings and can look up values dynamically with the key during run time.

Thanks for the replies.

I’m not sure how to better explain it, I was trying to define the integer’s name from a [serializedfield] in the inspector, but it sounds like that isn’t possible.

I am trying to build a system where I can tell the player where to spawn based on the last spawn point they touched.

So what I figured out I can do instead is just create a separate script for every level where I can manually define the variables. I was trying to do it with one script but I can’t figure out how to do that.

It could be possible but it depends on the example. A string such as “32” could be converted to an int. A strich such as “32 99” could be converted to an int array with the String.Split method and TryParse.

Without any examples like the ones in my first paragraph, it’s impossible to tell you if your idea can be accomplished with built-in C# features or if you will have to write your own solution.

I have a public static integer for every level, that I wanted to be able to update based on which spawn point collider you run into before you leave the level. Then I wanted to be able to call that integer if you reload the level and place the player at the proper position.

What I was trying to do was never going to work. I wanted to name an integer with serialized field entry, not use any numbers from it, but that still wouldn’t have changed which integer I was updating.

I’m probably still not making sense. I’m too new to this programming thing.

Could you please share your relevant code? At the moment, I’m not sure what you did exactly. Why public static? And why an int instead of a Vector3? Since you want to place the player at a specific position (a Vector3 object in Unity), it would make sense to use a Vector3 object to store the position.

Nina, thank you for your persistence. I really appreciate it.

Ok here goes…

I’m trying to do a metroid-like level system where I can go in a door (to a new scene) and when I come back through that door I start at the point I left from.

I have a GameManager object that doesn’t destroy on load to hold information, and I have all of my spawn points set in it so that they don’t get deleted. The spawns are children of the GameManager that I point to in the inspector. This is it’s script.

using System.Collections;
using UnityEngine.SceneManagement;
using System.Collections.Generic;
using UnityEngine;

public class GameManagerScript : MonoBehaviour
{
    GameObject player;
    Transform currentSpawnTransform;
    Scene currentScene;


    string newSceneName = "null";  // declaring variables so that they are never null



    //variables for level spawns
    //simpleOver
    [SerializeField]GameObject simpleOverspawn01;
    [SerializeField]GameObject simpleOverspawn02;
    public static int simpleOverSpawnLocationInt;

    //simpleUnder
    [SerializeField]GameObject simpleUnderspawn01;
    [SerializeField]GameObject simpleUnderspawn02;
    public static int simpleUnderSpawnLocationInt;

    

    // called first



    void OnEnable()
    {        
        SceneManager.sceneLoaded += OnSceneLoaded;//declares the OnSceneLoaded Method
    }


    // called second
    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        newSceneName = SceneManager.GetActiveScene().name;
        GameObject player = GameObject.FindGameObjectWithTag("Player");

        // controls for spawning player into correct position based off what level player came from previously
            if (newSceneName == "simpleOver")
            {   
                Debug.Log("we are in simplover and should be placing the player in the right spot");
                if (simpleOverSpawnLocationInt == 1)
                {                   
                    currentSpawnTransform = simpleOverspawn02.gameObject.GetComponent<Transform>();
                    player.transform.position = currentSpawnTransform.position;
                }
            }
            
            else if (newSceneName == "SimpleUnder")
            {   
                Debug.Log("we are in SimpleUnder and should be placing the player in the right spot");
                if (simpleUnderSpawnLocationInt == 1)
                {
                    currentSpawnTransform = simpleUnderspawn02.gameObject.GetComponent<Transform>();
                    player.transform.position = currentSpawnTransform.position;
                }

                else if (simpleUnderSpawnLocationInt == 0)
                {
                    currentSpawnTransform = simpleUnderspawn01.gameObject.GetComponent<Transform>();
                    player.transform.position = currentSpawnTransform.position;
                }
            }
        
    }



//Destroys the gamemanager object in the scene that is loading if there are two, since we don't want multiples.
    void Awake()
    {
        currentScene = SceneManager.GetActiveScene();
        GameObject player = GameObject.Find("Player");
        GameObject[] objs = GameObject.FindGameObjectsWithTag("GameManager");
        if (objs.Length > 1)
        {
            Destroy(this.gameObject);
        }
        DontDestroyOnLoad(this.gameObject);
    }



    // Start is called before the first frame update
    void Start()
    {
        
        //currentScene = SceneManager.GetActiveScene();
    }

    
    // Update is called once per frame
    void Update()

    {   
         Debug.Log("simpleunderspawnlocationint = " + simpleOverSpawnLocationInt);

        if (currentScene.name == "UpUpAndAway")
        {
            GameObject currentMusicPlayer = GameObject.Find("simpeOverMusicPlayer");//get music player from first level
            if (currentMusicPlayer != null)
            {
            Destroy(currentMusicPlayer.gameObject); //destroy 1st musicplayer
            } 
        }
        else if (currentScene.name == "ThroughTheMountain")
        {
            GameObject currentMusicPlayer = GameObject.Find("UpUpMusicPlayer");//get music player from UpUpandAwayLevel
            if (currentMusicPlayer != null)
            {
            Destroy(currentMusicPlayer.gameObject); //destroy 2cnd musicplayer
            }
        }
        else if (currentScene.name == "End")
        {
            GameObject currentMusicPlayer = GameObject.Find("MountainMusicPlayer");//get music player from UpUpandAwayLevel
            if (currentMusicPlayer != null)
            {
            Destroy(currentMusicPlayer.gameObject); //destroy 2cnd musicplayer
            }
           // GameObject mySelf = GameObject.Find("GameManager");//get music player from UpUpandAwayLevel
           // Destroy(mySelf.gameObject);
        }
        else if (currentScene.name == "OpeningMenu")
        {
            GameObject simpeOverMusicPlayer = GameObject.Find("simpeOverMusicPlayer");//get music player from UpUpandAwayLevel
            GameObject UpUpMusicPlayer = GameObject.Find("UpUpMusicPlayer");//get music player from UpUpandAwayLevel
            GameObject MountainMusicPlayer = GameObject.Find("MountainMusicPlayer");//get music player from UpUpandAwayLevel
            
            if (simpeOverMusicPlayer != null)
            {
            Destroy(simpeOverMusicPlayer.gameObject); //destroy 2cnd musicplayer
            }
            else if (UpUpMusicPlayer != null)
            {
            Destroy(UpUpMusicPlayer.gameObject); //destroy 2cnd musicplayer
            }
            else if (MountainMusicPlayer != null)
            {
            Destroy(MountainMusicPlayer.gameObject); //destroy 2cnd musicplayer
            }
            
        }
        
    }

    
}

each level has it’s own spawn controller script like this

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SimpleUnderSpawn : MonoBehaviour
{
    GameObject player;
    [SerializeField] GameObject gameManager;
    [SerializeField] int spawnLocationInt;
    
    void Start() 
    {
        gameManager.GetComponent<GameManagerScript>();
    }
   
    private void OnTriggerEnter(Collider other) {
        if (other.gameObject.tag == "Player")
        {
            GameManagerScript.simpleUnderSpawnLocationInt = spawnLocationInt;
        }
    }
}

and this

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SimpleOverSpawn : MonoBehaviour
{
 GameObject player;
    [SerializeField] GameObject gameManager;
    [SerializeField] int spawnLocationInt;
    
    void Start() 
    {
        gameManager.GetComponent<GameManagerScript>();
    }
    
    private void OnTriggerEnter(Collider other) {
        if (other.gameObject.tag == "Player")
        {
            GameManagerScript.simpleOverSpawnLocationInt = spawnLocationInt;
        }
    }
}

I keep thinking there must be an easier way to do this, because this is tedious and really starting to frustrate me. I can get this to work when I leave the first level and come back, but it will not work on the second level, and I haven’t figured out why yet. edit I figured out it was because I had the wrong script on the third level. Nowe everything works the way I wanted it to. It’s just tedious

The whole reason I wanted to declare variables in the inspector was to avoid making a separate spawn script for every level.

You don’t need MonoBehaviour classes if the stuff you want to store is not “in the scene” like a game object. You could, for example, write a “normal” C# class with one of the singleton pattern versions (the first version is sufficient).

In that class/instance, you could store the player’s position in the previous scene and whatever else you need for the game play. You call the Instance method of that class to get the reference to the object, then you’ll be able to get or set the data you stored there. That’ll work in all scenes, and you won’t have to look for that object via FindObjectOfType or something like that. Just call the Instance method.

Of course, you need one spawn script in each scene because you somehow need to set/reset the position of your player. And the spawn script gets the relevant data from the singleton object (see above).

Thank you Nina,

I truly appreciate the effort you have put into helping me out with this, but in all honesty I really don’t have enough understanding of c# yet to understand all of the things you just said. That singleton thing makes my head spin reading about it. :grinning:

I still am not even sure what the monobehavior is doing for me, and/or why I need or don’t need it. I’m just now at the level that I’m starting to understand where I need to put semicolons and {} curly brackets, and if/else statements.

I shouldn’t really even be doing what I was doing, but I’m a button pusher by nature. I haven’t even finished my course and I went off on a tangent trying to figure out how to do something. I understand now why what I wanted to do with strings wouldn’t work in c#, but it seemed a totally logical way at the time.

And with the level loading thing, I might not have done it “properly”, but I am proud of myself that I was able to make it work. That feels like a big accomplishment to me. But now that I scratched my button pushing itch, it’s probably time for me to go back to the course and finish it. So that I can find a better way to do it, like maybe with singletons and saving vector locations, as you have so kindly suggested.

Last week I just finished the project boost part of the introduction to Unity course, and I paused there to go off into excited craziness. With that said, I’m going to do some more of the courses and come back to what you told me. Hopefully I’ll understand it better then.

MonoBehaviour allows you to attach your scripts to the Inspector in Unity. You do that if you want to have something “in the scene” by which I mean what you see in the scene and in the Unity editor.

A normal C# class could not be added, and you will never see a visual representation of that object. When you write normal C# classes, you mainly imagine that there is something like an object which does stuff during runtime.

It is an accomplishment. Everything you made work is a step closer to the finished game. With each problem you solve, you improve your skills. And there is usually a lot to do, so it doesn’t matter much if you cannot solve every single problem.

If you feel stuck, it could be a good idea to take a break and do something else. If you are interested in a free C# course, I can recommend Bob Tabor’s. It does not have anything to do with Unity but can still help you in a lot of ways.

That’s also a good idea. From what I see, your code is already very complex. When you know a few more techniques, it might be that you will come up with a different solution for your current problem, or you’ll suddenly know how to make your current code work.