- Home /
"Injecting" an interface into an object
I have a class for my enemy which extends from MonoBehaviour. This class has inside a reference to another class that I have made:
[RequireComponent (typeof (Action))]
public class EnemyController : MonoBehaviour {
public Action action; // Action is an interface!
}
Now, I would like to "inject" this dependency using the Unity GUI, just dragging and dropping the desired object into the EnemyController. The problem is that Action is an interface, so Unity tells me that the class can't be abstract.
My idea was to be able to use different types of Actions... Is it possible to do this?
Thanks!
Answer by rutter · Jun 25, 2014 at 09:10 PM
Bad news: Unity's built-in serialization isn't polymorphic. Your Action
reference can point at any given subclass during runtime, of course, but when Unity writes the data to disk, it will serialize only an Action
and its associated fields.
You can find some discussion about this, online, but this thread is a pretty good overview.
Some people work around this by integrating other serialization libraries, such as JsonFX, MiniJSON, Protobufs, or so on. Others use Unity to serialize primitive data containers, which they use to reconstruct necessary objects at runtime.
Thanks for the fast answer, rutter. This is definetely bad news, since I had been planning this very nice object-oriented solution for my problem for some time, and it relies on interfaces and the possibility of switching implementations interchangeably (actually, it's AI related - just like the question in the post that you sent me).
This sucks. I'm depressed now. I guess I will have to make some very ugly and very big class with enums to handle this.
For those with the same kind of problem, I've made a quite simple workaround:
public enum ActionType {
ACTION1, ACTION2;
}
[RequireComponent(typeof (ActionType))]
public class EnemyController : $$anonymous$$onoBehaviour {
private Action action;
public ActionType actionType;
void Start () {
switch (actionType) {
case (ACTION1): action = new ProwlAction(); break;
case (ACTION2): action = new AttackAction(); break;
default: break;
}
}
}
Something like that should work. It is not as nice and elegant as the pure OO solution would be, but it's something.
Your answer
Follow this Question
Related Questions
Is it possible to use || (or) with RequireComponent? 5 Answers
Wierd problem with abstract classes and import statements in Javascript 2 Answers
Abstract class question 1 Answer
Abstract Class acting like a static Class when inherited 1 Answer
How should I structure my unit class relationships? 1 Answer