Есть у тебя на карте какой-нибудь Light типа Ambient с радиусом, скажем, 8. Ты каждый тик (например в функции RenderGameView в Player) телепортируешь этот специальный лайт (который нужно еще назначить в свой собственный специальный CEntityPointer) на координаты переменной m_vRayHit, которая находится уже в PlayerWeapons и которую внутри Player можно получить как: GetPlayerWeapons()->m_vRayHit. Телепортировать, естественно, функцией Teleport(CPlacement3D, FALSE) - (На место CPlacement3D пишешь "CPlacement3D(GetPlayerWeapons()->m_vRayHit, ANGLE3D(0,0,0))", на место FALSE - так же FALSE) - второй аргумент функции отвечает за телефраг, который нам не нужен и мы естественно его отключаем
Народ, объясните кто нибудь, как сделать фонарь, ну конечно кому не сложно. Я вижу, что несколько людей точно знают, как это делается. Это ведь форум, и форум для того и нужен, чтобы задавать вопросы и получать на них нормальные ответы, а не ответы типа "Не умеешь в базовые вещи - твои проблемы". если я не прав, то так и скажите.
Мой способ совсем не касается SDK. Надо скачать новый класс PlayerParenter отсюдова и прицепить в редакторе к игроку источник света. Необходимо настроить правильное положение источника света (можно даже несколько припэрентить). Фонарик можно будет включать от триггера в любой момент, но единственный минус такого способа в том, что PlayerParenter резко реагирует на повороты игрока, да и на движение в целом. Но в качестве дешманского фонаря для поиска картохи в погребе сойдет.
Jack_Stone, включается триггером. Если хочешь от кнопки на клавиатуре, можно сделать с SDK такую ентитю, которая отлавливает нажатия определённых клавиш и посылает сигнал триггеру, которой в свою очередь активирует PlayerParanter. Тут я не смогу помочь, к сожалению.
Jack_Stone, один из способов, как можно сделать фонарь.
1) CEntityPointer - это указатель на энтити. Я уверен, что ты видел поле Target у Trigger. Так вот, это тоже самое. Абстрактно будем говорить, что это объект в игре.
В Serious Sam есть объекты, которые могут освещать местность. Например, если пустить ракету в темном помещении, то можно заметить её небольшое свечение. Я предлагаю сделать тот же самый способ, нашей целью будет создать такой Projectile, который будет сам по себе невидим, но у него будет свет.
2) Почему надо лезть в PlayerWeapons. Дело в том, что в этом классе есть луч, который бьет прямо из игрока (примерно говорю, знатоки поправят меня), в место, куда направлен его прицел. Например, переменная m_vRayHit хранит в себе координаты того места, куда "ударил" этот луч. Чем это может нам помочь? Например, можно относительно этого луча телепортировать тот самый светящийся Projectilе, в итоге получаем освещение местности в зависимости от направления взгляда.
2.5) Создай какой-нибудь Projectile по аналогии со, скажем, PRT_ROCKET. Сделай так, чтобы он светился, модель была не видна и чтоб время жизни было очень-очень долгим.
3) Как заспавнить этот Projectile в коде и где это сделать?
Для начала надо объявить кнопку. Идем в Player.es. Я возьму в качестве аналогии кнопку bFireBomb, которая отвечает за запуск серьезной бомбы.
Все, практически готово. Теперь идешь на строку 4492. Видишь, как там реализован запуск бомбы. Делаешь примерно тоже самое:
Код
if (ulNewButtons&PLACT_FLASHLIGHT) { // здесь будет код по нажатию кнопки связанной с фонарем }
Далее, естественно, надо зайти в .ctl файл в папке Controls в самом Serious Sam и прописать по аналогии кнопку с Flashlight. Данная кнопка будет работать корректно и по сети
Определились где заспавнить. Теперь КАК заспавнить какую-либо энтити.
Возьмем пример: нам нужно чтобы в мире появился Trigger. Прежде всего создай глобальную переменную в PlayerWeapons, пусть она объявляется, например, так:
Это самый простой способ инициализации. У нас создается стандартный Trigger на том месте, где мы стоим (GetPlacement()). Вот, например, более сложный.
m_penTrigger = CreateEntity(GetPlacement(), CLASS_TRIGGER);((CTrigger*)&*m_penTrigger)->m_strName = "New Trigger"; m_penTrigger->Initialize();
Таким образом, ты можешь уточнять, какой именно Trigger ты хочешь заспавнить.
Теперь, зная как спавнить определенные объекты, загляни в функцию FireRocket в PlayerWeapons. Посмотри как там спавнится снаряд. Сделай свою функцию для включения и выключения фонарика в PlayerWeapons. Вот пример.
Jack_Stone, undeclared - необъявленный. Ых, вот так вот без азов я тебе вряд ли что-то объясню... Почитай про переменные в языках программирования и про их объявление.
Heming_Hitrowski, у меня что-то получилось. вместо фонаря получилась кнопка суицида, как в Постал 2. не знаю, почему так. Но взрывчатость я вроде удалил - m_bExplode у нового проджектайла PlayerFlashlight.
Where did all the dragons go? We searched in the hills and we searched down the canyons, we even scanned the depths of the caves with our armour, swords and lanterns. Oh, if only had we seen him lurch, from his glorious skull covered perch.
CRACK went his claws and SMACK swipped the tail, a ROAR of might, one big BITE.
Heming_Hitrowski, у меня получилось сделать включение фонаря, только телепортируется не модель (Projectile), как ты предлагал, а Light. Всё как надо светится. Но не получается ничего с выключением света. Есть функция Destroy, которой вроде как и можно удалить этот Light - в моём случае m_penLight - но она почему то не помогает.
Ты же сначала убираешь свой фонарик из переменной, а потом хочешь заставить его что-то сделать. Поменяй строки местами, а то выходит, что ты уничтожаешь ничто.
Создавая вот таким образом энтити, ты объявляешь локальную переменную, которая нигде не запоминается (мы потом не сможем уничтожить этот лайт). Правильнее будет вот так:
Я не уверен, что эта строчка вообще что-то даст. Если ты хочешь присвоить лайту light animation, то можно записать это так: [code((CLight*)&*m_penLight)->m_aoLightAnimation.SetData_t(CTFILENAME("Animations\\Flashlight.ani"));[/code] При этом тебе нужно будет в самом верху класса дописать #include связанный с классом Light (чтобы как раз не было ошибки undefined). 3.
Код
else if (m_penLight != NULL){
можно записать просто как
Код
else {
Сообщение отредактировалHeming_Hitrowski - Понедельник, 03.10.2016, 11:36
спасибо за советы, но что то опять не выходит. У меня короче получилось так: прописал две кнопки - вкл. (желтый Light) и выкл. (черный Light). Heming_Hitrowski, ((CLight*)&*m_penLight)->m_aoLightAnimation.SetData_t(CTFILENAME("Animations\\Flashlight.ani")) очень даже работает. Но есть проблема - вот эти 2 Light`а каким-то образом перебивают Light при стрельбе, даже если, например, в самом начале уровня нажать кнопку либо ВКЛ., либо ВЫКЛ., то свет от оружия нейтрализуется. Вариант фонаря не идеальный, но тоже сойдет.
Добавлено (03.10.2016, 21:29) --------------------------------------------- самое интересное то, что в этом коде только вот этого и хватает - ((CLight*)&*m_penLight)->m_aoLightAnimation.SetData_t(CTFILENAME("Animations\\Flashlight.ani")). Больше никакие переменные не нужны. Но непонятно как теперь передвинуть эту анимацию чуть дальше от Сэма.
Добавлено (03.10.2016, 21:32) --------------------------------------------- вот такой вот код, для выключения такой же, только анимация другая
Код
// turn on flashlight void Flashlight(){ { m_aoLightAnimation.SetData_t(CTFILENAME("Animations\\Flashlight.ani")); } };
Ты тут очень сильно нагородил)) Дело в том, что переменная m_aoLightAnimation используется как раз для вспышки при стрельбе, и ее ВООБЩЕ НЕ НАДО ТРОГАТЬ ЧТОБЫ СДЕЛАТЬ ФОНАРЬ, иначе произойдет такой ужас, который ты описал. Прочитай еще раз что мы тебе предлагали и старайся делать все по шагам.
Для начала давай попробуем все же заспавнить лайт, раз уж ты решил работать именно с ним, а не с Projectile.
По нажатии кнопки фонаря давай попробуем добавить вот такой код.
Код
CPlacement3D pl = GetPlacement(); // получили позицию игрока pl.pl_PositionVector(2) += 1.0f; // сдвинули ее чуть повыше, чтобы лайт не был в "земле" m_penLight = CreateEntity(pl, CLASS_LIGHT); // объяви CLASS_LIGHT заранее, в блоке components m_penLight->Initialize(); // инициализируем лайт на обработанных координатах
Что-нибудь происходит при выполнении?
Сообщение отредактировалHeming_Hitrowski - Вторник, 04.10.2016, 00:00
Heming_Hitrowski, нет, не происходит, но всё компилируется нормально.
Добавлено (04.10.2016, 00:26) --------------------------------------------- Хотя неее, что то да есть уже) сам Light появляется и исчезает при нажатии кнопки, но свет не производит.
Добавлено (04.10.2016, 00:28) --------------------------------------------- вот с этим кодом
Добавлено (04.10.2016, 00:28) --------------------------------------------- я вообще запутался уже))
Добавлено (04.10.2016, 00:32) --------------------------------------------- с твоим кодом точно также работает, но света нет
Код
// turn on off flashlight void Flashlight(){
if (m_penLight == NULL){ CPlacement3D pl = GetPlacement(); // получили позицию игрока pl.pl_PositionVector(2) += 1.0f; // сдвинули ее чуть повыше, чтобы лайт не был в "земле" m_penLight = CreateEntity(pl, CLASS_LIGHT); // объяви CLASS_LIGHT заранее, в блоке components m_penLight->Initialize(); } else { m_penLight->Destroy(); m_penLight = NULL;
}
};
Добавлено (04.10.2016, 10:10) --------------------------------------------- может он просто телепортирует модель лайта, а "физические свойства" надо отдельно прописывать? но как?
Heming_Hitrowski, всё то же самое. Как будто и не менял ничего. Света нет.
Добавлено (04.10.2016, 21:21) --------------------------------------------- (CTrigger*)&*m_penTrigger)->m_strName = "New Trigger";
эта строка вообще никак не влияет, написать можно любой набор букв на месте "New Trigger"
Добавлено (04.10.2016, 22:20) --------------------------------------------- попробовал ту же схему с моделью, та же фигня: почему то не меняет тип проджектайла - всегда выстреливает ракету, которая убивает Сэма
Добавлено (04.10.2016, 23:00) --------------------------------------------- тут и правда используется ракета Сэма, но это ладно. Я сделал так, чтобы она не летела, а как сделать так, чтобы она приатачилась к Сэму и двигалась вместе с ним?
Добавлено (06.10.2016, 10:30) --------------------------------------------- ВСЕМ, кто помогал мне с созданием фонарика, СПАСИБО, особенно Heming_Hitrowski, ) наконец-то получилось но вот чего я не пойму, так это почему он начал светить только тогда, когда прописал эту строчку:
(CTrigger*)&*m_penTrigger)->m_strName = "New Trigger";
эта строка вообще никак не влияет, написать можно любой набор букв на месте "New Trigger"
Оно и логично.) Попробуй сам себе объяснить этот код и понять, что он делает. Если не получится, вот спойлер.
Мы приводим класс CEntityPointer к типу CTrigger, затем присваиваем переменной m_strName значение New Trigger. А что за переменная m_strName? Это имя объекта. Что фактически изменится, если ты изменишь имя? Ничего) Я тебе просто пытался на пальцах объяснить это, но, видимо, оказалось недостаточно понятно) Тоже самое можно делать и с другими переменными класса Trigger, например, Message.
Код
m_penLight->SetParent( this);
Эта строчка привязывает лайт к игроку (на манер свойства Parent в Serious Editor). this - это как раз указатель на класс Player. Поэтому лайт движется за игроком) Это конечно грубый способ, но работать будет.
Сообщение отредактировалHeming_Hitrowski - Четверг, 06.10.2016, 13:52