I am confused as to how interface
s work.
I’m trying to test this in a separate project, what I’m trying to do is be able to switch between two weapons, inheriting from a single interface
, and call the shoot()
function to “fire” that weapon.
Ishootable.cs, an interface:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface Ishootable
{
void shoot();
}
These are the two weapon scripts inheriting from that interface, again, this is just a test, the functions are practically identical because it doesn’t matter:
Weapon1.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon1 : MonoBehaviour, Ishootable
{
public wepdat wd;
public void shoot()
{
if(wd.ammo>0)
{
wd.ammo--;
Debug.Log(1);
Debug.Log(wd.message);
}
}
}
Weapon2.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon2 : MonoBehaviour
{
public wepdat wd;
public void shoot()
{
if(wd.ammo>0)
{
wd.ammo--;
Debug.Log(2);
Debug.Log(wd.message);
}
}
}
By the way, public wepdat wd
is just a scriptable object with an ammo
int
eger and a message
string
.
What I want to do is switch between weapons with the number keys and fire with space:
WeaponBehavior.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponBehavior : MonoBehaviour
{
public GameObject body;
void Update()
{
if(Input.GetKeyDown(KeyCode.Alpha1)) {}
if(Input.GetKeyDown(KeyCode.Alpha2)) {}
if(Input.GetKeyDown(KeyCode.Space)) {}
}
}
What do I put in each condition?
And what is the best practice in this case?
To learn more about inheritance, please see this: OOP Concept for Beginners: What is Inheritance?.
But basically, in your case, you want an abstract class (most likely) or a parent class that has actual code in the method.
Convert Interface to abstract class:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public abstract class Shootable : MonoBehaviour
{
public abstract void shoot();
}
Update Weapon 1. to just extend from Shootable abstract class. Will require you to override the shoot() method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon1 : Shootable
{
public wepdat wd;
public override void shoot()
{
if(wd.ammo>0)
{
wd.ammo--;
Debug.Log(1);
Debug.Log(wd.message);
}
}
}
Similar for Weapon2. Extend the Shootable class. (You actually forgot to implement the interface in your sample code earlier)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon2 : Shootable
{
public wepdat wd;
public override void shoot()
{
if(wd.ammo>0)
{
wd.ammo--;
Debug.Log(2);
Debug.Log(wd.message);
}
}
}
Now you can just create a Shootable object that can be used as Weapon 1 and Weapon 2. Just keep in mind, you will only have access to the methods in the Shootable class ( aka only shoot() )
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponBehavior : MonoBehaviour
{
public GameObject body;
public Shootable currentWeapon;
public Weapon1 wp1;
public Weapon2 wp2;
void Update()
{
if(Input.GetKeyDown(KeyCode.Alpha1)) { currentWeapon = wp1; }
if(Input.GetKeyDown(KeyCode.Alpha2)) { currentWeapon = wp2; }
if(Input.GetKeyDown(KeyCode.Space)) { currentWeapon.shoot(); }
}
}
So this is how interfaces should work for your project. Leave all the scripts as they are. Just rewrite WeaponBehavior.cs . And one more thing. Look at this line:
public class Weapon2 : MonoBehaviour
and change it as follows:
public class Weapon2 : MonoBehaviour, Ishootable
And this is WeaponBehavior.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WeaponBehaviour : MonoBehaviour
{
Ishootable[] ishootable = new Ishootable[2];
Ishootable weapon;
void Awake()
{
ishootable[0] = (Ishootable)FindObjectOfType(typeof(weapon1));
ishootable[1] = (Ishootable)FindObjectOfType(typeof(weapon2));
weapon = ishootable[0];
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
weapon = ishootable[0];
if (Input.GetKeyDown(KeyCode.Alpha2))
weapon = ishootable[1];
if (Input.GetKeyDown(KeyCode.Space))
weapon.shoot();
}
}