Ru/Authoring a weapon entity: Difference between revisions
mNo edit summary |
No edit summary |
||
Line 24: | Line 24: | ||
== Точки входа == | == Точки входа == | ||
У оружия есть четыре функции, которые вызываются каждый кадр объектом которым владеет игрок: | |||
; <code>ItemPreFrame()</code> | ; <code>ItemPreFrame()</code> | ||
: | : Вызывается перед началом движения игрока. В [[Episode Two]], решает , подходящее ли сейчас время чтобы отобразить подсказку по использованию оружия в HUD. | ||
; <code>ItemHolsterFrame()</code> | ; <code>ItemHolsterFrame()</code> | ||
: | : Вызывается перед началом движения игрока, если игрок ничего не делает. В основном ничего не делает. | ||
; <code>ItemBusyFrame()</code> | ; <code>ItemBusyFrame()</code> | ||
: | : Вызывается перед началом движения игрока, если игрок не стреляет. В основном ничего не делает. | ||
; <code>ItemPostFrame()</code> | ; <code>ItemPostFrame()</code> | ||
: | : Вызывается после движения игрока. Это самая важная функция , ведь она ведёт к следующим: | ||
:* <code>PrimaryAttack()</code> | :* <code>PrimaryAttack()</code> | ||
:* <code>SecondaryAttack()</code> | :* <code>SecondaryAttack()</code> | ||
Line 40: | Line 40: | ||
:* <code>WeaponIdle()</code> | :* <code>WeaponIdle()</code> | ||
== | == Стрельба == | ||
Оружие обычно стреляет если кнопка отвечающая за +attack активна и <code>(m_flNextPrimaryAttack <= [[gpGlobals]]->curtime)</code>. Для дополнительного режима стрельбы, +attack2 и <code>m_flNext''Secondary''Attack</code> проверяются вместо предыдущей функции (?). | |||
{{todo| | {{todo|Как заставить NPC атаковать?}} | ||
=== | === Пули === | ||
[[Hitscan]] | [[Hitscan|Пули]] выстреливаются при соответствии , где <code>[[FireBulletsInfo_t]]</code> противоречит <code>GetOwner()->FireBullets()</code>. | ||
Если всё что вам нужно это основная атака , которая выстреливает постоянный поток пуль (Не важно отделяют их 2 или 0.2 секунды) <code>CBaseCombatWeapon</code> уже выполняет нужную работу и вам надо только написать две функции: | |||
; <code>float GetFireRate()</code> | ; <code>float GetFireRate()</code> | ||
: | : Время в секундах между каждым выстрелом. | ||
; <code>const Vector& GetBulletSpread()</code> | ; <code>const Vector& GetBulletSpread()</code> | ||
: | : Конус , внутри которого пули будут иметь случайный разброс. Для него используйте <code>VECTOR_CONE_*</code> #определяет, как избежать самостоятельной работы с математикой. | ||
Переходим к секции с [[#Networking|нетворкингом]] если это соответствует вашим требованиям; [[#Effects|Эффекты]] будут сделаны за вас. Иначе смотрите <code>[[FireBulletsInfo_t]]</code> за подробностями , чтобы настроить вашу собственную hitscan атаку. | |||
=== | === Снаряды === | ||
Ракеты, гранаты, и другие снаряды это самостоятельные энтити которые существуют независимо (почти) от оружия из которого они вылетели. Оружие должно создать их с помощью <code>[[Create()]]</code>: | |||
<source lang=cpp>CBaseEntity::Create( "my_projectile", GetOwner()->Weapon_ShootPosition(), GetOwner()->EyeAngles(), GetOwnerEntity() );</source> | <source lang=cpp>CBaseEntity::Create( "my_projectile", GetOwner()->Weapon_ShootPosition(), GetOwner()->EyeAngles(), GetOwnerEntity() );</source> | ||
Обратите внимание , что их владелец тот же , что и владеет оружием (<code>GetOwnerEntity()</code>), а само не оружие как таковое. | |||
{{tip| | {{tip|Не [[Lag compensation|компенсируйте лаги]] или [[Prediction|прогнозируйте]] этот вызов - ''делай'' прогнозируемую анимацию отсутствия патронов и перезарядки для [[viewmodel]].}} | ||
Читайте следующее: | |||
* [[Projectiles]] ( | * [[Projectiles|Снаряды]] (для проблем с дизайном модели снарядов) | ||
* [[Authoring a Model Entity]] ( | * [[Authoring a Model Entity|Создание энтити-модели]] (для создания [[QPhysics]] энтити) | ||
* <code>[[CPhysicsProp]]</code> ( | * <code>[[CPhysicsProp]]</code> (для создания [[VPhysics]] энтити) | ||
=== | === Эффекты === | ||
Здесь предполагается , что вы используете [[:Category:Particle System|систему партиклов]], которая создаётся художниками. Старая технология "закодирования партиклов намертво" никогда не документировалась. | |||
==== | ==== Следы от пуль ==== | ||
Следы должны быть отправлены <code>CBaseEntity::MakeTracer()</code>. <code>CBasePlayer</code> который настроен на излучение "намертво закодированных" эффектов; если вы хотите внести изменения, лучше всего осуществить партиклы(?). Это делается несложно: | |||
<source lang=cpp> | <source lang=cpp> | ||
// | // ВСЁ В ОБЩЕМ КОДЕ | ||
// | // всегда излучать следы; пусть система партиклов сама определяет объём | ||
// ( | // (если вы не собираетесь редактировать CBasePlayer, просто измените m_iTracerFreq ) | ||
void CMyPlayer::FireBullets( const FireBulletsInfo_t &info ) | void CMyPlayer::FireBullets( const FireBulletsInfo_t &info ) | ||
{ | { | ||
Line 95: | Line 95: | ||
} | } | ||
// | // перейдите к оружию, если есть необходимость | ||
void CMyPlayer::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ) | void CMyPlayer::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ) | ||
{ | { | ||
Line 101: | Line 101: | ||
} | } | ||
// | // излучает эффект этого оружия | ||
void CMyWeapon::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ) | void CMyWeapon::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType ) | ||
{ | { | ||
// 1 | // 1 это аттачмент #1, который является дулом | ||
UTIL_ParticleTracer("my_tracer",vecTracerSrc,tr.endpos,entindex(),1); | UTIL_ParticleTracer("my_tracer",vecTracerSrc,tr.endpos,entindex(),1); | ||
} | } | ||
</source> | </source> | ||
Код сверху позволяет создать новую [[particle system|систему частиц]] , которая подходит для эффектов одиночной стрельбы для каждой пули . Если ваше оружие стреляет быстро рассмотрите вместо этого возможность создания эффекта который создаёт поток партиклов когда игрок начинает стрелять , и используйте <code>StopParticleEffects(this)</code> чтобы завершить работу эффекта, когда он закончит стрелять. Попробуйте <code>(CBasePlayer::m_nButtons & IN_ATTACK)</code> чтобы достичь данного эффекта. | |||
{{note| | {{note|Если ваше оружие имеет другие партикл-эффекты вам понадобиться остановить след <code>ParticleProp()->StopEmission(CNewParticleEffect* pEffect)</code> вместо того , который находится на стороне игрока.}} | ||
Смотрите также <code>[[UTIL_ParticleTracer]]</code>. | |||
==== | ==== Эффект попадания ==== | ||
{{todo|<code>CBaseEntity::DoImpactEffect()</code>}} | {{todo|<code>CBaseEntity::DoImpactEffect()</code>}} | ||
Line 123: | Line 123: | ||
{{todo|Shared code, prediction, predicted viewmodels, compensation...}} | {{todo|Shared code, prediction, predicted viewmodels, compensation...}} | ||
== | == Оружие-пример == | ||
Смотрите [[AK47 weapon|ДОбавление нового оружия в ваш мод]]. | |||
[[Category:Weapons programming]] | [[Category:Weapons programming]] |
Revision as of 10:40, 9 January 2023
Как не удивительно Source имеет надёжные оружейные системы. Эта статья описывает шаги необходимые для создания пулевых и снарядных оружий и как правильно настроить их для использования в мультиплеере.
Общие сведения
- Большинство свойств оружия может быть сконфигурировано с помощью оружейных скриптов
- Если всё что тебе требуется - это выстреливать пули с постоянной скоростью, тебе необходимы какие-никакие навыки в программировании.
- Оружейный огонь может быть прогнозирован игроком и запозданием сервера
- Обычно это выглядит как снаряды в виде ракет, гранат, и других снарядов материализующихся из воздуха на компьютерах наблюдателей.
- Моделька от первого лица - это отдельная сущность
- Она создается игроком и делится между всеми видами оружия.
- В SDK есть широкий выбор оружия для изучения
- Valve предоставляет исходный код как однопользовательских, так и многопользовательских игр.
Оружейные скрипты
От оружейных скриптов зависит много свойств оружия , включая её модель, амуницию , звуки , размер обоймы , и имя в пользовательском интерфейсе. Использование, расширение и шифрование оружейных скриптов описано в их статье.
Скрипт оружия будет автоматически загружен для любого оружия с назначенным именем класса. Для более лёгкого кэширования ресурсов, определяемых скриптами вызовите PRECACHE_WEAPON_REGISTER(имя)
и никаких кавычек вокруг имени класса.
Точки входа
У оружия есть четыре функции, которые вызываются каждый кадр объектом которым владеет игрок:
ItemPreFrame()
- Вызывается перед началом движения игрока. В Episode Two, решает , подходящее ли сейчас время чтобы отобразить подсказку по использованию оружия в HUD.
ItemHolsterFrame()
- Вызывается перед началом движения игрока, если игрок ничего не делает. В основном ничего не делает.
ItemBusyFrame()
- Вызывается перед началом движения игрока, если игрок не стреляет. В основном ничего не делает.
ItemPostFrame()
- Вызывается после движения игрока. Это самая важная функция , ведь она ведёт к следующим:
PrimaryAttack()
SecondaryAttack()
HandleFireOnEmpty()
Reload()
WeaponIdle()
Стрельба
Оружие обычно стреляет если кнопка отвечающая за +attack активна и (m_flNextPrimaryAttack <= gpGlobals->curtime)
. Для дополнительного режима стрельбы, +attack2 и m_flNextSecondaryAttack
проверяются вместо предыдущей функции (?).
Пули
Пули выстреливаются при соответствии , где FireBulletsInfo_t
противоречит GetOwner()->FireBullets()
.
Если всё что вам нужно это основная атака , которая выстреливает постоянный поток пуль (Не важно отделяют их 2 или 0.2 секунды) CBaseCombatWeapon
уже выполняет нужную работу и вам надо только написать две функции:
float GetFireRate()
- Время в секундах между каждым выстрелом.
const Vector& GetBulletSpread()
- Конус , внутри которого пули будут иметь случайный разброс. Для него используйте
VECTOR_CONE_*
#определяет, как избежать самостоятельной работы с математикой.
Переходим к секции с нетворкингом если это соответствует вашим требованиям; Эффекты будут сделаны за вас. Иначе смотрите FireBulletsInfo_t
за подробностями , чтобы настроить вашу собственную hitscan атаку.
Снаряды
Ракеты, гранаты, и другие снаряды это самостоятельные энтити которые существуют независимо (почти) от оружия из которого они вылетели. Оружие должно создать их с помощью Create()
:
CBaseEntity::Create( "my_projectile", GetOwner()->Weapon_ShootPosition(), GetOwner()->EyeAngles(), GetOwnerEntity() );
Обратите внимание , что их владелец тот же , что и владеет оружием (GetOwnerEntity()
), а само не оружие как таковое.

Читайте следующее:
- Снаряды (для проблем с дизайном модели снарядов)
- Создание энтити-модели (для создания QPhysics энтити)
CPhysicsProp
(для создания VPhysics энтити)
Эффекты
Здесь предполагается , что вы используете систему партиклов, которая создаётся художниками. Старая технология "закодирования партиклов намертво" никогда не документировалась.
Следы от пуль
Следы должны быть отправлены CBaseEntity::MakeTracer()
. CBasePlayer
который настроен на излучение "намертво закодированных" эффектов; если вы хотите внести изменения, лучше всего осуществить партиклы(?). Это делается несложно:
// ВСЁ В ОБЩЕМ КОДЕ
// всегда излучать следы; пусть система партиклов сама определяет объём
// (если вы не собираетесь редактировать CBasePlayer, просто измените m_iTracerFreq )
void CMyPlayer::FireBullets( const FireBulletsInfo_t &info )
{
FireBulletsInfo_t new_info(info);
new_info.m_iTracerFreq = 1;
BaseClass::FireBullets(new_info);
}
// перейдите к оружию, если есть необходимость
void CMyPlayer::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType )
{
GetActiveWeapon()->MakeTracer(vecTracerSrc,tr,iTracerType);
}
// излучает эффект этого оружия
void CMyWeapon::MakeTracer( const Vector &vecTracerSrc, const trace_t &tr, int iTracerType )
{
// 1 это аттачмент #1, который является дулом
UTIL_ParticleTracer("my_tracer",vecTracerSrc,tr.endpos,entindex(),1);
}
Код сверху позволяет создать новую систему частиц , которая подходит для эффектов одиночной стрельбы для каждой пули . Если ваше оружие стреляет быстро рассмотрите вместо этого возможность создания эффекта который создаёт поток партиклов когда игрок начинает стрелять , и используйте StopParticleEffects(this)
чтобы завершить работу эффекта, когда он закончит стрелять. Попробуйте (CBasePlayer::m_nButtons & IN_ATTACK)
чтобы достичь данного эффекта.

ParticleProp()->StopEmission(CNewParticleEffect* pEffect)
вместо того , который находится на стороне игрока.Смотрите также UTIL_ParticleTracer
.
Эффект попадания
CBaseEntity::DoImpactEffect()
Networking
Оружие-пример
Смотрите ДОбавление нового оружия в ваш мод.