Search Unity

Question Classes

Discussion in 'Scripting' started by junior333istall, Feb 25, 2023.

  1. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    Ive looked at a few videos on classes, some stuff i can understand and some things i have questions about. Now are classes only to declare like variables or something, where do i put the code where the variable actually does something. For example if I want to move a player where am i going to be putting code like this at? The only seemed to use variables like name, age, speed, and power and just assigned them integer values and string names but didnt write any code relating to what direction my player is moving, velocity and things like that. (sorry if dont understand what i really mean)

    Example of what i mean:
    Code (CSharp):
    1. PlayerRb2d.velocity = _moveDirection * 5;
    Also another thing i saw, sometimes what they declare isnt even really a class, its a method which i dont understand

    On movement controls in the link below isnt the void Movement() just a method not a class?

    https://learn.unity.com/tutorial/classes-5#

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class MovementControls : MonoBehaviour
    5. {
    6.     public float speed;
    7.     public float turnSpeed;
    8.    
    9.    
    10.     void Update ()
    11.     {
    12.         Movement();
    13.     }
    14.    
    15.    
    16.     void Movement ()
    17.     {
    18.         float forwardMovement = Input.GetAxis("Vertical") * speed * Time.deltaTime;
    19.         float turnMovement = Input.GetAxis("Horizontal") * turnSpeed * Time.deltaTime;
    20.        
    21.         transform.Translate(Vector3.forward * forwardMovement);
    22.         transform.Rotate(Vector3.up * turnMovement);
    23.     }
    24. }
     
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,934
    In a class.

    Methods go in classes/structs. Classes/structs have members. These 'members' can be just about anything else. Fields, properties, methods, delegates, even more class/struct declarations.

    Every component you write is a class. They just all happen to inherit from Monobehaviour.

    I'm genuinely confused by what you're confused about. I feel like you're over-thinking things.
     
    Bunny83 and All_American like this.
  3. All_American

    All_American

    Joined:
    Oct 14, 2011
    Posts:
    1,528
    Think of "MovementControls" as your class....Like @spiney199 said.....declare all your stuff there. in time you will get more confident in creating classes that do not inherit from Monobehavior. Monobehavior is where you interact with Unity game objects. Although you can still interact with them in a non-mono class....but for now just stick to mono's until you're more comfortable.
     
  4. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    The videos i saw werent using monobehavior and were talking about constructors.
     
  5. All_American

    All_American

    Joined:
    Oct 14, 2011
    Posts:
    1,528
    You might want to start off with the beginners stuff.

    You can declare variables inside of methods. Those are variables that are local to the method, you won't be able to access them outside the method. Within the classes outside methods you can declare global variables/properties.
     
  6. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
  7. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    In Unity there are two different "types" of classes. That MovementControls thing you posted is technically a class, but we think of it as a "script". It goes onto an object in the scene, or on several (you drag it on). The variables speed and turnSpeed are for that object. If it goes on more than one, they each get copies. Update and Movement are things the script can do to the object its on. Instead of "script", some people call that a Monobehavior (since that word comes after the name).

    The other type of class -- the ones with constructors -- is something you probably won't write for awhile. You can just write:
    Code (CSharp):
    1. class spellFacts {
    2.   public int age, speed, power;
    3.   public string name;
    4. }
    All that does is group those things. If you want 3 spells you don't need to declare as much. Just declare 3 spellFacts:
    spellFacts s1, s2, s3;
    . Each one has all 4 variables in it. You can set s1.name="frogify"; or s2.name="counterspell"; and s2.power=7;. Later, when you write functions dealing with spells, you can write functions the normal way, or can put them inside the class. Most people the inside way. But it's a trick to organize lots of repeating data, so only makes sense after you've had to play with that stuff.
     
  8. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    thanks, i understand now
     
  9. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    also does it make a difference if you put a class inside or outside the main one
     
  10. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    4,005
    I think this is the pivot point of your confusion.

    A class declaration defines a new type. A class defines both, fields that an instance of that class will have as well as methods / executable code that is bundled with the class. That's what a class is and that's what OOP is about. To combine data and executable code in one unit. Unity specifically has some "magic" callback methods like Update, OnEnable, Awake, Start, .... which are automatically called by the Untiy engine when an instance of that class is attached to an object in the scene. That's the main entry point of your own logic. Update is called every frame.

    How you structure the logic inside your class is up to you. In the example you posted they defined a private method Movement (a private method can can only be accessed from within code in the same class) to split up the code into logical chunks. So they may add additional methods which may also be called from Update. That way it's easier to read / follow the logic. Methods can give a chunk of code a specific name and purpose. Functionality wise you could cram everything that should be executed every frame in Update. But that makes it harder to understand and follow what it happening. That's why we may split up code into separate methods.

    You can declare separate classes inside another class, however this only make sense in rare cases. Such a nested class is still just its own separate class. The outer class would act like a namespace. So when you want to use that nested type / class outside the class, you would need to use
    OuterClassName.NestedClassName
    . The main difference is, that a nested class, which "lives" inside the scope of the outer class, has access to private members of the outer class. Note that this just applies to the visibility in general, not to a specific instance of that class. So an instance of the nested class can simply access any private member of any instance of the outer class. That's essentially the main difference. As I said you rarely would define nested classes. Nested classes are usually closely related to the outer class and directly belongs to the outer class. You usually would not define a nested class when it's meant to be used separately from the outer class. So the only reasons for a nested class is either: internal usage, so the nested class is only used inside that class itself for internal purposes in which case that nested class could even be private and is not visible / accessible from the outside or the nested class needs direct access to internal structures of the outer class in order to fulfill its purpose.

    I would highly recommend to learn some general C# basics. A programming language is also just a language. However it differs from human languages that the ratio between syntax rules and vocabulary count is usually reversed. Human languages usually have just a couple of syntax rules which also aren't that strict in many cases but have a huge number of words / vocabulary. Programming languages usually just have a hand full of vocabulary but a much larger and stricter set of syntax rules. The vocabulary of C# is just this. A lot of the keywords may have different meaning depending on the context where they are used. So based on the syntax / structure of the code.

    Keep in mind that there's a difference between the bare language itself and predefined framework classes and types. There are some overlapping areas (such as alias type names like
    string
    for
    System.String
    ,
    int
    for
    System.Int32
    , ...). There are also some exceptions where a keyword is directly linked to a certain framework type. The only case I can think of at the moment is the IEnumerator / IEnumerable interface type and the yield keyword which may be used in Unity to implement coroutines.

    The available predefined types of the framework and other libraries can quickly get overwhelming (System.Collections.Generic.List, UnityEngine.MonoBehaviour, System.Action and many other types). Though it's important to distinguish or at least identify what is "just another type" and whats actually part of the language itself.

    So when working with Unity you face those 3 things you need to learn:
    • The C# language itself, or at least the most important syntax rules and general structure
    • Common useful framework types.
    • Unity specific types (usually in the UnityEngine namespace or a subnamespace) and how they work together with the engine core.
    When you're completely new to programming or the concept of OOP those things can be overwhelming and confusing. How easy it is to learn the language, the framework, the engine depends on your pre-knowledge and how well you can identify which parts belong into which category. Learning the C# language of course can be split into several parts as well. An important part is that you define your own types. Those are classes, structs, delegates, enums and interfaces (can't think of more at the moment).

    It's important to understand the concept of "scope" and context. As a general rule any nested block (pair of opening and closing curly bracket) can access things in the outer block. However blocks which are just next to each other are isolated from each other.

    We could write pages over pages of basic C# introduction, but it's difficult to explain things in a way so every level of pre-knowledge would understand it. Learning usually requires practise and repeating. Unfortunately there's no really linear x-step-program what you should learn in which order. Every person learns different. Though programming does not have any room of interpretation. The compiler is the most brutal and pedantic teacher you ever had. That's why it's important to learn the basic structure. The great thing about programming languages is that it's much more structured and logically compared to human languages which usually have tons of exceptions to certain rules. That means once you really understood the structure, you're good to go.
     
  11. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    So should i always be using methods for different thing? like a method for movement, a method for spawning objects, or a method to collide with another object. Ive just been really using methods generally for when the same line of code is repeated.
     
    Last edited: Feb 26, 2023
  12. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    Write new methods/functions whenever you think it would help. They don't "do" anything like IF's or variables. Their only purpose is to make things easier for you.

    There are a few ways to think of them. One way, as you wrote, is to avoid having to repeat the same code in many places. Another is to keep Update from being too long -- we can write functions to move a chunk of code out-of-the-way. It will only be called from Update, one time, so doesn't save anything; but it makes the program easier to read, so it's fine.

    Some people like to pre-write empty or very small methods for Move, Shoot, Follow, anything they can think of. That way they can write the real program faster. Other people say that's a waste of time since you're going to delete or change them, so only write new methods when you go "hey, I've used this same code in a few places now" or "gee, Update sure is getting long and hard to find things in". Sometime if there's part of the program that seems really tricky, people write it in a method so they can test it easier (with a call in Start, or when you press "Z"). Basically, remember you can write whatever methods you like.
     
    Bunny83 likes this.
  13. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    Whats spells? Are you talking about the spellFacts?
     
  14. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    You mentioned 4 variables: name, speed, age, and power. You didn't say what they were for, so I figured it was to describe a magic spell. Suppose we had 3 spells. We could make twelve variables (four for each spell): s1Name, s1Speed, s1Age, s1Power, s2Name, s2Speed, .... s3Age and finally s3Power. Uggg. So instead we could create the SpellFact class. That lets us declare a spell, like
    spellFact s1;
    we're declaring all four things we need for a spell at once, and it's easier to see we're declaring a spell. Later, we can even have functions that have a spell as input or output.

    That's the basic idea of a normal class that we make to organize data. And you probably won't have any use for one for a long time.
     
  15. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    Wouldnt it be good to know early on though since it seems to be a big fundamental of c# and OOP. In another post Repeating Names, someone suggested i should instead of making different scripts that assign one role like PlayerMovement i should have one script like Player that has different classes that does all the roles like PlayerMovement PlayerCollisions and things like that
     
  16. All_American

    All_American

    Joined:
    Oct 14, 2011
    Posts:
    1,528
    You can do that if all the players are the same type of player. But if you have a player that is different...then that player would be another class. Kind of like naval ships....there's different classes for different types of vessels. Destroyers...Battleships....cruisers. They're all ships(namespace), but different classes of ships.

    Check this out. https://refactoring.guru/design-patterns/factory-method
     
  17. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    I feel like ship types are the opposite problem -- it's too simple to require a fancy set-up. Making a class for Move and Shoot and so on is to let you mix&match different plug-in classes to make each ship type. But a ship is just speed, acceleration, damage, turnRadius and a few other things. You wouldn't plug in a different Move() class for a battleship, you'd just lower those values.
     
  18. All_American

    All_American

    Joined:
    Oct 14, 2011
    Posts:
    1,528
    I was just using that as a basic comparison. Although I would use their own classes as there could be a lot of differences between different ships. Unless you broke it down to numbers of engines and different types of weapons….and so on.
     
  19. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    I think Ima just do what i was doing splitting it into different scripts, but if I see something or theres a problem and it would be better to use a class I'll come here to see.
     
  20. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,934
    Every separate script (specifically, monobehaviour) you write is a class, you realise?

    Everything in C# happens inside of classes or structs.
     
  21. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
  22. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,934
    Just thought I'd point that out because "different scripts" and "use a class" are the same thing.
     
    All_American likes this.
  23. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    It's hard to understand because all the videos I see with classes and websites, even unity are using constructors. Not saying I would prefer constructors (that stuff looks madly intimidating). These small details, I can understand like what yall mean by ships and then you have the different types and you have a spell and all the stuff to make the spell. I would probably have to visualize it not by words but by like youtube videos and maybe some other things.
     
  24. All_American

    All_American

    Joined:
    Oct 14, 2011
    Posts:
    1,528
    @junior333istall i still sometimes use a white board to visually see it. There’s nothing wrong with scrum and creating work flows or process flows to get yourself organized.
     
    Last edited: Mar 1, 2023
  25. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    If you just started writing a game in Unity -- even though you don't understand constructors -- what bad thing do you think would happen?
     
    mopthrow likes this.
  26. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    nothing too bad i would probably say.I'm just saying for in the fututre it would probably be good to know how to use classes.
     
  27. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    Here are some basics to hopefully help you understand the basic vocabulary of classes and class members:

    A class defines an object.

    It's like the blueprint for an object; it contains all the information about what they are like and what they can do.

    Here is an example of a class:
    Code (CSharp):
    1. public class Chicken // <- here we define a class named "Chicken"
    2. {
    3.     // this is the "body" of the class
    4. }
    In C# you can use the new operator to create instances of a class.
    Code (CSharp):
    1. var firstChicken = new Chicken(); // <- this code creates one instance
    2. var secondChicken = new Chicken(); // <- and code creates a second one
    3. var thirdChicken = new Chicken(); // <- after this line is executed there are three chicken instances
    You can optionally define a constructor in the body of a class
    Code (CSharp):
    1. public class Chicken
    2. {
    3.     public Chicken() // <- this is a constructor
    4.     {
    5.  
    6.     }
    7. }
    When a new instance of a class is created, any code contained inside the body of the constructor is executed.
    Code (CSharp):
    1. public class Chicken
    2. {
    3.     public Chicken()
    4.     {
    5.         Debug.Log("A new chicken was born."); // <- this is executed when a new instance of Chicken is created
    6.     }
    7. }
    You can optionally add parameters to a constructor.
    Code (CSharp):
    1. public class Chicken
    2. {
    3.     public Chicken(string greeting) // this constructor has a parameter of type string
    4.     {
    5.         Debug.Log(greeting);
    6.     }
    7. }
    You can pass other objects to an object that is being created using a constructor that has parameters.
    Code (CSharp):
    1. var firstChicken = new Chicken("First!");
    2. var secondChicken = new Chicken("I'm second!");
    3. var thirdChicken = new Chicken("Last :(");
    You can define class members of different kinds inside the body of a class, such as:
    • Constructors (contain initialization logic)
    • Fields (hold values and references to other objects)
    • Properties (allow other objects read values of fields)
    • Methods (contain logic)
    Code (CSharp):
    1. public class Chicken
    2. {
    3.     private int hunger; // < - This is a field. Because it's private other classes can't see it or touch it.
    Code (CSharp):
    1. public class Chicken
    2. {
    3.     private int hunger;
    4.  
    5.     public int Hunger // <- This is a property. Because it's public other classes can see it.
    6.     {
    7.         get => hunger; // The property has a getter. It lets other classes get the value contained in the "hunger" field.
    8.     }
    Code (CSharp):
    1. public class Chicken
    2. {
    3.     private int hunger;
    4.  
    5.     public int Hunger
    6.     {
    7.         get => hunger;
    8.     }
    9.  
    10.     public void Feed() // This is a method. Because it's public other classes can call it.
    11.     {
    12.         hunger--; // When a method is called the code inside its body is executed.
    13.     }
    14. }
    The Chicken class does not inherit from any other class. Such a class is called a plain old class object (POCO).

    If we wanted to create more animals of different kinds, all of which can be fed just like the Chicken, we'd have to repeat a lot of code.

    We can avoid this by defining a so-called base class (a class that other classes inherit from).
    Code (CSharp):
    1. public class Animal
    2. {
    3.     private int hunger;
    4.  
    5.     public int Hunger
    6.     {
    7.         get => hunger;
    8.     }
    9.  
    10.     public void Feed()
    11.     {
    12.         hunger--;
    13.     }
    14. }
    When we define a class that inherits from the Animal class, that class will inherit all the member defined in the body of the Animal class.
    Code (CSharp):
    1. public class Chicken : Animal { }
    2. public class Cat : Animal { }
    3. public class Dog : Animal { }
    Unity has a class named "GameObject" and a class named "Component".

    These classes have been coded in such a way, that you can attach instances of the Component class into instances of the GameObject class.

    A method called "AddComponent" is defined in the GameObject class which can be called on a GameObject instance to create a new instance of a component of a certain type and attach it to the GameObject instance.
    Code (CSharp):
    1. public class GameObject : Object
    2. {
    3.     // You can imagine all the components that have been attached
    4.     // to a GameObject being stored in a private field inside of it.
    5.     private List<Component> attachedComponents = new List<Component>();
    6.  
    7.     public TComponent AddComponent<TComponent>()
    8.     {
    9.         var component = CreateNewComponent(typeof(TComponent));
    10.         attachedComponents.Add(component);
    11.         return component;
    12.     }
    13. }
    Unity has also created a base class named "MonoBehaviour" which inherits from the Component class.

    The MonoBehaviour class defines some additional members on top of the ones defined in the Component class, such as the StartCoroutine method.

    Unity users can create new components that can be attached to GameObjects by deriving from the MonoBehaviour base class.
    Code (CSharp):
    1. public class Player : MonoBehaviour
    2. {
    3.  
    4. }
    Unity has designed the Component class in such a way that they should only exist as part of a GameObject to which they have been attached. To remind us of this fact, they have added some code to the constructor of the MonoBehaviour class to print a warning to the Console if we create an instance of it directly using the new keyword instead of using the AddComponent method on the GameObject class, and letting Unity handle creating the instance internally.
    Code (CSharp):
    1. public class MonoBehaviour : Behaviour // <-- class definition
    2. {
    3.     private bool isBeingCreatedUsingAddComponent; // <- field
    4.  
    5.     public MonoBehaviour() // <- constructor
    6.     {
    7.         if(!isBeingCreatedUsingAddComponent)
    8.         {
    9.             Debug.LogWarning("You are trying to create a MonoBehaviour using the 'new' keyword.  This is not allowed.  MonoBehaviours can only be added using AddComponent().");
    10.         }
    11.     }
    12. }
    So to create a new instance of the Player class, you need to do it by calling the AddComponent method on an instance of the GameObject class.
    Code (CSharp):
    1. var gameObject = new GameObject("Player");
    2. var player = gameObject.AddComponent<Player>();
    Because Unity does not allow instances of classes that inherit from the Component class to be created using the new keyword directly, it's not possible to use it to pass other objects into a component instance via its constructor.

    What we can do instead is to attach components to GameObjects in scenes and prefabs in Edit Mode, and then use the Inspector to specify what objects to assign into serialized fields.
    Code (CSharp):
    1. public class Player : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     private Sword sword; // <- drag-and-drop any instance of the Sword class here
    5.  
    6.     [SerializeField]
    7.     private Armor armor; // <- drag-and-drop any instance of the Armor class here
    8.  
    9.     [SerializeField]
    10.     private int health = 100; // <- you can adjust the value of the health field
    11.  
    12.     private int Health
    13.     {
    14.         get => health; // <- allows other objects to see the value of the health field, but not modify it directly
    15.     }
    16.  
    17.     public void Attack(int damage) // <- methods can also have parameters
    18.     {
    19.         damage -= armor.Rating;
    20.         health -= damage;
    21.     }
    22.  
    23.     private void OnCollisionEnter(Collision collision)
    24.     {
    25.          if(collision.TryGetComponent(out Enemy enemy)) // you can call public methods on instances of other classes
    26.         {
    27.             enemy.Attack(sword.DamageOutput) // pass the value returned by the DamageOutput property on Sword class to the Attack method on the Enemy class.
    28.         }
    29.     }
    30. }
     
    Last edited: Mar 3, 2023
  28. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    Hmmm ... where's POCO from? For example POD is from old C++ -- a "plain old data" class, and I use it somewhat often. It describes things like Unity's Vector3 where the point is to be 3 simple floats plus useful functions on them (as opposed to a real class with hidden-internals + interface). It's a good term to say, for example "Quaternion's expose x,y,z and w but that's only for experts. It's not really a POD class".

    I'm wondering in what environment do we need to know a class doesn't inherit, leading to that POCO shorthand?
     
  29. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,934
    I mean... In Unity I suppose? There's a distinct difference between UnityEngine.Object derived classes, and those that aren't. I've always used POCO or similar to describe a class that isn't derived from Unity's core asset type.
     
    Kurt-Dekker likes this.
  30. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    This plus the class shouldn't contain any business logic, at least by my thinking of it.

    It is pure data and possibly getters / setters, but nothing that decides to set something... no intelligence.
     
  31. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,934
    Ah, I would include C# objects that do include functionality into the POCO definition.

    I mean how often do you have an object that's nothing but wrapped data (and constructors I suppose)? I can count about... three instances where I've done that (all very small
    readonly struct
    s).

    Like I would call a
    Vector3
    a POCO, by my definition.
     
  32. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,745
    I do it to tidy up functions that take more than one or two arguments or perhaps strongly belong together.

    By now you know I'm a huge fan of doing things one step at a time.

    Code (csharp):
    1. var input = new InputDamage();
    2.  
    3. input.damageAmount = finalDamageAmount;
    4. input.damageType = incomingType;
    5. input.damageLocation = enemy.position + enemy.forward * 1.0f;
    6.  
    7. ApplyDamageToEnemies(input);  // could even take some out
    8.  
    9. ApplyDamageToStatics(input);
    And if it returned a big old
    CombatResults
    structure, that would be another POCO.

    I tend to use those a lot to keep things tidy.

    Sometimes the InputDamage will have a ctor() for the core must-have bits, or it will have some factories to make common flavors of the InputDamage, but often not, I'll just build it up one step at a time.

    EDIT: here's some POCOs from the crater generation on the lunar level:

    Code (csharp):
    1. // file CraterPOCOs.cs:
    2. using UnityEngine;
    3.  
    4. public class CraterSpecification
    5. {
    6.     public Transform parent;
    7.     public Vector3 position;
    8.     public float radius;
    9.     public Material mtl;
    10. }
    11.  
    12. public class CraterLocation
    13. {
    14.     public Vector3 position;
    15.     public float outerRadius;
    16.  
    17.     public CraterLocation( Vector3 _position, float _outerRadius)
    18.     {
    19.         position = _position;
    20.         outerRadius = _outerRadius;
    21.     }
    22. }
    Parts of the spec get decided by different parts of the procgen: size, appearance, etc, and then they are all blasted out to the geometry maker once the complete list has been deconflicted and adjusted.
     
    Last edited: Mar 3, 2023
    spiney199 likes this.
  33. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,331
    The term plain old class object is a derivative of plain old Java object.

    Yeah I think this is actually more accurate than saying it shouldn't inherit from any classes.

    I think the main idea is that it's a simple class that doesn't use any fancy frameworks (like Unity's component system).
     
    Kurt-Dekker and spiney199 like this.
  34. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    I guess. But in practice I feel like we do it the reverse way. We call out writing a Monobehavior/Script or a Component. Otherwise we say simply "class" for a normal class (which is what you'd call a POCO class, I think).

    After the rest of the discussion ... I write a lot of Components whose only job is to add some data to a gameObject -- like 3 public fields and nothing else. Those feel like not actually POCO's (inherit from special framework class), but honorary ones (since they're simple).
     
    All_American likes this.
  35. orionsyndrome

    orionsyndrome

    Joined:
    May 4, 2014
    Posts:
    3,113
    @spiney199 Just wanted to correct you, hopefully to your benefit, that delegates aren't class members, they're class peers.

    These are known as 'type declarations', all top-level
    class
    struct
    interface
    enum
    delegate

    The fact that people typically declare a delegate inside a class is similar to how you can nest classes. There are certain patterns where you absolutely need to declare delegates as standalones, however.

    Reference: §13.7 Type declarations
     
  36. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    Okay so would an example of a class be like after hearing all your explanations be something like if I had multiple movements on different gameObjects can I create a class that contains all these movemnts. Like a player movement function inside the movement class and the same thing with an enemy movement inside the movement class? And put those in my player class and my enemy class?
     
  37. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    1,998
    Suppose you had several variables for the player's movement, and the exact same ones for the monsters'. And you noticed that the functions dealing with them were all the same. And you further noticed that as you improve the player's movement you always wanted to add the exact same improvements to the monster's. You'd realize "hey, I'm writing the same stuff twice, with double the work and double the chance for mistakes". Turning that into a class would be one way to make a shared version of the variables and the functions playing with them.

    But in most player vs. computer-mob cases it won't be that way. Don't force classes. For real the player's movement will be something like the monster's but with dozens of small changes. The player&monster movement class would need piles of confusing "if is-player/is-monster" and turn into a messy time-wasting piece of junk.
     
  38. junior333istall

    junior333istall

    Joined:
    Jan 11, 2023
    Posts:
    101
    Okay, thanks