diff --git a/Content/Tangibles/TangibleCharacter.uasset b/Content/Tangibles/TangibleCharacter.uasset index 7fcdcadc..1174747c 100644 --- a/Content/Tangibles/TangibleCharacter.uasset +++ b/Content/Tangibles/TangibleCharacter.uasset @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9b842fe1f573e136e995261869397027b47f39730d6bc705d7904977769d43cd -size 459158 +oid sha256:f0d9047abca327dcc1285cf8223a69c40c563be4f9c917516b5352e34fb8d63d +size 475102 diff --git a/Source/Integration/IntegrationGameModeBase.cpp b/Source/Integration/IntegrationGameModeBase.cpp index bbc211e2..09a153ee 100644 --- a/Source/Integration/IntegrationGameModeBase.cpp +++ b/Source/Integration/IntegrationGameModeBase.cpp @@ -6,6 +6,7 @@ #include "DebugPrint.h" #include "Tangible.h" #include "TangibleManager.h" +#include "LookAtDetector.h" #include "CommonTypes.h" #include "AnimQueue.h" #include @@ -83,9 +84,8 @@ void AIntegrationGameModeBase::ResetToInitialState() // Clear the PlayerID PlayerId = 0; - // Clear the camera ray state. - CameraRayTarget = nullptr; - CameraRayChanged = false; + // Clear the actor selector; + LookAtDetector = nullptr; // Reset the clocks. EngineSeconds = 0.0; @@ -152,54 +152,6 @@ void AIntegrationGameModeBase::UpdatePossessedTangible() { } } -void AIntegrationGameModeBase::CastCameraRay() { - // The range we're using is currently hardwired. - double range = 1000.0; - - // If there's no possessed tangible, then we don't even try casting the ray. - UlxTangible *possessed = TangibleManager->GetPossessedTangible(); - if (possessed == nullptr) { - CameraRayChanged = (CameraRayTarget != nullptr); - CameraRayTarget = nullptr; - return; - } - - // Get the ray in question. - // APlayerCameraManager *camManager = GetWorld()->GetFirstPlayerController()->PlayerCameraManager; - // FVector TraceStart = camManager->GetCameraLocation(); - // FVector TraceEnd = camManager->GetCameraRotation().Vector() * range; - FVector TraceStart, TraceVector; - APlayerController *ctrl = GetWorld()->GetFirstPlayerController(); - ctrl->DeprojectScreenPositionToWorld(0.5, 0.5, TraceStart, TraceVector); - FVector TraceEnd = TraceStart + (TraceVector * range); - - // FHitResult will hold all data returned by our line collision query - FHitResult Hit; - - // You can use FCollisionQueryParams to further configure the query - // Here we add ourselves to the ignored list so we won't block the trace - FCollisionQueryParams QueryParams; - QueryParams.AddIgnoredActor(possessed->GetActor()); - - // To run the query, you need a pointer to the current level, which you can get from an Actor with GetWorld() - // UWorld()->LineTraceSingleByChannel runs a line trace and returns the first actor hit over the provided collision channel. - GetWorld()->LineTraceSingleByChannel(Hit, TraceStart, TraceEnd, ECC_Visibility, QueryParams); - - // You can use DrawDebug helpers and the log to help visualize and debug your trace queries. - // DrawDebugLine(GetWorld(), TraceStart, TraceEnd, Hit.bBlockingHit ? FColor::Blue : FColor::Red, false, 5.0f, 0, 10.0f); - // UE_LOG(LogTemp, Log, TEXT("Tracing line: %s to %s"), *TraceStart.ToCompactString(), *TraceEnd.ToCompactString()); - - // If the trace hit something, bBlockingHit will be true, - // and its fields will be filled with detailed info about what was hit - if (Hit.bBlockingHit && IsValid(Hit.GetActor())) { - CameraRayChanged = (CameraRayTarget != Hit.GetActor()); - CameraRayTarget = Hit.GetActor(); - } else { - CameraRayChanged = (CameraRayTarget != nullptr); - CameraRayTarget = nullptr; - } -} - void AIntegrationGameModeBase::LuaCallEnd(InvocationKind kind, int64 place_id) { std::string_view datapk = LuaCallBuffer.view(); FlxLockedWrapper w(LockableWrapper); @@ -273,7 +225,7 @@ void AIntegrationGameModeBase::OnWorldPreActorTick(UWorld* InWorld, ELevelTick I UpdateConsoleOutput(); UpdateTangibles(); UpdatePossessedTangible(); - //CastCameraRay(); + if (LookAtDetector != nullptr) LookAtDetector->Update(); } } @@ -378,6 +330,11 @@ AIntegrationGameModeBase *AIntegrationGameModeBase::GetFromContext(UObject *cont return GetFromWorld(context->GetWorld()); } +void AIntegrationGameModeBase::SetLookAtDetector(UlxLookAtActorBase *selector) { + LookAtDetector = selector; +} + + // /** Gets the game mode that owns this component, this will always return null on the client */ // template // T* GetGameMode() const diff --git a/Source/Integration/IntegrationGameModeBase.h b/Source/Integration/IntegrationGameModeBase.h index 64ab7e23..8b0820d6 100644 --- a/Source/Integration/IntegrationGameModeBase.h +++ b/Source/Integration/IntegrationGameModeBase.h @@ -13,6 +13,8 @@ #include "IntegrationGameModeBase.generated.h" +class LookAtDetector; + /** * */ @@ -43,6 +45,9 @@ public: UFUNCTION(BlueprintCallable, Category = "Luprex") int64 GetPlayerId(); + UFUNCTION(BlueprintCallable, Category = "Luprex") + void SetLookAtDetector(UlxLookAtActorBase *det); + // Assemble a lua call. To call into lua: // // * Use LuaCallBegin @@ -76,10 +81,6 @@ public: // Maybe call 'BecomePossessed' on the player tangible. void UpdatePossessedTangible(); - // Cast a ray forward from the camera. Update the instance - // variables 'CameraRayTarget' and 'CameraRayChanged'. - void CastCameraRay(); - // Pre-tick and post-tick functions. void OnWorldPreActorTick(UWorld* InWorld, ELevelTick InLevelTick, float InDeltaSeconds); void OnWorldPostActorTick(UWorld* InWorld, ELevelTick InLevelTick, float InDeltaSeconds); @@ -96,6 +97,9 @@ public: UPROPERTY() UlxTangibleManager *TangibleManager; + UPROPERTY() + UlxLookAtActorBase *LookAtDetector; + // This stores the entire text currently visible in the console. FlxConsoleOutput ConsoleOutput; @@ -119,10 +123,6 @@ public: // Current Player ID int64 PlayerId; - // Object in front of camera. - AActor *CameraRayTarget; - bool CameraRayChanged; - // Amount of elapsed time since BeginPlay. float EngineSeconds; diff --git a/Source/Integration/LookAtDetector.cpp b/Source/Integration/LookAtDetector.cpp new file mode 100644 index 00000000..bea7cc33 --- /dev/null +++ b/Source/Integration/LookAtDetector.cpp @@ -0,0 +1,81 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "LookAtDetector.h" +#include "IntegrationGameModeBase.h" + + +UlxLookAtActorBase::UlxLookAtActorBase() { + GameMode = nullptr; + Player = nullptr; + PlayerController = nullptr; + CameraManager = nullptr; + PreviousSelectedActor = nullptr; + CurrentSelectedActor = nullptr; +} + +void UlxLookAtActorBase::Update() { + GameMode = nullptr; + Player = nullptr; + PlayerController = nullptr; + CameraManager = nullptr; + PreviousSelectedActor = CurrentSelectedActor; + CurrentSelectedActor = nullptr; + + // Make sure the world is fully configured before we attempt to cast rays. + AIntegrationGameModeBase *gm = AIntegrationGameModeBase::GetFromWorld(GetWorld()); + if (gm == nullptr) return; + UlxTangible *possessed = gm->TangibleManager->GetPossessedTangible(); + if (possessed == nullptr) return; + APlayerController *pc = GetWorld()->GetFirstPlayerController(); + if (pc == nullptr) return; + APawn *pawn = pc->GetPawn(); + if (pawn == nullptr) return; + APlayerCameraManager *cam = pc->PlayerCameraManager; + if (cam == nullptr) return; + + GameMode = gm; + Player = pawn; + PlayerController = pc; + CameraManager = cam; + + Recalculate(); +} + +// void AIntegrationGameModeBase::CastCameraRay() { +// // The range we're using is currently hardwired. +// double range = 1000.0; + +// // Get the ray in question. +// APlayerCameraManager *camManager = GetWorld()->GetFirstPlayerController()->PlayerCameraManager; +// FVector TraceStart = camManager->GetCameraLocation(); +// FVector TraceVector = camManager->GetCameraRotation().Vector(); +// FVector TraceEnd = TraceStart + (TraceVector * range); + +// // FHitResult will hold all data returned by our line collision query +// FHitResult Hit; + +// // You can use FCollisionQueryParams to further configure the query +// // Here we add ourselves to the ignored list so we won't block the trace +// FCollisionQueryParams QueryParams; +// QueryParams.AddIgnoredActor(possessed->GetActor()); + +// // To run the query, you need a pointer to the current level, which you can get from an Actor with GetWorld() +// // UWorld()->LineTraceSingleByChannel runs a line trace and returns the first actor hit over the provided collision channel. +// GetWorld()->LineTraceSingleByChannel(Hit, TraceStart, TraceEnd, ECC_Visibility, QueryParams); + +// // You can use DrawDebug helpers and the log to help visualize and debug your trace queries. +// // DrawDebugLine(GetWorld(), TraceStart, TraceEnd, Hit.bBlockingHit ? FColor::Blue : FColor::Red, false, 2.0f, 0, 5.0f); +// // UE_LOG(LogTemp, Log, TEXT("Tracing line: %s to %s"), *TraceStart.ToCompactString(), *TraceVector.ToCompactString()); + +// // If the trace hit something, bBlockingHit will be true, +// // and its fields will be filled with detailed info about what was hit +// if (Hit.bBlockingHit && IsValid(Hit.GetActor())) { +// CameraRayChanged = (CameraRayTarget != Hit.GetActor()); +// CameraRayTarget = Hit.GetActor(); +// } else { +// CameraRayChanged = (CameraRayTarget != nullptr); +// CameraRayTarget = nullptr; +// } +// } + diff --git a/Source/Integration/LookAtDetector.h b/Source/Integration/LookAtDetector.h new file mode 100644 index 00000000..3bf99837 --- /dev/null +++ b/Source/Integration/LookAtDetector.h @@ -0,0 +1,67 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Runtime/Engine/Classes/GameFramework/PlayerController.h" +#include "LookAtDetector.generated.h" + +class AIntegrationGameModeBase; + +/** + * + */ +UCLASS() +class INTEGRATION_API UlxLookAtActorBase : public UObject +{ + GENERATED_BODY() + +public: + UlxLookAtActorBase(); + ~UlxLookAtActorBase() {}; + + // Used by the IntegrationGameModeBase to trigger recalculation. + UFUNCTION(BlueprintCallable, Category = "Luprex") + void Update(); + + // Used in blueprints to set the result object. + UFUNCTION(BlueprintCallable, Category = "Luprex") + void SetSelectedActor(AActor *actor) { CurrentSelectedActor = actor; } + + // Used to find out if the selection recently changed. + UFUNCTION(BlueprintCallable, Category = "Luprex") + bool SelectionChanged() { return (PreviousSelectedActor != CurrentSelectedActor); } + + // Defined in blueprints to do the actual recalculation. + UFUNCTION(BlueprintImplementableEvent, Category = "Luprex") + void Recalculate(); + +public: + + +public: + // A pointer to an IntegrationGameModeBase. + UPROPERTY(BlueprintReadOnly) + AIntegrationGameModeBase *GameMode; + + // A pointer to an actor, the current character. + UPROPERTY(BlueprintReadOnly) + AActor *Player; + + // A pointer to the player controller. + UPROPERTY(BlueprintReadOnly) + APlayerController *PlayerController; + + // A pointer to the camera manager. + UPROPERTY(BlueprintReadOnly) + APlayerCameraManager *CameraManager; + + // The selected actor on the previous frame. + UPROPERTY(BlueprintReadOnly) + AActor *PreviousSelectedActor; + + // The selected actor on the current frame. + UPROPERTY(BlueprintReadOnly) + AActor *CurrentSelectedActor; + +};