- Home /
Calling a script with name
Total scripting noob, so forgive me.
I'm trying to use a string to hold an assigned value, and then call a method belonging to a script named that value. The context is a select screen where you choose one of 4 different rules of play, which are similar but slightly different. There is a script attached to the same object for each, named "mode1", "mode2" and so on. The idea is that once one is selected, it will store the name to the "gameMode" string, and then call the selected game mode easily, without having to bother with more complicated scripting.
Needless to say, Unity would have none of that. It just tells me that 'string' has no method of 'Initialize' for the below script.
Any ideas?
using UnityEngine; using System.Collections; using System.Collections.Generic;
public class GameModeSelect : MonoBehaviour { public Texture mode1Texture; public Texture mode2Texture; public Texture mode3Texture; public Texture mode4Texture;
public string gameMode;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
void OnGUI()
{
if(GUI.Button(new Rect(10, 10, 100, 100), mode1Texture))
{
gameMode = "mode1";
gameMode.Initialize();
}
if(GUI.Button(new Rect(10, 110, 100, 100), mode2Texture))
{
gameMode = "mode2";
gameMode.Initialize();
}
if(GUI.Button(new Rect(110, 10, 100, 100), mode3Texture))
{
gameMode = "mode3";
gameMode.Initialize();
}
if(GUI.Button(new Rect(110, 110, 100, 100), mode4Texture))
}
gameMode = "mode4";
gameMode.Initialize();
}
Before anyone reprimands me for doing things completely illogically, keep in mind that I tried to do it with a different kind of variable. Because each script is a different class, I can't just assign a variable that changes depending on which one you select, because then there's a type conflict. I tried to typecast it when it changes, but it didn't even let me launch because of it.
Any ideas on how to make this work simply?
I hope this makes sense...
Answer by rejj · Jul 18, 2011 at 01:05 PM
You can get around your issue with different types by using an interface, and having the classes defining the different modes all implement that.
eg
public interface IGameMode {
public void Initialize();
}
public class mode1 : IGameMode {
public void Initialize() {
// do stuff
}
}
public class mode2 : IGameMode {
public void Initialize() {
// do other stuff
}
}
And then in your script that selects game modes, you would have a variable defined to be of type IGameMode
.
private IGameMode selectedMode;
void OnGUI() {
If ( ... ) {
selectedMode = new mode1();
}
if ( ... ) {
selectedMode = new mode2();
}
selectedMode.Initialize();
}
edit / update:
Create a new empty project, and then add the following c# scripts to it:
IGameMode.cs
using UnityEngine;
using System.Collections;
interface IGameMode {
void Initialize();
}
ModeOne.cs
using UnityEngine;
using System.Collections;
public class ModeOne : MonoBehaviour, IGameMode {
public void Initialize() {
Debug.Log("Mode One init");
}
}
ModeTwo.cs
using UnityEngine;
using System.Collections;
public class ModeTwo : MonoBehaviour, IGameMode {
public void Initialize() {
Debug.Log("Mode Two init");
}
}
MainController.cs
using UnityEngine;
using System.Collections;
public class MainController : MonoBehaviour {
private IGameMode gameMode;
void OnGUI() {
if (gameMode == null) {
if(GUI.Button(new Rect(10, Screen.height / 2, 150, 50), "Button One")) {
gameMode = gameObject.AddComponent<ModeOne>();
gameMode.Initialize();
}
if(GUI.Button(new Rect(170, Screen.height / 2, 150, 50), "Button Two")) {
gameMode = gameObject.AddComponent<ModeTwo>();
gameMode.Initialize();
}
}
}
}
And then drag MainController onto the camera. Hit play, and then make sure you have the Console window visible. Click one of the buttons, and you should see the appropriate log message in the console, and notice the component has been added to the camera.
This is obviously a very simplified example, but hopefully it demonstrates the mechanism for you.
Aha! This is more or less exactly what I wanted. I did have a couple questions though. I was looking in the scripting reference and didn't find any entry for 'interface', so I'm not entirely sure what that's doing or how it works. Is it saving a list of methods in a pseudo-class, sorta thing?
Second, can the public classes for each of the game modes be stored in their own individual scripts (for neatness), or do they have to be in the same one as the interface?
Thank you for your help!
Update: I tried to implement the script you provided, but it keeps telling me that the namespace for IGame$$anonymous$$ode couldn't be found / does not exist. Did I do something catastrophically wrong?
Sorry for the delay in getting back to you. Interfaces are part of the C# language, not something specific to Unity scripting. They allow you to define a contract that anything implementing them must adhere to.
Yes, the classes can all exist in their own files (and should, most likely).
I'll edit my answer above with some more detailed info now.
Thank you so much for your clarification and updated example! I tried to look up the information on interfaces myself, but the results were all either about user interfaces, or were just about interfaces and went way over my head since I've only been using C# for a very short time.
Thank you so much for your help!
could you please mark this as the accepted answer then, so people in the future can tell this was helpful? :)