Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
RWTH VR Toolkit
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
LuFG VR VIS
VR-Group
Unreal-Development
Plugins
RWTH VR Toolkit
Commits
aeb67856
Commit
aeb67856
authored
Mar 22, 2024
by
Timon Römer
Browse files
Options
Downloads
Patches
Plain Diff
Comments and explains IntenSelect Component source code
parent
3ea5666d
Branches
Branches containing commit
No related tags found
1 merge request
!87
Merge IntenSelect into dev5.3
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
Source/RWTHVRToolkit/Private/Pawn/IntenSelectComponent.cpp
+215
-87
215 additions, 87 deletions
Source/RWTHVRToolkit/Private/Pawn/IntenSelectComponent.cpp
Source/RWTHVRToolkit/Public/Pawn/IntenSelectComponent.h
+149
-3
149 additions, 3 deletions
Source/RWTHVRToolkit/Public/Pawn/IntenSelectComponent.h
with
364 additions
and
90 deletions
Source/RWTHVRToolkit/Private/Pawn/IntenSelectComponent.cpp
+
215
−
87
View file @
aeb67856
...
@@ -77,47 +77,57 @@ void UIntenSelectComponent::BeginPlay()
...
@@ -77,47 +77,57 @@ void UIntenSelectComponent::BeginPlay()
InitInputBindings
();
InitInputBindings
();
InitMaterialParamCollection
();
InitMaterialParamCollection
();
// Calculate sphere cast radius
SphereCastRadius
=
CalculateSphereCastRadius
();
SphereCastRadius
=
CalculateSphereCastRadius
();
// Set interaction distance to maximum selection distance
InteractionDistance
=
MaxSelectionDistance
;
InteractionDistance
=
MaxSelectionDistance
;
// Set the component active based on the SetActiveOnStart flag
SetActive
(
SetActiveOnStart
,
false
);
SetActive
(
SetActiveOnStart
,
false
);
}
}
void
UIntenSelectComponent
::
InitInputBindings
()
void
UIntenSelectComponent
::
InitInputBindings
()
{
{
// Get the player controller
const
APlayerController
*
PC
=
UGameplayStatics
::
GetPlayerController
(
GetWorld
(),
0
);
const
APlayerController
*
PC
=
UGameplayStatics
::
GetPlayerController
(
GetWorld
(),
0
);
// Get the local player subsystem for enhanced input
UEnhancedInputLocalPlayerSubsystem
*
Subsystem
=
UEnhancedInputLocalPlayerSubsystem
*
Subsystem
=
ULocalPlayer
::
GetSubsystem
<
UEnhancedInputLocalPlayerSubsystem
>
(
PC
->
GetLocalPlayer
());
ULocalPlayer
::
GetSubsystem
<
UEnhancedInputLocalPlayerSubsystem
>
(
PC
->
GetLocalPlayer
());
// Get the player input component
UInputComponent
*
PlayerInputComponent
=
PC
->
InputComponent
;
UInputComponent
*
PlayerInputComponent
=
PC
->
InputComponent
;
UEnhancedInputComponent
*
PEI
=
Cast
<
UEnhancedInputComponent
>
(
PlayerInputComponent
);
UEnhancedInputComponent
*
PEI
=
Cast
<
UEnhancedInputComponent
>
(
PlayerInputComponent
);
// Check if the enhanced input component is valid
if
(
!
PEI
)
if
(
!
PEI
)
{
{
// Display an error message and quit the game if the enhanced input component is not found
const
FString
Message
=
"Could not get PlayerInputComponent for IntenSelect Input Assignment!"
;
const
FString
Message
=
"Could not get PlayerInputComponent for IntenSelect Input Assignment!"
;
#if WITH_EDITOR
#if WITH_EDITOR
const
FText
Title
=
FText
::
FromString
(
FString
(
"ERROR"
));
const
FText
Title
=
FText
::
FromString
(
FString
(
"ERROR"
));
FMessageDialog
::
Open
(
EAppMsgType
::
Ok
,
FText
::
FromString
(
Message
),
Title
);
FMessageDialog
::
Open
(
EAppMsgType
::
Ok
,
FText
::
FromString
(
Message
),
Title
);
#endif
#endif
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"%s"
),
*
Message
)
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"%s"
),
*
Message
)
UKismetSystemLibrary
::
QuitGame
(
this
,
nullptr
,
EQuitPreference
::
Quit
,
false
);
UKismetSystemLibrary
::
QuitGame
(
this
,
nullptr
,
EQuitPreference
::
Quit
,
false
);
return
;
return
;
}
}
// Bind the actions
// Bind the actions
for input events
PEI
->
BindAction
(
InputClick
,
ETriggerEvent
::
Started
,
this
,
&
UIntenSelectComponent
::
OnFireDown
);
PEI
->
BindAction
(
InputClick
,
ETriggerEvent
::
Started
,
this
,
&
UIntenSelectComponent
::
OnFireDown
);
PEI
->
BindAction
(
InputClick
,
ETriggerEvent
::
Completed
,
this
,
&
UIntenSelectComponent
::
OnFireUp
);
PEI
->
BindAction
(
InputClick
,
ETriggerEvent
::
Completed
,
this
,
&
UIntenSelectComponent
::
OnFireUp
);
}
}
void
UIntenSelectComponent
::
InitSplineComponent
()
void
UIntenSelectComponent
::
InitSplineComponent
()
{
{
// Create a new spline component
SplineComponent
=
NewObject
<
USplineComponent
>
(
this
,
TEXT
(
"SplineComponent"
));
SplineComponent
=
NewObject
<
USplineComponent
>
(
this
,
TEXT
(
"SplineComponent"
));
// Check if the spline component was successfully created
if
(
SplineComponent
)
if
(
SplineComponent
)
{
{
// Setup attachment and mobility of the spline component
SplineComponent
->
SetupAttachment
(
this
);
SplineComponent
->
SetupAttachment
(
this
);
SplineComponent
->
SetMobility
(
EComponentMobility
::
Movable
);
SplineComponent
->
SetMobility
(
EComponentMobility
::
Movable
);
SplineComponent
->
RegisterComponent
();
SplineComponent
->
RegisterComponent
();
...
@@ -125,27 +135,32 @@ void UIntenSelectComponent::InitSplineComponent()
...
@@ -125,27 +135,32 @@ void UIntenSelectComponent::InitSplineComponent()
}
}
else
else
{
{
// Display an error message if the spline component creation fails
const
FString
Message
=
"Error while spawning SplineComponent!"
;
const
FString
Message
=
"Error while spawning SplineComponent!"
;
#if WITH_EDITOR
#if WITH_EDITOR
const
FText
Title
=
FText
::
FromString
(
FString
(
"ERROR"
));
const
FText
Title
=
FText
::
FromString
(
FString
(
"ERROR"
));
FMessageDialog
::
Open
(
EAppMsgType
::
Ok
,
FText
::
FromString
(
Message
),
Title
);
FMessageDialog
::
Open
(
EAppMsgType
::
Ok
,
FText
::
FromString
(
Message
),
Title
);
#endif
#endif
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"%s"
),
*
Message
)
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"%s"
),
*
Message
)
}
}
}
}
void
UIntenSelectComponent
::
InitSplineMeshComponent
()
void
UIntenSelectComponent
::
InitSplineMeshComponent
()
{
{
// Create a new spline mesh component
SplineMeshComponent
=
SplineMeshComponent
=
NewObject
<
USplineMeshComponent
>
(
this
,
USplineMeshComponent
::
StaticClass
(),
TEXT
(
"SplineMeshComponent"
));
NewObject
<
USplineMeshComponent
>
(
this
,
USplineMeshComponent
::
StaticClass
(),
TEXT
(
"SplineMeshComponent"
));
// Check if the spline mesh component was successfully created
if
(
SplineMeshComponent
)
if
(
SplineMeshComponent
)
{
{
// Setup attachment and mobility of the spline mesh component
SplineMeshComponent
->
SetupAttachment
(
this
);
SplineMeshComponent
->
SetupAttachment
(
this
);
SplineMeshComponent
->
SetMobility
(
EComponentMobility
::
Movable
);
SplineMeshComponent
->
SetMobility
(
EComponentMobility
::
Movable
);
SplineMeshComponent
->
RegisterComponent
();
SplineMeshComponent
->
RegisterComponent
();
SplineMeshComponent
->
CreationMethod
=
EComponentCreationMethod
::
Instance
;
SplineMeshComponent
->
CreationMethod
=
EComponentCreationMethod
::
Instance
;
// Set the static mesh if available
if
(
SplineMesh
)
if
(
SplineMesh
)
{
{
SplineMeshComponent
->
SetStaticMesh
(
SplineMesh
);
SplineMeshComponent
->
SetStaticMesh
(
SplineMesh
);
...
@@ -155,6 +170,7 @@ void UIntenSelectComponent::InitSplineMeshComponent()
...
@@ -155,6 +170,7 @@ void UIntenSelectComponent::InitSplineMeshComponent()
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"SplineMesh not set!"
));
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"SplineMesh not set!"
));
}
}
// Set the material if available
if
(
SplineMaterial
)
if
(
SplineMaterial
)
{
{
SplineMeshComponent
->
SetMaterial
(
0
,
SplineMaterial
);
SplineMeshComponent
->
SetMaterial
(
0
,
SplineMaterial
);
...
@@ -164,35 +180,43 @@ void UIntenSelectComponent::InitSplineMeshComponent()
...
@@ -164,35 +180,43 @@ void UIntenSelectComponent::InitSplineMeshComponent()
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"SplineMesh material not set! Using default material instead."
));
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"SplineMesh material not set! Using default material instead."
));
}
}
// Set the forward axis and shadow casting properties
SplineMeshComponent
->
SetForwardAxis
(
ESplineMeshAxis
::
Z
);
SplineMeshComponent
->
SetForwardAxis
(
ESplineMeshAxis
::
Z
);
SplineMeshComponent
->
CastShadow
=
false
;
SplineMeshComponent
->
CastShadow
=
false
;
}
}
else
else
{
{
// Display an error message if the spline mesh component creation fails
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"Error while spawning SplineMeshComponent!"
))
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"Error while spawning SplineMeshComponent!"
))
}
}
}
}
void
UIntenSelectComponent
::
InitForwardRayMeshComponent
()
void
UIntenSelectComponent
::
InitForwardRayMeshComponent
()
{
{
// Create a new static mesh component for the forward ray
ForwardRayMeshComponent
=
ForwardRayMeshComponent
=
NewObject
<
UStaticMeshComponent
>
(
this
,
UStaticMeshComponent
::
StaticClass
(),
TEXT
(
"ForwardRay"
));
NewObject
<
UStaticMeshComponent
>
(
this
,
UStaticMeshComponent
::
StaticClass
(),
TEXT
(
"ForwardRay"
));
// Check if the forward ray mesh component was successfully created
if
(
ForwardRayMeshComponent
)
if
(
ForwardRayMeshComponent
)
{
{
// Setup attachment and mobility of the forward ray mesh component
ForwardRayMeshComponent
->
SetupAttachment
(
this
);
ForwardRayMeshComponent
->
SetupAttachment
(
this
);
ForwardRayMeshComponent
->
SetMobility
(
(
EComponentMobility
::
Movable
)
)
;
ForwardRayMeshComponent
->
SetMobility
(
EComponentMobility
::
Movable
);
ForwardRayMeshComponent
->
RegisterComponent
();
ForwardRayMeshComponent
->
RegisterComponent
();
ForwardRayMeshComponent
->
CreationMethod
=
EComponentCreationMethod
::
Instance
;
ForwardRayMeshComponent
->
CreationMethod
=
EComponentCreationMethod
::
Instance
;
// Configure shadow casting and collision properties
ForwardRayMeshComponent
->
SetCastShadow
(
false
);
ForwardRayMeshComponent
->
SetCastShadow
(
false
);
ForwardRayMeshComponent
->
SetCollisionEnabled
(
ECollisionEnabled
::
NoCollision
);
ForwardRayMeshComponent
->
SetCollisionEnabled
(
ECollisionEnabled
::
NoCollision
);
// Set relative scale and location based on max selection distance
const
float
MeshLength
=
MaxSelectionDistance
>
1000
?
1000
:
MaxSelectionDistance
;
const
float
MeshLength
=
MaxSelectionDistance
>
1000
?
1000
:
MaxSelectionDistance
;
ForwardRayMeshComponent
->
SetRelativeScale3D
(
FVector
(
MeshLength
,
ForwardRayWidth
,
ForwardRayWidth
));
ForwardRayMeshComponent
->
SetRelativeScale3D
(
FVector
(
MeshLength
,
ForwardRayWidth
,
ForwardRayWidth
));
ForwardRayMeshComponent
->
SetRelativeLocation
(
FVector
(
MeshLength
*
50
,
0
,
0
));
ForwardRayMeshComponent
->
SetRelativeLocation
(
FVector
(
MeshLength
*
50
,
0
,
0
));
//
const ConstructorHelpers::FObjectFinder<US
tatic
M
esh
> CubeMesh(TEXT("/Engine/BasicShapes/Cube.Cube"));
//
Set the s
tatic
m
esh
for the forward ray component if available
if
(
ForwardRayMesh
)
if
(
ForwardRayMesh
)
{
{
ForwardRayMeshComponent
->
SetStaticMesh
(
ForwardRayMesh
);
ForwardRayMeshComponent
->
SetStaticMesh
(
ForwardRayMesh
);
...
@@ -202,62 +226,76 @@ void UIntenSelectComponent::InitForwardRayMeshComponent()
...
@@ -202,62 +226,76 @@ void UIntenSelectComponent::InitForwardRayMeshComponent()
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"Mesh for RayComponent not set!"
));
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"Mesh for RayComponent not set!"
));
}
}
// Create dynamic material instance for the forward ray mesh component
UMaterialInstanceDynamic
*
DynamicMaterial
=
UMaterialInstanceDynamic
*
DynamicMaterial
=
UMaterialInstanceDynamic
::
Create
(
ForwardRayMaterial
,
ForwardRayMeshComponent
);
UMaterialInstanceDynamic
::
Create
(
ForwardRayMaterial
,
ForwardRayMeshComponent
);
this
->
ForwardRayMeshComponent
->
SetMaterial
(
0
,
DynamicMaterial
);
this
->
ForwardRayMeshComponent
->
SetMaterial
(
0
,
DynamicMaterial
);
// Set visibility based on draw forward ray flag
ForwardRayMeshComponent
->
SetHiddenInGame
(
!
bDrawForwardRay
);
ForwardRayMeshComponent
->
SetHiddenInGame
(
!
bDrawForwardRay
);
}
}
else
else
{
{
// Display an error message if the forward ray mesh component creation fails
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"Error while spawning ForwardRayMesh component!"
));
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"Error while spawning ForwardRayMesh component!"
));
}
}
}
}
void
UIntenSelectComponent
::
InitMaterialParamCollection
()
void
UIntenSelectComponent
::
InitMaterialParamCollection
()
{
{
// Check if the material parameter collection is set
if
(
MaterialParamCollection
)
if
(
MaterialParamCollection
)
{
{
// Get the parameter collection instance from the world
this
->
ParameterCollectionInstance
=
GetWorld
()
->
GetParameterCollectionInstance
(
MaterialParamCollection
);
this
->
ParameterCollectionInstance
=
GetWorld
()
->
GetParameterCollectionInstance
(
MaterialParamCollection
);
if
(
this
->
ParameterCollectionInstance
)
if
(
this
->
ParameterCollectionInstance
)
{
{
// Set the scalar parameter value for transparency
this
->
ParameterCollectionInstance
->
SetScalarParameterValue
(
"Transparency"
,
DebugRayTransparency
);
this
->
ParameterCollectionInstance
->
SetScalarParameterValue
(
"Transparency"
,
DebugRayTransparency
);
}
}
else
else
{
{
// Display a warning if the parameter collection instance is not found
UE_LOG
(
LogTemp
,
Warning
,
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"MaterialParameterCollection required for rendering of IntenSelect could not be found!"
))
TEXT
(
"MaterialParameterCollection required for rendering of IntenSelect could not be found!"
))
}
}
}
}
else
else
{
{
// Display a warning if the material parameter collection is not set
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"MaterialParameterCollection required for InteSelect visualization is not set!"
));
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"MaterialParameterCollection required for InteSelect visualization is not set!"
));
}
}
}
}
void
UIntenSelectComponent
::
InitDebugConeMeshComponent
()
void
UIntenSelectComponent
::
InitDebugConeMeshComponent
()
{
{
// Create a new static mesh component for the debug cone
DebugConeMeshComponent
=
DebugConeMeshComponent
=
NewObject
<
UStaticMeshComponent
>
(
this
,
UStaticMeshComponent
::
StaticClass
(),
TEXT
(
"DebugCone"
));
NewObject
<
UStaticMeshComponent
>
(
this
,
UStaticMeshComponent
::
StaticClass
(),
TEXT
(
"DebugCone"
));
// Check if the debug cone mesh component was successfully created
if
(
DebugConeMeshComponent
)
if
(
DebugConeMeshComponent
)
{
{
// Setup attachment and mobility of the debug cone mesh component
DebugConeMeshComponent
->
SetupAttachment
(
this
);
DebugConeMeshComponent
->
SetupAttachment
(
this
);
DebugConeMeshComponent
->
SetMobility
(
EComponentMobility
::
Movable
);
DebugConeMeshComponent
->
SetMobility
(
EComponentMobility
::
Movable
);
DebugConeMeshComponent
->
RegisterComponent
();
DebugConeMeshComponent
->
RegisterComponent
();
DebugConeMeshComponent
->
CreationMethod
=
EComponentCreationMethod
::
Instance
;
DebugConeMeshComponent
->
CreationMethod
=
EComponentCreationMethod
::
Instance
;
// Calculate transform for the cone based on selection cone angle and distance
FTransform
ConeTransform
=
DebugConeMeshComponent
->
GetRelativeTransform
();
FTransform
ConeTransform
=
DebugConeMeshComponent
->
GetRelativeTransform
();
const
float
ConeScale
=
MaxSelectionDistance
/
50
*
FMath
::
Tan
(
FMath
::
DegreesToRadians
(
SelectionConeAngle
));
const
float
ConeScale
=
MaxSelectionDistance
/
50
*
FMath
::
Tan
(
FMath
::
DegreesToRadians
(
SelectionConeAngle
));
ConeTransform
.
SetScale3D
(
FVector
(
ConeScale
,
ConeScale
,
MaxSelectionDistance
/
100
));
ConeTransform
.
SetScale3D
(
FVector
(
ConeScale
,
ConeScale
,
MaxSelectionDistance
/
100
));
// Set relative transform and location for the debug cone
DebugConeMeshComponent
->
SetRelativeTransform
(
ConeTransform
);
DebugConeMeshComponent
->
SetRelativeTransform
(
ConeTransform
);
DebugConeMeshComponent
->
SetRelativeLocation
(
FVector
(
MaxSelectionDistance
-
ConeBackwardShiftDistance
,
0
,
0
),
DebugConeMeshComponent
->
SetRelativeLocation
(
FVector
(
MaxSelectionDistance
-
ConeBackwardShiftDistance
,
0
,
0
),
false
);
false
);
DebugConeMeshComponent
->
SetRelativeRotation
(
DebugConeRotation
,
false
);
DebugConeMeshComponent
->
SetRelativeRotation
(
DebugConeRotation
,
false
);
DebugConeMeshComponent
->
SetCollisionEnabled
(
ECollisionEnabled
::
NoCollision
);
DebugConeMeshComponent
->
SetCollisionEnabled
(
ECollisionEnabled
::
NoCollision
);
// Set the static mesh for the debug cone component if available
if
(
DebugConeMesh
)
if
(
DebugConeMesh
)
{
{
DebugConeMeshComponent
->
SetStaticMesh
(
DebugConeMesh
);
DebugConeMeshComponent
->
SetStaticMesh
(
DebugConeMesh
);
...
@@ -266,6 +304,8 @@ void UIntenSelectComponent::InitDebugConeMeshComponent()
...
@@ -266,6 +304,8 @@ void UIntenSelectComponent::InitDebugConeMeshComponent()
{
{
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"DebugCone mesh not set!"
))
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"DebugCone mesh not set!"
))
}
}
// Set the material for the debug cone component if available
if
(
DebugConeMaterial
)
if
(
DebugConeMaterial
)
{
{
DebugConeMeshComponent
->
SetMaterial
(
0
,
DebugConeMaterial
);
DebugConeMeshComponent
->
SetMaterial
(
0
,
DebugConeMaterial
);
...
@@ -275,10 +315,12 @@ void UIntenSelectComponent::InitDebugConeMeshComponent()
...
@@ -275,10 +315,12 @@ void UIntenSelectComponent::InitDebugConeMeshComponent()
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"DebugCone material not set! Using default material instead."
))
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"DebugCone material not set! Using default material instead."
))
}
}
// Set visibility based on draw debug cone flag
DebugConeMeshComponent
->
SetVisibility
(
bDrawDebugCone
);
DebugConeMeshComponent
->
SetVisibility
(
bDrawDebugCone
);
}
}
else
else
{
{
// Display an error message if the debug cone mesh component creation fails
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"Error while spawning DebugCone component!"
))
UE_LOG
(
LogTemp
,
Error
,
TEXT
(
"Error while spawning DebugCone component!"
))
}
}
}
}
...
@@ -288,59 +330,72 @@ void UIntenSelectComponent::InitDebugConeMeshComponent()
...
@@ -288,59 +330,72 @@ void UIntenSelectComponent::InitDebugConeMeshComponent()
float
UIntenSelectComponent
::
CalculateSphereCastRadius
()
const
float
UIntenSelectComponent
::
CalculateSphereCastRadius
()
const
{
{
// Calculate sphere cast radius based on selection cone angle and max selection distance
return
FMath
::
Tan
(
FMath
::
DegreesToRadians
(
SelectionConeAngle
))
*
MaxSelectionDistance
;
return
FMath
::
Tan
(
FMath
::
DegreesToRadians
(
SelectionConeAngle
))
*
MaxSelectionDistance
;
}
}
bool
UIntenSelectComponent
::
CheckPointInCone
(
const
FVector
ConeStartPoint
,
const
FVector
ConeForward
,
bool
UIntenSelectComponent
::
CheckPointInCone
(
const
FVector
ConeStartPoint
,
const
FVector
ConeForward
,
const
FVector
PointToTest
,
const
float
Angle
)
const
const
FVector
PointToTest
,
const
float
Angle
)
const
{
{
// Shift the start origin point of the cone backward
const
FVector
ShiftedStartOriginPoint
=
ConeStartPoint
-
(
ConeForward
*
ConeBackwardShiftDistance
);
const
FVector
ShiftedStartOriginPoint
=
ConeStartPoint
-
(
ConeForward
*
ConeBackwardShiftDistance
);
// Calculate the direction to the test point
const
FVector
DirectionToTestPoint
=
(
PointToTest
-
ShiftedStartOriginPoint
).
GetSafeNormal
();
const
FVector
DirectionToTestPoint
=
(
PointToTest
-
ShiftedStartOriginPoint
).
GetSafeNormal
();
// Calculate the angle to the test point
const
float
AngleToTestPoint
=
const
float
AngleToTestPoint
=
FMath
::
RadiansToDegrees
(
FMath
::
Acos
((
FVector
::
DotProduct
(
ConeForward
,
DirectionToTestPoint
))));
FMath
::
RadiansToDegrees
(
FMath
::
Acos
((
FVector
::
DotProduct
(
ConeForward
,
DirectionToTestPoint
))));
// Check if the angle to the test point is within the specified cone angle
return
AngleToTestPoint
<=
Angle
;
return
AngleToTestPoint
<=
Angle
;
}
}
void
UIntenSelectComponent
::
OnNewSelected_Implementation
(
UIntenSelectable
*
Selection
)
void
UIntenSelectComponent
::
OnNewSelected_Implementation
(
UIntenSelectable
*
Selection
)
{
{
// Set the current selection
CurrentSelection
=
Selection
;
CurrentSelection
=
Selection
;
// Play sound feedback if cooldown allows
if
(
FeedbackCooldown
==
0
)
if
(
FeedbackCooldown
==
0
)
{
{
// UGameplayStatics::GetPlayerController(GetWorld(), 0)->PlayHapticEffect(SelectionFeedbackHaptic,
// EControllerHand::Right, 0.1, false);
UGameplayStatics
::
PlaySound2D
(
GetWorld
(),
OnSelectSound
);
UGameplayStatics
::
PlaySound2D
(
GetWorld
(),
OnSelectSound
);
FeedbackCooldown
=
0.1
;
FeedbackCooldown
=
0.1
;
}
}
}
}
bool
UIntenSelectComponent
::
GetActorsFromSphereCast
(
const
FVector
&
SphereCastStart
,
TArray
<
FHitResult
>&
OutHits
)
const
bool
UIntenSelectComponent
::
GetActorsFromSphereCast
(
const
FVector
&
SphereCastStart
,
TArray
<
FHitResult
>&
OutHits
)
const
{
{
// Calculate start and end positions for the sphere cast
const
FVector
StartPos
=
const
FVector
StartPos
=
SphereCastStart
+
(
GetComponentTransform
().
GetRotation
().
GetForwardVector
()
*
SphereCastRadius
);
SphereCastStart
+
(
GetComponentTransform
().
GetRotation
().
GetForwardVector
()
*
SphereCastRadius
);
const
FVector
EndPos
=
const
FVector
EndPos
=
StartPos
+
(
GetComponentTransform
().
GetRotation
().
GetForwardVector
()
*
MaxSelectionDistance
);
StartPos
+
(
this
->
GetComponentTransform
().
GetRotation
().
GetForwardVector
()
*
(
MaxSelectionDistance
));
// Set up collision query parameters
const
FCollisionQueryParams
Params
=
FCollisionQueryParams
(
FName
(
TEXT
(
"SphereTraceMultiForObjects"
)),
false
);
const
FCollisionQueryParams
Params
=
FCollisionQueryParams
(
FName
(
TEXT
(
"SphereTraceMultiForObjects"
)),
false
);
// GetWorld()->SweepMultiByChannel(OutHits, StartPos, EndPos, FQuat::Identity, ECC_Visibility,
// FCollisionShape::MakeSphere(SphereCastRadius), Params);
// Perform sphere cast
GetWorld
()
->
SweepMultiByChannel
(
OutHits
,
StartPos
,
EndPos
,
FQuat
::
Identity
,
ECC_Visibility
,
GetWorld
()
->
SweepMultiByChannel
(
OutHits
,
StartPos
,
EndPos
,
FQuat
::
Identity
,
ECC_Visibility
,
FCollisionShape
::
MakeSphere
(
SphereCastRadius
),
Params
);
FCollisionShape
::
MakeSphere
(
SphereCastRadius
),
Params
);
// UKismetSystemLibrary::SphereTraceMulti(GetWorld(),StartPos,EndPos,SphereCastRadius,ETraceTypeQuery::TraceTypeQuery1,false,{},EDrawDebugTrace::ForOneFrame,OutHits,true);
return
true
;
return
true
;
}
}
UIntenSelectable
*
UIntenSelectComponent
::
GetMaxScoreActor
(
const
float
DeltaTime
)
UIntenSelectable
*
UIntenSelectComponent
::
GetMaxScoreActor
(
const
float
DeltaTime
)
{
{
const
FVector
ConeOrigin
=
this
->
GetComponentTransform
().
GetLocation
();
// Get cone origin and forward direction
const
FVector
ConeForward
=
this
->
GetComponentTransform
().
GetRotation
().
GetForwardVector
();
const
FVector
ConeOrigin
=
GetComponentTransform
().
GetLocation
();
const
FVector
ConeForward
=
GetComponentTransform
().
GetRotation
().
GetForwardVector
();
// Perform sphere cast to detect selectable actors
TArray
<
FHitResult
>
OutHits
;
TArray
<
FHitResult
>
OutHits
;
if
(
GetActorsFromSphereCast
(
ConeOrigin
,
OutHits
))
if
(
GetActorsFromSphereCast
(
ConeOrigin
,
OutHits
))
{
{
// Iterate through hit results
for
(
const
FHitResult
&
Hit
:
OutHits
)
for
(
const
FHitResult
&
Hit
:
OutHits
)
{
{
const
FVector
PointToCheck
=
Hit
.
ImpactPoint
;
const
FVector
PointToCheck
=
Hit
.
ImpactPoint
;
...
@@ -349,36 +404,39 @@ UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
...
@@ -349,36 +404,39 @@ UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
const
AActor
*
HitActor
=
Hit
.
GetActor
();
const
AActor
*
HitActor
=
Hit
.
GetActor
();
if
(
HitActor
)
if
(
HitActor
)
{
{
cons
t
a
u
to
S
electable
=
HitActor
->
FindComponentByClass
<
UIntenSelectable
>
();
// Check if the hi
t a
c
to
r is s
electable
and within selection distance
UIntenSelectable
*
Selectable
=
HitActor
->
FindComponentByClass
<
UIntenSelectable
>
();
if
(
Selectable
&&
Selectable
->
IsSelectable
&&
DistanceToActor
<=
MaxSelectionDistance
)
if
(
Selectable
&&
Selectable
->
IsSelectable
&&
DistanceToActor
<=
MaxSelectionDistance
)
{
{
// Add to score map
ScoreMap
.
FindOrAdd
(
Selectable
,
0
);
ScoreMap
.
FindOrAdd
(
Selectable
,
0
);
}
}
}
}
}
}
}
}
// Variables for tracking the maximum score selectable
UIntenSelectable
*
MaxScoreSelectable
=
nullptr
;
UIntenSelectable
*
MaxScoreSelectable
=
nullptr
;
float
MaxScore
=
TNumericLimits
<
float
>::
Min
();
float
MaxScore
=
TNumericLimits
<
float
>::
Min
();
TArray
<
UIntenSelectable
*>
RemoveList
;
TArray
<
UIntenSelectable
*>
RemoveList
;
TArray
<
TPair
<
UIntenSelectable
*
,
FHitResult
>>
CandidateList
;
TArray
<
TPair
<
UIntenSelectable
*
,
FHitResult
>>
CandidateList
;
for
(
TTuple
<
UIntenSelectable
*
,
float
>&
OldScoreEntry
:
ScoreMap
)
// Iterate through the score map
for
(
TPair
<
UIntenSelectable
*
,
float
>&
OldScoreEntry
:
ScoreMap
)
{
{
// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Black, OldScoreEntry.Key->GetOwner()->GetName() + "
// - Score: " + FString::SanitizeFloat(OldScoreEntry.Value));
if
(
!
OldScoreEntry
.
Key
)
if
(
!
OldScoreEntry
.
Key
)
{
{
continue
;
continue
;
}
}
// Calculate the new score and contact point
TPair
<
FHitResult
,
float
>
NewScorePair
=
OldScoreEntry
.
Key
->
GetBestPointScorePair
(
TPair
<
FHitResult
,
float
>
NewScorePair
=
OldScoreEntry
.
Key
->
GetBestPointScorePair
(
ConeOrigin
,
ConeForward
,
ConeBackwardShiftDistance
,
SelectionConeAngle
,
OldScoreEntry
.
Value
,
DeltaTime
);
ConeOrigin
,
ConeForward
,
ConeBackwardShiftDistance
,
SelectionConeAngle
,
OldScoreEntry
.
Value
,
DeltaTime
);
ContactPointMap
.
Add
(
OldScoreEntry
.
Key
,
NewScorePair
.
Key
);
ContactPointMap
.
Add
(
OldScoreEntry
.
Key
,
NewScorePair
.
Key
);
const
float
DistanceToActor
=
FVector
::
Dist
(
ConeOrigin
,
NewScorePair
.
Key
.
ImpactPoint
);
const
float
DistanceToActor
=
FVector
::
Dist
(
ConeOrigin
,
NewScorePair
.
Key
.
ImpactPoint
);
// Check if the new score is valid and if the actor is still selectable
const
float
Eps
=
0.01
;
const
float
Eps
=
0.01
;
if
(
NewScorePair
.
Value
<=
0.01
||
DistanceToActor
>=
MaxSelectionDistance
||
!
OldScoreEntry
.
Key
->
IsSelectable
)
if
(
NewScorePair
.
Value
<=
0.01
||
DistanceToActor
>=
MaxSelectionDistance
||
!
OldScoreEntry
.
Key
->
IsSelectable
)
{
{
...
@@ -388,15 +446,16 @@ UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
...
@@ -388,15 +446,16 @@ UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
{
{
OldScoreEntry
.
Value
=
NewScorePair
.
Value
;
OldScoreEntry
.
Value
=
NewScorePair
.
Value
;
// Check if the new score exceeds the maximum score
if
(
NewScorePair
.
Value
>
(
1.0
-
Eps
)
&&
if
(
NewScorePair
.
Value
>
(
1.0
-
Eps
)
&&
this
->
CheckPointInCone
(
ConeOrigin
,
ConeForward
,
NewScorePair
.
Key
.
ImpactPoint
,
SelectionConeAngle
))
CheckPointInCone
(
ConeOrigin
,
ConeForward
,
NewScorePair
.
Key
.
ImpactPoint
,
SelectionConeAngle
))
{
{
CandidateList
.
Emplace
(
OldScoreEntry
.
Key
,
NewScorePair
.
Key
);
CandidateList
.
Emplace
(
OldScoreEntry
.
Key
,
NewScorePair
.
Key
);
MaxScore
=
NewScorePair
.
Value
;
MaxScore
=
NewScorePair
.
Value
;
MaxScoreSelectable
=
OldScoreEntry
.
Key
;
MaxScoreSelectable
=
OldScoreEntry
.
Key
;
}
}
else
if
(
NewScorePair
.
Value
>
MaxScore
&&
else
if
(
NewScorePair
.
Value
>
MaxScore
&&
this
->
CheckPointInCone
(
ConeOrigin
,
ConeForward
,
NewScorePair
.
Key
.
ImpactPoint
,
SelectionConeAngle
))
CheckPointInCone
(
ConeOrigin
,
ConeForward
,
NewScorePair
.
Key
.
ImpactPoint
,
SelectionConeAngle
))
{
{
MaxScore
=
NewScorePair
.
Value
;
MaxScore
=
NewScorePair
.
Value
;
MaxScoreSelectable
=
OldScoreEntry
.
Key
;
MaxScoreSelectable
=
OldScoreEntry
.
Key
;
...
@@ -404,19 +463,22 @@ UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
...
@@ -404,19 +463,22 @@ UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
}
}
}
}
for
(
const
UIntenSelectable
*
i
:
RemoveList
)
// Remove non-selectable actors from the maps
for
(
UIntenSelectable
*
i
:
RemoveList
)
{
{
ContactPointMap
.
Remove
(
i
);
ContactPointMap
.
Remove
(
i
);
ScoreMap
.
Remove
(
i
);
ScoreMap
.
Remove
(
i
);
}
}
// Select the nearest actor from the candidate list if available
if
(
CandidateList
.
Num
()
>
0
)
if
(
CandidateList
.
Num
()
>
0
)
{
{
auto
DistanceToMaxScore
=
float
DistanceToMaxScore
=
FVector
::
Distance
(
MaxScoreSelectable
->
GetOwner
()
->
GetActorLocation
(),
GetComponentLocation
());
FVector
::
Distance
(
MaxScoreSelectable
->
GetOwner
()
->
GetActorLocation
(),
GetComponentLocation
());
auto
Dist
=
TNumericLimits
<
float
>::
Max
();
float
Dist
=
TNumericLimits
<
float
>::
Max
();
for
(
const
TPair
<
UIntenSelectable
*
,
FHitResult
>&
Actor
:
CandidateList
)
for
(
const
TPair
<
UIntenSelectable
*
,
FHitResult
>&
Actor
:
CandidateList
)
{
{
const
auto
DistanceToCandidate
=
FVector
::
Distance
(
Actor
.
Value
.
ImpactPoint
,
GetComponentLocation
());
const
float
DistanceToCandidate
=
FVector
::
Distance
(
Actor
.
Value
.
ImpactPoint
,
GetComponentLocation
());
if
(
DistanceToCandidate
<
Dist
)
if
(
DistanceToCandidate
<
Dist
)
{
{
MaxScoreSelectable
=
Actor
.
Key
;
MaxScoreSelectable
=
Actor
.
Key
;
...
@@ -427,46 +489,48 @@ UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
...
@@ -427,46 +489,48 @@ UIntenSelectable* UIntenSelectComponent::GetMaxScoreActor(const float DeltaTime)
return
MaxScoreSelectable
;
return
MaxScoreSelectable
;
}
}
// RAYCASTING
// RAYCASTING
void
UIntenSelectComponent
::
HandleWidgetInteraction
()
void
UIntenSelectComponent
::
HandleWidgetInteraction
()
{
{
const
FVector
Forward
=
this
->
GetComponentTransform
().
GetRotation
().
GetForwardVector
();
// Get forward vector and origin of the component
const
FVector
Origin
=
this
->
GetComponentTransform
().
GetLocation
();
const
FVector
Forward
=
GetComponentTransform
().
GetRotation
().
GetForwardVector
();
const
FVector
Origin
=
GetComponentTransform
().
GetLocation
();
// Raytrace to find the first hit
TOptional
<
FHitResult
>
Hit
=
RaytraceForFirstHit
(
Origin
,
Origin
+
Forward
*
MaxSelectionDistance
);
TOptional
<
FHitResult
>
Hit
=
RaytraceForFirstHit
(
Origin
,
Origin
+
Forward
*
MaxSelectionDistance
);
// If no hit, clear focus and return
if
(
!
Hit
.
IsSet
())
if
(
!
Hit
.
IsSet
())
{
{
IsWidgetInFocus
=
false
;
IsWidgetInFocus
=
false
;
return
;
return
;
}
}
// Set hit result and check if a widget is in focus
SetCustomHitResult
(
Hit
.
GetValue
());
SetCustomHitResult
(
Hit
.
GetValue
());
UWidgetComponent
*
FocusedWidget
=
Cast
<
UWidgetComponent
>
(
Hit
.
GetValue
().
GetComponent
());
UWidgetComponent
*
FocusedWidget
=
Cast
<
UWidgetComponent
>
(
Hit
.
GetValue
().
GetComponent
());
IsWidgetInFocus
=
(
FocusedWidget
!=
nullptr
);
IsWidgetInFocus
=
(
FocusedWidget
!=
nullptr
);
// Handle widget events (commented out for now)
/*
/*
if (IsWidgetInFocus)
if (IsWidgetInFocus)
{
{
if (FocusedWidget != LastFocusedWidget)
if (FocusedWidget != LastFocusedWidget)
{
{
//We can always execute the enter event as we are sure that a hit occured
if (FocusedWidget->GetOwner()->Implements<UTargetable>())
if (FocusedWidget->GetOwner()->Implements<UTargetable>())
{
{
ITargetable::Execute_OnTargetedEnter(FocusedWidget->GetOwner());
ITargetable::Execute_OnTargetedEnter(FocusedWidget->GetOwner());
}
}
//Only execute the Leave Event if there was an actor that was focused previously
if (LastFocusedWidget != nullptr && LastFocusedWidget->GetOwner()->Implements<UTargetable>())
if (LastFocusedWidget != nullptr && LastFocusedWidget->GetOwner()->Implements<UTargetable>())
{
{
ITargetable::Execute_OnTargetedLeave(LastFocusedWidget->GetOwner());
ITargetable::Execute_OnTargetedLeave(LastFocusedWidget->GetOwner());
}
}
}
}
// for now uses the same distance as clicking
if (FocusedWidget->GetOwner()->Implements<UTargetable>())
if (FocusedWidget->GetOwner()->Implements<UTargetable>())
{
{
ITargetable::Execute_OnTargeted(FocusedWidget->GetOwner(), Hit->Location);
ITargetable::Execute_OnTargeted(FocusedWidget->GetOwner(), Hit->Location);
...
@@ -478,27 +542,33 @@ void UIntenSelectComponent::HandleWidgetInteraction()
...
@@ -478,27 +542,33 @@ void UIntenSelectComponent::HandleWidgetInteraction()
FVector pos = IIntenSelectableWidget::Execute_GetCoordinates(FocusedWidget->GetOwner());
FVector pos = IIntenSelectableWidget::Execute_GetCoordinates(FocusedWidget->GetOwner());
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Black, "C++ Pos: " + pos.ToString());
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Black, "C++ Pos: " + pos.ToString());
WidgetFocusPoint = pos;
WidgetFocusPoint = pos;
}else
}
else
{
{
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Black, "C++ Pos not available");
GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Black, "C++ Pos not available");
}
}
}*/
}
}
*/
}
TOptional
<
FHitResult
>
UIntenSelectComponent
::
RaytraceForFirstHit
(
const
FVector
&
Start
,
const
FVector
&
End
)
const
TOptional
<
FHitResult
>
UIntenSelectComponent
::
RaytraceForFirstHit
(
const
FVector
&
Start
,
const
FVector
&
End
)
const
{
{
//
will
be filled by
the
Line Trace
F
unction
//
Hit result to
be filled by Line Trace
f
unction
FHitResult
Hit
;
FHitResult
Hit
;
// Set up collision query parameters
FCollisionQueryParams
Params
;
FCollisionQueryParams
Params
;
Params
.
AddIgnoredActor
(
GetOwner
()
->
GetUniqueID
());
// prevents actor hitting itself
Params
.
AddIgnoredActor
(
GetOwner
()
->
GetUniqueID
());
// Ignore the owner actor to prevent hitting itself
// Perform line trace
if
(
GetWorld
()
->
LineTraceSingleByChannel
(
Hit
,
Start
,
End
,
ECollisionChannel
::
ECC_Visibility
,
Params
))
if
(
GetWorld
()
->
LineTraceSingleByChannel
(
Hit
,
Start
,
End
,
ECollisionChannel
::
ECC_Visibility
,
Params
))
{
{
return
{
Hit
};
return
{
Hit
};
}
}
else
else
{
{
return
{};
return
{};
// No hit
}
}
}
}
...
@@ -507,78 +577,106 @@ TOptional<FHitResult> UIntenSelectComponent::RaytraceForFirstHit(const FVector&
...
@@ -507,78 +577,106 @@ TOptional<FHitResult> UIntenSelectComponent::RaytraceForFirstHit(const FVector&
void
UIntenSelectComponent
::
DrawSelectionCurve
(
const
FVector
&
EndPoint
)
const
void
UIntenSelectComponent
::
DrawSelectionCurve
(
const
FVector
&
EndPoint
)
const
{
{
const
FVector
StartPoint
=
this
->
GetComponentTransform
().
GetLocation
();
// Get start point, forward vector, and set spline points
const
FVector
Forward
=
this
->
GetComponentTransform
().
GetRotation
().
GetForwardVector
();
const
FVector
StartPoint
=
GetComponentTransform
().
GetLocation
();
const
FVector
Forward
=
GetComponentTransform
().
GetRotation
().
GetForwardVector
();
SplineComponent
->
ClearSplinePoints
(
true
);
SplineComponent
->
ClearSplinePoints
(
true
);
SplineMeshComponent
->
SetHiddenInGame
(
false
);
SplineMeshComponent
->
SetHiddenInGame
(
false
);
AddSplinePointsDefault
(
StartPoint
,
Forward
,
EndPoint
);
AddSplinePointsDefault
(
StartPoint
,
Forward
,
EndPoint
);
// Get spline start and end positions and tangents
const
FVector
StartPosition
=
SplineComponent
->
GetLocationAtSplinePoint
(
0
,
ESplineCoordinateSpace
::
Local
);
const
FVector
StartPosition
=
SplineComponent
->
GetLocationAtSplinePoint
(
0
,
ESplineCoordinateSpace
::
Local
);
const
FVector
StartTangent
=
SplineComponent
->
GetTangentAtSplinePoint
(
0
,
ESplineCoordinateSpace
::
Local
);
const
FVector
StartTangent
=
SplineComponent
->
GetTangentAtSplinePoint
(
0
,
ESplineCoordinateSpace
::
Local
);
const
FVector
EndPosition
=
SplineComponent
->
GetLocationAtSplinePoint
(
1
,
ESplineCoordinateSpace
::
Local
);
const
FVector
EndPosition
=
SplineComponent
->
GetLocationAtSplinePoint
(
1
,
ESplineCoordinateSpace
::
Local
);
const
FVector
EndTangent
=
SplineComponent
->
GetTangentAtSplinePoint
(
1
,
ESplineCoordinateSpace
::
Local
);
const
FVector
EndTangent
=
SplineComponent
->
GetTangentAtSplinePoint
(
1
,
ESplineCoordinateSpace
::
Local
);
// Set start and end for spline mesh component
SplineMeshComponent
->
SetStartAndEnd
(
StartPosition
,
StartTangent
,
EndPosition
,
EndTangent
,
true
);
SplineMeshComponent
->
SetStartAndEnd
(
StartPosition
,
StartTangent
,
EndPosition
,
EndTangent
,
true
);
}
}
void
UIntenSelectComponent
::
AddSplinePointsDefault
(
const
FVector
&
StartPoint
,
const
FVector
&
Forward
,
void
UIntenSelectComponent
::
AddSplinePointsDefault
(
const
FVector
&
StartPoint
,
const
FVector
&
Forward
,
const
FVector
&
EndPoint
)
const
const
FVector
&
EndPoint
)
const
{
{
// Add start and end points to the spline
SplineComponent
->
AddSplineWorldPoint
(
StartPoint
);
SplineComponent
->
AddSplineWorldPoint
(
StartPoint
);
const
FVector
StartToEnd
=
EndPoint
-
StartPoint
;
const
FVector
ForwardProjection
=
StartToEnd
.
ProjectOnTo
(
Forward
);
SplineComponent
->
AddSplineWorldPoint
(
EndPoint
);
SplineComponent
->
AddSplineWorldPoint
(
EndPoint
);
// Set spline point types
SplineComponent
->
SetSplinePointType
(
0
,
ESplinePointType
::
Curve
,
true
);
SplineComponent
->
SetSplinePointType
(
0
,
ESplinePointType
::
Curve
,
true
);
SplineComponent
->
SetSplinePointType
(
1
,
ESplinePointType
::
Curve
,
true
);
SplineComponent
->
SetSplinePointType
(
1
,
ESplinePointType
::
Curve
,
true
);
SplineComponent
->
SetTangentAtSplinePoint
(
0
,
Forward
*
ForwardProjection
.
Size
()
*
SplineCurvatureStrength
,
// Calculate tangents for smooth curve
ESplineCoordinateSpace
::
World
,
true
);
const
FVector
StartToEnd
=
EndPoint
-
StartPoint
;
SplineComponent
->
SetTangentAtSplinePoint
(
1
,
StartToEnd
.
GetSafeNormal
(),
ESplineCoordinateSpace
::
World
,
true
);
const
FVector
ForwardProjection
=
StartToEnd
.
ProjectOnTo
(
Forward
);
const
FVector
StartTangent
=
Forward
*
ForwardProjection
.
Size
()
*
SplineCurvatureStrength
;
const
FVector
EndTangent
=
StartToEnd
.
GetSafeNormal
();
// Set tangents at spline points
SplineComponent
->
SetTangentAtSplinePoint
(
0
,
StartTangent
,
ESplineCoordinateSpace
::
World
,
true
);
SplineComponent
->
SetTangentAtSplinePoint
(
1
,
EndTangent
,
ESplineCoordinateSpace
::
World
,
true
);
}
}
void
UIntenSelectComponent
::
UpdateForwardRay
(
const
FVector
&
ReferencePoint
)
const
void
UIntenSelectComponent
::
UpdateForwardRay
(
const
FVector
&
ReferencePoint
)
const
{
{
// Check if transparency curve is available
if
(
ForwardRayTransparencyCurve
)
if
(
ForwardRayTransparencyCurve
)
{
{
const
FVector
C
one
F
orward
=
this
->
GetComponentTransform
().
GetRotation
().
GetForwardVector
();
// Calculate c
one
f
orward
vector and origin
const
FVector
Cone
Origin
=
const
FVector
Cone
Forward
=
GetComponentTransform
().
GetRotation
().
GetForwardVector
();
this
->
GetComponentTransform
().
GetLocation
()
-
(
ConeForward
*
ConeBackwardShiftDistance
);
const
FVector
ConeOrigin
=
GetComponentTransform
().
GetLocation
()
-
(
ConeForward
*
ConeBackwardShiftDistance
);
// Calculate angle to test point
const
FVector
TestPointVector
=
(
ReferencePoint
-
ConeOrigin
).
GetSafeNormal
();
const
FVector
TestPointVector
=
(
ReferencePoint
-
ConeOrigin
).
GetSafeNormal
();
const
float
AngleToTestPoint
=
const
float
AngleToTestPoint
=
FMath
::
RadiansToDegrees
(
FMath
::
Acos
(
(
FVector
::
DotProduct
(
ConeForward
,
TestPointVector
)))
)
;
FMath
::
RadiansToDegrees
(
FMath
::
Acos
(
FVector
::
DotProduct
(
ConeForward
,
TestPointVector
)));
// Calculate new transparency based on curve
const
float
NewTransparency
=
const
float
NewTransparency
=
ForwardRayTransparencyCurve
->
GetFloatValue
(
AngleToTestPoint
/
SelectionConeAngle
)
*
DebugRayTransparency
;
ForwardRayTransparencyCurve
->
GetFloatValue
(
AngleToTestPoint
/
SelectionConeAngle
)
*
DebugRayTransparency
;
// Set transparency parameter value in parameter collection
if
(
ParameterCollectionInstance
)
{
ParameterCollectionInstance
->
SetScalarParameterValue
(
"Transparency"
,
NewTransparency
);
ParameterCollectionInstance
->
SetScalarParameterValue
(
"Transparency"
,
NewTransparency
);
}
}
else
{
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"ParameterCollectionInstance is null!"
));
}
}
else
{
UE_LOG
(
LogTemp
,
Warning
,
TEXT
(
"ForwardRayTransparencyCurve is null!"
));
}
}
}
// INPUT-HANDLING
// INPUT-HANDLING
void
UIntenSelectComponent
::
OnFireDown
()
void
UIntenSelectComponent
::
OnFireDown
()
{
{
//
s
tart interaction of WidgetInteractionComponent
//
S
tart interaction of WidgetInteractionComponent
PressPointerKey
(
EKeys
::
LeftMouseButton
);
PressPointerKey
(
EKeys
::
LeftMouseButton
);
// Check if there is a current selection
if
(
!
CurrentSelection
)
if
(
!
CurrentSelection
)
{
{
return
;
return
;
}
}
if
(
CurrentSelection
)
// Handle action start events for current selection
const
FHitResult
*
GrabbedPoint
=
ContactPointMap
.
Find
(
CurrentSelection
);
if
(
GrabbedPoint
)
{
{
const
FHitResult
GrabbedPoint
=
*
ContactPointMap
.
Find
(
CurrentSelection
);
CurrentSelection
->
HandleOnActionStartEvents
(
this
);
CurrentSelection
->
HandleOnActionStartEvents
(
this
);
LastKnownSelection
=
CurrentSelection
;
LastKnownSelection
=
CurrentSelection
;
LastKnownGrabPoint
=
LastKnownGrabPoint
=
LastKnownSelection
->
GetOwner
()
->
GetRootComponent
()
->
GetComponentTransform
().
InverseTransformPosition
(
LastKnownSelection
->
GetOwner
()
->
GetRootComponent
()
->
GetComponentTransform
().
InverseTransformPosition
(
GrabbedPoint
.
ImpactPoint
);
GrabbedPoint
->
ImpactPoint
);
}
}
else
else
{
{
...
@@ -587,19 +685,22 @@ void UIntenSelectComponent::OnFireDown()
...
@@ -587,19 +685,22 @@ void UIntenSelectComponent::OnFireDown()
IsGrabbing
=
true
;
IsGrabbing
=
true
;
// Update transparency if required
if
(
bDrawForwardRay
&&
ParameterCollectionInstance
)
if
(
bDrawForwardRay
&&
ParameterCollectionInstance
)
{
{
ParameterCollectionInstance
->
SetScalarParameterValue
(
"Transparency"
,
0
);
ParameterCollectionInstance
->
SetScalarParameterValue
(
"Transparency"
,
0
);
}
}
}
}
void
UIntenSelectComponent
::
OnFireUp
()
void
UIntenSelectComponent
::
OnFireUp
()
{
{
//
e
nd interaction of WidgetInteractionComponent
//
E
nd interaction of WidgetInteractionComponent
ReleasePointerKey
(
EKeys
::
LeftMouseButton
);
ReleasePointerKey
(
EKeys
::
LeftMouseButton
);
IsGrabbing
=
false
;
IsGrabbing
=
false
;
// Handle action end events for last known selection
if
(
LastKnownSelection
)
if
(
LastKnownSelection
)
{
{
FInputActionValue
v
;
FInputActionValue
v
;
...
@@ -607,92 +708,113 @@ void UIntenSelectComponent::OnFireUp()
...
@@ -607,92 +708,113 @@ void UIntenSelectComponent::OnFireUp()
}
}
}
}
// SELECTION-HANDLING
// SELECTION-HANDLING
void
UIntenSelectComponent
::
SelectObject
(
UIntenSelectable
*
SelectableComponent
,
AActor
*
SelectedBy
)
void
UIntenSelectComponent
::
SelectObject
(
UIntenSelectable
*
SelectableComponent
,
AActor
*
SelectedBy
)
{
{
// Set the current selection to the specified selectable component
CurrentSelection
=
SelectableComponent
;
CurrentSelection
=
SelectableComponent
;
}
}
void
UIntenSelectComponent
::
Unselect
()
void
UIntenSelectComponent
::
Unselect
()
{
{
// Stop grabbing
IsGrabbing
=
false
;
IsGrabbing
=
false
;
// Hide spline mesh component
SplineMeshComponent
->
SetHiddenInGame
(
true
);
SplineMeshComponent
->
SetHiddenInGame
(
true
);
// Reset current selection
CurrentSelection
=
nullptr
;
CurrentSelection
=
nullptr
;
this
->
CurrentSelection
=
nullptr
;
}
}
void
UIntenSelectComponent
::
SetActive
(
bool
bNewActive
,
bool
bReset
)
void
UIntenSelectComponent
::
SetActive
(
bool
bNewActive
,
bool
bReset
)
{
{
if
(
bNewActive
)
if
(
bNewActive
)
{
{
// Show forward ray and spline mesh components
ForwardRayMeshComponent
->
SetVisibility
(
true
);
ForwardRayMeshComponent
->
SetVisibility
(
true
);
SplineMeshComponent
->
SetVisibility
(
true
);
SplineMeshComponent
->
SetVisibility
(
true
);
// Call superclass setActive function
Super
::
SetActive
(
true
,
bReset
);
Super
::
SetActive
(
true
,
bReset
);
}
}
else
else
{
{
// If there is a current selection, handle no actor selected
if
(
CurrentSelection
)
if
(
CurrentSelection
)
{
{
HandleNoActorSelected
();
HandleNoActorSelected
();
}
}
// If there is a last known selection, end the fire action
if
(
LastKnownSelection
)
if
(
LastKnownSelection
)
{
{
OnFireUp
();
OnFireUp
();
}
}
// Hide forward ray and spline mesh components
ForwardRayMeshComponent
->
SetVisibility
(
false
);
ForwardRayMeshComponent
->
SetVisibility
(
false
);
SplineMeshComponent
->
SetVisibility
(
false
);
SplineMeshComponent
->
SetVisibility
(
false
);
// Call superclass setActive function
Super
::
SetActive
(
false
,
bReset
);
Super
::
SetActive
(
false
,
bReset
);
}
}
}
}
// TICK
// TICK
void
UIntenSelectComponent
::
HandleCooldown
(
const
float
DeltaTime
)
void
UIntenSelectComponent
::
HandleCooldown
(
const
float
DeltaTime
)
{
{
// Reduce feedback cooldown by delta time
if
(
FeedbackCooldown
>
0
)
if
(
FeedbackCooldown
>
0
)
{
{
FeedbackCooldown
-=
DeltaTime
;
FeedbackCooldown
-=
DeltaTime
;
}
}
// Ensure feedback cooldown does not go below 0
else
else
{
{
FeedbackCooldown
=
0
;
FeedbackCooldown
=
0
;
}
}
}
}
void
UIntenSelectComponent
::
HandleGrabbing
(
const
float
DeltaTime
)
const
{}
void
UIntenSelectComponent
::
HandleActorSelected
(
UIntenSelectable
*
NewSelection
)
void
UIntenSelectComponent
::
HandleActorSelected
(
UIntenSelectable
*
NewSelection
)
{
{
// Check if the new selection is different from the current selection
if
(
NewSelection
!=
CurrentSelection
)
if
(
NewSelection
!=
CurrentSelection
)
{
{
// If there is a current selection, handle hover end events
if
(
CurrentSelection
)
if
(
CurrentSelection
)
{
{
CurrentSelection
->
HandleOnHoverEndEvents
(
this
);
CurrentSelection
->
HandleOnHoverEndEvents
(
this
);
}
}
// If there is a new selection, handle hover start events
if
(
NewSelection
)
if
(
NewSelection
)
{
{
UIntenSelectable
*
NewIntenSelectable
=
NewSelection
;
const
FHitResult
*
GrabbedPoint
=
ContactPointMap
.
Find
(
NewSelection
);
const
FHitResult
GrabbedPoint
=
*
ContactPointMap
.
Find
(
NewIntenSelectable
);
if
(
GrabbedPoint
)
NewIntenSelectable
->
HandleOnHoverStartEvents
(
this
,
GrabbedPoint
);
{
NewSelection
->
HandleOnHoverStartEvents
(
this
,
*
GrabbedPoint
);
}
}
}
// Set the new selection as the current selection and trigger new selected event
CurrentSelection
=
NewSelection
;
CurrentSelection
=
NewSelection
;
OnNewSelected
(
NewSelection
);
OnNewSelected
(
NewSelection
);
}
}
// If there is a current selection, update forward ray and draw selection curve
if
(
CurrentSelection
)
if
(
CurrentSelection
)
{
{
const
UIntenSelectable
*
NewIntenSelectable
=
NewSelection
;
const
FHitResult
*
GrabbedPoint
=
ContactPointMap
.
Find
(
NewSelection
);
const
auto
V_Net
=
ContactPointMap
.
Find
(
NewIntenSelectable
)
->
ImpactPoint
;
if
(
GrabbedPoint
)
const
FVector
PointToDrawTo
=
ConvertNetVector
(
V_Net
);
{
const
FVector
PointToDrawTo
=
ConvertNetVector
(
GrabbedPoint
->
ImpactPoint
);
if
(
bDrawForwardRay
)
if
(
bDrawForwardRay
)
{
{
...
@@ -702,41 +824,49 @@ void UIntenSelectComponent::HandleActorSelected(UIntenSelectable* NewSelection)
...
@@ -702,41 +824,49 @@ void UIntenSelectComponent::HandleActorSelected(UIntenSelectable* NewSelection)
DrawSelectionCurve
(
PointToDrawTo
);
DrawSelectionCurve
(
PointToDrawTo
);
}
}
}
}
}
FVector
UIntenSelectComponent
::
ConvertNetVector
(
FVector_NetQuantize
v
)
FVector
UIntenSelectComponent
::
ConvertNetVector
(
FVector_NetQuantize
v
)
{
{
FVector
Result
;
// Convert NetQuantize vector to FVector
Result
.
X
=
v
.
X
;
return
FVector
(
v
.
X
,
v
.
Y
,
v
.
Z
);
Result
.
Y
=
v
.
Y
;
Result
.
Z
=
v
.
Z
;
return
Result
;
}
}
void
UIntenSelectComponent
::
HandleNoActorSelected
()
void
UIntenSelectComponent
::
HandleNoActorSelected
()
{
{
// Hide spline mesh component
SplineMeshComponent
->
SetHiddenInGame
(
true
);
SplineMeshComponent
->
SetHiddenInGame
(
true
);
// If there is a current selection, handle hover end events and reset current selection
if
(
CurrentSelection
)
if
(
CurrentSelection
)
{
{
CurrentSelection
->
HandleOnHoverEndEvents
(
this
);
CurrentSelection
->
HandleOnHoverEndEvents
(
this
);
CurrentSelection
=
nullptr
;
}
}
// Reset transparency parameter if drawing forward ray
if
(
bDrawForwardRay
&&
ParameterCollectionInstance
)
if
(
bDrawForwardRay
&&
ParameterCollectionInstance
)
{
{
ParameterCollectionInstance
->
SetScalarParameterValue
(
"Transparency"
,
DebugRayTransparency
);
ParameterCollectionInstance
->
SetScalarParameterValue
(
"Transparency"
,
DebugRayTransparency
);
}
}
CurrentSelection
=
nullptr
;
}
}
void
UIntenSelectComponent
::
TickComponent
(
const
float
DeltaTime
,
const
ELevelTick
TickType
,
void
UIntenSelectComponent
::
TickComponent
(
const
float
DeltaTime
,
const
ELevelTick
TickType
,
FActorComponentTickFunction
*
ThisTickFunction
)
FActorComponentTickFunction
*
ThisTickFunction
)
{
{
// Call parent tick function
Super
::
TickComponent
(
DeltaTime
,
TickType
,
ThisTickFunction
);
Super
::
TickComponent
(
DeltaTime
,
TickType
,
ThisTickFunction
);
this
->
HandleCooldown
(
DeltaTime
);
// Handle cooldown for feedback
HandleCooldown
(
DeltaTime
);
// Get the new selection based on current parameters
UIntenSelectable
*
const
NewSelection
=
GetMaxScoreActor
(
DeltaTime
);
UIntenSelectable
*
const
NewSelection
=
GetMaxScoreActor
(
DeltaTime
);
// If currently grabbing an object, update selection curve and check for angle constraints
if
(
IsGrabbing
&&
LastKnownSelection
)
if
(
IsGrabbing
&&
LastKnownSelection
)
{
{
const
FVector
GrabPointWorld
=
const
FVector
GrabPointWorld
=
...
@@ -744,10 +874,10 @@ void UIntenSelectComponent::TickComponent(const float DeltaTime, const ELevelTic
...
@@ -744,10 +874,10 @@ void UIntenSelectComponent::TickComponent(const float DeltaTime, const ELevelTic
LastKnownGrabPoint
);
LastKnownGrabPoint
);
DrawSelectionCurve
(
GrabPointWorld
);
DrawSelectionCurve
(
GrabPointWorld
);
const
FVector
ConeOrigin
=
this
->
GetComponentLocation
();
const
FVector
ConeOrigin
=
GetComponentLocation
();
const
FVector
ConeForward
=
this
->
GetForwardVector
().
GetSafeNormal
();
const
FVector
ConeForward
=
GetForwardVector
().
GetSafeNormal
();
if
(
!
this
->
CheckPointInCone
(
ConeOrigin
,
ConeForward
,
GrabPointWorld
,
MaxClickStickAngle
))
if
(
!
CheckPointInCone
(
ConeOrigin
,
ConeForward
,
GrabPointWorld
,
MaxClickStickAngle
))
{
{
OnFireUp
();
OnFireUp
();
}
}
...
@@ -760,11 +890,10 @@ void UIntenSelectComponent::TickComponent(const float DeltaTime, const ELevelTic
...
@@ -760,11 +890,10 @@ void UIntenSelectComponent::TickComponent(const float DeltaTime, const ELevelTic
DrawSelectionCurve
(
GrabbedPoint
);
DrawSelectionCurve
(
GrabbedPoint
);
}
}
//
this->
Handle
W
idget
I
nteraction
();
// Handle
w
idget
i
nteraction
IsWidgetInFocus
=
false
;
IsWidgetInFocus
=
false
;
if
(
IsWidgetInFocus
)
if
(
IsWidgetInFocus
)
{
{
// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Red, "Widget focused");
HandleNoActorSelected
();
HandleNoActorSelected
();
const
FVector
PointToDrawTo
=
WidgetFocusPoint
;
const
FVector
PointToDrawTo
=
WidgetFocusPoint
;
...
@@ -778,14 +907,13 @@ void UIntenSelectComponent::TickComponent(const float DeltaTime, const ELevelTic
...
@@ -778,14 +907,13 @@ void UIntenSelectComponent::TickComponent(const float DeltaTime, const ELevelTic
}
}
else
else
{
{
// If there is a new selection, handle it; otherwise, handle no actor selected
if
(
NewSelection
)
if
(
NewSelection
)
{
{
// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Red, "Focused Actor:" + NewSelection->GetName());
HandleActorSelected
(
NewSelection
);
HandleActorSelected
(
NewSelection
);
}
}
else
else
{
{
// GEngine->AddOnScreenDebugMessage(INDEX_NONE, 0, FColor::Red, "No Actor in Focus");
HandleNoActorSelected
();
HandleNoActorSelected
();
}
}
}
}
...
...
This diff is collapsed.
Click to expand it.
Source/RWTHVRToolkit/Public/Pawn/IntenSelectComponent.h
+
149
−
3
View file @
aeb67856
...
@@ -143,71 +143,217 @@ public:
...
@@ -143,71 +143,217 @@ public:
#pragma region
/** INITIALIZATION */
#pragma region
/** INITIALIZATION */
private:
private:
/**
* \brief Initializes the input bindings for interacting with the component.
*/
void
InitInputBindings
();
void
InitInputBindings
();
/**
* \brief Initializes the debug cone mesh component used for visualization.
*/
void
InitDebugConeMeshComponent
();
void
InitDebugConeMeshComponent
();
/**
* \brief Initializes the spline mesh component used for visualization.
*/
void
InitSplineMeshComponent
();
void
InitSplineMeshComponent
();
/**
* \brief Initializes the spline component used for visualization.
*/
void
InitSplineComponent
();
void
InitSplineComponent
();
/**
* \brief Initializes the forward ray mesh component used for visualization.
*/
void
InitForwardRayMeshComponent
();
void
InitForwardRayMeshComponent
();
/**
* \brief Initializes the material parameter collection used for visualization.
*/
void
InitMaterialParamCollection
();
void
InitMaterialParamCollection
();
#pragma endregion
#pragma endregion
#pragma region
/** SCORING */
#pragma region
/** SCORING */
private:
private:
/**
* \brief Calculates the radius for sphere casting based on the selection cone angle and maximum selection distance.
* \return The calculated sphere cast radius.
*/
float
CalculateSphereCastRadius
()
const
;
float
CalculateSphereCastRadius
()
const
;
/**
* \brief Retrieves actors from sphere casting to determine potential selections.
* \param SphereCastStart The starting point of the sphere cast.
* \param OutHits The array to store hit results.
* \return True if successful, false otherwise.
*/
bool
GetActorsFromSphereCast
(
const
FVector
&
SphereCastStart
,
TArray
<
FHitResult
>&
OutHits
)
const
;
bool
GetActorsFromSphereCast
(
const
FVector
&
SphereCastStart
,
TArray
<
FHitResult
>&
OutHits
)
const
;
/**
* \brief Checks if a point is within the selection cone.
* \param ConeStartPoint The starting point of the selection cone.
* \param ConeForward The forward direction of the selection cone.
* \param PointToTest The point to test for inclusion in the cone.
* \param Angle The angle of the selection cone.
* \return True if the point is within the cone, false otherwise.
*/
bool
CheckPointInCone
(
const
FVector
ConeStartPoint
,
const
FVector
ConeForward
,
const
FVector
PointToTest
,
bool
CheckPointInCone
(
const
FVector
ConeStartPoint
,
const
FVector
ConeForward
,
const
FVector
PointToTest
,
const
float
Angle
)
const
;
const
float
Angle
)
const
;
/**
* \brief Determines the actor with the maximum score for selection.
* \param DeltaTime The time elapsed since the last frame.
* \return The actor with the maximum score for selection.
*/
UIntenSelectable
*
GetMaxScoreActor
(
const
float
DeltaTime
);
UIntenSelectable
*
GetMaxScoreActor
(
const
float
DeltaTime
);
#pragma endregion
#pragma endregion
#pragma region
/** VISUALS */
#pragma region
/** VISUALS */
private:
private:
/**
* \brief Draws a selection curve from the component to the specified end point.
* \param EndPoint The end point of the selection curve.
*/
void
DrawSelectionCurve
(
const
FVector
&
EndPoint
)
const
;
void
DrawSelectionCurve
(
const
FVector
&
EndPoint
)
const
;
/**
* \brief Adds default spline points for creating a spline between start and end points.
* \param StartPoint The starting point of the spline.
* \param Forward The forward direction of the spline.
* \param EndPoint The end point of the spline.
*/
void
AddSplinePointsDefault
(
const
FVector
&
StartPoint
,
const
FVector
&
Forward
,
const
FVector
&
EndPoint
)
const
;
void
AddSplinePointsDefault
(
const
FVector
&
StartPoint
,
const
FVector
&
Forward
,
const
FVector
&
EndPoint
)
const
;
/**
* \brief Updates the forward ray visualization based on the reference point.
* \param ReferencePoint The reference point to update the forward ray to.
*/
void
UpdateForwardRay
(
const
FVector
&
ReferencePoint
)
const
;
void
UpdateForwardRay
(
const
FVector
&
ReferencePoint
)
const
;
#pragma endregion
#pragma endregion
#pragma region
/** RAYCASTING */
#pragma region
/** RAYCASTING */
private:
private:
/**
* \brief Handles the interaction with widgets.
*/
void
HandleWidgetInteraction
();
void
HandleWidgetInteraction
();
/**
* \brief Performs a raycast from the start to the end point and returns the first hit result, if any.
* \param Start The starting point of the raycast.
* \param End The ending point of the raycast.
* \return The optional hit result of the raycast.
*/
TOptional
<
FHitResult
>
RaytraceForFirstHit
(
const
FVector
&
Start
,
const
FVector
&
End
)
const
;
TOptional
<
FHitResult
>
RaytraceForFirstHit
(
const
FVector
&
Start
,
const
FVector
&
End
)
const
;
#pragma endregion
#pragma endregion
#pragma region
/** INPUT-HANDLING */
#pragma region
/** INPUT-HANDLING */
private:
private:
/**
* \brief Handles the input event when the fire button is pressed.
*/
UFUNCTION
(
BlueprintCallable
)
UFUNCTION
(
BlueprintCallable
)
void
OnFireDown
();
void
OnFireDown
();
/**
* \brief Handles the input event when the fire button is released.
*/
UFUNCTION
(
BlueprintCallable
)
UFUNCTION
(
BlueprintCallable
)
void
OnFireUp
();
void
OnFireUp
();
#pragma endregion
#pragma endregion
#pragma region
/** OTHER */
#pragma region
/** OTHER */
private:
private:
/**
* \brief Handles the cooldown mechanism based on the passed time interval.
* \param DeltaTime The time elapsed since the last frame.
*/
void
HandleCooldown
(
const
float
DeltaTime
);
void
HandleCooldown
(
const
float
DeltaTime
);
void
HandleGrabbing
(
const
float
DeltaTime
)
const
;
/**
* \brief Handles the scenario when no actor is selected.
*/
void
HandleNoActorSelected
();
void
HandleNoActorSelected
();
/**
* \brief Handles the selection of a new actor.
* \param NewSelection The new selectable component to be selected.
*/
void
HandleActorSelected
(
UIntenSelectable
*
NewSelection
);
void
HandleActorSelected
(
UIntenSelectable
*
NewSelection
);
/**
* \brief Converts a network quantized vector to a regular FVector.
* \param v The network quantized vector to convert.
* \return The converted FVector.
*/
FVector
ConvertNetVector
(
FVector_NetQuantize
v
);
FVector
ConvertNetVector
(
FVector_NetQuantize
v
);
#pragma endregion
#pragma endregion
public:
public:
/**
* \brief Constructor for the UIntenSelectComponent class.
*/
UIntenSelectComponent
(
const
FObjectInitializer
&
ObjectInitializer
);
UIntenSelectComponent
(
const
FObjectInitializer
&
ObjectInitializer
);
#pragma region
/** SELECTION */
#pragma region
/** SELECTION */
/**
* \brief Selects a given selectable component.
* \param SelectableComponent The selectable component to be selected.
* \param SelectedBy The actor responsible for the selection.
*/
void
SelectObject
(
UIntenSelectable
*
SelectableComponent
,
AActor
*
SelectedBy
);
void
SelectObject
(
UIntenSelectable
*
SelectableComponent
,
AActor
*
SelectedBy
);
/**
* \brief Unselects the currently selected object.
*/
void
Unselect
();
void
Unselect
();
#pragma endregion
#pragma endregion
/**
* \brief Sets whether the component is active or not.
* \param bNewActive The new active state of the component.
* \param bReset Whether the activation should happen even if ShouldActivate returns false.
*/
virtual
void
SetActive
(
bool
bNewActive
,
bool
bReset
)
override
;
virtual
void
SetActive
(
bool
bNewActive
,
bool
bReset
)
override
;
/**
* \brief Blueprint-native event called when a new object is selected.
* \param Selection The newly selected object.
*/
UFUNCTION
(
BlueprintNativeEvent
)
UFUNCTION
(
BlueprintNativeEvent
)
void
OnNewSelected
(
UIntenSelectable
*
Selection
);
void
OnNewSelected
(
UIntenSelectable
*
Selection
);
protected:
protected:
// Called when the game starts
/**
* \brief Called when the game starts.
*/
virtual
void
BeginPlay
()
override
;
virtual
void
BeginPlay
()
override
;
// Called every frame
/**
* \brief Called every frame.
* \param DeltaTime The time since the last frame.
* \param TickType The type of tick.
* \param ThisTickFunction The tick function for this component.
*/
virtual
void
TickComponent
(
float
DeltaTime
,
ELevelTick
TickType
,
virtual
void
TickComponent
(
float
DeltaTime
,
ELevelTick
TickType
,
FActorComponentTickFunction
*
ThisTickFunction
)
override
;
FActorComponentTickFunction
*
ThisTickFunction
)
override
;
};
};
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment