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

Add Properties to a GameObject

Discussion in 'Scripting' started by ThySpektre, Jul 22, 2019.

  1. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Hello.

    This is related to previous thread here:

    https://forum.unity.com/threads/adding-a-method-to-a-game-object.656557/
    https://forum.unity.com/threads/interfaces-vs-events.699092/

    In a related question. Since Unity does not treat GameObjects like objects, how would one create a "property" of the game object, not of a component of the object.

    If I have a GameObject that is to report it's state to a Game Manager at regular intervals, and this state is split among variables in the many components implementing the functionality, is there a kludge similar to using Interfaces to obtain method fucntionality that allows these variables to be grouped together for reporting out?

    Something that does not involve one of the compoents having a listing of GetComponent<"scriptname"> statements in order to access the various variables split among components (that should simply be properties of an inherited from GameObject)?
     
    Angelo13C likes this.
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    I think to change GameObject you'd need to change the Unity engine, which is not how you're supposed to use Unity.

    When in Rome, do as the Romans do. Unity is a component model at the scripting level: GameObjects accept any number of MonoBehaviors (and indeed Components if you want to be pedantic)... those can implement any number of interfaces you want.

    With helpers such as FindObjectsOfType and GetComponent and GetComponentsInChildren, etc. you can find all your such things and check if they are the interface you're after, then bang on them appropriately.
     
    tcmeric likes this.
  3. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    You don't. Game objects do not have many attributes, that's the point. You have to make components that report the values you want. Suppose you want to report the position of an enemy AI. In that case, you can either have the manager fetch all the enemy AI scripts, or you can have each script report to it.
    Think of it this way: the game object class is just a handle. It isn't a representation of the enemy. The enemy component is what makes it an enemy. This lets you partition your game logic into different, potentially overlapping systems.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,711
    And this is even moreso true with the ECS/DOTS. An 'entity' is really just an index number in a stream of data, not really an entity per se, certainly not a GameObject. Check out some of the Unity ECS/DOTS talks by Mike Acton.
     
  5. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Having all scripts report to it is what I am doing currently. Except each object needs its own manager, as the states required are not all located within the same Component. Once one component gathers them all up (and thus that component needing to know about all the other components on the object) it can then report that object's info to the game manager. Not a very Object Oriented approach. IMO.

    Yeah, I get it. Unity GameObjects aren't normal objects. They don't represent things.

    If all logic that makes it an "enemy" is located in one component...

    Or look for kludges to bypass this limitation in Unity. Interfaces work adequately for adding methods to GameObjects. It appears this crosstalking of Components (which breaks good OOP IMO) is needed to represent a property, and even in that, not very well (a component name, or a separate "properties class" would be required for the Game Manager to access it).

    Thanks for the replies.
     
    Last edited: Jul 23, 2019
  6. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    Game object is special object type. It may contain components only. You can normalize your model so every component will handle single property value, but it's better to split them based on responsibilities. You'd better learn your tools prior attempting to use it in non supposed ways. or you'll lose a lot of time on useless attemtps.
     
    Kurt-Dekker likes this.
  7. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Yes, learning the tool is the reason for the post. Unity has a limitation that breaks good OOP design rules IMO by not allowing inheritance. As such GameObjects aren't objects. They don't represent things.

    By splitting values "based on responsibilities", the objects are left with important state information scattered about in various components. To set or report on the various properties of the object then requires these supposedly modular components to be aware of each other and communicate to achieve what should be a simple property of the object.

    I learned previously that GameObject methods can be simulated through the use of interfaces so that the internal structure of the GameObject did not need to be known externally in order to call a method on the GameObject. This could be extended to create Get and Set methods for the required values.

    I was hoping there was a better way.
     
  8. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    Actually, no. Unity uses well-known OOP components pattern. It prefers composition over inheritance. With inheritance, you add functions to classes by extending them, but with composition you make new classes by composing instances of old. It is just another approach to OOP design.It is just another approach to OOP design. GameObject is class for creating such compositions known as prefabs. Component is to implement functions. Stick to it and you'll be fine. You may use inheritance with components.
     
  9. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Actually yes. If I make a bicycle and remove the wheel, but keep the handle bars, it does indeed use well-known bicycle design, but people will still have to find a way around not having the wheel functionality. Such is the case with inheritance.

    "Sticking to" not having inheritance means finding ways to implement such functionality in other ways, and thus the point of the question.
     
  10. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    This way is long ago found in OOP theory. It is called composition. Instead of composing methods in classes creating inheritance hierarchies, you compose components within containers. Unity design is not something new or different in the world of OOP. It is based on best practices know for few decades already. You should push yourself to understand that instead of trying to break in with your undestanding of what is right and what is wrong based on limited knowledge (you said you just learning, right, i mean no any harm)?
     
  11. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    Sigh. I don't know why you think that pure OOP is better than the paradigm used across the entire games industry and many other sectors of the programming industry. OOP is not the only thing that exists, and is actually an ancient paradigm that is mostly used today because of legacy systems and how easy it is to teach beginners. OOP is about 60 years old. It is one tool and you are trying to use it for everything. The sooner you accept that all of the experts in the games industry are not randomly lying to you for some reason, the sooner you will be able to grow and join their ranks. Use of component based design is not something you have to "kludge" around. The problem is that you are trying to use a hammer when everyone around you is saying your really should be using a wrench. Sure, you can tighten a bolt with a hammer if you try hard enough, but that's a crazy way to solve the problem.
    Here's a more lengthy discussion of the criticisms of OOP if you care:
     
    Kurt-Dekker and tcmeric like this.
  12. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    Why you people alway contrapose OOP and unity component system? Unity component system is a good example of OOP design, why do you think it is not?
     
    tcmeric and lordofduct like this.
  13. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Still wondering why you refuse to work with a component type which does what you're looking for and which wraps around all the stuff you need. This will solve your problem and you'll be free to subclass it as often as you like until you recognize deep hierarchies are not the best way.

    OOP is not just defined by inheritance, inheritance is one optional tool in OOP languages.

    Composing any number of components to build a more complex system is just as valid as implementing all sorts of variants using inheritance, difference being that complex hierarchies have often enough proven to lead to bad architectural decisions, code duplication, issues with responsibilities and such.

    You keep claiming that Unity breaks good OOP design. But apparently, it really doesn't in this particular case.

    At the same time, you're saying you'd spread all of the information among multiple components which have to know each other... This may already indicate something could be wrong with the design decisions you've made, but we cannot tell for sure unless you post some examples.
     
    tcmeric, Ryiah and lordofduct like this.
  14. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    o_O

    GameObjects are objects... not sure how they're not.

    The only reason you can't do what you want is because the GameObject class is 'sealed':
    https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sealed

    C# has tons of sealed classes... string for instance is sealed. It too is a regular old object.

    ...

    As for how you do what you ask. The same way everyone has been repeating in all your threads.

    Create a component, put the "property" on that, and access it as follow:
    Code (csharp):
    1. theGameObject.GetComponent<MyScript>().MyProperty = 5;
    This is a "is a" vs "has a" argument in OOP (inheritance vs composition).
    https://www.google.com/search?q=oop...0j69i57j0l4.3063j0j4&sourceid=chrome&ie=UTF-8

    Unity's GameObjects embrace a "has a" design. Get used to it. It's proper OOP.
     
    Ryiah likes this.
  15. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    I spent a good part of a career writing procedural based code in assembly. OOP is not the only thing that exists, but it is a great tool for what it is, a way to encapsulate functionality.

    Who said anyone was lying, randomly or otherwise?

    And you can drive in a nail with a wrench. That's why a well rounded toolkit contains both, and when faced with a nail and only being presented a wrench, it seems reasonable to ask how others are kludging their way around not having a hammer.
     
    Last edited: Jul 23, 2019
    DragonAngel1st likes this.
  16. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Or the design decision Unity made, but we can't know more without understanding better what's under the hood.
     
    Last edited: Jul 23, 2019
  17. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    How about this @ThySpektre...

    Could you show us a code example of what you'd want to do via inheritance? Give us an idea of the design you wish you could do.
     
    Ryiah and ThySpektre like this.
  18. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    It's a subset of proper OOP, and the only one available here. Fortunately there are kludges that allow for a proper OOP functionality in cases where inheritance is the correct answer. Such is the reason for the question.

    Interfaces allows for such a functionality for methods. They can also be used to obtain this functionality for properties. I was hoping there was a better way.
     
  19. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    I think you're very much hung up on inheritance...

    You should go check out the language 'Go', it may open your eyes to how inheritance can actually be defined as a subset of composition.
     
    xVergilx and Ryiah like this.
  20. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Let's extend the previous example. In it I wanted to be able to "reset" various GameObjects to their state at the start of the level.

    How a window, player, gun, ball, dog, etc reset vary so greatly in implementation that making a "Reset" component that I attach to each of them would be difficult to maintain and not very useful. Therefore I must make variation of the reset component WindowReset, PlayerReset, GunReset, etc That implement these and attach them to their respective objects. Create an interface that defines a Reset contract, and make sure my various components implement that...

    Likewise, those windows, players, guns, etc have properties I would like to access. The case in point was a case where I would like to access the "state" of the objects on a regular time interval. What that state is, is different based on the object. My main program really doesn't need to care about what data is involved for that particular object's state, nor what internal component structure makes up that object. I would like to be able to access the GameObject's "state" property.

    Without being able to create such a property for the GameObject, I can find ways to work around it. The "kludges".

    One example was given above, where the main program DOES concern itself with the internal structures of the object:

    theGameObject.GetComponent<MyScript>().MyProperty = 5;

    Another would be to again encapsulate the GameObject property functionality desired inside an Interface, using Get and Set contracts. The internal object would still need a component that knows about it's various components in order to grab and package the info, but it would work.
     
  21. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    I mean... in your examples, even with inheritance, there's a need to know more about the GameObject.

    Like this 'Reset' functionality... you'd do what? Create a 'ResettableGameObject'?

    Code (csharp):
    1.  
    2. public abstract class ResettableGameObject : GameObject
    3. {
    4.     public abstract void Reset();
    5. }
    6.  
    7. public class PlayerResettableGameObject : ResettableGameObject
    8. {
    9.     public override void Reset()
    10.     {
    11.         //reset player
    12.     }
    13. }
    14.  
    15. public class GunResettableGameObject : ResettableGameObject
    16. {
    17.     public override void Reset()
    18.     {
    19.         //reset gun
    20.     }
    21. }
    22.  
    We now need to know that GameObject "is a" ResettableGameObject.

    If we change over to an interface model and composition you get:

    Code (csharp):
    1.  
    2. public interface IResettable
    3. {
    4.     void Reset();
    5. }
    6.  
    7. public class PlayerObject : MonoBehaviour, IResettable
    8. {
    9.     public void Reset()
    10.     {
    11.         //reset player
    12.     }
    13. }
    14.  
    15. public class GunObject : MonoBehaviour, IResettable
    16. {
    17.     public void Reset()
    18.     {
    19.         //reset gun
    20.     }
    21. }
    22.  
    And now we just have a "has a" situation (The GameObject has a IResettable).

    Furthermore... you could have multiple Resettables easily since we're compositing them. So maybe you have a health script that ALSO needs to be reset. You just have each component implement IResettable and you just call it on all of them (get all components on the gameobject).

    Unity actually has a simple method that does this for you:
    https://docs.unity3d.com/Manual/MessagingSystem.html

    Code (csharp):
    1. ExecuteEvents.Execute<IResettable>(theGameObject, null, (c,o) => c.Reset());
    I personally was disatisfied with the shape of it and instead wrote my own:
    https://github.com/lordofduct/space...acepuppyUnityFramework/Utils/Messaging.cs#L14

    Code (csharp):
    1. theGameObject.Execute<IResettable>((c) => c.Reset());
    Or you could write your own extension method, or just inline it with 'GetComponents'.

    ...

    You could do the same as above.

    But in the same respect... I would argue you don't even need a reference to the GameObject. Why reference the GameObject when you could reference the component?

    Just like I said above:
    "We now need to know that GameObject "is a" ResettableGameObject."

    We need to know it's it. So you'll likely have some variable referencing your objects as that type:
    Code (csharp):
    1. public ResettableGameObject go;
    2. public List<ResettableGameObject> gos;
    Why not just have the variable reference the component?

    Code (csharp):
    1. public GunObject component;
    2. public List<GunObject> components;
    Now of course that's the concrete type GunObject... but you could do it as IResettable:
    Code (csharp):
    1. public IResettable component;
    2. public List<IResettable> components;
    Though interfaces gunk up the unity serialization engine (one of my gripes with Unity)...

    But you can use inheritance:
    Code (csharp):
    1.  
    2. public abstract class ResettableComponent : MonoBehaviour
    3. {
    4.     public abstract void Reset();
    5. }
    6.  
    7. public class PlayerObject : ResettableComponent
    8. {
    9.     public override void Reset()
    10.     {
    11.         //reset player
    12.     }
    13. }
    14.  
    15. public class GunObject : ResettableComponent
    16. {
    17.     public override void Reset()
    18.     {
    19.         //reset gun
    20.     }
    21. }
    22.  
    And thusly have:
    Code (csharp):
    1. public ResettableComponent component;
    2. public List<ResettableComponent> components;
     
    tcmeric, Stardog and Ryiah like this.
  22. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Yes

    This goes back to the earlier thread. We don't need to know anything more than "A ResettableGameObject is a ResettableGameObject"

    Actually we'd know that "A ResettableGameObject 'is a' GameObject", right? The reverse is not necessarily so.

    But the reason for why you would reference the GameObject is the same for why you would reference any object. The object is a representation, an abstraction, of the object you wish to model.

    Because the component does not represent the object, rather one aspect of the object.
     
  23. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    I think you're misunderstanding what I mean when I say you need to know the GameObject is a ResettableGameObject.

    You have to explicitly have a ResettableGameObject.

    Code (csharp):
    1. ResettableGameObject obj = *some ref*;
    Your variable is a ResettableGameObject, therefore you know it's a ResettableGameObject. You can't willy nilly treat a GameObject as ResettableGameObject, rather instead you have to explicitly have a ResettableGameObject.


    See my previous statement.

    But you don't want a reference to GameObject. You want a reference to ResettableGameObject.

    What's it matter if ResettableGameObject inherited from GameObject, or was a component of GameObject. Either way you can treat it as Resettable as well as access the GameObject aspects of it.

    Code (csharp):
    1. ResettableComponent component = *ref to component*;
    2. component.gameObject.name = "BLARGH";
    vs

    Code (csharp):
    1. ResettableGameObject go = *ref to ResettableGameObject which inherits from GameObject*;
    2. go.name = "BLARGH";
    If you KNOW it's a ResettableGameObject/Component, the access GameObject is trivial.

    And?

    It's a part of the object though... you still have access to the object since it's been composited by the GameObject.

    Hence the Component.gameObject property.
     
    Ryiah likes this.
  24. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Here's a concrete example I just ran into.

    I have a GameObject that can be active or not. We will call it "Blocker". The blocker reports its state out to the Game Manager, which consists of a boolean. It sends a signature of its state to the GSM (It consists of 1 boolean) at start and then reports it.

    Later I decide to make some blockers movable. I add a Component to the blocker object which scripts the movement and timing parameters. The state signature of this composited object is now 4 floats and a boolean.

    Same object type (blocker), completely different state signature, with parts of it spread across 2 components).

    With Inheritance I'd make a blocker and inherit from blocker to make a movingblocker.
     
    Last edited: Jul 23, 2019
  25. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Yes.

    Yes, as I said, a ResettableGameObject IS a GameObject. The reverse is not necessarily so.

    Because the GameObject is the abstraction of the object you are modelling. The component is not.

    No and. That's full stop.

    Sure, but when other functionality is within a different components of the object, Unity has left out:

    Component.gameObject.mindreadingWhatOtherComponentIsNeeded.
     
  26. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    So what's wrong with:

    Code (csharp):
    1.  
    2. public class Blocker : MonoBehaviour
    3. {
    4.  
    5. }
    6.  
    7. public class MovingBlocker : Blocker
    8. {
    9.  
    10. }
    11.  
    ???

    Personally I would avoid this since I don't know why a MovingBlocker is necessarily a Blocker as well... I'd personally have a "Mover" and a "Blocker", and because it has both it's a "Mover Blocker". So that way we have 3 permutations... Mover, Blocker, Mover Blocker.

    BUT

    If you want inheritance...

    What's wrong with MovingBlocker inheriting from Blocker?

    And Blocker reports its "signature" (whatever you mean by that) to the GSM.

    ...

    Also... what do you mean by "state signature"? Are you generating signatures based on the fields it has?

    OK... so instead of your signature being:
    Code (csharp):
    1.  
    2. {
    3.     field1,
    4.     field2,
    5.     field3
    6.     ...
    7. }
    8.  
    It becomes:
    Code (csharp):
    1.  
    2. {
    3.     component1: {
    4.         field1
    5.     },
    6.     component2: {
    7.         field2,
    8.         field3,
    9.         ...
    10.     }
    11. }
    12.  
    It's a signature... so what.
     
    Ryiah likes this.
  27. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    You know what...

    whatever.

    You clearly have your own specific view on how things MUST work, and you just ignore all other options thrown out there.

    You want an answer to your problem, yet you dismiss all answers.

    I don't know what you expect for an answer other than "enable inheriting from GameObject"... in which case.

    NO.

    FULL STOP.

    Peaces bro.
     
    Ryiah, Suddoha and Kurt-Dekker like this.
  28. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    I'm not sure why you choose to answer questions if you are going to become so emotionally invested in proselytizing "a wrench". This was a problem on a previous thread as well.

    The parameters of what were desired were spelled out fairly well in the original post.

    For methods, a kludge exists that enables inheritance like functionality for GameObjects via Interfaces. They can likewise be extended to kludge properties as well. However, it's not a one-kludge-fits-all situation always.

    Occasionally there are more than one way to skin a cat. I was looking for alternatives to interfaces to implement property functionality on GameObjects. I haven't seen one in the thread yet, so it is likely I will implement it through interfaces as well.
     
  29. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    smh

    I'm not emotionally proselytizing a wrench.

    I'm saying we're in Unity where GameObjects are wrenches.

    Yep... and I served up MULTIPLE.
     
  30. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    You served up some suggestions that did not provide the desired functionality.

    In a related question. Since Unity does not treat GameObjects like objects, how would one create a "property" of the game object, not of a component of the object.

    If I have a GameObject that is to report it's state to a Game Manager at regular intervals, and this state is split among variables in the many components implementing the functionality, is there a kludge similar to using Interfaces to obtain method fucntionality that allows these variables to be grouped together for reporting out?

    Something that does not involve one of the compoents having a listing of GetComponent<"scriptname"> statements in order to access the various variables split among components (that should simply be properties of an inherited from GameObject)?
     
  31. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    You clearly have a very flawed concept of what OOP is, the nomenclature within OOP, and much much more. The mere fact you insist over and over that GameObjects aren't objects is just a clear sign you have no clue what you're talking about.
     
  32. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Yes, I can see your lack of emotionalism.
     
  33. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,124
    It's rare that I read a thread and have the immediate desire to squelch someone before I've even responded to any of their posts but you're definitely succeeding. To be blunt, if you care about inheritance to the point that you are willing to neglect every other aspect of OOP, then (aside from being a bad programmer) you've chosen the wrong game engine.

    Unreal 4 is a game engine that is focused around inheritance. It's the game engine you should have chosen. Go there.
     
    lordofduct likes this.
  34. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    How does your GameObject know what functionality you have glued to it in order to know what signature to report out?
     
  35. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    It's called its component list.
     
  36. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    What? But I've read all though this thread how poor a design choice inheritance is. It's a wonder anything gets published in that engine. (chuckle)
     
  37. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Which some manager component of the object is supposed to keep track of and decide how to construct the signature?
     
  38. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,124
    GameObjects are basically just an object with a list. AddComponent adds a reference to the component to the list.
     
  39. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    :: looks through thread ::

    I only see people telling you that Unity "prefers composition over inheritance"... having a preference isn't necessarily saying inheritance is a poor design choice.

    No... the GameObject keeps track of the component list. That's the job of GameObject. It is the controller that all components get "glued" to.

    Your GameManager just has to sniff the GameObject for its components and build the signature from that.

    I mean honestly... how were you planning on building the 'signature' in the first place with inheritance? (What the f is a signature anyways? What an arbitrary term.)
     
  40. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    I'm speaking of the values forming the state of the gameobject spread throughout the various behavior components. You would need some type of manager component on each gameobject that the various components could register with to let it know what values it was providing.
     
  41. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    No you wouldn't.

    Why would you need that?

    Are you talking about creating a save state, and the need to create a token for your objects that can be saved and loaded?

    OK... create an 'ISaveable' interface, loop all ISaveable components of the GameObject, hand it your serialization container and let it write its state into it.

    For load do the same but call the 'Load' method, handing in the serialization container, which it reads its state from.

    Again... how were you planning on doing this using inheritance?
     
  42. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,124
    No, you don't need a "manager" component. You simply try to GetComponent the component you need values from and if it exists then you read the appropriate variables.
     
    lordofduct likes this.
  43. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Really??

    It is simplicity itself with inheritance.
     
  44. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    I didn't say describe A way... I was saying describe YOUR way.

    How were YOU going to do it.

    Because yes... it's simple. It's simple with inheritance, it's simple with composition. Yet you seem to be unable to understand how it gets done with composition. So I wonder... what were your plans in the first place?
     
  45. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Each of the various components has a number of values that needs saved at regular intervals. I would like the object to report out the signature of its state (number of booleans, into, floats, etc.). Then on a regular interval report out the values of each to the Game Manager.

    Finally, I would like the ability for the Game Manager to send this state information (in the same format) and have it distributed to the various components. With inheritance, all of these values exist as properties of the same object.
     
  46. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Yes... but how would you do that with inheritance? What does your code look like? How does your GameManager know what type the object is? How does it know what properties are on those types? Or is it that the GM doesn't know, and rather the object knows its field? In which case what does it matter if it's a component or a child class... the component knows its own fields and can report to the GM?

    How about you share us some pseudo-code of your proposed design?
     
  47. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    Unity design is not something new or different in the world of OOP. It is based on best practices know for few decades already.

    Sigh. I don't know why you think that pure OOP is better than the paradigm used across the entire games industry and many other sectors of the programming industry. OOP is not the only thing that exists, and is actually an ancient paradigm that is mostly used today because of legacy systems and how easy it is to teach beginners. OOP is about 60 years old. It is one tool and you are trying to use it for everything. The sooner you accept that all of the experts in the games industry are not randomly lying to you for some reason, the sooner you will be able to grow and join their ranks.

    This will solve your problem and you'll be free to subclass it as often as you like until you recognize deep hierarchies are not the best way.
     
  48. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Unity doesn't block inheritance, except for from GameObject. Just like the .net/mono framework as a whole has several 'sealed' classes you can't inherit from (string). Unity does prefer coposition with its GameObjects based on best practices discovered over decades. This does not mean inheritance is bad... it means composition is considered a best practice.

    Driving from Florida to New England I can take many ways. I-95 is usually considered a best practice as its the most direct an efficient route (barring terrible traffic). Scooting up I-26 to I-85 is still a suitable route and I've taken it many times to side step the Baltimore to NYC metro area. It may not be the preferred route as it adds a couple hundred miles... but it's not a poor/bad route (also it would allow me to stop in and say hi to my grammy in PA!).

    Where as taking I-10 to LA, I-5 to Seattle, and then I-90 back across to Massachusetts is a bad route.

    Not being the preferred isn't bad... bad implies extremely bad choices like driving 10,000 miles out of your way.

    I'd argue either this person doesn't realize composition is part of OOP... or they're saying "pure OOP" in the context of your repeated statements about being all about the "pure OOP" and since you keep talking about inheritance, then you must mean pure OOP requires inheritance rather than options it.

    Nothing about this though says that inheritance is bad... it rather is saying your insistence on foregoing composition is dragging you down from "joing their ranks".

    This statement clearly doesn't bang on inheritance. Rather instead is demonstrating how you can setup something so as to get subclasses.

    They do tack on the "deep hierarchies are not the best way"... saying deep hierarchies are bad doesn't mean inheritance is bad. It means DEEP HIERARCHIES are bad.

    Just like how driving 10,000 miles out of your way to get from FL to NE is bad. Driving there isn't necessarily bad... driving through LA and Seattle is (long distance synonymous with deep hierarchies).
     
    Suddoha and Ryiah like this.
  49. Ryiah

    Ryiah

    Joined:
    Oct 11, 2012
    Posts:
    20,124
    If the object is already responsible for creating a list of variables then you may as well make it responsible for collecting the values into a format that can be quickly saved to a file. A process that could literally be done with one line of code for each.

    https://docs.unity3d.com/ScriptReference/JsonUtility.ToJson.html
    https://docs.unity3d.com/ScriptReference/JsonUtility.FromJson.html
     
  50. ThySpektre

    ThySpektre

    Joined:
    Mar 15, 2016
    Posts:
    362
    The GM knows nothing about the objects except what it reports out.

    Each GameObject would have:

    GetStateSignature() method that returns a fixed-size array of integers representing the number of the various base data types it stores. (bool, int, float, string)
    ReceiveState(ReplayState state) method

    The GameManager has a method:

    SendState(GameObject go, ReplayState state)

    which is called from the various GameObjects.

    A list of GameObjects for which states are to be stored is kept in the GameManager. The size of the data is already unwieldy despite significant optimization for which a good deal of it is indexing for which object the data is associated with.