Повешать скрипт на префаб из консоли

Раздел, посвящённый всему, что связано с программированием для Редактора Юнити. Скрипты Редактора, Wizards и прочее.

Повешать скрипт на префаб из консоли

Сообщение bboypanda 10 мар 2016, 09:24

Всем привет!
Может кто сталкивался, или знает как решить..

Есть кастомный плагин со сценой, префабом на сцене и скриптом на префабе. Иногда при копировании плагина в проект (например, из одной версии Unity в другую) ломается связь со скриптом или даже весь префаб.

Задача в том, чтобы программно открывать сцену, очищать от "старых" и "missing" префабов, пересоздавать префаб (на случай если тот совсем сломан) и вешать на префаб скрипт.

Проблема в том, что из редактора всё работает. А вот если запускать из консоли (как раз и нужно для CI), то либо (если не "применять" изменения ReplacePrefab'ом) префаб на сцене получается каким нужно, но в ассетах в поле скрипта на префабе надпись None (Mono Script), либо (если использовать ReplacePrefab) и в ассетах и на сцене у префаба будет None (Mono Script).

Может дело в том, что исполняемый скрипт лежит в папке Editor, а скрипт, который нужно прикручивать к префабу в своей отдельной папке и при консольном запуске исполняемый просто не дожидается "готовности" этого скрипта?

Хотя GetType скрипт находит:
Синтаксис:
Используется csharp
var scriptType = System.Type.GetType ("Namespace.ClassName, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false, true);
 


Тогда есть ли способ как-то всё-таки его "дожидаться"?


Синтаксис:
Используется csharp
public static void RestorePrefab()
{
        Scene myScene = EditorSceneManager.OpenScene (scenePath);

        var missingGOs = myScene.GetRootGameObjects().ToList().FindAll((go)=>{return go.name == "Missing Prefab";});

        var oldGOs = myScene.GetRootGameObjects().ToList().FindAll((go)=>{return go.name == goName;});

        if (missingGOs != null)
        {
                foreach (var item in missingGOs)
                {
                        UnityEngine.Object.DestroyImmediate (item);
                }
        }
        if (oldCrmGOs != null)
        {
                foreach (var item in oldGOs)
                {
                        UnityEngine.Object.DestroyImmediate (item);
                }
        }

        try
        {
                var scriptType = System.Type.GetType ("Namespace.ClassName, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", false, true);
        }
        catch (Exception)
        {}

        GameObject tempGO = new GameObject (goName);
        tempGO.AddComponent (scriptType);

        var newPrefab = PrefabUtility.CreatePrefab (prefabPath, tempGO);

        UnityEngine.Object.DestroyImmediate (tempGO);

        var prefabInstance = PrefabUtility.InstantiatePrefab (newPrefab);

        EditorSceneManager.SaveScene (myScene);
}
 
bboypanda
UNец
 
Сообщения: 6
Зарегистрирован: 20 дек 2014, 07:23

Re: Повешать скрипт на префаб из консоли

Сообщение DbIMok 10 мар 2016, 09:41

bboypanda писал(а):var newPrefab = PrefabUtility.CreatePrefab (prefabPath, tempGO);

вероятно затем нужен http://docs.unity3d.com/ScriptReference ... fresh.html
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: Повешать скрипт на префаб из консоли

Сообщение bboypanda 10 мар 2016, 10:13

DbIMok писал(а):вероятно затем нужен http://docs.unity3d.com/ScriptReference ... fresh.html


Увы, не помогло. Как и AssetDatabase.ImportAsset (prefabPath, ImportAssetOptions.ForceUpdate);
bboypanda
UNец
 
Сообщения: 6
Зарегистрирован: 20 дек 2014, 07:23

Re: Повешать скрипт на префаб из консоли

Сообщение IDoNotExist 10 мар 2016, 10:55

А что если попробовать так:
Синтаксис:
Используется csharp

GameObject tempGO = new GameObject (goName);

GameObject newPrefab = PrefabUtility.CreatePrefab (prefabPath, tempGO) as GameObject ;
var script = newPrefab .AddComponent (scriptType);

EditorUtility.SetDirty(script );
EditorUtility.SetDirty(newPrefab);
AssetDatabase.SaveAssets();

 
Аватара пользователя
IDoNotExist
Адепт
 
Сообщения: 1432
Зарегистрирован: 23 мар 2011, 09:18
Skype: iamnoexist

Re: Повешать скрипт на префаб из консоли

Сообщение bboypanda 10 мар 2016, 12:12

IDoNotExist писал(а):А что если попробовать так:


То же самое.. :|

Попробовал повторить последовательность действий "как в редакторе руками":
Синтаксис:
Используется csharp
newPrefab = PrefabUtility.CreateEmptyPrefab (prefabPath);

GameObject tempGO = new GameObject (goName);
tempGO.AddComponent (scriptType);

EditorSceneManager.SaveScene (myScene);

PrefabUtility.ReplacePrefab (tempGO, newPrefab, ReplacePrefabOptions.ConnectToPrefab);

EditorUtility.SetDirty (newPrefab);
AssetDatabase.SaveAssets ();

EditorSceneManager.SaveScene (myScene);
 

Но результат тот же :|
bboypanda
UNец
 
Сообщения: 6
Зарегистрирован: 20 дек 2014, 07:23

Re: Повешать скрипт на префаб из консоли

Сообщение DbIMok 10 мар 2016, 13:09

запускаю CreatePrefab.cmd, получаю Test.prefab. ссылки на месте.
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: Повешать скрипт на префаб из консоли

Сообщение bboypanda 10 мар 2016, 14:39

DbIMok писал(а):запускаю CreatePrefab.cmd, получаю Test.prefab. ссылки на месте.


Видимо дело в том, что прикрепляемого скрипта в проекте может изначально не быть. Хотя копируется он туда задолго до выполнения "восстановления" префаба и AssetDatabase.Refresh() там стоит сразу после копирования..

Тем не менее, видимо, юнити всё же не успевает понять, что скрипт уже в проекте и не может его привязать.

Можно конечно запускать две консольных команды, одну на добавление скрипта, вторую уже на пересборку префаба, но это уже больше похоже на костыль.. Может всё-таки есть способ для консоли дожидаться всех рефрешей и перекомпиляций (как [DidReloadScripts] для режима редактора)?
bboypanda
UNец
 
Сообщения: 6
Зарегистрирован: 20 дек 2014, 07:23

Re: Повешать скрипт на префаб из консоли

Сообщение DbIMok 10 мар 2016, 14:47

правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05

Re: Повешать скрипт на префаб из консоли

Сообщение bboypanda 12 мар 2016, 06:51

DbIMok писал(а):http://docs.unity3d.com/ScriptReference/EditorApplication-isCompiling.html
http://docs.unity3d.com/ScriptReference ... ating.html

Странно, но эффект тот же.. Видимо проблема в чем-то другом...
Натыкался где-то на инфу, что юнити полностью начинает воспринимать новые скрипты только после executeMethod'a, но никаких решений, кроме двойного запуска из консоли видимо так и нет
bboypanda
UNец
 
Сообщения: 6
Зарегистрирован: 20 дек 2014, 07:23

Re: Повешать скрипт на префаб из консоли

Сообщение DbIMok 13 мар 2016, 19:38

bboypanda писал(а):никаких решений, кроме двойного запуска из консоли видимо так и нет

пока видимо да (есть соотв. незакрытый багрепорт). или двойной запуск или копирование/создание скриптов до запуска юнити.
правильный вопрос - половина ответа. учитесь формулировать вопросы понятно.
Новости > _Telegram чат @unity3d_ru (11.6k/4.8k online) > _Telegram канал @unity_news (4.7k подписчиков) > Телеграм тема > "Спасибо"
Аватара пользователя
DbIMok
Адепт
 
Сообщения: 6372
Зарегистрирован: 31 июл 2009, 14:05


Вернуться в Editor

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1