1
\$\begingroup\$

Sorry for the bad title, but I couldn't think of a way to word my problem for a title.

So I have this script, with two classes:

using UnityEngine;
using System.Collections;

public class GameItem {

    public string ItemName { get; set; }

    public string ItemDesc { get; set; }

    public Item_Type ItemType { get; set; }

    public int ItemValue { get; set; }

    public int ItemID { get; set; }

    public GameItem() {

    }

    public GameItem(string name, string desc, Item_Type type, int value, int id) {
        this.ItemName = name;
        this.ItemDesc = desc;
        this.ItemType = type;
        this.ItemValue = value;
        this.ItemID = id;
    }
}

public class Weapon : GameItem {

    public string WeapEnch { get; set; }

    public float WeapEffic { get; set; }

    public Weapon() {

    }

    public Weapon(string name, string desc, string ench, float effic, int id) {
        this.ItemType = Item_Type.WEAPON;
        this.ItemName = name;
        this.ItemDesc = desc;
        this.WeapEnch = ench;
        this.WeapEffic = effic;
        this.ItemID = id;
    }

    public void Attack() {

    }
}

public enum Item_Type {
    APPAREL,
    WEAPON,
    TOOL,
    CONSUMABLE,
    BOOK,
    MISC
}

And then I have a script for adding items to a list using the constructors:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class InventoryManager : MonoBehaviour {

    public List<GameItem> GameItems { get; set; }

    void Start () {
        GameItems.Add(new Weapon("Sword", "It's just a sword.", null, 5, 0));
    }

    void Update () {
        if(Input.GetButtonDown("Interact")) {
            Debug.Log(GameItems[0].ItemName);
        }
    }
}

So when I create a new Weapon in the list, I can access everything from the GameItem class, but nothing from the Weapon class, even though I used the Weapon constructor. So I can't use the Attack () function, or access the Weapon's variables. How can I get around this problem?

\$\endgroup\$
1
\$\begingroup\$

The thing is that with your list you dont know if the element is a weapon or a apple. It's just a GameItem. To be able to use the weapon specific properties you need to retrieve the element and cast it back to a Weapon. For example the update in inventory manager will look like this.

 void Update()
    {
        if (Input.GetKeyDown("a"))
        {
            Debug.Log(GameItems[0].ItemName);
            Weapon currentWeapon =(Weapon)GameItems[0];
            Debug.Log(currentWeapon.ItemName);
            currentWeapon.Attack();
        }
    }

What you can do is add a virtual method UseItem() to your GameItem class if you dont want it to be abstract(I would say that it should be). Example :

 public virtual void UseItem()
    {

    }

Then your weapons class you can do this :

  public override void UseItem()
    {
        Attack();
    }

Now if you call UseItem on a elemet from your GameItems list and it was added as a weapon it go and call the Attack method from the Weapons class.

An alternative design is to use interfaces to specify different logical boundaries. For example

interface IItem
{

}
interface IWeapon : IItem
{

}
interface IFood : IItem
{

} 
interface IRangedWeapon: IWeapon
{

}
void ProcessItems()
{
    foreach (var item in Items)
    {
        if (item is IWeapon) //do some logic
         if (item is IFood) //do some logic
                if (item is IRangedWeapon) //do some logic
    }
}

Note this is more or less a pseudo implementation. I also suggest you read up on Polymorphism. For a bit more in depth look and information check out this question

\$\endgroup\$
  • \$\begingroup\$ Damn, you beat me with that edit. \$\endgroup\$ – Tyyppi_77 Jun 24 '16 at 8:05
  • \$\begingroup\$ Which one I made like 3 of them :P \$\endgroup\$ – Uri Popov Jun 24 '16 at 8:06
  • \$\begingroup\$ No you didn't (it shows only one for me), but with the addition of the virtual method. I had just written my answer on that approach, as your was missing that when I started typing. \$\endgroup\$ – Tyyppi_77 Jun 24 '16 at 8:08
  • \$\begingroup\$ Ah yes It popped into my head after I added the interface solution and I jumped back to my PC to write it as quickly as I could saying to myself that someone will beat me to it :D \$\endgroup\$ – Uri Popov Jun 24 '16 at 8:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.