Particles = PCIP.CreateDefaultSubobject(this,
TEXT("ParticleSystem"));
// Particles
является корневым компонентом, а ProxBox
//
является дочерним объектом системы частиц - Particle.
//
Если бы это был другой способ, то масштабирование ProxBox
//
также масштабировало бы Particles, чего мы не хотим
RootComponent = Particles;
ProxBox->AttachTo( RootComponent );
Duration = 3; //
Продолжительность
DamagePerSecond = 1; //
Урон за секунду
TimeAlive = 0; //
Время жизни
PrimaryActorTick.bCanEverTick = true; //
требуется, чтобы заклинания
//
“тикали” (tick)!
}
Особенно важна здесь, последняя строка PrimaryActorTick.bCanEverTick = true.
Если
вы не установили это, то ваш объект Spell не вызовет Tick().
Далее у нас есть метод SetCaster(). Он вызывается так, что тот, кто посылает
заклинание, известен объекту Spell. Мы можем гарантировать, что посылающий
заклинания не сможет навредить сам себе, своими собственными
заклинаниями, используя следующий код:
void ASpell::SetCaster( AActor *caster )
{
Caster = caster;
AttachRootComponentTo( caster->GetRootComponent() );
}
И наконец то, у нас есть метод ASpell::Tick(), который собственно наносит урон
ко всем содержащимся акторам, как показано в следующем коде:
void ASpell::Tick( float DeltaSeconds )
{
Super::Tick( DeltaSeconds );
//
ищем ProxBox для всех акторов в объёме.
285 |
С т р а н и ц а
TArray actors;
ProxBox->GetOverlappingActors( actors );
//
наносим урон каждому актору попадающему в область блока
for( int c = 0; c < actors.Num(); c++ )
{
//
чтобы не навредить тому, кто посылает заклинание
if( actors[ c ] != Caster )
{
//
Наносим урон только, если блок пересекается с
//
КОРНЕВЫМ компонентом актора.
//
Таким образом, урона не будет, если будет просто
//
пересечение с SightSphere монстра
AMonster *monster = Cast( actors[c] );
if( monster && ProxBox->IsOverlappingComponent( monster->CapsuleComponent ) )
{
monster->TakeDamage( DamagePerSecond*DeltaSeconds, FDamageEvent(),0, this );
}
//
чтобы наносить урон другим типам класса, попробуйте проверенное насылание
//
здесь...
}
}
TimeAlive += DeltaSeconds;
if( TimeAlive > Duration )
{
Destroy();
}
}
Функция ASpell::Tick() выполняет следующее:
Получает всех акторов пересекающихся с ProxBox. Любой актор не
являющийся посылателем заклинаний, получает урон, если пересекаемый
компонент является корневым компонентом объекта. Причина, по которой
нам нужно проверять на пересечение с корневым компонентом, заключается
в том, что если мы этого не сделаем, то заклинание может пересечься с
SightSphere монстра, что означает, что атака будет происходить с очень
большого расстояния, чего мы не хотим.
Заметьте, что если у нас есть другой класс, который должен получать урон,
мы бы могли попробовать посылать заклинание на каждый тип объекта
специально. Каждый тип класса может иметь различные типы объёма
ограничения, которыми они должны сталкиваться. Другие типы могут даже
не иметь CapsuleComponent (они могут иметь ProxBox или ProxSphere).
Повышает объём времени жизни заклинания. Если продолжительность
времени выделенного на заклинание заканчивается, то оно удаляется с
уровня.
286 |
С т р а н и ц а
Теперь давайте сфокусируемся на том, как игрок может приобретать заклинания,
создавая индивидуальный PickupItem для каждого объекта заклинания, который
может брать игрок.