How would I add a method to all gameobjects?
I'm sure a lot of this is not the correct way to do things, but I'm just getting started with C# and with Unity, so please bear with me on this one.
I'm trying to implement a simple "use" system so players can press E while looking at a gameobject and have it execute the "use" method stored on that gameobject. I have a very simple version of it working that turns a cube red when a player looks at it and presses E.
The issue I'm running into is that in order to even attempt to call the use() method I have in a script, added as a component to this cube, I have to guarantee to the compiler that the use() method exists, by first searching for the component containing the use() method via
gameObject.GetComponent<ColorChangeBlock>()
This would work fine if I wanted each and every usable item to act identically when used.
So I need to know how I can make this work. I think ideally I'd like to create a "useable" class with an empty default use function and have every gameobject extend that, but I'm not sure how I would go about doing that.
I'm very likely going about this all wrong, and I would love it if someone with more knowledge on the subject could help me out.
Answer by phxvyper · Jun 17, 2016 at 02:47 AM
What you're looking for is probably Inheritance.
Have something along the lines of:
public abstract class UsableItem : MonoBehaviour {
// Abstract fields, properties and methods HAVE to be overriden by an inheriting type.
public abstract void Use() {}
}
public class ColorChangingItem : UsableItem {
public Renderer Renderer { get; private set; }
void Start() {
Renderer = GetComponent<Renderer>();
}
// Override the abstract method
public override void Use() {
// Set color to black on player use.
Renderer.material.SetColor(Color.black);
}
}
public class MovingItem : UsableItem {
// Override the abstract method
public override void Use() {
// Move this object up .5 units every time the player uses it.
transform.Translate(new Vector3(0f, 0.5f, 0f));
}
}
And now you can attach MovingItem and ColorChangingItem to ANY GameObject, just like a normal Component/Script/MonoBehaviour. Then, when your player uses the item do:
UsableItem item = usedItem.GetComponent<UsableItem>();
if (item) item.Use();
And the method call will be dispatched accordingly to the overridden Use function, if any.
...Side Note... Instead, you could use SendMessage:
usedItem.SendMessage("Use", SendMessageOptions.DontRequireReceiver);
However, this uses .NET Reflection, which is significantly slower than simply null-checking the component, like I did above.
Answer by a1steaksa · Jul 06, 2016 at 01:14 AM
Hey, @phxvyper thanks for the help.
Edit: Except never mind that's my bad I wasn't doing
public class ColorChangeBlock : UsableItem {
Thanks again!
I'm just now back at trying to implement this and I'm getting an error with my color change and moving item code where it's telling me that
`ColorChangeBlock.Use()' is marked as an override but no suitable method found to override
Any clue what would cause this?
The entire code for the color change block is
public class ColorChangeBlock : MonoBehaviour {
public override void Use() {
gameObject.GetComponent<Renderer>().material.color = Color.red;
}
}
With my UsableItem code being
public abstract class UsableItem : MonoBehaviour {
public abstract void Use();
}
Your answer
![](https://koobas.hobune.stream/wayback/20220612083116im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Activating Scripts in another Script? 2 Answers
Changing the order of Components 9 Answers
How to expose other components fields 0 Answers
New UI - Referencing deep nested components on an prefab instantiation 1 Answer
Depth of Field 1 Answer