在Unity3D游戏中,
我希望将数据存储在各种子类中,所有子类都派生自单个类Tool
,并且能够随意检索它,并遍历每个类。
例如,一个工具是Hammer
,我想存储在int timesUsed
之类的关卡中使用任何锤子的总次数。静态属性似乎是处理此问题的方法,但我找不到一种方法可以轻松迭代Tool
的所有子类并检索其timesUsed
属性。
为了澄清,我希望Tool
的每个子类都拥有timeUsed
。因此Hammer
,Drill
和Saw
都具有独立的timesUsed
属性。但Hammer
的每个实例都将始终具有相同的timesUsed
。
另一个简短示例,每个Tool
子类(如Hammer
)都有一个指向“Hammer”文本框的链接。该文本框对于该类的所有实例都是相同的。
处理此问题的正确方法是什么?
答案 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--;
}
}
}