void AAmethystWeapon_Projectile::FireWeapon()
{
    FVector ShootDir = GetAdjustedAim();
    FVector Origin = GetMuzzleLocation();
    
    // trace from camera to check what's under crosshair
    const float ProjectileAdjustRange = 10000.0f;
    const FVector StartTrace = GetCameraDamageStartLocation(ShootDir);
    const FVector EndTrace = StartTrace + ShootDir * ProjectileAdjustRange;
    FHitResult Impact = WeaponTrace(StartTrace, EndTrace);
    
    // and adjust directions to hit that actor
    if (Impact.bBlockingHit)
    {
        const FVector AdjustedDir = (Impact.ImpactPoint - Origin).SafeNormal();
        bool bWeaponPenetration = false;
        
        const float DirectionDot = FVector::DotProduct(AdjustedDir, ShootDir);
        if (DirectionDot < 0.0f)
        {
            // shooting backwards = weapon is penetrating
            bWeaponPenetration = true;
        }
        else if (DirectionDot < 0.5f)
        {
            // check for weapon penetration if angle difference is big enough
            // raycast along weapon mesh to check if there's blocking hit
            
            FVector MuzzleStartTrace = Origin - GetMuzzleDirection() * 150.0f;
            FVector MuzzleEndTrace = Origin;
            FHitResult MuzzleImpact = WeaponTrace(MuzzleStartTrace, MuzzleEndTrace);
            
            if (MuzzleImpact.bBlockingHit)
            {
                bWeaponPenetration = true;
            }
        }
        
        if (bWeaponPenetration)
        {
            // spawn at crosshair position
            Origin = Impact.ImpactPoint - ShootDir * 10.0f;
        }
        else
        {
            // adjust direction to hit
            ShootDir = AdjustedDir;
        }
    }
    
    ServerFireProjectile(Origin, ShootDir);
}
示例#2
0
void AWizardsCharacter::OnFire()
{
	if (!mySpellBook.IsValidIndex(0)) {
		UE_LOG(LogTemp, Warning, TEXT("Spell Gathering Needed!"));
		newCharactersSpells();
	}
	if (Mana > mySpellBook[currSpell].spellCost) {
		Mana -= mySpellBook[currSpell].spellCost;
		// try and fire a projectile

		if (mySpellBook[currSpell].spellType == 0)
		{
			const FRotator SpawnRotation = GetControlRotation();
			const FVector SpawnLocation = GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* projParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				UParticleSystem* blastParticle = particleList[mySpellBook[currSpell].spellEffect + 5];
				AWizardsProjectile* wizardsSpell = World->SpawnActor<AWizardsProjectile>(ProjectileClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsSpell->SpellCreation(&mySpellBook[currSpell], projParticle, blastParticle, this);*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);//mySpellBook[currSpell]);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		else if (mySpellBook[currSpell].spellType == 1) {
			const FRotator SpawnRotation = FRotator(0.0);//GetControlRotation();
														 // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
			const FVector SpawnLocation = FVector(0.0);//GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* blastParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				AWizardsBlast* wizardsSpell = World->SpawnActor<AWizardsBlast>(BlastClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsSpell->SpellCreation(blastParticle, mySpellBook[currSpell].spellSize, mySpellBook[currSpell].spellDamage, this);
				wizardsSpell->AttachRootComponentTo(GetCapsuleComponent());//Probably useful for Blasts, Rays, and Conical attacks*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		else if (mySpellBook[currSpell].spellType == 2) {
			const FRotator SpawnRotation = FRotator(0.0);//GetControlRotation();
														 // MuzzleOffset is in camera space, so transform it to world space before offsetting from the character location to find the final muzzle position
			const FVector SpawnLocation = FVector(0.0);//GetActorLocation() + SpawnRotation.RotateVector(GunOffset);

			UWorld* const World = GetWorld();
			if (World)
			{
				// spawn the projectile at the muzzle
				/*UParticleSystem* coneParticle = particleList[mySpellBook[currSpell].spellEffect + mySpellBook[currSpell].spellType * 5];
				AWizardsCone* wizardsCone = World->SpawnActor<AWizardsCone>(ConeClass, SpawnLocation, SpawnRotation);// , myparams);
				wizardsCone->SpellCreation(coneParticle, mySpellBook[currSpell].spellSize, mySpellBook[currSpell].spellDamage, this);
				wizardsCone->AttachRootComponentTo(GetCapsuleComponent());//Probably useful for Blasts, Rays, and Conical attacks
				activeAttack = Cast<AActor>(wizardsCone);*/
				if (Role < ROLE_Authority)
				{
					ServerFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
				else {
					ClientFireProjectile(mySpellBook[currSpell], SpawnRotation, SpawnLocation);
				}
			}
		}
		// God this sound is so annoying
		/*if (FireSound != NULL)
		{
		UGameplayStatics::PlaySoundAtLocation(this, FireSound, GetActorLocation());
		}*/

		// try and play a firing animation if specified
		if (FireAnimation != NULL)
		{
			// Get the animation object for the arms mesh
			UAnimInstance* AnimInstance = Mesh1P->GetAnimInstance();
			if (AnimInstance != NULL)
			{
				AnimInstance->Montage_Play(FireAnimation, 1.f);
			}
		}

	}
}