Custom class reference not recognized

So, I have a gameObject Soil, which is a soil patch with below script attached to it (it is of class interactable), and a PlayerController which has the variable focus, which focuses on the nearest interactable. If i am near a soil patch and press E, which initiates “focussing”, so to say, this variable focus should point to the soil gameObject. This works! I can check the inspector and it is showing the soil patch gameObject.

Once I press an Item in my inventory (the item is a scriptableObject), I would like to use/consume it. I’ve got a base Item script from which scripts derive, such as the Compost Item, which is an Item I would like to use when near compost. Thing is, the compost script needs to recognize the soil patch, because I would like to change some properties of the soil from the Use() method within my Compost script. As of now, it does not, even though I’m quite certain I’ve done the referencing right. That’s where I would greatly appreciate some help. It must be a subtle easy-to-miss mistake or error due to me being a novice, haha!


Compost.cs (derived from Item.cs)

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    
    [CreateAssetMenu(fileName = "New Compost", menuName = "Inventory/Compost")]
    public class Compost : Item
    {
        public Interactable closestSoil = null;
        public GameObject playerObject;
    
        public override void Use()
        {
            PlayerController playerControllerScript = playerObject.GetComponent<PlayerController>();
            Interactable focus = playerControllerScript.focus; //MOST LIKELY, SOMETHING IS GOING WRONG HERE.
    
            Debug.Log(playerControllerScript.name);
            Debug.Log(focus is null);
    
            if (focus is null)
            {
                Debug.Log("No focus set"); 
            }
            else
            {
                if (focus.GetType() == typeof(Soil))
                {
                    Debug.Log("Reached loop");
                    closestSoil = focus;
                    Debug.Log("Now fertilizing the soil");
                    closestSoil.GetComponent<Soil>().fertilization += 1;
                    // Remove item from inventory
                }
                else
                {
                    Debug.Log("Focussed interactable is not of type Soil");
                }
            }
        }
    }

Item.cs (Compost.cs derives from this)

using UnityEngine;

[CreateAssetMenu(fileName = "New Item", menuName = "Inventory/Item")]
public class Item : ScriptableObject
{
    // new implies overwrite any existing definitions of 
    // name if present
    new public string name = "New Item";
    public Sprite icon = null;
    public bool isDefaultItem = false;

    public virtual void Use ()
    {
        Debug.Log("Using " + name);
    }
}

Interactable.cs (Soil.cs derives from this)

using UnityEngine;
using System.Collections;

public class Interactable : MonoBehaviour
{
    public bool isFocus = false;
    public bool hasInteracted = false;

    public virtual void Interact ()
    {
        Debug.Log("Interacting with " + transform.name);
    }

    void Update ()
    {
        if (isFocus && !hasInteracted)
        {
            Interact();
            hasInteracted = true;
        }
    }
}

Soil.cs is very straight-forward; it’s just an instance of the Interactable class with some basic variables (some ints and bools). Within my PlayerController script, focus is an Interactable, but not much more. If any of these scripts can help with finding the solution I’ll be glad to post them.

Thanks in advance! :slight_smile:

You most likely are dealing with the wrong object. So you may think that you have the right object but you may actually have the wrong one. You can use Debug.Log statements and provide a context object as second parameter. When you click on such a log message in the console, Unity will highlight that context object in the hierarchy view / project view. Maybe you linked a prefab where you need the actual object in the scene? That’s a common mistake.