1
\$\begingroup\$

I was wondering if it was possible to use the existing native components inside Unity to extend them, and create my own.

For instance, if I wanted to create a component called Hurtbox, could I maybe do something like this?

class Hurtbox : BoxCollider2D { ... }

That would allow me to use the existing logic of the component and enhance it for my purposes.

Currently I have a separated BoxCollider2D and a Hurtbox components. The latter uses the former, but I thought if I managed to combine them both in a single one, it would be more elegant.

Is it doable? How?

\$\endgroup\$
  • 1
    \$\begingroup\$ Have you tried to simply extend the classes? I would imagine that it should work in a simple C# manner, but I've never done this before. \$\endgroup\$ – Jesse Williams Sep 12 '16 at 20:22
  • \$\begingroup\$ Though you would likely have to extend your editor for new values as well. I think this is why the expectation is to clump things together onto a GameObject and consider the GO as a single entity with multiple components. \$\endgroup\$ – Jesse Williams Sep 12 '16 at 20:23
  • \$\begingroup\$ It is not that I can't test this. I know it can't be done this way. What I'm asking is if there is any way of doing this. \$\endgroup\$ – Enrique Moreno Tent Sep 13 '16 at 6:37
  • \$\begingroup\$ what are you talking about? of course you can do it that way. Again, simply testing on your behalf would have gone a long way, here. \$\endgroup\$ – Gnemlock Sep 13 '16 at 22:31
3
\$\begingroup\$

It's absolutely possible to extend existing components in the way you describe. Take for example my extension to add a onHold event to the normal unity button.

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Events;
[AddComponentMenu("UI/Hold Button")]
public class HoldButton : Button
{
    private bool isBeingPressed;
    private float currTime;
    private static float TimeMax = 1;
    private bool startTimer;
    public ButtonHoldEvent onHold { get; set; }
    public override void OnPointerDown(PointerEventData eventData)
    {
        startTimer = true;
        currTime = 0;
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        startTimer = false;
        currTime = 0;
        isBeingPressed = false;
    }
    void Update()
    {
      if(startTimer)
        {
            currTime += Time.deltaTime;
            if(currTime >= TimeMax)
            {
                isBeingPressed = true;
            }else
            {
                isBeingPressed = false;
            }
        }
        if (isBeingPressed)
        {
            onHold.Invoke(); 
        }
    }
    public class ButtonHoldEvent : UnityEvent
    {
        public ButtonHoldEvent() : base()
        {

        }
    }
}

With this code I get all the features of a normal button with the added onHold functionality that I needed.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I got this message on my editor: Assets/Scripts/Hurtbox.cs(8,14): error CS0509: "Hurtbox": cannot derive from sealed type "UnityEngine.BoxCollider2D"' \$\endgroup\$ – Enrique Moreno Tent Sep 16 '16 at 17:52
  • \$\begingroup\$ Well yes BoxCollider2D seems to be sealed and this prevents other classes from inheriting from it. You can try and inherit Collider2D and implement that. \$\endgroup\$ – Uri Popov Sep 17 '16 at 7:23
  • \$\begingroup\$ With Collider2D I didn't get the warning of "sealed type", but it did also not appear on the Component List. This is my code: hastebin.com/esiraroxot.cs \$\endgroup\$ – Enrique Moreno Tent Sep 17 '16 at 10:15
1
\$\begingroup\$

It is possible, but I wouldn't take that approach, for two main reasons:

  1. If Unity folks change some underlying implementation later on, it may break functionality.
  2. You would probably need a custom editor as well.

But instead, you can make custom components and add RequireComponent attribute at the top of your class. You will eventually end up with two components instead of a single extended one (and a bit of tight coupling), but you will save yourself from some headaches in the long run.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I wanted to make the binding the CustomComponent and its derived component more tight. Imagine I want to derive BoxCollider2D in 2 Components: Hitbox and Hurtbox. If I use RequireComponent I would end up with 2 BoxColliders and the scripts can get fuzzy about which one to use. That is why I wanted to extend the native ones. \$\endgroup\$ – Enrique Moreno Tent Sep 16 '16 at 17:56
  • \$\begingroup\$ @Dbugger I can't say I understand, RequireComponent doesn't add component instance if there is already one on GameObject. But instead, extending the component and adding two derived componnets essentially means double components, because each component is also the type of component you derived from. \$\endgroup\$ – S. Tarık Çetin Sep 17 '16 at 7:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.