Firstly I understand about MonoBehaviour and how to add it (like attach) to a gameObject using AddComponent.
However in this scenario where I just need a class inheriting from MonoBehaviour and don’t use any methods of MonoBehaviour. The class needs to inherit from MonoBehaviour because I have a MonoBehaviourExtension (implementing C# extension methods). I want to use these extension methods on both MonoBehaviour and my class. To avoid duplicating all the extension methods for separate unrelated classes, I managed to let my class inherit from MonoBehaviour.
Everything works just fine except the ugly warnings complaining about creating new MonoBehaviour using new keyword. I don’t want to use AddComponent here because my class has a Queue<> to manage some coroutines. The class instance does not need to be referenced every time, so all its members including the Queue<> will be garbage-collected at some time. When adding my class instance as a component of gameObject, I think there is no chance for the Queue to be collected even when it’s no longer used. As far as I know we can only disable component but cannot remove it, so the reference may be still alive and there won’t be any garbage collection job.
Another dirty solution is turn all my MonoBehaviour extension methods into Behaviour extension methods and let my class inherit from Behaviour instead (using new to create a new Behaviour does not give any warning). But then the extension methods may be called on any Behaviour (although almost are MonoBehaviour). It also does not look nice when my methods require a MonoBehaviour (to use StartCoroutine, …) but they can still be used (called) on Behaviour (which may not have StartCoroutine, …).
I’ve experienced that giving a warning can cause some performance drop when the frequency of generating is high enough. In this case my methods are not used too frequently. So performance is not a very important issue. I would like to know about other possible issues. In my point of view, everything looks best now except the warnings. The next best choice is using AddComponent (to remove warnings) but all the gameObject having my extension methods called on will keep a reference to my Component (which keeps a reference to a Queue) even when it may no longer be used.
Hello!
I don’t know of anything specific, but Unity’s warning seems pretty stern and you are likely incurring undefined consequences that may become very difficult to uproot. For example, it’s possible that a MonoBehaviour registers itself somewhere deep in Unity’s internals in such a way that it will end up keeping a reference to it indefinitely since it doesn’t actually exist as a component attached to a gameobject that will get de-allocated when that object is destroyed. Just my speculation there but I think it’d be a very bad idea to ignore this warning.
It sounds to me like there’s some concepts getting mixed here. If the extension methods require a MonoBehaviour, then obviously that’s what you should extend; but if they don’t then it sounds more like your extending the wrong thing. Since you are trying to reuse extension methods for different types of objects but are also needing to extend them regardless of whether or not they are MonoBehaviours (i.e. regardless of the type of object, which contradicts the initial premise) then I think what you want to be doing is extend off an interface that both your MonoBehaviour and… non-MonoBehaviour objects implement.
Also, you can indeed remove a component by calling the Destroy() method and passing a reference to the component itself (as opposed to it’s gameObject).
Anyways, extending an interface would be my first suggestion.
Cheers!
I’d also suggest its a bad idea. No particular reason why. I just like to follow the rules and generally can’t stomach ignoring warnings and errors.
This is the heart of the issue. Why are you extending MonoBehaviour if the extension methods don’t belong on MonoBehaviour? There may be another way to accomplish your functionality that doesn’t involve extending MonoBehaviour.
I thought about using some kind of interface here but I would like to use my extension methods on the standard MonoBehaviour. If using interface I have to let all my components inherit from my own MonoBehaviour version (which inherits from MonoBehaviour). That requires a bit of editing and changing MonoBehaviour to such as MyMonoBehaviour every time creating a new script (from Unity). I’ve now ended up with using AddComponent. Some ones here (including you) told about how to remove component by using Destroy, which I never knew before (I thought it would destroy the attached gameObject), so it would be a better way. Thank you for your opinion.
I think using extension methods is a totally different thing. You can call all the extension methods on the native standard MonoBehaviour (not my own MonoBehaviour). That means I can use my extension methods inside any other component script (just by this.MyMethod()). In fact the idea of creating extension methods for MonoBehaviour is just because it has StartCoroutine and it’s also attached to some gameObject and transform. My methods do some simple animating on the attached gameObject (such as transitioning, scaling, fading …). So creating extension methods for MonoBehaviour is the right direction.
It just does not stop there, I would like to sequence the calls (some kind of fluent syntax in jQuery) like this:
this.SlideTo(…).FadeTo(…).Delay(…).ScaleTo(…);
All the after appended calls should be queued, that’s why I need some type (on which I can also use my extension methods as I can on MonoBehaviour) to wrap/contain all the necessary info (in this case it’s mainly the Queue).
It’s totally fine if I create my own MonoBehaviour here but as I said, I would like to use these methods on the standard base MonoBehaviour, it would be much more convenient. Thanks for your reply.