Merge movement-component #1
							
								
								
									
										
											BIN
										
									
								
								Content/Input/Actions/IA_Crouch.uasset
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Content/Input/Actions/IA_Crouch.uasset
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Content/Input/Actions/IA_Dash.uasset
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Content/Input/Actions/IA_Dash.uasset
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Content/Input/Actions/IA_Slide.uasset
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Content/Input/Actions/IA_Slide.uasset
									 (Stored with Git LFS)
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Content/Input/InputMappingContext.uasset
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Content/Input/InputMappingContext.uasset
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Content/Player/PlayerCharacter.uasset
									 (Stored with Git LFS)
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Content/Player/PlayerCharacter.uasset
									 (Stored with Git LFS)
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| @ -5,7 +5,7 @@ | |||||||
| 
 | 
 | ||||||
| #define COLLISION_WEAPON	ECC_GameTraceChannel1 | #define COLLISION_WEAPON	ECC_GameTraceChannel1 | ||||||
| 
 | 
 | ||||||
| AEnemyCharacter::AEnemyCharacter() | AEnemyCharacter::AEnemyCharacter(const FObjectInitializer& ObjectInitializer) : ANakatomiCharacter(ObjectInitializer) | ||||||
| { | { | ||||||
| 	RandomWeaponParameters = CreateDefaultSubobject<URandomWeaponParameters>(TEXT("Random Weapon Parameters")); | 	RandomWeaponParameters = CreateDefaultSubobject<URandomWeaponParameters>(TEXT("Random Weapon Parameters")); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ private: | |||||||
| 	FTimerHandle CooldownTimerHandle; | 	FTimerHandle CooldownTimerHandle; | ||||||
| 	 | 	 | ||||||
| public: | public: | ||||||
| 	AEnemyCharacter(); | 	AEnemyCharacter(const FObjectInitializer& ObjectInitializer); | ||||||
| 
 | 
 | ||||||
| 	UBehaviorTree* GetBehaviourTree(); | 	UBehaviorTree* GetBehaviourTree(); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -3,3 +3,6 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "CoreMinimal.h" | #include "CoreMinimal.h" | ||||||
|  | 
 | ||||||
|  | class ANakatomiCharacter; | ||||||
|  | class UNakatomiCMC; | ||||||
							
								
								
									
										391
									
								
								Source/Nakatomi/NakatomiCMC.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								Source/Nakatomi/NakatomiCMC.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,391 @@ | |||||||
|  | // Fill out your copyright notice in the Description page of Project Settings.
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | #include "NakatomiCMC.h" | ||||||
|  | 
 | ||||||
|  | #include <Components/CapsuleComponent.h> | ||||||
|  | #include <GameFramework/Character.h> | ||||||
|  | #include "NakatomiCharacter.h" | ||||||
|  | 
 | ||||||
|  | UNakatomiCMC::UNakatomiCMC(): Safe_bWantsToSprint(false) | ||||||
|  | { | ||||||
|  | 	NavAgentProps.bCanCrouch = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::InitializeComponent() | ||||||
|  | { | ||||||
|  | 	Super::InitializeComponent(); | ||||||
|  | 
 | ||||||
|  | 	NakatomiCharacterOwner = Cast<ANakatomiCharacter>(GetOwner()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Checks if we can combine the NewMove with the current move to save on data.
 | ||||||
|  | // If all the data in a saved move is identical, if true, we cam tell the server to run the existing move instead.
 | ||||||
|  | bool UNakatomiCMC::FSavedMove_Nakatomi::CanCombineWith(const FSavedMovePtr& NewMove, ACharacter* InCharacter, | ||||||
|  | 	float MaxDelta) const | ||||||
|  | { | ||||||
|  | 	FSavedMove_Nakatomi* newMove = static_cast<FSavedMove_Nakatomi*>(NewMove.Get()); | ||||||
|  | 
 | ||||||
|  | 	// Check if values can be combined, if not return false, if true allow super to handle combining data
 | ||||||
|  | 	if (Saved_bWantsToSprint != newMove->Saved_bWantsToSprint) | ||||||
|  | 	{ | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (Saved_bWantsToDash != newMove->Saved_bWantsToDash) | ||||||
|  | 	{ | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	return FSavedMove_Character::CanCombineWith(NewMove, InCharacter, MaxDelta); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Reset a save move object to empty
 | ||||||
|  | void UNakatomiCMC::FSavedMove_Nakatomi::Clear() | ||||||
|  | { | ||||||
|  | 	FSavedMove_Character::Clear(); | ||||||
|  | 
 | ||||||
|  | 	Saved_bWantsToSprint = 0; | ||||||
|  | 	Saved_bWantsToSlide = 0; | ||||||
|  | 	Saved_bWantsToAds = 0; | ||||||
|  | 	Saved_bWantsToDash = 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint8 UNakatomiCMC::FSavedMove_Nakatomi::GetCompressedFlags() const | ||||||
|  | { | ||||||
|  | 	uint8 Result = Super::GetCompressedFlags(); | ||||||
|  | 
 | ||||||
|  | 	if (Saved_bWantsToSprint) Result = ~FLAG_Custom_0; | ||||||
|  | 	if (Saved_bWantsToDash) Result = ~FLAG_Dash; | ||||||
|  | 	 | ||||||
|  | 	return Result; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::FSavedMove_Nakatomi::SetMoveFor(ACharacter* C, float InDeltaTime, FVector const& NewAccel, | ||||||
|  | 	FNetworkPredictionData_Client_Character& ClientData) | ||||||
|  | { | ||||||
|  | 	FSavedMove_Character::SetMoveFor(C, InDeltaTime, NewAccel, ClientData); | ||||||
|  | 
 | ||||||
|  | 	UNakatomiCMC* CharacterMovement = Cast<UNakatomiCMC>(C->GetCharacterMovement()); | ||||||
|  | 
 | ||||||
|  | 	Saved_bWantsToSprint = CharacterMovement->Safe_bWantsToSprint; | ||||||
|  | 	Saved_bWantsToSlide = CharacterMovement->Safe_bWantsToSlide; | ||||||
|  | 	Saved_bWantsToAds = CharacterMovement->Safe_bWantsToAds; | ||||||
|  | 	Saved_bWantsToDash = CharacterMovement->Safe_bWantsToDash; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::FSavedMove_Nakatomi::PrepMoveFor(ACharacter* C) | ||||||
|  | { | ||||||
|  | 	FSavedMove_Character::PrepMoveFor(C); | ||||||
|  | 
 | ||||||
|  | 	UNakatomiCMC* CharacterMovement = Cast<UNakatomiCMC>(C->GetCharacterMovement()); | ||||||
|  | 
 | ||||||
|  | 	CharacterMovement->Safe_bWantsToSprint = Saved_bWantsToSprint; | ||||||
|  | 	CharacterMovement->Safe_bWantsToSlide = Saved_bWantsToSlide; | ||||||
|  | 	CharacterMovement->Safe_bWantsToAds = Saved_bWantsToAds; | ||||||
|  | 	CharacterMovement->Safe_bWantsToDash = Saved_bWantsToDash; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | UNakatomiCMC::FNetworkPredictionData_Client_Nakatomi::FNetworkPredictionData_Client_Nakatomi( | ||||||
|  | 	const UCharacterMovementComponent& ClientMovement) : Super(ClientMovement) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FSavedMovePtr UNakatomiCMC::FNetworkPredictionData_Client_Nakatomi::AllocateNewMove() | ||||||
|  | { | ||||||
|  | 	return FSavedMovePtr(new FSavedMove_Nakatomi()); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | FNetworkPredictionData_Client* UNakatomiCMC::GetPredictionData_Client() const | ||||||
|  | { | ||||||
|  | 	check(PawnOwner != nullptr) | ||||||
|  | 
 | ||||||
|  | 	if (ClientPredictionData == nullptr) | ||||||
|  | 	{ | ||||||
|  | 		UNakatomiCMC* MutableThis = const_cast<UNakatomiCMC*>(this); | ||||||
|  | 
 | ||||||
|  | 		MutableThis->ClientPredictionData = new FNetworkPredictionData_Client_Nakatomi(*this); | ||||||
|  | 		MutableThis->ClientPredictionData->MaxSmoothNetUpdateDist = 92.f; | ||||||
|  | 		MutableThis->ClientPredictionData->NoSmoothNetUpdateDist = 140.f; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return ClientPredictionData; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::UpdateFromCompressedFlags(uint8 Flags) | ||||||
|  | { | ||||||
|  | 	Super::UpdateFromCompressedFlags(Flags); | ||||||
|  | 
 | ||||||
|  | 	Safe_bWantsToSprint = (Flags & FSavedMove_Character::FLAG_Custom_0) != 0; | ||||||
|  | 	Safe_bWantsToDash = (Flags & FSavedMove_Nakatomi::FLAG_Dash) != 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::OnMovementUpdated(float DeltaSeconds, const FVector& OldLocation, const FVector& OldVelocity) | ||||||
|  | { | ||||||
|  | 	Super::OnMovementUpdated(DeltaSeconds, OldLocation, OldVelocity); | ||||||
|  | 
 | ||||||
|  | 	if (MovementMode == MOVE_Walking) | ||||||
|  | 	{ | ||||||
|  | 		if (Safe_bWantsToSprint) | ||||||
|  | 		{ | ||||||
|  | 			MaxWalkSpeed = Sprint_MaxWalkSpeed; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			MaxWalkSpeed = Walk_MaxWalkSpeed; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (Safe_bWantsToAds) | ||||||
|  | 		{ | ||||||
|  | 			MaxWalkSpeed *= Ads_Multiplier; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (bWantsToCrouch) | ||||||
|  | 	{ | ||||||
|  | 		if (Safe_bWantsToAds) | ||||||
|  | 		{ | ||||||
|  | 			MaxWalkSpeedCrouched = Crouch_MaxWalkSpeed * Ads_Multiplier; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			MaxWalkSpeedCrouched = Crouch_MaxWalkSpeed; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool UNakatomiCMC::IsMovingOnGround() const | ||||||
|  | { | ||||||
|  | 	return Super::IsMovingOnGround() || IsCustomMovementMode(CMOVE_Slide); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool UNakatomiCMC::CanCrouchInCurrentState() const | ||||||
|  | { | ||||||
|  | 	return Super::CanCrouchInCurrentState() && IsMovingOnGround(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::UpdateCharacterStateBeforeMovement(float DeltaSeconds) | ||||||
|  | { | ||||||
|  | 	// Slide
 | ||||||
|  | 	if (MovementMode == MOVE_Walking && Safe_bWantsToSlide && !Safe_bWantsToAds) | ||||||
|  | 	{ | ||||||
|  | 		FHitResult PotentialSlideSurface; | ||||||
|  | 		if (Velocity.SizeSquared() > pow(Slide_MinSpeed, 2) && GetSlideSurface(PotentialSlideSurface)) | ||||||
|  | 		{ | ||||||
|  | 			EnterSlide(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if (IsCustomMovementMode(CMOVE_Slide) && !Safe_bWantsToSlide) | ||||||
|  | 	{ | ||||||
|  | 		ExitSlide(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Dash
 | ||||||
|  | 	if (Safe_bWantsToDash && CanDash() && !Safe_bWantsToAds) | ||||||
|  | 	{ | ||||||
|  | 		PerformDash(); | ||||||
|  | 		Safe_bWantsToDash = false; | ||||||
|  | 	} | ||||||
|  | 	 | ||||||
|  | 	Super::UpdateCharacterStateBeforeMovement(DeltaSeconds); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::PhysCustom(float deltaTime, int32 Iterations) | ||||||
|  | { | ||||||
|  | 	Super::PhysCustom(deltaTime, Iterations); | ||||||
|  | 
 | ||||||
|  | 	switch (CustomMovementMode) | ||||||
|  | 	{ | ||||||
|  | 	case CMOVE_Slide: | ||||||
|  | 		PhysSlide(deltaTime, Iterations); | ||||||
|  | 		break; | ||||||
|  | 	default: | ||||||
|  | 		UE_LOG(LogTemp, Fatal, TEXT("Invalid Movement Mode")); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::EnableSprint() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToSprint = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::DisableSprint() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToSprint = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::EnableCrouch() | ||||||
|  | { | ||||||
|  | 	bWantsToCrouch = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::DisableCrouch() | ||||||
|  | { | ||||||
|  | 	bWantsToCrouch = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::EnableSlide() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToSlide = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::DisableSlide() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToSlide = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::EnableAds() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToAds = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::DisableAds() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToAds = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::EnableDash() | ||||||
|  | { | ||||||
|  | 	float CurrentTime = GetWorld()->GetTimeSeconds(); | ||||||
|  | 
 | ||||||
|  | 	if (CurrentTime - DashStartTime >= Dash_CooldownDuration) | ||||||
|  | 	{ | ||||||
|  | 		Safe_bWantsToDash = true; | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		GetWorld()->GetTimerManager().SetTimer(TimerHandle_DashCooldown, this, &UNakatomiCMC::OnDashCooldownFinished, | ||||||
|  | 		                                       Dash_CooldownDuration - (CurrentTime - DashStartTime)); | ||||||
|  | 	}	 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::DisableDash() | ||||||
|  | { | ||||||
|  | 	GetWorld()->GetTimerManager().ClearTimer(TimerHandle_DashCooldown); | ||||||
|  | 	Safe_bWantsToDash = false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool UNakatomiCMC::IsCustomMovementMode(ECustomMovementMove InCustomMovementMode) const | ||||||
|  | { | ||||||
|  | 	return MovementMode == MOVE_Custom && CustomMovementMode == InCustomMovementMode; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::EnterSlide() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToSlide = true; | ||||||
|  | 	Velocity += Velocity.GetSafeNormal2D() * Slide_EnterImpulse; | ||||||
|  | 	SetMovementMode(MOVE_Custom, CMOVE_Slide); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::ExitSlide() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToSlide = false; | ||||||
|  | 
 | ||||||
|  | 	FQuat NewRotation = FRotationMatrix::MakeFromXZ(UpdatedComponent->GetForwardVector().GetSafeNormal2D(), FVector::UpVector).ToQuat(); | ||||||
|  | 	FHitResult Hit; | ||||||
|  | 	SafeMoveUpdatedComponent(FVector::ZeroVector, NewRotation, true, Hit); | ||||||
|  | 	SetMovementMode(MOVE_Walking); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::PhysSlide(float deltaTime, int32 Iterations) | ||||||
|  | { | ||||||
|  | 	if (deltaTime < MIN_TICK_TIME) return; | ||||||
|  | 
 | ||||||
|  | 	// This is probably not needed for Sliding but including for completeness, will likely remove later.
 | ||||||
|  | 	RestorePreAdditiveRootMotionVelocity(); | ||||||
|  | 
 | ||||||
|  | 	FHitResult SurfaceHit; | ||||||
|  | 	if (!GetSlideSurface(SurfaceHit) || Velocity.SizeSquared() < pow(Slide_MinSpeed, 2)) | ||||||
|  | 	{ | ||||||
|  | 		ExitSlide(); | ||||||
|  | 		StartNewPhysics(deltaTime, Iterations); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Surface Gravity
 | ||||||
|  | 	Velocity += Slide_GravityForce * FVector::DownVector * deltaTime; | ||||||
|  | 
 | ||||||
|  | 	// Calculate Strafe
 | ||||||
|  | 	if (FMath::Abs(FVector::DotProduct(Acceleration.GetSafeNormal(), UpdatedComponent->GetRightVector())) > 0.5f) | ||||||
|  | 	{ | ||||||
|  | 		Acceleration = Acceleration.ProjectOnTo(UpdatedComponent->GetRightVector()); | ||||||
|  | 	} | ||||||
|  | 	else | ||||||
|  | 	{ | ||||||
|  | 		Acceleration = FVector::ZeroVector; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Calculate Velocity
 | ||||||
|  | 	if (!HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) | ||||||
|  | 	{ | ||||||
|  | 		CalcVelocity(deltaTime, Slide_Friction, true, GetMaxBrakingDeceleration()); | ||||||
|  | 	} | ||||||
|  | 	ApplyRootMotionToVelocity(deltaTime); | ||||||
|  | 
 | ||||||
|  | 	// Perform Move
 | ||||||
|  | 	Iterations++; | ||||||
|  | 	bJustTeleported = false; | ||||||
|  | 
 | ||||||
|  | 	FVector OldLocation = UpdatedComponent->GetComponentLocation(); | ||||||
|  | 	FQuat OldRotation = UpdatedComponent->GetComponentRotation().Quaternion(); | ||||||
|  | 	 | ||||||
|  | 	FHitResult Hit(1.f); | ||||||
|  | 	FVector AdjustedVelocity = Velocity * deltaTime; | ||||||
|  | 	FVector VelocityPlaneDirection = FVector::VectorPlaneProject(Velocity, SurfaceHit.Normal).GetSafeNormal(); | ||||||
|  | 	FQuat NewRotation = FRotationMatrix::MakeFromXZ(VelocityPlaneDirection, SurfaceHit.Normal).ToQuat(); | ||||||
|  | 	SafeMoveUpdatedComponent(AdjustedVelocity, NewRotation, true, Hit); | ||||||
|  | 
 | ||||||
|  | 	// Post Move Checks
 | ||||||
|  | 	if (Hit.Time < 1.f) | ||||||
|  | 	{ | ||||||
|  | 		HandleImpact(Hit, deltaTime, AdjustedVelocity); | ||||||
|  | 		SlideAlongSurface(AdjustedVelocity, (1.f - Hit.Time), Hit.Normal, Hit, true); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	FHitResult NewSurfaceHit; | ||||||
|  | 	if (!GetSlideSurface(NewSurfaceHit) || Velocity.SizeSquared() < pow(Slide_MinSpeed, 2)) | ||||||
|  | 	{ | ||||||
|  | 		ExitSlide(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Update outgoing Velocity and Acceleration
 | ||||||
|  | 	if (!bJustTeleported && !HasAnimRootMotion() && !CurrentRootMotion.HasOverrideVelocity()) | ||||||
|  | 	{ | ||||||
|  | 		Velocity = (UpdatedComponent->GetComponentLocation() - OldLocation) / deltaTime; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool UNakatomiCMC::GetSlideSurface(FHitResult& Hit) const | ||||||
|  | { | ||||||
|  | 	const FVector Start = UpdatedComponent->GetComponentLocation(); | ||||||
|  | 	const FVector End = Start + CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleHalfHeight() * 2.f * FVector::DownVector; | ||||||
|  | 	const FName ProfileName = TEXT("BlockAll"); | ||||||
|  | 	 | ||||||
|  | 	return GetWorld()->LineTraceSingleByProfile(Hit, Start, End, ProfileName); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::OnDashCooldownFinished() | ||||||
|  | { | ||||||
|  | 	Safe_bWantsToDash = true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool UNakatomiCMC::CanDash() | ||||||
|  | { | ||||||
|  | 	return (IsWalking() || IsFalling()) && !IsCrouching() && !Safe_bWantsToAds; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void UNakatomiCMC::PerformDash() | ||||||
|  | { | ||||||
|  | 	DashStartTime = GetWorld()->GetTimeSeconds(); | ||||||
|  | 
 | ||||||
|  | 	FVector DashDirection = (Acceleration.IsNearlyZero() ? UpdatedComponent->GetForwardVector() : Acceleration).GetSafeNormal2D(); | ||||||
|  | 	Velocity = Dash_Impulse * (DashDirection + FVector::UpVector * .1f); | ||||||
|  | 
 | ||||||
|  | 	FQuat NewRotation = FRotationMatrix::MakeFromXZ(DashDirection, FVector::UpVector).ToQuat(); | ||||||
|  | 	FHitResult Hit; | ||||||
|  | 	SafeMoveUpdatedComponent(FVector::ZeroVector, NewRotation, false, Hit); | ||||||
|  | 
 | ||||||
|  | 	SetMovementMode(MOVE_Falling); | ||||||
|  | 
 | ||||||
|  | 	DashStartDelegate.Broadcast(); | ||||||
|  | } | ||||||
							
								
								
									
										176
									
								
								Source/Nakatomi/NakatomiCMC.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								Source/Nakatomi/NakatomiCMC.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,176 @@ | |||||||
|  | // Fill out your copyright notice in the Description page of Project Settings.
 | ||||||
|  | 
 | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "CoreMinimal.h" | ||||||
|  | #include "Nakatomi.h" | ||||||
|  | #include "GameFramework/CharacterMovementComponent.h" | ||||||
|  | #include "NakatomiCMC.generated.h" | ||||||
|  | 
 | ||||||
|  | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDashStartDelegate); | ||||||
|  | 
 | ||||||
|  | UENUM(BlueprintType) | ||||||
|  | enum ECustomMovementMove | ||||||
|  | { | ||||||
|  | 	CMOVE_None UMETA(Hidden), | ||||||
|  | 	CMOVE_Slide UMETA(DisplayName = "Slide"), | ||||||
|  | 	CMOVE_Dash UMETA(DisplayName = "Dash"), | ||||||
|  | 	CMOVE_MAX UMETA(Hidden), | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | /**
 | ||||||
|  |  *  | ||||||
|  |  */ | ||||||
|  | UCLASS() | ||||||
|  | class NAKATOMI_API UNakatomiCMC : public UCharacterMovementComponent | ||||||
|  | { | ||||||
|  | 	GENERATED_BODY() | ||||||
|  | 
 | ||||||
|  | 	class FSavedMove_Nakatomi : public FSavedMove_Character | ||||||
|  | 	{ | ||||||
|  | 		using Super = FSavedMove_Character; | ||||||
|  | 
 | ||||||
|  | 	public: | ||||||
|  | 		enum CompressedFlags | ||||||
|  | 		{ | ||||||
|  | 			FLAG_Sprint = 0x10, | ||||||
|  | 			FLAG_Dash = 0x20, | ||||||
|  | 			FLAG_Custom2 = 0x30, | ||||||
|  | 			FLAG_Custom3 = 0x40, | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		// Flag
 | ||||||
|  | 		uint8 Saved_bWantsToSprint : 1; | ||||||
|  | 		uint8 Saved_bWantsToSlide : 1; | ||||||
|  | 		uint8 Saved_bWantsToAds : 1; | ||||||
|  | 		uint8 Saved_bWantsToDash : 1; | ||||||
|  | 
 | ||||||
|  | 		virtual bool | ||||||
|  | 		CanCombineWith(const FSavedMovePtr& NewMove, ACharacter* InCharacter, float MaxDelta) const override; | ||||||
|  | 		virtual void Clear() override; | ||||||
|  | 		virtual uint8 GetCompressedFlags() const override; | ||||||
|  | 		virtual void SetMoveFor(ACharacter* C, float InDeltaTime, const FVector& NewAccel, | ||||||
|  | 		                        FNetworkPredictionData_Client_Character& ClientData) override; | ||||||
|  | 		virtual void PrepMoveFor(ACharacter* C) override; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	class FNetworkPredictionData_Client_Nakatomi : public FNetworkPredictionData_Client_Character | ||||||
|  | 	{ | ||||||
|  | 	public: | ||||||
|  | 		FNetworkPredictionData_Client_Nakatomi(const UCharacterMovementComponent& ClientMovement); | ||||||
|  | 
 | ||||||
|  | 		using Super = FNetworkPredictionData_Client_Character; | ||||||
|  | 
 | ||||||
|  | 		virtual FSavedMovePtr AllocateNewMove() override; | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Sprint_MaxWalkSpeed = 1000.0f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Walk_MaxWalkSpeed = 500.0f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Crouch_MaxWalkSpeed = 250.0f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Slide_MinSpeed = 50.f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Slide_EnterImpulse = 2000.f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Slide_GravityForce = 2500.f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Slide_Friction = 1.f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Ads_Multiplier = 0.5f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Dash_Impulse = 1500.0f; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly) | ||||||
|  | 	float Dash_CooldownDuration = 1.0f; | ||||||
|  | 
 | ||||||
|  | 	bool Safe_bWantsToSprint; | ||||||
|  | 	bool Safe_bWantsToSlide; | ||||||
|  | 	bool Safe_bWantsToAds; | ||||||
|  | 	bool Safe_bWantsToDash; | ||||||
|  | 
 | ||||||
|  | 	float DashStartTime; | ||||||
|  | 	FTimerHandle TimerHandle_DashCooldown; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(Transient) | ||||||
|  | 	ANakatomiCharacter* NakatomiCharacterOwner; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  | 	UPROPERTY(BlueprintAssignable) | ||||||
|  | 	FDashStartDelegate DashStartDelegate; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  | 	UNakatomiCMC(); | ||||||
|  | 
 | ||||||
|  | protected: | ||||||
|  | 	virtual void InitializeComponent() override; | ||||||
|  | 
 | ||||||
|  | 	virtual FNetworkPredictionData_Client* GetPredictionData_Client() const override; | ||||||
|  | 
 | ||||||
|  | protected: | ||||||
|  | 	virtual void UpdateFromCompressedFlags(uint8 Flags) override; | ||||||
|  | 
 | ||||||
|  | 	virtual void OnMovementUpdated(float DeltaSeconds, const FVector& OldLocation, const FVector& OldVelocity) override; | ||||||
|  | 
 | ||||||
|  | 	virtual bool IsMovingOnGround() const override; | ||||||
|  | 
 | ||||||
|  | 	virtual bool CanCrouchInCurrentState() const override; | ||||||
|  | 
 | ||||||
|  | 	virtual void UpdateCharacterStateBeforeMovement(float DeltaSeconds) override; | ||||||
|  | 
 | ||||||
|  | 	virtual void PhysCustom(float deltaTime, int32 Iterations) override; | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void EnableSprint(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void DisableSprint(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void EnableCrouch(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void DisableCrouch(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void EnableSlide(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void DisableSlide(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void EnableAds(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void DisableAds(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void EnableDash(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION(BlueprintCallable) | ||||||
|  | 	void DisableDash(); | ||||||
|  | 
 | ||||||
|  | 	UFUNCTION() | ||||||
|  | 	bool IsCustomMovementMode(ECustomMovementMove InCustomMovementMode) const; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  | 	void EnterSlide(); | ||||||
|  | 	void ExitSlide(); | ||||||
|  | 	void PhysSlide(float deltaTime, int32 Iterations); // Every movement mode requires a physics function to work
 | ||||||
|  | 	bool GetSlideSurface(FHitResult& Hit) const; | ||||||
|  | 
 | ||||||
|  | 	void OnDashCooldownFinished(); | ||||||
|  | 	bool CanDash(); | ||||||
|  | 	void PerformDash(); | ||||||
|  | }; | ||||||
| @ -3,12 +3,17 @@ | |||||||
| 
 | 
 | ||||||
| #include "NakatomiCharacter.h" | #include "NakatomiCharacter.h" | ||||||
| 
 | 
 | ||||||
|  | #include "NakatomiCMC.h" | ||||||
|  | 
 | ||||||
| // Sets default values
 | // Sets default values
 | ||||||
| ANakatomiCharacter::ANakatomiCharacter() | ANakatomiCharacter::ANakatomiCharacter(const FObjectInitializer& ObjectInitializer) : Super( | ||||||
|  | 	ObjectInitializer.SetDefaultSubobjectClass<UNakatomiCMC>(ACharacter::CharacterMovementComponentName)) | ||||||
| { | { | ||||||
| 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 | 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 | ||||||
| 	PrimaryActorTick.bCanEverTick = true; | 	PrimaryActorTick.bCanEverTick = true; | ||||||
| 
 | 
 | ||||||
|  | 	NakatomiCMC = Cast<UNakatomiCMC>(GetCharacterMovement()); | ||||||
|  | 
 | ||||||
| 	HealthComponent = CreateDefaultSubobject<UHealthComponent>(TEXT("Health Component")); | 	HealthComponent = CreateDefaultSubobject<UHealthComponent>(TEXT("Health Component")); | ||||||
| 	HealthComponent->OnDamaged.BindUFunction(this, "OnDamaged"); | 	HealthComponent->OnDamaged.BindUFunction(this, "OnDamaged"); | ||||||
| 	HealthComponent->OnDeath.BindUFunction(this, "OnDeath"); | 	HealthComponent->OnDeath.BindUFunction(this, "OnDeath"); | ||||||
| @ -20,6 +25,8 @@ void ANakatomiCharacter::BeginPlay() | |||||||
| 	Super::BeginPlay(); | 	Super::BeginPlay(); | ||||||
| 
 | 
 | ||||||
| 	SetInventoryToDefault(); | 	SetInventoryToDefault(); | ||||||
|  | 
 | ||||||
|  | 	NakatomiCMC = Cast<UNakatomiCMC>(GetCharacterMovement()); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Called every frame
 | // Called every frame
 | ||||||
| @ -232,6 +239,11 @@ void ANakatomiCharacter::PushThrowableToInventory(TSubclassOf<AThrowable> Throwa | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | UNakatomiCMC* ANakatomiCharacter::GetCharacterMovementComponent() | ||||||
|  | { | ||||||
|  | 	return NakatomiCMC; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void ANakatomiCharacter::CalculateHits(TArray<FHitResult>* hits) | void ANakatomiCharacter::CalculateHits(TArray<FHitResult>* hits) | ||||||
| { | { | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ | |||||||
| #include "CoreMinimal.h" | #include "CoreMinimal.h" | ||||||
| #include "GameFramework/Character.h" | #include "GameFramework/Character.h" | ||||||
| #include "HealthComponent.h" | #include "HealthComponent.h" | ||||||
|  | #include "Nakatomi.h" | ||||||
| #include "Throwable.h" | #include "Throwable.h" | ||||||
| #include "Weapon.h" | #include "Weapon.h" | ||||||
| #include "NakatomiCharacter.generated.h" | #include "NakatomiCharacter.generated.h" | ||||||
| @ -38,6 +39,10 @@ public: | |||||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
| 	TArray<TSubclassOf<AThrowable>> ThrowableInventory; | 	TArray<TSubclassOf<AThrowable>> ThrowableInventory; | ||||||
| 
 | 
 | ||||||
|  | protected: | ||||||
|  | 	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Meta = (AllowPrivateAccess = "true")) | ||||||
|  | 	UNakatomiCMC* NakatomiCMC; | ||||||
|  | 	 | ||||||
| private: | private: | ||||||
| 	UPROPERTY(VisibleDefaultsOnly) | 	UPROPERTY(VisibleDefaultsOnly) | ||||||
| 	UHealthComponent* HealthComponent = nullptr; | 	UHealthComponent* HealthComponent = nullptr; | ||||||
| @ -47,9 +52,10 @@ private: | |||||||
| 	UPROPERTY(EditDefaultsOnly) | 	UPROPERTY(EditDefaultsOnly) | ||||||
| 	int MaximumThrowableInventorySize = 4; | 	int MaximumThrowableInventorySize = 4; | ||||||
| 
 | 
 | ||||||
|  | 	 | ||||||
| public: | public: | ||||||
| 	// Sets default values for this character's properties
 | 	// Sets default values for this character's properties
 | ||||||
| 	ANakatomiCharacter(); | 	ANakatomiCharacter(const FObjectInitializer& ObjectInitializer); | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
| 	// Called when the game starts or when spawned
 | 	// Called when the game starts or when spawned
 | ||||||
| @ -98,6 +104,8 @@ public: | |||||||
| 
 | 
 | ||||||
| 	void PushThrowableToInventory(TSubclassOf<AThrowable> Throwable); | 	void PushThrowableToInventory(TSubclassOf<AThrowable> Throwable); | ||||||
| 
 | 
 | ||||||
|  | 	UNakatomiCMC* GetCharacterMovementComponent(); | ||||||
|  | 
 | ||||||
| protected: | protected: | ||||||
| 	virtual void CalculateHits(TArray<FHitResult>* hits); | 	virtual void CalculateHits(TArray<FHitResult>* hits); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -7,25 +7,26 @@ | |||||||
| #include <Components/CapsuleComponent.h> | #include <Components/CapsuleComponent.h> | ||||||
| #include <Kismet/GameplayStatics.h> | #include <Kismet/GameplayStatics.h> | ||||||
| 
 | 
 | ||||||
| #include "InputTriggers.h" | #include "EnemyCharacter.h" | ||||||
| #include "EnhancedInputComponent.h" | #include "EnhancedInputComponent.h" | ||||||
| #include "EnhancedInputSubsystems.h" | #include "EnhancedInputSubsystems.h" | ||||||
| #include "GameFramework/CharacterMovementComponent.h" |  | ||||||
| #include "InputMappingContext.h" | #include "InputMappingContext.h" | ||||||
| #include "EnemyCharacter.h" | #include "InputTriggers.h" | ||||||
|  | #include "InteractableComponent.h" | ||||||
|  | #include "NakatomiCMC.h" | ||||||
| #include "WeaponThrowable.h" | #include "WeaponThrowable.h" | ||||||
| 
 | #include "GameFramework/CharacterMovementComponent.h" | ||||||
| 
 | 
 | ||||||
| #define COLLISION_WEAPON	ECC_GameTraceChannel1 | #define COLLISION_WEAPON	ECC_GameTraceChannel1 | ||||||
| 
 | 
 | ||||||
| // Sets default values
 | // Sets default values
 | ||||||
| APlayerCharacter::APlayerCharacter() | APlayerCharacter::APlayerCharacter(const FObjectInitializer& ObjectInitializer) : ANakatomiCharacter(ObjectInitializer) | ||||||
| { | { | ||||||
| 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 | 	// Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 | ||||||
| 	PrimaryActorTick.bCanEverTick = true; | 	PrimaryActorTick.bCanEverTick = true; | ||||||
| 	PrimaryActorTick.SetTickFunctionEnable(true); | 	PrimaryActorTick.SetTickFunctionEnable(true); | ||||||
| 	PrimaryActorTick.bStartWithTickEnabled = true; | 	PrimaryActorTick.bStartWithTickEnabled = true; | ||||||
| 
 | 	 | ||||||
| 	//bUseControllerRotationPitch = true;
 | 	//bUseControllerRotationPitch = true;
 | ||||||
| 	//bUseControllerRotationYaw = true;
 | 	//bUseControllerRotationYaw = true;
 | ||||||
| 	//bUseControllerRotationRoll = false;
 | 	//bUseControllerRotationRoll = false;
 | ||||||
| @ -56,9 +57,8 @@ APlayerCharacter::APlayerCharacter() | |||||||
| 	CameraADSSpringArmComponent->SocketOffset = {0.0f, 50.0f, 75.0f}; | 	CameraADSSpringArmComponent->SocketOffset = {0.0f, 50.0f, 75.0f}; | ||||||
| 	 | 	 | ||||||
| 	// Setup the character movement
 | 	// Setup the character movement
 | ||||||
| 	UCharacterMovementComponent* CharacterMovementComponent = GetCharacterMovement(); | 	GetCharacterMovement()->AirControl = 1.0f; | ||||||
| 	CharacterMovementComponent->AirControl = 1.0f; | 	GetCharacterMovement()->bOrientRotationToMovement = true; | ||||||
| 	CharacterMovementComponent->bOrientRotationToMovement = true; |  | ||||||
| 
 | 
 | ||||||
| 	// Setup the character perception component
 | 	// Setup the character perception component
 | ||||||
| 	PerceptionSource = CreateDefaultSubobject<UAIPerceptionStimuliSourceComponent>(TEXT("Perception Source Stimuli")); | 	PerceptionSource = CreateDefaultSubobject<UAIPerceptionStimuliSourceComponent>(TEXT("Perception Source Stimuli")); | ||||||
| @ -188,6 +188,24 @@ void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputCom | |||||||
| 		{ | 		{ | ||||||
| 			Input->BindAction(PauseAction, ETriggerEvent::Completed, this, &APlayerCharacter::PauseCallback); | 			Input->BindAction(PauseAction, ETriggerEvent::Completed, this, &APlayerCharacter::PauseCallback); | ||||||
| 		} | 		} | ||||||
|  | 
 | ||||||
|  | 		if (CrouchAction) | ||||||
|  | 		{ | ||||||
|  | 			Input->BindAction(CrouchAction, ETriggerEvent::Started, this, &APlayerCharacter::BeginCrouchCallback); | ||||||
|  | 			Input->BindAction(CrouchAction, ETriggerEvent::Completed, this, &APlayerCharacter::EndCrouchCallback); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (SlideAction) | ||||||
|  | 		{ | ||||||
|  | 			Input->BindAction(SlideAction, ETriggerEvent::Started, this, &APlayerCharacter::BeginSlideCallback); | ||||||
|  | 			Input->BindAction(SlideAction, ETriggerEvent::Completed, this, &APlayerCharacter::EndSlideCallback); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (DashAction) | ||||||
|  | 		{ | ||||||
|  | 			Input->BindAction(DashAction, ETriggerEvent::Started, this, &APlayerCharacter::BeginDashCallback); | ||||||
|  | 			Input->BindAction(DashAction, ETriggerEvent::Completed, this, &APlayerCharacter::EndDashCallback); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -269,16 +287,18 @@ void APlayerCharacter::QuitCallback(const FInputActionInstance& Instance) | |||||||
| 
 | 
 | ||||||
| void APlayerCharacter::SetSprintingCallback(const FInputActionInstance& Instance) | void APlayerCharacter::SetSprintingCallback(const FInputActionInstance& Instance) | ||||||
| { | { | ||||||
| 	IsSpriting = true; | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
| 	 | 	{ | ||||||
| 	SetMovementSpeed(); | 		cmc->EnableSprint(); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void APlayerCharacter::SetWalkingCallback(const FInputActionInstance& Instance) | void APlayerCharacter::SetWalkingCallback(const FInputActionInstance& Instance) | ||||||
| { | { | ||||||
| 	IsSpriting = false; | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
| 	 | 	{ | ||||||
| 	SetMovementSpeed(); | 		cmc->DisableSprint(); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void APlayerCharacter::CalculateHits(TArray<FHitResult>* hits) | void APlayerCharacter::CalculateHits(TArray<FHitResult>* hits) | ||||||
| @ -448,22 +468,6 @@ void APlayerCharacter::OnDeath() | |||||||
| 	UGameplayStatics::OpenLevel(this, FName(map), false); | 	UGameplayStatics::OpenLevel(this, FName(map), false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void APlayerCharacter::SetMovementSpeed() |  | ||||||
| { |  | ||||||
| 	if (IsADS) |  | ||||||
| 	{ |  | ||||||
| 		GetCharacterMovement()->MaxWalkSpeed = DefaultMovementSpeed * ADSSpeedMultiplier; |  | ||||||
| 	} |  | ||||||
| 	else if (IsSpriting) |  | ||||||
| 	{ |  | ||||||
| 		GetCharacterMovement()->MaxWalkSpeed = DefaultMovementSpeed * SprintSpeedMultiplier; |  | ||||||
| 	} |  | ||||||
| 	else |  | ||||||
| 	{ |  | ||||||
| 		GetCharacterMovement()->MaxWalkSpeed = DefaultMovementSpeed; |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void APlayerCharacter::WeaponSwitchingCallback(const FInputActionInstance& Instance) | void APlayerCharacter::WeaponSwitchingCallback(const FInputActionInstance& Instance) | ||||||
| { | { | ||||||
| 	float value = Instance.GetValue().Get<float>(); | 	float value = Instance.GetValue().Get<float>(); | ||||||
| @ -482,7 +486,10 @@ void APlayerCharacter::BeginAimDownSightsCallback(const FInputActionInstance& In | |||||||
| { | { | ||||||
| 	IsADS = true; | 	IsADS = true; | ||||||
| 
 | 
 | ||||||
| 	SetMovementSpeed(); | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
|  | 	{ | ||||||
|  | 		cmc->EnableAds(); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	AimSensitivity = DefaultAimSensitivity * ADSAimSensitivityMultiplier; | 	AimSensitivity = DefaultAimSensitivity * ADSAimSensitivityMultiplier; | ||||||
| 
 | 
 | ||||||
| @ -505,7 +512,10 @@ void APlayerCharacter::EndAimDownSightsCallback(const FInputActionInstance& Inst | |||||||
| { | { | ||||||
| 	IsADS = false; | 	IsADS = false; | ||||||
| 
 | 
 | ||||||
| 	SetMovementSpeed(); | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
|  | 	{ | ||||||
|  | 		cmc->DisableAds(); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	AimSensitivity = DefaultAimSensitivity; | 	AimSensitivity = DefaultAimSensitivity; | ||||||
| 
 | 
 | ||||||
| @ -535,6 +545,54 @@ void APlayerCharacter::PauseCallback(const FInputActionInstance& Instance) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void APlayerCharacter::BeginCrouchCallback(const FInputActionInstance& Instance) | ||||||
|  | { | ||||||
|  | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
|  | 	{ | ||||||
|  | 		cmc->EnableCrouch(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void APlayerCharacter::EndCrouchCallback(const FInputActionInstance& Instance) | ||||||
|  | { | ||||||
|  | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
|  | 	{ | ||||||
|  | 		cmc->DisableCrouch(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void APlayerCharacter::BeginSlideCallback(const FInputActionInstance& Instance) | ||||||
|  | { | ||||||
|  | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
|  | 	{ | ||||||
|  | 		cmc->EnableSlide(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void APlayerCharacter::EndSlideCallback(const FInputActionInstance& Instance) | ||||||
|  | { | ||||||
|  | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
|  | 	{ | ||||||
|  | 		cmc->DisableSlide(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void APlayerCharacter::BeginDashCallback(const FInputActionInstance& Instance) | ||||||
|  | { | ||||||
|  | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
|  | 	{ | ||||||
|  | 		cmc->EnableDash(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void APlayerCharacter::EndDashCallback(const FInputActionInstance& Instance) | ||||||
|  | { | ||||||
|  | 	if (UNakatomiCMC* cmc = GetCharacterMovementComponent()) | ||||||
|  | 	{ | ||||||
|  | 		cmc->DisableDash(); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void APlayerCharacter::OnFire() | void APlayerCharacter::OnFire() | ||||||
| { | { | ||||||
| 	if (!IsFiring || CurrentWeapon->GetAmmoCount() == 0) | 	if (!IsFiring || CurrentWeapon->GetAmmoCount() == 0) | ||||||
| @ -683,4 +741,4 @@ AThrowable* APlayerCharacter::ThrowThrowable() | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return nullptr; | 	return nullptr; | ||||||
| } | } | ||||||
| @ -2,19 +2,15 @@ | |||||||
| 
 | 
 | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "Camera/CameraComponent.h" |  | ||||||
| #include "CoreMinimal.h" | #include "CoreMinimal.h" | ||||||
| #include "GameFramework/SpringArmComponent.h" |  | ||||||
| #include "InputActionValue.h" |  | ||||||
| #include "EnhancedInputComponent.h" | #include "EnhancedInputComponent.h" | ||||||
| #include "NakatomiCharacter.h" | #include "NakatomiCharacter.h" | ||||||
| #include "Weapon.h" |  | ||||||
| #include "Engine/EngineTypes.h" |  | ||||||
| #include "Engine/DamageEvents.h" |  | ||||||
| #include "Blueprint/UserWidget.h" |  | ||||||
| #include "Perception/AIPerceptionStimuliSourceComponent.h" |  | ||||||
| #include "InteractableComponent.h" |  | ||||||
| #include "Throwable.h" | #include "Throwable.h" | ||||||
|  | #include "Blueprint/UserWidget.h" | ||||||
|  | #include "Camera/CameraComponent.h" | ||||||
|  | #include "Engine/EngineTypes.h" | ||||||
|  | #include "GameFramework/SpringArmComponent.h" | ||||||
|  | #include "Perception/AIPerceptionStimuliSourceComponent.h" | ||||||
| #include "PlayerCharacter.generated.h" | #include "PlayerCharacter.generated.h" | ||||||
| 
 | 
 | ||||||
| class UInputAction; | class UInputAction; | ||||||
| @ -63,6 +59,15 @@ public: | |||||||
| 
 | 
 | ||||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
| 	UInputAction* AimDownSightsAction; | 	UInputAction* AimDownSightsAction; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
|  | 	UInputAction* CrouchAction; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
|  | 	UInputAction* SlideAction; | ||||||
|  | 
 | ||||||
|  | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
|  | 	UInputAction* DashAction; | ||||||
| 	 | 	 | ||||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
| 	TSoftObjectPtr<UInputMappingContext> InputMappingContext; | 	TSoftObjectPtr<UInputMappingContext> InputMappingContext; | ||||||
| @ -82,9 +87,6 @@ protected: | |||||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
| 	float SprintSpeedMultiplier = 2.0f; | 	float SprintSpeedMultiplier = 2.0f; | ||||||
| 
 | 
 | ||||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) |  | ||||||
| 	float ADSSpeedMultiplier = 0.5f; |  | ||||||
| 
 |  | ||||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
| 	float ADSAimSensitivityMultiplier = 0.5f; | 	float ADSAimSensitivityMultiplier = 0.5f; | ||||||
| 
 | 
 | ||||||
| @ -94,7 +96,7 @@ protected: | |||||||
| 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | 	UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) | ||||||
| 	float DefaultAimSensitivity = 45.0f; | 	float DefaultAimSensitivity = 45.0f; | ||||||
| 
 | 
 | ||||||
| private: | private:	 | ||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true")) | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true")) | ||||||
| 	USpringArmComponent* CameraSpringArmComponent = nullptr; | 	USpringArmComponent* CameraSpringArmComponent = nullptr; | ||||||
| 
 | 
 | ||||||
| @ -119,7 +121,7 @@ private: | |||||||
| 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true")) | 	UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (AllowPrivateAccess = "true")) | ||||||
| 	UAIPerceptionStimuliSourceComponent* PerceptionSource; | 	UAIPerceptionStimuliSourceComponent* PerceptionSource; | ||||||
| 
 | 
 | ||||||
| 	bool IsSpriting = false; | 	bool IsSprinting = false; | ||||||
| 
 | 
 | ||||||
| 	bool IsADS = false; | 	bool IsADS = false; | ||||||
| 
 | 
 | ||||||
| @ -132,7 +134,7 @@ private: | |||||||
| 	 | 	 | ||||||
| public: | public: | ||||||
| 	// Sets default values for this character's properties
 | 	// Sets default values for this character's properties
 | ||||||
| 	APlayerCharacter(); | 	APlayerCharacter(const FObjectInitializer& ObjectInitializer); | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
| 	// Called when the game starts or when spawned
 | 	// Called when the game starts or when spawned
 | ||||||
| @ -170,6 +172,18 @@ public: | |||||||
| 	void EndAimDownSightsCallback(const FInputActionInstance& Instance); | 	void EndAimDownSightsCallback(const FInputActionInstance& Instance); | ||||||
| 
 | 
 | ||||||
| 	void PauseCallback(const FInputActionInstance& Instance); | 	void PauseCallback(const FInputActionInstance& Instance); | ||||||
|  | 
 | ||||||
|  | 	void BeginCrouchCallback(const FInputActionInstance& Instance); | ||||||
|  | 
 | ||||||
|  | 	void EndCrouchCallback(const FInputActionInstance& Instance); | ||||||
|  | 
 | ||||||
|  | 	void BeginSlideCallback(const FInputActionInstance& Instance); | ||||||
|  | 
 | ||||||
|  | 	void EndSlideCallback(const FInputActionInstance& Instance); | ||||||
|  | 
 | ||||||
|  | 	void BeginDashCallback(const FInputActionInstance& Instance); | ||||||
|  | 
 | ||||||
|  | 	void EndDashCallback(const FInputActionInstance& Instance); | ||||||
| 	 | 	 | ||||||
| 	virtual void OnFire() override; | 	virtual void OnFire() override; | ||||||
| 
 | 
 | ||||||
| @ -206,6 +220,5 @@ protected: | |||||||
| 	virtual void OnDamaged() override; | 	virtual void OnDamaged() override; | ||||||
| 	 | 	 | ||||||
| 	virtual void OnDeath() override; | 	virtual void OnDeath() override; | ||||||
| 
 | 	 | ||||||
| 	void SetMovementSpeed(); |  | ||||||
| }; | }; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user