인터렉션 시스템
https://docs.unrealengine.com/5.2/ko/lyra-sample-game-interaction-system-in-unreal-engine/
라이라 인터렉션 시스템
LyraGameplayAbility_Interact 클래스
- interaction을 어떻게 호출할지에 관한 로직 관리
#pragma once
#include "CoreMinimal.h"
#include "AbilitySystem/Abilities/LyraGameplayAbility.h"
#include "Interaction/InteractionQuery.h"
#include "Interaction/IInteractableTarget.h"
#include "LyraGameplayAbility_Interact.generated.h"
class FIndicatorDescriptor;
/**
* ULyraGameplayAbility_Interact
*
* 캐릭터 상호작용에 사용되는 게임플레이 어빌리티
*/
UCLASS(Abstract)
class ULyraGameplayAbility_Interact : public ULyraGameplayAbility
{
GENERATED_BODY()
public:
void UpdateInteractions(const TArray<FInteractionOption>& InteractiveOptions);
void TriggerInteraction();
protected:
TArray<FInteractionOption> CurrentOptions;
TArray<TSharedRef<FIndicatorDescriptor>> Indicators;
protected:
float InteractionScanRate = 0.1f;
float InteractionScanRange = 500;
TSoftClassPtr<UUserWidget> DefaultInteractionWidgetClass;
};
```
상호작용 가능한 타깃(InteractableTarget) - IInteractableTarget 인터페이스를 구현하는 액터나 컴포넌트로, 월드의 어떤 오브젝트가 상호작용 가능한지 결정합니다.
```cpp
/** */
UINTERFACE(MinimalAPI, meta = (CannotImplementInterfaceInBlueprint))
class UInteractableTarget : public UInterface
{
GENERATED_BODY()
};
/** */
class IInteractableTarget
{
GENERATED_BODY()
public:
/** */
virtual void GatherInteractionOptions(const FInteractionQuery& InteractQuery, FInteractionOptionBuilder& OptionBuilder) = 0;
/** */
virtual void CustomizeInteractionEventData(const FGameplayTag& InteractionEventTag, FGameplayEventData& InOutEventData) { }
};
상호작용 옵션(InteractionOption) - ‘행동 유도성’ 또는 ‘옵션’으로, 예를 들어 사과는 ‘수집’할 수도 있고 ‘사용’할 수도 있습니다.
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/GameplayAbility.h"
#include "InteractionOption.generated.h"
class IInteractableTarget;
class UUserWidget;
/** */
USTRUCT(BlueprintType)
struct FInteractionOption
{
GENERATED_BODY()
public:
/** The interactable target */
UPROPERTY(BlueprintReadWrite)
TScriptInterface<IInteractableTarget> InteractableTarget;
/** Simple text the interaction might return */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FText Text;
/** Simple sub-text the interaction might return */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
FText SubText;
// METHODS OF INTERACTION
//--------------------------------------------------------------
// 1) Place an ability on the avatar that they can activate when they perform interaction.
/** The ability to grant the avatar when they get near interactable objects. */
UPROPERTY(EditAnywhere, BlueprintReadOnly)
TSubclassOf<UGameplayAbility> InteractionAbilityToGrant;
// - OR -
// 2) Allow the object we're interacting with to have its own ability system and interaction ability, that we can activate instead.
/** The ability system on the target that can be used for the TargetInteractionHandle and sending the event, if needed. */
UPROPERTY(BlueprintReadOnly)
TObjectPtr<UAbilitySystemComponent> TargetAbilitySystem = nullptr;
/** The ability spec to activate on the object for this option. */
UPROPERTY(BlueprintReadOnly)
FGameplayAbilitySpecHandle TargetInteractionAbilityHandle;
// UI
//--------------------------------------------------------------
/** The widget to show for this kind of interaction. */
UPROPERTY(EditAnywhere, BlueprintReadWrite)
TSoftClassPtr<UUserWidget> InteractionWidgetClass;
//--------------------------------------------------------------
public:
FORCEINLINE bool operator==(const FInteractionOption& Other) const
{
return InteractableTarget == Other.InteractableTarget &&
InteractionAbilityToGrant == Other.InteractionAbilityToGrant&&
TargetAbilitySystem == Other.TargetAbilitySystem &&
TargetInteractionAbilityHandle == Other.TargetInteractionAbilityHandle &&
InteractionWidgetClass == Other.InteractionWidgetClass &&
Text.IdenticalTo(Other.Text) &&
SubText.IdenticalTo(Other.SubText);
}
FORCEINLINE bool operator!=(const FInteractionOption& Other) const
{
return !operator==(Other);
}
FORCEINLINE bool operator<(const FInteractionOption& Other) const
{
return InteractableTarget.GetInterface() < Other.InteractableTarget.GetInterface();
}
};
상호작용 유발자(InteractionInstigator) - 인터랙션을 개시하는 폰(LyraPawnActor)입니다. 이 폰은 옵션과 표시 방식을 더 자세히 커스터마이징할 수 있는 IInteractionInstigator 인터페이스를 구현할 수도, 구현하지 않을 수도 있습니다.
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/GameplayAbility.h"
#include "InteractionOption.h"
#include "IInteractionInstigator.generated.h"
struct FInteractionQuery;
/** */
UINTERFACE(MinimalAPI, meta = (CannotImplementInterfaceInBlueprint))
class UInteractionInstigator : public UInterface
{
GENERATED_BODY()
};
/**
* Implementing this interface allows you to add an arbitrator to the interaction process. For example,
* some games present the user with a menu to pick which interaction they want to perform. This will allow you
* to take the multiple matches (Assuming your ULyraGameplayAbility_Interact subclass generates more than one option).
*/
class IInteractionInstigator
{
GENERATED_BODY()
public:
/** Will be called if there are more than one InteractOptions that need to be decided on. */
virtual FInteractionOption ChooseBestInteractionOption(const FInteractionQuery& InteractQuery, const TArray<FInteractionOption>& InteractOptions) = 0;
};
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/GameplayAbility.h"
#include "InteractionQuery.generated.h"
/** */
USTRUCT(BlueprintType)
struct FInteractionQuery
{
GENERATED_BODY()
public:
/** The requesting pawn. */
UPROPERTY(BlueprintReadWrite)
TWeakObjectPtr<AActor> RequestingAvatar;
/** Allow us to specify a controller - does not need to match the owner of the requesting avatar. */
UPROPERTY(BlueprintReadWrite)
TWeakObjectPtr<AController> RequestingController;
/** A generic UObject to shove in extra data required for the interaction */
UPROPERTY(BlueprintReadWrite)
TWeakObjectPtr<UObject> OptionalObjectData;
};
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "InteractionStatics.generated.h"
template <typename InterfaceType> class TScriptInterface;
class AActor;
class IInteractableTarget;
class UObject;
struct FFrame;
struct FHitResult;
struct FOverlapResult;
/** */
UCLASS()
class UInteractionStatics : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UInteractionStatics();
public:
UFUNCTION(BlueprintCallable)
static AActor* GetActorFromInteractableTarget(TScriptInterface<IInteractableTarget> InteractableTarget);
UFUNCTION(BlueprintCallable)
static void GetInteractableTargetsFromActor(AActor* Actor, TArray<TScriptInterface<IInteractableTarget>>& OutInteractableTargets);
static void AppendInteractableTargetsFromOverlapResults(const TArray<FOverlapResult>& OverlapResults, TArray<TScriptInterface<IInteractableTarget>>& OutInteractableTargets);
static void AppendInteractableTargetsFromHitResult(const FHitResult& HitResult, TArray<TScriptInterface<IInteractableTarget>>& OutInteractableTargets);
};
Leave a comment