Home > database >  Inovking an action from a parent in a child class?
Inovking an action from a parent in a child class?

Time:01-12

I'm trying to create a kind of interactables system, where you can have collectible elements and interactable elements, where the collectible elements simply adds to your inventory once entered a collider, and the interactable elements need to have some feedback (user input) to be added

Here is the BaseInteractable class:

using System;
using UnityEngine;

[RequireComponent(typeof(SphereCollider))]
public abstract class BaseInteractable : MonoBehaviour, IInteractable
{
    public enum Collectiblestate
    {
        Collected,
        NotCollected
    }

    protected Collectiblestate _collectibleState = Collectiblestate.NotCollected;
    public static event Action<IInteractable> OnInteractedItem;

    private void OnTriggerEnter(Collider other) => OnItemInteracted();

    // This this function comes from the interface
    public virtual void OnItemInteracted() => OnInteractedItem?.Invoke(this);
}

Here is the StandardCollectible class:

using UnityEngine;

public class StandardCollectible : BaseInteractable
{
    [SerializeField] private GameObject _collectibleImage = default;

    public override void OnItemInteracted()
    {
        base.OnItemInteracted();
        _collectibleState = Collectiblestate.Collected;
        _collectibleImage.SetActive(false);
    }
}

And here the StandardInteractable class:

using System;
using UnityEngine;

public class StandardInteractable : BaseInteractable
{
    public static event Action OnInteractThresholdReached;

    [SerializeField] private KeyCode _interactKey = KeyCode.L;
    [SerializeField] private GameObject _collectibleImage = default;
    public override void OnItemInteracted()
    {
        //this is a notice for the canvas, to display a UI showing the interaction key
        OnInteractThresholdReached?.Invoke();

        if(Input.GetKeyDown(_interactKey))
        {
            // Here I am trying to call the interact item action
            base.OnInteractedItem?.Invoke(this);

            _collectibleState = Collectiblestate.Collected;
            _collectibleImage.SetActive(false);
        }
    }
}

The problem is with this line right here on the StandardInteractable class:

base.OnInteractedItem?.Invoke(this);

I can't seem to invoke the Action from the parent class, and I'm not really finding any helpful information about it, because I don't want to subscribe StandardInteractable to the event, I want to Invoke it when the button is pressed.

Is this actually possible?

Thanks in advance for your help guys!

CodePudding user response:

Calling a class event in a derived class is not possible like that in C#. There is a common workaround for that by raising the base class event.

Simply create a method in BaseInteractable and invoke the event there. Then you can call this method from the derived class.

Here is the official MS explanation for that: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/events/how-to-raise-base-class-events-in-derived-classes

Update (added code example): BaseInteractable.cs

protected void RaiseOnInteractedItem(StandardInteractable standardInteractable)
{
    OnInteractedItem?.Invoke(this);
}

StandardInteractable.cs

if(Input.GetKeyDown(_interactKey))
{
    // Here I am trying to call the interact item action
    RaiseOnInteractedItem(this);

    _collectibleState = Collectiblestate.Collected;
    _collectibleImage.SetActive(false);
}
  • Related