Пятница, 09 Июня 2023, 05:29

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

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Динамическое чтение строк кода в C#? Возможно ли?
Динамическое чтение строк кода в C#? Возможно ли?
alexsilentДата: Пятница, 08 Октября 2021, 09:11 | Сообщение # 1
почти ветеран
Сейчас нет на сайте
Пытаюсь придумать какой-то динамический способ изменения чтения строк кода или динамическую функцию.

1) Насколько я знаю в C# невозможно сделать как в Basic, оператор Goto?! То есть переметнуться на определённую строку,
чтобы начать читать сразу оттуда?!

2) В Lua и GML можно задать любой переменной сразу функцию. Которая будет работать вызывая эту переменную,
и если надо будет, можно было бы поменять в переменной функцию, очень удобная штука. Опять же C# и этого вроде как не умеет.

3) Также я попытался к типу Component прикрепить любой скрипт, и тут хз, можно ли сделать что-то, ибо у меня не получилось:

Код
public class CompRun : MonoBehaviour {
    public Component test;
    
    void Start () {
  test = Game.it.gameObject.GetComponent<MyScript>(); // получил MyScript скрипт с GameObject
  print("test: "+test); // Тут строка работает и показывает, что с test переменной всё норм
  test.RunFunction(); // А эта строка не хочет вызывать функцию с кастомного компонента
    }
}


Выходит, что только можно сделать огромный список Switch и напихать все функции в такой идиотский список?
Код
public string MyScript
switch (MySciprt) {
case "script1": Script1();break;
case "script2": Script2();break;
case "script3": Script3();break;
}

А ещё есть динамический вызов функции SendMessage, но он слишком медленный для тех вещей, что мне нужно,
примерно 60 раз в секунду вызывать до 100-200 NPC в сцене.


Сообщение отредактировал alexsilent - Пятница, 08 Октября 2021, 09:11
masb8ly-GCДата: Пятница, 08 Октября 2021, 13:40 | Сообщение # 2
постоянный участник
Сейчас нет на сайте
Цитата alexsilent ()

Выходит, что только можно сделать огромный список Switch и напихать все функции в такой идиотский список?

Если я верно понял запрос, то Вам подойдет что-то вроде:
Код
Dictionary<string, Action> m_Map = new Dictionary<string, Action> m_Map;

Почитайте про делегаты и их виды и все встанет на свои места. Ну и про то как работать с Dictionary, само собой.


Backend Developer ESIS
Client Side Developer Room8Studio
Technical Leader Lucid Reality Labs
Chief Technology Officer The Intruders
Chief Technology Officer RoyalePlay Games
alexsilentДата: Пятница, 08 Октября 2021, 13:52 | Сообщение # 3
почти ветеран
Сейчас нет на сайте
Цитата masb8ly-GC ()
Почитайте про делегаты и их виды и все встанет на свои места. Ну и про то как работать с Dictionary, само собой.


Спасибо! С Dictionary знаком и работаю, но вот про тип <string, Action> - Action , первый раз слышу,
погуглю также и про делегаты, что-то знакомое, но забыл.
drcrackДата: Пятница, 08 Октября 2021, 18:29 | Сообщение # 4
старожил
Сейчас нет на сайте
Цитата
test.RunFunction(); // А эта строка не хочет вызывать функцию с кастомного компонента

Потому что вместо Component надо указать реальный тип твоего компонента:
Код
public Component test;// здесь


Сообщение отредактировал drcrack - Пятница, 08 Октября 2021, 18:30
alexsilentДата: Суббота, 09 Октября 2021, 13:17 | Сообщение # 5
почти ветеран
Сейчас нет на сайте
Цитата drcrack ()
Потому что вместо Component надо указать реальный тип твоего компонента:


А как? Если сделать вместо компонента, чёткое имя скрипта, то тогда это не имеет смысла, потому-что я хотел бы разные туда скрипты подставлять, то есть мне нужен динамический метод доступа к некоторым строкам кода.

А в таком виде компоненту вроде не нужно указывать ничего:
Код
Component[] trs = transform.GetComponentsInChildren<Transform>();
foreach (Transform tr in trs) {
    tr.gameObject.layer = 1;
}


Сообщение отредактировал alexsilent - Суббота, 09 Октября 2021, 13:19
drcrackДата: Суббота, 09 Октября 2021, 18:57 | Сообщение # 6
старожил
Сейчас нет на сайте
Цитата
потому-что я хотел бы разные туда скрипты подставлять

тогда эти скрипты должны реализовывать какой-то один интерфейс, который ты и пишешь вместо типа
ну или иметь в родителях определенный тип в котором есть все нужные методы
интерфейс в целом удобней, но не будет работать с GetComponent

Цитата
то есть мне нужен динамический метод доступа к некоторым строкам кода.

но вообще сама постановка задачи уже звучит так, как будто ты делаешь что-то не то


Сообщение отредактировал drcrack - Суббота, 09 Октября 2021, 19:02
alexsilentДата: Воскресенье, 10 Октября 2021, 00:25 | Сообщение # 7
почти ветеран
Сейчас нет на сайте
Цитата drcrack ()
но вообще сама постановка задачи уже звучит так, как будто ты делаешь что-то не то


Ну вот несколько задач:

1) мне нужно добавить разный AI для разных NPC, я просто делаю разные скрипты, а иногда эти скрипты хотелось бы переключать, то есть из одного ИИ переключиться на другой ИИ. По мне кажется идеальнее вариант был бы как в Lua:
Код
//для обычных монстров
MyAI = WalkingAI(); // если бы можно к переменной просто функцию присобачить, было бы удобно
//а для летающих тут подставить
MyAI = FlyingAI(); // но подобные строки не работают
//а это например, когда враг стал бешенным
MyAI = AngryAI();
// а вот например 2 состояния лошади, когда герой сел на неё, и когда лошадь стоит без хозяина
MyAI = CreatureAI(); // без хозяина
MyAI = PlayerMountAI(); // управляется героем


2) мне нужно сделать свой встроенный Пиксельарт Аниматор, и в этом аниматоре сделать "вермишелевый" код,
просто написав кодом, это самый быстрый способ, чем придумать способ, чтобы эти формулы считывались как-то иначе.
И мне нужно написать для каждого персонажа свой "вермишелевый" код, у людей одна анимация, у лошадей другая,
у врагов особого вида третья и т.д., получается я могу этот Switch просто сделать неимоверно большим,
или разбить на разные скрипты, чтобы на каждое существо был свой код:
Код

void AnimWork() {
    Timer += Time.deltaTime;
    float t = Timer; //Time.time;
    switch(MyMode) { // Body Animation
  case "attack": // attack animation
   aBody.Anim(Mod(t,2)+3);
   aHead.Anim(0);
   aHandA.Anim(5);
    aHandB.Anim(5);
    
    t *= 9f;
    aSkirt.Anim(4-Mod(t,2));
    aEarA.Anim(Pong(t+.9f,3));
    aEarB.Anim(Pong(t+.8f,3));
    aHairA.Anim(Pong(t*2,4));
    aHairB.Anim(Mod(t+.25f,5));
    aTail.Anim(Pong(t,3));
    aRibbon.Anim(Pong(t,3));
    
    aTool.Anim(0,.2f,.07f,-95);
    break;
   case "idle": // idle animation
    aBody.Anim(Mod(t,2)+3);
    aHead.Anim(0);
    aHandA.Anim(5);
    aHandB.Anim(5);
    
    t *= 9f;
    aSkirt.Anim(4-Mod(t,2));
    aEarA.Anim(Pong(t+.9f,3));
    aEarB.Anim(Pong(t+.8f,3));
    aHairA.Anim(Pong(t*2,4));
    aHairB.Anim(Mod(t+.25f,5));
    aTail.Anim(Pong(t,3));
    aRibbon.Anim(Pong(t,3));
    
    aTool.Anim(0,.07f,.24f,85);
    break;
    }
}


Добавлено (10 Октября 2021, 00:29)
---------------------------------------------
Просто юнити аниматор не может в резкие изменения данных спрайтов, он делает плавно,
например голова повернулась, а спрайт ещё не изменил свой кадр.
Бывает ещё прикол когда нужно чтобы один спрайт спрятался, а другой рядом включился
и опять же аниматор бывает делает так, что либо оба спрятались, либо оба появились, и это портит картинку
точного пиксельарта. Другими словами лучше для анимации пиксельарта юзать что-то другое, а не аниматор,
ну я выбрал простой вариант, просто кодом.

А частей тела много, потому-что я планирую кастомизацию.

Добавлено (10 Октября 2021, 00:36)
---------------------------------------------
Например я тут тестировал анимацию на множество частей тела. Правда это Tic-80, а не Unity.
https://tic80.com/play?cart=1859
Ну и в саму юнити уже добавил эту систему, правда не хватает чего-то, чтобы можно было на каждого персонажа
свою группу функций анимации накинуть, у лошадей своя, а у людей своя, а у гоблинов тоже своя.
https://twitter.com/nyanarium/status/1430494168397275136

Добавлено (10 Октября 2021, 00:50)
---------------------------------------------
Я вначале хотел для анимации сделать таблицу, но сделав систему считывания символов из такой таблицы
и превращение символов в формулу уже будет тратиться время, а эта операция должна проходить по 60 раз в секунду
ещё и на 100-200 неписей, и самый быстрый способ реализации и работы, конечно же сделать просто кодом.
И неплохо бы придумать динамическое перемещение в нужную часть кода, а иначе этот вермишелевый код будет очень большим, просто если не придумаю динамическую функцию, то получается всю вермишель для всех анимаций, всех персонажей придётся добавить в один огромный код через Switch, и это будет кошмарнее выглядеть, чем на данный момент,
ибо пока у меня всего несколько анимаций для одного персонажа.


Сообщение отредактировал alexsilent - Воскресенье, 10 Октября 2021, 00:59
drcrackДата: Воскресенье, 10 Октября 2021, 04:14 | Сообщение # 8
старожил
Сейчас нет на сайте
1) ну так сделай скрипт class AI: MonoBehaviour и в него добавь нужные виртуальные методы, далее от этого скрипта наследуй конкретные реализации типа class CreatureAI: AI в которых определяй нужное поведение, тогда сможешь делать то, что пытался сделать, просто вместо Component пишешь AI
2) на юнити сделаны сотни и тысячи пиксель арт игр, и как-то все работает на обычных аниматорах, без свитчей на пять экранов. почему твоя игра так не может?


Сообщение отредактировал drcrack - Воскресенье, 10 Октября 2021, 04:14
alexsilentДата: Воскресенье, 10 Октября 2021, 08:03 | Сообщение # 9
почти ветеран
Сейчас нет на сайте
Цитата drcrack ()
ну так сделай скрипт class AI: MonoBehaviour и в него добавь нужные виртуальные методы, далее от этого скрипта наследуй конкретные реализации типа class CreatureAI: AI в которых определяй нужное поведение, тогда сможешь делать то, что пытался сделать, просто вместо Component пишешь AI

Как вариант, тоже думал над таким. Но только потом вроде нельзя перенаследовать, и поменять скрипт с CreatureAI,
на MountAI (если это животное можно было бы оседлать)

Цитата drcrack ()
2) на юнити сделаны сотни и тысячи пиксель арт игр, и как-то все работает на обычных аниматорах, без свитчей на пять экранов. почему твоя игра так не может?

Возможно потому-что у обычных игр не так много частей тела у спрайта, просто мне это нужно для кастомизации,
потому многие куски тел разделены:

Обычно у классических игр, просто 1 часть тела на персонажа, ну или может 2-3 куска тела (Body, Weapon, Shield).
А у меня в финальной версии должно быть около 20-30 (хотя сейчас их пока 10, там ещё должны быть слои одежды),
и спрайты должны синхронно менять своё содержание и положение (округляя позицию до сотых долей, а то иначе пиксельарт "поплывёт", например сам аниматор не может округлять позицию, поэтому всё равно придётся корректировать это программно), возможно есть плагины для анимации пиксельарта, но скорее всего они платные, так что приходится делать такой громоздкий код.


Сообщение отредактировал alexsilent - Воскресенье, 10 Октября 2021, 08:04
drcrackДата: Воскресенье, 10 Октября 2021, 08:06 | Сообщение # 10
старожил
Сейчас нет на сайте
Цитата
Как вариант, тоже думал над таким. Но только потом вроде нельзя перенаследовать, и поменять скрипт с CreatureAI, на MountAI (если это животное можно было бы оседлать)

а ты попробуй
alexsilentДата: Воскресенье, 10 Октября 2021, 17:15 | Сообщение # 11
почти ветеран
Сейчас нет на сайте
Цитата drcrack ()
а ты попробуй


А делегаты это не вариант? Как мне в первом варианте предложил masb8ly-GC!
PS Ну то есть быстрая ли эта опция с делегатами и нет ли там других подводных камней?
Просто кажется, насколько я нагуглил тему,
с делегатами можно на ходу менять текущую функцию ИИ, если оно конечно нормально работает.
Хз... надо попробовать оба вариант потестировать на креш-тест.


Сообщение отредактировал alexsilent - Воскресенье, 10 Октября 2021, 17:17
drcrackДата: Воскресенье, 10 Октября 2021, 20:28 | Сообщение # 12
старожил
Сейчас нет на сайте
Цитата
А делегаты это не вариант?

ну если для тебя даже свитчи это вариант, то и делегаты подойдут наверно :D
alexsilentДата: Понедельник, 11 Октября 2021, 07:50 | Сообщение # 13
почти ветеран
Сейчас нет на сайте
Цитата drcrack ()
ну если для тебя даже свитчи это вариант, то и делегаты подойдут наверно


То есть делегаты хуже свитчей?)
drcrackДата: Понедельник, 11 Октября 2021, 13:30 | Сообщение # 14
старожил
Сейчас нет на сайте
я уже написал выше что эта задача решается наследованием (в общем случае также интерфейсами, но не в юнити)
не вижу смысла сравнивать плохие решения когда есть хорошее
BrightSpotДата: Четверг, 14 Октября 2021, 13:15 | Сообщение # 15
заслуженный участник
Сейчас нет на сайте
Немного поправлю, Интерфейсы работаю с GetComponent (единственное условие монобех в родителях)...


Более мощный компьютер глючит быстрее и точнее.


Сообщение отредактировал BrightSpot - Четверг, 14 Октября 2021, 13:17
alexsilentДата: Понедельник, 25 Октября 2021, 10:21 | Сообщение # 16
почти ветеран
Сейчас нет на сайте
Цитата drcrack ()
(в общем случае также интерфейсами, но не в юнити)


А что не так с интерфейсами в юнити?


Сообщение отредактировал alexsilent - Среда, 27 Октября 2021, 01:07
Форум игроделов » Движки для разработки игр и сложные системы разработки » Unity » Динамическое чтение строк кода в C#? Возможно ли?
  • Страница 1 из 1
  • 1
Поиск:

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