Понедельник, 11 Ноября 2024, 12:38

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
DestroyImmediate ошибка
SmallNibblerДата: Воскресенье, 27 Сентября 2015, 20:39 | Сообщение # 1
частый гость
Сейчас нет на сайте
Написал добавление используемого компонента, при добавлении компонента использующего компонента в инспектор, и удаление используемого компонента, при удалении использующего компонента. Если не понятно, то вот скрипт:
Код
using UnityEngine;
using System.Collections;

[ExecuteInEditMode]
public class Test : MonoBehaviour {

   void Awake ()   
   {
    gameObject.AddComponent<SpriteRenderer>();
   }

   void OnDestroy()
   {
    DestroyImmediate (GetComponent<SpriteRenderer>());
   }
}


Лог ошибки:
Код
Destroying object multiple times. Don't use DestroyImmediate on the same object in OnDisable or OnDestroy.
UnityEngine.Object:DestroyImmediate(Object)
Test:OnDestroy() (at Assets/Test.cs:14)


Вообще цель этого скрипта, это добавлять компонент SpriteRenderer когда я добавляю скрипт в инспектор, и удалять его когда я удаляю скрипт. Атрибут RequireComponent не предлагать, потому что я использую HideFlags.HideInInspector, по этому когда я удаляю скрипт, компонент остается на объекте и его не как не убрать.

Как мне быть? Заранее спасибо!


Сообщение отредактировал SmallNibbler - Воскресенье, 27 Сентября 2015, 20:40
berilДата: Воскресенье, 27 Сентября 2015, 21:43 | Сообщение # 2
Я не ленивый, я — энергосберегающий
Сейчас нет на сайте
Посмотри это, может поможет



Накодил? Убери за собой!
Инвентарь в Unity(UI)
Инвентарь в Unity(GUI)
SmallNibblerДата: Понедельник, 28 Сентября 2015, 18:12 | Сообщение # 3
частый гость
Сейчас нет на сайте
Цитата beril ()
Посмотри это, может поможет


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

Код
using UnityEngine;
using System.Collections.Generic;

namespace de.softfun.drawntogether {
     public class EnhancedBehavior : MonoBehaviour {
         private List<GameObject> linkedObjects = new List<GameObject>();

         protected void destroy(params GameObject[] objects) {
             foreach (GameObject o in objects) {
                 try {
                     Destroy(o);
                 } catch {
                     continue;
                 }
             }
         }

         public void LinkObjects(params GameObject[] objects) {
             foreach (GameObject o in objects) {
                 linkedObjects.Add(o);
             }
         }

         void OnDestroy() {
             foreach (GameObject o in linkedObjects) {
                 destroy(o);
             }
         }

         protected T instantiate<T>(T prefab, bool addLink = true) where T : Object {
             T o =  (T)Instantiate(prefab);
             if (addLink && (o is GameObject)) {
                 linkedObjects.add(o);
             }
             return o;
         }

     }
}

Добавлено (28 сентября 2015, 17:13)
---------------------------------------------
А нет, поспешил с выводами, ошибка не исчезла. Она возникает при нажатии кнопки play.
Подскажите boolean переменную которая показывает воспроизведена игра или нет, думаю это исправит проблему.

Добавлено (28 сентября 2015, 17:26)
---------------------------------------------
Попробовал Application.isPlaying не помогает. Насколько я понимаю когда в инспекторе нажимается Remove Component то вызывается метод OnDestroy(), и мне нужно как то при нажатии Remove Component делать DestroyImmediate, но в OnDestroy() не получается, потому что при запуске игры и её остановки вылазят ошибки. Подскажите решение.

Добавлено (28 сентября 2015, 18:12)
---------------------------------------------
Нашел решение:

Код
using UnityEngine;
using System.Collections;
using UnityEditor;

[ExecuteInEditMode]
public class Test : MonoBehaviourEnhanced {

  void Awake ()   
  {
   if(!GetComponent<SpriteRenderer>())gameObject.AddComponent <SpriteRenderer> ();
  }

  void OnDestroy()
  {
   if(Application.isPlaying || Application.isLoadingLevel || EditorApplication.isPlayingOrWillChangePlaymode) return;
    else DestroyImmediate (GetComponent<SpriteRenderer>());
  }
}
berilДата: Понедельник, 28 Сентября 2015, 18:18 | Сообщение # 4
Я не ленивый, я — энергосберегающий
Сейчас нет на сайте
Как вариант можешь свое контекстное меню сделать, перекрыв базовое (я так понимаю оно перекрывает базовые пункты меню
Код

   //[ContextMenu("Remove Component")]
      //void DoSomething()
      //{
      //    foreach (GameObject o in Selection.gameObjects)
      //    {
      //        DestroyImmediate(o, true);
      //    }
      //}
)
Вроде все работает

Цитата SmallNibbler ()
Нашел решение:

Это хорошо)




Накодил? Убери за собой!
Инвентарь в Unity(UI)
Инвентарь в Unity(GUI)
SmallNibblerДата: Понедельник, 28 Сентября 2015, 20:18 | Сообщение # 5
частый гость
Сейчас нет на сайте
Цитата beril ()
Как вариант можешь свое контекстное меню сделать, перекрыв базовое

Идеально, то что нужно! Спасибо!
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг