Hi there–I’m pretty new to OOP, trying to figure some stuff out. Any help is much appreciated.
I’m working on a simple overhead 2d game. I want to create enemies that move around the screen in a variety of ways. There are two major qualities that each enemy has: how it moves, and how it reacts at the edge of the screen.
Some enemies move in straight lines, some enemies move in sine waves, etc. Some enemies bounce off the edge of the screen, Pong-style; others, when they hit the edge, get repositioned to the opposite edge, looping merrily along their way.
I have a BaseEnemy class that holds their HP, their X and Y velocities, etc. I’ve successfully coded two child scripts, Ponger and Looper, that derive from BaseEnemy, that control how the enemy reacts to screen edges.
I now want to create a different set of scripts that control how the enemy moves. Call them Drifter and Siner. One moves steadily in one direction; the other moves in a sine wave.
On its own, this would be pretty easy. What I can’t figure out is how to correctly set up the movement scripts to interact with the edge scripts. If both edge scripts and movement scripts inherit from BaseEnemy, and I add them both to an object, one simply stops working, and I can see in the inspector that each of them has its own versions of the BaseEnemy’s variables (HP etc). So that’s no go.
If one (either edge script or movement script) is a MonoBehavior, it doesn’t have access to the base class’s variables (velocities etc.) I can maybe do a GetComponent to get that access (? maybe?) but that doesn’t seem like the right thing.
Third option is to create hybrid scripts derived from the BaseEnemy class, called LooperDrifter, LooperSiner, PongerDrifter, PongerSiner. This obviously gets unwieldy as I add more behaviors, and is pretty clearly not the way OOP is supposed to be.
Fourthly, I could put the edge behaviors into the base class. That probably would work in this case since I don’t imagine ending up with more than 3-4 edge behaviors. But that doesn’t seem philosophically right either.
Could somebody help me understand what the right way to do this is? Thanks for your time!
Here’s a simplified version of BaseEnemy:
public class BaseEnemy : MonoBehaviour {
protected float xSpeed;
protected float ySpeed;
protected int HP;
public virtual void Start () {
}
public virtual void Move () {
transform.Translate(new Vector3(xSpeed, ySpeed, 0) * Time.deltaTime);
}
public virtual void Update () {
Move();
}
}
Here’s a simplified version of Ponger:
public class Ponger : BaseEnemy {
public virtual void Start () {
base.Start();
}
public virtual void Update () {
base.Update ();
// this is what makes it a Ponger
if ((transform.position.x < -10)||(transform.position.x > 10)) {
xSpeed = -xSpeed;
}
if ((transform.position.y < -10)||(transform.position.y > 10)) {
ySpeed = -ySpeed;
}
}
}
Here’s a simplified version of Drifter:
public class Drifter : BaseEnemy {
void Start () {
xSpeed = Random.Range(-10,10);
ySpeed = Random.Range(-10,10);
}
void Update () {
base.Update();
}
}