- Home /
How to use Interfaces in UnityScript/JavaScript? Is it even possible?
So I have tried using the keyword interface in JavaScript/UnityScript but that does not compile correctly when I try to implement the interface.
I have seen it used in Unity C#.
I want to know if you can achieve this with UnityScript/JavaScript or not. Is it even possible? Is there an equivalent way of achieve a similar goal to what Interfaces achieve?
Answer by robhuhn · Sep 03, 2013 at 09:38 AM
According to the documentation you can use interfaces in UnityScript since Unity3.
interface IFoo {
function bar();
}
class Foo implements IFoo {
function bar() {
Console.WriteLine("Foo.bar");
}
}
EDIT: In order to get interfaces compiling and running correctly, you need to:
The file name of the script defining the interface must match the interface name. e.g MyInterface.js contains the MyInterface interface declaration.
The file using the interface needs to extend from MonoBehaviour (if the file is going to be attached to a game object)
The file name using the interface needs to match the class name.
// The following class is using the MyInterface interface. // It is contained in a file called MyImpl.js class MyImpl extends MonoBehaviour implements MyInterface { function bar() { Debug.Log("Interfaces work!"); } }
I tried using it outside of the $$anonymous$$onoBehaviour class it was defined in and that didn't work for me. There is no point to an interface if it is being declared and used from within the same class.
Just had a quick test and this works:
#pragma strict
interface IFoo {
function bar();
}
class TestJS extends $$anonymous$$onoBehaviour implements IFoo {
function bar() {
Debug.Log("Foo.bar");
}
function Start () {
}
}
It will also throw a warning if function bar is not implemented.
I tried using it outside of the $$anonymous$$onoBehaviour class it was defined
Creating a file ITest.js containing these lines and implement the interface in TestJS works too:
#pragma strict
interface ITest{
function bar();
}
$$anonymous$$ay be you could post your code.
_shock and rob (sounds like "shock and awe!") is it one of those weird U/S things where it will work in a "naked" script (filename.js, but with NO explicit class inside) but it won't work in filename.js with explicit filename class inside??
great question BTW
ok, that should definitely give a warning when launching "The class defined in script file named 'testImpl' does not match the file name!".
Try to change the class filename to "testImpl.js" and the interface filename to "myInterface.js". But I need to say that there is a first to upper convention when na$$anonymous$$g classes. So actually it should be "TestImpl.js" - class TestImpl and "$$anonymous$$yInterface.js" - interface $$anonymous$$yInterface.
Answer by fafase · Sep 03, 2013 at 02:17 PM
I know the question is about how to use Interface but here why I do not use them. Interface cannot inherit from MonoBehaviour so you lose all of the advantages of making it a component.
As a matter of fact you get the exact same behaviour with an total abstract class except the fact of the single inheritance but you can easily get over that.
Fetching an object of type IInterface means you need to use a FindObjectOfType which is not that good. Using an abstract class you can do GetComponent()
Also, you can actually create a reference in another class and use the drag and drop in the inspector which I never managed to get working with an interface since no MonoBehaviour. I guess a Editor scritp would do.
Nonetheless, I may be wrong and there might be a way to do with Interface what I could not do...Forgive my ignorance.
Yes actually that's not the use case for interfaces. You don't want to derive an interface from $$anonymous$$onoBehaviour.
Imagine a component class "Weapon" extending $$anonymous$$onobehaviour then you could write interfaces to provide some additional method headers like "Reloadable", "$$anonymous$$ountable". Then you would write something like (pseudo code):
weapon = GetComponent(LaserWeapon) //LaserWeapon extends Weapon implements $$anonymous$$ountable (it's not reloadable)
if(weapon is Reloadable)
{
weapon.Reload();
}
if(weapon is $$anonymous$$ountable)
{
weapon.mount();
)
So interfaces are totally useful and can improve your code architecture.
You can also do that with abstract class, the down point is that you now have one more level of inheritance.
public abstract class AbClass:$$anonymous$$onoBehaviour{
public abstract void Reloadable();
public abstract void $$anonymous$$ountable();
}
public class Weapon:AbClass{
public override void Reloadable(){}
public override void $$anonymous$$ountable(){}
}
Same result.
As for: "You don't want to derive an interface from $$anonymous$$onoBehaviour. " you simply cannot do that. An interface can only inherit from another interface.
But I see your point in using interfaces as only one behaviour. Yes that is the whole point of interfaces, but Unity makes it quite complicated (I think).
In your example, LazerWeapon is a component but how do you know which interface it implements? You have to use some reflection.
This is getting to be a discussion, but I feel the need to chime in.
I also prefer abstract classes when dealing with monobehaviours, but sometimes interfaces just make more sense. When I know which interface I need to access, I use this handy function to get all $$anonymous$$onoBehaviours that implement a specific interface from a GameObject.
Yep, does the trick but it uses reflection if(obj is T) which tends to be slow. Dunno if that makes it that much slower though. And yes it is turning into a discussion on whether one or the other :).
Answer by Ericool · Jan 08, 2015 at 05:08 PM
The problem is that unityscript dont have the keyword abstract so you must use virtual and leave {} empty or with a return and then override it to have the same effect of an abstract but if you just have method to implement you can "inherit" from an interface that is why you would use it. You cannot make a component with an abstract class or an interface by the way and you use find of type because you are actually making a new type right?.
Your answer
Follow this Question
Related Questions
C# to UnityScript conversion help. 0 Answers
How do I access a variable from another GameObject? 1 Answer
UnityScript equivalent of JavaScript objects 2 Answers
Enemy following Player in range 2 Answers