proper way to initialize classes in unity?

so i got into a little problem with initialize in unity i properly never got it fully. but when i try to initialize a class and i got some information going through it doesn’t initialize the values?

 private PlayerStatLogic playerstat;

    // Use this for initialization
    void Start () {
        BasicClass NewClass = new BasicClass().Beginner();
        playerstat = GetComponent<PlayerStatLogic>();
        playerstat = new PlayerStatLogic();
      
        playerstat.PlayerHealth();
        playerstat.PlayerMana();
      


    }

and this is the class i have my values being set and stuff.

public class PlayerStatLogic : PlayerStats {

    public Slider healthbar;
    public Slider manabar;
    public Text playerlevel;
    public Text playername;

    public void PlayerHealth()
    {
        SetPlayerMaxHealth = GetBaseClassHealth;
        SetPlayerHealth = GetBaseClassHealth;
        SetPlayerCurrentHealth = GetPlayerHealth;

        Debug.Log("Max Health : " + GetPlayerMaxHealth);
        Debug.Log("Current Health : " + GetPlayerCurrentHealth);
        Debug.Log("Current Mana : " + GetPlayerCurrentMana);

    
    }

    public void PlayerMana()
    {
        SetPlayerMaxMana = GetBaseClassMana;
        SetPlayerMana = GetBaseClassMana;
        SetPlayerCurrentMana = GetPlayerMana;

        Debug.Log("Max Health : " + GetPlayerMaxHealth);
        Debug.Log("Current Health : " + GetPlayerCurrentHealth);
        Debug.Log("Current Mana : " + GetPlayerCurrentMana);

     
    }

    public float CalculateHealth()
    {
        return GetPlayerCurrentHealth / GetPlayerMaxHealth;
    }

    public float CalculateMana()
    {
        return GetPlayerCurrentMana / GetPlayerMaxMana;
    }

    public void DealDamage(float damagevalue)
    {
        SetPlayerCurrentHealth = GetPlayerCurrentHealth - damagevalue;
        SetPlayerCurrentMana = GetPlayerCurrentMana - damagevalue;
        Debug.Log(healthbar.value = CalculateHealth());
        Debug.Log(manabar.value = CalculateMana());
        Debug.Log("Current Health : " + GetPlayerCurrentHealth);
        Debug.Log("Current Mana : " + GetPlayerCurrentMana);
    }

    // Use this for initialization
    void Start () {
     
        SetPlayerLevel = 1;
        playerlevel.text = "Level : " + GetPlayerLevel.ToString();
        SetPlayerName = "Reaper";
        playername.text = GetPlayerName.ToString();
        Debug.Log("ClassHealth : " + GetBaseClassHealth.ToString());
        Debug.Log("ClassMana : " + GetBaseClassMana.ToString());
        Debug.Log("ClassType : " + GetClassType.ToString());

        Debug.Log(healthbar.value = CalculateHealth());
        Debug.Log(manabar.value = CalculateMana());
    }
 
    // Update is called once per frame
    void Update () {
        if (Input.GetKeyDown(KeyCode.X))
        {
            DealDamage(6);
        }
    }
}

but whenever i try to initialize the player class it wont set the values i have in playerstatlogic.
if someone can help me better understand how to initialize classes in unity i would be greatful.

oh and the last classes i got is purely used as a way ot storing values and creating ingame classes etc.

playerstats is just a bunch of get/set where as ClassStats is also a get/set for classes, i got a ton of inheritences

public class PlayerStats : ClassStats {

    private string _PlayerName;
    public string GetPlayerName
    {
        get { return _PlayerName; }
    }
    public string SetPlayerName
    {
        set { _PlayerName = value; }
    }

    private float _Health;
    public float GetPlayerHealth
    {
        get { return _Health; }
    }
    public float SetPlayerHealth
    {
        set { _Health = value; }
    }

    private float _MaxHealth;
    public float GetPlayerMaxHealth
    {
        get { return _MaxHealth; }
    }
    public float SetPlayerMaxHealth
    {
        set { _MaxHealth = value; }
    }

    private float _CurrentHealth;
    public float GetPlayerCurrentHealth
    {
        get { return _CurrentHealth; }
       
    }
    public float SetPlayerCurrentHealth
    {   
        set { _CurrentHealth = value; }
    }

    private float _Mana;
    public float GetPlayerMana
    {
        get { return _Mana; }
    }
    public float SetPlayerMana
    {
        set { _Mana = value; }
    }

    private float _MaxMana;
    public float GetPlayerMaxMana
    {
        get { return _MaxMana; }
    }
    public float SetPlayerMaxMana
    {
        set { _MaxMana = value; }
    }

    private float _CurrentMana;
    public float GetPlayerCurrentMana
    {
        get { return _CurrentMana; }

    }
    public float SetPlayerCurrentMana
    {
        set { _CurrentMana = value; }
    }

    private float _Exp;
    public float GetPlayerExp
    {
        get { return _Exp; }
    }
    public float SetPlayerExp
    {
        set { _Exp = value; }
    }

    private float _Level;
    public float GetPlayerLevel
    {
        get { return _Level; }
    }
    public float SetPlayerLevel
    {
        set { _Level = value; }
    }

    private BasicClassTypes _Class;
    public BasicClassTypes GetClassType
    {
        get { return _Class; }
    }
    public BasicClassTypes SetClassType
    {
        set { _Class = value; }
    }
  


}

What is PlayerStats? By which I really mean: is PlayerStats a class that derives from MonoBehaviour?

There are two kinds of classes in Unity: MonoBehaviours and everything else. “Everything else” should be initialized as you would in any other dev environment, e.g. with a constructor.

If a class ultimately inherits from MonoBehaviour, though, it’s not gonna use constructors, nor should you use the new keyword to create it. Instead, it is created either in the editor or with .AddComponent, and any initialization code you need, should be run in methods like Awake() [the first thing that gets run], OnEnable() [executed each time the object is activated], and Start() [best for initialization that depends on other objects, since the other objects’ Awake will have already been run].

1 Like

playerstats,classtats are both get/setter classes.

What do you mean by “get/setter class”? That’s not a thing. Do you mean a wrapper class?

And the more important question was, do they inherit from MonoBehaviour?

what i ment by get/setter class is just as u see above just a bunch of get/set prop, and yes Player inherit from Monobehaviour. should i get rid of it>? and do something else

This still doesn’t answer the question ,which seems really straightforward. Does PlayerStats which inherits from ClassStats ultimately inherit from Monobehaviour? Your Player class clearly does since you posted a snippet of it with a Start method.

The reason being is MonoBehaviour classes are created with the new keyword like any other class. But Unity does it for you behind the scenes. If you then try to create another PlayerStats using the new keyword your making an entirely new instance of this class that is NOT the one in your scene.

I am assuming somewhere down the chain you are in fact inheriting Monobehaviour for PlayerStatLogic because of this line:
playerstat = GetComponent<PlayerStatLogic>();\

For that to work I assume your PlayerStatLogic script is attached to your GameObject
so that code right there correctly gets the PlayerStatLogic instance you need. However you are immediately throwing it away and overwriting it with this:

 playerstat = new PlayerStatLogic();

Now all you code that calls playerstat.Whatever() is operating on an instance of PlayerStatLogic… but this instance isn’t in your scene at all. It is definitely not the PlayerStatLogic on your Player. Just take out that line and use the first GetComponentCall.

As soon as you attached PlayerStatLogic script to your Player GameObject Unity did all the “new PlayerStatLogic()” calls for you.

ultimately no nothing but player has access to monobehaviour or inherit it

okay so far i got the correct things loading i believe however i am still unable to get the values i set out. atm all values are just 0

welp i solved all problems apart from Argumentexpception getcomponent requires that the requested component ‘Player’ derives from monobehaviour or component or is an inferfact and player does not derive from mono or any other componenets

That makes this line odd then:

playerstat = GetComponent<PlayerStatLogic>();

Is PlayerStatLogic a script attached to the GameObject in your scene. If it is its required that it inherits from MonoBehaviour. Otherwise the editor wouldn’t let you add it to the scene. Heh and i just noticed it does have a Start and Update. So clearly something down the inheritance chain is inheriting from Monobehaviour

So this code here is the part that is getting the PlayerStatLogic Component and setting the values

 playerstat = GetComponent<PlayerStatLogic>();
playerstat.PlayerHealth();
playerstat.PlayerMana();

And PlayerHealth Looks like this:

public void PlayerHealth()
    {
        SetPlayerMaxHealth = GetBaseClassHealth;
        SetPlayerHealth = GetBaseClassHealth;
        SetPlayerCurrentHealth = GetPlayerHealth;

Is GetBaseClassHealth a property in the ClassStats class? You didn’t post it in any of your code. Is it actually being set to anyting?

Your code is very confusing especially in snippets. Could you post the code for Player and PlayerStatLogic that includes the class declaration. Your initial code snippet cut that off. Does anything you have inherit MonoBehaviour? I don’t see how you using Unity or making GameObjects without it.

using UnityEngine;

public class Player : PlayerStatLogic
{


    public Player()
    {
        startplayer();
    }

    public void startplayer()
    {
        BasicClass newclass = new BasicClass();
        newclass.Beginner();
        PlayerHealth();
        PlayerMana();
        PlayerLevel();
        PlayerName();
     
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;


public class PlayerStatLogic : PlayerStats {

    public Slider healthbar;
    public Slider manabar;
    public Text playerlevel;
    public Text playername;

  

    public void PlayerHealth()
    {
        SetPlayerMaxHealth = GetBaseClassHealth;
        SetPlayerHealth = GetBaseClassHealth;
        SetPlayerCurrentHealth = GetPlayerHealth;

        Debug.Log("Max Health : " + GetPlayerMaxHealth);
        Debug.Log("Current Health : " + GetPlayerCurrentHealth);
        Debug.Log("Current Mana : " + GetPlayerCurrentMana);

     
    }

    public void PlayerMana()
    {
        SetPlayerMaxMana = GetBaseClassMana;
        SetPlayerMana = GetBaseClassMana;
        SetPlayerCurrentMana = GetPlayerMana;

        Debug.Log("Max Health : " + GetPlayerMaxHealth);
        Debug.Log("Current Health : " + GetPlayerCurrentHealth);
        Debug.Log("Current Mana : " + GetPlayerCurrentMana);

      
    }

    public void PlayerLevel()
    {
        SetPlayerLevel = 1;
        playerlevel.text = "Level : " + GetPlayerLevel.ToString();
    }

    public void PlayerName()
    {
        SetPlayerName = "Reaper";
        playername.text = GetPlayerName.ToString();
    }

    public float CalculateHealth()
    {
        return GetPlayerCurrentHealth / GetPlayerMaxHealth;
    }

    public float CalculateMana()
    {
        return GetPlayerCurrentMana / GetPlayerMaxMana;
    }

    public void DealDamage(float damagevalue)
    {
        SetPlayerCurrentHealth = GetPlayerCurrentHealth - damagevalue;
        SetPlayerCurrentMana = GetPlayerCurrentMana - damagevalue;
        Debug.Log(healthbar.value = CalculateHealth());
        Debug.Log(manabar.value = CalculateMana());
        Debug.Log("Current Health : " + GetPlayerCurrentHealth);
        Debug.Log("Current Mana : " + GetPlayerCurrentMana);
    }
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class World : MonoBehaviour {

   

    public void GameWorld()
    {
        Player newplayer = GetComponent<Player>();
        newplayer.startplayer();
       

    }

    public World()
    {
       
    }
   

    // Use this for initialization
    void Start () {
       
    }
   
    // Update is called once per frame
    void Update () {
       
    }
}

i reworked it and it should work but i get that argument failur.

and note i completly forgot to say that i am using a World class to hold all things that is going to be in a world.

GetComponent is only used for MonoBehaviours. Since a Monobehaviour is attached to a gameObject Unity creates the instance for you ( runs the new keyword for you behind the scenes). Since it does this you need a way to get a handle on that object. Thats what GetCompnent is for.

However, your Player Class is just a data object sittting in your project its not attached to any GameObject (It can’t be since it does not inherit from MonoBehaviour). So you just need to create it the normal way using the new keyword.

Additionally Since MonoBehaviours are created for you by Unity you should NOT have public constructor. Just use Awake and Start. Change your GameWorld script to this:

public class World : MonoBehaviour {
    // Use Awake to initialize things about ourself
    void Awake()
    {
        Player newplayer = new Player();
        newplayer.startplayer();
    }
  
   // Use Start to initialize things that require other scripts
    void Start () {
     
    }
 
    // Update is called once per frame
    void Update () {
     
    }
}

So quick overview:
If a class inherits from Monobehaviour

  • You attach to game Objects in your scene
  • Unity creates the instance for you. Don’t use new to create a copy.
  • Use GetComponent() to get a handle to the object that Unity created
  • Do NOT have public constructors … public Class()
  • Use Awake() and Start() to initialize things

If a class doesn’t inherit from MonoBehaviour

  • This is a “normal” C# class that just sits in your project
  • You are not allowed to add it to GameObjects
  • You must use Class myClass = new Class() to make a new copy of it
  • Use public Constructors public Class() to initialize it.

oright thanks for your help. gonna test it in few

The following is rather a little off-topic, but still worth to be mentioned:

I’d like to kindly recommend to follow some naming conventions.
Yo do this almost everywhere:

private int _someField;

public int GetSomeField
{
    get { return _someField; }
}

public int SetSomeField
{
    set { _someField = value; }
}

Don’t get me wrong, this works flawlessly but it’s a really unconventional way to name properties.
Usually, you have a common name when using C# properties, as they have field-like syntax, i.e. when you write some code, it looks as if they were just some fields. (In the end methods will be generated anways, but that’s not the point.)

Additionally, it shortens your code and defines the accessors in one block, which is nice since they’re always defined in the same place using the same name.

private int _someField;

public int SomeField
{
    get { return _someField; }
    set { _someField = value; }
}

That’s how it’s usually done.

In contrast, if it says GetXXX and SetXXX, one usually expects these accessors to be implemented as methods:

private int _someField;

public int GetSomeField()
{
    return _someField;
}

public void SetSomeField(int value)
{
    _someField = value;
}

In the end it’s the result will be the same, and it’s really up to you whether you ignore this or find this helpful.

2 Likes

Does PlayerStats extend anything. Also you really should look into using composition pattern rather than inheritance here. A Player is not a type of PlayerStats ultimately.

In your game world in you need to call the constructor of Player

Player newplayer = new Player();

First break the inheritance, then do the following to Player

public class Player{

  private PlayerStats playerStats;
  private PlayerStatLogic playerStatLogic;

  public Player(PlayerStats playerStats, PlayerStatLogic playerStatLogic) {
this.playerStats = playerStats;
this.playerStatLogic = playerStatLogic
}

}

This way the logic of playerStats and PlayerStatLogic is decoupled from and you can make alterations to the code in those classes without affecting Player. They are now seen as dependencies instead.

Think of composition as “has-a” rather than “is-a”

Player has a playerStat

If you need multiple implementations of the class playerStats and playerStatLogic, you can make an interface for both of them.

ye i know naming and stuff :smile: however it isnt my concern atm

ye i was just trying some stuff.
however player is the parent of them and i have trouble getting the values instantiated they are just returning null

And where do you set them? In the inspector?
We don’t know that unless you either post the pieces of code that set values programatically or tell us that you’ve set them in the inspector.