239 |
С т р а н и ц а
//
Список того, что оружие
уже ударило этим взмахом
//
Убеждаемся, что всё через что проходит меч, получает удар один раз
TArray
ThingsHit;
//
предотвращаем урон, в кадрах
//
где не было взмаха меча
bool Swinging;
// "
Перестань бить себя" – используется, чтобы проверить если
//
актор держащий оружие бьёт сам себя
AMonster *WeaponHolder;
//
ограничивающий блок, определяющий, когда бьёт оружие
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category =
MeleeWeapon)
UBoxComponent* ProxBox;
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category =
MeleeWeapon)
UStaticMeshComponent* Mesh;
UFUNCTION(BlueprintNativeEvent, Category = Collision)
void Prox( AActor* OtherActor, UPrimitiveComponent* OtherComp, int32
OtherBodyIndex, bool bFromSweep, const FHitResult & SweepResult );
void Swing();
void Rest();
};
Обратите внимание, как я использовал ограничивающий блок (также известный
как ограничивающий параллелепипед) для ProxBox, а не ограничивающую сферу.
Это потому что мечи и топоры будут лучше обрабатываться посредством блоков
нежели сфер. Есть две функции-члены, Rest() и Swing(), которые дают
MeleeWeapon знать, в каком состоянии находится актор (стоит спокойно или
делает взмахи). Есть также свойство TArray ThingsHit в этом классе,
которое отслеживает удары актора, при каждом взмахе оружием. Мы
программируем это так, что оружие может наносить только один удар при одном
взмахе.
Файл AMeleeWeapon.cpp будет содержать только базовый конструктор и какой-то
простой код, чтобы посылать повреждения другому актору – OtherActor, когда наш
меч бьёт его. Файл MeleeWeapon.cpp содержит следующий код:
AMeleeWeapon::AMeleeWeapon(const class FObjectInitializer& PCIP) :
Super(PCIP)
{
AttackDamage = 1;
Swinging = false;
WeaponHolder = NULL;
Mesh = PCIP.CreateDefaultSubobject(this, TEXT("Mesh"));
RootComponent = Mesh;
ProxBox = PCIP.CreateDefaultSubobject(this, TEXT("ProxBox"));
240 |
С т р а н и ц а
ProxBox->OnComponentBeginOverlap.AddDynamic( this, &AMeleeWeapon::Prox );
ProxBox->AttachTo( RootComponent );
}
void AMeleeWeapon::Prox_Implementation( AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep,
const FHitResult & SweepResult )
{
//
не бьём не корневые компоненты
if( OtherComp != OtherActor->GetRootComponent() )
{
return;
}
//
избегаем нанесение ударов когда нет замахов мечём,
//
избегаем
нанесение удаоров по себе, и
//
избегаем нанесение ударов по одному OtherActor дважды
if( Swinging && OtherActor != WeaponHolder && !ThingsHit.Contains(OtherActor) )
{
OtherActor->TakeDamage( AttackDamage + WeaponHolder- >BaseAttackDamage,
FDamageEvent(), NULL, this );
ThingsHit.Add( OtherActor );
}
}
void AMeleeWeapon::Swing()
{
ThingsHit.Empty(); //
опустошаем список
Swinging = true;
}
void AMeleeWeapon::Rest()
{
ThingsHit.Empty();
Swinging = false;
}
Достарыңызбен бөлісу: