EDIT: If you need to display a combination of static and dynamic data, one way is to wrap the static data in a container:
public interface IWeapon {
string DisplayName { get; }
float Damage { get; }
}
public class Weapon : ScriptableObject, IWeapon {
[SerializeField] private string displayName;
[SerializeField] private float damage = 10;
//etc
public string DisplayName => displayName;
public float Damage => damage;
//etc
}
public class DamageScaledWeapon : IWeapon {
private Weapon weapon;
private float damageMultiplier = 1;
public string DisplayName => weapon.DisplayName;
public float Damage => weapon.Damage * damageMultiplier;
public float DamageMultiplier { get => damageMultiplier; set => damageMultiplier = value; }
//etc
public DamageScaledWeapon(Weapon weapon) {
this.weapon = weapon;
}
}
//Can display a Weapon or a DamageScaledWeapon
public class WeaponPresenter : MonoBehaviour {
[SerializeField] private Text nameText;
[SerializeField] private Text damageText;
//etc
private IWeapon model;
public IWeapon Model {
get => model;
set {
model = value;
Refresh();
}
}
private void Refresh() {
if (model != null) {
nameText.text = model.DisplayName;
damageText.text = model.Damage.ToString("N1");
//etc
}
}
}