Problem Serializing Interfaces

I tried following along with this lecture by applying it to the 2D Laser Defender game from the 2D course. I loved the interface idea because my weapon scripts for Laser Defender were SUPER messy.

I ran into a problem with serializing the interface, as Sam and Rick do in the video (at 3:32). In my Player.cs script, I wrote:

[SerializeField] IWeapon activeWeapon = null;

(I changed it from IGun to reflect the game I was making.)

I made an IWeapon interface:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

interface IWeapon
{
    void Fire();
}

I then created RapidFire.cs and implemented the interface:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class RapidFire : MonoBehaviour, IWeapon
{
    [SerializeField] GameObject projectile;
    [SerializeField] float projectileSpeed = 10f;
    [SerializeField] float projectileFiringPeriod = 0.1f;
    [SerializeField] AudioClip projectileSound;
    [SerializeField] [Range(0, 1)] float projectileSoundVolume = .25f;

    public void Fire()
    {
        StartCoroutine(FireContinuously());
    }

    IEnumerator FireContinuously()
    {
        while (true)
        {
            AudioSource.PlayClipAtPoint(projectileSound,
                Camera.main.transform.position,
                projectileSoundVolume);
            GameObject newProjectile = Instantiate(
                projectile,
                transform.position,
                Quaternion.identity) as GameObject;
            newProjectile.GetComponent<Rigidbody2D>().velocity = new Vector2(0, projectileSpeed);
            yield return new WaitForSeconds(projectileFiringPeriod);
        }
    }
}

Finally, I created a gameobject that has the RapidFire (IWeapon) script on it.

The problem comes in when I attempt to drag the prefabbed RapidFire gameobject onto the serialized IWeapon field (like Sam and Rick do in the video). The serialized field does not show up. Initial searching on Unity forums seems to indicate Unity does not support serialization of interfaces.

How did Sam and Rick pull it off? Am I missing something?

1 Like

Could it be a version thing? I’m using 2019.4.18f, but they are using 2019.3.0f3

Sam pulls this off by actually using a MonoBehavior, and then testing to make sure it implements the IGun interface before using it.

1 Like

Thanks, but I’m still a little confused. Sam then changes “MonoBehaviour” to “IGun” at 3:32. However, I noticed this time that when he goes back to Unity the Serialized field’s type for activeGun is still labeled “MonoBehaviour” when he drags in the rocket launcher at 4:48. Did he only type “IGun” to illustrate the point that we are using an interface but then change it back to MonoBehaviour off screen?

I just tried this again, and I can get a “MonoBehaviour” type to show up, but it disappears if I change it to IGun.

If it disappears, how can you test if it “implements the iGun interface.” Sam doesn’t use an if statement, but that’s the only thing I can think of. But if we use an if statement, that clutters the code quite a bit, and we’re trying to simplify.

I ended up making a new Gun abstract class and making new scripts for rocket launcher, shotgun, etc. that inherit from it. These “Gun” types can then be serialized. This works, but I’d like to wrap my head around what Sam’s doing with interfaces.

Use abstract class :

public abstract class BaseWeapon : Monobehaviour
{
public abstract GameObject Projectile {get; set;}

public abstract void Fire();
}

And then you can use it in inspector and derive weapons from it

I believe that’s exactly what he did. As this section is illustrative, it’s not actually backed by a Github commit I can compare to. I do know that you can’t Serialize an interface. In the code I saw, it was a GameObject, and then an if GetComponent()

Thanks for the tip!

Thanks, Brian. I appreciate it.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms