完成场景中有一个东西,点击后交互,然后加到背包中,就算OK
另外,地上的枪的获得不是这一套东西
交互物的创建
/Game/Items/B_InteractableRock.B_InteractableRock
创建这个物品,添加StaticMesh 随便加一个mesh。设置碰撞预设自定义,注意 Lyra_TraceChannel_Interaction改成Overlap,这样可以被相关的检测检测到。其他Block
然后我们需要配置交互技能,获得的物品。
- 物品
这是/Game/Items/TestID_Rock.TestID_Rock 物品定义蓝图,父类是UEqZeroInventoryItemDefinition
他只配置了显示的名字,没有片段,只是一个普通的物品
- 获得物品的技能
首先是TAG,激活Block配置了 Movement.Mode.Falling 下落不让激活
配置Trigger是 Ability.Interaction.Activate,用这个TAG可以激活这个技能。
具体逻辑等等写吧,先空着
然后把Item丢到场景中
体验中的交互技能
/EqZeroCore/Experiences/LAS_InventoryTest.LAS_InventoryTest
这是哪个体检的Action Set
这里面要配置一些东西
输入Input Mapping Context 和 Input Action => TAG 的配置
开始配置
/Game/Input/Mappings/IMC_Inventory.IMC_Inventory
/Game/Input/Actions/IA_Interact.IA_Interact
只是一个非常简单的G键交互。
/Game/Input/InputData_Inventory.InputData_Inventory
这是那个 Input Action => TAG 的配置
/Game/Input/Abilities/AbilitySet_Inventory.AbilitySet_Inventory
这里关联了交互技能 GA_Interact 这个,就是哪个扫描交互物的哪个技能。
到这里,允许后,显示范围
EqZero.Interaction.DebugScan 1
调试一下,拿到这个技能了
if (!InteractionAbilityCache.Find(ObjectKey))
{
FGameplayAbilitySpec Spec(Option.InteractionAbilityToGrant, 1, INDEX_NONE, this);
FGameplayAbilitySpecHandle Handle = AbilitySystemComponent->GiveAbility(Spec);
InteractionAbilityCache.Add(ObjectKey, Handle);
}
但是这个技能好像不打算删除了

靠近后多了一个交互技能
暂时怎么写,射线检测,在激活的时候,和有输入的时候进行一次,后面接入一个print

【图1】
按G,触发交互

【图2】
这个wait input 为什么是G呢?
我们在 UEqZeroAbilitySystemComponent::ProcessAbilityInput 里面
按键激活的时候手动设置了 AbilitySpec->InputPressed = true;
这时候触发获得物品的技能,就成功获得物品了。但是我们还差点逻辑。
在上面图1,扫描的的时候,找到了交互物打印,的地方。原来的逻辑是更新显示一个UI,然后把这个交互物丢到一个容器里面。然后图2的触发交互,才能从这个Option里面拿到交互技能。
图1的UI更新先不管吧。先写Option的缓存逻辑。
哦,就一行
void UEqZeroGameplayAbility_Interact::UpdateInteractions(const TArray<FInteractionOption>& InteractiveOptions)
{
CurrentOptions = InteractiveOptions;
}
然后按G
void UEqZeroGameplayAbility_Interact::TriggerInteraction()
{
if (CurrentOptions.Num() == 0)
{
return;
}
UAbilitySystemComponent* AbilitySystem = GetAbilitySystemComponentFromActorInfo();
if (AbilitySystem)
{
const FInteractionOption& InteractionOption = CurrentOptions[0];
AActor* Instigator = GetAvatarActorFromActorInfo();
AActor* InteractableTargetActor = UInteractionStatics::GetActorFromInteractableTarget(InteractionOption.InteractableTarget);
// 允许目标自定义我们将要传入的事件数据,以防能力需要只有 Actor 才知道的自定义数据。
FGameplayEventData Payload;
Payload.EventTag = TAG_Ability_Interaction_Activate;
Payload.Instigator = Instigator;
Payload.Target = InteractableTargetActor;
// 如果需要,我们允许可交互目标操纵事件数据,例如墙上的按钮可能希望指定一个门 Actor 来执行该能力,因此它可以选择将 Target 覆盖为门 Actor。
InteractionOption.InteractableTarget->CustomizeInteractionEventData(TAG_Ability_Interaction_Activate, Payload);
// 从有效负载中获取目标 Actor,我们将使用它作为交互的 'Avatar',并将源 InteractableTarget Actor 作为拥有者 Actor。
AActor* TargetActor = const_cast<AActor*>(ToRawPtr(Payload.Target));
FGameplayAbilityActorInfo ActorInfo;
ActorInfo.InitFromActor(InteractableTargetActor, TargetActor, InteractionOption.TargetAbilitySystem);
const bool bSuccess = InteractionOption.TargetAbilitySystem->TriggerAbilityFromGameplayEvent(
InteractionOption.TargetInteractionAbilityHandle,
&ActorInfo,
TAG_Ability_Interaction_Activate,
&Payload,
*InteractionOption.TargetAbilitySystem
);
}
}
然后试试 GA_Interact_Collect 能不能被激活,print一下
成功了。
完成这个技能蓝图,服务器加物品。
截图略。。。后续写成代码 TODO
看看这个断点能不能达到。
UEqZeroInventoryItemInstance* UEqZeroInventoryManagerComponent::AddItemDefinition(TSubclassOf<UEqZeroInventoryItemDefinition> ItemDef, int32 StackCount)
{
UEqZeroInventoryItemInstance* Result = nullptr;
if (ItemDef != nullptr)
{
Result = InventoryList.AddEntry(ItemDef, StackCount);
if (IsUsingRegisteredSubObjectList() && IsReadyForReplication() && Result)
{
AddReplicatedSubObject(Result);
}
}
return Result;
}
物品组件没配置。这个是通过GameFeature的 Actions 挂到 Controller上的
配置好,断点一下,成功获得物品。
完成Cue,然后交互动画蒙太奇配置一个近战动画
这个Cue配置下TAG和 Unique Instance Per Insigator 打勾
这个Cue先用TimeLine做一个简单的缩小吧。
交互系统OK,后续再补。