// Fill out your copyright notice in the Description page of Project Settings. #include "Mouse.h" #include "LinearVisualObject.h" #include "ParabolaVisualObject.h" #include "ProjectT/ProjectT.h" #include "ProjectT/System/Core/Common/AssetUtilsLibrary.h" #include "ProjectT/System/Core/Common/GlobalUtilsLibrary.h" #include "ProjectT/System/Core/Interfaces/MouseInteraction.h" UMouse::UMouse() : bTickEnabled(false), bMouseTracing(false), Range(0), CurrentResultType(), LinearTraceQuery(), MouseTraceQuery(), StandardActor(nullptr), CurrentPlayerController(nullptr) { OnConstruct(); } void UMouse::Tick(float DeltaTime) { if(bMouseTracing) { FHitResult LocHitResult; switch(CurrentResultType) { case EMouseResultType::Linear : { LocHitResult = GetLinearCalibrateHitResult(); IMouseInteraction::Execute_RefreshCursorHitResult(LinearVisualObject, LocHitResult); break; } case EMouseResultType::Parabola : { LocHitResult = GetParabolaCalibrateHitResult(); IMouseInteraction::Execute_RefreshCursorHitResult(ParabolaVisualObject, LocHitResult); break; } default: NMT_LOG("ResultType None") break; } for(AActor* LocAffectActor : AffectActors) { IMouseInteraction::Execute_RefreshCursorHitResult(LocAffectActor, LocHitResult); } } } TStatId UMouse::GetStatId() const { return TStatId(); } bool UMouse::IsTickable() const { return bTickEnabled; } void UMouse::SetTickEnabled(const bool InbEnabled) { bTickEnabled = InbEnabled; } void UMouse::InitializeMouse() { if(UWorld* LocWorld = UGlobalUtilsLibrary::GetValidWorld(this)) { if(APlayerController* LocGetController = UGameplayStatics::GetPlayerController(LocWorld,0)) { CurrentPlayerController = LocGetController; LinearTraceQuery = UEngineTypes::ConvertToTraceType(ECC_GameTraceChannel3); MouseTraceQuery = UEngineTypes::ConvertToTraceType(ECC_GameTraceChannel1); LinearVisualObject = LocWorld->SpawnActor(LinearVisualObjectClass); LinearVisualObject->InitializeLinearObject(); ParabolaVisualObject = LocWorld->SpawnActor(ParabolaVisualObjectClass); ParabolaVisualObject->InitializeParabolaObject(); } } } void UMouse::OnConstruct() { //TODO : Edit Path Relative FString LocTempPath = "/Script/Engine.Blueprint'/Game/System/Core/Mouse/Blueprints/BP_LinearVisualObject.BP_LinearVisualObject'"; FString ClassPath = UAssetUtilsLibrary::AssetReferencePathToClassPath(LocTempPath); UClass* LoadedClass = StaticLoadClass(UObject::StaticClass(), nullptr, *ClassPath); NMT_CHECKF(LoadedClass); LinearVisualObjectClass = LoadedClass; LoadedClass = nullptr; LocTempPath = "/Script/Engine.Blueprint'/Game/System/Core/Mouse/Blueprints/BP_ParabolaVisualObject.BP_ParabolaVisualObject'"; ClassPath = UAssetUtilsLibrary::AssetReferencePathToClassPath(LocTempPath); LoadedClass = StaticLoadClass(UObject::StaticClass(), nullptr, *ClassPath); NMT_CHECKF(LoadedClass); ParabolaVisualObjectClass = LoadedClass; } void UMouse::OnEndPlay() { SetTickEnabled(false); } void UMouse::AimTracing(bool InbStart, AActor* InStandardActor, const TArray& InAffectActors, const float InRange, const float InAffectRange, const EMouseResultType InResultType, bool InbPathVisible) { if(InbStart) { StandardActor = InStandardActor; AffectActors = InAffectActors; Range = InRange; CurrentResultType = InResultType; bMouseTracing = true; SetTickEnabled(true); switch(InResultType) { case EMouseResultType::Parabola: { ParabolaVisualObject->SetAimVisibility(true, InbPathVisible, InAffectRange); break; } case EMouseResultType::Linear: { LinearVisualObject->SetAimVisibility(true); break; } default: NMT_LOG("MouseHitResult Type None"); } } else { ParabolaVisualObject->SetAimVisibility(false); LinearVisualObject->SetAimVisibility(false); SetTickEnabled(false); bMouseTracing = false; StandardActor = nullptr; AffectActors.Empty(); Range = 0.f; CurrentResultType = EMouseResultType::None; } } FHitResult UMouse::GetCursorHitResult(AActor* InStandardActor, const TArray& InAffectActors, const float InRange, const EMouseResultType InResultType) { StandardActor = InStandardActor; AffectActors = InAffectActors; Range = InRange; FHitResult LocHitResult; switch(InResultType) { case EMouseResultType::Linear : { LocHitResult = GetLinearCalibrateHitResult(); break; } case EMouseResultType::Parabola : { LocHitResult = GetParabolaCalibrateHitResult(); break; } default: NMT_LOG("ResultType None") break; } return LocHitResult; } FHitResult UMouse::GetParabolaCalibrateHitResult() { FHitResult LocCursorHitResult; CurrentPlayerController->GetHitResultUnderCursorByChannel(MouseTraceQuery, true, MouseCursorHitResult); if(MouseCursorHitResult.bBlockingHit) { float LocCursorDistance = FVector::Dist2D(StandardActor->GetActorLocation(), MouseCursorHitResult.Location); float LocTraceLength = LocCursorDistance > Range ? LocTraceLength = Range : LocTraceLength = LocCursorDistance; FVector LocHitForward(MouseCursorHitResult.Location.X, MouseCursorHitResult.Location.Y, StandardActor->GetActorLocation().Z); LocHitForward = LocHitForward - StandardActor->GetActorLocation(); LocHitForward.Normalize(); TArray LocIgnoreActors; LocIgnoreActors.Add(StandardActor); FHitResult LocTopDownHitResult; UKismetSystemLibrary::LineTraceSingle(this, FVector(0.f, 0.f, 300.f) + StandardActor->GetActorLocation() + LocHitForward * LocTraceLength, FVector(0.f, 0.f, -100.f) + StandardActor->GetActorLocation() + LocHitForward * LocTraceLength, LinearTraceQuery, false, LocIgnoreActors, EDrawDebugTrace::None, LocTopDownHitResult, true); if(LocTopDownHitResult.bBlockingHit) { FHitResult LocWallHitResult; TArray> LocWallObjectType; LocWallObjectType.Add(UEngineTypes::ConvertToObjectType(ECC_GameTraceChannel4)); UKismetSystemLibrary::LineTraceSingleForObjects(this, StandardActor->GetActorLocation(), StandardActor->GetActorLocation() + LocHitForward * LocTraceLength, LocWallObjectType, false, LocIgnoreActors, EDrawDebugTrace::None, LocWallHitResult, true); if(LocWallHitResult.bBlockingHit) { LocTopDownHitResult.Component = LocWallHitResult.Component; LocTopDownHitResult.Location = LocWallHitResult.Location; LocTopDownHitResult.Location.Z = MouseCursorHitResult.Location.Z; LocTraceLength = LocWallHitResult.Distance; } } TArray LocPropHitResults; TArray> LocPropObjectType; LocPropObjectType.Add(UEngineTypes::ConvertToObjectType(ECC_GameTraceChannel6)); UKismetSystemLibrary::LineTraceMultiForObjects(this, StandardActor->GetActorLocation(), StandardActor->GetActorLocation() + LocHitForward * LocTraceLength, LocPropObjectType, false, LocIgnoreActors, EDrawDebugTrace::None, LocPropHitResults, true); if(LocPropHitResults.Num() > 0) { if(LocTopDownHitResult.Component->GetCollisionProfileName() == TEXT("Ground")||LocTopDownHitResult.Component->GetCollisionProfileName() == TEXT("Wall")) { LocCursorHitResult = LocTopDownHitResult; } else { LocPropHitResults.Last().Location.Z = MouseCursorHitResult.Location.Z; LocCursorHitResult = LocPropHitResults.Last(); } } else { LocTopDownHitResult.Location.Z = MouseCursorHitResult.Location.Z; LocCursorHitResult = LocTopDownHitResult; } LastUpdatedHitResult = LocCursorHitResult; } else { LocCursorHitResult = LastUpdatedHitResult; } return LocCursorHitResult; } FHitResult UMouse::GetLinearCalibrateHitResult() { FHitResult LocCursorHitResult; CurrentPlayerController->GetHitResultUnderCursorByChannel(MouseTraceQuery, true, MouseCursorHitResult); if(MouseCursorHitResult.bBlockingHit) { FVector LocHitForward(MouseCursorHitResult.Location.X, MouseCursorHitResult.Location.Y, StandardActor->GetActorLocation().Z); LocHitForward = LocHitForward - StandardActor->GetActorLocation(); LocHitForward.Normalize(); TArray LocIgnoreActors; LocIgnoreActors.Add(StandardActor); UKismetSystemLibrary::LineTraceSingle(this, StandardActor->GetActorLocation(), StandardActor->GetActorLocation() + LocHitForward * Range, LinearTraceQuery, false, LocIgnoreActors, EDrawDebugTrace::None, LocCursorHitResult, true); if(!LocCursorHitResult.bBlockingHit) { LocCursorHitResult.Location = MouseCursorHitResult.Location; LocCursorHitResult.Distance = Range; } LastUpdatedHitResult = LocCursorHitResult; } else { LocCursorHitResult = LastUpdatedHitResult; } return LocCursorHitResult; }