В шутерах есть такой луч пересекающий меш и в момент пересечения у противника отнимается хп. То есть при пересечении меша лучом мы получаем доступ к хп врага...
А если я выбираю противника мышкой это происходит с помощью того же луча? Мне надо чтобы при нажатии на спелл и следующем нажатии на противника работал каст фаербола в этого выбраного противника.
class character { string mesh; bool ally; string name; int hp; int atk; }
такой код атаки:
character vrag; if vrag.ally= false { vrag.hp-=fireball(); }
Я вот не понимаю как с помощью луча получить доступ к переменным этого обьекта.
Сорян если глупо сформулировал вопрос, я немного слоупок)).
Kukuruz
> Я вот не понимаю как с помощью луча получить доступ к переменным этого обьекта.
Поскольку ты не стал сообщать о движке, яп, что там у тебя вообще, то можно ответить только в общем виде: рейкасты и меши - это геометрия.
Последние обычно оборачивается в объект-логическую сущность. Эту сущность (class character) тебе и надо уметь получать: тайпкастом, словарём,
но обычно доки к движку описывают.
А вообще это не "солидно", из луча иметь доступ к переменным пересекаемого класса, а тем более реализовывать логику типа манипуляций с HP.
rcsim, спасибо.
Движка пока нет, но он должен быть на C++, самописный. Скорее всего на DX11. Писать буду не я. Но мне интересно как это делается.
rcsim
> А вообще это не "солидно", из луча иметь доступ к переменным пересекаемого
> класса, а тем более реализовывать логику типа манипуляций с HP.
Почему не солидно? Ну а как по другому я не знаю, опыта у меня совсем нет.
Разумеется, я имел ввиду SOLID
Kukuruz
Отправь сообщение классу НПС
Псевдокод:
fireball_damage = 10;
actors = world.raycast(ray);
foreach actor from actors
{
асtor.apply_damage(fireball_damage);
}
Kukuruz
>Движка пока нет, но он должен быть на C++, самописный. Скорее всего на DX11.
На С++ в мире так мало движков, что обязательно писать ещё один новый! Чем больше сил потратишь на движок, тем меньше останется на игру. Если хочется своего, то форкай, например годот и дописывай в код что тебе надо.
Мне надо чтобы при нажатии на спелл и следующем нажатии на противника работал каст фаербола в этого выбраного противника.
То есть, по сути таргетная система. Тогда у персонажей необходимо сделать такую вещь, как фокус, который будет ссылкой на другого персонажа.
class Character { public: ... virtual ~Character(); ... inline bool hasTarget( ) const; inline Character * getTarget( ) const; inline void setTarget( Character * character); inline void resetTarget( ); private: Charater * target; }; bool Character::hasTarget( ) const { return target != NULL; } Character * Character::getTarget( ) const { return target; } void Character::setTarget( Character * character) { target = character; } void Character::resetTarget( ) { target = NULL; }
Это позволит запоминать, кто у персонажа в фокусе. Причём этот механизм можно использовать для разных персонажей, в том числе и NPC, что бы они могли кастовать на игрока
if vrag.ally= false { vrag.hp-=fireball(); }
По-моему, лучше так:
if (!vrag.ally) { vrag.hp-=fireball( ); }
А ещё лучше проверку применяемости спелла сделать либо в классе спелла (либо вообще в шаблоне стратегия).
Внутри класса Spell:
class FireballSpell { public: ... bool canCast(const Character * character) { if ( !character.hasTarget( )) { return false; } //TODO: Проверить, можно ли применить к target } ... };
Как проверить.
Вариант 1. Оставить флаг ally
Вариант 2. Ввести в игру группы персонажей (фракции). Фракции позволят не только союзных и враждебных персонажей иметь, но и нейтральных, если потребуется.
Вот простой пример жёстко зашитых вариантов фракций:
class Character { public: const int FRACTION_ALLIANCE = 0x1; const int FRACTION_HORDE = 0x2; const int FRACTION_CARTEL = 0x3; const int RELATION_FRIENDLY = 1; const int RELATION_NEUTRAL = 0; const int RELATION_HOSTILE = -1; ... virtual ~Character(); ... inline bool hasTarget( ) const; inline Character * getTarget( ) const; inline void setTarget( Character * character); inline void resetTarget( ); int getRelationTo( Character * character) const; private: Charater * target; int fraction; }; int Character::getRelationTo( Character * character) const { if ( fraction == character->fraction) { return RELATION_FRIENDLY; } if ( fraction == FRACTION_CARTEL || character->fraction == FRACTION_CARTEL) { return RELATION_NEUTRAL; } return RELATION_HOSTILE; }
Тогда метод canCast будет таким:
bool FireballSpell::canCast(const Character * character) { if ( !character->hasTarget( )) { return false; } return character->getRelationTo( character->getTarget( )) <= RELATION_NEUTRAL; }
Да, в классе Character можно сделать отдельный метода getRelationToTarget:
int Character::getRelationToTarget() const { if ( target == NULL) { return RELATION_FRIENDLY; // отношение персонажа к самому себе } return getRelationTo( target); }
Kukuruz
> Я вот не понимаю как с помощью луча получить доступ к переменным этого обьекта.
Есть пара англоязычных статей:
Object picking with Vulkan
Mouse Picking with Ray Casting
Тут на gamedev есть очень древняя статья с применением glu:
Способ выделения объектов мышью в OpenGL приложениях
Morgend
спасибо большое!
всем спасибо.
Тема в архиве.