Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

its possible to derive reference of gameobject/component from abstract class to all chiled classes??

Discussion in 'Scripting' started by halevi, Feb 9, 2022.

  1. halevi

    halevi

    Joined:
    Dec 13, 2020
    Posts:
    35
    if i have abstract class with lets say 5 chiled classes and i want to assign certain game object/component reference from the abstract class to the chiled classes that related to all or most of the chiled classes how i can do this without to make this certain field public in the abstract class and assign the component to each chiled class by drag and drop in the inspector ? i can't simply derive this to all chiled classes from the abstract now since from what I know i can't assign component/gameobject to field in abstract class because abstract class not active in the scene, so there is different way that i can derive gameobject/component refernce from abstract class without to assign reference to each chiled class separately in the inspector ?
     
  2. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Your question is a little hard to understand, but you can absolutely define a reference in an abstract base class that carries over to your derived classes.

    Code (csharp):
    1.  
    2. public abstract class MyBaseClass : MonoBehaviour
    3. {
    4.    [SerializeField]
    5.    protected GameObject gameObjectReference;
    6. }
    7.  
    8. public class MyDerivedClass : MyBaseClass
    9. {
    10.    // gameObjectReference will be visible in the inspector when you add this component to a GO
    11. }
    12.  
    If you don't want to assign it manually through drag and drop, there's always Reset or OnValidate where you can write code to automatically assign it.
     
  3. halevi

    halevi

    Joined:
    Dec 13, 2020
    Posts:
    35
    hi thanks (i'm working on my english probably because of that its a little hard to undestend me)maybe I will use onvalidate or reset to pass the references directly to the abstract class, and yes i I know that i can define the object reference in the abstract class and then manually drag this,this is what I did , I thought I could somehow to pass an references of object/list of objects directly to the abstract class (even without to catch references with onvalidate or reset because its still seems a little cumbersome to me)and than derive these refernces in the chileds clasess directly from the abstract class(like parent non abstract class).
     
  4. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    Could you share what you're trying to do in more concrete terms? Like what gameplay systems you're trying to create?

    A derived class has full access to any public or protected methods and members on the base class. If the base class wants to keep that reference private, you can expose protected or public methods that interact with it:
    Code (csharp):
    1.  
    2. public abstract class MyBaseClass : MonoBehaviour
    3. {
    4.    private GameObject gameObjectReference;
    5.  
    6.    protected void AssignReference(GameObject go)
    7.    {
    8.        gameObjectReference = go;
    9.    }
    10.  
    11.    protected void ProcessReference()
    12.    {
    13.        if(gameObjectReference != null)
    14.        {
    15.            // do whatever
    16.        }
    17.    }
    18. }
    19.  
    20. public class MyDerivedClass : MyBaseClass
    21. {
    22.    public void OnPlayerClicked(GameObject target)
    23.    {
    24.        AssignReference(target);
    25.    }
    26.  
    27.    public void Update()
    28.    {
    29.        ProcessReference();
    30.    }
    31. }
    32.  
     
  5. halevi

    halevi

    Joined:
    Dec 13, 2020
    Posts:
    35
    Code (CSharp):
    1. public abstract class MyBaseClass : MonoBehaviour
    2. {
    3.     // even it was public field you need to drag and drop reference to each child
    4.     private GameObject gameObjectReference;
    5.  
    6.     // how you pass the argumant reference to assignReference method/from where
    7.     protected void AssignReference(GameObject go)
    8.     {
    9.         gameObjectReference = go;
    10.     }
    11.  
    12.     protected void ProcessReference()
    13.     {
    14.         if (gameObjectReference != null)
    15.         {
    16.             // do whatever
    17.         }
    18.     }
    19. }
    20.  
    i have certain gameobject that i need to use it in all chiled classes to , i need the ability to control on his position from all chiled clasess and more things that i need to control on this go runtime, in your example you initilize the gameObjectReference by passing argumant to AssignReference method in the abstract class , how/from where you pass this argumant ? and even if gameobjectrefernce field in the abstract class was public i stiil have the question how you inithilize this gameobject reference field In the abstract class itself without having to drag and drop reference to each chiled in the inspector or use on validate/reset, the point in my question its not how the chiled clasess have access to the abstract class variables methods atc i know that the chiled clasess have access to it but how in the abstract class they inithilize
     
  6. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,528
    To me it seems you kind of confuse what a class and what an object is. Your line of reasoning sound like you come from a language that has prototypical OOP and not class based OOP. A class just defines the structure of a type and is seperate from an instance of that class. References stored in variables is data and therefore part of the object / the instance and not the class. Inheritance is just about inheriting the structure on the class level.

    What you seem to be asking is if you can provide a single reference "somewhere" once so all instances of child classes would have that data available. However that's like assuming if you could give Lucy a wooden stick into her right hand and assume all decendents would have that same stick already in their hand when they are born. Yes, real world analogies are lacking a bit, but hopefully you get the point. A class just defines the structure, memory layout and what methods a class has. A class can define default values for variables but they have to be constant values that are available at compile time. Also such values are simply part of the contructor / field initializer code that runs when an instance is created.

    An abstract base class can not have an instance (that's one of the points of having an abstract class). Since there is no instance of such a class, there is no memory that could store a reference. Also seperate instances of the same class are completely seperate entities. They only share the same structure and memory layout, but each instance has its own memory area where all of the variables live.

    Well, there's an exception to this rule and that is static variables. Static variables / fields actually do not belong to an instance of a class but essentially belong to the class itself. Static variables are not "inherited" as there is no seperate memory space in derived classes. Static variables are simply global variables that do not belong to any object or instance. They belong to the class scope, so a private static varaible may only be accessed from a method inside a class, but the variable itself is seperate from the instance.

    Static variables are not serialized and can not be edited in the inspector (since the inspector is about inspecting objects / instances).

    You can use static variables to make a single reference be shared among all instances, however you have to initialize that reference yourself somewhere in code once. Also the usage of static variables should be minimized as they make testing and reasoning about your code very difficult. Common patterns when several objects need access to a central single object is to use the Singleton pattern.
     
    halevi likes this.