Reputation: 73
I'm making a 2D grid based game in Unity and have a Weapon
class that has properties for getting the stats on the weapon. The stats are calculated by the parts that the weapon is made up of, and the number and type of parts is defined by the type of weapon WepGun
, WepStaff
, or WepSword
. Every weapon type has an affinity and a grip. In order to allow the player to equip parts to the weapon, I have to get it's actual type (gun/staff/sword) so that I can use the fields on the weapon. The weapon is stored in the save data as a Weapon (which may be a problem idk) and is saved to disk with the Newtonsoft.Json
json library.
When I attempt to assign the fields of Weapon
, no problem, but when I try to assign the fields of the actual weapon type I get an InvalidCastException: Cannot cast from source type to destination type.
. I'm pretty sure it's not downcasting since I create the characters with the type of weapon they start with. (this link shows an example that works somewhat similar to my situation)
Code in question:
[SaveData.cs]
[JsonProperty] public static CharacterSaveData JESSIE = new CharacterSaveData(...,new StatManager.WepGun());
public class CharacterSaveData {
...
[JsonProperty] public StatManager.Weapon weapon;
internal CharacterSaveData (..., StatManager.Weapon weapon) {
this.weapon = weapon;
weapon.affinity = StatManager.Part.ART_AFFINITY;
((StatManager.WepGun)weapon).barrel = new StatManager.Part(StatManager.PartType.GUN_BARREL, StatManager.AttackType.CARDINAL_SINGLE_TARGET, 3, 0, 0.2f); //error occurs here
}
[StatManager.cs]
public abstract class Weapon {
[JsonProperty] private Part _affinity;
public Part affinity {...}
[JsonProperty] private Part _grip;
public Part grip {...}
...properties
internal Weapon (Part affinity, Part grip) {
_affinity = affinity;
_grip = grip;
}
}
public class Part {
...predefined parts (ART_AFFINITY is here)
public PartType? partType; //enum
public AttackType? attackType; //enum
public int? attackRange;
public int? damageRange;
public float? modifier;
public ModType? modifierType; //enum
public Part (PartType? partType = null, AttackType? attackType = null, int? attackRange = null, int? damageRange = null, float? modifier = null, ModType? modifierType = null) {
this.partType = partType;
this.attackType = attackType;
this.attackRange = attackRange;
this.damageRange = damageRange;
this.modifier = modifier;
this.modifierType = modifierType;
}
}
public class WepGun : Weapon {
[JsonProperty] private Part _barrel;
public Part barrel {...}
[JsonProperty] private Part _sight;
public Part sight {...}
[JsonProperty] private Part _bullet;
public Part bullet {...}
...properties
public WepGun (Part barrel = null, Part grip = null, Part sight = null, Part bullet = null, Part affinity = null) : base(affinity,grip) {
_barrel = barrel;
_sight = sight;
_bullet = bullet;
}
}
public class WepStaff : Weapon {
[JsonProperty] private Part _shaft;
public Part shaft {...}
[JsonProperty] private Part _head;
public Part head {...}
[JsonProperty] private Part _accessory;
public Part accessory {...}
...properties
public WepStaff (Part shaft = null, Part grip = null, Part head = null, Part accessory = null, Part affinity = null) : base(affinity,grip) {
_shaft = shaft;
_head = head;
_accessory = accessory;
}
}
public class WepSword : Weapon {
[JsonProperty] private Part _blade;
public Part blade {...}
[JsonProperty] private Part _guard;
public Part guard {...}
[JsonProperty] private Part _accessory;
public Part accessory {...}
...properties
public WepSword (Part blade = null, Part guard = null, Part grip = null, Part accessory = null, Part affinity = null) : base(affinity,grip) {
_blade = blade;
_guard = guard;
_accessory = accessory;
}
}
Upvotes: 0
Views: 90
Reputation: 11955
If this is the offending line, change it and debug it.
((StatManager.WepGun)weapon).barrel = new StatManager.Part(StatManager.PartType.GUN_BARREL, StatManager.AttackType.CARDINAL_SINGLE_TARGET, 3, 0, 0.2f);
change to
var wepGun = weapon as StatManager.WepGun;
if(null != wepGun)
wepGun.barrel = new StatManager.Part(StatManager.PartType.GUN_BARREL, StatManager.AttackType.CARDINAL_SINGLE_TARGET, 3, 0, 0.2f);
else
{
// debug code
}
PS I think you should be using Interfaces and not classes for weapon types. Someday you are going to want to merge two weapon types into one. You can't do that with classes.
Upvotes: 1