Custom GetComponent with Generic for nonmonobehaviour class?

Hi all
I have several classes(non monobehaviour) with some same fields.I need to access them into loops.
How can I implement GetComponent(generic) for them or convert my classes to monobehaviour classes?

You can’t attach non-component classes to game objects, so you can’t call GetComponent to get them. You make something inherit MonoBehaviour by adding " : MonoBehaviour" after the class name.

public class MyClassName : MonoBehaviour {

thx but I said “Custom GetComponent” using generic. suppose we implement in c# .net not unity.

Maybe I don’t understand what you’re asking. GetComponent already is generic:

var thing = gameObject.GetComponent<MyClassName>();

But you have to make your class a Component by implementing MonoBehaviour. That’s the only way to attach it to a game object, and GetComponent is for getting things attached to a game object.

This screams interfaces.

interfaces can’t contain fields. Sounds like a base class that inherits from monobehavior might be better if GetComponet is needed.

@mahdiii What is the purpose of these classes? Do they just contain data? Are they suppose to be attached to a gameobject?

Interfaces can contain properties. Which is close enough to fields as to not make a difference.

2 Likes

you don’t know my question:)
I said you forgot getcomponent function and unity. Suppose I write in c#(console application or winform) for one application.
I have some classes with some same fields(that are interface objects like IDisplayable,IAttackable,IMovable,…)
one class has (IDisplayable,IAttackable,IMovable), other class (IDisplayable,IMovable) other class (IAttackable,IMovable) etc
I know I can use interface inheritance like below instead of component based design pattern:

public class CSoldior1:IMovable,IAttackable{
public void Move(){

}
public void Attack(){

}
}

public class CSoldior2:IMovable,IAttackable,IDisplayable{
public void Move(){

}
public void Attack(){

}
public void Display(){

}
}
public class CSoldior3:IMovable,IDisplayable{
public void Move(){

}
public void Display(){

}
}

but it is not component based design pattern and can create duplicate codes (methods like move method etc)
So I would like to define interface fields into the classes:

public class Soldior1{
IMovable m_movable;
IAttackable m_attackable;
}
public class Soldior2{
IMovable m_movable;
IAttackable m_attackable;
IDisplable m_displayable;
}
public class Soldior3{
IMovable m_movable;
IDisplable m_displayable;
}

and loop for some method like below:

foreach(IMovable movable in MovableList){//Movablelist contain IMovable interfaces of different classes
movable.move();
}

Therefore I need to use custom getcomponent to access to special interface fields of different classes (for example all IMovable fields)
I read somewhere that we can use generics and dynamic to get components in classic classes.

I honestly don’t think you do either. :stuck_out_tongue:

Are you trying to duplicate the component architecture of Unity in pure C#? There is probably a library for that. In that case GetComponent will look something like this:

// GameObject analouge
public class ComponentContainer {
    List<Component> components ();

    public T GetComponent<T> () where T : Component {
        foreach(Component component in components){
            T componentAsT = component as T;
            if (componentAsT != null) return componentAsT;
        }
    return null;
    }
}

// UnityEngine.Component analouge. All components inherit from this
public class Component {
}

You’ll also need to make analouges for all the other useful methods Unity provides, such as AddComponent, GetComponents, Destroy and so on.

4 Likes

Perfect Thank you. it is really I want.
So I firstly need to create a component class and Movable,Attackable etc classes inherit from it. Then keep the list of the components and then access to them with custom getcomponent method.
Is it the only way to prevent duplicate codes(duplicate methods) in different classes and can loop for special method of classes?

Well, no…You can create a base class, have other classes inherit from the base class, and then create a list of the base class which you can loop through. The base class would define shared methods while the other classes would have code unique to them. Which honestly is no different then what you are trying to do…

public class Animal: Monobehaviour
{
   public void Move()
   { }
}

public class Dog: Animal
{ }

public class Cat: Animal
{ }

public List<Animal> myAnimals; //Can add dog and cat and loop through and access Move method.

You can then use GetComponent on Animal to get access to the shared code. You will have to cast it to get access to stuff unique to dog or cat, but that’s true of anything like this. Also note this allows you to put cat and dog on gameobjects in the scene.

plz read accurately, it was not my problem! yes in your simple example it is ok but I said I have several classes with some same object fields(components), if I use inheritance I will definitely have some duplicate codes(methods). it is the classic problem of inheritance

if your meaning is virtual or abstract functions like move in animal class, you need to override or implement it for all children that can create duplicate codes. So I prefer to implement components only one time and use them inside classes

No, you don’t duplicate move. It’s in the base class. That’s why your list is of type Animal and not cat/dog. You can clearly see I didn’t implement move in cat or dog and there is no override.

Technically, your base class can implement all your “components” and your other classes can inherit those as well.

@Kiwasi method will work just fine for you though, so no reason to worry about it if that is what you want.

1 Like

plz write more complete, I see only a move method in the parent and the children dog and cat have it

“Technically, your base class can implement all your “components” and your other classes can inherit those as well.”
you say we can implement all components in the base class and because the children inherit all components?!
I said one children has several components and the other children has different components with some same components
plz reimplement my classes soldiers above/ thx

my problem:
I have soldiers that have different types. all of them can move but differently (different implementation), some of them can attack but differently and some of them can display something but differently. hint: it is possible some soldiers move the same but attack differently or other combinations

What are you asking?

The set up you have with Soldier is good. It has a move interface field that you can access to make it move. You’re trying to come up with a generic way to get that interface? Or other interfaces like it?

1 Like

Why don’t you just use actual components? Just make them MonoBehaviours and drag and drop the ones you want onto the different soldiers.

2 Likes

For now this is probably the answer OP needs.

OP, I’ve learned one thing doing this for a year: it’s that Unity can handle hundreds of BS MonoB scripts. I mean it, hundreds. Some people just do whole involved games with every script being a MonoB all the way down to little trivial single-use things like a “destroy myself on command” script.

The key takeaway is that if a MonoB does not include an event-subscribing function (Update, FixedUpdate) it doesn’t get added to whatever call stack calls all those update event functions you write.

I know it seems like it will become unruly fast, but just keep separation of concerns in mind and “encapsulate” each script to its entity. For example let the UI require a plug reference to the player (for obvious usage); don’t write embedded logic in the player that updates the UI.

This is the pattern I like, personally.

Several interfaces. ISoldierMovement, ISoldierAttack, ISoldierDisplay. A soldier gets one script of each of these types. Think of interfaced scripts as sharing a type. You can even make new ones or change them on the fly. Each soldier has one MonoB, its MonoB calls some function updating each non-mono-behavior script.

The only thing this laves you high and dry on is that your interface scripts can’t start Unity’s coroutines. If you take the time to learn IEnumerable though, you can just do the same thing yourself.

1 Like

thank you all. yes with components it is ok but [Brathnann said we can use inheritance like above but I think it can generate duplicate codes

because I don’t need trigger functions like update,start,onEnable,etc. I don’t want to inherit from monobehaviour only for using getcomponent. I maybe can use component unity class that has getcomponent function. The other problem is that you can only inherit from one class, my soldiers inherit from a base soldierBase class but it can be solved with inheritance branch : Monobehaviour->SoldierBase->Soldiers classes](https://forum.unity3d.com/members/brathnann.670510/)

Then don’t use them?

Soldier should be a prefab that is composed of the different components that a soldier would need to do soldier-like things.