Home > OS >  Unity C# - Calling subclass dynamically from the base class
Unity C# - Calling subclass dynamically from the base class

Time:10-18

I'm pretty new to C# and Unity and I've trying to figure out how to handle subclasses through the base class.

I am making a card game. I've made a baseclass PlayerCard, which has subclasses such as Minion : PlayerCard.

My current structure is that PlayerCard class is instantiated like this from the deck at the start

public class PlayerDeck : MonoBehaviour{

[SerializeField] PlayerCard[] playerCardArray;

private int xPos = 2;


public void DrawCards()
{
    var cardIndex = Random.Range(0, playerCardArray.Length);
    AddCardToPlayer(playerCardArray[cardIndex]);
}

private void AddCardToPlayer(PlayerCard myCard)
{

    Vector3 cardPos = new Vector3(transform.position.x   xPos, transform.position.y, transform.position.z);
    PlayerCard newCard = Instantiate(myCard, cardPos, transform.rotation) as PlayerCard;
    xPos = xPos   2;
}

I want my baseclass (PlayerCard) handle all mundane things such as dragging and moving the card as they will be the same for all the cards.

    private void OnMouseDown()
{
    ToggleDrag();
}

void Update()
{
    if (DraggingON) { Drag(); }
}

private void ToggleDrag()
{
    Debug.Log(playerCard);
    mouseOffset = gameObject.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, mouseScreenPoint.z));

    if (DraggingON)
    {
        DraggingON = false;
        SnapCardToPosition();
    }
    else
    {
        DraggingON = true;

        SnapPositionX = transform.position.x;   //Return to same x position if user has not hovered other available slot
        SnapPositionY = transform.position.y;   //Return to same y position if user has not hovered other available slot

        //Variables above will be reset to default position x/y when user has hovered a slot but then moved object away from the slot, so reset to default
        defaultPositionX = transform.position.x;
        defaultPositionY = transform.position.y;
    }
}

private void Drag()
{
    Vector3 currentMouseScreenPoint = new Vector3(Input.mousePosition.x, Input.mousePosition.y, mouseScreenPoint.z);
    Vector3 currentMousePosition = Camera.main.ScreenToWorldPoint(currentMouseScreenPoint)   mouseOffset;
    transform.position = currentMousePosition;
}

My problem lies, when SnapCardToPosition is called, which is when I want the subclass (whatever it is) to take over and handle interactions with position they were dragged into.

    private void SnapCardToPosition()
{
    Vector2 NewCardPosition = new Vector2(SnapPositionX, SnapPositionY);
    transform.position = NewCardPosition;

    //Dynamically call the subclass here?
}

So the subclass would look something like this

public class Minion : PlayerCard{
[SerializeField] int Damage = 1;


public void HandleCardPlacement()
{
    //Do something
}

I haven't figured out how this could be achieved using my structure or is it fundamentally wrong?

CodePudding user response:

  • Make your method not private (= only this class can see this) but rather protected (= this and any derived class can see this)
  • And make your method either virtual (if there is a common base behavior) or abstract (if every card has to implement it from scratch) and override it in the subclass

In your base class e.g.

protected virtual void SnapCardToPosition()
{
    Vector2 NewCardPosition = new Vector2(SnapPositionX, SnapPositionY);
    transform.position = NewCardPosition;
}

and then in the subclass

protected override void SnapCardToPosition()
{
    // make sure that the base implementation is executed first
    base.SnapCardToPosition();

    // do additional stuff
}

so here each subclass can decide

  • whether to override the method or simply keep he default one of the base class
  • if it overrides it can decide if and when to call the default behavior via the base.SnapCardToPosition();
  • Related