- Home /
Script only running the code of the script it inherits from
Hey all!
I've hit a bit of a snag that I can't work out and some advice would be amazing. I have a script named Interactable which inherits from MonoBehavior and from the Interactable script I have subclass scripts which inherit from it.
I've just written a script for cutting down trees in the game called FellableTree which inherits from Interactable, I've attached the FellableTree script to the trees in my scene. For whatever reason the code within the Interactable script is being run but nothing within the FellableTree script is happening.
As the only script attached the tree prefabs is FellableTree it must be functioning to a degree as it's inheriting from Interactable just fine. Here are the scripts.
using UnityEngine;
public class Interactable : MonoBehaviour
{
public float radius = 2.7f;
bool isFocus = false;
bool hasInteracted = false;
Transform player;
public Transform interactableTransform;
public virtual void Interact()
{
}
public void OnFocus(Transform playerTransform)
{
isFocus = true;
hasInteracted = false;
player = playerTransform;
}
public void OnDefocus()
{
hasInteracted = false;
isFocus = false;
}
void Update()
{
if (isFocus == true && hasInteracted == false)
{
float distance = Vector3.Distance(player.position, interactableTransform.position);
if (distance <= radius )
{
Interact();
hasInteracted = true;
}
}
}
private void OnDrawGizmosSelected()
{
if (interactableTransform == null)
interactableTransform = transform;
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(interactableTransform.position, radius);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FellableTreeScript : Interactable
{
public int axeStrength = 2;
public Tree tree;
public override void Interact()
{
Debug.Log("Chopping down a ");
base.Interact();
FellTree();
}
void FellTree()
{
axeStrength++;
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
If you have any idea why this is happening I'd really appreciate it. Thanks for taking the Time to read this, you're awesome
How are you invoking Interact()
?
Also I feel like this is screa$$anonymous$$g for an interface for Interactable
, not a base class.
Thanks for responding so quickly.
I'm invoking Interact() through a script called PlayerController. a ray is cast from the main camera to the mouse pointer on right click to see if it hits anything with an Interactable script or a script that inherits from interactable.
If it has found an Interactable then PlayerController is storing a reference to that instance of interactable (or subclass) in a variable called focus. I've set that variable to public so I can see how it's being populated at runtime and it is getting the FellableTree script and not the interactable.
Also worth noting that I have other interactables that are working with this system just fine and I've tripple checked that I've got all the same code bringing the tree cutting scripts together as I do with the other interactables.
I'm pretty new to unity and scripting so I'll have to look into what you mean by an interface for Interactable.
Answer by Bunny83 · Feb 03, 2021 at 06:21 PM
Unity is calling all of its callbacks through reflection. You re - implemented the Update and Start method in your derived class therefore Start and Update of the base class will never run. When you use inheritance with MonoBehaviours you generally should implement the Unity callbacks as protected virtual methods and if you really need / want to implement an Update method in your derived class you have to call the base class method as well.
In other words your base class should look like this:
public class Interactable : MonoBehaviour
{
// [ ... ]
protected virtual void Update()
{
// [ ... ]
in your derived class you either don't implement Update at all or if you do, you should do:
public class FellableTreeScript : Interactable
{
// [ ... ]
protected override void Update()
{
base.Update();
// [ ... ]
}
// [ ... ]
Now Unity will call the new overridden method and inside that method we call the base method.
You're an absolute LEGEND! Thanks very much @Bunny83. That makes a lot of sense, I'll keep that in $$anonymous$$d moving forward.