samedi 13 août 2016

Design patterns: how to properly build such case with passing and getting variables?

I have a big (3000 lines as of yet) CharacterGenerator script in Unity3D, which inherits from Unity's built-in class MonoBehaviour. It uses other scripts and generates the character for my game. For example, it uses ClassFighter script.

Now, I have calculated some modifer in CharacterGenerator, called con_mod. After player has chosen his character class, I need to calculate his Hit Points. Those Hit Points are generated in a function specific to character class, in this example: in ClassFighter script.

So, I have such code:

public class CharacterGenerator : MonoBehaviour {
// (...)
public BasePlayer basePlayer = new BasePlayer();
// (...)
if (classGenerator.classArray [4] == true)
characterClass = "Fighter";
newPlayer.PlayerClass = new ClassFighter();
// (...)
con_mod = somecalculation;
    basePlayer.Con_mod = con_mod;
// (...)
    public void CalculateCharacterStartingHitPoints() {
    characterStartingHitPoints = newPlayer.PlayerClass.GenerateStartingHitPoints();
    }
}

...where newPlayer.PlayerClass is (new) ClassFighter. I debugged it, it shows ClassFighter properly.

GenerateStartingHitPoints() is:

public class ClassFighter : BaseCharacterClass {
// (...)
BasePlayer basePlayer = new BasePlayer();
// (...)
    public override int GenerateStartingHitPoints () {
    startingHitPoints = 10 + basePlayer.Con_mod;
    Debug.Log ("basePlayer.Con_mod: " + basePlayer.con_mod);
    return startingHitPoints;
    }
}

Which is override for:

public class BaseCharacterClass {
// (...)
    public virtual int GenerateStartingHitPoints () {
    return startingHitPoints = 0;
    }   
}

And BasePlayer includes:

public class BasePlayer {
// (...)
    private int con_mod;
    public int Con_mod {
       get { return con_mod; }
       set { con_mod = value; }
    }

But I get 10 Hit Points. No Con_mod value added. I think that's because basePlayer was instantiated with "new" keyword in CharacterGenerator script, so when I access basePlayer.Con_mod via ClassFighter script, it doesn't have value stored in basePlayer by CharacterGenerator... Those are probably two different variables, one created in CharacterGenerator and diffent in ClassFighter. Am I right?

How can I do it so it works? I implement variable "BaseClass playerClass" holding character class chosen by player, so I won't have to hardcode "if (characterClass == "ClassName")" for every each class all the time. BaseClass class, which scripts of specific character classes inherit from, isn't of any use other than for making this possible, I guess. It's just to make all character classes scripts have one same type.

I also didn't want to inherit from CharacterGenerator, because it's a big file, and can't create it with "new" keyword because in Unity you can't create new "Monobehaviour" this way.

I (probably?) could access CharacterGenerator from ClassFighter script via variableName = GameObject.Find("Object With CharacterGenerator Component").GetComponent().con_mod, but wouldn't that load whole 3000 lines of code again just to get this 1 variable? This would be bad performance-wise...

Plus, I don't see any reason to add the above scripts as components to objects (other than CharacterGenerator, which is a component). It would mess up my current code and isn't logical.

I'm just concerned about good programming pattern here and performance. I am learning, so I'd like to have some good template for such situations in future.

One important thing - I don't want to make con_mod or Con_mod static, because we may be creating multiplayer game later on this base. Players will use their personal con_mod, monsters too.

Aucun commentaire:

Enregistrer un commentaire