2016-05-17 3 views
0

В игре Unity3D,Unity3D, хранение данных в подклассах

Я хочу, чтобы хранить данные на различных подклассов, все из которых получены из одного класса Tool и быть в состоянии получить его по собственному желанию, а также как итерация по каждому из классов.

Например, один инструмент: Hammer, и я хочу, чтобы общее количество раз, когда любой молот использовался на уровне примерно в int timesUsed. Статические свойства выглядят как способ справиться с этим, но я не могу найти способ легко перебирать все подклассы Tool сразу и получить их свойство timesUsed.

Чтобы уточнить, я хочу, чтобы каждый подкласс Tool обладали timeUsed. Таким образом, Hammer, Drill и Saw все имеют независимые timesUsed. Но у каждого экземпляра Hammer всегда будет одинаковое timesUsed.

Еще один короткий пример: каждый подкласс Tool, такой как Hammer, будет иметь ссылку на текстовое поле для «Молот». Это текстовое поле будет одинаковым для всех экземпляров этого класса.

Каков правильный способ справиться с этим?

+2

Может numRemaining это не так .. Вы, наверное, нужна какая-то "ToolRepository" или класса "ToolPool", который может быть доступным как статический singleton ->, позволяющий вам одновременно считать ваши инструменты, а также извлекать только инструменты определенного подтипа –

+0

Просто для уточнения ... У вас есть базовый класс 'tool', и у вас есть« Hammer ».. если у вас 10 молотов. .. вы хотите определить 1 или 10 классов из Hammer ....? –

+0

Каждый «Молот» будет его собственным экземпляром. Именно здесь могут появиться статические свойства, поскольку они живут на самом классе «Хаммер». В этом случае свойство 'public static numRemaining' в классе' Hammer' будет равно 10. – Preston

ответ

-1

Если вы храните каждый инструмент в своей собственной коллекции, то подсчет коллекции - это количество инструментов такого типа.

Если вы храните все инструменты в одной коллекции, вы можете получить количество инструментов, получив счет каждого инструмента, используя .OfType(), например.

Если вы не планируете использовать коллекции для хранения объектов инструмента, вы можете использовать метод статического свойства, который является ссылочным числом вашего объекта, который вы можете увеличить в своем конструкторе и уменьшить его. Или вы можете создать метод .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--; 
      } 
     } 
    } 
+1

Это Единство. 'using Microsoft.VisualStudio.TestTools.UnitTesting;' недоступен. Использование Dispose a-lot в GameEngine/Unity не является хорошей идеей. Вы получаете всплески и другие проблемы с производительностью. – Programmer

4

Каждый Молот будет свой собственный экземпляр. Вот где статические свойства могут быть в наличии

Нет. Вам здесь не нужна статичность.

Каждый Хаммер был бы его собственным примером.

Использовать список для хранения каждого экземпляра 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 и иметь возможность добавлять другие инструменты.Эти функции больше не будут заблокированы до Hammers и затем могут быть использованы с другими инструментами/классами.

+0

Имея список '', а затем, имея этот класс, удерживает счетчик, на самом деле не имеет смысла.(Вопрос состоял из нескольких разных инструментов (молот, топор, ...) и имел счетчик для каждого из них.) –

+0

@GunnarB. Я думал, он сказал, что хочет хранить много подклассов в классе под названием «Инструменты». Например, подкласс под названием «Hammer» в классе, называемом инструментами, нуждается в способе доступа к «numRemaining» подкласса? Затем он хочет узнать, сколько молотков осталось в переменной numRemaining. Это то, что я понял из вопроса. Может быть, я все понял неправильно .... – Programmer

+1

@GunnarB. Чувак снова посмотрит, подход P идеален. – Fattie

1

Как предложил rudolf_franek, у вас есть класс менеджера, который отслеживает все ваши инструменты (типичный список объектов, созданных при помощи экземпляра).

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

Определенный инструмент, например. Hammer:

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().


Примеры собственности в C#/Unity (Джо 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; } 
    } 
+0

Чувак в вашей схеме GetHammerCount был бы свойством, то есть более прохладным. (это ничем не отличается - вы просто чувствуете себя более холодным) – Fattie

+0

Обратите внимание, что такое свойство уже существует :) «.Count» (или «Length» или что-то, я всегда забываю). Код будет выглядеть как «tools.hammers.Count» или «tools.bolts.Count» – Fattie

+0

, вам не следует использовать имена классов/переменных, такие как «ToolsManager» или «xFloat» или «trackList» или «vertsArray» и т. Д. Конечно, вы просто говорите «Инструменты» «x» «tracks» «verts». Не указывайте в названиях «вид» или «Тип» или другое описание. – Fattie

Смежные вопросы