Reputation: 37
I recently decided to make a command console for my game, and then proceeded to make some groundwork. My issue is I cannot use it to change any relevant variables, as I have gotten stuck trying to get references to the classes where said variables are stored.
I have an abstract class for my command:
public abstract class Command
{
public abstract void Execute(string[] args);
}
Then I have a class deriving from above class for my command
public class RunesAdd : Command
{
public override void Execute(string[] args)
{
int number;
if(args.Length == 1 && int.TryParse(args[0], out number))
{
Debug.Log(number);
RunCtr.runes += number;
}
else
{
ConCtr.addLogEntry("Incorrect syntax, correct syntax is: runes.add <runes>");
}
}
}
and finally my registry of commands
public class CommandRegistry
{
private Dictionary<string, Command> _commands;
public CommandRegistry()
{
_commands = new Dictionary<string, Command>();
}
public void RegisterCommand(string name, Command command)
{
if (_commands.ContainsKey(name))
{
Debug.Log("Created command already exists");
}
_commands[name] = command;
}
public void RegisterAllCommands()
{
RegisterCommand("testcommand", new TestCommand());
RegisterCommand("runes.add", new RunesAdd());
}
public bool ExecuteCommand(string commandName, string[] args)
{
if (_commands.ContainsKey(commandName) == false)
return false;
_commands[commandName].Execute(args);
return true;
}
}
My problem is that I am unable to get a reference to my class with the variable for runes. I first tried to get a reference to the class in the Command class, so that those variables would be available in all children, but in order to do that I must make a method to actually assign those references, which would look like this:
public void GetReferences()
{
controllerObject = GameObject.FindGameObjectWithTag("Controller Object");
RunCtr = controllerObject.GetComponent<Runes_Controller>();
ConCtr = controllerObject.GetComponent<Console_Controller>();
}
The issue here is that since I cannot get a reference the Command class (due to it being abstract) in any of my monobehavior scripts which have the void Start() method, I cannot actually execute this method to assign the references. I then tried to make another class called GetReferences, which looks like this:
public class GetReferences
{
public GameObject controllerObject;
public Runes_Controller RunCtr;
public Console_Controller ConCtr;
public void GetReferencesMethod()
{
controllerObject = GameObject.FindGameObjectWithTag("Controller Object");
RunCtr = controllerObject.GetComponent<Runes_Controller>();
ConCtr = controllerObject.GetComponent<Console_Controller>();
}
}
Then I made the Command class derive from my GetReferences class, called the GetReferencesMethod() from a monobehavior script on start. Doing this I no longer get an error for not having assigned my classes to references, but whenever I try to edit the values it just does nothing. I have been searching the web for 2 hours now, but no dice. If I explained myself poorly please let me know. Any help is much appreciated, and thanks in advance!
Upvotes: 3
Views: 404
Reputation: 2598
Ok from what I understand is that you are trying to get your Command
class using the GetComponent<>
method. I might be wrong on this, so correct me if I am wrong.
If it is, then the issue is GetComponent<> only works with MonoBehaviour
derived classes. Meaning you have to implement your class as a MonoBehaviour
, which should be as simple as this:
public abstract class Command : MonoBehaviour {...}
After reading your comments I believe you can use of the a Singleton pattern.
If you place your RuneController & CommandController on the same object and add another class called GameManager or InGameManager. Then you can use a singleton pattern to access it.
public class GameManager
{
public GameManager Instance { get; private set; }
public RuneController RuneController { get; private set; }
public CommandController CommandController { get; private set; }
void Awake ()
{
// If there is an instance, and it's not me, delete myself.
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
}
}
void Start()
{
this.RuneController = GetComponent<RuneController>();
this.CommandController = GetComponent<CommandController>()
}
}
So the usage will look as follow:
GameManager.Instance.RuneController.Execute(command);
Upvotes: 1