Unity3D,将数据存储在子类

时间:2016-05-17 20:52:01

标签: c# unity3d

在Unity3D游戏中,

我希望将数据存储在各种子类中,所有子类都派生自单个类Tool,并且能够随意检索它,并遍历每个类。

例如,一个工具是Hammer,我想存储在int timesUsed之类的关卡中使用任何锤子的总次数。静态属性似乎是处理此问题的方法,但我找不到一种方法可以轻松迭代Tool的所有子类并检索其timesUsed属性。

为了澄清,我希望Tool的每个子类都拥有timeUsed。因此HammerDrillSaw都具有独立的timesUsed属性。但Hammer的每个实例都将始终具有相同的timesUsed

另一个简短示例,每个Tool子类(如Hammer)都有一个指向“Hammer”文本框的链接。该文本框对于该类的所有实例都是相同的。

处理此问题的正确方法是什么?

3 个答案:

答案 0 :(得分:4)

  

每个锤子都是它自己的实例。那就是静态属性   可以进来

没有。你不需要静电。

  

每个Hammer都是它自己的实例。

使用List来保存每个Hammer实例。

public class Tool
{
    private List<Hammer> hammers;

    public Tool()
    {
        hammers = new List<Hammer>();

    }

    public void addNewHammer()
    {
        hammers.Add(new Hammer());
    }

    public void addNewHammer(int amount)
    {
        for (int i = 0; i < amount; i++)
        {
            hammers.Add(new Hammer());
        }
    }

    public void removeHammer(int index)
    {
        hammers.RemoveAt(index);
    }

    public void removeAllHammer()
    {
        hammers.Clear();
    }

    public int getRemainingNum(int index)
    {
        return hammers[index].getRemainingNum();
    }

    public Hammer getCurrentHammerInstance(int index)
    {
        return hammers[index];
    }

    public Hammer[] getAllHammerInstance()
    {
        return hammers.ToArray();
    }
}

public class Hammer
{
    private int numRemaining = 0;
    public int getRemainingNum()
    {
        return numRemaining;
    }
}

如何使用:

void Start()
{
    Tool mytools = new Tool();

    //Add 1 new Hammer
    mytools.addNewHammer();

    //Add 10 Hammers
    mytools.addNewHammer(10);


    //Get numRemaining
    mytools.getRemainingNum(0);

    //Remove a Hammer by index
    mytools.removeHammer(0);

    //Remove all Hammers
    mytools.removeAllHammer();

    //Get Hammer instance
    Hammer myhammer = mytools.getCurrentHammerInstance(0);

    //Get All Hammer instance as array
    Hammer[] allHammers = mytools.getAllHammerInstance();

    //Loop through all numRemaining from each hammer
    for (int i = 0; i < allHammers.Length; i++)
    {
        Debug.Log(allHammers[i].getRemainingNum());
    }
}

重要您可以使用T将其转换为 generics ,并可以添加其他工具。这些函数将不再锁定到Hammers,然后可以与其他工具/类一起使用。

答案 1 :(得分:1)

正如rudolf_franek建议的那样,有一个管理器类来跟踪所有工具(典型的实例化对象列表)。

public class Tool : MonoBehaviour
{
    public int durability;
    public string name;
}

某些工具,例如锤:

public class Hammer : Tool
{
    public void HammerAction(){...}
}

经理(这应该是一个单身人士):

public class ToolManager : MonoBehaviour
{
    List<Hammer> hammers;

    public int GetHammerCount()
    {
        return hammers.Count;
    }

    // other stuff like adding when instantiating etc.
}

请注意,从MonoBehaviour派生意味着您无法通过new Tool()来创建工具的工具/子类,而是需要采用统一的方式来执行Instantiate()。< / p>

c#/ Unity中的属性示例(作者Joe Blow)

private float _ordinaryMps;
public float OrdinaryMps
    {
    set {
        _ordinaryMps = value;
        foreach(BaseFrite e in all)
            e.mpsNow = _ordinaryMps * widthSpeedFactor;
        }
    get { return _ordinaryMps; }
    }

private float _mps;
public float Mps
    {
    set {
        _mps = value;
        for (int i=0; i<kParts; ++i)
            parts[i].mps = Mps;
        }
    get { return _mps; }
    }

public int Count
    {
    get { return prepped != null ? prepped.Count : 0; }
    }

private int _hearts;
public int Hearts
    {
    set {
        _hearts = value;
        controls.HeartNumber(_hearts);
        }
    get { return _hearts; }
    }

private int _megabombs;
public int Megabombs
    {
    set {
        _megabombs = value;
        controls.MegabombNumber(_megabombs);
        }
    get { return _megabombs; }
    }

答案 2 :(得分:-1)

如果你把每个工具都保存在它自己的集合中,那么集合的数量就是那种工具的数量。

如果将所有工具保存在单个集合中,则可以通过使用.OfType()获取每个工具的计数来获取工具数量。

如果您不打算使用集合来保存工具对象,则可以使用静态属性方法,该方法是对象的引用计数,您可以在构造函数中递增并在dispose中递减。或者您可以创建.Use()方法或其他类似的方法,您不必使用IDispose。

以下是您可能正在寻找的非集合计数抽象属性方法的示例。

    using System;
    using System.Collections.Generic;
    using Microsoft.VisualStudio.TestTools.UnitTesting;

    namespace UnitTestProject1
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestMethod1()
            {
                Hammer hammer1 = new Hammer();
                Hammer hammer2 = new Hammer();                    
                Assert.AreEqual(2, hammer1.NumRemaining);

                // Calling dispose doesn't set hammer1 null, just decrements the _numRemaining count
                hammer1.Dispose();

                Saw saw1 = new Saw();
                Saw saw2 = new Saw();
                var tools = new List<Tool> {hammer1, hammer2, saw1, saw2};

                foreach (Tool tool in tools)
                {
                    if (tool is Hammer)
                        Assert.AreEqual(1, tool.NumRemaining);
                    if (tool is Saw)
                        Assert.AreEqual(2, tool.NumRemaining);
                }
            }
        }

        public abstract class Tool
        {
            public abstract int NumRemaining { get; }
        }

        public class Hammer : Tool, IDisposable
        {
            private static int _numRemaining;

            public Hammer()
            {
                _numRemaining++;
            }

            public override int NumRemaining
            {
                get { return _numRemaining; }
            }

            public void Dispose()
            {
                _numRemaining--;
            }
        }

        public class Saw : Tool, IDisposable
        {
            private static int _numRemaining;

            public Saw()
            {
                _numRemaining++;
            }

            public override int NumRemaining
            {
                get { return _numRemaining; }
            }

            public void Dispose()
            {
                _numRemaining--;
            }
        }
    }