2
\$\begingroup\$

I am designing a physics class library for Unity and would love to be able to hook and inject functionality into Unity's Rigidbody class, but it's my understanding that there is no way to do this directly while still being able to target all platforms.

I thought the next best thing might be to create a new class that inherits directly from Rigidbody. However, it looks like Unity has prevented this from occurring in anything but the UnityEngine namespace by requiring the internal sealed ExtensionOfNativeClassAttribute on anything that inherits native classes. Furthermore, Unity does not serialize inherited classes well.

So, in review, I'm not able to hook into Rigidbody directly (please correct me if this is wrong!), and I'm not able to inherit from Rigidbody directly (please correct me if this is wrong as well!). I think the next best option is to:

  1. Create a new Monobehavior, let's say it's called ModRigidbody, which makes a parallel implementation of all of Rigidbody's members. This class does not actually inherit from Rigidbody, but merely has members with all the same names/signatures as Rigidbody.
  2. On ModRigidbody add the attribute [RequireComponent(typeof(Rigidbody))]. Now I can add functionality to some ModRigidbody's members as I see fit, and have other members simply 'pass through' to transform.GetComponent<Rigidbody>().
  3. Have any end users (programmers) change all of their references to Rigidbody over to ModRigidbody.

To me, this feels quite sloppy. Is there a way to mod the functionality of Rigidbody so that future users of this library will not have to change all of their Rigidbody over to ModRigidbody?

\$\endgroup\$
5
  • 2
    \$\begingroup\$ Unity generally favours a composition over inheritance approach. So if the target audience for your library is Unity developers, they'll be used to interacting with separate components rather than a single component that's a superset of some inherited functionality. If all you need to add are methods as syntactic sugar over the existing API, you can do that with extension methods without inheritance. For other use cases, it would help if you clarify what new functionality your ModRigidbody provides. \$\endgroup\$
    – DMGregory
    Mar 30, 2023 at 16:37
  • \$\begingroup\$ What does your physics library do? How is it different from the built-in physics? \$\endgroup\$
    – Kevin
    Mar 30, 2023 at 18:08
  • \$\begingroup\$ @DMGregory My use case is a bit complicated. A simplified version: I am interested in taking all forces applied to one rigidbody and re-applying those forces to another 'entangled' rigidbody. The reference to the entangled rigidbody would be added state. This added state would not be exposed or managed by the unity developer. \$\endgroup\$ Apr 5, 2023 at 13:32
  • \$\begingroup\$ @Kevin See my above comment. \$\endgroup\$ Apr 5, 2023 at 13:32
  • \$\begingroup\$ Edit this into your question. Do you need to support a mix of bodies that have entanglement in this way and bodies that don't? Or is it expected that 100% of all Rigidbody interactions will be going via this entangled path? \$\endgroup\$
    – DMGregory
    Apr 5, 2023 at 16:39

1 Answer 1

3
\$\begingroup\$

Unity doesn't generally allow extending its built-in classes. But, if you mean to add functionalities to a standard class rather than overriding some, you can use C# Extension Methods: they allow you to add features without creating a new derived type. You can find a well-written guide on Extension Methods in Unity on the GameDeveloper website.

Instead of using, say, a helper class that forces you to write ugly code like this:

GameObjectHelper.WannabeInstanceMethod(gameObject, someArgument);

you can instead extend a class' functionalities with EMs and get a nicer function call signature:

gameObject.WannabeInstanceMethod(someArgument);

Declaring An Extension Method

Create a non-generic, non-nested static class, and add a static method whose first argument has the this keyword referring to the calling data object:

public static class GameObjectExtensions
{
    public static void WannabeInstanceMethod(this GameObject gameObject, int argument)
    {
        // Implementation goes here
    }
}

Though declared as static, this will be invoked as if it were an instance method:

gameObject.WannabeInstanceMethod(someArgument);

You will find many examples on the internet about how to use Extension Methods in your code. Beyond GameObjects, you can also use EMs on Vectors and Lists, as explained in this blog post by MonoFlauta.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .