Compare commits
5 Commits
388c2ef945
...
e2d5098b45
Author | SHA1 | Date | |
---|---|---|---|
e2d5098b45 | |||
179eacb628 | |||
2a085bbb9c | |||
44e9bc1369 | |||
644083344e |
.gitattributesREADME.md
Audio
Documentation
Game design.docxInteractableProcess.drawioInteractableProcess.pdfLevel design.docxRAI DHF.docxREADME.mdStory.docxTechnical documentation.docxTechnicka dokumentace.docx
Fonts
Images
Models
README.mdReleaseBuilds
UnrealProject/Lost_Edge
Config
Content
Blueprints
Levels/Test
UI
Blueprints
MainMenu
UI_MainMenu.uassetUI_MainMenuCredits.uassetUI_MainMenuOptions.uassetUI_MainMenuOptionsAudio.uassetUI_MainMenuOptionsControls.uassetUI_MainMenuOptionsGame.uassetUI_MainMenuOptionsVideo.uasset
UI_CameraMode.uassetComponents
MainMenu
UIC_MainMenu_OptionsButton.uassetUIC_MainMenu_OptionsCategory.uassetUIC_MainMenu_OptionsComboBox.uassetUIC_MainMenu_OptionsKeySelector.uassetUIC_MainMenu_OptionsSlider.uassetUIC_MainMenu_OptionsSwitchButton.uassetUIC_MainMenu_PageButton.uassetUIC_MainMenu_Title.uasset
UIC_MainMenu_OptionsButton.uassetUIC_MainMenu_OptionsCategory.uassetUIC_MainMenu_OptionsComboBox.uassetUIC_MainMenu_OptionsKeySelector.uassetUIC_MainMenu_OptionsSlider.uassetUIC_MainMenu_OptionsSwitchButton.uassetUIC_MainMenu_PageButton.uassetUIC_MainMenu_Title.uassetSource/Lost_Edge/Private
CameraModeBase.cppCameraModeBase.hCommonFunctions.cppCommonFunctions.hContentLoader.cppContentLoader.hCustomGameInstance.cppCustomGameInstance.hCustomGameInstanceBase.cppCustomGameSettings.cppCustomGameSettings.hCustomGameUserSettings.cppCustomGameUserSettings.hCustomPlayerController.cppCustomPlayerController.hCutsceneManager.cppCutsceneManager.hDialogueManager.cppDialogueManager.h
Interactable
Activators
InCameraInteractableActivator.cppInCameraInteractableActivator.hInteractableActivator.cppInteractableActivator.hInteractableScreenCapturer.cppInteractableScreenCapturer.hRaycastInteractableActivator.cppRaycastInteractableActivator.h
Interactable.cppInteractable.hModificators
ActivateInteractableModificator.cppActivateInteractableModificator.hEditInteractableModificator.cppEditInteractableModificator.hInteractableModificator.cppInteractableModificator.hInventoryInteractableModificator.cppInventoryInteractableModificator.hMoveInteractableModificator.cppMoveInteractableModificator.hSawInteractableModificator.cppSawInteractableModificator.h
Levels
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -1,4 +0,0 @@
|
||||
ReleaseBuilds/** filter=lfs diff=lfs merge=lfs -text
|
||||
Images/** filter=lfs diff=lfs merge=lfs -text
|
||||
Fonts/** filter=lfs diff=lfs merge=lfs -text
|
||||
Audio/** filter=lfs diff=lfs merge=lfs -text
|
3
Audio/.gitattributes
vendored
Normal file
3
Audio/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
./** filter=lfs diff=lfs merge=lfs -text
|
||||
.gitignore -filter
|
||||
.gitattributes -filter
|
Binary file not shown.
@ -1,158 +1,131 @@
|
||||
<mxfile host="app.diagrams.net" modified="2024-05-08T09:39:53.079Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" etag="wAs-_Z6muctMyUQpajhH" version="24.3.1" type="device">
|
||||
<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36" version="25.0.3">
|
||||
<diagram name="Stránka-1" id="jncRwyBWY97r-PTh6Wm3">
|
||||
<mxGraphModel dx="2261" dy="746" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<mxGraphModel dx="1102" dy="527" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-1" value="ContentLoader" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="340" width="120" height="40" as="geometry" />
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-12" value="Component with&nbsp;<span style="background-color: initial;">AInteractable</span><div><span style="background-color: initial;">actors scanning method</span></div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#CCE5FF;" parent="1" vertex="1">
|
||||
<mxGeometry x="208" y="220" width="180" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-2" value="GameInstance" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="340" y="60" width="120" height="40" as="geometry" />
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-7" value="On instantiation creates U<span style="background-color: initial;">InteractableActivator components&nbsp;</span><span style="background-color: initial;">stored in registers</span>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#E6FFCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="558" y="120" width="261" height="41" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-3" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-1" target="OfQ8P6CXFFix212gcqCM-2">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-4" value="On construct call appends its class to AInteractable registers" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#FFFFCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="549" y="30" width="230" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-1" value="UInteractable Activator/Modificator" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="398" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-2" value="AInteractable" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFFFCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="398" y="60" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-3" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" parent="1" source="OfQ8P6CXFFix212gcqCM-1" target="OfQ8P6CXFFix212gcqCM-2" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="390" y="240" as="sourcePoint" />
|
||||
<mxPoint x="440" y="190" as="targetPoint" />
|
||||
<mxPoint x="488" y="240" as="sourcePoint" />
|
||||
<mxPoint x="538" y="190" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-4" value="Appends&nbsp;<span style="background-color: initial;">instance.</span><span style="background-color: initial;">interactionsCollection.</span><div><span style="background-color: initial;">(array of interactable interfaces)</span></div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="460" y="5" width="230" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-5" value="Player" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="340" y="120" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-2" target="OfQ8P6CXFFix212gcqCM-5">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" parent="1" source="OfQ8P6CXFFix212gcqCM-2" target="OfQ8P6CXFFix212gcqCM-5" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="410" y="-10" as="sourcePoint" />
|
||||
<mxPoint x="410" y="70" as="targetPoint" />
|
||||
<mxPoint x="508" y="-10" as="sourcePoint" />
|
||||
<mxPoint x="508" y="70" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-7" value="On instantiation creates InteractableActivator components<div>from `InteractableInterface.GetActivatorsAndCallers()`.</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="460" y="125" width="320" height="30" as="geometry" />
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-8" value="UInteractableActivator" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#CCE5FF;" parent="1" vertex="1">
|
||||
<mxGeometry x="218" y="180" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-8" value="InteractableActivator" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="180" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-9" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-5" target="OfQ8P6CXFFix212gcqCM-8">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-9" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" parent="1" source="OfQ8P6CXFFix212gcqCM-5" edge="1" target="OfQ8P6CXFFix212gcqCM-8">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="410" y="110" as="sourcePoint" />
|
||||
<mxPoint x="410" y="130" as="targetPoint" />
|
||||
<mxPoint x="508" y="111" as="sourcePoint" />
|
||||
<mxPoint x="258" y="181" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-10" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-5" target="OfQ8P6CXFFix212gcqCM-8">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-10" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" parent="1" source="OfQ8P6CXFFix212gcqCM-5" edge="1" target="OfQ8P6CXFFix212gcqCM-8">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="410" y="170" as="sourcePoint" />
|
||||
<mxPoint x="380" y="200" as="targetPoint" />
|
||||
<mxPoint x="508" y="171" as="sourcePoint" />
|
||||
<mxPoint x="258" y="201" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-11" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-5" target="OfQ8P6CXFFix212gcqCM-8">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-11" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;entryX=1;entryY=1;entryDx=0;entryDy=0;" parent="1" source="OfQ8P6CXFFix212gcqCM-5" edge="1" target="OfQ8P6CXFFix212gcqCM-8">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="420" y="180" as="sourcePoint" />
|
||||
<mxPoint x="390" y="210" as="targetPoint" />
|
||||
<mxPoint x="518" y="181" as="sourcePoint" />
|
||||
<mxPoint x="398" y="240" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-12" value="Component with special&nbsp;<div>interactable actor scanning method.</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-160" y="185" width="200" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-15" value="Player.<div>InteractableActivated()</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="120" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-16" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-8" target="OfQ8P6CXFFix212gcqCM-15">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-16" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeWidth=3;" parent="1" edge="1" target="OfQ8P6CXFFix212gcqCM-15" source="OfQ8P6CXFFix212gcqCM-8">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="250" y="170" as="sourcePoint" />
|
||||
<mxPoint x="220" y="200" as="targetPoint" />
|
||||
<mxPoint x="323" y="182" as="sourcePoint" />
|
||||
<mxPoint x="323" y="162" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-18" value="MainGameMode<div>.widgetsManager</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-20" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-15" target="OfQ8P6CXFFix212gcqCM-18">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-20" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeWidth=3;" parent="1" source="OfQ8P6CXFFix212gcqCM-15" target="OfQ8P6CXFFix212gcqCM-18" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="190" y="220" as="sourcePoint" />
|
||||
<mxPoint x="110" y="170" as="targetPoint" />
|
||||
<mxPoint x="548" y="220" as="sourcePoint" />
|
||||
<mxPoint x="468" y="170" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-21" value="<div>Shows interactions hint.</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="-100" y="5" width="140" height="30" as="geometry" />
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-21" value="<div>Show interactions hint</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#FFCCFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="228" y="15" width="140" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-22" value="Player.<div>activatedInteractable</div>" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="340" y="240" width="120" height="40" as="geometry" />
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-28" value="Component with AInteractable modifcator<span style="background-color: initial;">&nbsp;methods</span>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillColor=#FFCCCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="8" y="220" width="180" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-24" value="InteractableCaller" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="180" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-25" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-5" target="OfQ8P6CXFFix212gcqCM-24">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-32" value="" style="endArrow=none;html=1;rounded=0;strokeWidth=3;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" target="OfQ8P6CXFFix212gcqCM-5" edge="1" source="OfQ8P6CXFFix212gcqCM-15">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="410" y="170" as="sourcePoint" />
|
||||
<mxPoint x="330" y="240" as="targetPoint" />
|
||||
<mxPoint x="358" y="150" as="sourcePoint" />
|
||||
<mxPoint x="348" y="110" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-26" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;strokeWidth=3;" edge="1" parent="1" target="OfQ8P6CXFFix212gcqCM-24">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-34" value="UInteractableModificator::[Un]Bind()&nbsp;<span style="background-color: initial;">player's input</span>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFCCCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="18" y="120" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-35" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.25;exitY=0;exitDx=0;exitDy=0;strokeWidth=3;entryX=0.25;entryY=1;entryDx=0;entryDy=0;" parent="1" source="OfQ8P6CXFFix212gcqCM-24" target="OfQ8P6CXFFix212gcqCM-34" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="400" y="160" as="sourcePoint" />
|
||||
<mxPoint x="490" y="200" as="targetPoint" />
|
||||
<mxPoint x="-22" y="-37" as="sourcePoint" />
|
||||
<mxPoint x="73" y="141.75" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-27" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=1;entryDx=0;entryDy=0;strokeWidth=3;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-5" target="OfQ8P6CXFFix212gcqCM-24">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-36" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=0;exitDx=0;exitDy=0;strokeWidth=3;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" parent="1" source="OfQ8P6CXFFix212gcqCM-24" target="OfQ8P6CXFFix212gcqCM-34" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="410" y="170" as="sourcePoint" />
|
||||
<mxPoint x="490" y="220" as="targetPoint" />
|
||||
<mxPoint x="88" y="83" as="sourcePoint" />
|
||||
<mxPoint x="118" y="161.75" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-28" value="Component with special&nbsp;<div>input processing method.</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="740" y="185" width="150" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-29" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=1;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-15" target="OfQ8P6CXFFix212gcqCM-22">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-37" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.75;exitY=0;exitDx=0;exitDy=0;strokeWidth=3;entryX=0.75;entryY=1;entryDx=0;entryDy=0;" parent="1" source="OfQ8P6CXFFix212gcqCM-24" target="OfQ8P6CXFFix212gcqCM-34" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="270" y="200" as="sourcePoint" />
|
||||
<mxPoint x="270" y="170" as="targetPoint" />
|
||||
<mxPoint x="118" y="83" as="sourcePoint" />
|
||||
<mxPoint x="158" y="161.75" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-32" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-15" target="OfQ8P6CXFFix212gcqCM-5">
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-5" value="APlayerBase" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#E6FFCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="398" y="120" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-24" value="UInteractableModificator" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFCCCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="18" y="180" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="dr_dVIBuduT0epV415MF-4" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;strokeWidth=3;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-15" target="OfQ8P6CXFFix212gcqCM-24">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="110" y="200" as="sourcePoint" />
|
||||
<mxPoint x="110" y="170" as="targetPoint" />
|
||||
<mxPoint x="133" y="131" as="sourcePoint" />
|
||||
<mxPoint x="133" y="89" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-33" value="Player.<div>EnableInteractableCallers</div><div>ByInteractableImplemented</div><div>InteractionInterfaces</div>" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="170" y="60" width="150" height="70" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-34" value="InputEvents" style="rounded=0;whiteSpace=wrap;html=1;" vertex="1" parent="1">
|
||||
<mxGeometry x="620" y="240" width="120" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-35" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.25;entryY=0;entryDx=0;entryDy=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-24" target="OfQ8P6CXFFix212gcqCM-34">
|
||||
<mxCell id="dr_dVIBuduT0epV415MF-5" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;strokeWidth=3;entryX=1;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-15" target="OfQ8P6CXFFix212gcqCM-24">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="550" y="110" as="sourcePoint" />
|
||||
<mxPoint x="550" y="130" as="targetPoint" />
|
||||
<mxPoint x="248" y="151" as="sourcePoint" />
|
||||
<mxPoint x="168" y="151" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-36" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-24" target="OfQ8P6CXFFix212gcqCM-34">
|
||||
<mxCell id="dr_dVIBuduT0epV415MF-6" value="" style="endArrow=classic;html=1;rounded=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;strokeWidth=3;entryX=1;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-15" target="OfQ8P6CXFFix212gcqCM-24">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="660" y="230" as="sourcePoint" />
|
||||
<mxPoint x="660" y="250" as="targetPoint" />
|
||||
<mxPoint x="248" y="151" as="sourcePoint" />
|
||||
<mxPoint x="168" y="171" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-37" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.75;entryY=0;entryDx=0;entryDy=0;exitX=0.75;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-24" target="OfQ8P6CXFFix212gcqCM-34">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="690" y="230" as="sourcePoint" />
|
||||
<mxPoint x="690" y="250" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-15" value="APlayerBase::<div>Interactable[<span style="background-color: initial;">De]</span><span style="background-color: initial;">Activated()</span></div>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#E6FFCC;" parent="1" vertex="1">
|
||||
<mxGeometry x="218" y="120" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-38" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0;entryDx=0;entryDy=0;exitX=0;exitY=0;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-34" target="OfQ8P6CXFFix212gcqCM-22">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="520" y="230" as="sourcePoint" />
|
||||
<mxPoint x="520" y="250" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-40" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=1;entryDx=0;entryDy=0;exitX=0;exitY=1;exitDx=0;exitDy=0;strokeWidth=3;" edge="1" parent="1" source="OfQ8P6CXFFix212gcqCM-34" target="OfQ8P6CXFFix212gcqCM-22">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="490" y="270" as="sourcePoint" />
|
||||
<mxPoint x="470" y="270" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-41" value="<div>Interactable</div>.Call(InputDescription)" style="text;html=1;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="460" y="245" width="160" height="30" as="geometry" />
|
||||
<mxCell id="OfQ8P6CXFFix212gcqCM-18" value="AMainGameModeBase::<div>widgetsManager</div>" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#FFCCFF;" parent="1" vertex="1">
|
||||
<mxGeometry x="218" y="45" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
|
Binary file not shown.
Binary file not shown.
BIN
Documentation/RAI DHF.docx
Normal file
BIN
Documentation/RAI DHF.docx
Normal file
Binary file not shown.
3
Documentation/README.md
Normal file
3
Documentation/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# Documentation
|
||||
The always actual documentation is on [google drive](https://drive.google.com/drive/folders/1o40kh_8BgrMI3BzPyfNT0ZLG_5mrIjEy?usp=sharing). \
|
||||
There is only a dump/backup.
|
Binary file not shown.
BIN
Documentation/Technical documentation.docx
Normal file
BIN
Documentation/Technical documentation.docx
Normal file
Binary file not shown.
Binary file not shown.
3
Fonts/.gitattributes
vendored
Normal file
3
Fonts/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
./** filter=lfs diff=lfs merge=lfs -text
|
||||
.gitignore -filter
|
||||
.gitattributes -filter
|
3
Images/.gitattributes
vendored
Normal file
3
Images/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
./** filter=lfs diff=lfs merge=lfs -text
|
||||
.gitignore -filter
|
||||
.gitattributes -filter
|
0
.gitignore → Images/.gitignore
vendored
0
.gitignore → Images/.gitignore
vendored
3
Models/.gitattributes
vendored
Normal file
3
Models/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
./** filter=lfs diff=lfs merge=lfs -text
|
||||
.gitignore -filter
|
||||
.gitattributes -filter
|
1
Models/.gitignore
vendored
Normal file
1
Models/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
*.blend1
|
34
README.md
34
README.md
@ -1,15 +1,31 @@
|
||||
# Repo structure
|
||||
This repository contains all sources and data. The current unreal project is located in UnrealProject/Lost_Edge/.
|
||||
This repository contains all sources and data for project Lost_Edge excluding server and network deploy configs. \
|
||||
Most of subdirectories represents individual modules and contains their own README.
|
||||
|
||||
# Documentation
|
||||
Actualised documentation is on [google drive](https://drive.google.com/drive/folders/1o40kh_8BgrMI3BzPyfNT0ZLG_5mrIjEy?usp=sharing).
|
||||
Lost_Edge/ \
|
||||
├─ [Audio/](Audio) ---> Audio data (e.g. music, sounds, dialogues) \
|
||||
├─ [Documentation/](Documentation) ---> Documentation (e.g. game and level design) \
|
||||
├─ [Fonts/](Fonts) ---> Fonts used in project \
|
||||
├─ [Images/](Images) ---> Image data (e.g. textures, postures, logo) \
|
||||
├─ [Models/](Models) ---> Models data (e.g. characters, decorations, foliages) \
|
||||
├─ [ReleaseBuilds/](ReleaseBuilds) \
|
||||
│ ├─ Legacy/ ---> Legacy build created as high school project \
|
||||
│ └─ vX.X/ ---> Current builds of Lost_Edge (university project) \
|
||||
├─ UnrealProject/ \
|
||||
│ ├─ [Lost_Edge/](UnrealProject/Lost_Edge) ---> Current unreal project of Lost_Edge \
|
||||
│ └─ Lost_Edge_Legacy/ ---> Legacy unreal project created as high school project \
|
||||
└─[VoiceGenerator/](VoiceGenerator) ---> AI voice generation module
|
||||
|
||||
# How to compile
|
||||
It's recommended to work in Unreal Engine 5.4 and to install Visual Studio with the necessary packages as it described in the [official documentation](https://dev.epicgames.com/documentation/en-us/unreal-engine/setting-up-visual-studio-development-environment-for-cplusplus-projects-in-unreal-engine) (recommended settings aren't needed). \
|
||||
After repo cloning, the Visual Studio project files needs to be generated. It can be done in the explorer RMB context menu of file "UnrealProject/Lost_Edge/Lost_Edge.uproject". Or by typing "%UE5PATH%\Engine\Build\BatchFiles\GenerateProjectFiles.bat" "%REPOPATH%\UnrealProject\Lost_Edge\Lost_Edge.uproject". \
|
||||
After generating, "Lost_Edge.sln" can be opened and project can start building for the first time, which will fail. This is because of using OpenCV plugin that together with UnrealEngine implement their own "check()" function. This error can be used to determine that in the file "%UE5PATH%\Engine\Plugins\Runtime\OpenCV\Source\ThirdParty\OpenCV\include\opencv2\core\utility.hpp" it is necessary to comment out the warning macro on lines 52-54 and rename the function itself on line 957 to, for example, "checkcv()".
|
||||
After this modification, the build should run fine and it is possible to open the project in UnrealEngine.
|
||||
# Building your own project copy
|
||||
Building a copy of the game requires only [UnrealProject/LostEdge/](UnrealProject/Lost_Edge) directory. \
|
||||
For that purposes you can download the directory as archive or do a sparse checkout via commands below.
|
||||
- git clone --no-checkout https://pixelyfier.com/git/Pixelyfier/Lost_Edge.git
|
||||
- cd Lost_Edge/
|
||||
- git sparse-checkout init
|
||||
- git sparse-checkout set UnrealProject/Lost_Edge
|
||||
- git checkout master
|
||||
|
||||
# Git lfs common issues
|
||||
The download can be sometimes too long which make git lfs drop the connection with error "LFS: Put "https://pixelyfier.com/git/Pixelyfier/Lost_Edge.git/info/lfs/objects/HASH": read tcp IP:PORT->pixelyfier.com:443: i/o timeout" \
|
||||
The download can be sometimes too long which makes git lfs drop the connection with error \
|
||||
`"LFS: Put "https://pixelyfier.com/git/Pixelyfier/Lost_Edge.git/info/lfs/objects/HASH": read tcp IP:PORT->pixelyfier.com:443: i/o timeout"`
|
||||
- To fix this set local/global repo config `git config lfs.activitytimeout 240`
|
||||
|
3
ReleaseBuilds/.gitattributes
vendored
Normal file
3
ReleaseBuilds/.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
./** filter=lfs diff=lfs merge=lfs -text
|
||||
.gitignore -filter
|
||||
.gitattributes -filter
|
@ -84,7 +84,7 @@ CommandletClass=Class'/Script/UnrealEd.WorldPartitionConvertCommandlet'
|
||||
+ActiveGameNameRedirects=(OldGameName="TP_Blank",NewGameName="/Script/Lost_Edge")
|
||||
+ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/Lost_Edge")
|
||||
+ActiveClassRedirects=(OldClassName="TP_BlankGameModeBase",NewClassName="Lost_EdgeGameModeBase")
|
||||
GameUserSettingsClassName=/Script/Lost_Edge.CustomGameUserSettings
|
||||
GameUserSettingsClassName=/Script/Lost_Edge.CustomGameSettings
|
||||
LevelScriptActorClassName=/Script/Lost_Edge.LevelBase
|
||||
|
||||
[/Script/AndroidFileServerEditor.AndroidFileServerRuntimeSettings]
|
||||
|
@ -1,4 +1,4 @@
|
||||
[/Script/Lost_Edge.CustomGameUserSettings]
|
||||
[/Script/Lost_Edge.CustomGameSettings]
|
||||
bUseMotionBlur=False
|
||||
bShowFps=False
|
||||
bMouseInverted=False
|
||||
|
BIN
UnrealProject/Lost_Edge/Content/Blueprints/BP_CustomGameInstance.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/Blueprints/BP_CustomGameInstance.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/Blueprints/BP_PlayerController.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/Blueprints/BP_PlayerController.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/Levels/Test/Actors/RuntimeLoadTest/BP_Test_RuntimeLoad.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/Levels/Test/Actors/RuntimeLoadTest/BP_Test_RuntimeLoad.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/Levels/Test/Actors/SaveTest/BP_Test_SaveLoad.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/Levels/Test/Actors/SaveTest/BP_Test_SaveLoad.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/Levels/Test/L_Test.umap
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/Levels/Test/L_Test.umap
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/Levels/Test/L_Test_BuiltData.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/Levels/Test/L_Test_BuiltData.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenu.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenu.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuCredits.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuCredits.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptions.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptions.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptionsAudio.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptionsAudio.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptionsControls.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptionsControls.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptionsGame.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptionsGame.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptionsVideo.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/MainMenu/UI_MainMenuOptionsVideo.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/UI_CameraMode.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Blueprints/UI_CameraMode.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsButton.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsButton.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsCategory.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsCategory.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsComboBox.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsComboBox.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsKeySelector.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsKeySelector.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsSlider.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsSlider.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsSwitchButton.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_OptionsSwitchButton.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_PageButton.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_PageButton.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_Title.uasset
(Stored with Git LFS)
Normal file
BIN
UnrealProject/Lost_Edge/Content/UI/Components/MainMenu/UIC_MainMenu_Title.uasset
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsButton.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsButton.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsCategory.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsCategory.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsComboBox.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsComboBox.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsKeySelector.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsKeySelector.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsSlider.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsSlider.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsSwitchButton.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_OptionsSwitchButton.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_PageButton.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_PageButton.uasset
(Stored with Git LFS)
Binary file not shown.
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_Title.uasset
(Stored with Git LFS)
BIN
UnrealProject/Lost_Edge/Content/UI/Components/UIC_MainMenu_Title.uasset
(Stored with Git LFS)
Binary file not shown.
5
UnrealProject/Lost_Edge/README.md
Normal file
5
UnrealProject/Lost_Edge/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# How to compile
|
||||
It's recommended to work in Unreal Engine 5.4 and to install Visual Studio with the necessary packages as it described in the [official documentation](https://dev.epicgames.com/documentation/en-us/unreal-engine/setting-up-visual-studio-development-environment-for-cplusplus-projects-in-unreal-engine) (recommended settings aren't needed). \
|
||||
After repo cloning, the Visual Studio project files needs to be generated. It can be done in the explorer RMB context menu of file "UnrealProject/Lost_Edge/Lost_Edge.uproject". Or by typing "%UE5PATH%\Engine\Build\BatchFiles\GenerateProjectFiles.bat" "%REPOPATH%\UnrealProject\Lost_Edge\Lost_Edge.uproject". \
|
||||
After generating, "Lost_Edge.sln" can be opened and project can start building for the first time, which will fail. This is because of using OpenCV plugin that together with UnrealEngine implement their own "check()" function. This error can be used to determine that in the file "%UE5PATH%\Engine\Plugins\Runtime\OpenCV\Source\ThirdParty\OpenCV\include\opencv2\core\utility.hpp" it is necessary to comment out the warning macro on lines 52-54 and rename the function itself on line 957 to, for example, "checkcv()".
|
||||
After this modification, the build should run fine and it is possible to open the project in UnrealEngine.
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "CameraModeBase.h"
|
||||
|
||||
#include "Camera/CameraComponent.h"
|
||||
@ -10,12 +9,16 @@
|
||||
#include "InputMappingContext.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "CustomGameUserSettings.h"
|
||||
#include "CustomGameSettings.h"
|
||||
#include "CustomPlayerController.h"
|
||||
#include "MainGameModeBase.h"
|
||||
|
||||
ACameraModeBase::ACameraModeBase()
|
||||
{
|
||||
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_CameraMode.IMC_CameraMode'") };
|
||||
context = asset.Object;
|
||||
ACustomPlayerController::AppendInputContext(context);
|
||||
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
}
|
||||
|
||||
@ -25,28 +28,11 @@ void ACameraModeBase::BeginPlay()
|
||||
|
||||
auto world = GetWorld();
|
||||
|
||||
//GetMovementComponent()->speed
|
||||
// GetCharacterMovement()->MaxWalkSpeed = moveSpeed;
|
||||
|
||||
auto gameSettings = UCustomGameUserSettings::GetCustomGameUserSettings();
|
||||
|
||||
if(auto camera = FindComponentByClass<UCameraComponent>())
|
||||
if(auto gameSettings = UCustomGameSettings::Get())
|
||||
{
|
||||
camera->PostProcessSettings.MotionBlurAmount = gameSettings->bUseMotionBlur ? 1.0f : 0.0f;
|
||||
}
|
||||
|
||||
if(auto PC = Cast<APlayerController>(GetController()))
|
||||
{
|
||||
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
|
||||
if(auto camera = FindComponentByClass<UCameraComponent>())
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
|
||||
{
|
||||
inputSubsystem->ClearAllMappings();
|
||||
for(auto& inputContext : GI->inputContexts)
|
||||
{
|
||||
inputSubsystem->AddMappingContext(inputContext.LoadSynchronous(), 0);
|
||||
}
|
||||
}
|
||||
camera->PostProcessSettings.MotionBlurAmount = gameSettings->bUseMotionBlur ? 1.0f : 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -66,13 +52,8 @@ void ACameraModeBase::SetupPlayerInputComponent(UInputComponent* PlayerInputComp
|
||||
|
||||
void ACameraModeBase::SwitchToPlayerPawn()
|
||||
{
|
||||
if(auto gamemode_base = UGameplayStatics::GetGameMode(GetWorld()))
|
||||
{
|
||||
if(auto gamemode = Cast<AMainGameModeBase>(gamemode_base))
|
||||
{
|
||||
gamemode->SwitchCameraMode();
|
||||
}
|
||||
}
|
||||
if(auto gamemode = AMainGameModeBase::Get())
|
||||
gamemode->SwitchCameraMode();
|
||||
}
|
||||
|
||||
void ACameraModeBase::ElevatePawn(float value)
|
||||
@ -86,4 +67,4 @@ void ACameraModeBase::SwitchRun(bool run)
|
||||
// GetMovement()->MaxWalkSpeed = moveSpeed * runSpeedMultiplier;
|
||||
//else
|
||||
// GetCharacterMovement()->MaxWalkSpeed = moveSpeed;
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/SpectatorPawn.h"
|
||||
|
||||
#include "CameraModeBase.generated.h"
|
||||
|
||||
/**
|
||||
* Cheap copy of PlayerBase for level fly spectating purposes.
|
||||
*/
|
||||
UCLASS()
|
||||
class ACameraModeBase : public ASpectatorPawn
|
||||
{
|
||||
@ -33,4 +35,8 @@ protected:
|
||||
float moveSpeed = 200;
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
float runSpeedMultiplier = 4;
|
||||
|
||||
private:
|
||||
TSoftObjectPtr<class UInputMappingContext> context;
|
||||
|
||||
};
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "UObject/Object.h"
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "CustomGameInstance.h"
|
||||
#include "Levels/LevelBase.h"
|
||||
#include "PlayerBase.h"
|
||||
|
||||
@ -53,25 +53,6 @@ TArray<int32> UCommonFunctions::GetRandomIntArray(int32 size, int32 min, int32 m
|
||||
|
||||
|
||||
|
||||
ALevelBase* UCommonFunctions::GetCurrentLevelScript(UObject* obj)
|
||||
{
|
||||
if(auto world = obj->GetWorld())
|
||||
if(auto level = world->GetCurrentLevel())
|
||||
if(auto script = level->GetLevelScriptActor())
|
||||
return Cast<ALevelBase>(script);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
APlayerBase* UCommonFunctions::GetPlayer(UObject* obj)
|
||||
{
|
||||
if(auto pc = UGameplayStatics::GetPlayerController(obj->GetWorld(), 0))
|
||||
if(auto pawn = pc->GetPawn())
|
||||
return Cast<APlayerBase>(pawn);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace SlowMotion
|
||||
{
|
||||
FTimerHandle timer;
|
||||
@ -86,7 +67,7 @@ void UCommonFunctions::EnterSlowMotion(float duration)
|
||||
|
||||
SlowMotion::targetDilation = SlowMotion::slowDilation;
|
||||
|
||||
auto GI = UCustomGameInstanceBase::GetGameInstance();
|
||||
auto GI = UCustomGameInstance::Get();
|
||||
if(!GI)
|
||||
return;
|
||||
|
||||
@ -101,7 +82,7 @@ void UCommonFunctions::ExitSlowMotion(float duration)
|
||||
|
||||
SlowMotion::targetDilation = SlowMotion::normalDilation;
|
||||
|
||||
auto GI = UCustomGameInstanceBase::GetGameInstance();
|
||||
auto GI = UCustomGameInstance::Get();
|
||||
if(!GI)
|
||||
return;
|
||||
|
||||
@ -116,7 +97,7 @@ FWorldDilationChangedDelegate& UCommonFunctions::GetWorldDilationChangedDelegate
|
||||
|
||||
void UCommonFunctions::SlowMotionTick()
|
||||
{
|
||||
const UWorld* world = UCustomGameInstanceBase::GetGameInstance()->GetWorld();
|
||||
const UWorld* world = UCustomGameInstance::Get()->GetWorld();
|
||||
const float currentDilation = UGameplayStatics::GetGlobalTimeDilation(world);
|
||||
float newDilation = FMath::FInterpTo(currentDilation, SlowMotion::targetDilation, 1, SlowMotion::interpolationSpeed);
|
||||
|
||||
|
@ -2,34 +2,33 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
|
||||
#include "CommonFunctions.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FWorldDilationChangedDelegate, float, newDilation);
|
||||
|
||||
/**
|
||||
* Collection of common/universal/without own scope/specific functions.
|
||||
*/
|
||||
UCLASS()
|
||||
class UCommonFunctions : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Returns true if the object is UE class template (used for copy/archetype/meta system but not on the level) */
|
||||
UFUNCTION(BlueprintPure)
|
||||
static bool IsNonGameObject(class UObject* object);
|
||||
|
||||
/** "Overload" of the built-in keys translator (to not build own engine copy) */
|
||||
UFUNCTION(BlueprintPure)
|
||||
static FText GetKeyDisplayName(struct FKey key);
|
||||
|
||||
/** Recursively destroy actor and all its childs (the default Destroy doesn't have consistent behavior) */
|
||||
UFUNCTION(BlueprintCallable, Category = Actor)
|
||||
static void DestroyActorRecursively(class AActor* actor);
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
static TArray<int32> GetRandomIntArray(int32 size = 16, int32 min = 0, int32 max = 16);
|
||||
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Level)
|
||||
static class ALevelBase* GetCurrentLevelScript(class UObject* obj);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Player)
|
||||
static class APlayerBase* GetPlayer(class UObject* obj);
|
||||
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = World)
|
||||
@ -41,6 +40,10 @@ public:
|
||||
static FWorldDilationChangedDelegate& GetWorldDilationChangedDelegate();
|
||||
|
||||
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
static TArray<int32> GetRandomIntArray(int32 size = 16, int32 min = 0, int32 max = 16);
|
||||
|
||||
template<typename T>
|
||||
static TArray<T> ArrayDiff(const TArray<T>& a, const TArray<T>& b);
|
||||
template<typename T>
|
||||
|
@ -1,12 +1,12 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "ContentLoader.h"
|
||||
|
||||
#include "CommonFunctions.h"
|
||||
#include "IPlatformFilePak.h"
|
||||
#include "Misc/FileHelper.h"
|
||||
|
||||
#include "CommonFunctions.h"
|
||||
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -10,13 +10,16 @@
|
||||
UENUM(BlueprintType)
|
||||
enum class EContentDownloadMethod : uint8
|
||||
{
|
||||
ClearRandom = 0,
|
||||
NonRepeatRandom,
|
||||
RatingOftenRandom
|
||||
ClearRandom = 0, //!< Always random from 0 to n
|
||||
NonRepeatRandom, //!< Download the one that isn't downloaded in current runtime (Reset on full set)
|
||||
RatingOftenRandom //!< NonRepeatRandom combined with asset rating [WIP]
|
||||
};
|
||||
|
||||
DECLARE_DYNAMIC_DELEGATE_OneParam(FContentDownloadedCallback, FString, pakFilePath);
|
||||
|
||||
/*
|
||||
* High language wrapper for Paks(Assets) download and loading.
|
||||
*/
|
||||
UCLASS(BlueprintType)
|
||||
class UContentLoader : public UObject
|
||||
{
|
||||
@ -35,12 +38,18 @@ public:
|
||||
protected:
|
||||
virtual void BeginDestroy() override;
|
||||
|
||||
/** Sends http get request */
|
||||
void HttpGet(const FString& url, FHttpRequestCompleteDelegate requestCompleteCallback);
|
||||
/** Parses assets html/json index */
|
||||
TArray<FString> ParseDirectoryIndex(const TArray<uint8>& content, const FString& contentType);
|
||||
/** Selects item by desired method */
|
||||
FString SelectContentByMethod(const TArray<FString>& content, const EContentDownloadMethod method);
|
||||
|
||||
/** Reads Pak content */
|
||||
FString GetPakMountContent(const FString& pakFilePath, TArray<FString>* content = nullptr);
|
||||
/** Returns mount path to desired content item */
|
||||
UClass* GetPakClass(const FString& pakContentPath);
|
||||
|
||||
/** Cache of already downloaded content at runtime (used by EContentDownloadMethod::NonRepeatRandom)*/
|
||||
TArray<FString> downloadedContent;
|
||||
};
|
||||
|
@ -0,0 +1,74 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#include "CustomGameInstance.h"
|
||||
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
|
||||
#include "ContentLoader.h"
|
||||
#include "Levels/LevelBase.h"
|
||||
#include "PlayerBase.h"
|
||||
#include "SaveData.h"
|
||||
|
||||
UCustomGameInstance* UCustomGameInstance::instance = nullptr;
|
||||
|
||||
void UCustomGameInstance::Init()
|
||||
{
|
||||
UGameInstance::Init();
|
||||
|
||||
instance = this;
|
||||
contentLoader = NewObject<UContentLoader>(this);
|
||||
saveData = Cast<USaveData>(UGameplayStatics::CreateSaveGameObject(USaveData::StaticClass()));
|
||||
}
|
||||
|
||||
UCustomGameInstance* UCustomGameInstance::Get()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
UContentLoader* UCustomGameInstance::GetContentLoader()
|
||||
{
|
||||
if(auto GI = Get())
|
||||
return GI->contentLoader;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UCustomGameInstance::SaveGame(FName checkpointName)
|
||||
{
|
||||
auto levelScript = ALevelBase::Get();
|
||||
if(!levelScript)
|
||||
return;
|
||||
|
||||
auto player = APlayerBase::Get();
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
saveData->level = GetWorld()->GetFName();
|
||||
saveData->state = levelScript->GetState();
|
||||
saveData->checkpoint = checkpointName;
|
||||
if(player->leftPocketItem)
|
||||
saveData->playerLeftPocketItem = player->leftPocketItem->GetFName();
|
||||
else
|
||||
saveData->playerLeftPocketItem = FName(TEXT(""));
|
||||
if(player->rightPocketItem)
|
||||
saveData->playerRightPocketItem = player->rightPocketItem->GetFName();
|
||||
else
|
||||
saveData->playerRightPocketItem = FName(TEXT(""));
|
||||
|
||||
UGameplayStatics::SaveGameToSlot(saveData, TEXT("Save"), 0);
|
||||
}
|
||||
|
||||
void UCustomGameInstance::LoadGame()
|
||||
{
|
||||
saveData = Cast<USaveData>(UGameplayStatics::LoadGameFromSlot(TEXT("Save"), 0));
|
||||
if(!saveData)
|
||||
return;
|
||||
|
||||
UGameplayStatics::OpenLevel(this, saveData->level);
|
||||
}
|
||||
|
||||
void UCustomGameInstance::ExitGame()
|
||||
{
|
||||
UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, true);
|
||||
}
|
@ -4,29 +4,29 @@
|
||||
|
||||
#include "Engine/GameInstance.h"
|
||||
|
||||
#include "CustomGameInstanceBase.generated.h"
|
||||
#include "CustomGameInstance.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FLevelBeginnedDelegate, FName, levelName);
|
||||
|
||||
/**
|
||||
* Expands basic UE game instance.
|
||||
* Manages saves, handles content loader and can shutdown the game.
|
||||
*/
|
||||
UCLASS()
|
||||
class UCustomGameInstanceBase : public UGameInstance
|
||||
class UCustomGameInstance : public UGameInstance
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Instantiates content loader, dummy save data and applies settings */
|
||||
virtual void Init() override;
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
static UCustomGameInstanceBase* GetGameInstance();
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Custom Game Instance"))
|
||||
static UCustomGameInstance* Get();
|
||||
|
||||
UFUNCTION(BlueprintPure)
|
||||
static class UContentLoader* GetContentLoader();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Settings)
|
||||
void ApplyMouseSettings();
|
||||
|
||||
void AppendInteractableModificatorClass(TSubclassOf<class UInteractableModificator> modificator);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = Save)
|
||||
void SaveGame(FName checkpointName);
|
||||
UFUNCTION(BlueprintCallable, Category = Save)
|
||||
@ -34,17 +34,11 @@ public:
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void ExitGame();
|
||||
|
||||
static UCustomGameInstanceBase* instance;
|
||||
static UCustomGameInstance* instance;
|
||||
|
||||
/** Public delegate called by ALevelBase instance on instantiation */
|
||||
FLevelBeginnedDelegate OnLevelBeginned;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TSet<TSubclassOf<class UInteractableActivator>> interactionsActivators;
|
||||
TSet<TSubclassOf<class UInteractableModificator>> interactionsModificators;
|
||||
|
||||
UPROPERTY(EditDefaultsOnly)
|
||||
TSet<TSoftObjectPtr<class UInputMappingContext>> inputContexts;
|
||||
|
||||
UPROPERTY(VisibleAnywhere)
|
||||
class USaveData* saveData = nullptr;
|
||||
|
@ -1,149 +0,0 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
|
||||
#include "EnhancedInputLibrary.h"
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "InputMappingContext.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
|
||||
#include "CommonFunctions.h"
|
||||
#include "ContentLoader.h"
|
||||
#include "CustomGameUserSettings.h"
|
||||
#include "Interactable/Activators/InCameraInteractableActivator.h"
|
||||
#include "Interactable/Activators/RaycastInteractableActivator.h"
|
||||
#include "Interactable/Modificators/ActivateInteractableModificator.h"
|
||||
#include "Interactable/Modificators/SawInteractableModificator.h"
|
||||
#include "Levels/LevelBase.h"
|
||||
#include "PlayerBase.h"
|
||||
#include "SaveData.h"
|
||||
|
||||
UCustomGameInstanceBase* UCustomGameInstanceBase::instance = nullptr;
|
||||
|
||||
void UCustomGameInstanceBase::Init()
|
||||
{
|
||||
UGameInstance::Init();
|
||||
|
||||
instance = this;
|
||||
|
||||
contentLoader = NewObject<UContentLoader>(this);
|
||||
|
||||
interactionsActivators.Add(URaycastInteractableActivator::StaticClass());
|
||||
interactionsActivators.Add(UInCameraInteractableActivator::StaticClass());
|
||||
|
||||
for(auto& modificator : interactionsModificators)
|
||||
{
|
||||
if(modificator.GetDefaultObject()->GetMappingContext())
|
||||
{
|
||||
inputContexts.Add(modificator.GetDefaultObject()->GetMappingContext());
|
||||
}
|
||||
}
|
||||
|
||||
ApplyMouseSettings();
|
||||
|
||||
saveData = Cast<USaveData>(UGameplayStatics::CreateSaveGameObject(USaveData::StaticClass()));
|
||||
}
|
||||
|
||||
UCustomGameInstanceBase* UCustomGameInstanceBase::GetGameInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
UContentLoader* UCustomGameInstanceBase::GetContentLoader()
|
||||
{
|
||||
if(auto GI = GetGameInstance())
|
||||
return GI->contentLoader;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UCustomGameInstanceBase::ApplyMouseSettings()
|
||||
{
|
||||
if(auto gameSettings = UCustomGameUserSettings::GetCustomGameUserSettings())
|
||||
{
|
||||
for(auto& context : inputContexts)
|
||||
{
|
||||
if(!context.LoadSynchronous())
|
||||
continue;
|
||||
|
||||
for(auto& mapping : context.LoadSynchronous()->GetMappings())
|
||||
{
|
||||
if(mapping.Key == EKeys::Mouse2D)
|
||||
{
|
||||
for(auto& modifier : mapping.Modifiers)
|
||||
{
|
||||
if(auto negate_modifier = Cast<UInputModifierNegate>(modifier))
|
||||
{
|
||||
negate_modifier->bY = !gameSettings->bMouseInverted;
|
||||
}
|
||||
if(auto scalar_modifier = Cast<UInputModifierScalar>(modifier))
|
||||
{
|
||||
scalar_modifier->Scalar = FVector{ gameSettings->GetMouseSensetivity() * 0.5 };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
UEnhancedInputLibrary::RequestRebuildControlMappingsUsingContext(context.LoadSynchronous());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UCustomGameInstanceBase::AppendInteractableModificatorClass(TSubclassOf<class UInteractableModificator> modificator)
|
||||
{
|
||||
bool alreadyPresent = false;
|
||||
interactionsModificators.Add(modificator, &alreadyPresent);
|
||||
if(!alreadyPresent)
|
||||
{
|
||||
if(auto IC = modificator.GetDefaultObject()->GetMappingContext())
|
||||
{
|
||||
inputContexts.Add(IC);
|
||||
if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
|
||||
{
|
||||
if(auto inputSubsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
|
||||
{
|
||||
inputSubsystem->AddMappingContext(IC, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UCustomGameInstanceBase::SaveGame(FName checkpointName)
|
||||
{
|
||||
auto levelScript = UCommonFunctions::GetCurrentLevelScript(this);
|
||||
if(!levelScript)
|
||||
return;
|
||||
|
||||
auto player = UCommonFunctions::GetPlayer(this);
|
||||
if(!player)
|
||||
return;
|
||||
saveData->level = GetWorld()->GetFName();
|
||||
saveData->state = levelScript->GetState();
|
||||
saveData->checkpoint = checkpointName;
|
||||
if(player->leftPocketItem)
|
||||
saveData->playerLeftPocketItem = player->leftPocketItem->GetFName();
|
||||
else
|
||||
saveData->playerLeftPocketItem = FName(TEXT(""));
|
||||
if(player->rightPocketItem)
|
||||
saveData->playerRightPocketItem = player->rightPocketItem->GetFName();
|
||||
else
|
||||
saveData->playerRightPocketItem = FName(TEXT(""));
|
||||
|
||||
UGameplayStatics::SaveGameToSlot(saveData, TEXT("Save"), 0);
|
||||
}
|
||||
|
||||
void UCustomGameInstanceBase::LoadGame()
|
||||
{
|
||||
saveData = Cast<USaveData>(UGameplayStatics::LoadGameFromSlot(TEXT("Save"), 0));
|
||||
if(!saveData)
|
||||
return;
|
||||
|
||||
UGameplayStatics::OpenLevel(this, saveData->level);
|
||||
}
|
||||
|
||||
void UCustomGameInstanceBase::ExitGame()
|
||||
{
|
||||
UKismetSystemLibrary::QuitGame(GetWorld(), nullptr, EQuitPreference::Quit, true);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#include "CustomGameSettings.h"
|
||||
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
UCustomGameSettings::UCustomGameSettings(const FObjectInitializer& ObjectInitializer) :Super(ObjectInitializer)
|
||||
{
|
||||
bUseMotionBlur = false;
|
||||
bShowFps = false;
|
||||
bMouseInverted = false;
|
||||
fMouseSensetivity = 1.0f;
|
||||
}
|
||||
|
||||
UCustomGameSettings* UCustomGameSettings::Get()
|
||||
{
|
||||
return Cast<UCustomGameSettings>(UGameUserSettings::GetGameUserSettings());
|
||||
}
|
||||
|
||||
void UCustomGameSettings::SetMouseSensetivity(float value)
|
||||
{
|
||||
fMouseSensetivity = FMath::Clamp(value, 0.1f, 2.0f);
|
||||
}
|
||||
|
||||
float UCustomGameSettings::GetMouseSensetivity() const
|
||||
{
|
||||
return fMouseSensetivity;
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameFramework/GameUserSettings.h"
|
||||
|
||||
#include "CustomGameSettings.generated.h"
|
||||
|
||||
/**
|
||||
* Manages custom game settings.
|
||||
* Mouse sensetivity and inversion, motion blur usage, fps show.
|
||||
*/
|
||||
UCLASS(Config = Game, defaultconfig)
|
||||
class UCustomGameSettings : public UGameUserSettings
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
// Is auto defined by UE but implementation is in cpp
|
||||
//UCustomGameSettings(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = Settings, meta = (DisplayName = "Get Custom Game Settings"))
|
||||
static UCustomGameSettings* Get();
|
||||
|
||||
/**
|
||||
* Sets mouse sensetivity multiplier
|
||||
* @param value [0.1 - 2.0]
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = Settings)
|
||||
void SetMouseSensetivity(float value);
|
||||
|
||||
/** Returns mouse sensetivity multiplier in [0.1 - 2.0] */
|
||||
UFUNCTION(BlueprintCallable, Category = Settings)
|
||||
float GetMouseSensetivity() const;
|
||||
|
||||
UPROPERTY(Config, BlueprintReadWrite)
|
||||
bool bUseMotionBlur;
|
||||
|
||||
UPROPERTY(Config, BlueprintReadWrite)
|
||||
bool bShowFps;
|
||||
|
||||
UPROPERTY(Config, BlueprintReadWrite)
|
||||
bool bMouseInverted;
|
||||
|
||||
protected:
|
||||
UPROPERTY(Config)
|
||||
float fMouseSensetivity;
|
||||
|
||||
};
|
@ -1,29 +0,0 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "CustomGameUserSettings.h"
|
||||
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
UCustomGameUserSettings::UCustomGameUserSettings(const FObjectInitializer& ObjectInitializer) :Super(ObjectInitializer)
|
||||
{
|
||||
bUseMotionBlur = false;
|
||||
bShowFps = false;
|
||||
bMouseInverted = false;
|
||||
fMouseSensetivity = 1.0f;
|
||||
}
|
||||
|
||||
UCustomGameUserSettings* UCustomGameUserSettings::GetCustomGameUserSettings()
|
||||
{
|
||||
return Cast<UCustomGameUserSettings>(UGameUserSettings::GetGameUserSettings());
|
||||
}
|
||||
|
||||
void UCustomGameUserSettings::SetMouseSensetivity(float value)
|
||||
{
|
||||
fMouseSensetivity = FMath::Clamp(value, 0.1f, 2.0f);
|
||||
}
|
||||
|
||||
float UCustomGameUserSettings::GetMouseSensetivity() const
|
||||
{
|
||||
return fMouseSensetivity;
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/GameUserSettings.h"
|
||||
|
||||
#include "CustomGameUserSettings.generated.h"
|
||||
|
||||
UCLASS()
|
||||
class UCustomGameUserSettings : public UGameUserSettings
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintCallable, Category = Settings)
|
||||
static UCustomGameUserSettings* GetCustomGameUserSettings();
|
||||
|
||||
// Sets mouse sensetivity multiplier
|
||||
// @param value [0.1 - 2.0]
|
||||
UFUNCTION(BlueprintCallable, Category = Settings)
|
||||
void SetMouseSensetivity(float value);
|
||||
|
||||
// Returns mouse sensetivity multiplier in [0.1 - 2.0]
|
||||
UFUNCTION(BlueprintCallable, Category = Settings)
|
||||
float GetMouseSensetivity() const;
|
||||
|
||||
UPROPERTY(Config, BlueprintReadWrite)
|
||||
bool bUseMotionBlur;
|
||||
|
||||
UPROPERTY(Config, BlueprintReadWrite)
|
||||
bool bShowFps;
|
||||
|
||||
UPROPERTY(Config, BlueprintReadWrite)
|
||||
bool bMouseInverted;
|
||||
|
||||
protected:
|
||||
UPROPERTY(Config)
|
||||
float fMouseSensetivity;
|
||||
|
||||
};
|
@ -0,0 +1,116 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#include "CustomPlayerController.h"
|
||||
|
||||
#include "EnhancedInputComponent.h"
|
||||
#include "EnhancedInputLibrary.h"
|
||||
#include "EnhancedInputSubsystems.h"
|
||||
#include "InputMappingContext.h"
|
||||
|
||||
#include "CustomGameInstance.h"
|
||||
#include "CustomGameSettings.h"
|
||||
|
||||
ACustomPlayerController* ACustomPlayerController::instance = nullptr;
|
||||
UEnhancedInputComponent* ACustomPlayerController::input = nullptr;
|
||||
UEnhancedInputLocalPlayerSubsystem* ACustomPlayerController::subsystem = nullptr;
|
||||
TSet<TSoftObjectPtr<UInputMappingContext>> ACustomPlayerController::contexts = {};
|
||||
TSet<TSoftObjectPtr<UInputMappingContext>> ACustomPlayerController::contextsBeforeInit = {};
|
||||
|
||||
void ACustomPlayerController::AppendInputContext(TSoftObjectPtr<class UInputMappingContext> context)
|
||||
{
|
||||
if(!context.IsValid())
|
||||
return;
|
||||
|
||||
if(!UCustomGameInstance::Get()) //game settings not initialized yet
|
||||
{
|
||||
contextsBeforeInit.Add(context);
|
||||
return;
|
||||
}
|
||||
|
||||
ApplyMouseSettings(context);
|
||||
contexts.Add(context);
|
||||
if(subsystem)
|
||||
subsystem->AddMappingContext(context.LoadSynchronous(), 0);
|
||||
}
|
||||
|
||||
void ACustomPlayerController::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
instance = this;
|
||||
|
||||
for(auto& context : contextsBeforeInit)
|
||||
{
|
||||
ApplyMouseSettings(context);
|
||||
contexts.Add(context);
|
||||
}
|
||||
contextsBeforeInit.Empty();
|
||||
|
||||
subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer());
|
||||
if(subsystem)
|
||||
{
|
||||
subsystem->ClearAllMappings();
|
||||
for(auto& inputContext : contexts)
|
||||
subsystem->AddMappingContext(inputContext.LoadSynchronous(), 0);
|
||||
}
|
||||
|
||||
input = Cast<UEnhancedInputComponent>(InputComponent);
|
||||
if(input)
|
||||
{
|
||||
((UInputComponent*)input)->BindAction(TEXT("AnyKey"), IE_Pressed, this, &ACustomPlayerController::OnAnyKeyPressed);
|
||||
((UInputComponent*)input)->BindAction(TEXT("AnyKey"), IE_Released, this, &ACustomPlayerController::OnAnyKeyReleased);
|
||||
}
|
||||
}
|
||||
|
||||
void ACustomPlayerController::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
{
|
||||
instance = nullptr;
|
||||
input = nullptr;
|
||||
subsystem = nullptr;
|
||||
|
||||
Super::EndPlay(EndPlayReason);
|
||||
}
|
||||
|
||||
void ACustomPlayerController::ApplyMouseSettings(TSoftObjectPtr<class UInputMappingContext>& context)
|
||||
{
|
||||
auto gameSettings = UCustomGameSettings::Get();
|
||||
if(!gameSettings)
|
||||
return;
|
||||
|
||||
if(!context.LoadSynchronous())
|
||||
return;
|
||||
|
||||
for(auto& mapping : context.LoadSynchronous()->GetMappings())
|
||||
{
|
||||
if(mapping.Key != EKeys::Mouse2D)
|
||||
continue;
|
||||
|
||||
for(auto& modifier : mapping.Modifiers)
|
||||
{
|
||||
if(gameSettings->bMouseInverted)
|
||||
{
|
||||
if(auto negate_modifier = Cast<UInputModifierNegate>(modifier))
|
||||
{
|
||||
negate_modifier->bY = !negate_modifier->bY;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(auto scalar_modifier = Cast<UInputModifierScalar>(modifier))
|
||||
scalar_modifier->Scalar = FVector{ gameSettings->GetMouseSensetivity() * 0.5 };
|
||||
}
|
||||
}
|
||||
|
||||
UEnhancedInputLibrary::RequestRebuildControlMappingsUsingContext(context.LoadSynchronous());
|
||||
}
|
||||
|
||||
void ACustomPlayerController::OnAnyKeyPressed(FKey key)
|
||||
{
|
||||
if(onAnyKeyPressed.IsBound())
|
||||
onAnyKeyPressed.Broadcast(key);
|
||||
}
|
||||
|
||||
void ACustomPlayerController::OnAnyKeyReleased(FKey key)
|
||||
{
|
||||
if(onAnyKeyReleased.IsBound())
|
||||
onAnyKeyReleased.Broadcast(key);
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameFramework/PlayerController.h"
|
||||
|
||||
#include "CustomPlayerController.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPlayerAnyKeyPressedDelegate, FKey, key);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FPlayerAnyKeyReleasedDelegate, FKey, key);
|
||||
|
||||
/**
|
||||
* De-facto wrapper/interface of all usefull shortcuts and automatization around input system.
|
||||
* Append new input context here for auto init on BeginPlay and apply user input settings.
|
||||
* Also, has delegates onAnyKeyPressed/Released.
|
||||
*/
|
||||
UCLASS()
|
||||
class ACustomPlayerController : public APlayerController
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure, meta = (DisplayName = "Get Custom Player Controller"))
|
||||
static ACustomPlayerController* Get() { return instance; }
|
||||
UFUNCTION(BlueprintPure)
|
||||
static class UEnhancedInputComponent* GetInput() { return input; }
|
||||
UFUNCTION(BlueprintPure)
|
||||
static class UEnhancedInputLocalPlayerSubsystem* GetInputSubsystem() { return subsystem; }
|
||||
|
||||
UFUNCTION(BlueprintCallable)
|
||||
static void AppendInputContext(TSoftObjectPtr<class UInputMappingContext> context);
|
||||
|
||||
FPlayerAnyKeyPressedDelegate onAnyKeyPressed;
|
||||
FPlayerAnyKeyReleasedDelegate onAnyKeyReleased;
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
private:
|
||||
static void ApplyMouseSettings(TSoftObjectPtr<class UInputMappingContext>& context);
|
||||
|
||||
void OnAnyKeyPressed(FKey key);
|
||||
void OnAnyKeyReleased(FKey key);
|
||||
|
||||
static ACustomPlayerController* instance;
|
||||
static class UEnhancedInputLocalPlayerSubsystem* subsystem;
|
||||
static class UEnhancedInputComponent* input;
|
||||
static TSet<TSoftObjectPtr<class UInputMappingContext>> contexts;
|
||||
/** Contexts added before game instance fully initialized cannot apply game settings because not fully initialized game */
|
||||
static TSet<TSoftObjectPtr<class UInputMappingContext>> contextsBeforeInit;
|
||||
};
|
@ -9,7 +9,7 @@
|
||||
#include "LevelSequence.h"
|
||||
#include "LevelSequencePlayer.h"
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "CustomPlayerController.h"
|
||||
#include "MainGameModeBase.h"
|
||||
#include "PlayerBase.h"
|
||||
#include "Widgets/CutsceneSkipWidget.h"
|
||||
@ -19,14 +19,8 @@
|
||||
UCutsceneManager::UCutsceneManager()
|
||||
{
|
||||
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_Cutscene.IMC_Cutscene'") };
|
||||
_inputContext = asset.Object;
|
||||
if(auto world = GetWorld())
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(world->GetGameInstance()))
|
||||
{
|
||||
GI->inputContexts.Add(_inputContext);
|
||||
}
|
||||
}
|
||||
context = asset.Object;
|
||||
ACustomPlayerController::AppendInputContext(context);
|
||||
}
|
||||
|
||||
void UCutsceneManager::EnqueueSequence(ULevelSequence* sequence, FCutsceneEndCallback endCallback)
|
||||
@ -34,106 +28,82 @@ void UCutsceneManager::EnqueueSequence(ULevelSequence* sequence, FCutsceneEndCal
|
||||
if(!sequence)
|
||||
return;
|
||||
|
||||
FScopeLock lock1(&_sequencesLock);
|
||||
FScopeLock lock2(&_callbacksLock);
|
||||
FScopeLock lock1(&sequencesLock);
|
||||
FScopeLock lock2(&callbacksLock);
|
||||
|
||||
if(_endCallbacks.IsEmpty()) // most first sequence, so widgets and binds don't exist
|
||||
{
|
||||
if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
|
||||
{
|
||||
_lastPlayer = Cast<APlayerBase>(PC->GetPawn());
|
||||
if(_lastPlayer)
|
||||
{
|
||||
_lastPlayer->LockPlayer({ .walk = true, .jump = true, .run = true, .interaction = true, .camera = true });
|
||||
OnFirstCutsceneInit();
|
||||
|
||||
auto& mapping = _inputContext.LoadSynchronous()->GetMapping(0);
|
||||
int32 handler1 = _lastPlayer->inputComponent->BindAction(mapping.Action, ETriggerEvent::Started, this, &UCutsceneManager::OnInputHold).GetHandle();
|
||||
int32 handler2 = _lastPlayer->inputComponent->BindAction(mapping.Action, ETriggerEvent::Completed, this, &UCutsceneManager::OnInputUnhold).GetHandle();
|
||||
_handlers = { handler1, handler2 };
|
||||
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->HideWidgets();
|
||||
static FSkipCutsceneDelegate skipCutsceneDelegate;
|
||||
if(!skipCutsceneDelegate.IsBound())
|
||||
skipCutsceneDelegate.BindDynamic(this, &UCutsceneManager::SkipSequence);
|
||||
WM->EnableCutsceneWidget(skipCutsceneDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_nextSequences.Enqueue(sequence);
|
||||
_endCallbacks.Enqueue(endCallback);
|
||||
nextSequences.Enqueue(sequence);
|
||||
endCallbacks.Enqueue(endCallback);
|
||||
|
||||
PlayNextSequence();
|
||||
}
|
||||
|
||||
void UCutsceneManager::PlayNextSequence()
|
||||
{
|
||||
if(_sequencePlayer)
|
||||
if(sequencePlayer)
|
||||
{
|
||||
if(_sequencePlayer->IsPlaying())
|
||||
if(sequencePlayer->IsPlaying())
|
||||
return;
|
||||
else
|
||||
_sequencePlayer->MarkAsGarbage();
|
||||
sequencePlayer->MarkAsGarbage();
|
||||
}
|
||||
|
||||
FScopeLock lock(&_sequencesLock);
|
||||
FScopeLock lock(&sequencesLock);
|
||||
|
||||
ULevelSequence* sequence;
|
||||
_nextSequences.Dequeue(sequence);
|
||||
_sequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(), sequence, FMovieSceneSequencePlaybackSettings{}, _sequencePlayerActor);
|
||||
_sequencePlayer->OnStop.AddDynamic(this, &UCutsceneManager::OnSequenceEnd);
|
||||
_sequencePlayer->Play();
|
||||
nextSequences.Dequeue(sequence);
|
||||
sequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(GetWorld(), sequence, FMovieSceneSequencePlaybackSettings{}, sequencePlayerActor);
|
||||
sequencePlayer->OnStop.AddDynamic(this, &UCutsceneManager::OnSequenceEnd);
|
||||
sequencePlayer->Play();
|
||||
}
|
||||
|
||||
void UCutsceneManager::SkipSequence()
|
||||
{
|
||||
if(!_sequencePlayer || !_sequencePlayer->IsPlaying())
|
||||
if(!sequencePlayer || !sequencePlayer->IsPlaying())
|
||||
return;
|
||||
|
||||
_lastlySkipped = true;
|
||||
_sequencePlayer->GoToEndAndStop();
|
||||
lastlySkipped = true;
|
||||
sequencePlayer->GoToEndAndStop();
|
||||
}
|
||||
|
||||
void UCutsceneManager::ClearQueue()
|
||||
{
|
||||
FScopeLock lock1(&_sequencesLock);
|
||||
FScopeLock lock2(&_callbacksLock);
|
||||
if(!_nextSequences.IsEmpty())
|
||||
_nextSequences.Empty();
|
||||
if(!_endCallbacks.IsEmpty())
|
||||
_endCallbacks.Empty();
|
||||
FScopeLock lock1(&sequencesLock);
|
||||
FScopeLock lock2(&callbacksLock);
|
||||
if(!nextSequences.IsEmpty())
|
||||
nextSequences.Empty();
|
||||
if(!endCallbacks.IsEmpty())
|
||||
endCallbacks.Empty();
|
||||
}
|
||||
|
||||
void UCutsceneManager::LockCallback(bool lock)
|
||||
{
|
||||
_lockCallback = lock;
|
||||
lockCallback = lock;
|
||||
}
|
||||
|
||||
void UCutsceneManager::OnSequenceEnd()
|
||||
{
|
||||
if(_lockCallback)
|
||||
if(lockCallback)
|
||||
return;
|
||||
|
||||
_sequencePlayer->MarkAsGarbage();
|
||||
_sequencePlayer = nullptr;
|
||||
sequencePlayer->MarkAsGarbage();
|
||||
sequencePlayer = nullptr;
|
||||
|
||||
FScopeLock lock(&_callbacksLock);
|
||||
FScopeLock lock(&callbacksLock);
|
||||
|
||||
FCutsceneEndCallback callback;
|
||||
_endCallbacks.Dequeue(callback);
|
||||
endCallbacks.Dequeue(callback);
|
||||
if(callback.IsBound())
|
||||
callback.Execute();
|
||||
|
||||
if(!_nextSequences.IsEmpty())
|
||||
if(!nextSequences.IsEmpty())
|
||||
{
|
||||
PlayNextSequence();
|
||||
if(_lastlySkipped)
|
||||
if(lastlySkipped)
|
||||
{
|
||||
_lastlySkipped = false;
|
||||
if(_holding)
|
||||
lastlySkipped = false;
|
||||
if(holding)
|
||||
{
|
||||
OnInputHold();
|
||||
}
|
||||
@ -147,36 +117,63 @@ void UCutsceneManager::OnSequenceEnd()
|
||||
WM->ShowWidgets();
|
||||
}
|
||||
|
||||
if(_lastPlayer)
|
||||
if(lastPlayer)
|
||||
{
|
||||
_lastPlayer->UnlockPlayer({ .walk = true, .jump = true, .run = true, .interaction = true, .camera = true });
|
||||
lastPlayer->UnlockPlayer({ .walk = true, .jump = true, .run = true, .interaction = true, .camera = true });
|
||||
|
||||
_lastPlayer->inputComponent->RemoveBindingByHandle(_handlers.Key);
|
||||
_lastPlayer->inputComponent->RemoveBindingByHandle(_handlers.Value);
|
||||
auto input = ACustomPlayerController::GetInput();
|
||||
input->RemoveBindingByHandle(handlers.Key);
|
||||
input->RemoveBindingByHandle(handlers.Value);
|
||||
|
||||
_lastPlayer = nullptr;
|
||||
lastPlayer = nullptr;
|
||||
}
|
||||
|
||||
_lastlySkipped = false;
|
||||
_holding = false;
|
||||
lastlySkipped = false;
|
||||
holding = false;
|
||||
}
|
||||
|
||||
void UCutsceneManager::OnFirstCutsceneInit() // most first sequence, so widgets and binds don't exist
|
||||
{
|
||||
if(!endCallbacks.IsEmpty())
|
||||
return;
|
||||
|
||||
if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
|
||||
{
|
||||
lastPlayer = Cast<APlayerBase>(PC->GetPawn());
|
||||
if(lastPlayer)
|
||||
{
|
||||
lastPlayer->LockPlayer({ .walk = true, .jump = true, .run = true, .interaction = true, .camera = true });
|
||||
|
||||
auto& mapping = context.LoadSynchronous()->GetMapping(0);
|
||||
auto input = ACustomPlayerController::GetInput();
|
||||
int32 handler1 = input->BindAction(mapping.Action, ETriggerEvent::Started, this, &UCutsceneManager::OnInputHold).GetHandle();
|
||||
int32 handler2 = input->BindAction(mapping.Action, ETriggerEvent::Completed, this, &UCutsceneManager::OnInputUnhold).GetHandle();
|
||||
handlers = { handler1, handler2 };
|
||||
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->HideWidgets();
|
||||
static FSkipCutsceneDelegate skipCutsceneDelegate;
|
||||
if(!skipCutsceneDelegate.IsBound())
|
||||
skipCutsceneDelegate.BindDynamic(this, &UCutsceneManager::SkipSequence);
|
||||
WM->EnableCutsceneWidget(skipCutsceneDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UCutsceneManager::OnInputHold()
|
||||
{
|
||||
_holding = true;
|
||||
holding = true;
|
||||
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->AnimateCutsceneWidget(EInputAnimatedWidgetAnimation::Hold);
|
||||
}
|
||||
}
|
||||
|
||||
void UCutsceneManager::OnInputUnhold()
|
||||
{
|
||||
_holding = false;
|
||||
holding = false;
|
||||
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->AnimateCutsceneWidget(EInputAnimatedWidgetAnimation::Unhold);
|
||||
}
|
||||
}
|
||||
|
@ -32,22 +32,23 @@ private:
|
||||
void PlayNextSequence();
|
||||
UFUNCTION()
|
||||
void OnSequenceEnd();
|
||||
void OnFirstCutsceneInit();
|
||||
|
||||
void OnInputHold();
|
||||
void OnInputUnhold();
|
||||
|
||||
class ULevelSequencePlayer* _sequencePlayer = nullptr;
|
||||
class ALevelSequenceActor* _sequencePlayerActor = nullptr;
|
||||
TQueue<class ULevelSequence*> _nextSequences;
|
||||
FCriticalSection _sequencesLock;
|
||||
TQueue<FCutsceneEndCallback> _endCallbacks;
|
||||
FCriticalSection _callbacksLock;
|
||||
class ULevelSequencePlayer* sequencePlayer = nullptr;
|
||||
class ALevelSequenceActor* sequencePlayerActor = nullptr;
|
||||
TQueue<class ULevelSequence*> nextSequences;
|
||||
FCriticalSection sequencesLock;
|
||||
TQueue<FCutsceneEndCallback> endCallbacks;
|
||||
FCriticalSection callbacksLock;
|
||||
|
||||
class APlayerBase* _lastPlayer = nullptr;
|
||||
TSoftObjectPtr<class UInputMappingContext> _inputContext;
|
||||
TPair<int32, int32> _handlers;
|
||||
class APlayerBase* lastPlayer = nullptr;
|
||||
TSoftObjectPtr<class UInputMappingContext> context;
|
||||
TPair<int32, int32> handlers;
|
||||
|
||||
bool _lockCallback = false;
|
||||
bool _lastlySkipped = false;
|
||||
bool _holding = false;
|
||||
bool lockCallback = false;
|
||||
bool lastlySkipped = false;
|
||||
bool holding = false;
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "DialogueManager.h"
|
||||
|
||||
#include "Components/AudioComponent.h"
|
||||
@ -11,7 +10,7 @@
|
||||
#include "Kismet/KismetMathLibrary.h"
|
||||
#include "Sound/SoundWave.h"
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "CustomPlayerController.h"
|
||||
#include "MainGameModeBase.h"
|
||||
#include "PlayerBase.h"
|
||||
#include "Widgets/DialogueSkipWidget.h"
|
||||
@ -21,14 +20,8 @@
|
||||
UDialogueManager::UDialogueManager()
|
||||
{
|
||||
static ConstructorHelpers::FObjectFinder<UInputMappingContext> asset{ TEXT("/Script/EnhancedInput.InputMappingContext'/Game/Input/IMC_Dialogue.IMC_Dialogue'") };
|
||||
_inputContext = asset.Object;
|
||||
if(auto world = GetWorld())
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(world->GetGameInstance()))
|
||||
{
|
||||
GI->inputContexts.Add(_inputContext);
|
||||
}
|
||||
}
|
||||
context = asset.Object;
|
||||
ACustomPlayerController::AppendInputContext(context);
|
||||
}
|
||||
|
||||
void UDialogueManager::PlayDialogue(FDialogueEnqueProperties properties, FDialogueEndCallback endCallback)
|
||||
@ -49,32 +42,28 @@ void UDialogueManager::PlayDialogue(FDialogueEnqueProperties properties, FDialog
|
||||
|
||||
FTimerHandle timer;
|
||||
int32 timerId;
|
||||
_timersLock.Lock();
|
||||
timerId = _timers.Num();
|
||||
_timers.Add(timer);
|
||||
_timersLock.Unlock();
|
||||
timersLock.Lock();
|
||||
timerId = timers.Num();
|
||||
timers.Add(timer);
|
||||
timersLock.Unlock();
|
||||
|
||||
UGameplayStatics::PlaySound2D(this, row->wave.LoadSynchronous());
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->ShowDialogueWidget(*row);
|
||||
}
|
||||
|
||||
auto func = [properties = properties,
|
||||
timerId = timerId,
|
||||
_timersLock = &_timersLock,
|
||||
_timers = &_timers,
|
||||
endCallback = endCallback]()
|
||||
auto func = [properties,
|
||||
timerId,
|
||||
timersLock = &timersLock,
|
||||
timers = &timers,
|
||||
endCallback]()
|
||||
{
|
||||
FDialogueRow* row = reinterpret_cast<FDialogueRow*>(properties.dialogue.LoadSynchronous()->FindRowUnchecked(properties.rowName));
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->HideDialogueWidget(*row);
|
||||
}
|
||||
|
||||
_timersLock->Lock();
|
||||
_timers->RemoveAt(timerId);
|
||||
_timersLock->Unlock();
|
||||
timersLock->Lock();
|
||||
timers->RemoveAt(timerId);
|
||||
timersLock->Unlock();
|
||||
|
||||
endCallback.Execute();
|
||||
};
|
||||
@ -88,51 +77,30 @@ void UDialogueManager::EnqueDialogue(FDialogueEnqueProperties properties, FDialo
|
||||
if(!properties.dialogue.LoadSynchronous())
|
||||
return;
|
||||
|
||||
FScopeLock lock1(&_dialoguesLock);
|
||||
FScopeLock lock2(&_callbacksLock);
|
||||
FScopeLock lock1(&dialoguesLock);
|
||||
FScopeLock lock2(&callbacksLock);
|
||||
|
||||
if(_endCallbacks.IsEmpty()) // most first dialogue, so widgets and binds don't exist
|
||||
{
|
||||
if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
|
||||
{
|
||||
_lastPlayer = Cast<APlayerBase>(PC->GetPawn());
|
||||
if(_lastPlayer)
|
||||
{
|
||||
auto& mapping = _inputContext.LoadSynchronous()->GetMapping(0);
|
||||
_inputHandler = _lastPlayer->inputComponent->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &UDialogueManager::OnInputPress).GetHandle();
|
||||
OnFirstDialogueInit();
|
||||
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
static FDialogueSkipDelegate skipDialogueDelegate;
|
||||
if(!skipDialogueDelegate.IsBound())
|
||||
{
|
||||
skipDialogueDelegate.BindDynamic(this, &UDialogueManager::SkipDialogue);
|
||||
WM->SetInputDialogueWidget(mapping.Key, mapping.Action->ActionDescription, skipDialogueDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_nextDialogues.Enqueue(properties);
|
||||
_endCallbacks.Enqueue(endCallback);
|
||||
nextDialogues.Enqueue(properties);
|
||||
endCallbacks.Enqueue(endCallback);
|
||||
|
||||
PlayNextDialogue();
|
||||
}
|
||||
|
||||
void UDialogueManager::PlayNextDialogue()
|
||||
{
|
||||
_dialoguesLock.Lock();
|
||||
dialoguesLock.Lock();
|
||||
|
||||
auto properties = _nextDialogues.Peek();
|
||||
auto properties = nextDialogues.Peek();
|
||||
|
||||
TArray<FName> rows = properties->dialogue.LoadSynchronous()->GetRowNames();
|
||||
if(rows.Num() == 0)
|
||||
{
|
||||
FDialogueEndCallback callback;
|
||||
if(_endCallbacks.Dequeue(callback))
|
||||
if(endCallbacks.Dequeue(callback))
|
||||
callback.Execute();
|
||||
_nextDialogues.Pop();
|
||||
nextDialogues.Pop();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -146,22 +114,20 @@ void UDialogueManager::PlayNextDialogue()
|
||||
if(!row)
|
||||
{
|
||||
FDialogueEndCallback callback;
|
||||
_endCallbacks.Dequeue(callback);
|
||||
endCallbacks.Dequeue(callback);
|
||||
callback.ExecuteIfBound();
|
||||
_nextDialogues.Pop();
|
||||
nextDialogues.Pop();
|
||||
return;
|
||||
}
|
||||
|
||||
if(properties->playMode == EDialoguePlayMode::Sequential)
|
||||
if(properties->playMode == EDialoguePlayMode::Sequential
|
||||
&& !properties->rowName.ToString().IsNumeric())
|
||||
{
|
||||
if(!properties->rowName.ToString().IsNumeric())
|
||||
{
|
||||
_nextDialogues.Pop();
|
||||
FDialogueEndCallback callback;
|
||||
if(_endCallbacks.Dequeue(callback))
|
||||
callback.Execute();
|
||||
return;
|
||||
}
|
||||
nextDialogues.Pop();
|
||||
FDialogueEndCallback callback;
|
||||
if(endCallbacks.Dequeue(callback))
|
||||
callback.Execute();
|
||||
return;
|
||||
}
|
||||
|
||||
if(row->wave.LoadSynchronous())
|
||||
@ -170,9 +136,7 @@ void UDialogueManager::PlayNextDialogue()
|
||||
leadDialogueAudio = nullptr;
|
||||
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->ShowDialogueWidget(*row);
|
||||
}
|
||||
|
||||
FTimerHandle timer;
|
||||
int32 timerId;
|
||||
@ -180,27 +144,53 @@ void UDialogueManager::PlayNextDialogue()
|
||||
const float duration = row->wave ? row->wave->GetDuration() : row->duration;
|
||||
GetWorld()->GetTimerManager().SetTimer(timer, [&]() { OnDialogueEnd(); }, duration, false);
|
||||
|
||||
_timersLock.Lock();
|
||||
timerId = _timers.Num();
|
||||
_timers.Add(timer);
|
||||
_timersLock.Unlock();
|
||||
timersLock.Lock();
|
||||
timerId = timers.Num();
|
||||
timers.Add(timer);
|
||||
timersLock.Unlock();
|
||||
|
||||
leadDialogueTimerId = timerId;
|
||||
leadDialogueProperties = properties;
|
||||
|
||||
_dialoguesLock.Unlock();
|
||||
dialoguesLock.Unlock();
|
||||
}
|
||||
|
||||
void UDialogueManager::OnFirstDialogueInit() // most first dialogue, so widgets and binds don't exist
|
||||
{
|
||||
if(!endCallbacks.IsEmpty())
|
||||
return;
|
||||
|
||||
if(auto PC = UGameplayStatics::GetPlayerController(GetWorld(), 0))
|
||||
{
|
||||
lastPlayer = Cast<APlayerBase>(PC->GetPawn());
|
||||
if(lastPlayer)
|
||||
{
|
||||
auto& mapping = context.LoadSynchronous()->GetMapping(0);
|
||||
inputHandler = ACustomPlayerController::GetInput()->BindAction(mapping.Action, ETriggerEvent::Triggered, this, &UDialogueManager::OnInputPress).GetHandle();
|
||||
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
static FDialogueSkipDelegate skipDialogueDelegate;
|
||||
if(!skipDialogueDelegate.IsBound())
|
||||
{
|
||||
skipDialogueDelegate.BindDynamic(this, &UDialogueManager::SkipDialogue);
|
||||
WM->SetInputDialogueWidget(mapping.Key, mapping.Action->ActionDescription, skipDialogueDelegate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UDialogueManager::SkipDialogue()
|
||||
{
|
||||
if(_timers.Num() == 0 || leadDialogueTimerId < 0)
|
||||
if(timers.Num() == 0 || leadDialogueTimerId < 0)
|
||||
return;
|
||||
|
||||
_timersLock.Lock();
|
||||
GetWorld()->GetTimerManager().ClearTimer(_timers[leadDialogueTimerId]);
|
||||
_timers.RemoveAt(leadDialogueTimerId);
|
||||
timersLock.Lock();
|
||||
GetWorld()->GetTimerManager().ClearTimer(timers[leadDialogueTimerId]);
|
||||
timers.RemoveAt(leadDialogueTimerId);
|
||||
leadDialogueTimerId = -1;
|
||||
_timersLock.Unlock();
|
||||
timersLock.Unlock();
|
||||
|
||||
if(leadDialogueAudio)
|
||||
leadDialogueAudio->Stop();
|
||||
@ -210,25 +200,25 @@ void UDialogueManager::SkipDialogue()
|
||||
|
||||
void UDialogueManager::ClearQueue()
|
||||
{
|
||||
if(!_nextDialogues.IsEmpty())
|
||||
_nextDialogues.Empty();
|
||||
if(!_endCallbacks.IsEmpty())
|
||||
_endCallbacks.Empty();
|
||||
if(!nextDialogues.IsEmpty())
|
||||
nextDialogues.Empty();
|
||||
if(!endCallbacks.IsEmpty())
|
||||
endCallbacks.Empty();
|
||||
}
|
||||
|
||||
void UDialogueManager::LockCallback(bool lock)
|
||||
{
|
||||
_lockCallback = lock;
|
||||
lockCallback = lock;
|
||||
}
|
||||
|
||||
void UDialogueManager::BeginDestroy()
|
||||
{
|
||||
if(auto world = GetWorld())
|
||||
{
|
||||
_timersLock.Lock();
|
||||
for(auto& timer : _timers)
|
||||
timersLock.Lock();
|
||||
for(auto& timer : timers)
|
||||
world->GetTimerManager().ClearTimer(timer);
|
||||
_timersLock.Unlock();
|
||||
timersLock.Unlock();
|
||||
}
|
||||
|
||||
UObject::BeginDestroy();
|
||||
@ -236,41 +226,35 @@ void UDialogueManager::BeginDestroy()
|
||||
|
||||
void UDialogueManager::OnDialogueEnd()
|
||||
{
|
||||
_dialoguesLock.Lock();
|
||||
dialoguesLock.Lock();
|
||||
|
||||
FDialogueRow* row = reinterpret_cast<FDialogueRow*>(leadDialogueProperties->dialogue.LoadSynchronous()->FindRowUnchecked(leadDialogueProperties->rowName));
|
||||
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->HideDialogueWidget(*row);
|
||||
}
|
||||
|
||||
if(leadDialogueProperties->playMode == EDialoguePlayMode::Sequential)
|
||||
if(leadDialogueProperties->playMode == EDialoguePlayMode::Sequential
|
||||
&& leadDialogueProperties->rowName.ToString().IsNumeric())
|
||||
{
|
||||
if(leadDialogueProperties->rowName.ToString().IsNumeric())
|
||||
{
|
||||
leadDialogueProperties->rowName = FName(FString::FromInt(FCString::Atoi(*(leadDialogueProperties->rowName.ToString())) + 1));
|
||||
}
|
||||
leadDialogueProperties->rowName = FName(FString::FromInt(FCString::Atoi(*(leadDialogueProperties->rowName.ToString())) + 1));
|
||||
}
|
||||
|
||||
_dialoguesLock.Unlock();
|
||||
dialoguesLock.Unlock();
|
||||
|
||||
if(!_endCallbacks.IsEmpty())
|
||||
if(!endCallbacks.IsEmpty())
|
||||
PlayNextDialogue();
|
||||
|
||||
_dialoguesLock.Lock();
|
||||
if(_endCallbacks.IsEmpty() && _lastPlayer)
|
||||
dialoguesLock.Lock();
|
||||
if(endCallbacks.IsEmpty() && lastPlayer)
|
||||
{
|
||||
_lastPlayer->inputComponent->RemoveBindingByHandle(_inputHandler);
|
||||
_lastPlayer = nullptr;
|
||||
ACustomPlayerController::GetInput()->RemoveBindingByHandle(inputHandler);
|
||||
lastPlayer = nullptr;
|
||||
}
|
||||
_dialoguesLock.Unlock();
|
||||
dialoguesLock.Unlock();
|
||||
}
|
||||
|
||||
void UDialogueManager::OnInputPress()
|
||||
{
|
||||
if(auto WM = AMainGameModeBase::GetWidgetsManager())
|
||||
{
|
||||
WM->AnimateDialogueWidget(EInputAnimatedWidgetAnimation::Click);
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class UDialogueManager : public UObject
|
||||
public:
|
||||
UDialogueManager();
|
||||
|
||||
// Ignores play mode and force pushing dialogue
|
||||
/** Ignores play mode and force pushing dialogue */
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void PlayDialogue(FDialogueEnqueProperties properties, FDialogueEndCallback endCallback);
|
||||
|
||||
@ -89,26 +89,28 @@ protected:
|
||||
|
||||
private:
|
||||
void PlayNextDialogue();
|
||||
void OnFirstDialogueInit();
|
||||
|
||||
UFUNCTION()
|
||||
void OnDialogueEnd();
|
||||
|
||||
void OnInputPress();
|
||||
|
||||
TQueue<FDialogueEnqueProperties> _nextDialogues;
|
||||
FCriticalSection _dialoguesLock;
|
||||
TQueue<FDialogueEndCallback> _endCallbacks;
|
||||
FCriticalSection _callbacksLock;
|
||||
TQueue<FDialogueEnqueProperties> nextDialogues;
|
||||
FCriticalSection dialoguesLock;
|
||||
TQueue<FDialogueEndCallback> endCallbacks;
|
||||
FCriticalSection callbacksLock;
|
||||
|
||||
TArray<FTimerHandle> _timers;
|
||||
FCriticalSection _timersLock;
|
||||
TArray<FTimerHandle> timers;
|
||||
FCriticalSection timersLock;
|
||||
|
||||
int32 leadDialogueTimerId = -1;
|
||||
FDialogueEnqueProperties* leadDialogueProperties;
|
||||
class UAudioComponent* leadDialogueAudio;
|
||||
|
||||
class APlayerBase* _lastPlayer = nullptr;
|
||||
TSoftObjectPtr<class UInputMappingContext> _inputContext;
|
||||
int32 _inputHandler;
|
||||
class APlayerBase* lastPlayer = nullptr;
|
||||
TSoftObjectPtr<class UInputMappingContext> context;
|
||||
int32 inputHandler;
|
||||
|
||||
bool _lockCallback = false;
|
||||
bool lockCallback = false;
|
||||
};
|
||||
|
@ -1,9 +1,9 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "InCameraInteractableActivator.h"
|
||||
|
||||
#include "CommonFunctions.h"
|
||||
#include "Interactable/Interactable.h"
|
||||
#include "InteractableScreenCapturer.h"
|
||||
|
||||
UInCameraInteractableActivator::UInCameraInteractableActivator(const FObjectInitializer& ObjectInitializer)
|
||||
@ -20,10 +20,10 @@ UInCameraInteractableActivator::UInCameraInteractableActivator(const FObjectInit
|
||||
activatorType = EActivatorType::Saw;
|
||||
scanDistance = 7000;
|
||||
|
||||
_capturer = CreateDefaultSubobject<UInteractableScreenCapturer>(TEXT("UInCameraInteractableActivator_UInteractableScreenCapturer"));
|
||||
_capturer->interactableInScreenDelegate.BindUObject(this, &UInCameraInteractableActivator::NewSeenInteractable_Implementation);
|
||||
_capturer->SetupAttachment(this);
|
||||
_capturer->scanDistance = scanDistance;
|
||||
capturer = CreateDefaultSubobject<UInteractableScreenCapturer>(TEXT("UInCameraInteractableActivator_UInteractableScreenCapturer"));
|
||||
capturer->interactableInScreenDelegate.BindUObject(this, &UInCameraInteractableActivator::NewSeenInteractable);
|
||||
capturer->SetupAttachment(this);
|
||||
capturer->scanDistance = scanDistance;
|
||||
|
||||
PrimaryComponentTick.bCanEverTick = true;
|
||||
PrimaryComponentTick.bStartWithTickEnabled = false;
|
||||
@ -31,27 +31,28 @@ UInCameraInteractableActivator::UInCameraInteractableActivator(const FObjectInit
|
||||
|
||||
void UInCameraInteractableActivator::OnRegister()
|
||||
{
|
||||
UInteractableActivator::OnRegister();
|
||||
_capturer->RegisterComponent();
|
||||
_capturer->Activate();
|
||||
Super::OnRegister();
|
||||
capturer->RegisterComponent();
|
||||
capturer->Activate();
|
||||
}
|
||||
|
||||
void UInCameraInteractableActivator::NewSeenInteractable_Implementation(AInteractable* interactable)
|
||||
void UInCameraInteractableActivator::NewSeenInteractable(AInteractable* interactable)
|
||||
{
|
||||
_interactablesToActivate.Enqueue(interactable);
|
||||
interactablesToActivate.Enqueue(interactable);
|
||||
SetComponentTickEnabled(true);
|
||||
}
|
||||
|
||||
void UInCameraInteractableActivator::Scan_Implementation()
|
||||
{
|
||||
SetComponentTickEnabled(false);
|
||||
while(!_interactablesToActivate.IsEmpty())
|
||||
while(!interactablesToActivate.IsEmpty())
|
||||
{
|
||||
AInteractable* interactable;
|
||||
_interactablesToActivate.Dequeue(interactable);
|
||||
interactablesToActivate.Dequeue(interactable);
|
||||
if(interactableActivatedDelegate.IsBound())
|
||||
{
|
||||
interactableActivatedDelegate.Execute(interactable, activatorType);
|
||||
OnNewSeenInteractable(interactable);
|
||||
}
|
||||
}
|
||||
}
|
@ -2,13 +2,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "InteractableActivator.h"
|
||||
|
||||
#include "InCameraInteractableActivator.generated.h"
|
||||
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
/**
|
||||
* Activates interactable only once if is in a camera view
|
||||
*/
|
||||
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableActivator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Activates interactable only once if is in a camera view"), MinimalAPI)
|
||||
class UInCameraInteractableActivator : public UInteractableActivator
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@ -19,14 +20,30 @@ public:
|
||||
protected:
|
||||
virtual void OnRegister() override;
|
||||
|
||||
virtual bool AutoInstantiateInPlayer() override { return true; }
|
||||
|
||||
/**
|
||||
* Scan is performed independently by _capturer member object.
|
||||
* This implementation just activates interactables in the game thread.
|
||||
*/
|
||||
virtual void Scan_Implementation() override;
|
||||
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
LOST_EDGE_API void NewSeenInteractable(class AInteractable* interactable);
|
||||
virtual void NewSeenInteractable_Implementation(class AInteractable* interactable);
|
||||
/**
|
||||
* Thread safe enques interactable for activation in the next game tick
|
||||
* @param interactable .. interactable to activate
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void NewSeenInteractable(class AInteractable* interactable);
|
||||
|
||||
/**
|
||||
* Called after interactable activation
|
||||
* @param interactable .. interactable activated
|
||||
*/
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void OnNewSeenInteractable(class AInteractable* interactable);
|
||||
|
||||
private:
|
||||
UPROPERTY()
|
||||
class UInteractableScreenCapturer* _capturer;
|
||||
TQueue<class AInteractable*> _interactablesToActivate;
|
||||
class UInteractableScreenCapturer* capturer;
|
||||
TQueue<class AInteractable*> interactablesToActivate;
|
||||
};
|
||||
|
@ -1,19 +1,23 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "InteractableActivator.h"
|
||||
|
||||
#include "Engine/CollisionProfile.h"
|
||||
|
||||
#include "Interactable/Interactable.h"
|
||||
#include "PlayerBase.h"
|
||||
|
||||
UInteractableActivator::UInteractableActivator(const FObjectInitializer& ObjectInitializer)
|
||||
: USceneComponent(ObjectInitializer)
|
||||
{
|
||||
if(HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
|
||||
if(GetClass() != UInteractableActivator::StaticClass())
|
||||
{
|
||||
return;
|
||||
AInteractable::AppendActivatorClass(GetClass());
|
||||
}
|
||||
|
||||
if(HasAnyFlags(RF_ClassDefaultObject | RF_ArchetypeObject))
|
||||
return;
|
||||
|
||||
world = GetWorld();
|
||||
player = Cast<APlayerBase>(GetOwner());
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "Components/SceneComponent.h"
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "Interactable/Interactable.h"
|
||||
|
||||
@ -12,15 +11,22 @@
|
||||
DECLARE_DELEGATE_TwoParams(FInteractableActivated, AInteractable*, EActivatorType);
|
||||
DECLARE_DELEGATE_TwoParams(FInteractableDeactivated, AInteractable*, EActivatorType);
|
||||
|
||||
UCLASS(Abstract, Blueprintable, BlueprintType)
|
||||
/**
|
||||
* Activates interactable based on type
|
||||
*/
|
||||
UCLASS(Abstract, Blueprintable, BlueprintType, ClassGroup = InteractableActivator, meta = (ShortTooltip = "Activates interactable based on type"), MinimalAPI)
|
||||
class UInteractableActivator : public USceneComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/** Append itself to CustomGameInstance modificators registry */
|
||||
UInteractableActivator(const FObjectInitializer& ObjectInitializer);
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
virtual bool AutoInstantiateInPlayer() { return false; }
|
||||
|
||||
/** Resets activator state forcing to rescan */
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
LOST_EDGE_API void Rescan();
|
||||
virtual void Rescan_Implementation() {}
|
||||
@ -29,6 +35,7 @@ public:
|
||||
FInteractableActivated interactableDeactivatedDelegate;
|
||||
|
||||
protected:
|
||||
/** Activator scan function in game thread tick */
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
LOST_EDGE_API void Scan();
|
||||
virtual void Scan_Implementation() PURE_VIRTUAL(UInteractableActivator::Scan_Implementation, );
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "InteractableScreenCapturer.h"
|
||||
|
||||
#include "Engine/Texture.h"
|
||||
@ -16,9 +15,12 @@
|
||||
#include "Interactable/Interactable.h"
|
||||
#include "InteractableScreenCapturerBitMapCS.h"
|
||||
|
||||
constexpr float tickInterval = 1.0f / 5;
|
||||
constexpr float textureWidth = 1280 / 2;
|
||||
constexpr float textureHeight = 720 / 2;
|
||||
namespace
|
||||
{
|
||||
constexpr float tickInterval = 1.0f / 5;
|
||||
constexpr float textureWidth = 1280 / 2;
|
||||
constexpr float textureHeight = 720 / 2;
|
||||
}
|
||||
|
||||
UInteractableScreenCapturer::UInteractableScreenCapturer(const FObjectInitializer& ObjectInitializer)
|
||||
: USceneCaptureComponent2D(ObjectInitializer)
|
||||
@ -85,7 +87,7 @@ void UInteractableScreenCapturer::TickComponent(float DeltaTime, enum ELevelTick
|
||||
{
|
||||
USceneCaptureComponent2D::TickComponent(DeltaTime, TickType, ThisTickFunction);
|
||||
CaptureScene();
|
||||
GetCameraView(DeltaTime, _view);
|
||||
GetCameraView(DeltaTime, view);
|
||||
Process();
|
||||
}
|
||||
break;
|
||||
@ -104,7 +106,7 @@ void UInteractableScreenCapturer::Process()
|
||||
[
|
||||
capture = TextureTarget->GetResource()->TextureRHI,
|
||||
world = GetWorld(),
|
||||
view = _view,
|
||||
view = view,
|
||||
//output = _output->GetResource()->TextureRHI,
|
||||
this
|
||||
]
|
||||
@ -262,6 +264,7 @@ void UInteractableScreenCapturer::Process()
|
||||
AsyncTask(ENamedThreads::GameThread, [=, this]()
|
||||
{
|
||||
interactableInScreenDelegate.Execute(interactable);
|
||||
OnInteractableInScreen(interactable);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,10 @@
|
||||
|
||||
DECLARE_DELEGATE_OneParam(FInteractableInScreen, class AInteractable*);
|
||||
|
||||
UCLASS(hidecategories = (Collision, Object, Physics, SceneComponent), ClassGroup = Rendering, editinlinenew, meta = (BlueprintSpawnableComponent), MinimalAPI)
|
||||
/**
|
||||
* Notifies only once about interactable is in a camera view
|
||||
*/
|
||||
UCLASS(BlueprintType, hidecategories = (Collision, Object, Physics, SceneComponent), ClassGroup = Rendering, editinlinenew, meta = (BlueprintSpawnableComponent, ShortTooltip = "Notifies only once about interactable is in a camera view"), MinimalAPI)
|
||||
class UInteractableScreenCapturer : public USceneCaptureComponent2D
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@ -19,15 +22,18 @@ public:
|
||||
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
|
||||
|
||||
FInteractableInScreen interactableInScreenDelegate;
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void OnInteractableInScreen(class AInteractable* interactable);
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float scanDistance = 7000;
|
||||
|
||||
protected:
|
||||
/** Enques render thread task to find obect on screen */
|
||||
void Process();
|
||||
|
||||
private:
|
||||
FMinimalViewInfo _view;
|
||||
FMinimalViewInfo view; //!< Camera view cache
|
||||
TSet<class AInteractable*> _sawInteractables;
|
||||
//class UTextureRenderTarget2D* _output;
|
||||
};
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "RaycastInteractableActivator.h"
|
||||
|
||||
#include "DrawDebugHelpers.h"
|
||||
@ -14,12 +13,12 @@ URaycastInteractableActivator::URaycastInteractableActivator(const FObjectInitia
|
||||
|
||||
void URaycastInteractableActivator::Rescan_Implementation()
|
||||
{
|
||||
_last = nullptr;
|
||||
lastInteractable = nullptr;
|
||||
}
|
||||
|
||||
void URaycastInteractableActivator::Scan_Implementation()
|
||||
{
|
||||
FHitResult result{};
|
||||
FHitResult result;
|
||||
FVector startLocation = GetComponentLocation();
|
||||
FVector endLocation = startLocation + (GetComponentRotation().Vector() * scanDistance);
|
||||
|
||||
@ -32,17 +31,17 @@ void URaycastInteractableActivator::Scan_Implementation()
|
||||
|
||||
if(result.bBlockingHit)
|
||||
{
|
||||
if(_last != result.GetActor())
|
||||
if(lastInteractable != result.GetActor())
|
||||
{
|
||||
if(_last)
|
||||
if(lastInteractable)
|
||||
{
|
||||
interactableDeactivatedDelegate.Execute(_last, activatorType);
|
||||
_last = nullptr;
|
||||
interactableDeactivatedDelegate.Execute(lastInteractable, activatorType);
|
||||
lastInteractable = nullptr;
|
||||
}
|
||||
_activated = true;
|
||||
activated = true;
|
||||
if(auto interactable = Cast<AInteractable>(result.GetActor()))
|
||||
{
|
||||
_last = interactable;
|
||||
lastInteractable = interactable;
|
||||
if(interactableActivatedDelegate.IsBound())
|
||||
{
|
||||
interactableActivatedDelegate.Execute(interactable, activatorType);
|
||||
@ -53,21 +52,21 @@ void URaycastInteractableActivator::Scan_Implementation()
|
||||
#ifdef INTERACTABLE_ACTIVATOR_DEBUG
|
||||
DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Green, false, PrimaryComponentTick.TickInterval, 0, 0.1f);
|
||||
#endif // INTERACTABLE_ACTIVATOR_DEBUG
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(_activated)
|
||||
if(activated)
|
||||
{
|
||||
if(interactableDeactivatedDelegate.IsBound())
|
||||
{
|
||||
interactableDeactivatedDelegate.Execute(_last, activatorType);
|
||||
interactableDeactivatedDelegate.Execute(lastInteractable, activatorType);
|
||||
}
|
||||
_activated = false;
|
||||
_last = nullptr;
|
||||
activated = false;
|
||||
lastInteractable = nullptr;
|
||||
}
|
||||
|
||||
#ifdef INTERACTABLE_ACTIVATOR_DEBUG
|
||||
DrawDebugLine(GetWorld(), startLocation, endLocation, FColor::Red, false, PrimaryComponentTick.TickInterval, 10, 0.1f);
|
||||
#endif // INTERACTABLE_ACTIVATOR_DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,12 +2,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InteractableActivator.h"
|
||||
|
||||
#include "RaycastInteractableActivator.generated.h"
|
||||
|
||||
UCLASS(Blueprintable, BlueprintType)
|
||||
/**
|
||||
* Activates interactable with a single raycast from a camera center
|
||||
*/
|
||||
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableActivator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Activates interactable with a single raycast from a camera center"), MinimalAPI)
|
||||
class URaycastInteractableActivator : public UInteractableActivator
|
||||
{
|
||||
GENERATED_BODY()
|
||||
@ -15,12 +17,14 @@ class URaycastInteractableActivator : public UInteractableActivator
|
||||
public:
|
||||
URaycastInteractableActivator(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
virtual bool AutoInstantiateInPlayer() override { return true; }
|
||||
|
||||
virtual void Rescan_Implementation() override;
|
||||
|
||||
protected:
|
||||
virtual void Scan_Implementation() override;
|
||||
|
||||
private:
|
||||
class AInteractable* _last = nullptr;
|
||||
bool _activated = false;
|
||||
class AInteractable* lastInteractable = nullptr;
|
||||
bool activated = false;
|
||||
};
|
||||
|
@ -1,15 +1,38 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "Interactable.h"
|
||||
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
#include "Activators/InteractableActivator.h"
|
||||
#include "CustomPlayerController.h"
|
||||
#include "MainGameModeBase.h"
|
||||
#include "Modificators/InteractableModificator.h"
|
||||
#include "PlayerBase.h"
|
||||
#include "Widgets/WidgetsManager.h"
|
||||
|
||||
TSet<TSubclassOf<class UInteractableActivator>> AInteractable::interactionActivators = {};
|
||||
TSet<TSubclassOf<class UInteractableModificator>> AInteractable::interactionModificators = {};
|
||||
|
||||
void AInteractable::AppendActivatorClass(TSubclassOf<class UInteractableActivator> activator)
|
||||
{
|
||||
if(interactionActivators.Contains(activator))
|
||||
return;
|
||||
|
||||
interactionActivators.Add(activator);
|
||||
}
|
||||
|
||||
void AInteractable::AppendModificatorClass(TSubclassOf<class UInteractableModificator> modificator)
|
||||
{
|
||||
if(interactionModificators.Contains(modificator))
|
||||
return;
|
||||
|
||||
interactionModificators.Add(modificator);
|
||||
|
||||
auto IC = modificator.GetDefaultObject()->GetMappingContext();
|
||||
ACustomPlayerController::AppendInputContext(IC);
|
||||
}
|
||||
|
||||
int32 AInteractable::GetActivatedFlags()
|
||||
{
|
||||
return activated;
|
||||
@ -86,13 +109,13 @@ void AInteractable::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
if(activated)
|
||||
{
|
||||
activationLockers.Empty();
|
||||
_Deactivate(static_cast<EActivatorType>(activated));
|
||||
Deactivate(static_cast<EActivatorType>(activated));
|
||||
}
|
||||
|
||||
Super::EndPlay(EndPlayReason);
|
||||
}
|
||||
|
||||
void AInteractable::_Activate(EActivatorType type)
|
||||
void AInteractable::Activate(EActivatorType type)
|
||||
{
|
||||
#ifdef INTERACTABLE_DEBUG
|
||||
GEngine->AddOnScreenDebugMessage(30 + (int)type, 5.0f, FColor::Cyan, TEXT("Player activate: ") + this->GetName()
|
||||
@ -113,7 +136,7 @@ void AInteractable::_Activate(EActivatorType type)
|
||||
if(static_cast<uint8>(modificator.Value->GetActivatorTypes()) & static_cast<uint8>(type))
|
||||
{
|
||||
WM->ShowInteractionHints(modificator.Value);
|
||||
modificator.Value->Bind(player->inputComponent);
|
||||
modificator.Value->Bind(ACustomPlayerController::GetInput());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -124,10 +147,10 @@ void AInteractable::_Activate(EActivatorType type)
|
||||
collision->SetCustomDepthStencilValue(132);
|
||||
}
|
||||
|
||||
Activate(type);
|
||||
OnActivate(type);
|
||||
}
|
||||
|
||||
void AInteractable::_Deactivate(EActivatorType type)
|
||||
void AInteractable::Deactivate(EActivatorType type)
|
||||
{
|
||||
#ifdef INTERACTABLE_DEBUG
|
||||
GEngine->AddOnScreenDebugMessage(30 + (int)type, 5.0f, FColor::Magenta, TEXT("Player deactivate: ") + this->GetName()
|
||||
@ -159,5 +182,5 @@ void AInteractable::_Deactivate(EActivatorType type)
|
||||
collision->SetCustomDepthStencilValue(0);
|
||||
}
|
||||
|
||||
Deactivate(type);
|
||||
OnDeactivate(type);
|
||||
}
|
||||
|
@ -2,15 +2,18 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "GameFramework/Actor.h"
|
||||
|
||||
#include "Interactable.generated.h"
|
||||
|
||||
/** Turns on debug of interactable objects */
|
||||
//#define INTERACTABLE_DEBUG
|
||||
/** Turns on debug of interactable activator components */
|
||||
//#define INTERACTABLE_ACTIVATOR_DEBUG
|
||||
/** Turns on debug of interactable modificator components */
|
||||
//#define INTERACTABLE_MODIFICATOR_DEBUG
|
||||
|
||||
/** Defines activation types */
|
||||
UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true"))
|
||||
enum class EActivatorType : uint8
|
||||
{
|
||||
@ -27,38 +30,61 @@ enum class EActivatorType : uint8
|
||||
};
|
||||
ENUM_CLASS_FLAGS(EActivatorType);
|
||||
|
||||
/**
|
||||
* Object capable of reacting to activators and execute modificators.
|
||||
* Sets all needed settings as collision layers on begin play.
|
||||
*/
|
||||
UCLASS(Blueprintable, BlueprintType, MinimalAPI)
|
||||
class AInteractable : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
static void AppendActivatorClass(TSubclassOf<class UInteractableActivator> activator);
|
||||
static void AppendModificatorClass(TSubclassOf<class UInteractableModificator> modificator);
|
||||
|
||||
/** Interactables shared cache */
|
||||
static TSet<TSubclassOf<class UInteractableActivator>> interactionActivators;
|
||||
static TSet<TSubclassOf<class UInteractableModificator>> interactionModificators;
|
||||
|
||||
public:
|
||||
|
||||
/** Returns flags mask of activated types */
|
||||
int32 GetActivatedFlags();
|
||||
|
||||
void _Activate(EActivatorType type);
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
/** Receives activate signal from activator of specific type and activates all modificators of that type */
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void Activate(EActivatorType type);
|
||||
virtual void Activate_Implementation(EActivatorType type) {}
|
||||
|
||||
void _Deactivate(EActivatorType type);
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
/** Receives deactivate signal from activator of specific type and deactivates all modificators of that type */
|
||||
UFUNCTION(BlueprintCallable)
|
||||
void Deactivate(EActivatorType type);
|
||||
virtual void Deactivate_Implementation(EActivatorType type) {}
|
||||
|
||||
/**
|
||||
* All modificators that requires (de)activation lock for current interactable.
|
||||
* Used manually by modificators to handle operations which can be continued after physical deactivation.
|
||||
* Eg. MoveModificator movement while mouse buttons are down even if player don't activating interactable anymore.
|
||||
*/
|
||||
TSet<class UInteractableModificator*> activationLockers;
|
||||
|
||||
protected:
|
||||
virtual void BeginPlay() override;
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void OnActivate(EActivatorType type);
|
||||
UFUNCTION(BlueprintImplementableEvent)
|
||||
void OnDeactivate(EActivatorType type);
|
||||
|
||||
/** Mask of active activator types */
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (Bitmask, BitmaskEnum = "EActivatorType"))
|
||||
int32 activated = 0;
|
||||
|
||||
/** Map of modificators to activator types initialized on BeginPlay */
|
||||
UPROPERTY()
|
||||
TMap<EActivatorType, class UInteractableModificator*> modificators;
|
||||
|
||||
class APlayerBase* player = nullptr;
|
||||
TArray<UPrimitiveComponent*> collisions;
|
||||
|
||||
class APlayerBase* player = nullptr;
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "ActivateInteractableModificator.h"
|
||||
|
||||
#include "EnhancedInputComponent.h"
|
||||
|
@ -2,14 +2,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InteractableModificator.h"
|
||||
|
||||
#include "ActivateInteractableModificator.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FActivateInteractableModificatorActivatedDelegate);
|
||||
|
||||
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
|
||||
/**
|
||||
* Basic modificator for type Use
|
||||
*/
|
||||
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Basic modificator for type Use"), MinimalAPI)
|
||||
class UActivateInteractableModificator : public UInteractableModificator
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
@ -1,14 +1,11 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "EditInteractableModificator.h"
|
||||
|
||||
#include "Interactable/Interactable.h"
|
||||
|
||||
UEditInteractableModificator::UEditInteractableModificator(const FObjectInitializer& ObjectInitializer)
|
||||
: UInteractableModificator(ObjectInitializer)
|
||||
{
|
||||
activatorTypes |= static_cast<uint8>(EActivatorType::Collide);
|
||||
|
||||
|
||||
}
|
||||
//UEditInteractableModificator::UEditInteractableModificator(const FObjectInitializer& ObjectInitializer)
|
||||
// : UInteractableModificator(ObjectInitializer)
|
||||
//{
|
||||
// activatorTypes |= static_cast<uint8>(EActivatorType::Collide);
|
||||
//}
|
||||
|
@ -2,17 +2,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InteractableModificator.h"
|
||||
|
||||
#include "EditInteractableModificator.generated.h"
|
||||
//#include "EditInteractableModificator.generated.h"
|
||||
|
||||
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
|
||||
class UEditInteractableModificator : public UInteractableModificator
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UEditInteractableModificator(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
};
|
||||
/**
|
||||
* <WIP>
|
||||
* Edits object topology on collision
|
||||
*/
|
||||
//UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Edits object topology on collision"), MinimalAPI)
|
||||
//class UEditInteractableModificator : public UInteractableModificator
|
||||
//{
|
||||
// GENERATED_BODY()
|
||||
//
|
||||
//public:
|
||||
// UEditInteractableModificator(const FObjectInitializer& ObjectInitializer);
|
||||
//
|
||||
//};
|
||||
|
@ -1,29 +1,20 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "InteractableModificator.h"
|
||||
|
||||
#include "InputMappingContext.h"
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "Interactable/Interactable.h"
|
||||
#include "Widgets/InteractableHintWidget.h"
|
||||
|
||||
void UInteractableModificator::OnRegister()
|
||||
{
|
||||
UActorComponent::OnRegister();
|
||||
|
||||
if(auto world = GetWorld())
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(world->GetGameInstance()))
|
||||
{
|
||||
GI->AppendInteractableModificatorClass(this->GetClass());
|
||||
}
|
||||
}
|
||||
AInteractable::AppendModificatorClass(GetClass());
|
||||
}
|
||||
|
||||
const UInputMappingContext* UInteractableModificator::GetMappingContext() const
|
||||
const TSoftObjectPtr<class UInputMappingContext> UInteractableModificator::GetMappingContext() const
|
||||
{
|
||||
return inputMapping.LoadSynchronous();
|
||||
return inputMapping;
|
||||
}
|
||||
|
||||
EActivatorType UInteractableModificator::GetActivatorTypes() const
|
||||
|
@ -3,29 +3,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "Components/ActorComponent.h"
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "InteractableModificator.generated.h"
|
||||
|
||||
enum class EActivatorType : uint8;
|
||||
|
||||
UCLASS(Abstract, Blueprintable, BlueprintType)
|
||||
/**
|
||||
* Do something on activation by specified activator types
|
||||
*/
|
||||
UCLASS(Abstract, Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Do something on activation by specified activator types"), MinimalAPI)
|
||||
class UInteractableModificator : public UActorComponent
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
void OnRegister() override;
|
||||
/** Append itself to CustomGameInstance modificators registry */
|
||||
virtual void OnRegister() override;
|
||||
|
||||
/** Returns input mappings assigned in constructor */
|
||||
UFUNCTION(BlueprintCallable)
|
||||
const class UInputMappingContext* GetMappingContext() const;
|
||||
const TSoftObjectPtr<class UInputMappingContext> GetMappingContext() const;
|
||||
|
||||
/** Filters activation type in interractable */
|
||||
UFUNCTION(BlueprintCallable)
|
||||
EActivatorType GetActivatorTypes() const;
|
||||
|
||||
/** Called from interactable on activation (mostly used to bind input context to internal modificator functions) */
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void Bind(class UEnhancedInputComponent* input);
|
||||
virtual void Bind_Implementation(class UEnhancedInputComponent* input) {}
|
||||
|
||||
/** Called from interactable on deactivation (mostly used to unbind input context from internal functions) */
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void Unbind();
|
||||
virtual void Unbind_Implementation() {}
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "InventoryInteractableModificator.h"
|
||||
|
||||
#include "EnhancedInputComponent.h"
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InteractableModificator.h"
|
||||
|
||||
#include "InventoryInteractableModificator.generated.h"
|
||||
|
||||
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
|
||||
/**
|
||||
* Modificator of type Use for storing items in a APlayerBase
|
||||
*/
|
||||
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Modificator of type Use for storing items in a APlayerBase"), MinimalAPI)
|
||||
class UInventoryInteractableModificator : public UInteractableModificator
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "MoveInteractableModificator.h"
|
||||
|
||||
#include "EnhancedInputComponent.h"
|
||||
@ -90,7 +89,7 @@ void UMoveInteractableModificator::Unbind_Implementation()
|
||||
bindindingHandlers.Empty();
|
||||
|
||||
SetComponentTickEnabled(false);
|
||||
actor->_Deactivate(GetActivatorTypes());
|
||||
actor->Deactivate(GetActivatorTypes());
|
||||
|
||||
OnMoveDeactivated.Broadcast();
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InputActionValue.h"
|
||||
#include "InteractableModificator.h"
|
||||
|
||||
@ -13,7 +12,10 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE(FDeactivateMoveInteractableModificatorActivat
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FHoldingMoveInteractableModificatorActivatedDelegate);
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FRotatingMoveInteractableModificatorActivatedDelegate);
|
||||
|
||||
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
|
||||
/**
|
||||
* Basic modificator for Move type activator
|
||||
*/
|
||||
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Basic modificator for Move type activator"), MinimalAPI)
|
||||
class UMoveInteractableModificator : public UInteractableModificator
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "SawInteractableModificator.h"
|
||||
|
||||
#include "Interactable/Interactable.h"
|
||||
|
@ -2,14 +2,16 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "InteractableModificator.h"
|
||||
|
||||
#include "SawInteractableModificator.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FSawInteractableModificatorActivatedDelegate);
|
||||
|
||||
UCLASS(ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent), Blueprintable, BlueprintType)
|
||||
/**
|
||||
* Basic modificator for Saw type activator
|
||||
*/
|
||||
UCLASS(Blueprintable, BlueprintType, ClassGroup = InteractableModificator, meta = (BlueprintSpawnableComponent, ShortTooltip = "Basic modificator for Saw type activator"), MinimalAPI)
|
||||
class USawInteractableModificator : public UInteractableModificator
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
@ -1,12 +1,11 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "Checkpoint.h"
|
||||
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "CustomGameInstance.h"
|
||||
|
||||
void ACheckpoint::SaveGame()
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
|
||||
if(auto GI = UCustomGameInstance::Get())
|
||||
GI->SaveGame(GetFName());
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "Checkpoint.generated.h"
|
||||
|
||||
/** Simple actor for game save */
|
||||
UCLASS(Blueprintable, BlueprintType, MinimalAPI)
|
||||
class ACheckpoint : public AActor
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "Level1.h"
|
||||
|
||||
#include "Atmosphere/AtmosphericFog.h"
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "Level2.h"
|
||||
|
||||
void ALevel2::BeginPlay()
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "Level3.h"
|
||||
|
||||
#include "Atmosphere/AtmosphericFog.h"
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "Level4.h"
|
||||
|
||||
#include "Atmosphere/AtmosphericFog.h"
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "Level5.h"
|
||||
|
||||
#include "Atmosphere/AtmosphericFog.h"
|
||||
|
@ -1,6 +1,5 @@
|
||||
// Oleg Petruny proprietary.
|
||||
|
||||
|
||||
#include "LevelBase.h"
|
||||
|
||||
#include "Engine/StaticMesh.h"
|
||||
@ -10,8 +9,8 @@
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
#include "LevelSequencePlayer.h"
|
||||
|
||||
#include "CommonFunctions.h"
|
||||
#include "CustomGameInstanceBase.h"
|
||||
#include "CustomGameInstance.h"
|
||||
#include "CustomPlayerController.h"
|
||||
#include "Interactable/Interactable.h"
|
||||
#include "Levels/Checkpoint.h"
|
||||
#include "MainGameModeBase.h"
|
||||
@ -19,21 +18,17 @@
|
||||
#include "PlayerBase.h"
|
||||
#include "SaveData.h"
|
||||
|
||||
ALevelBase* ALevelBase::Get()
|
||||
{
|
||||
if(auto GM = AMainGameModeBase::Get())
|
||||
return GM->leadLevel.Get();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ALevelBase::BeginPlay()
|
||||
{
|
||||
AMainGameModeBase::leadLevel = TStrongObjectPtr<ALevelBase>{ this };
|
||||
|
||||
if(auto world = GetWorld())
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(world->GetGameInstance()))
|
||||
{
|
||||
for(TActorIterator<AMinigame> it(GetWorld()); it; ++it)
|
||||
{
|
||||
GI->inputContexts.Add(it->GetInputMappings());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ALevelScriptActor::BeginPlay();
|
||||
|
||||
BroadcastNewLevelBeginPlay();
|
||||
@ -62,7 +57,7 @@ void ALevelBase::IterateToState(int32 to)
|
||||
|
||||
void ALevelBase::BroadcastNewLevelBeginPlay()
|
||||
{
|
||||
if(auto GI = Cast<UCustomGameInstanceBase>(GetWorld()->GetGameInstance()))
|
||||
if(auto GI = UCustomGameInstance::Get())
|
||||
GI->OnLevelBeginned.Broadcast(GetFName());
|
||||
}
|
||||
|
||||
@ -83,13 +78,13 @@ void ALevelBase::StartLevelAnimations()
|
||||
|
||||
void ALevelBase::ApplySaveData()
|
||||
{
|
||||
auto GI = UCustomGameInstanceBase::GetGameInstance();
|
||||
auto GI = UCustomGameInstance::Get();
|
||||
if(!GI || !GI->saveData || GI->saveData->level != GetWorld()->GetFName())
|
||||
return;
|
||||
|
||||
IterateToState(GI->saveData->state);
|
||||
|
||||
auto player = UCommonFunctions::GetPlayer(this);
|
||||
auto player = APlayerBase::Get();
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user