Не компилированные скрипты поведения объекта

Программирование на Юнити.

Не компилированные скрипты поведения объекта

Сообщение Woolf 12 дек 2011, 22:38

Вот тут в соседней ветке подняли тему добавления скриптов поведения объекта в уже скомпилированный проект.

А вот действительно..

Дано - бандля объекта с сеткой и текстурами и скрипт поведения на c-sharp (обычный Monobehavior) в текстовом виде (в виде string, полученный по сети).. Положим, бандлю мы загрузили и проинстанировали, там ничего сложного, а вот как теперь добавить ему скрипт без перекомпиляции проекта?
Разработчик theFisherOnline - там, где клюёт
Разработчик Atom Fishing II - Первая 3D MMO про рыбалку
Разработчик Atom Fishing - Рыбалка на поплавок, донку, нахлыст, блесну в постъядерный период.
Аватара пользователя
Woolf
Адепт
 
Сообщения: 7179
Зарегистрирован: 02 мар 2009, 16:59

Re: Не компилированные скрипты поведения объекта

Сообщение Akai 13 дек 2011, 13:14

Woolf писал(а):Положим, бандлю мы загрузили и проинстанировали, там ничего сложного, а вот как теперь добавить ему скрипт без перекомпиляции проекта?

Если в общем виде, то загружаешь скрипт, как текст, создаёшь экземпляр компилятора, настраиваешь, компилируешь, создаёшь инстанс класса из скрипта. Потом надо было бы сказать: добавляешь его, как компонент, к нужному объекту графа сцены. Но тут есть проблема: юнити не знает про Microsoft.CSharp (покури в МСДН следующие пространства имён: Microsoft.CSharp и System.CodeDom.Compiler, ещё вот можно ознакомиться — «Динамическая компиляция и загрузка кода»). В связи с этим, вероятно, надо пробовать прикручивать к юнити стороннее решение. Что-нибудь типа жынта, журассика, крыостазиса или дотскрипта (первые два, правда, жабоскрипт). Или луа. Или другое, их чуть менее чем до хрена. Правда, есть сомнения, что обойдётся без бубна, но какое-нибудь да заведётся.

Сам, лично? Нет, не пробовал, так как пока без надобности. Интересовался — это да, но чисто теоретически.
Akai
UNец
 
Сообщения: 29
Зарегистрирован: 11 сен 2010, 08:26
Откуда: Вельск

Re: Не компилированные скрипты поведения объекта

Сообщение DbIMok 13 дек 2011, 13:20

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

Re: Не компилированные скрипты поведения объекта

Сообщение Akai 14 дек 2011, 17:35

Как я и думал, нашлось очень простое решение. Обобщённо оно выглядит так: нужно взять и использовать любой компилятор, который создаёт IL-код. Собственно, это всё. Компилятор транслирует исходный код, получается сборка .net, загрузив которую в тот же application domain, в котором выполняется дочернее приложение юнити (то есть наша игра), получим то, что и требовалось — натуральный, «живой» скриптинг.

Реализовать было чуть сложнее.

Сначала я хотел подружить юнити с немерлем. В плюсе то, что он опенсорсный и совершенно бесплатный, синтаксис похож на с#, ну и позволяет он выделывать всякое, что с# не умеет. А в минусе то, что он очень хреново документирован. Это — отсутствие документации — и решило исход: я от немерля отказался, раз решить задачу с наскока не удалось (это, конечно, не значит, что она в принципе не решаема, просто надо сидеть и курить исходники, а настроения на это не было).

Тогда я пошёл по пути наименьшего сопротивления: решил прикрутить то, с чем вообще не надо возиться. Поприсматривался сначала к s# (он хоть и открытый, и бесплатный, и синтаксис на с# похож, но не поддерживает ООП (правда, может притвориться, что поддерживает), а потом к c# script (это практический честный с#). Вот последний и прикрутил к юнити, причём буквально за полминуты. Серьёзно.

Допустим, есть у нас вот такой скрипт, расширяющий поведенческую реакцию какого-то объекта. Не важно, откуда он взялся: был ли получен по сети, взят с харда или вообще сгенерирован в рантайме — это совершенно по фигу, главное — код есть.

Синтаксис:
Используется csharp
using UnityEngine;

public class CSSBehaviourScript : MonoBehaviour
{
    public void Update()
    {
        this.transform.Rotate(Vector3.up, 0.01f);
    }
}
 


Тогда, чтобы использовать его в своей игре надо произвести следующие телодвижения. Во-первых, добавить DLL C# Script в свой проект (как я понимаю, в инди не сработает, хотя есть способ, но об этом ниже). Во-вторых, надо скомпилировать исходник. Сделать это можно, например, вот так:

Синтаксис:
Используется csharp
using UnityEngine;
using System.Reflection;
// Подключим библиотеку для использования C# Script'а
using CSScriptLibrary;

public class CSSBehaviourExtender : MonoBehaviour
{
    public void SetBehaviour(string SourceCode)
    {
        if (SourceCode.Length > 0)
        {
                // Переданный в качестве параметра в функцию код компилируется
                // в отдельную сборку, с которой уже можно работать хоть стандартными
                // средствами System.Reflection, хоть средствами библиотеки C# Script'а,
                // и она загружается автоматически в текущий application domain
                Assembly assembly = CSScript.LoadCode(SourceCode, null);
                // Получаем список типов, которые определены в сборке
                System.Type[] types = assembly.GetTypes();
                if (types.Length > 0)
                {
                    // Допустим, первый попавшийся тип и есть наследник монобеха,
                    // соответственно ему и лезть на объект
                    this.gameObject.AddComponent(types[0]);
                }
        }
    }
}

Этот код висит на объекте, поведение которого необходимо изменить полученным скриптом. Для изменения необходимо вызвать единственный метод SetBehaviour(), который я описал, и в качестве параметра передать ему строку, содержащую исходный код скрипта. Для работы в реальных условиях, конечно, не помешало бы добавить дополнительных проверок (так, компиляция может завершиться с ошибкой, в этом случае C# Script бросит исключение) и поменять принцип добавления (скажем, делать это сразу для множества объектов и при загрузке очередного уровня). Но в качестве примера допустимо и так. Главное, что этот код компилируется и работает. Тестовый скрипт тоже компилируется (уже в рантайме), добавляется на объект как компонент и прекрасно работает. Задача решена.

Вот в билде под веб C# Script юнити почему-то зарезала. Но приятная новость, что он распространяется в том числе и в исходниках, то есть потенциально скриптинг доступен и в вебе (а также для инди-версии). Но, думаю, уже с этим будут некоторые сложности: там лицензия изменения в исходном коде чётко оговаривает — нельзя. Взять C# Script можно здесь. Он, кстати, поддерживает не только c# синтаксис и прекрасно документирован. Разработчик — Олег Шило.

В общем, для себя я решил. Неплохой вариант, пока немерль к юнити не прикручу.
Akai
UNец
 
Сообщения: 29
Зарегистрирован: 11 сен 2010, 08:26
Откуда: Вельск

Re: Не компилированные скрипты поведения объекта

Сообщение gnoblin 14 дек 2011, 18:51

dll на C# можно использовать в проекте на unity (free) без проблем (ограничение есть для native плагинов)

за пример спс!
skypeid: madkust
Мои крайние проекты:
Убойный Хоккей
Cube Day Z (альфа)
Аватара пользователя
gnoblin
Адепт
 
Сообщения: 4633
Зарегистрирован: 08 окт 2008, 17:23
Откуда: Минск, Беларусь
Skype: madkust
  • Сайт

Re: Не компилированные скрипты поведения объекта

Сообщение Akai 14 дек 2011, 19:57

Значит, проблемы нет. Отлично.
Akai
UNец
 
Сообщения: 29
Зарегистрирован: 11 сен 2010, 08:26
Откуда: Вельск

Re: Не компилированные скрипты поведения объекта

Сообщение slawik 18 фев 2014, 13:25

Добрый день. У меня возникло несколько вопросов.
1. как сделать чтобы скрипт работал уже в скомпилированной программе?
2. Как обратиться к созданному скрипту из другого скрипта?

вот скрипт
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using CSScriptLibrary;
using System.Reflection;

public class scene1_1 : MonoBehaviour
{
    public string peremennaya;
    // Use this for initialization
    void Start()
    {
        peremennaya = @"
using UnityEngine;
using System.Collections;

public class scene1_2 : MonoBehaviour
{
public string proverka;

void OnGUI()
    {
        GUI.Box(new Rect(100, 100, 200, 200), "
"slawik"");
    }
}"
;
        SetBehaviour(peremennaya);
        //GameObject dialog = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
    }
    public void SetBehaviour(string SourceCode)
    {
        if (SourceCode.Length > 0)
        {
            // Переданный в качестве параметра в функцию код компилируется
            // в отдельную сборку, с которой уже можно работать хоть стандартными
            // средствами System.Reflection, хоть средствами библиотеки C# Script'а,
            // и она загружается автоматически в текущий application domain
            Assembly assembly = CSScript.LoadCode(SourceCode, null);
            // Получаем список типов, которые определены в сборке
            System.Type[] types = assembly.GetTypes();
            if (types.Length > 0)
            {
                // Допустим, первый попавшийся тип и есть наследник монобеха,
                // соответственно ему и лезть на объект
                //GameObject dialog = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                this.gameObject.AddComponent(types[0]);
            }

        }
    }
}
 
Последний раз редактировалось slawik 18 фев 2014, 23:08, всего редактировалось 1 раз.
slawik
UNец
 
Сообщения: 47
Зарегистрирован: 06 янв 2012, 17:43

Re: Не компилированные скрипты поведения объекта

Сообщение zzz7net 18 фев 2014, 17:49

А Buildout, это о чём? Нельзя к этой ситуации применить?
Добавить mvd777 в Skype
Аватара пользователя
zzz7net
UNITрон
 
Сообщения: 273
Зарегистрирован: 21 июн 2011, 13:26
Откуда: Eastern Siberia
Skype: mvd777

Re: Не компилированные скрипты поведения объекта

Сообщение slawik 18 фев 2014, 18:52

честно я не знаю что это и как оно работает
slawik
UNец
 
Сообщения: 47
Зарегистрирован: 06 янв 2012, 17:43

Re: Не компилированные скрипты поведения объекта

Сообщение seaman 18 фев 2014, 19:04

Как обратиться к созданному скрипту из другого скрипта?

Читаем FAQ
как сделать чтобы скрипт работал уже в скомпилированной программе?

А Вы не считаете, что Вам еще рано об этом думать, раз возникают вопросы #2? Подучитесь слегка, потом поговорим.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Не компилированные скрипты поведения объекта

Сообщение slawik 18 фев 2014, 19:22

1. При создании скрипта таким образом у него нету имени и как вы прикажите к нему обращаться? (transform.GetComponent<scene1_1>().peremennaya = "name";) я если что с Unity3D не один год знаком
2. возле каждого скрипта пишется название, а у него нету этого названия
slawik
UNец
 
Сообщения: 47
Зарегистрирован: 06 янв 2012, 17:43

Re: Не компилированные скрипты поведения объекта

Сообщение seaman 18 фев 2014, 19:32

Это
При создании скрипта таким образом у него нету имени

абсолютно не стыкуется с этим
я если что с Unity3D не один год знаком

Либо одно,либо другое - ложь. И я уверен, что второе.
Синтаксис:
Используется csharp
transform.GetComponent<scene1_1>().peremennaya

Что в данном случае по Вашему - scene1_1?
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Не компилированные скрипты поведения объекта

Сообщение slawik 18 фев 2014, 19:44

1. scene1_1 - это название скрипта
2. если я был бы знаком как вы утверждаете мало времени я бы не написал http://www.portal-unity3d.ru/ вот такую вещь
3. если и этому вы не верите 1. можете посмотреть на дату регистрации 2. или на крайний случай спросить у Neodrop
4. я начинал учиться с уроков Огасоды + сейчас изучаю и пытаюсь писать сервер на Photone
5. вы хоть пробовали запустить на своей машине вот этот скрипт
Синтаксис:
Используется csharp
using UnityEngine;
using System.Collections;
using CSScriptLibrary;
using System.Reflection;

public class scene1_1 : MonoBehaviour
{
    public string peremennaya;
    // Use this for initialization
    void Start()
    {
        peremennaya = @"
using UnityEngine;
using System.Collections;

public class scene1_2 : MonoBehaviour
{
public string proverka;

void OnGUI()
    {
        GUI.Box(new Rect(100, 100, 200, 200), "
"slawik"");
    }
}"
;
        SetBehaviour(peremennaya);
        //GameObject dialog = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
    }
    public void SetBehaviour(string SourceCode)
    {
        if (SourceCode.Length > 0)
        {
            // Переданный в качестве параметра в функцию код компилируется
            // в отдельную сборку, с которой уже можно работать хоть стандартными
            // средствами System.Reflection, хоть средствами библиотеки C# Script'а,
            // и она загружается автоматически в текущий application domain
            Assembly assembly = CSScript.LoadCode(SourceCode, null);
            // Получаем список типов, которые определены в сборке
            System.Type[] types = assembly.GetTypes();
            if (types.Length > 0)
            {
                // Допустим, первый попавшийся тип и есть наследник монобеха,
                // соответственно ему и лезть на объект
                //GameObject dialog = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                this.gameObject.AddComponent(types[0]);
            }

        }
    }
}
 
Последний раз редактировалось slawik 18 фев 2014, 23:08, всего редактировалось 1 раз.
slawik
UNец
 
Сообщения: 47
Зарегистрирован: 06 янв 2012, 17:43

Re: Не компилированные скрипты поведения объекта

Сообщение seaman 18 фев 2014, 21:11

Вы сами читаете, что пишете,- или накурились?
scene1_1 - это название скрипта

При создании скрипта таким образом у него нету имени

Так есть или нет? Вы уж определитесь!
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Не компилированные скрипты поведения объекта

Сообщение slawik 18 фев 2014, 23:21

1. seaman вопрос именно к вам, вы читаете с начала материал или отрывками? (если вы читаете отрывками, то вы не понимаете основной сути)
2. если бы вы прочитали тот скрипт который я 2 раза продемонстрировал вы бы поняли, что есть основной скрипт "scene1_1", который уже висит на объекте и в свою очередь создает из string другой скрипт (будем называть его "скрипт 2") и вешает на тот же самый объект на котором висит скрипт "scene1_1".
3. вот собственно вопрос как обратиться к скрипту 2 если у него нету имени?
У вас нет доступа для просмотра вложений в этом сообщении.
slawik
UNец
 
Сообщения: 47
Зарегистрирован: 06 янв 2012, 17:43

След.

Вернуться в Скрипты

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

Сейчас этот форум просматривают: Yandex [Bot] и гости: 18