Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Inheritance/Initializing/Monster Spawning Problems, oh my!

Discussion in 'Scripting' started by Scottk42, May 27, 2017.

  1. Scottk42

    Scottk42

    Joined:
    Apr 13, 2017
    Posts:
    11
    I'm currently making a pokemon clone and during a battle I want the stage to populate with the enemy and the friendly monsters.

    I have a Monster class that has a bunch of predefined methods like 'attack' or 'takeDamage' and variables like 'attackStat' and 'defenseStat' :
    Code (CSharp):
    1. public abstract class Monster : MonoBehaviour {
    2.  
    3.     //stats
    4.     public virtual int attackStat { get { return 0; } protected set { } }
    5.     public virtual int defenseStat { get { return 0; } protected set { } }
    6.  
    7. public virtual void Initialize (string name, int level)
    8.     {
    9.         print("this should not appear");
    10.     }
    11. }
    12.  
    13.  
    I have specific Pokemon that inherit this class, in order to populate the battle easily with that pokemon. For instance I have a Pikachu class that has a bunch of predefined stats like 'attackStat' and 'defendStat'.
    Code (CSharp):
    1. public class Pikachu : Monster {
    2.  
    3.     public override void Initialize (string newName, int startingLevel)
    4.     {
    5.         print("Initialize method for " + newName + " level: " + startingLevel);
    6.         monsterName = newName;
    7.         level = startingLevel;
    8.  
    9.         attackStat = 10 + 3 * startingLevel;
    10.         defenseStat = 2 * startingLevel;
    11. }
    Now here's where I get into trouble. In a battle I have a script called 'Spawner' that Instantiates two pokemon, both pikachu, one enemy and one friendly. Here's an example of spawning some friendly Monsters:
    Code (CSharp):
    1. if (friendlyMonsterPrefabArray[i])
    2.             {
    3.                 GameObject myFriendlyMonsterObject = Instantiate(friendlyMonsterPrefabArray[i], battleCanvas.transform) as GameObject;
    4.                 myFriendlyMonsterObject.transform.parent = enemyPosition.transform;
    5.                 myFriendlyMonsterObject.transform.position = new Vector3((enemyPosition.transform.position.x + (i * 5)), enemyPosition.transform.position.y);
    6.                 myFriendlyMonster = myFriendlyMonsterObject.GetComponent<Monster>();
    7.                 myFriendlyMonster.Initialize("john", 5);
    8.             }
    Now the problem occurs that given all this code, for some reason the attackStat and defenseStat are never set. I have them fight each other, and I print out the 'attackStat' and it's always '0'. I'm screwing up some sort of inheritance here because I never learned properly how to do it so I kind of botched my way through and just followed compiler errors until there weren't any more!

    Is there a better way to be spawning monsters on a battlefield from a prefab array? Should I be using a constructor? I tried to but it never worked either. I also tried having the Pikachu class change the stats by saying base.attackStat = 5; and it didn't work either.

    Thanks
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,514
    Do your prefabs have Pikachu scripts on them?

    If so... did you put both a Monster and Pikachu script on them, and the Monster script is above the Pikachu? Cause don't do that.

    Furthermore, if the only thing your Pikachu class does is set the properties like attack to a special value, and nothing more. You don't need inheritance for that. Rather go with a factory design pattern, where the Monster script gets added, and its configured as a Pikachu (the pikachu values are assigned). Which doesn't have to be done in the class, but could be done elsewhere.
     
  3. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I don't mean any disrespect here, but is this overriden later?
    Code (csharp):
    1.  public virtual int attackStat { get { return 0; } protected set { } }
     
    lordofduct likes this.
  4. Scottk42

    Scottk42

    Joined:
    Apr 13, 2017
    Posts:
    11
    So the Pikachu script is added to the Prefab. The Monster script is not added. I don't quite understand what a factory design means. My Pikachu prefab also has a Pikachu sprite, and Pikachu abilities (like electroShock script). If the factory design is a more elegant way could you explain how I would implement that?

    Well, it appears that the attackStat is not overridden and I think you figured it out. However I don't know how to override it. Do you see how I was trying to 'set' that value by putting it into the Pikachu script, and calling that Initialize() function later? How should I do it properly?

    Thanks!
     
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I saw it. So, if you want the set to be protected, that's no problem.
    I think all you need is:
    Code (csharp):
    1.  
    2. class C {
    3.     public virtual int g { get; protected set; } // this can still "force return 0" in get if you want
    4.   }
    5.  class D: C {
    6.    public override int g { get; protected set; } // don't force return zero here for sure! :)
    7.    public override void Initialize(int _g)
    8.    {
    9.        g = _g;
    10.    }
    11. }
    12.  
    Sorry, my 'short' variables were just easier to type ;)