gedamial
(gedamial)
July 24, 2018, 6:29pm
1
My Projectile collides with the Character that fired it when shooting upwards.
This is how I spawn it in the Weapon class:
MyOwner is the Character that owns the Weapon
FVector SocketLocation = MyOwner->GetMesh()->GetSocketLocation((FName("WeaponSocket")));
FVector SocketRotation = MyOwner->GetMesh()->GetSocketRotation((FName("WeaponSocket"))).Vector();
FVector CameraLoc;
FRotator CameraRot;
MyOwner->GetActorEyesViewPoint(CameraLoc, CameraRot);
FVector Origin = SocketLocation;
FVector ShootDir = CameraRot.Vector();
// trace from camera to check what's under crosshair
const float ProjectileAdjustRange = Range;
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).GetSafeNormal();
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 - SocketRotation * 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;
}
}
FTransform SpawnTM(MyOwner->GetMesh()->GetSocketLocation((FName("WeaponSocket"))));
APAProjectile* Projectile = Cast<APAProjectile>(UGameplayStatics::BeginDeferredActorSpawnFromClass(this, ProjectileClass, SpawnTM));
if (Projectile)
{
Projectile->Instigator = Instigator;
Projectile->SetOwner(this);
Projectile->InitVelocity(ShootDir); // here we set the direction of our projectile
UGameplayStatics::FinishSpawningActor(Projectile, SpawnTM);
}
The **WeaponSocket **is in the Skeleton and I’ve set it in a position where the weapon would be:
But when I shoot upwards, the Projectile detects the collision and applies damage to the “shooter”.
How could I solve?
Thanks in advance.
gedamial
(gedamial)
July 30, 2018, 10:21am
2
bump if there’s a better way to achieve projectile shooting, let me know
Hey there,
Try calling IgnoreActorWhenMoving(this, true) on the projectile’s collision component, ‘this’ being your character.
MyProjectileCollision->IgnoreActorWhenMoving(MyCharacter, /*bShouldIgnore=*/true);
Do this before calling UGameplayStatics::FinishSpawningActor()
gedamial
(gedamial)
July 30, 2018, 6:42pm
4
Zhi_Kang_Shao:
Hey there,
Try calling IgnoreActorWhenMoving(this, true) on the projectile’s collision component, ‘this’ being your character.
MyProjectileCollision->IgnoreActorWhenMoving(MyCharacter, /*bShouldIgnore=*/true);
Do this before calling UGameplayStatics::FinishSpawningActor()
Hi and thanks for the answer.
After adding that line of code, this is what happens:
As you can see, when the Character (on the left) shoots upwards, the Projectile goes behind the Character himself and not towards the sky.
Why do you start with a trace? To shoot a projectile you only need transform and direction. Remove all the trace code and just spawn the projectile.
gedamial
(gedamial)
July 31, 2018, 9:30am
6
I use the trace to get the direction! Don’t know how to do it otherwise!
Whats wrong with this direction?
FVector ShootDir = CameraRot.Vector();
Nothing, that’s my point. I should be clearer; remove all code that calculates the direction, including the trace. Keep only the snippet above.
Test it! What happens?
gedamial
(gedamial)
August 3, 2018, 10:32am
10
Thank you! It solves the problem, BUT…
The projectile hits the wall BEFORE it aligns with the crosshair.
This means the projectile doesn’t hit the wall in the point I was aiming.
I’m quite sure that in every FPS the projectile hits the point you were aiming with the crosshair. This is a problem I don’t know how to solve!
If you are using physical projectiles they will drop if you have a reasonable speed, but that’s expected. The player need to lead the target and also compensate for how much the projectile will drop for the distance. For our game we always fire the projectile aligned with the crosshair, not really 100% correct but it feels better and is consistant between weapon types.
gedamial
(gedamial)
August 5, 2018, 1:15pm
12
If you are using physical projectiles they will drop if you have a reasonable speed, but that’s expected. The player need to lead the target and also compensate for how much the projectile will drop for the distance. For our game we always fire the projectile aligned with the crosshair, not really 100% correct but it feels better and is consistant between weapon types.
The projectile in this case is a rocket, so it doesn’t drop : it goes forward until it hits something. Any hint?
Look into your Projectile Movemement Component and find Gravity, you should be able to change the scale.
gedamial
(gedamial)
August 5, 2018, 7:20pm
14
It doesn’t have gravity. The problem is what I described before: it takes time ti align with the crosshair (since the projectile is spawned in the weapon socket location)
So you have an RPG that you fire from the hip and want it to hit exactly where the crosshair points to, ok slighty different from what I was thinking about. Can you change it to be a shoulder mounted RPG instead and then fire from the camera? Otherwise you are back to something similar that you started with.
gedamial
(gedamial)
August 25, 2018, 8:58pm
16
So you have an RPG that you fire from the hip and want it to hit exactly where the crosshair points to, ok slighty different from what I was thinking about. Can you change it to be a shoulder mounted RPG instead and then fire from the camera? Otherwise you are back to something similar that you started with.
Of course: the rocket has to hit the point I’m aiming at!
That’s the way it works in 99,9% of videogames I believe.
But something tells me I shouldn’t spawn the projectile at the weapon muzzle.
Any suggestions?
I don’t see why spawning your projectile at the muzzle would be a bad idea, how else would you do it? I do recommend pooling your projectiles in an object pool instead of spawning them if you have a lot.
gedamial
(gedamial)
August 27, 2018, 9:32am
18
The alternative would be to spawn the projectile in front of the camera, so it will SURELY hit the crosshair.
Spawning it from the weapon muzzle causes the issue I described some posts ago
How about, when shooting the weapon
FVector TargetLocation = Do a line trace or get hit result under mouse cursor or whatever determines the target location where your weapon is pointing at
FVector StartLocation = Get the weapons missile launch location (a Slot location, for example)
Use
UKismetMathLibrary::FindLookAtRotation(StartLocation, TargetLocation);
to get the rotation needed to get from the start point to the end point in a straight line.
That should give you the proper direction/rotation to shoot from your weapons missile spawn location to wherever you want to shoot at, no matter where your missile launch location is…
If you want to get the direction as a FVector instead of a Rotator, use
UKismetMathLibrary::FindLookAtRotation(StartLocation, TargetLocation).Vector();
If the compiler can’t find UKismetMathLibrary, do
#include "Kismet/KismetMathLibrary.h"
Intellisense might complain (it does for me) that FindLookAtRotation is private/inaccessible, but it should still compile and work just fine.
gedamial
(gedamial)
August 27, 2018, 3:38pm
20
StefanHohnwald:
How about, when shooting the weapon
FVector TargetLocation = Do a line trace or get hit result under mouse cursor or whatever determines the target location where your weapon is pointing at
FVector StartLocation = Get the weapons missile launch location (a Slot location, for example)
Use
UKismetMathLibrary::FindLookAtRotation(StartLocation, TargetLocation);
to get the rotation needed to get from the start point to the end point in a straight line.
Thank you for the detailed explanation!
The problem isn’t the implementation, but the system itself!
Should projectiles start from the muzzle weapon or from the camera?