Interface for your robot to the weapon system and some proxy function to shoot.
public interface IRobot {
IWeaponSystem WeaponSystem { get; set; }
void ShootTarget();
}
Interface for your weapon system and some undefined way to settarget and shoot.
public interface IWeaponSystem {
void SetTarget();
void Shoot();
}
Base class for the Robot that extends MonoBehaviour, and uses the IRobot interface.
public class Robot : MonoBehaviour, IRobot {
private IWeaponSystem weaponSystem;
/// <summary>
/// Can be set to some initial weapon system in UI
/// or set programmatically from code.
/// </summary>
public IWeaponSystem WeaponSystem {
// assumes some sort of IWeaponSystem is attached
get { return weaponSystem; }
set { weaponSystem = value; }
}
void Update() {
WeaponSystem.SetTarget(); // if there is one
ShootTarget(); // same as above, but the weapon system still handles it
}
public void ShootTarget() {
WeaponSystem.Shoot();
}
}
Base astract class for WeaponSystem. Can’t be instantiated i.e. abstract, extend this for all weapon systems.
public abstract class WeaponSystem : MonoBehaviour, IWeaponSystem {
void IWeaponSystem.SetTarget() {
/*do set target ai logic at this level*/
}
void IWeaponSystem.Shoot() { /*do nothing abstract base*/ }
}
Subclass for some turret weapon system.
public class TurretWeaponSystem : WeaponSystem {
// re-define shoot here
public void Shoot() {
// do TurretWeaponSystem specific Shoot() behavior
}
}
Most of your logic will take place elsewhere, but here is a rough example of the indirect interactions.
void exampleUsage() {
Robot myRobot = new Robot();
WeaponSystem genericWeaponSystem = new TurretWeaponSystem();
// noting that myRobot.WeaponSystem is of IWeaponSystem type
myRobot.WeaponSystem = genericWeaponSystem;
myRobot.ShootTarget();
}
This isn’t exactly how I would do it, but based on what I read, I tried to keep the interfaces in there. With interfaces, if performance is a concern, you’ll want to avoid boxing and unboxing of the real types the interfaces point to as often as possible. Once it gets pass and set to to a variable, it should be fine, but constant marshaling will amount to some level of performance hit across the whole system if you use the pattern a lot.