A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
InteractionButton.cpp
Go to the documentation of this file.
1// Copyright(c) Pixo Group. All Rights Reserved.
2
4#include "PixoVRCharacter.h"
5#include "Components/SphereComponent.h"
6#include "Kismet/GameplayStatics.h"
7#include "NavAreas/NavArea_Obstacle.h"
8
10{
11 PrimaryActorTick.bCanEverTick = true;
12 bReplicates = true;
13
14 static ConstructorHelpers::FObjectFinder<UStaticMesh> ButtonMeshFinder(
15 TEXT("StaticMesh'/PixoCore/Meshes/InteractableObjects/SM_ButtonMoving.SM_ButtonMoving'"));
16 UStaticMesh* ButtonMesh = ButtonMeshFinder.Object;
17
18 static ConstructorHelpers::FObjectFinder<UStaticMesh> ButtonSupportMeshFinder(
19 TEXT("StaticMesh'/PixoCore/Meshes/InteractableObjects/SM_ButtonSupport.SM_ButtonSupport'"));
20 UStaticMesh* ButtonSupportMesh = ButtonSupportMeshFinder.Object;
21
22 USceneComponent* DefaultRootComponent = CreateDefaultSubobject<USceneComponent>("DefaultRootComponent");
23 SetRootComponent(DefaultRootComponent);
24
25 ButtonSupportComp = CreateDefaultSubobject<UStaticMeshComponent>("ButtonSupport");
26 ButtonSupportComp->SetupAttachment(GetRootComponent());
27 ButtonSupportComp->SetStaticMesh(ButtonSupportMesh);
28 ButtonSupportComp->SetRelativeRotation(FRotator(0.0f, 0.0f, 90.0f));
29
30 ButtonMovingComp = CreateDefaultSubobject<UStaticMeshComponent>("ButtonMoving");
31 ButtonMovingComp->SetupAttachment(ButtonSupportComp);
32 ButtonMovingComp->SetStaticMesh(ButtonMesh);
33 ButtonMovingComp->SetRelativeLocation(FVector(0.0f, -1.4f, 0.0f));
34
35 BoxCollisionComp = CreateDefaultSubobject<UBoxComponent>("BoxCollision");
36 BoxCollisionComp->SetupAttachment(ButtonMovingComp);
37 BoxCollisionComp->AreaClass = UNavArea_Obstacle::StaticClass();
38 BoxCollisionComp->SetBoxExtent(FVector(4.0f, 1.0f, 4.0f));
39 BoxCollisionComp->OnComponentBeginOverlap.AddDynamic(this, &AInteractionButton::OnBeginOverlapButton);
40
41 PointLightComp = CreateDefaultSubobject<UPointLightComponent>("PointLight");
42 PointLightComp->SetupAttachment(ButtonMovingComp);
43 PointLightComp->SetIntensity(100.f);
44 PointLightComp->SetAttenuationRadius(20.f);
45 PointLightComp->SetSoftSourceRadius(10.f);
46 PointLightComp->SetCastShadows(false);
47 PointLightComp->SetLightColor(FLinearColor::Green);
48
49 TextRenderComp = CreateDefaultSubobject<UTextRenderComponent>("TextRender");
50 TextRenderComp->SetupAttachment(ButtonSupportComp);
51 TextRenderComp->SetText(FText::FromName(ButtonText));
52 TextRenderComp->SetWorldSize(20.f);
53 TextRenderComp->SetHorizontalAlignment(EHTA_Center);
54 TextRenderComp->SetVerticalAlignment(EVRTA_TextCenter);
55 TextRenderComp->SetRelativeRotation(FRotator(0.0f, 0.0f, -90.0f));
56 TextRenderComp->SetRelativeLocation(FVector(0.0f, -15.0f, 0.0f));
57}
58
59void AInteractionButton::Tick(float DeltaSeconds)
60{
61 Super::Tick(DeltaSeconds);
62
63 MovingButtonTimeLine.TickTimeline(DeltaSeconds);
64}
65
67{
68 ButtonSupportComp->SetVisibility(bVisible);
69 ButtonMovingComp->SetVisibility(bVisible);
70 BoxCollisionComp->SetVisibility(bVisible);
71 BoxCollisionComp->SetCollisionEnabled(
72 bVisible ? ECollisionEnabled::QueryAndPhysics : ECollisionEnabled::NoCollision);
73 PointLightComp->SetVisibility(bVisible);
74 TextRenderComp->SetVisibility(bVisible);
75}
76
78{
79 CurrentButtonState = InButtonState;
80 switch (CurrentButtonState)
81 {
83 PointLightComp->SetLightColor(FLinearColor::Green);
84 ButtonMovingComp->SetVectorParameterValueOnMaterials("ButtonColor", FVector(0.207881f, 0.71875f, 0.074695f));
85 break;
86
88 PointLightComp->SetLightColor(FLinearColor::Red);
89 ButtonMovingComp->SetVectorParameterValueOnMaterials("ButtonColor", FVector(1.f, 0.f, 0.f));
90 break;
91
93 PointLightComp->SetLightColor(FLinearColor(0.1f, 0.1f, 0.1f));
94 ButtonMovingComp->SetVectorParameterValueOnMaterials("ButtonColor", FVector(0.1f, 0.1f, 0.1f));
95 break;
96
97 default:
98 break;
99 }
100}
101
102void AInteractionButton::SetButtonName(const FName& InButtonName)
103{
104 if (TextRenderComp)
105 {
106 TextRenderComp->SetText(FText::FromName(InButtonName));
107 }
108}
109
110void AInteractionButton::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
111{
112 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
113
114 DOREPLIFETIME(AInteractionButton, ButtonText);
115}
116
118{
119 Super::BeginPlay();
120
121 if (MovingButtonCurve != nullptr)
122 {
123 FOnTimelineFloat TimelineProgress;
124 TimelineProgress.BindUFunction(this, FName("MovingButtonTimelineProgress"));
125 MovingButtonTimeLine.AddInterpFloat(MovingButtonCurve, TimelineProgress);
126
127 FOnTimelineEventStatic TimelineFinished;
128 TimelineFinished.BindUFunction(this, FName("MovingButtonTimelineFinished"));
129 MovingButtonTimeLine.SetTimelineFinishedFunc(TimelineFinished);
130
131 MovingButtonTimeLine.SetLooping(false);
132 MovingButtonTimeLine.SetDirectionPropertyName("TimelineDirection");
133 }
134
135 TextRenderComp->SetHiddenInGame(!bIsButtonHaveText);
136}
137
138void AInteractionButton::ButtonPress_Implementation()
139{
140 bIsPressed = true;
142 TimelineDirection = ETimelineDirection::Forward;
143 MovingButtonTimeLine.PlayFromStart();
144 UGameplayStatics::PlaySoundAtLocation(this, ButtonPressSound, ButtonMovingComp->GetComponentLocation(),
145 ButtonPressSound->GetVolumeMultiplier(),
146 ButtonPressSound->GetPitchMultiplier(), 0.f,
147 ButtonPressSound->AttenuationSettings);
148}
149
150void AInteractionButton::ButtonRelease_Implementation()
151{
153 TimelineDirection = ETimelineDirection::Backward;
154 MovingButtonTimeLine.ReverseFromEnd();
155}
156
157void AInteractionButton::OnBeginOverlapButton(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor,
158 UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep,
159 const FHitResult& SweepResult)
160{
162 {
163 return;
164 }
165
166 if (APixoVRHand* Hand = Cast<APixoVRHand>(OtherActor))
167 {
168 if (Hand->HandMotionSource == EControllerHand::Left)
169 {
170 PlayerController = Cast<APlayerController>(Hand->OwningCharacter->GetController());
171 const FForceFeedbackParameters ForceFeedbackParameters;
172 PlayerController->ClientPlayForceFeedback(LeftHandFeedbackEffect, ForceFeedbackParameters);
173 }
174 else if (Hand->HandMotionSource == EControllerHand::Right)
175 {
176 PlayerController = Cast<APlayerController>(Hand->OwningCharacter->GetController());
177 const FForceFeedbackParameters ForceFeedbackParameters;
178 PlayerController->ClientPlayForceFeedback(RightHandFeedbackEffect, ForceFeedbackParameters);
179 }
180 else
181 {
182 return;
183 }
184
185 ButtonPress();
186 }
187}
188
190{
191 ButtonMovingComp->SetRelativeLocation(FVector(ButtonMovingComp->GetRelativeLocation().X, Value,
192 ButtonMovingComp->GetRelativeLocation().Z));
193}
194
196{
197 switch (TimelineDirection)
198 {
199 case ETimelineDirection::Forward:
201 break;
202
203 case ETimelineDirection::Backward:
205 {
207 }
209 bIsPressed = false;
210 break;
211
212 default:
213 break;
214 }
215}
EButtonState
Enumeration defining the possible states of the button.
@ BS_Disabled
Disabled state.
@ BS_Pressed
Pressed state.
@ BS_Default
Default state.
Represents an interaction button actor.
bool bIsButtonHaveText
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Setup)
void MovingButtonTimelineFinished()
Event handler for the finished state of the moving button timeline.
void MovingButtonTimelineProgress(float Value)
Event handler for the progress of the moving button timeline.
bool bIsPressed
Indicates whether the button is currently pressed.
UBoxComponent * BoxCollisionComp
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Components)
UPointLightComponent * PointLightComp
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Components)
APlayerController * PlayerController
UPROPERTY()
FName ButtonText
UPROPERTY(Replicated, EditAnywhere, BlueprintReadOnly, Category = Setup, meta = (EditCondition = "bIs...
virtual void Tick(float DeltaTime) override
USoundBase * ButtonPressSound
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Setup)
void SetButtonVisibility(bool bVisible)
Sets the visibility of the button.
EButtonState CurrentButtonState
The current state of the button.
EButtonState GetButtonState() const
Gets the current state of the button.
void SetButtonState(EButtonState InButtonState)
Sets the state of the button.
UForceFeedbackEffect * RightHandFeedbackEffect
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Setup)
UForceFeedbackEffect * LeftHandFeedbackEffect
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Setup)
UStaticMeshComponent * ButtonSupportComp
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Components)
FTimeline MovingButtonTimeLine
Timeline for the movement of the button.
void ButtonRelease()
Event called when button was released. Overload it when you want to add functionality.
UCurveFloat * MovingButtonCurve
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = Setup)
void ButtonPress()
Event called when button was pressed. Overload it when you want to add functionality.
virtual void BeginPlay() override
TEnumAsByte< ETimelineDirection::Type > TimelineDirection
UPROPERTY()
FButtonReleasedDelegate ButtonReleasedDelegate
UPROPERTY(BlueprintAssignable)
void SetButtonName(const FName &InButtonName)
Sets the name of the button (will be displayed on TextRenderComp).
FButtonPressedDelegate ButtonPressedDelegate
UPROPERTY(BlueprintAssignable)
virtual void GetLifetimeReplicatedProps(TArray< FLifetimeProperty > &OutLifetimeProps) const override
UStaticMeshComponent * ButtonMovingComp
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Components)
UTextRenderComponent * TextRenderComp
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = Components)
void OnBeginOverlapButton(UPrimitiveComponent *OverlappedComponent, AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
UFUNCTION()
APixoVRHand is an actor class that represents a hand in the VR environment.
Definition PixoVRHand.h:99