Add aim assist
This commit is contained in:
parent
27edeb0f0c
commit
f551802cef
@ -51,6 +51,7 @@ bUseSplitscreen=False
|
||||
+Profiles=(Name="UI",CollisionEnabled=QueryOnly,bCanModify=False,ObjectTypeName="WorldDynamic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility"),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap)),HelpMessage="WorldStatic object that overlaps all actors by default. All new custom channels will use its own default response. ")
|
||||
+Profiles=(Name="Pickup",CollisionEnabled=QueryAndPhysics,bCanModify=True,ObjectTypeName="WorldStatic",CustomResponses=((Channel="WorldStatic",Response=ECR_Overlap),(Channel="WorldDynamic",Response=ECR_Overlap),(Channel="Pawn",Response=ECR_Overlap),(Channel="Visibility",Response=ECR_Overlap),(Channel="Camera",Response=ECR_Overlap),(Channel="PhysicsBody",Response=ECR_Overlap),(Channel="Vehicle",Response=ECR_Overlap),(Channel="Destructible",Response=ECR_Overlap),(Channel="Character",Response=ECR_Overlap)),HelpMessage="Item to pickup")
|
||||
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel1,DefaultResponse=ECR_Block,bTraceType=False,bStaticObject=False,Name="Character")
|
||||
+DefaultChannelResponses=(Channel=ECC_GameTraceChannel2,DefaultResponse=ECR_Ignore,bTraceType=True,bStaticObject=False,Name="Enemy")
|
||||
-ProfileRedirects=(OldName="BlockingVolume",NewName="InvisibleWall")
|
||||
-ProfileRedirects=(OldName="InterpActor",NewName="IgnoreOnlyPawn")
|
||||
-ProfileRedirects=(OldName="StaticMeshComponent",NewName="BlockAllDynamic")
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -4,9 +4,12 @@
|
||||
#include "BasePawn.h"
|
||||
#include "Components/StaticMeshComponent.h"
|
||||
#include "GameFramework/FloatingPawnMovement.h"
|
||||
#include "DrawDebugHelpers.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
#include "Util.h"
|
||||
|
||||
#define LogInfo(Msg) Util::log_info(TEXT("ABasePawn"), Msg)
|
||||
#define LogError(Msg) Util::log_error(TEXT("ABasePawn"), Msg)
|
||||
|
||||
// Sets default values
|
||||
ABasePawn::ABasePawn(const FObjectInitializer &object_initializer):
|
||||
@ -147,12 +150,30 @@ void ABasePawn::shoot()
|
||||
{
|
||||
if (current_ammo > 0)
|
||||
{
|
||||
FVector player_location = player_mesh->GetComponentLocation();
|
||||
const float y = yaw.calculate_yaw();
|
||||
const FRotator rotator(0, y, 0);
|
||||
FVector forward = FRotationMatrix(rotator).GetUnitAxis(EAxis::X) * 100;
|
||||
const FVector player_location = get_location();
|
||||
FRotator rotator(0, yaw.calculate_yaw(), 0);
|
||||
if (use_aim_assist)
|
||||
{
|
||||
LogInfo(FString::Printf(TEXT("Yaw %f"), rotator.Yaw));
|
||||
const float y_offset = aim_assist(player_location, rotator);
|
||||
if (y_offset != 0)
|
||||
{
|
||||
rotator.Yaw = y_offset;
|
||||
}
|
||||
LogInfo(FString::Printf(TEXT("Offset %f"), y_offset));
|
||||
FVector line_end = FVector(5000, 0, 0);
|
||||
FVector aim_line_end = rotator.RotateVector(line_end);
|
||||
// DrawDebugLine(
|
||||
// GetWorld(),
|
||||
// player_location,
|
||||
// aim_line_end + player_location,
|
||||
// FColor::Red,
|
||||
// true
|
||||
// );
|
||||
}
|
||||
|
||||
FVector spawn_location = player_location + forward;
|
||||
FVector forward = FRotationMatrix(rotator).GetUnitAxis(EAxis::X);
|
||||
FVector spawn_location = player_location + (forward * 100);
|
||||
FActorSpawnParameters spawnParameters;
|
||||
spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
|
||||
spawnParameters.Owner = this;
|
||||
@ -169,6 +190,81 @@ void ABasePawn::shoot()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the yaw angle needed to hit the nearest enemy target.
|
||||
*
|
||||
* @return Yaw angle offset.
|
||||
*/
|
||||
float ABasePawn::aim_assist(const FVector start, const FRotator rotator)
|
||||
{
|
||||
/*
|
||||
* Create trace end based on start location and given rotator.
|
||||
*/
|
||||
FVector trace = start + FVector(10000, 0, 0);
|
||||
trace = rotator.RotateVector(trace);
|
||||
|
||||
/*
|
||||
* Run box trace for enemy targets.
|
||||
*/
|
||||
FHitResult out_hit;
|
||||
const bool succeeded = UKismetSystemLibrary::SphereTraceSingle(
|
||||
GetWorld(),
|
||||
start,
|
||||
trace,
|
||||
aim_assist_distance,
|
||||
ETraceTypeQuery::TraceTypeQuery3, // "Enemy" trace channel
|
||||
false,
|
||||
TArray<AActor*>(),
|
||||
EDrawDebugTrace::Type::None,
|
||||
out_hit,
|
||||
true,
|
||||
FLinearColor::Green,
|
||||
FLinearColor::Green,
|
||||
0
|
||||
);
|
||||
|
||||
/*
|
||||
* No enemies were within range.
|
||||
*/
|
||||
if (!succeeded)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
ABasePawn* enemy_pawn = Cast<ABasePawn>(out_hit.Actor);
|
||||
/*
|
||||
* Bad setup. We should only be hitting pawns.
|
||||
*/
|
||||
if (!enemy_pawn)
|
||||
{
|
||||
LogError("Aim assist trace hit non-pawn");
|
||||
return 0;
|
||||
}
|
||||
|
||||
const FVector enemy_vector = enemy_pawn->get_location() - start;
|
||||
const FRotator new_rotator = enemy_vector.Rotation();
|
||||
|
||||
//FVector target_vector = FVector(enemy_vector.X, enemy_vector.Y, 0);
|
||||
//target_vector.Normalize();
|
||||
|
||||
//FVector actual_vector = FVector(trace.X, trace.Y, 0) - start;
|
||||
//actual_vector.Normalize();
|
||||
|
||||
//const float angle_between = UKismetMathLibrary::DegAcos(FVector::DotProduct(actual_vector, target_vector));
|
||||
//const FVector cross = FVector::CrossProduct(actual_vector, target_vector);
|
||||
//if (cross.Z > 0)
|
||||
//{
|
||||
// return angle_between;
|
||||
//}
|
||||
//else if (cross.Z < 0)
|
||||
//{
|
||||
// return angle_between * -1;
|
||||
//}
|
||||
|
||||
//return 0;
|
||||
return new_rotator.Yaw;
|
||||
}
|
||||
|
||||
void ABasePawn::handle_death()
|
||||
{
|
||||
/*
|
||||
|
@ -112,11 +112,20 @@ protected:
|
||||
float fire_rate_s;
|
||||
|
||||
/**
|
||||
* Max ammor.
|
||||
* Max ammo.
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Attack")
|
||||
int32 max_ammo;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UPROPERTY(EditAnywhere, Category = "Attack")
|
||||
float aim_assist_distance;
|
||||
|
||||
UPROPERTY(EditAnywhere, Category = "Attack")
|
||||
bool use_aim_assist;
|
||||
|
||||
/**
|
||||
* Shooting enabled;
|
||||
*/
|
||||
@ -146,4 +155,7 @@ protected:
|
||||
* Spawned death effect actor.
|
||||
*/
|
||||
AActor* death_effect;
|
||||
|
||||
private:
|
||||
float aim_assist(const FVector start, const FRotator rotator);
|
||||
};
|
||||
|
@ -38,14 +38,24 @@ void AEnemyAIController::Tick(float delta_time)
|
||||
else
|
||||
{
|
||||
FVector target_location = president->get_location();
|
||||
FVector current_location = Cast<ABasePawn>(GetPawn())->get_location();
|
||||
FVector between = target_location - current_location;
|
||||
between = FVector(between.X, between.Y, 0);
|
||||
between.Normalize();
|
||||
FVector extended = (between * overshoot_multiplier) + target_location;
|
||||
const ABasePawn* local_pawn = Cast<ABasePawn>(GetPawn());
|
||||
if (local_pawn)
|
||||
{
|
||||
FVector current_location = local_pawn->get_location();
|
||||
FVector between = target_location - current_location;
|
||||
between = FVector(between.X, between.Y, 0);
|
||||
between.Normalize();
|
||||
FVector extended = (between * overshoot_multiplier) + target_location;
|
||||
|
||||
MoveToLocation(extended);
|
||||
current_state = state_t::moving;
|
||||
}
|
||||
else
|
||||
{
|
||||
// This will be cleaned up shortly.
|
||||
current_state = state_t::dead;
|
||||
}
|
||||
|
||||
MoveToLocation(extended);
|
||||
current_state = state_t::moving;
|
||||
}
|
||||
break;
|
||||
case state_t::moving:
|
||||
@ -95,7 +105,7 @@ ABasePawn* AEnemyAIController::get_president() const
|
||||
|
||||
if (!found)
|
||||
{
|
||||
LogError("No president found!");
|
||||
// LogError("No president found!");
|
||||
}
|
||||
|
||||
return found;
|
||||
|
@ -43,6 +43,7 @@ private:
|
||||
wait,
|
||||
target,
|
||||
moving,
|
||||
dead
|
||||
};
|
||||
|
||||
ABasePawn* get_president() const;
|
||||
|
7
todo.txt
7
todo.txt
@ -14,6 +14,10 @@ xShoot from any direction
|
||||
xShoot at continuous rate when holding shoot button
|
||||
xAdd player damage
|
||||
xAdd player ammo
|
||||
xAdd auto aim
|
||||
Add art
|
||||
- Car models
|
||||
- Street shader
|
||||
Add win condition
|
||||
- Time based. Keep president alive until he reaches destination.
|
||||
Add HUD UI
|
||||
@ -21,9 +25,6 @@ Add menu
|
||||
Add local multiplayer
|
||||
x Blueprint
|
||||
- C++
|
||||
Add art
|
||||
- Car models
|
||||
- Street shader
|
||||
Add sounds
|
||||
Add juice
|
||||
Add muzzle on shoot
|
||||
|
Loading…
Reference in New Issue
Block a user