Как обновить массив объектов с индексом dymani c - PullRequest
0 голосов
/ 08 апреля 2020

START

ex "Потерянный класс или индекс потеряли размер"

Я строю объект, который сохраняет значения моего автомобиля.

Основа c logi c - это: Для каждой коробки передач> сохранить каждую подвеску> сохранить каждое колесо.

Лог c скрипта:

  public class VehicleController : MonoBehaviour
  {
      public gearbox[] gearboxes = new gearbox[0]; //999 not change effect

      [System.Serializable] 
      public class gearbox
      {
        public Transform gearBoxTarget;

        public List<Transform> assets = new List<Transform>();

        public gearbox(Transform gearBoxTarget, List<Transform> assets  )
        {
            this.gearBoxTarget = gearBoxTarget;
            this.assets = assets;
        }
      }

      void Awake()
      {
        /// count all gBox into 3d model
        List<Transform> boxes = new List<Transform>();
        Transform[] elems = transform.GetComponentsInChildren<Transform>();
        int Index = 0;
        for (int c = 0; c < elems.Length; c++)
        {
          if (elems[c].name == "gearbox")
          {
            Index++;
            boxes.Add(elems[c].transform);
          }
        }

        /// set array length (1 for gBox finded)
        System.Array.Resize(ref gearboxes, Index);

        /// for all gearboxes finded (or boxes.Length... It's equal)
        for (int box = 0; box < gearboxes.Length; box++)
        {
          // get suspansions and wheels
          Transform[] inBox = boxes[box].GetComponentsInChildren<Transform>();
          List <Transform> Items = new List <Transform>();
          for (int e = 0; e < inBox.Length; e++)
          {
              var el = inBox[e];
              if (el.parent.name == "gearbox" || el.name == "wheel"){ Debug.Log(e+" => "+el); Items.Add(el); }else{Debug.Log(e);}
              if(e==inBox.Length) { Debug.Log("finder end"); }
          }

          /// add elements into the gearbox object
          Debug.Log(gearboxes[box]); // NULL!
          gearboxes[box].gearBoxTarget = boxes[box]; // NULL!
          gearboxes[box].assets.AddRange(Items); // NULL!
        }
      }
  }

Дон Не понимаю, почему длина массива изменилась, кажется, что сценарий больше не видит коробку передач, несмотря на то, что инспектор был обновлен.

Что бы вы ни пытались вставить, коробка передач ... пуста


ТЕСТ 02

Новый упрощенный тест.

Я пытаюсь инициализировать список в Awake.

Это также создает второй список, в котором элементы будут обрабатываться.

Не удается создать экземпляр объекта напрямую. Я пытаюсь перенести все из нового списка в старый.

  public class VehicleController : MonoBehaviour
  {

    public gearbox[] gearboxes;

    [System.Serializable]
    public class gearbox
    {

      public Transform boxtarget; 

        public gearbox( Transform boxtarget  )
        {
        this.boxtarget = boxtarget;
        }

    }

    void Awake()
    {

        // count all gBox and set it on inspector and add to list
        Transform[] elems = transform.GetComponentsInChildren<Transform>();
        List<Transform> targets = new List<Transform>();
        for (int c = 0; c < elems.Length; c++)
        {
          if (elems[c].name == "gearbox")
          {
            targets.Add(elems[c]);
          }
        }

        int Counter = targets.Count;

        // System.Array.Resize(ref gearboxes, Index);
        gearbox[] gboxes = new gearbox[Counter];
        gearboxes = new gearbox[Counter];

        for (int i = 0; i < Counter; ++i)
        { 

          Debug.Log(targets[i]); //ok exist
          gboxes[i].boxtarget = targets[i];
        }

        System.Array.Copy(gboxes, 0, gearboxes , 0, Counter);


    }

  }

Еще один сбой. В списке инспекторов обновление до 3 элементов, но оно пустое и отладочная запись. Null.

коробка передач (UnityEngine.Transform) (цели в порядке)

NullReferenceException: ссылка на объект не установлена ​​на экземпляр объекта VehicleControllerManager.VehicleController.Awake () (в


ТЕСТ 03

другой подход ...

Попытка теперь состоит в том, чтобы добавить класс в список и извлечь объект, принадлежащий этому классу.

Таким образом, я должен обойти тот факт, что моно указывает непосредственно на коробки передач, но видит его как дополнительный объект.

public class VehicleController : MonoBehaviour
{
    [SerializeField]
    public List<gearbox> gearboxes = new List<gearbox>();

    [System.Serializable] 
    public class gearbox
    {
      public class box
      {
        public Transform boxTarget;
        public box(Transform boxTarget)
        {
          this.boxTarget = boxTarget;
        }
      }
    }

    void Awake()
    {


      /// count all gBox into 3d model
      List<Transform> boxes = new List<Transform>();
      Transform[] elms = transform.GetComponentsInChildren<Transform>();
      int Counted = 0;
      for (int c = 0; c < elms.Length; c++)
      {
        if (elms[c].name == "gearbox")
        { Counted++; boxes.Add(elms[c].transform); }
      }

      Debug.Log(boxes.Count); // yes, it's 3

      /// add class on link (1 for all gBox finded)
      for (int box = 0; box < boxes.Count; box++)
      {
        gearboxes.Add( new VehicleController.gearbox()); // ok, added it
      }

      /// for all gearboxes in list
      for (int i = 0; i < gearboxes.Count; i++)
      {
        /// into the gearboxes get object and set values of box
        //gearboxes[i].gearbox.box.boxTarget = boxes[i]; WTF? I can't navigate into the class!??
      }

    }
}

Результат: 3 Инспектора появляются в элементах, но внутри них, похоже, ничего нет, или, во всяком случае ... "gearboxes[i].gearbox.box.boxTarget = boxes[i];" Я не могу перейти в класс ...

можно ли будет восстановить ящики и установить их внутренние значения?


ТЕСТ 03.b

Следуя различным предложениям и примерам, которые я нашел a "половинный раствор" .

Это не является окончательным, поскольку я не отображаю содержимое в инспекторе, а только вставленный класс.

Однако, если я l oop ..., данные существуют и возвращаются!

public class VehicleController : MonoBehaviour
{
    [SerializeField]        public List<gearbox> gearboxes = new List<gearbox>();
    [System.Serializable]   public class gearbox
                            {
                              public _box box = new _box();
                              [System.Serializable]
                              public class _box
                              {
                                public Transform boxTarget { get; set; }
                              }
                            }


    void Start()
    {


      /// count all gBox into 3d model
      List<Transform> boxes = new List<Transform>();
      Transform[] elms = transform.GetComponentsInChildren<Transform>();
      int Counted = 0;
      for (int c = 0; c < elms.Length; c++)
      {
        if (elms[c].name == "gearbox")
        { Counted++; boxes.Add(elms[c].transform); }
      }

      Debug.Log(boxes.Count);

      /// add class on link (1 for all gBox finded)
      for (int box = 0; box < boxes.Count; box++)
      {
        gearboxes.Add( new VehicleController.gearbox());
      }

      // for all gearboxes in list
      for (int i = 0; i < gearboxes.Count; i++)
      {
        /// add elements into the gearbox object
        gearboxes[i].box.boxTarget = boxes[i];
      }

      for (int i = 0; i < gearboxes.Count; i++)
      {
        Debug.Log("++ "+gearboxes[i].box.boxTarget);
      }

    }
}

ТЕСТ 03. c - РЕШЕНИЕ

Как предполагалось, это было "создание объекта", однако это было создано непосредственно к построению списка .

Без этого большой проблемой было бы понять, что «НЕВОЗМОЖНО МОМЕНТИРОВАТЬ ОБЪЕКТ, ЕСЛИ ЭТО ПУСТО», или вы найдете знаменитую «нулевую ошибку» .

Итак ... давайте дадим ему ноль! : D и вот решение!

public class VehicleController : MonoBehaviour
{
    [SerializeField]        public List<boxvalues> gearboxes = new List<boxvalues>();
    [System.Serializable]   public class boxvalues
                            {
                              public Transform boxTarget;
                              public boxvalues(Transform boxTarget)
                              {
                                this.boxTarget = boxTarget;
                              }
                              // [SerializeField] public Transform boxTarget { get; set; } // This is a safer system but does not expose variables.
                            }


    void Awake()
    {


      /// count all gBox into 3d model
      List<Transform> boxes = new List<Transform>();                       // prepare a list of gameObject.
      Transform[] elms = transform.GetComponentsInChildren<Transform>();   // find all child into main gameObject.
      int Counted = 0;                                                     // Counter of gameObject
      for (int c = 0; c < elms.Length; c++)                                // Loop all finded gameObject into main
      {
        if (elms[c].name == "gearbox")                                     // if is my gameObject...
        { Counted++; boxes.Add(elms[c].transform); }                       // add it to list and count it...
      }

      Debug.Log(boxes.Count);                                              // yes, It's 3 gameObject.

      /// add class on link (1 for all gBox finded)
      for (int box = 0; box < boxes.Count; box++) 
      {
        gearboxes.Add( new VehicleController.boxvalues(null));            // now for all gameObject init a new data container... empty (yooo! new list of data!)
      }

      // for all gearboxes in list
      for (int i = 0; i < gearboxes.Count; i++)                           // now for all data container... put a new values. Win!
      {
        /// add elements into the box object
        gearboxes[i].boxTarget = boxes[i];
      }

      // test return the values
      for (int i = 0; i < gearboxes.Count; i++)
      {
        Debug.Log("++ "+gearboxes[i].boxTarget);
      }

    }
}

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

Я надеюсь, что эта схема дидактически полезна для других.

1 Ответ

1 голос
/ 08 апреля 2020

Вам нужно создать экземпляр класса:

public class VehicleController : MonoBehaviour
  {
      public gearbox[] gearboxes = null;

      public VehicleController()
      {
        gearboxes = new gearbox[0];
      }

      [System.Serializable] 
      public class gearbox
      {
        public Transform gearBoxTarget;

        public List<Transform> assets = new List<Transform>();

        public gearbox(Transform gearBoxTarget, List<Transform> assets  )
        {
            this.gearBoxTarget = gearBoxTarget;
            this.assets = assets;
        }
      }

      void Awake()
      {
        /// count all gBox into 3d model
        List<Transform> boxes = new List<Transform>();
        Transform[] elems = transform.GetComponentsInChildren<Transform>();
        int Index = 0;
        for (int c = 0; c < elems.Length; c++)
        {
          if (elems[c].name == "gearbox")
          {
            Index++;
            boxes.Add(elems[c].transform);
          }
        }

        /// set array length (1 for gBox finded)
        System.Array.Resize(ref gearboxes, Index);

        /// for all gearboxes finded (or boxes.Length... It's equal)
        for (int box = 0; box < gearboxes.Length; box++)
        {
          // get suspansions and wheels
          Transform[] inBox = boxes[box].GetComponentsInChildren<Transform>();
          List <Transform> Items = new List <Transform>();
          for (int e = 0; e < inBox.Length; e++)
          {
              var el = inBox[e];
              if (el.parent.name == "gearbox" || el.name == "wheel"){ Debug.Log(e+" => "+el); Items.Add(el); }else{Debug.Log(e);}
              if(e==inBox.Length) { Debug.Log("finder end"); }
          }

          /// add elements into the gearbox object
          Debug.Log(gearboxes[box]);
          gearboxes[box].gearBoxTarget = boxes[box];
          gearboxes[box].assets.AddRange(Items);
        }
      }
  }

Я полагаю, что функция, которую вы не добавляете, должна выглядеть примерно так:

public class Transform
    {

        public string name { get; set; }

        public Transform parent { get; set; }

        public Transform[] GetComponentsInChildren<T>()
        {
            return (new List<Transform>() {
                new Transform() { name = "gearbox" },
                new Transform() { parent = new Transform() { name = "gearbox" }, name = "wheel" }
            }).ToArray();
        }
    }

Если это так, то это те же логики c, вы должны инициализировать переменную, поскольку вы инициализируете класс, иначе он всегда будет нулевым.

public class VehicleController
    {
        private gearbox[] gearboxes;
        private readonly Transform transform;

        public VehicleController(Transform _transform)
        {
            gearboxes = new gearbox[0];
            transform = _transform;
        }

        [System.Serializable]
        public class gearbox
        {
            public Transform gearBoxTarget;

            public List<Transform> assets = new List<Transform>();

            public gearbox(Transform gearBoxTarget, List<Transform> assets)
            {
                this.gearBoxTarget = gearBoxTarget;
                this.assets = assets;
            }
        }

        void Awake()
        {
            /// count all gBox into 3d model
            List<Transform> boxes = new List<Transform>();
            Transform[] elems = transform.GetComponentsInChildren<Transform>();
            int Index = 0;
            for (int c = 0; c < elems.Length; c++)
            {
                if (elems[c].name == "gearbox")
                {
                    Index++;
                    boxes.Add(elems[c].transform);
                }
            }

            /// set array length (1 for gBox finded)
            System.Array.Resize(ref gearboxes, Index);

            /// for all gearboxes finded (or boxes.Length... It's equal)
            for (int box = 0; box < gearboxes.Length; box++)
            {
                // get suspansions and wheels
                Transform[] inBox = boxes[box].GetComponentsInChildren<Transform>();
                List<Transform> Items = new List<Transform>();
                for (int e = 0; e < inBox.Length; e++)
                {
                    var el = inBox[e];
                    if (el.parent.name == "gearbox" || el.name == "wheel") { Debug.Log(e + " => " + el); Items.Add(el); } else { Debug.Log(e); }
                    if (e == inBox.Length) { Debug.Log("finder end"); }
                }

                /// add elements into the gearbox object
                Debug.Log(gearboxes[box]);
                gearboxes[box].gearBoxTarget = boxes[box];
                gearboxes[box].assets.AddRange(Items);
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...