2017-04-18 98 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我認爲你應該使用的接口,而不是類武器類型。有一天你會想要將兩種武器類型合併爲一種。你不能用類來做到這一點。