| 
				
				Написание псевдоскрипта для быстрого скриптинга уровней.
				 |   |  
| alexsilent | Дата: Пятница, 17 Апреля 2015, 15:54 | Сообщение # 1 |  
 
почти ветеран 
Сейчас нет на сайте 
 
 | Приветствую друзья! Пишу псевдоскрипт, для быстрого написания мини скриптов,   для меня очень удобно писать сокращённо, очень давно я придумал свой встроенный скрипт в Blitz Max,   для скриптинга уровней, теперь хочу перенести его в Unity3d (ибо мой скрипт оптимизирован под "1 короткая строка - максимум результата",   а в обычном скрипте я буду писать всё это очень долго, каждый раз забывая длинные фразы и поглядывая в документацию): 
   Код    if collision player         create obj1 100,100,0         send last Rename item         talk hi1         talk hi2         delete   end      
   И появились вопросы: 
   1) Появился пока барьер, который не могу обойти: 
   Нужно принять сообщение от SendMessage, оно может быть абсолютно любое,   есть ли какие-то другие средства перехвата сообщения, кроме самого названия функции? 
   Либо придётся прописывать все возможные варианты принятия сообщений в виде функций,   но это будет слегка тягомотно. 
   2)  Можно ли как-то превращать строку String  в математическое действие, чтобы это всё само посчиталось?   Либо придётся по старинке, парсером. Но вдруг есть халявный метод?
 
 Сообщение отредактировал alexsilent - Пятница, 17 Апреля 2015, 16:22  |  
| 
 | 
 |    |  
| MANMANA | Дата: Суббота, 18 Апреля 2015, 07:46 | Сообщение # 2 |  
| 
 почти ветеран 
Сейчас нет на сайте 
 
 | Цитата alexsilent (  )  2) Можно ли как-то превращать строку String     кхы, пока копался, нарыл вот такое http://www.blackbeltcoder.com/Article....aluator   функционал можно дописать самому, а главное выражения можно брать от пользователей     но все равно - это парсер
  http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг   VKонтакте 3Dbuffer 
   Последнее: 
   Новый раздел "Текстуры" 
   Как запатентовать, защитить техническое решение, игру, идею
 |  
| 
 | 
 |    |  
| beril | Дата: Суббота, 18 Апреля 2015, 09:26 | Сообщение # 3 |  
 
Я не ленивый, я — энергосберегающий 
Сейчас нет на сайте 
 
 | Цитата MANMANA (  )  т SendMessage     лучше бы ты не использовал часто этот метод и подобные ему
 
         Накодил? Убери за собой!   Инвентарь в Unity(UI)   Инвентарь в Unity(GUI) 
 |  
| 
 | 
 |    |  
| alexsilent | Дата: Суббота, 18 Апреля 2015, 09:39 | Сообщение # 4 |  
 
почти ветеран 
Сейчас нет на сайте 
 
 | Цитата beril (  )  лучше бы ты не использовал часто этот метод и подобные ему     дорогая операция?   Просто у меня не стратегия (субъектов не много), я думаю сильно проблематично с этим не будет. Не так массивно у меня проводятся SendMessage     как это было бы в играх жанра RTS   Очень часто мне нужно именно SendMessage и BroadcastMessage, ибо я дизайнер, я не люблю много кода , много текста и много строк,   из-за этого я и пишу этот псевдоскриптер, чтобы в будущем ограничить себя от большого кода,   и мне нужна простая и универсальная передача данных, а не сложная.   GetComponent сложная, статичная и не универсальная - чтобы передать данные из скрипта, надо во первых знать, как этот скрипт называется,   (обязательно прописать название скрипта в качестве типа этой переменной принимающей скрипт),   а что если я с разных скриптов передаю эту информацию? И тогда мне помогает SendMessage, чтобы не знать и не прописывать все варианты   откуда эта информация может передаваться. А иногда нужно нескольким сразу поведениям на одном объекте принять один и тот же сигнал.   Если б был ещё более простой и универсальный способ, я б им пользовался) 
   Мне нужно от кода минимум текста - максимум результата), даже если это дороже по затратам процессов. 
   PS В Юнити иногда требуется очень много писать, я каждый божий раз забываю даже избитую оскоминой фразу, как правильно писать:   gameObject.SendMessage("Messsage",text, эту длинную фразу, которую я всегда забываю и ищу в документациях или копипаста) я о фразе SendMessageOptions.DontRequireReceiver (почему по дефолту не стоит эта опция?)   Юнити совсем не способствует сокращению писанины, хотя бывают некоторые полезные упрощения, но фразы часто очень длинные и легко забываемые   для дизайнеров, которые больше используют правое полушарие мозга и не всегда любят зубрёжку и логику.
 
 Сообщение отредактировал alexsilent - Суббота, 18 Апреля 2015, 11:10  |  
| 
 | 
 |    |  
| beril | Дата: Суббота, 18 Апреля 2015, 09:50 | Сообщение # 5 |  
 
Я не ленивый, я — энергосберегающий 
Сейчас нет на сайте 
 
 | Что то типо того, если есть возможность избегай их (SendMessage, BroadcastMessage). Используй стандартные нетовские делегаты и события или можно, как вариант CSharpMessenger 
   Можешь почитать дискуссии по этому поводу на форуме unity. К примеру тут  
   Цитата So, on my (rather old) machine, a loop of 5000000 SendMessage calls, using an empty function, takes 9.872 seconds. A loop of 5000000 direct calls (using a cached GetComponent) takes .024 seconds.      Обычно падение производительности если используес ПК не так критична, но вот под мобильные устройство очень сильно заметно 
   Цитата alexsilent (  )  Мне нужно от кода минимум текста - максимум результата), даже если это дороже по затратам процессов.      Тогда CSharpMessenger, если нет желания разбираться с делегатами и событиями.
 
         Накодил? Убери за собой!   Инвентарь в Unity(UI)   Инвентарь в Unity(GUI) 
 
 Сообщение отредактировал beril - Суббота, 18 Апреля 2015, 09:56  |  
| 
 | 
 |    |  
| alexsilent | Дата: Понедельник, 20 Апреля 2015, 10:13 | Сообщение # 6 |  
 
почти ветеран 
Сейчас нет на сайте 
 
 | Цитата MANMANA (  )  кхы, пока копался, нарыл вот такое http://www.blackbeltcoder.com/Article....aluator   функционал можно дописать самому, а главное выражения можно брать от пользователей   но все равно - это парсер     MANMANA, спасибо большое! Интересная вещь.   
   Добавлено (20 апреля 2015, 10:10)   ---------------------------------------------   Сделал первую версию ускоренного скриптера для уровней)   Не будет рекомпиляции после написания мини-кода, и вдобавок тот же самый код пишется быстрее в разы   и не будет проблем с небольшими уникальными кодами   (естественно, в скорости будет заметно проигрывать обычному коду,   но это будет подходить для уникальных событий, коих будет не мало, но и не так уж и много на одной локации):     
   Добавлено (20 апреля 2015, 10:13)   ---------------------------------------------   Цитата beril (  )  Тогда CSharpMessenger, если нет желания разбираться с делегатами и событиями.      beril, спасибо!  
 
 Сообщение отредактировал alexsilent - Понедельник, 20 Апреля 2015, 10:16  |  
| 
 | 
 |    |  
| MANMANA | Дата: Понедельник, 20 Апреля 2015, 12:09 | Сообщение # 7 |  
| 
 почти ветеран 
Сейчас нет на сайте 
 
 | на чем реализовал?
  http://www.3dbuffer.com/ Текстуры, Unity3D, Blender: Эффекты, скрипты, моделирование, текстурирование, скульптинг   VKонтакте 3Dbuffer 
   Последнее: 
   Новый раздел "Текстуры" 
   Как запатентовать, защитить техническое решение, игру, идею
 |  
| 
 | 
 |    |  
| alexsilent | Дата: Понедельник, 20 Апреля 2015, 14:01 | Сообщение # 8 |  
 
почти ветеран 
Сейчас нет на сайте 
 
 | Цитата MANMANA (  )  на чем реализовал?   
   На ЯваСкрипт, конечно я не программист и получилось, как обычно г*код :3 
   Ещё switch не успел прикрутить к этой основе, не до конца наполнил скрипт. 
   Код    #pragma strict 
   // загрузка уровней: резкая / плавная(игровая)   // принимать и посылать мессаги   // создавать объекты, двигать объекты, крутить их, ставить объекты в нужное место, удалять объекты   // задержка скрипта для катсцены(пауза), delay   // Global.Quake, Camera Fade Control,    // контроль сутками и погодой (возможно)   // контроль туманом и эмбинтом (возможно)   // менять музыку, играть звук, играть анимацию   // менять цвет и спрайт   // управлять сторонними гейм-объектами   // выводить сообщение игры 
   // особые переменные Global   // присваивать переменные к гейм объекту   // локальные и глобальные переменные в пределах скриптера для обмена между скриптерами   // Global.Var 
   // проверка, удаление и запись квестов   // проверка переменных Global.Var и других   // проверка столкновения, проверка Fade Camera   // проверка суток и погоды (возможно)   // проверка использование вещи, проверка вещи в инвентаре(возможно)   // проверка дистанции   // проверять звук, анимацию 
   // генератор случайностей   // abs   // lerp lerpangle   // vector3 ?   // distance   // sin cos time   // clamp ?   // int   // sign 
   // switch (?) смогу ли реализовать? 
   @Multiline (15)   var Code : String; // изначальный текст кода 
   // движение по строкам   private var LastLine : int; // может стоит убрать или нет?? 
   private var Text : Codes[]; // разобранный код 
   class Codes {    var Word : String[];   } 
   private var CurrentLine : int; // текущая линия 
   private var LastCreatedObject : GameObject; // хранение последнего созданного объекта для каждого скрипта отдельно 
   // локальные переменные   private var LocalInt : int[] = new int[10];   // библиотека объектов   // слушатель   // команды операторы 
   function Awake() {    // инициализация локальных переменных 
    // взять код, парсить на линии    Code = Code.Replace("\t", ""); // remove TAB char    var words : String[] = Code.Split("\n"[0]);    // создать массив слов    Text = new Codes[words.length];    // парсить линии на слова, убирать пустые слова    for (var num : int = 0; num < words.length; num++) {     var words2 : String[] = words[num].Split(" "[0]); // парсить     var newarr : Array = new Array (words2); // создать временный массив     // проверка на пустые слова, и убирать их     for (var a : int = newarr.length-1; a > 0-1; a--) {      if ((newarr[a] as String) == "" || (newarr[a] as String) == null || (newarr[a] as String) == " ") {       newarr.RemoveAt(a);      }     }     // назад в свой массив     Text[num] = new Codes(); // init     Text[num].Word = newarr.ToBuiltin(String) as String[];     // debug log     print("****** debug: "+num);     var text : String;     for (var num2 : int = 0; num2 < Text[num].Word.length; num2++) {      text += Text[num].Word[num2]+"*";     }     print(text);    }   } 
   function Update() {    if (Global.Pause) return;        ScriptReader();   } 
   function ScriptReader() {    // читать скрипт от начала до конца    if (Text.length == 0) return; // коррекция, если нет кода    if (LastLine >= Text.length) {LastLine = 0;} // сначала 
    // читать    for (CurrentLine = LastLine; CurrentLine < Text.length; CurrentLine++) {     if (CurrentLine >= Text.length) return; // внезапный конец, коррекция при перемотке if end     LastLine = CurrentLine+1; // последняя строка     var check : String = ScriptCore(CurrentLine); // ядро скрипта, чтение оператора     print("CurrentLine: "+CurrentLine+" Text "+Text[CurrentLine].Word[0]);     switch (check) {      case "stop": // внезапно остановить чтение скрипта       LastLine = 0;       return;break;      default:       break;     }    }    LastLine = 0; // сброс строк   } 
   // Конвертация слов в переменные int   function GrabInt(name : String) : int {    if (name == null) {return 0;}    var words : String[] = name.Split("!"[0]); // Парсить слово    switch (words[0]) {     case "l": // возвращение локальной переменной внутри скрипта      return LocalInt[System.Convert.ToInt32(words[1])];     default:      return System.Convert.ToInt32(name);      break;    }   } 
   // Конвертация слов в объекты   function GrabObject(name : String) : GameObject {    if (name == null) {return gameObject;} // этот объект по умолчанию, когда не понятно, что возвращать    var words : String[] = name.Split("!"[0]); // Парсить слово    switch (words[0]) {     case "it": // этот объект      return gameObject;     default: // этот объект по умолчанию, когда не понятно, что возвращать      return gameObject;      break;    }   } 
   // Конвертация слов в вектор   function GrabVector(name : String) : Vector3 {    if (name == null) {return Vector3.zero;} // возвращение пустого вектора    var words : String[] = name.Split("!"[0]); // Парсить слово    switch (words[0]) {     case "v": // свой вектор      return Vector3(System.Convert.ToInt32(words[1]),System.Convert.ToInt32(words[2]),System.Convert.ToInt32(words[3]));     case "t": case "trans": // возвращение позиции трансформа      if (words.length > 1) { // если больше одного слова       if (words[1] == "last" || words[1] == "l") {return LastCreatedObject.transform.position;} // возвращение позиции недавно созданного объекта      } else {       return transform.position; // возвращение позиции себя по умолчанию      }      break;     default:      return Vector3.zero; // возвращение пустого вектора      break;    }   } 
   // If проверка   function IfCore(WORD : String[]) : boolean {    if (WORD[1] == null) {return false;}    switch(WORD[1]) { // проверка второго слова после "If"     case "":      break;     default: // остальные проверки, к примеру локальные переменные      var words : String[] = WORD[1].Split("!"[0]); // Парсить второе слово      switch (words[0]) {       case "l": // проверка локальной переменной [if <A> {< > != ==} <B>]        var loc : int = LocalInt[System.Convert.ToInt32(words[1])];        return (IfAction(loc,WORD[2],WORD[3])); // возвращать результат проверки      }      break;    }   } 
   function IfAction(A : int, B : String, B2 : String) { // if (A) (B < > = >= <=) <B2>    var C : int = GrabInt(B2); 
    switch(B) {     case "=": case "==":      if (A == C) {return true;}      break;     case "<": if (A < C) {return true;}      break;     case ">": if (A > C) {return true;}      break;     case "<=": if (A <= C) {return true;}      break;     case ">=": if (A >= C) {return true;}      break;     case "!=": if (A != C) {return true;}      break;    }    return false;   } 
   // Математические операции   function MathAction(A : float,WORD : String[]) : int {    // {A} {=+-*/} {B} ( {+-*/} {C} )    var B : float = GrabInt(WORD[2]);    var C : float = GrabInt(WORD[4]);    switch (WORD[1]+WORD[3]) {     case "=":      return B;break; // A = B 
     case "=+": return B+C; break; // A = B + C     case "=-": return B-C; break; // A = B - C     case "=*": return B*C; break; // A = B * C     case "=/": return B/C; break; // A = B / C 
     case "+": return A+B; break; // A += B     case "-": return A-B; break; // A -= B     case "*": return A*B; break; // A *= B     case "/": return A/B; break; // A /= B 
     default: return B; break; // A = B    }   } 
   // Ядро движка скриптов   function ScriptCore(num : int) : String {    if (Text[num].Word.length == 0) return; // коррекция    if (Text[num].Word[0].Substring(0,1) == "/") return ""; // комментарий пропускаем 
    var ifnum : int = 0;    var a : int; 
    var WORD : String[] = new String[7];    if (Text[num].Word.length > 0) WORD[0] = Text[num].Word[0];    if (Text[num].Word.length > 1) WORD[1] = Text[num].Word[1];    if (Text[num].Word.length > 2) WORD[2] = Text[num].Word[2];    if (Text[num].Word.length > 3) WORD[3] = Text[num].Word[3];    if (Text[num].Word.length > 4) WORD[4] = Text[num].Word[4]; 
    switch(WORD[0]) {     case "print": // принт для отладки      if (WORD[2]) {       print(""+WORD[1]+" "+GrabInt(WORD[2]));      } else {       print(""+WORD[1]);      }      break; 
     /*case "switch": // switch [switch <GrabInt>]      Switcher = GrabInt(WORD[1]);      break;     case "case": // case [case <name$/num$>]      if (Switcher != GrabInt)      break;     case "def": case "default": // default case      if ()      break;*/ 
     case "if": // оператор если      if (IfCore(WORD)) {       // читать дальше скрипт, потому-что выполнено условие       print("IfCore() "+num);      } else {       print("else: "+num);       // искать конец ветви, потому-что не выполнено условие       ifnum = 0;       for (a = num+1; a < Text.length; a++) { // пройти по всему скрипту от текущего места, в поисках конца условия        if (Text[a].Word.length > 0) { // если в строке есть хоть одно слово         if (Text[a].Word[0] == "if") {ifnum++;} // новое условие, углубиться дальше         if (Text[a].Word[0] == "get") {ifnum++;} // новое условие, углубиться дальше         if (Text[a].Word[0] == "switch") {ifnum++;} // свитч         if (Text[a].Word[0] == "end") {ifnum--;} // вслпыть с условия 
         if (Text[a].Word[0] == "else" && ifnum == 0) { // else условие          CurrentLine=a;return "ok"; // найден конец ветви else         } 
         if (ifnum < 0) {CurrentLine=a;return "ok";} // найден конец ветви        }       }       return "stop";      }      break;     case "else": // оператор иначе      // искать конец ветви для Else т.е. искать свой END       ifnum = 0;       for (a = num+1; a < Text.length; a++) { // пройти по всему скрипту от текущего места, в поисках конца условия        if (Text[a].Word.length > 0) { // если в строке есть хоть одно слово         if (Text[a].Word[0] == "if") {ifnum++;} // новое условие, углубиться дальше         if (Text[a].Word[0] == "get") {ifnum++;} // новое условие, углубиться дальше         if (Text[a].Word[0] == "switch") {ifnum++;} // свитч         if (Text[a].Word[0] == "end") {ifnum--;} // вслпыть с условия 
         if (ifnum < 0) {CurrentLine=a; return "ok";} // найден конец ветви        }       }       return "stop";      break;     // конец if get switch etc     case "end": // end if / end get / etc      break; 
     // остановить скрипт     case "stop": // [stop] stop the script      return "stop";      break;     // отключить (удалить) скрипт до перегрузки уровня[off]     case "off":      Destroy(this);      return "stop";      break;     // задержка скрипта для катсцены(пауза),      case "delay": // delay []      // взять время, и потом проверять время в Update      // ?????????????????????????????????????      break; 
     // загрузка уровней: резкая / плавная(игровая)     case "load": // load level [load <name$> <id$>]      Global.LoadLEVEL(WORD[1],WORD[2]);      break;     // принимать и посылать мессаги     case "send": // send message [send <game object> <name$> <mode$>]      GrabObject(WORD[1]).SendMessage(WORD[2],WORD[3],SendMessageOptions.DontRequireReceiver);      break; 
     // создавать объекты, двигать объекты, крутить их, ставить объекты в нужное место, удалять объекты     case "create": // [create <game object> <position>]      LastCreatedObject = Instantiate(GrabObject(WORD[1]),GrabVector(WORD[2]),Quaternion.identity);      break;     case "pos": case "position":// изменять позицию объекта [pos <GO> <position>]      GrabObject(WORD[1]).transform.position = GrabVector(WORD[2]);      break;     case "locPos": // изменять локальную позицию объекта [locPos <GO> <position>]      GrabObject(WORD[1]).transform.localPosition = GrabVector(WORD[2]);      break;     // Global.Quake, Camera Fade Control     case "ang": case "angle": // set angle [ang <GO> <vector>]      GrabObject(WORD[1]).transform.eulerAngles = GrabVector(WORD[2]);      break;     case "locAng":// local angle [locAng <GO> <vector>]      GrabObject(WORD[1]).transform.localEulerAngles = GrabVector(WORD[2]);      break;     // удалить объект     case "delete": // [delete <game object>] delete object      Destroy(GrabObject(WORD[1]));      return "stop";      break;     // контроль сутками и погодой (возможно)     // контроль туманом и эмбинтом (возможно)     // менять музыку, играть звук, играть анимацию     // менять цвет и спрайт     // управлять сторонними гейм-объектами     // выводить сообщение игры     default: // различные действия присвоения      var words : String[] = WORD[0].Split("!"[0]); // Парсить первое слово      switch (words[0]) {       case "l": // [l.2 = <A> <+ - * /> <B>]        var loc : int = System.Convert.ToInt32(words[1]);        var nn : int = MathAction(LocalInt[loc],WORD);        LocalInt[loc] = nn; // математические операции        break;       default:        // ???????        break;      }      break;    }   }     
 
 Сообщение отредактировал alexsilent - Понедельник, 20 Апреля 2015, 14:29  |  
| 
 | 
 |    |  
| Storm54 | Дата: Понедельник, 20 Апреля 2015, 14:54 | Сообщение # 9 |  
 
постоянный участник 
Сейчас нет на сайте 
 
 | Цитата alexsilent (  )  Приветствую друзья! Пишу псевдоскрипт, для быстрого написания мини скриптов,   для меня очень удобно писать сокращённо, очень давно я придумал свой встроенный скрипт в Blitz Max,   для скриптинга уровней, теперь хочу перенести его в Unity3d (ибо мой скрипт оптимизирован под "1 короткая строка - максимум результата",   а в обычном скрипте я буду писать всё это очень долго, каждый раз забывая длинные фразы и поглядывая в документацию):      Ставишь студию и решарпер. И не нужно никуда подсматривать.
 |  
| 
 | 
 |    |   |     
		
		 
 |