Unity uses a Component Base Object Management approach. There's a famous article about it in Game Programming Gems 5.
In a few words suchs systems put the accent on Composition over Inheritance. Any object or type (in this case GameObject
) is defined as a collection of Components
, each one responsible for a specific domain. When you want to add functionality to an object, you'll add a Component
instead of extending it. (a full exposition of CBOM is beyond the purpose of this thread, but search for it on the web)
So for what concern your question and unity patterns in general:
Unity Extending Game Object best practice
The sentence above makes no sense. In fact you never extends GameObjects, but eventually MonoBehaviors that are Components (actually they inheritance chains is MonoBehavior
->Behavior
-Component
).
I would like all GameObject to be able to change color IF they have a
renderer
I'd say you want to change the color dispkayed by every Render Component
that has a Material
that allows that.
Ive tried using a helper class that takes a GameObject and lerps the
color value but if i want it to have an update method it must inherit
MonoBehaviour, and if it does inherit it then i cant instanciate that
helper class.
Here you are on the right way. The only thing you are missing is how to extend an operation (color lerp
) over multiple frames. In fact you don't need to rely on the Update
callback (in a certain way it would even be wrong or at least inefficient). You should use a coroutine for that.
So you helper class simply becomes a method (for this I usually put a collection of static methods like this in a static class that act as my helper class):
IEnumerator LerpColorInSeconds(float sec, Material m, Color newCol)
{
float t = Time.deltaTime;
Color startColor = m.color;
while (t < sec)
{
material.color = Color.Lerp (startColor, newCol, sec / t);
yield return null;
t += Time.deltaTime;
}
material.color = newCol;
}
when you need to lerp a color of a Material from inside a given MonoBehavior:
StartCoroutine(LerpColorInSeconds(1f, renderer.material,Color.black));
For more details on coroutines have a look here.
EDIT
Sorry for the mistake. StartCoroutine isn't a GameObject method but belongs to MonoBehavior. So for what concern your question on extension methods: in order to use StartCoroutine method you need a reference to a MonoBehavior. I don't think use an extension method is a particularly good idea here, btw you can't add an extension method to GameObject because it's not a behavior itself.
If you want to extend MonoBehavior:
public static class Extension
{
public static void LerpColor(this MonoBehaviour g, Color col, float lerpTime)
{
if (g.renderer != null)
{
g.StartCoroutine(LerpColor(lerpTime,g.renderer.material,col));
}
}
}