2017-04-18 45 views
0

我在Unity中制作基于2D网格的游戏,并拥有一个Weapon类,该类具有获取武器统计信息的属性。统计数据由武器组成部分计算,部件的数量和类型由武器类型WepGunWepStaffWepSword定义。每种武器类型都有亲和力和抓地力。为了让玩家装备武器,我必须得到它的实际类型(枪/职员/剑),以便我可以使用武器上的区域。该武器作为武器存储在保存数据中(可能是idk问题),并通过Newtonsoft.Json json库保存到磁盘。C#InvalidCastException获取派生类型

当我尝试分配Weapon的字段时,没有问题,但是当我尝试分配实际武器类型的字段时,我得到InvalidCastException: Cannot cast from source type to destination type.我很确定这不是因为我用他们开始的武器类型创造角色而是下贱的。this链接显示的作品有点类似于我的情况为例)

代码中的问题:

[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; 
    } 
} 
+2

每个'WepGun'都是'Weapon',但不是每个'Weapon'都是'WepGun' ... – DavidG

+0

DavidG说的是什么。让我们用不同的类比来做这件事:你有基类Person和一个从Person继承的类BaseballPlayer。每个BaseballPlayer都是一个人,但不是每个人都是一个BaseballPlayer。 – Rafael

+1

但是,如果我将该字段的值定义为'WepGun',那么试图将其作为'WepGun'来获取它不应该失败。如果我将其定义为'WepStaff',我会期望演员失败。这些东西在放入一个不同形状的桶中时奇迹般地忘记了它自己的形状吗? – MattDahEpic

回答

1

如果这是违规行,请更改并调试它。

((StatManager.WepGun)weapon).barrel = new StatManager.Part(StatManager.PartType.GUN_BARREL, StatManager.AttackType.CARDINAL_SINGLE_TARGET, 3, 0, 0.2f); 

变化

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我认为你应该使用的接口,而不是类武器类型。有一天你会想要将两种武器类型合并为一种。你不能用类来做到这一点。