- Home /
Multiple Game Objects, different components
This is probably a really dumb question, but I'm completely stumped at this point. Here is the functionality I need to create:
Load multiple GameObjects, which have an attached script that has stat and function information.
Get data out of that attached script and then use it.
Now, I've been able to do this in a singular case via:
var Player1: GameObject;
function PrintDatas(){
var p1Stats = Player1.GetComponent(MageScript);
Debug.Log(p1Stats.Health);
}
Where I'm having issues, however, is if I want to use a different character - a Fighter for example. The fighter is unlikely to have the "MageScript" component, since that contains spells and stats for the Mage.
So, how would I access that script without being specific to the name? I tried substituting a string, but was not successful.
var statsString:String = Player1.name+"Script";
Resulting in the error: 'Health' is not a member of UnityEngine.Component'.
My other idea was to create a uniform "stats" script and save it as part of a prefab on the character game objects, but of course it's the same script on each, so that doesn't work for me - I need different functions and values.
Any help would be appreciated.
Answer by whydoidoit · Jul 14, 2012 at 08:59 PM
Sounds like you need an Interface or a base class that your other scripts inherit from.
Your problem with the string version of GetComponent is that neither you nor the compiler can cast it to a variable of the script you need.
If you have a base class with the common stats in it (inherited from MonoBehaviour) then you can inherit the other scripts from that rather than MonoBehaviour. Or you could use a common interface and implement it on all of your scripts. Or you could have separate scripts for each of the different stats and have all your characters implement the basic health ones.
Hi! Thanks for your answer!
Is "Interface" a general program$$anonymous$$g concept? I couldn't find anything specific searching in the Unity Script Reference.
Inheritance: I would create a class called "BasicStats" that contains health and, say, Damage. I would then create a "$$anonymous$$age" class that extends that "BasicStats" class and that has specific $$anonymous$$age centric values and functions - Spells, intelligence stats, etc?
Again though, how would I access data in the "$$anonymous$$age" component without specifying the name? Could be I'm going about this in the wrong way, in general.
The goal: Have several characters with their unique functions in a script per character. And be able to use those characters in non-character specific functions.
Example - $$anonymous$$age Class and Fighter Class. Both have an "Attack" function which receives a "Target" (found via a raytraced click). Typically the target is an "enemy" which will receive damage output from the "Attack" function based on a function in the "enemy" script that receives "Damage".
I'm just trying to figure out how to deter$$anonymous$$e which character takes the action outside of building a bunch of if statements. Psuedo-Code: if (currentCharacter==$$anonymous$$age){ playerStats = "$$anonymous$$ageScript"; }else if (currentCharacter==Fighter){ playerStats = "FighterScript"; }
Just seems ineffective. Sorry for asking a dozen more questions, heh. Just trying to wrap my head around this mess.
Interfaces are a basic program$$anonymous$$g concept. An interface defines a program$$anonymous$$g contract that says everything that implements them (extends them as well as a base class) will guarantee to implement all of their functions. You use them like you would a class reference and then each script has it's own version of their code - you are inheriting a function set, not the implementation of that set. .NET based languages use them ins$$anonymous$$d of multiple inheritance to enable objects to act as multiple things.
You define an interface as a list of functions with no implementation.
interface IDoSomething
{
function DoIt();
}
interface ISomethingElse
{
function DoThat();
}
class Hello extends $$anonymous$$onoBehaviour implements IDoSomething, ISomethingElse
{
function DoIt()
{
}
function DoThat()
{
}
}
You might have an IFight interface for anything that can fight and an ILive interface for anything that has health and an ICast interface for anything that can be magically invoked and maybe an ICarryable interface for anything that can be picked up etc etc. You can use GetComponent to get interfaces etc. Very useful they are too.
gameObject.GetComponentInChildren<IDoSomething>().DoIt();
I believe you can also do function get and function set to enable properties. Functions can return values, they don't just have to be void like the ones I show here.
They are used less in Unity as the composition model of multiple scripts on a single object provides a similar implementation pattern with the ability to inherit the actual values. However, they do provide very useful functionality if you use them for things like spells, objects etc. It allows you to treat multiple scripts without needing to know which one you have. In general interfaces are more flexible than inheritance (you can have multiple of them on a single object) but you need to code the implementation each time.
Interesting. I'll give this a shot. I may just use inheritance for the stats and this Interface model for the functions.
Again, thank you very much!