1"use strict";(self.webpackChunkmy_website=self.webpackChunkmy_website||[]).push([[1283],{3320:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_ChestInteractionStateTree-9906e085457989101e49316bc706380e.png"},8779:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_UpdateInteractionStageData-ccdd111ab32e939a98c3ed8bd99d17cd.png"},20333:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_SetCustomDepthDataView-1c8f14a6f82cb4df67cfdd58125f37c7.png"},28453:(e,t,n)=>{n.d(t,{R:()=>r,x:()=>o});var a=n(96540);const s={},i=a.createContext(s);function r(e){const t=a.useContext(i);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function o(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:r(e.components),a.createElement(i.Provider,{value:t},e.children)}},30696:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_GiveAbilitySetTask-9d389454d4a63a1a850f0bc49591f0f7.png"},54199:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_SetCustomDepthStencilTask-805702f15d6a60fcd6514ea9eff9f2e1.png"},67384:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_UpdateStageInteractionVariables-bf722b16a8aff8344f29140798a3b5a7.png"},68763:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>o,default:()=>h,frontMatter:()=>r,metadata:()=>a,toc:()=>d});const a=JSON.parse('{"id":"Staged-Interaction-System/HandlingTheInteractionResults","title":"Handing the Interaction Results","description":"Now that we know how we add our interaction stages to the interactables, we now ready to use the runtime stage information to effect our game world.","source":"@site/docs/Staged-Interaction-System/HandlingTheInteractionResults.md","sourceDirName":"Staged-Interaction-System","slug":"/Staged-Interaction-System/HandlingTheInteractionResults","permalink":"/docs/Staged-Interaction-System/HandlingTheInteractionResults","draft":false,"unlisted":false,"tags":[],"version":"current","sidebarPosition":4,"frontMatter":{"sidebar_position":4},"sidebar":"tutorialSidebar","previous":{"title":"Using Stage Interaction","permalink":"/docs/Staged-Interaction-System/UsingStageInteraction"},"next":{"title":"Finally","permalink":"/docs/Staged-Interaction-System/FinalWords"}}');var s=n(74848),i=n(28453);const r={sidebar_position:4},o="Handing the Interaction Results",c={},d=[{value:"State Trees For Handling Interaction Stages",id:"state-trees-for-handling-interaction-stages",level:2},{value:"Showcase",id:"showcase",level:3},{value:"Keypoints",id:"keypoints",level:4},{value:"State Tree Conditions",id:"state-tree-conditions",level:4},{value:"State Tree Interaction Tasks",id:"state-tree-interaction-tasks",level:4}];function l(e){const t={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",h4:"h4",header:"header",hr:"hr",img:"img",li:"li",p:"p",strong:"strong",ul:"ul",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.header,{children:(0,s.jsx)(t.h1,{id:"handing-the-interaction-results",children:"Handing the Interaction Results"})}),"\n",(0,s.jsx)(t.p,{children:"Now that we know how we add our interaction stages to the interactables, we now ready to use the runtime stage information to effect our game world."}),"\n",(0,s.jsxs)(t.p,{children:["As said in the ",(0,s.jsx)(t.strong,{children:"Setup"}),", you can use the ",(0,s.jsx)(t.em,{children:"On Player Gameplay Interaction Stage Changed"})," or ",(0,s.jsx)(t.em,{children:"On Player Indication Indication Changed"})," events on the ",(0,s.jsx)(t.em,{children:"Stage Gameplay Interactable"})," to handle these interactions in blueprints. If so you can create a nested if-else conditions to handle each case of the interaction."]}),"\n",(0,s.jsx)(t.p,{children:"Such as:"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"Is Player Near?"}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"Is Player Looking at the Actor?"}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsx)(t.p,{children:"Is Someone else interacting?"}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["This is completely achievable using the delegates and the current states of the ",(0,s.jsx)(t.em,{children:"gameplay"})," and ",(0,s.jsx)(t.em,{children:"indication"})," stages. But if your interaction system is a complex or multiplayer, this can be hard to manage."]}),"\n",(0,s.jsxs)(t.p,{children:[(0,s.jsx)(t.em,{children:"Data Structure of Stages that are holded per interactor."}),"\n",(0,s.jsx)(t.img,{alt:"DataStructureOfInteractionStages",src:n(83294).A
1+"",width:"1433",height:"642"})]}),"\n",(0,s.jsx)(t.h2,{id:"state-trees-for-handling-interaction-stages",children:"State Trees For Handling Interaction Stages"}),"\n",(0,s.jsxs)(t.p,{children:["Instead of using if else statements, I recommend you to use ",(0,s.jsx)(t.a,{href:"https://dev.epicgames.com/documentation/en-us/unreal-engine/state-tree-in-unreal-engine",children:"State Trees"})," to handle the stage updates. State trees can be added to any Actor and has a clear view of nested conditions. Which is perfect match for this framework."]}),"\n",(0,s.jsx)(t.admonition,{title:"Video Showcase",type:"tip",children:(0,s.jsxs)(t.p,{children:["If you want to see a working example of implementing a state tree for stage interaction system, please check out this ",(0,s.jsx)(t.a,{href:"https://youtu.be/N_uTlWtp7rg?si=3kOuyNfDsfCJCaPx",children:"Overview Video"})," of this plugin."]})}),"\n",(0,s.jsx)(t.h3,{id:"showcase",children:"Showcase"}),"\n",(0,s.jsxs)(t.p,{children:["This showcase will try to explain the use case of a ",(0,s.jsx)(t.em,{children:"State Tree"})," for handling Interactions."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.em,{children:"Interaction handling example of a Lootable Chest"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"ChestInteractionStateTree",src:n(3320).A+"",width:"2156",height:"1756"})}),"\n",(0,s.jsx)(t.h4,{id:"keypoints",children:"Keypoints"}),"\n",(0,s.jsxs)(t.ul,{children:["\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Create a State Tree with ",(0,s.jsx)(t.em,{children:"State Tree Actor Component"})," schema."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Attach a ",(0,s.jsx)(t.em,{children:"State Tree Actor Component"})," to your interactable actor."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Create a ",(0,s.jsx)(t.em,{children:"State Tree Task"})," named ",(0,s.jsx)(t.em,{children:"STT_UpdateInteractionStageData"}),"."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["In the ",(0,s.jsx)(t.em,{children:"STT_UpdateInteractionStageData"})," create an ",(0,s.jsx)(t.em,{children:"Actor"})," variable inside the ",(0,s.jsx)(t.em,{children:"Context"})," so we can get the interactable reference. And create two variables under ",(0,s.jsx)(t.em,{children:"Output"})," category: ",(0,s.jsx)(t.em,{children:"Current Local Interaction Stage"})," as ",(0,s.jsx)(t.code,{children:"FGameplayTag"})," and ",(0,s.jsx)(t.em,{children:"Current Gameplay Interaction Stage"})," as ",(0,s.jsx)(t.code,{children:"FStageBasedGameplayInteractableInteractionData"}),".\n",(0,s.jsx)(t.img,{alt:"UpdateStageInteractionVariables",src:n(67384).A+"",width:"1810",height:"294"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["Then get your interactable actor on the ",(0,s.jsx)(t.code,{children:"Event Enter State"})," and bind interaction update events like following. Than send a ",(0,s.jsx)(t.code,{children:"State Tree Event"})," whenever an interaction event happens.\n",(0,s.jsx)(t.img,{alt:"UpdateInteractionStageData",src:n(8779).A+"",width:"2398",height:"1136"})]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["On your State Tree's ",(0,s.jsx)(t.code,{children:"Global Tasks"})," add the Task that we have created and make sure that variables are correctly referenced."]}),"\n"]}),"\n",(0,s.jsxs)(t.li,{children:["\n",(0,s.jsxs)(t.p,{children:["On the ",(0,s.jsx)(t.code,{children:"Root State"}),"'s Transition, add an ",(0,s.jsx)(t.em,{children:"Event Transition"})," and set it's required event tag with the same tag that you have defined on your global task and set the ",(0,s.jsx)(t.code,{children:"Transition To"})," ",(0,s.jsx)(t.code,{children:"Root"}),". This way whenever an Interaction Stage gets updated, State Tree will reevalute itself."]}),"\n"]}),"\n"]}),"\n",(0,s.jsxs)(t.p,{children:["Then you are set! You can create your custom ",(0,s.jsx)(t.code,{children:"State Tree Conditions"})," and ",(0,s.jsx)(t.code,{children:"State Tree Tasks"})," to handle your interaction stages. I will show you my State Tree Conditions and few State Tree Tasks so it may give your few more ideas."]}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h4,{id:"state-tree-conditions",children:"State Tree Conditions"}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Is There Any Gameplay Interaction?"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"IsThereAnyGameplayInteraction",src:n(71069).A+"",width:"2776",height:"678"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Does Container Matches Query"})}),"\n",(0,s.jsx)(t.p,{children:"This is an Unreal Engine's build-in condition actually."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"DoesContainerMatchesQuery",src:n(72640).A+"",width:"2312",height:"498"})}),"\n",(0,s.jsxs)(t.p,{children:["There are few other conditions but I belive you got the idea. After you have the actual ",(0,s.jsx)(t.em,{children:"Interaction Stage"})," structs, you are able to create any type of condition on your state trees!"]}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.h4,{id:"state-tree-interaction-tasks",children:"State Tree Interaction Tasks"}),"\n",(0,s.jsx)(t.p,{children:"In here you activate actors, add outlines, grant-activate abilities on your instigators etc. Both gameplay and indication interactions can be achieved here."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Give Ability Set To Interactors"})}),"\n",(0,s.jsxs)(t.p,{children:["This example is very game specific but it demonstrates that you can get the ",(0,s.jsx)(t.em,{children:"Interactors"})," and do stuff with them whenever they interact."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Add Gameplay Ability Set To Interactor",src:n(30696).A+"",width:"2926",height:"644"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.strong,{children:"Set The Interactable's Custom Depth Stencil Value"})}),"\n",(0,s.jsxs)(t.p,{children:["This a good example to demonstrate why you should make your tasks modular. It is very easy to bind stencil value's to integers so that your different ",(0,s.jsx)(t.em,{children:"States"})," can use the same tasks but with different values."]}),"\n",(0,s.jsx)(t.p,{children:"In this example I use my stencil values to create outlines around my interactables with different c
1olors based on the stencil value."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Set Custom Stencil Value",src:n(54199).A+"",width:"2856",height:"960"})}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.img,{alt:"Set Custom Depth Data View",src:n(20333).A+"",width:"1284",height:"288"})}),"\n",(0,s.jsx)(t.hr,{}),"\n",(0,s.jsx)(t.p,{children:"I believe that is it for the examples. As you can see this part is very game dependent. I think that this the most fun, optimized, modular way to create interaction handling. So I wish you good luck to create your state tree logic!"})]})}function h(e={}){const{wrapper:t}={...(0,i.R)(),...e.components};return t?(0,s.jsx)(t,{...e,children:(0,s.jsx)(l,{...e})}):l(e)}},71069:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_STC_IsThereAnyGameplayInteraction-b061f01ccf24f6d1c135b3285f154c29.png"},72640:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_STC_DoesContainerMatchesQuery-61e4b57ccd224c6b52d01577e0aefc60.png"},83294:(e,t,n)=>{n.d(t,{A:()=>a});const a=n.p+"assets/images/T_StageInteractionValueTypes-62a08135e4169cbf39c95745c29eba8a.png"}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.