Can I access variables of scripts that inherit from abstract classes?

Hi there I have been trying to wrap my around the use of abstract classes and I can work out how to call functions of scripts derived from abstract classes but not how to access variables using the same method.

Here’s my scripts:

public class InputManager: MonoBehaviour{
   public GameObject exampleObject;
   private AttackAction exampleScript;

   void Update(){
      if(Input.GetKeyDown("f")){
         exampleScript = exampleObject.GetComponent<AttackAction>();
         exampleScript.PrimaryAttack();
      }
      if(Input.GetKeyDown("d")){
         exampleScript = exampleObject.GetComponent<AttackAction>();
         Debug.Log(exampleScript.damage);
      }
   }
}

public class AttackAction: MonoBehaviour{
   public int damage;

   public virtual void PrimaryAttack(){}
}

public class SwordAttack: AttackAction{
   public int damage = 10;

   public override void PrimaryAttack(){Debug.Log("sword swipe");}
}

public class BowAttack: AttackAction{
   public int damage = 8;

   public override void PrimaryAttack(){Debug.Log("shoot bow");}
}

Now my problem is on Line 12 i.e. - (Debug.Log(exampleScript.damage);

My question is - “What do I have to do to access these damage variables?” (C# ideally)

Thankyou

Technically you do not have abstract classes, because an abstract class is defined with the keyword abstract. One way to solve your problem is to use an abstract getter, like the following:

public abstract class AttackAction : MonoBehaviour {
	
	public abstract int GetDamage();
	public abstract void PrimaryAttack();

}

public class SwordAttack: AttackAction{
	public int damage = 10;
 
	public override int GetDamage(){ return damage;	}
	public override void PrimaryAttack(){Debug.Log("Sword swipe: "+ damage.ToString()+" damage.");}
}

Now we have an abstract class, which expects all of it’s children to provide an implementation for getting the damage and doing a primary attack. Because you treat exampleScripts as AttackActions, you will only have access to whatever is defined in AttackAction. Thus, in line 12 of you snippet, you would call exampleScript.GetDamage().ToString()

Also worth noting is that if AttackAction will never contain any implementation (=code inside methods), it should be declared as an interface. Then people who want to see implementation know not to look there.

You can access variables from the base class the same way as you access other variables. However there might be a problem because you redefine damage in the derived classes and they hide the variable from the base class. So you may use Awake to initialize the damage in each class, but define it only in AttackAction.