├── .gitattributes ├── .github ├── FUNDING.yml └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── ActorInteractionPlugin.uplugin ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Config ├── DefaultActorInteractionPlugin.ini ├── DefaultMounteaSettings.ini ├── FilterPlugin.ini └── Tags │ └── MounteaInteractionSystemTags.ini ├── Content ├── Blueprints │ ├── Components │ │ ├── Interactable │ │ │ ├── BPC_InteractableAuto.uasset │ │ │ ├── BPC_InteractableHold.uasset │ │ │ ├── BPC_InteractableHover.uasset │ │ │ ├── BPC_InteractableMash.uasset │ │ │ └── BPC_InteractablePress.uasset │ │ └── Interactor │ │ │ ├── BPC_InteractorOverlap.uasset │ │ │ └── BPC_InteractorTrace.uasset │ └── Structures │ │ └── S_InteractionData.uasset ├── Config │ └── DA_DefaultInteactionConfig.uasset ├── Data │ └── DT_InteractionData.uasset ├── Example │ ├── BP_InteractinExample_GameMode.uasset │ ├── BP_InteractionExample_Character.uasset │ ├── BP_InteractionExample_NPC.uasset │ └── M_Example.umap ├── Input │ ├── IA_Interact.uasset │ ├── IA_Interact_Controller.uasset │ ├── IA_Jump.uasset │ ├── IA_Look.uasset │ ├── IA_Move.uasset │ ├── IMC_Default.uasset │ └── IMC_Interact.uasset ├── Localization │ └── ST_ExampleLocalization.uasset ├── Materials │ ├── Circle │ │ ├── MI_CircleFull_Hard.uasset │ │ ├── MI_CircleFull_Soft.uasset │ │ └── M_CircleFull.uasset │ ├── CircularProgressBar │ │ ├── MI_CircularProgressBar.uasset │ │ └── M_CircularProgressBar.uasset │ ├── GlowingDot │ │ ├── MI_PulsingDotV1.uasset │ │ ├── MI_PulsingDotV2.uasset │ │ ├── M_PulsingDotV1.uasset │ │ └── M_PulsingDotV2.uasset │ ├── Gradient │ │ ├── MI_Gradient.uasset │ │ └── M_Gradient.uasset │ ├── Lines │ │ ├── MI_Lines.uasset │ │ └── M_TopBottomLines.uasset │ ├── NoisyProgressBar │ │ ├── MI_ProgressBar.uasset │ │ └── M_ProgressBar.uasset │ ├── OutlineSquare │ │ ├── MI_EdgedSquare.uasset │ │ └── M_EdgedSquare.uasset │ ├── OverlayMaterial │ │ ├── MI_OverlayMaterial.uasset │ │ ├── MI_OverlayMaterial_Glowing.uasset │ │ ├── MI_OverlayMaterial_Noisy.uasset │ │ ├── M_OverlayMaterial.uasset │ │ └── M_OverlayMaterial_Glowing.uasset │ ├── PostProcessMaterials │ │ ├── Outline │ │ │ ├── MI_Outline.uasset │ │ │ └── M_Outline.uasset │ │ ├── OutlineGlowing │ │ │ ├── MI_OutlineGlowing.uasset │ │ │ └── M_OutlineGlowing.uasset │ │ ├── OutlineOverlay │ │ │ ├── MI_OutlineOverlay.uasset │ │ │ └── M_OutlineOverlay.uasset │ │ ├── OutlineOverlayGlowing │ │ │ ├── MI_OutlineOverlayGlowing.uasset │ │ │ └── M_OutlineOverlayGlowing.uasset │ │ ├── Overlay │ │ │ ├── MI_Overlay.uasset │ │ │ └── M_Overlay.uasset │ │ └── OverlayGlowing │ │ │ ├── MI_OverlayGlowing.uasset │ │ │ └── M_OverlayGlowing.uasset │ ├── Radials │ │ ├── MI_Radials.uasset │ │ └── M_Radials.uasset │ └── Triangle │ │ ├── MI_Triangle.uasset │ │ └── M_Triangle.uasset ├── Misc │ └── Localization │ │ └── ST_InteractableNames.uasset ├── Textures │ ├── Editor │ │ └── T_MounteaLogo.uasset │ ├── Keys │ │ ├── T_Key_GamepadFaceButtonBottm_Switch.uasset │ │ ├── T_Key_GamepadFaceButtonBottom_PS.uasset │ │ ├── T_Key_GamepadFaceButtonBottom_XBX.uasset │ │ └── T_Key_MKB_F.uasset │ └── Noise │ │ └── T_Voronoi.uasset └── UMG │ ├── Base │ └── WBP_InteractableBase.uasset │ ├── Examples │ ├── WBP_InteractableWidget_01.uasset │ ├── WBP_InteractableWidget_02.uasset │ ├── WBP_InteractableWidget_03.uasset │ ├── WBP_InteractableWidget_04.uasset │ ├── WBP_InteractableWidget_05.uasset │ ├── WBP_InteractableWidget_06.uasset │ ├── WBP_InteractableWidget_07.uasset │ ├── WBP_InteractableWidget_08.uasset │ ├── WBP_InteractableWidget_09.uasset │ └── WBP_InteractableWidget_10.uasset │ └── Generic │ ├── WBP_Circle.uasset │ └── WBP_InteractableWidget_Empty.uasset ├── LICENSE ├── README.md ├── Resources ├── CloseIcon.png ├── Dialoguer_Icon.png ├── HeartIcon.png ├── Help_Icon.png ├── Icon128.png ├── InteractableIcon.png ├── InteractionConfigIcon.png ├── InteractorIcon.png ├── MPLIcon.png ├── MoneyIcon.png ├── Mountea_Logo.png ├── UnrealBucketIcon.png ├── Wiki_Icon.png ├── settings_icon.png ├── tutorialPage_icon.png └── youtube_icon.png └── Source ├── ActorInteractionPlugin ├── ActorInteractionPlugin.Build.cs ├── Private │ ├── ActorInteractionPlugin.cpp │ ├── Components │ │ ├── Interactable │ │ │ ├── ActorInteractableComponentAutomatic.cpp │ │ │ ├── ActorInteractableComponentBase.cpp │ │ │ ├── ActorInteractableComponentHold.cpp │ │ │ ├── ActorInteractableComponentHover.cpp │ │ │ ├── ActorInteractableComponentMash.cpp │ │ │ └── ActorInteractableComponentPress.cpp │ │ └── Interactor │ │ │ ├── ActorInteractorComponentBase.cpp │ │ │ ├── ActorInteractorComponentOverlap.cpp │ │ │ └── ActorInteractorComponentTrace.cpp │ └── Helpers │ │ ├── ActorInteractionFunctionLibrary.cpp │ │ ├── ActorInteractionPluginSettings.cpp │ │ ├── MounteaInteractionHelperEvents.cpp │ │ ├── MounteaInteractionSettingsConfig.cpp │ │ └── MounteaInteractionSystemBFL.cpp └── Public │ ├── ActorInteractionPlugin.h │ ├── Components │ ├── Interactable │ │ ├── ActorInteractableComponentAutomatic.h │ │ ├── ActorInteractableComponentBase.h │ │ ├── ActorInteractableComponentHold.h │ │ ├── ActorInteractableComponentHover.h │ │ ├── ActorInteractableComponentMash.h │ │ └── ActorInteractableComponentPress.h │ └── Interactor │ │ ├── ActorInteractorComponentBase.h │ │ ├── ActorInteractorComponentOverlap.h │ │ └── ActorInteractorComponentTrace.h │ ├── Helpers │ ├── ActorInteractionFunctionLibrary.h │ ├── ActorInteractionPluginLog.cpp │ ├── ActorInteractionPluginLog.h │ ├── ActorInteractionPluginSettings.h │ ├── InteractionHelpers.h │ ├── MounteaInteractionGeneralDataTypes.h │ ├── MounteaInteractionHelperEvents.h │ ├── MounteaInteractionSettingsConfig.h │ └── MounteaInteractionSystemBFL.h │ └── Interfaces │ ├── ActorInteractableInterface.h │ ├── ActorInteractionWidget.h │ └── ActorInteractorInterface.h ├── ActorInteractionPluginEditor ├── ActorInteractionPluginEditor.Build.cs ├── Private │ ├── ActorInteractionPluginEditor.cpp │ ├── AssetActions │ │ ├── InteractableComponentAssetActions.h │ │ ├── InteractionSettingsConfig.h │ │ └── InteractorComponentAssetActions.h │ ├── DetailsPanel │ │ ├── MounteaInteractableBase_DetailsPanel.cpp │ │ └── MounteaInteractableBase_DetailsPanel.h │ ├── Factories │ │ ├── ActorInteractionClassViewerFilter.h │ │ ├── InteractableComponentAssetFactory.cpp │ │ ├── InteractableComponentAssetFactory.h │ │ ├── InteractionSettingsConfigAssetFactory.cpp │ │ ├── InteractionSettingsConfigAssetFactory.h │ │ ├── InteractorComponentAssetFactory.cpp │ │ └── InteractorComponentAssetFactory.h │ ├── HelpButton │ │ ├── AIntPCommands.cpp │ │ ├── AIntPCommands.h │ │ ├── AIntPHelpStyle.cpp │ │ ├── AIntPHelpStyle.h │ │ ├── InteractionSystemTutorialPage.cpp │ │ └── InteractionSystemTutorialPage.h │ ├── Helpers │ │ ├── MounteaInteractionSystemEditorLog.cpp │ │ └── MounteaInteractionSystemEditorLog.h │ ├── Popup │ │ ├── AIntPPopup.cpp │ │ ├── AIntPPopup.h │ │ └── AIntPPopupConfig.h │ ├── Settings │ │ ├── MounteaInteractionEditorSettings.cpp │ │ └── MounteaInteractionEditorSettings.h │ └── Utilities │ │ ├── ActorInteractionEditorUtilities.cpp │ │ └── ActorInteractionEditorUtilities.h └── Public │ └── ActorInteractionPluginEditor.h └── InteractionEditorNotifications ├── InteractionEditorNotifications.build.cs ├── Private ├── EditorHelper.cpp └── InteractionEditorNotifications.cpp └── Public ├── EditorHelper.h └── InteractionEditorNotifications.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: Mountea-Framework 4 | patreon: mountea 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Visual Studio 2015 user specific files 2 | .vs/ 3 | .idea/* 4 | 5 | # Compiled Object files 6 | *.slo 7 | *.lo 8 | *.o 9 | *.obj 10 | 11 | # Precompiled Headers 12 | *.gch 13 | *.pch 14 | 15 | # Compiled Dynamic libraries 16 | *.so 17 | *.dylib 18 | *.dll 19 | 20 | # Fortran module files 21 | *.mod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | *.ipa 34 | 35 | # These project files can be generated by the engine 36 | *.xcodeproj 37 | *.xcworkspace 38 | *.sln 39 | *.suo 40 | *.opensdf 41 | *.sdf 42 | *.VC.db 43 | *.VC.opendb 44 | 45 | # Precompiled Assets 46 | SourceArt/**/*.png 47 | SourceArt/**/*.tga 48 | 49 | # Binary Files 50 | Binaries/* 51 | Plugins/*/Binaries/* 52 | 53 | # Builds 54 | Build/* 55 | 56 | # Whitelist PakBlacklist-.txt files 57 | !Build/*/ 58 | Build/*/** 59 | !Build/*/PakBlacklist*.txt 60 | 61 | # Don't ignore icon files in Build 62 | !Build/**/*.ico 63 | 64 | # Built data for maps 65 | *_BuiltData.uasset 66 | 67 | # Configuration files generated by the Editor 68 | Saved/* 69 | 70 | # Compiled source files for the engine to use 71 | Intermediate/* 72 | Plugins/*/Intermediate/* 73 | 74 | # Cache files for the editor to use 75 | DerivedDataCache/* 76 | 77 | # Visual Studio 78 | .vscode/* 79 | .idea/* 80 | Config/UpdateConfig.ini 81 | *.zip 82 | *.png~ 83 | -------------------------------------------------------------------------------- /ActorInteractionPlugin.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 4, 4 | "VersionName": "4.2.3.55", 5 | "FriendlyName": "Mountea Interaction System", 6 | "Description": "Mountea Interaction System is an Open-source Mountea Framework components-based simple framework providing utilities for smart Actor Interaction with other Actors.\nDeveloped with Game Developers in mind to allow as easy as possible implementation while maintaining high scalability and diverse options to tweak everything.", 7 | "Category": "Mountea Framework", 8 | "CreatedBy": "Dominik (Pavlicek) Morse", 9 | "CreatedByURL": "https://github.com/Mountea-Framework", 10 | "DocsURL": "https://github.com/Mountea-Framework/MounteaInteractionSystem/wiki", 11 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/ca842c00ec0d4db0b3aad17701e1637b", 12 | "SupportURL": "https://bit.ly/DominikPavlicek_SupportServer", 13 | "EngineVersion": "5.5.0", 14 | "CanContainContent": true, 15 | "IsBetaVersion": false, 16 | "IsExperimentalVersion": false, 17 | "Installed": true, 18 | "Modules": [ 19 | { 20 | "Name": "ActorInteractionPlugin", 21 | "Type": "Runtime", 22 | "LoadingPhase": "PreDefault", 23 | "PlatformAllowList": [ 24 | "Win64", 25 | "Mac", 26 | "Linux" 27 | ] 28 | }, 29 | { 30 | "Name": "ActorInteractionPluginEditor", 31 | "Type": "Editor", 32 | "LoadingPhase": "Default" 33 | }, 34 | { 35 | "Name": "InteractionEditorNotifications", 36 | "Type": "Editor", 37 | "LoadingPhase": "Default" 38 | } 39 | ], 40 | "Plugins": [ 41 | { 42 | "Name": "EnhancedInput", 43 | "Enabled": true 44 | }, 45 | { 46 | "Name": "CommonUI", 47 | "Enabled": true 48 | } 49 | ] 50 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Current Version: 4.2.3.55 2 | 3 | # Changelog 4 | 5 | All notable changes to this project will be documented in this file. 6 | 7 | ** Version 4.2.3 ** 8 | ### Added 9 | > - Toolbar Tutorial button 10 | 11 | ### Changed 12 | > - Ribbon Button to Guide Player 13 | > - - Design now matches `Dialogue System` 14 | > - Emoji for Content Browser menu 15 | 16 | ### Fixed 17 | > - Compilation errors for `HighlightableComponents` 18 | > - Conflicting `PrintLog` functions with other systems 19 | > - `SetLifecycleCount` can set count to -1 20 | > - `SetCooldownPeriod` now really sets Cooldown period 21 | > - Editor crash for `InteractableBase` 22 | 23 | ** Version 4.2.1 ** 24 | ### Added 25 | > - Support for **5.5** 26 | 27 | ### Changed 28 | > - Ribbon Button to Guide Player 29 | > - - Design now matches `Dialogue System` 30 | > - Events in `Interactor` are now re-arranged to logical order 31 | 32 | ### Fixed 33 | > - 34 | 35 | ** Version 4.2.0 ** 36 | ### Added 37 | > - Auto Gameplay Tags download 38 | > - - This way default Gameplay Tags will always be present 39 | 40 | ### Changed 41 | > - *Participant* now has button in Details panel to *Load Defaults* 42 | > - - This button is available for instances in Level as well as for base Blueprint classes 43 | > - Right-click menu updated 44 | > - - Menu is now on top 45 | > - Toolbar Ribbon buttons reworked 46 | > - - Dropdown menu now offers more links with better descriptions 47 | > - Updated welcome screen 48 | 49 | ### Fixed 50 | > - Fixed build issues with default data 51 | > - Fixed editor issues with changing properties using code 52 | > - Fixed *WBP_InteractableBase* icons loading issues 53 | > - Fixed broken Input Actions and Mappings 54 | 55 | ** Version 4.0.0 ** 56 | ### Changed 57 | > - Interfaces are now much more exposed to blueprints 58 | > - - almost all functions are now Blueprint Native Events, therefore allows BP overriding 59 | > - ***Replication*** of the whole system 60 | > - Example UI is now unified and contains even more examples 61 | > - System is updated to work with *Enhanced Input* 62 | > - Interactable is now completely passive 63 | > - - all logic is driven by Interactor component 64 | > - Added new Editor/Debug Build logging to Console and Screen 65 | > - Whole interactor system now contains additional safety trace to avoid starting interaction while obstacles are in a way 66 | > - - If you have interactable behind a wall and its interaction collision is peaking through it a safety check is cast based on different collision channel (camera by default) to ensure you can see the interactable 67 | > - Added regex replacement for better managing Interaction Data in data table 68 | > - Added Gameplay Tag support to further refine searching for interactables 69 | > - Added automatic UI switching based on Input Mode, Platform & Input Device 70 | > - - This way button "A" can be mapped for Xbox Controller and "X" for PS5 Controller (only for Platforms now, hardware ID is not available for now) 71 | > - Added dependency on `CommonUI` 72 | > - Added dependency on `EnhancedInput` 73 | 74 | ### Fixed 75 | > - Fixed old interaction widgets 76 | > - Fixed many small issues 77 | > - Fixed loosing interactor after pausing interaction 78 | 79 | ** Version 3.0.1 ** 80 | ### Added 81 | > - Added: Improved performance for Consoles and Mobile devices 82 | ### Fixed 83 | > - Fixed: Wrong state machine decisions when going from Cooldown to Awake for Interactables 84 | ### Changed 85 | > - Changed: Deprecated *SnoozeInteractable* functions 86 | > - Changed: Depreacted *Asleep* Interactable State 87 | 88 | ** Version 3.0.0 ** 89 | ### Added 90 | > - Added: New Interactor Component Base Class implementing IActorInteractorInterface 91 | > - Added: Child Classes for this new Interactor Base class, replacing existing monolithic ActorInteractorComponent solution 92 | > - Added: New Interactable Base Component class implementing IActorInteractableInterface 93 | > - Added: New child Classes for this new Interactable Base class, replacing existing monolithic ActorInteractableComponent solution 94 | > - Added: New Interactable Widget Interface for easier communication between Widgets and Interactables 95 | > - Added: Editor billboard so Interactable Components are now easier to spot 96 | > - Added: New Overlay Materials (for 5.1 only) 97 | ### Fixed 98 | > - Fixed: Missing descriptions for multiple functions 99 | > - Fixed: Missing descriptions for multiple variables 100 | ### Changed 101 | > - Changed: Added explicit warning about using old Interactor and Interactable Components 102 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | dominikpavlicek.business@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Actor Interaction Plugin 2 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: 3 | 4 | - Reporting a bug 5 | - Discussing the current state of the code 6 | - Submitting a fix 7 | - Proposing new features 8 | - Becoming a maintainer 9 | 10 | ## We Develop with Github 11 | We use github to host code, to track issues and feature requests, as well as accept pull requests. 12 | 13 | ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests 14 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: 15 | 16 | 1. Fork the repo and create your branch from `master` or Engine Version specific branch. 17 | 2. If you've added code that should be tested, add tests. 18 | 3. If you've changed APIs, update the documentation. 19 | 4. Ensure the test suite passes. 20 | 5. Make sure your code lints. 21 | 6. Issue that pull request! 22 | 23 | ## Any contributions you make will be under the MIT Software License 24 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. 25 | 26 | ## Report bugs using Github's [issues](https://github.com/Mountea-Framework/ActorInteractionPlugin/issues) 27 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](); it's that easy! 28 | 29 | ## Write bug reports with detail, background, and sample code 30 | [This is an example](http://stackoverflow.com/q/12488905/180626) of a bug report I wrote, and I think it's not a bad model. Here's [another example from Craig Hockenberry](http://www.openradar.me/11905408), an app developer whom I greatly respect. 31 | 32 | **Great Bug Reports** tend to have: 33 | 34 | - A quick summary and/or background 35 | - Steps to reproduce 36 | - Be specific! 37 | - Give sample code if you can. [My stackoverflow question](http://stackoverflow.com/q/12488905/180626) includes sample code that *anyone* with a base R setup can run to reproduce what I was seeing 38 | - What you expected would happen 39 | - What actually happens 40 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 41 | 42 | People *love* thorough bug reports. I'm not even kidding. 43 | 44 | ## Use a Consistent Coding Style 45 | I'm again borrowing these from [Facebook's Guidelines](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) 46 | 47 | * 2 spaces for indentation rather than tabs 48 | 49 | ## License 50 | By contributing, you agree that your contributions will be licensed under its MIT License. 51 | 52 | ## References 53 | This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) 54 | -------------------------------------------------------------------------------- /Config/DefaultActorInteractionPlugin.ini: -------------------------------------------------------------------------------- 1 | [CoreRedirects] 2 | +PropertyRedirects=(OldName="/Script/ActorInteractionPlugin.ActorInteractorComponentBase.OnInteractableSelected",NewName="/Script/ActorInteractionPlugin.ActorInteractorComponentBase.OnInteractableUpdated") 3 | +FunctionRedirects=(OldName="/Script/ActorInteractionPlugin.IActorInteractorInterface.WakeUpInteractor",NewName="/Script/ActorInteractionPlugin.IActorInteractorInterface.EnableInteractor") 4 | +StructRedirects=(OldName="/Script/ActorInteractionPlugin.InteractorSettings",NewName="/Script/ActorInteractionPlugin.InteractorBaseSettings") 5 | +PropertyRedirects=(OldName="/Script/ActorInteractionPlugin.ActorInteractableComponentBase.InteractionDeviceChanged",NewName="/Script/ActorInteractionPlugin.ActorInteractableComponentBase.OnInteractionDeviceChanged") -------------------------------------------------------------------------------- /Config/DefaultMounteaSettings.ini: -------------------------------------------------------------------------------- 1 | 2 | 3 | [/Script/ActorInteractionPlugin.ActorInteractionPluginSettings] 4 | DefaultInteractionSystemConfig=/ActorInteractionPlugin/Config/DA_DefaultInteactionConfig.DA_DefaultInteactionConfig 5 | bEditorDebugEnabled=True 6 | WidgetUpdateFrequency=0.100000 7 | InteractableDefaultWidgetClass=/ActorInteractionPlugin/UMG/Examples/WBP_InteractableWidget_01.WBP_InteractableWidget_01_C 8 | InteractableDefaultDataTable=/ActorInteractionPlugin/Data/DT_InteractionData.DT_InteractionData 9 | InteractionInputMapping=/ActorInteractionPlugin/Input/IMC_Interact.IMC_Interact -------------------------------------------------------------------------------- /Config/FilterPlugin.ini: -------------------------------------------------------------------------------- 1 | [FilterPlugin] 2 | .../Tags/MounteaInteractionSystemTags.ini 3 | ...DefaultMounteaSettings.ini 4 | ...DefaultActorInteractionPlugin.ini -------------------------------------------------------------------------------- /Config/Tags/MounteaInteractionSystemTags.ini: -------------------------------------------------------------------------------- 1 | [/Script/GameplayTags.GameplayTagsList] 2 | GameplayTagList=(Tag="Mountea_Interaction",DevComment="Root tag for Mountea Interaction System") 3 | GameplayTagList=(Tag="Mountea_Interaction.Interactor",DevComment="") 4 | GameplayTagList=(Tag="Mountea_Interaction.Interactor.NPC",DevComment="") 5 | GameplayTagList=(Tag="Mountea_Interaction.Interactor.Player",DevComment="") 6 | GameplayTagList=(Tag="Mountea_Interaction.Interactable",DevComment="") 7 | GameplayTagList=(Tag="Mountea_Interaction.Interactable.NPC",DevComment="") 8 | GameplayTagList=(Tag="Mountea_Interaction.Interactable.Player",DevComment="") -------------------------------------------------------------------------------- /Content/Blueprints/Components/Interactable/BPC_InteractableAuto.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Blueprints/Components/Interactable/BPC_InteractableAuto.uasset -------------------------------------------------------------------------------- /Content/Blueprints/Components/Interactable/BPC_InteractableHold.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Blueprints/Components/Interactable/BPC_InteractableHold.uasset -------------------------------------------------------------------------------- /Content/Blueprints/Components/Interactable/BPC_InteractableHover.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Blueprints/Components/Interactable/BPC_InteractableHover.uasset -------------------------------------------------------------------------------- /Content/Blueprints/Components/Interactable/BPC_InteractableMash.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Blueprints/Components/Interactable/BPC_InteractableMash.uasset -------------------------------------------------------------------------------- /Content/Blueprints/Components/Interactable/BPC_InteractablePress.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Blueprints/Components/Interactable/BPC_InteractablePress.uasset -------------------------------------------------------------------------------- /Content/Blueprints/Components/Interactor/BPC_InteractorOverlap.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Blueprints/Components/Interactor/BPC_InteractorOverlap.uasset -------------------------------------------------------------------------------- /Content/Blueprints/Components/Interactor/BPC_InteractorTrace.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Blueprints/Components/Interactor/BPC_InteractorTrace.uasset -------------------------------------------------------------------------------- /Content/Blueprints/Structures/S_InteractionData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Blueprints/Structures/S_InteractionData.uasset -------------------------------------------------------------------------------- /Content/Config/DA_DefaultInteactionConfig.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Config/DA_DefaultInteactionConfig.uasset -------------------------------------------------------------------------------- /Content/Data/DT_InteractionData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Data/DT_InteractionData.uasset -------------------------------------------------------------------------------- /Content/Example/BP_InteractinExample_GameMode.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Example/BP_InteractinExample_GameMode.uasset -------------------------------------------------------------------------------- /Content/Example/BP_InteractionExample_Character.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Example/BP_InteractionExample_Character.uasset -------------------------------------------------------------------------------- /Content/Example/BP_InteractionExample_NPC.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Example/BP_InteractionExample_NPC.uasset -------------------------------------------------------------------------------- /Content/Example/M_Example.umap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Example/M_Example.umap -------------------------------------------------------------------------------- /Content/Input/IA_Interact.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Input/IA_Interact.uasset -------------------------------------------------------------------------------- /Content/Input/IA_Interact_Controller.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Input/IA_Interact_Controller.uasset -------------------------------------------------------------------------------- /Content/Input/IA_Jump.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Input/IA_Jump.uasset -------------------------------------------------------------------------------- /Content/Input/IA_Look.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Input/IA_Look.uasset -------------------------------------------------------------------------------- /Content/Input/IA_Move.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Input/IA_Move.uasset -------------------------------------------------------------------------------- /Content/Input/IMC_Default.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Input/IMC_Default.uasset -------------------------------------------------------------------------------- /Content/Input/IMC_Interact.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Input/IMC_Interact.uasset -------------------------------------------------------------------------------- /Content/Localization/ST_ExampleLocalization.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Localization/ST_ExampleLocalization.uasset -------------------------------------------------------------------------------- /Content/Materials/Circle/MI_CircleFull_Hard.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Circle/MI_CircleFull_Hard.uasset -------------------------------------------------------------------------------- /Content/Materials/Circle/MI_CircleFull_Soft.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Circle/MI_CircleFull_Soft.uasset -------------------------------------------------------------------------------- /Content/Materials/Circle/M_CircleFull.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Circle/M_CircleFull.uasset -------------------------------------------------------------------------------- /Content/Materials/CircularProgressBar/MI_CircularProgressBar.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/CircularProgressBar/MI_CircularProgressBar.uasset -------------------------------------------------------------------------------- /Content/Materials/CircularProgressBar/M_CircularProgressBar.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/CircularProgressBar/M_CircularProgressBar.uasset -------------------------------------------------------------------------------- /Content/Materials/GlowingDot/MI_PulsingDotV1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/GlowingDot/MI_PulsingDotV1.uasset -------------------------------------------------------------------------------- /Content/Materials/GlowingDot/MI_PulsingDotV2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/GlowingDot/MI_PulsingDotV2.uasset -------------------------------------------------------------------------------- /Content/Materials/GlowingDot/M_PulsingDotV1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/GlowingDot/M_PulsingDotV1.uasset -------------------------------------------------------------------------------- /Content/Materials/GlowingDot/M_PulsingDotV2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/GlowingDot/M_PulsingDotV2.uasset -------------------------------------------------------------------------------- /Content/Materials/Gradient/MI_Gradient.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Gradient/MI_Gradient.uasset -------------------------------------------------------------------------------- /Content/Materials/Gradient/M_Gradient.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Gradient/M_Gradient.uasset -------------------------------------------------------------------------------- /Content/Materials/Lines/MI_Lines.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Lines/MI_Lines.uasset -------------------------------------------------------------------------------- /Content/Materials/Lines/M_TopBottomLines.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Lines/M_TopBottomLines.uasset -------------------------------------------------------------------------------- /Content/Materials/NoisyProgressBar/MI_ProgressBar.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/NoisyProgressBar/MI_ProgressBar.uasset -------------------------------------------------------------------------------- /Content/Materials/NoisyProgressBar/M_ProgressBar.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/NoisyProgressBar/M_ProgressBar.uasset -------------------------------------------------------------------------------- /Content/Materials/OutlineSquare/MI_EdgedSquare.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/OutlineSquare/MI_EdgedSquare.uasset -------------------------------------------------------------------------------- /Content/Materials/OutlineSquare/M_EdgedSquare.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/OutlineSquare/M_EdgedSquare.uasset -------------------------------------------------------------------------------- /Content/Materials/OverlayMaterial/MI_OverlayMaterial.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/OverlayMaterial/MI_OverlayMaterial.uasset -------------------------------------------------------------------------------- /Content/Materials/OverlayMaterial/MI_OverlayMaterial_Glowing.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/OverlayMaterial/MI_OverlayMaterial_Glowing.uasset -------------------------------------------------------------------------------- /Content/Materials/OverlayMaterial/MI_OverlayMaterial_Noisy.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/OverlayMaterial/MI_OverlayMaterial_Noisy.uasset -------------------------------------------------------------------------------- /Content/Materials/OverlayMaterial/M_OverlayMaterial.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/OverlayMaterial/M_OverlayMaterial.uasset -------------------------------------------------------------------------------- /Content/Materials/OverlayMaterial/M_OverlayMaterial_Glowing.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/OverlayMaterial/M_OverlayMaterial_Glowing.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/Outline/MI_Outline.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/Outline/MI_Outline.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/Outline/M_Outline.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/Outline/M_Outline.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/OutlineGlowing/MI_OutlineGlowing.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/OutlineGlowing/MI_OutlineGlowing.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/OutlineGlowing/M_OutlineGlowing.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/OutlineGlowing/M_OutlineGlowing.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/OutlineOverlay/MI_OutlineOverlay.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/OutlineOverlay/MI_OutlineOverlay.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/OutlineOverlay/M_OutlineOverlay.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/OutlineOverlay/M_OutlineOverlay.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/OutlineOverlayGlowing/MI_OutlineOverlayGlowing.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/OutlineOverlayGlowing/MI_OutlineOverlayGlowing.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/OutlineOverlayGlowing/M_OutlineOverlayGlowing.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/OutlineOverlayGlowing/M_OutlineOverlayGlowing.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/Overlay/MI_Overlay.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/Overlay/MI_Overlay.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/Overlay/M_Overlay.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/Overlay/M_Overlay.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/OverlayGlowing/MI_OverlayGlowing.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/OverlayGlowing/MI_OverlayGlowing.uasset -------------------------------------------------------------------------------- /Content/Materials/PostProcessMaterials/OverlayGlowing/M_OverlayGlowing.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/PostProcessMaterials/OverlayGlowing/M_OverlayGlowing.uasset -------------------------------------------------------------------------------- /Content/Materials/Radials/MI_Radials.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Radials/MI_Radials.uasset -------------------------------------------------------------------------------- /Content/Materials/Radials/M_Radials.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Radials/M_Radials.uasset -------------------------------------------------------------------------------- /Content/Materials/Triangle/MI_Triangle.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Triangle/MI_Triangle.uasset -------------------------------------------------------------------------------- /Content/Materials/Triangle/M_Triangle.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Materials/Triangle/M_Triangle.uasset -------------------------------------------------------------------------------- /Content/Misc/Localization/ST_InteractableNames.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Misc/Localization/ST_InteractableNames.uasset -------------------------------------------------------------------------------- /Content/Textures/Editor/T_MounteaLogo.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Textures/Editor/T_MounteaLogo.uasset -------------------------------------------------------------------------------- /Content/Textures/Keys/T_Key_GamepadFaceButtonBottm_Switch.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Textures/Keys/T_Key_GamepadFaceButtonBottm_Switch.uasset -------------------------------------------------------------------------------- /Content/Textures/Keys/T_Key_GamepadFaceButtonBottom_PS.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Textures/Keys/T_Key_GamepadFaceButtonBottom_PS.uasset -------------------------------------------------------------------------------- /Content/Textures/Keys/T_Key_GamepadFaceButtonBottom_XBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Textures/Keys/T_Key_GamepadFaceButtonBottom_XBX.uasset -------------------------------------------------------------------------------- /Content/Textures/Keys/T_Key_MKB_F.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Textures/Keys/T_Key_MKB_F.uasset -------------------------------------------------------------------------------- /Content/Textures/Noise/T_Voronoi.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/Textures/Noise/T_Voronoi.uasset -------------------------------------------------------------------------------- /Content/UMG/Base/WBP_InteractableBase.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Base/WBP_InteractableBase.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_01.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_01.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_02.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_02.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_03.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_03.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_04.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_04.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_05.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_05.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_06.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_06.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_07.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_07.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_08.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_08.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_09.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_09.uasset -------------------------------------------------------------------------------- /Content/UMG/Examples/WBP_InteractableWidget_10.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Examples/WBP_InteractableWidget_10.uasset -------------------------------------------------------------------------------- /Content/UMG/Generic/WBP_Circle.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Generic/WBP_Circle.uasset -------------------------------------------------------------------------------- /Content/UMG/Generic/WBP_InteractableWidget_Empty.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Content/UMG/Generic/WBP_InteractableWidget_Empty.uasset -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | 4 | http://www.apache.org/licenses/ 5 | 6 | 7 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 8 | 9 | 1. Definitions. 10 | 11 | "License" shall mean the terms and conditions for use, reproduction, 12 | and distribution as defined by Sections 1 through 9 of this document. 13 | 14 | "Licensor" shall mean the copyright owner or entity authorized by 15 | the copyright owner that is granting the License. 16 | 17 | "Legal Entity" shall mean the union of the acting entity and all 18 | other entities that control, are controlled by, or are under common 19 | control with that entity. For the purposes of this definition, 20 | "control" means (i) the power, direct or indirect, to cause the 21 | direction or management of such entity, whether by contract or 22 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 23 | outstanding shares, or (iii) beneficial ownership of such entity. 24 | 25 | "You" (or "Your") shall mean an individual or Legal Entity 26 | exercising permissions granted by this License. 27 | 28 | "Source" form shall mean the preferred form for making modifications, 29 | including but not limited to software source code, documentation 30 | source, and configuration files. 31 | 32 | "Object" form shall mean any form resulting from mechanical 33 | transformation or translation of a Source form, including but 34 | not limited to compiled object code, generated documentation, 35 | and conversions to other media types. 36 | 37 | "Work" shall mean the work of authorship, whether in Source or 38 | Object form, made available under the License, as indicated by a 39 | copyright notice that is included in or attached to the work 40 | (an example is provided in the Appendix below). 41 | 42 | "Derivative Works" shall mean any work, whether in Source or Object 43 | form, that is based on (or derived from) the Work and for which the 44 | editorial revisions, annotations, elaborations, or other modifications 45 | represent, as a whole, an original work of authorship. For the purposes 46 | of this License, Derivative Works shall not include works that remain 47 | separable from, or merely link (or bind by name) to the interfaces of, 48 | the Work and Derivative Works thereof. 49 | 50 | "Contribution" shall mean any work of authorship, including 51 | the original version of the Work and any modifications or additions 52 | to that Work or Derivative Works thereof, that is intentionally 53 | submitted to Licensor for inclusion in the Work by the copyright owner 54 | or by an individual or Legal Entity authorized to submit on behalf of 55 | the copyright owner. For the purposes of this definition, "submitted" 56 | means any form of electronic, verbal, or written communication sent 57 | to the Licensor or its representatives, including but not limited to 58 | communication on electronic mailing lists, source code control systems, 59 | and issue tracking systems that are managed by, or on behalf of, the 60 | Licensor for the purpose of discussing and improving the Work, but 61 | excluding communication that is conspicuously marked or otherwise 62 | designated in writing by the copyright owner as "Not a Contribution." 63 | 64 | "Contributor" shall mean Licensor and any individual or Legal Entity 65 | on behalf of whom a Contribution has been received by Licensor and 66 | subsequently incorporated within the Work. 67 | 68 | 2. Grant of Copyright License. Subject to the terms and conditions of 69 | this License, each Contributor hereby grants to You a perpetual, 70 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 71 | copyright license to reproduce, prepare Derivative Works of, 72 | publicly display, publicly perform, sublicense, and distribute the 73 | Work and such Derivative Works in Source or Object form, provided 74 | that the additional restrictions in Section 10 are met. 75 | 76 | 3. Grant of Patent License. Subject to the terms and conditions of 77 | this License, each Contributor hereby grants to You a perpetual, 78 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 79 | (except as stated in this section) patent license to make, have made, 80 | use, offer to sell, sell, import, and otherwise transfer the Work, 81 | where such license applies only to those patent claims licensable 82 | by such Contributor that are necessarily infringed by their 83 | Contribution(s) alone or by combination of their Contribution(s) 84 | with the Work to which such Contribution(s) was submitted. If You 85 | institute patent litigation against any entity (including a 86 | cross-claim or counterclaim in a lawsuit) alleging that the Work 87 | or a Contribution incorporated within the Work constitutes direct 88 | or contributory patent infringement, then any patent licenses 89 | granted to You under this License for that Work shall terminate 90 | as of the date such litigation is filed. 91 | 92 | 4. Redistribution. You may reproduce and distribute copies of the 93 | Work or Derivative Works thereof in any medium, with or without 94 | modifications, and in Source or Object form, provided that You 95 | meet the following conditions: 96 | 97 | (a) You must give any other recipients of the Work or 98 | Derivative Works a copy of this License; and 99 | 100 | (b) You must cause any modified files to carry prominent notices 101 | stating that You changed the files; and 102 | 103 | (c) You must retain, in the Source form of any Derivative Works 104 | that You distribute, all copyright, patent, trademark, and 105 | attribution notices from the Source form of the Work, 106 | excluding those notices that do not pertain to any part of 107 | the Derivative Works; and 108 | 109 | (d) If the Work includes a "NOTICE" text file as part of its 110 | distribution, then any Derivative Works that You distribute must 111 | include a readable copy of the attribution notices contained 112 | within such NOTICE file, excluding those notices that do not 113 | pertain to any part of the Derivative Works, in at least one 114 | of the following places: within a NOTICE text file distributed 115 | as part of the Derivative Works; within the Source form or 116 | documentation, if provided along with the Derivative Works; or, 117 | within a display generated by the Derivative Works, if and 118 | wherever such third-party notices normally appear. The contents 119 | of the NOTICE file are for informational purposes only and 120 | do not modify the License. You may add Your own attribution 121 | notices within Derivative Works that You distribute, alongside 122 | or as an addendum to the NOTICE text from the Work, provided 123 | that such additional attribution notices cannot be construed 124 | as modifying the License. 125 | 126 | You may add Your own copyright statement to Your modifications and 127 | may provide additional or different license terms and conditions 128 | for use, reproduction, or distribution of Your modifications, or 129 | for any such Derivative Works as a whole, provided Your use, 130 | reproduction, and distribution of the Work otherwise complies with 131 | the conditions stated in this License. 132 | 133 | 5. Submission of Contributions. Unless You explicitly state otherwise, 134 | any Contribution intentionally submitted for inclusion in the Work 135 | by You to the Licensor shall be under the terms and conditions of 136 | this License, without any additional terms or conditions. 137 | Notwithstanding the above, nothing herein shall supersede or modify 138 | the terms of any separate license agreement you may have executed 139 | with Licensor regarding such Contributions. 140 | 141 | 6. Trademarks. This License does not grant permission to use the trade 142 | names, trademarks, service marks, or product names of the Licensor, 143 | except as required for reasonable and customary use in describing the 144 | origin of the Work and reproducing the content of the NOTICE file. 145 | 146 | 7. Disclaimer of Warranty. Unless required by applicable law or 147 | agreed to in writing, Licensor provides the Work (and each 148 | Contributor provides its Contributions) on an "AS IS" BASIS, 149 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 150 | implied, including, without limitation, any warranties or conditions 151 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 152 | PARTICULAR PURPOSE. You are solely responsible for determining the 153 | appropriateness of using or redistributing the Work and assume any 154 | risks associated with Your exercise of permissions under this License. 155 | 156 | 8. Limitation of Liability. In no event and under no legal theory, 157 | whether in tort (including negligence), contract, or otherwise, 158 | unless required by applicable law (such as deliberate and grossly 159 | negligent acts) or agreed to in writing, shall any Contributor be 160 | liable to You for damages, including any direct, indirect, special, 161 | incidental, or consequential damages of any character arising as a 162 | result of this License or out of the use or inability to use the 163 | Work (including but not limited to damages for loss of goodwill, 164 | work stoppage, computer failure or malfunction, or any and all 165 | other commercial damages or losses), even if such Contributor 166 | has been advised of the possibility of such damages. 167 | 168 | 9. Accepting Warranty or Additional Liability. While redistributing 169 | the Work or Derivative Works thereof, You may choose to offer, 170 | and charge a fee for, acceptance of support, warranty, indemnity, 171 | or other liability obligations and/or rights consistent with this 172 | License. However, in accepting such obligations, You may act only 173 | on Your own behalf and on Your sole responsibility, not on behalf 174 | of any other Contributor, and only if You agree to indemnify, 175 | defend, and hold each Contributor harmless for any liability 176 | incurred by, or claims asserted against, such Contributor by reason 177 | of your accepting any such warranty or additional liability. 178 | 179 | 10. Additional Restrictions. 180 | 181 | (a) Monetized distribution of the Work or Derivative Works is limited to the following scenarios: 182 | 183 | (i) Heavily modified versions of the Work, where more than 35% of 184 | the source code has been changed. 185 | (ii) Integration as part of a larger product, such as a game or other 186 | finished product. 187 | (b) You are explicitly allowed to use all Mountea Plugins, including 188 | this Work, in your games, even if those games are sold, with no 189 | requirement for shared revenue or other obligations. 190 | (c) You may create your own plugins or systems that utilize this Work, 191 | provided that you do not sell such plugins or systems as standalone 192 | products. 193 | 194 | END OF TERMS AND CONDITIONS 195 | 196 | APPENDIX: How to apply the Apache License to your work. 197 | 198 | To apply the Apache License to your work, attach the following 199 | boilerplate notice, with the fields enclosed by brackets "[]" 200 | replaced with your own identifying information. (Don't include 201 | the brackets!) The text should be enclosed in the appropriate 202 | comment syntax for the file format. We also recommend that a 203 | file or class name and description of purpose be included on the 204 | same "printed page" as the copyright notice for easier 205 | identification within third-party archives. 206 | 207 | Copyright 2024 Dominik Morse 208 | 209 | Licensed under the Apache License, Version 2.0 (the "License"); 210 | you may not use this file except in compliance with the License. 211 | You may obtain a copy of the License at 212 | 213 | http://www.apache.org/licenses/LICENSE-2.0 214 | 215 | Unless required by applicable law or agreed to in writing, software 216 | distributed under the License is distributed on an "AS IS" BASIS, 217 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 218 | See the License for the specific language governing permissions and 219 | limitations under the License. 220 | 221 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Documentation](https://img.shields.io/badge/documentation-github?style=flat&logo=GitHub&labelColor=5a5a5a&color=98c510)](https://github.com/Mountea-Framework/MounteaInteractionSystem/wiki/How-to-Setup-Interaction) 2 | [![Marketplace](https://img.shields.io/badge/marketplace-epicgames?style=flat&logo=UnrealEngine&labelColor=5a5a5a&color=98c510)](https://www.unrealengine.com/marketplace/en-US/product/ca842c00ec0d4db0b3aad17701e1637b) 3 | ![UE](https://img.shields.io/badge/supported-4.26%2B-green) 4 | [![license](https://img.shields.io/badge/license-Apache%20License%20++-99c711?labelColor=555555&style=flat&link=https://github.com/Mountea-Framework/MounteaInteractionSystem/blob/master/LICENSE)](https://github.com/Mountea-Framework/MounteaInteractionSystem/blob/master/LICENSE) 5 | [![YouTube](https://img.shields.io/badge/YouTube-Subscribe-red?style=flat&logo=youtube)](https://www.youtube.com/@mounteaframework) 6 | [![Discord](https://badgen.net/discord/online-members/2vXWEEN?label=Discord&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.com/invite/2vXWEEN) 7 | [![Discord](https://badgen.net/discord/members/2vXWEEN?label=Discord&logo=discord&logoColor=ffffff&color=7389D8)](https://discord.com/invite/2vXWEEN) 8 | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/a89e2403ce31422ea6235995246b9ef7)](https://app.codacy.com/gh/Mountea-Framework/MounteaInteractionSystem/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade) 9 | 10 | # Mountea Interaction System 11 | 12 | Mountea Interaction System is an Open-source Mountea Framework components-based simple framework providing utilities for smart Actor Interaction with other Actors. 13 | Developed with Game Developers in mind to allow as easy as possible implementation while maintaining high scalability and diverse options to tweak everything. 14 | 15 | ## Playable Demo 16 | Feel free to download the playable demo and take a look at what this plugin (in combination with its Dialogue sibling) can do in a matter of a few clicks! 17 |

18 | 19 | 20 | 21 |

22 | 23 | ## Discord Channel 24 | Discord LINK 25 | 26 | ## Documentation 27 | Online [Documentation](https://github.com/Mountea-Framework/MounteaInteractionSystem/wiki/How-to-Setup-Interaction) including a Quick Start guide which will help you set up the plugin in a few easy-to-follow steps. 28 | 29 | ## Tutorial videos 30 | TUTORIAL playlist 31 | 32 | Join support and community Discord! 33 | 34 | ## Compatible Engine Version 35 | 36 | ### Legend 37 | 🟩 - Supported 38 | 🟨 - WIP 39 | 🟪 - Deprecated 40 | 🟥 - Partially supported 41 | 42 | ### Support Table 43 | Engine Version | Plugin Version | Support 44 | -------------- | -------------- | ---- 45 | UE 4.25 | 2.0.0.0 | 🟪 46 | UE 4.26 | 3.0.1.5 | 🟪 47 | UE 4.27 | 3.0.1.5 | 🟪 48 | UE 5.00 | 3.0.1.5 | 🟪 49 | UE 5.1 | [4.0.2.51](https://github.com/Mountea-Framework/MounteaInteractionSystem/releases/tag/4.0.2.51) | 🟩 50 | UE 5.2 | [4.0.2.52](https://github.com/Mountea-Framework/MounteaInteractionSystem/releases/tag/4.0.2.52) | 🟩 51 | UE 5.3 | [4.0.2.53](https://github.com/Mountea-Framework/MounteaInteractionSystem/releases/tag/4.0.2.53) | 🟩 52 | UE 5.4 | [4.0.2.54](https://github.com/Mountea-Framework/MounteaInteractionSystem/releases/tag/4.0.2.54) | 🟩 53 | UE 5.5 | [4.0.2.54](https://github.com/Mountea-Framework/MounteaInteractionSystem/releases/tag/4.0.2.54) | 🟩 54 | 55 | # Features 56 | 57 | ## Settings & Configuration 58 | 59 |

60 | 61 | 62 |

63 | 64 | ## In-Engine Tutorial 65 | Interaction System has a simplified in-engine tutorial page that can be opened anytime in the engine. This does **not** replace actual documentation and this tutorial is meant to provide basic steps with interactive links to Project Settings, Project Folders or Documentation Links. 66 |

67 | 68 |

69 | 70 | ## Dynamic Input Mapping 71 | 72 |

73 | 74 |

75 | 76 | Powerful configuration allows setting different textures for different Platforms, Input Types and even Gamepad Types! 77 |

78 | 79 |

80 | 81 | ## Free Examples 82 | All good products contain samples and this plugin is not difference! There are 10 (plus 1 Blueprint Base Class) ready to use examples of various Interaction widgets. All created with performance and scalability in mind. 83 |

84 | 85 |

86 | 87 | ### Installation 88 | 89 | Download the plugin (either from Releases or from Marketplace). For a more detailed guide take a look at the Wiki page. 90 | 91 | 1. Download the branch release you are interested in 92 | 2. Instal the plugin to your Game Project (within /Plugin folder) 93 | 94 | 95 | ## Usage 96 | 97 | The best way to describe the usage is to take a look or play the demo build. 98 | * Video: https://youtu.be/OCCcxqhCBkY 99 | * Build: https://drive.google.com/file/d/1XS6meFqXbDM_YfbjQijcco6q1O1wl9-J/view?usp=drive_link 100 | 101 | ### Branches 102 | 103 | * Master: A development branch, that should always be relevant to the most current Engine version. 104 | * Version Branch: A development branch for a specified Engine version 105 | 106 | ## Additional Documentation and Acknowledgments 107 | 108 | * Documentation: https://github.com/Mountea-Framework/MounteaInteractionSystem/wiki/How-to-Setup-Interaction 109 | 110 | ## Star History 111 | 112 | [![Star History Chart](https://api.star-history.com/svg?repos=Mountea-Framework/MounteaInteractionSystem&type=Date)](https://star-history.com/#Mountea-Framework/MounteaInteractionSystem&Date) 113 | 114 | -------------------------------------------------------------------------------- /Resources/CloseIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/CloseIcon.png -------------------------------------------------------------------------------- /Resources/Dialoguer_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/Dialoguer_Icon.png -------------------------------------------------------------------------------- /Resources/HeartIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/HeartIcon.png -------------------------------------------------------------------------------- /Resources/Help_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/Help_Icon.png -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/Icon128.png -------------------------------------------------------------------------------- /Resources/InteractableIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/InteractableIcon.png -------------------------------------------------------------------------------- /Resources/InteractionConfigIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/InteractionConfigIcon.png -------------------------------------------------------------------------------- /Resources/InteractorIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/InteractorIcon.png -------------------------------------------------------------------------------- /Resources/MPLIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/MPLIcon.png -------------------------------------------------------------------------------- /Resources/MoneyIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/MoneyIcon.png -------------------------------------------------------------------------------- /Resources/Mountea_Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/Mountea_Logo.png -------------------------------------------------------------------------------- /Resources/UnrealBucketIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/UnrealBucketIcon.png -------------------------------------------------------------------------------- /Resources/Wiki_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/Wiki_Icon.png -------------------------------------------------------------------------------- /Resources/settings_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/settings_icon.png -------------------------------------------------------------------------------- /Resources/tutorialPage_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/tutorialPage_icon.png -------------------------------------------------------------------------------- /Resources/youtube_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/d8bfd600f9fa13a069baf96a75a7e3f1bb9076ac/Resources/youtube_icon.png -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/ActorInteractionPlugin.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Morse (Pavlicek) 2024. All Rights Reserved. 2 | 3 | using UnrealBuildTool; 4 | using System.IO; 5 | 6 | public class ActorInteractionPlugin : ModuleRules 7 | { 8 | public ActorInteractionPlugin(ReadOnlyTargetRules Target) : base(Target) 9 | { 10 | PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs; 11 | 12 | PublicIncludePaths.AddRange( 13 | new string[] { 14 | // ... add public include paths required here ... 15 | Path.Combine(ModuleDirectory, "Public") 16 | } 17 | ); 18 | 19 | 20 | PrivateIncludePaths.AddRange( 21 | new string[] { 22 | // ... add other private include paths required here ... 23 | Path.Combine(ModuleDirectory, "Private") 24 | } 25 | ); 26 | 27 | 28 | PublicDependencyModuleNames.AddRange( 29 | new string[] 30 | { 31 | "Core", 32 | "UMG", 33 | "InputCore", 34 | "Engine" 35 | // ... add other public dependencies that you statically link with here ... 36 | } 37 | ); 38 | 39 | 40 | PrivateDependencyModuleNames.AddRange( 41 | new string[] 42 | { 43 | "Core", 44 | "CoreUObject", 45 | "Engine", 46 | "UMG", 47 | "Slate", 48 | "SlateCore", 49 | "Projects", 50 | "InputCore", 51 | "GameplayTags", 52 | "EnhancedInput", 53 | "NetCore", 54 | "EnhancedInput", 55 | "ApplicationCore", 56 | "CommonInput", 57 | 58 | "InteractionEditorNotifications", 59 | 60 | #if UE_4_26_OR_LATER 61 | "DeveloperSettings", 62 | #endif 63 | // ... add private dependencies that you statically link with here ... 64 | } 65 | ); 66 | 67 | DynamicallyLoadedModuleNames.AddRange( 68 | new string[] 69 | { 70 | // ... add any modules that your module loads dynamically here ... 71 | } 72 | ); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/ActorInteractionPlugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Morse (Pavlicek) 2024. All Rights Reserved. 2 | 3 | #include "ActorInteractionPlugin.h" 4 | 5 | #include "GameplayTagsManager.h" 6 | #include "Interfaces/IPluginManager.h" 7 | #include "Styling/SlateStyleRegistry.h" 8 | 9 | #define LOCTEXT_NAMESPACE "FActorInteractionPluginModule" 10 | 11 | void FActorInteractionPluginModule::StartupModule() 12 | { 13 | // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module 14 | 15 | TSharedPtr ThisPlugin = IPluginManager::Get().FindPlugin(TEXT("ActorInteractionPlugin")); 16 | check(ThisPlugin.IsValid()); 17 | 18 | UGameplayTagsManager::Get().AddTagIniSearchPath(ThisPlugin->GetBaseDir() / TEXT("Config") / TEXT("Tags")); 19 | } 20 | 21 | void FActorInteractionPluginModule::ShutdownModule() 22 | { 23 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 24 | // we call this function before unloading the module. 25 | } 26 | 27 | #undef LOCTEXT_NAMESPACE 28 | 29 | IMPLEMENT_MODULE(FActorInteractionPluginModule, ActorInteractionPlugin) -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Components/Interactable/ActorInteractableComponentAutomatic.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "Components/Interactable/ActorInteractableComponentAutomatic.h" 5 | #include "TimerManager.h" 6 | 7 | #include "Helpers/ActorInteractionPluginLog.h" 8 | 9 | #define LOCTEXT_NAMESPACE "ActorInteractableComponentAutomatic" 10 | 11 | UActorInteractableComponentAutomatic::UActorInteractableComponentAutomatic() 12 | { 13 | InteractableName = NSLOCTEXT("ActorInteractableComponentAutomatic", "Auto", "Auto"); 14 | 15 | DefaultInteractableState = EInteractableStateV2::EIS_Awake; 16 | InteractionPeriod = 1.f; 17 | 18 | bInteractionHighlight = false; 19 | } 20 | 21 | void UActorInteractableComponentAutomatic::BeginPlay() 22 | { 23 | Super::BeginPlay(); 24 | 25 | OnInteractionStopped.RemoveAll(this); 26 | } 27 | 28 | void UActorInteractableComponentAutomatic::InteractableSelected_Implementation(const TScriptInterface& Interactable) 29 | { 30 | if(!GetWorld()) return; 31 | Super::InteractableSelected_Implementation(Interactable); 32 | 33 | if (Interactable == this) 34 | { 35 | if (GetWorld()->GetTimerManager().IsTimerActive(Timer_Interaction) == false) 36 | { 37 | OnInteractionStarted.Broadcast(GetWorld()->GetTimeSeconds(), Execute_GetInteractor(this)); 38 | } 39 | } 40 | } 41 | 42 | void UActorInteractableComponentAutomatic::InteractionStarted_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) 43 | { 44 | if (!GetWorld()) return; 45 | 46 | if (Execute_CanInteract(this) && !GetWorld()->GetTimerManager().IsTimerActive(Timer_Interaction)) 47 | { 48 | // Force Interaction Period to be at least 0.01s 49 | const float TempInteractionPeriod = FMath::Max(0.01f, InteractionPeriod); 50 | 51 | FTimerDelegate Delegate; 52 | Delegate.BindUObject(this, &UActorInteractableComponentAutomatic::OnInteractionCompletedCallback); 53 | 54 | GetWorld()->GetTimerManager().SetTimer 55 | ( 56 | Timer_Interaction, 57 | Delegate, 58 | TempInteractionPeriod, 59 | false 60 | ); 61 | 62 | Super::InteractionStarted_Implementation(TimeStarted, CausingInteractor); 63 | 64 | UpdateInteractionWidget(); 65 | } 66 | } 67 | 68 | void UActorInteractableComponentAutomatic::InteractionStopped_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) 69 | { 70 | #if WITH_EDITOR 71 | LOG_WARNING(TEXT("[InteractionStopped] This function does nothing in UActorInteractableComponentAutomatic")) 72 | #endif 73 | } 74 | 75 | FInteractionStarted& UActorInteractableComponentAutomatic::GetOnInteractionStartedHandle() 76 | { 77 | #if WITH_EDITOR 78 | LOG_WARNING(TEXT("[GetOnInteractionStartedHandle] This handle is invalid in UActorInteractableComponentAutomatic")) 79 | #endif 80 | 81 | return EmptyHandle_Started; 82 | } 83 | 84 | FInteractionStopped& UActorInteractableComponentAutomatic::GetOnInteractionStoppedHandle() 85 | { 86 | #if WITH_EDITOR 87 | LOG_WARNING(TEXT("[GetOnInteractionStoppedHandle] This handle is invalid in UActorInteractableComponentAutomatic")) 88 | #endif 89 | 90 | return EmptyHandle_Stopped; 91 | } 92 | 93 | void UActorInteractableComponentAutomatic::OnInteractionCompletedCallback() 94 | { 95 | if (!GetWorld()) 96 | { 97 | OnInteractionCanceled.Broadcast(); 98 | return; 99 | } 100 | 101 | Execute_ToggleWidgetVisibility(this, false); 102 | if (LifecycleMode == EInteractableLifecycle::EIL_Cycled) 103 | { 104 | if (Execute_TriggerCooldown(this)) return; 105 | } 106 | 107 | OnInteractionCompleted.Broadcast(GetWorld()->GetTimeSeconds(), Execute_GetInteractor(this)); 108 | } 109 | 110 | #undef LOCTEXT_NAMESPACE 111 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Components/Interactable/ActorInteractableComponentHold.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "Components/Interactable/ActorInteractableComponentHold.h" 5 | #include "TimerManager.h" 6 | #include "Interfaces/ActorInteractorInterface.h" 7 | #include "TimerManager.h" 8 | #include "Helpers/ActorInteractionPluginLog.h" 9 | #include "Helpers/MounteaInteractionSystemBFL.h" 10 | 11 | #define LOCTEXT_NAMESPACE "InteractableComponentHold" 12 | 13 | UActorInteractableComponentHold::UActorInteractableComponentHold() 14 | { 15 | bInteractionHighlight = true; 16 | DefaultInteractableState = EInteractableStateV2::EIS_Awake; 17 | InteractionPeriod = 3.f; 18 | InteractableName = NSLOCTEXT("InteractableComponentHold", "Hold", "Hold"); 19 | } 20 | 21 | void UActorInteractableComponentHold::InteractionStarted_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) 22 | { 23 | if (GetOwner() && GetOwner()->HasAuthority()) 24 | { 25 | if (!GetWorld()) return; 26 | 27 | if (!Execute_CanInteract(this)) 28 | return; 29 | 30 | // Force Interaction Period to be at least 0.1s 31 | const float TempInteractionPeriod = FMath::Max(0.1f, InteractionPeriod); 32 | 33 | // Either unpause or start from start 34 | if (bCanPersist && GetWorld()->GetTimerManager().IsTimerPaused(Timer_Interaction)) 35 | { 36 | GetWorld()->GetTimerManager().UnPauseTimer(Timer_Interaction); 37 | } 38 | else 39 | { 40 | FTimerDelegate Delegate; 41 | Delegate.BindUObject(this, &UActorInteractableComponentHold::OnInteractionCompletedCallback); 42 | 43 | GetWorld()->GetTimerManager().SetTimer 44 | ( 45 | Timer_Interaction, 46 | Delegate, 47 | TempInteractionPeriod, 48 | false 49 | ); 50 | } 51 | 52 | Super::InteractionStarted_Implementation(TimeStarted, CausingInteractor); 53 | } 54 | } 55 | 56 | void UActorInteractableComponentHold::OnInteractionCompletedCallback() 57 | { 58 | if (GetOwner() && GetOwner()->HasAuthority()) 59 | { 60 | if (!GetWorld()) 61 | { 62 | LOG_WARNING(TEXT("[OnInteractionCompletedCallback] No World, this is bad!")) 63 | OnInteractionCanceled.Broadcast(); 64 | return; 65 | } 66 | 67 | if (UMounteaInteractionSystemBFL::CanExecuteCosmeticEvents(GetWorld())) 68 | { 69 | ProcessToggleActive(false); 70 | } 71 | else 72 | { 73 | ProcessToggleActive_Client(false); 74 | } 75 | 76 | if (LifecycleMode == EInteractableLifecycle::EIL_Cycled) 77 | { 78 | if (Execute_TriggerCooldown(this)) return; 79 | } 80 | 81 | OnInteractionCompleted.Broadcast(GetWorld()->GetTimeSeconds(), Execute_GetInteractor(this)); 82 | } 83 | } 84 | 85 | #undef LOCTEXT_NAMESPACE 86 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Components/Interactable/ActorInteractableComponentHover.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "Components/Interactable/ActorInteractableComponentHover.h" 5 | 6 | #define LOCTEXT_NAMESPACE "ActorInteractableComponentHover" 7 | 8 | UActorInteractableComponentHover::UActorInteractableComponentHover() 9 | { 10 | bInteractionHighlight = true; 11 | DefaultInteractableState = EInteractableStateV2::EIS_Awake; 12 | InteractionPeriod = 3.f; 13 | InteractableName = NSLOCTEXT("ActorInteractableComponentHover", "Hover", "Hover"); 14 | } 15 | 16 | void UActorInteractableComponentHover::BeginPlay() 17 | { 18 | Super::BeginPlay(); 19 | 20 | OnInteractorOverlapped. RemoveDynamic(this, &UActorInteractableComponentHover::OnInteractableBeginOverlapEvent); 21 | OnInteractorStopOverlap. RemoveDynamic(this, &UActorInteractableComponentHover::OnInteractableStopOverlapEvent); 22 | OnInteractorTraced. RemoveDynamic(this, &UActorInteractableComponentHover::OnInteractableTracedEvent); 23 | } 24 | 25 | void UActorInteractableComponentHover::BindCollisionShape_Implementation(UPrimitiveComponent* PrimitiveComponent) const 26 | { 27 | Super::BindCollisionShape_Implementation(PrimitiveComponent); 28 | 29 | if (PrimitiveComponent) 30 | { 31 | PrimitiveComponent->OnBeginCursorOver. AddUniqueDynamic(this, &UActorInteractableComponentHover::OnHoverBeginsEvent); 32 | PrimitiveComponent->OnEndCursorOver. AddUniqueDynamic(this, &UActorInteractableComponentHover::OnHoverStopsEvent); 33 | } 34 | } 35 | 36 | void UActorInteractableComponentHover::UnbindCollisionShape_Implementation(UPrimitiveComponent* PrimitiveComponent) const 37 | { 38 | Super::UnbindCollisionShape_Implementation(PrimitiveComponent); 39 | 40 | if (PrimitiveComponent) 41 | { 42 | PrimitiveComponent->OnBeginCursorOver. RemoveDynamic(this, &UActorInteractableComponentHover::OnHoverBeginsEvent); 43 | PrimitiveComponent->OnEndCursorOver. RemoveDynamic(this, &UActorInteractableComponentHover::OnHoverStopsEvent); 44 | } 45 | } 46 | 47 | bool UActorInteractableComponentHover::CanInteract_Implementation() const 48 | { 49 | return Super::CanInteract_Implementation() && OverlappingComponent != nullptr; 50 | } 51 | 52 | void UActorInteractableComponentHover::OnHoverBeginsEvent(UPrimitiveComponent* PrimitiveComponent) 53 | { 54 | OverlappingComponent = PrimitiveComponent; 55 | OnCursorBeginsOverlap.Broadcast(PrimitiveComponent); 56 | } 57 | 58 | void UActorInteractableComponentHover::OnHoverStopsEvent(UPrimitiveComponent* PrimitiveComponent) 59 | { 60 | OverlappingComponent = nullptr; 61 | OnCursorStopsOverlap.Broadcast(PrimitiveComponent); 62 | } 63 | 64 | #undef LOCTEXT_NAMESPACE 65 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Components/Interactable/ActorInteractableComponentMash.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "Components/Interactable/ActorInteractableComponentMash.h" 5 | 6 | #include "TimerManager.h" 7 | #include "Helpers/ActorInteractionPluginLog.h" 8 | 9 | #define LOCTEXT_NAMESPACE "ActorInteractableComponentMash" 10 | 11 | UActorInteractableComponentMash::UActorInteractableComponentMash() : 12 | MinMashAmountRequired(5), 13 | KeystrokeTimeThreshold(1.f), 14 | ActualMashAmount(0) 15 | { 16 | bInteractionHighlight = true; 17 | DefaultInteractableState = EInteractableStateV2::EIS_Awake; 18 | InteractionPeriod = 3.f; 19 | InteractableName = NSLOCTEXT("ActorInteractableComponentMash", "Mash", "Mash"); 20 | } 21 | 22 | void UActorInteractableComponentMash::BeginPlay() 23 | { 24 | Super::BeginPlay(); 25 | 26 | OnInteractionFailed. AddUniqueDynamic(this, &UActorInteractableComponentMash::InteractionFailed); 27 | OnKeyMashed. AddUniqueDynamic(this, &UActorInteractableComponentMash::OnKeyMashedEvent); 28 | } 29 | 30 | void UActorInteractableComponentMash::InteractionFailed() 31 | { 32 | Execute_SetState(this, Execute_GetDefaultState(this)); 33 | 34 | CleanupComponent(); 35 | 36 | OnInteractionFailedEvent(); 37 | } 38 | 39 | void UActorInteractableComponentMash::OnInteractionFailedCallback() 40 | { 41 | OnInteractionFailed.Broadcast(); 42 | } 43 | 44 | void UActorInteractableComponentMash::OnInteractionCompletedCallback() 45 | { 46 | if (!GetWorld()) 47 | { 48 | return; 49 | } 50 | 51 | GetWorld()->GetTimerManager().ClearTimer(TimerHandle_Mashed); 52 | 53 | if (LifecycleMode == EInteractableLifecycle::EIL_Cycled) 54 | { 55 | if (Execute_TriggerCooldown(this)) return; 56 | } 57 | 58 | if (ActualMashAmount >= MinMashAmountRequired) 59 | { 60 | OnInteractionCompleted.Broadcast(GetWorld()->GetTimeSeconds(), Execute_GetInteractor(this)); 61 | } 62 | else 63 | { 64 | OnInteractionFailed.Broadcast(); 65 | } 66 | 67 | CleanupComponent(); 68 | } 69 | 70 | void UActorInteractableComponentMash::CleanupComponent() 71 | { 72 | ActualMashAmount = 0; 73 | 74 | OnInteractableStateChanged.Broadcast(InteractableState); 75 | 76 | if (GetWorld()) 77 | { 78 | GetWorld()->GetTimerManager().ClearTimer(TimerHandle_Mashed); 79 | GetWorld()->GetTimerManager().ClearTimer(Timer_Interaction); 80 | } 81 | } 82 | 83 | void UActorInteractableComponentMash::InteractionStarted_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) 84 | { 85 | Super::InteractionStarted_Implementation(TimeStarted, CausingInteractor); 86 | 87 | if (Execute_CanInteract(this)) 88 | { 89 | if(!GetWorld()->GetTimerManager().IsTimerActive(Timer_Interaction)) 90 | { 91 | // Force Interaction Period to be at least 0.1s 92 | const float TempInteractionPeriod = FMath::Max(0.1f, InteractionPeriod); 93 | 94 | FTimerDelegate Delegate_Completed; 95 | Delegate_Completed.BindUObject(this, &UActorInteractableComponentMash::OnInteractionCompletedCallback); 96 | 97 | GetWorld()->GetTimerManager().SetTimer 98 | ( 99 | Timer_Interaction, 100 | Delegate_Completed, 101 | TempInteractionPeriod, 102 | false 103 | ); 104 | } 105 | 106 | if (GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_Mashed)) 107 | { 108 | GetWorld()->GetTimerManager().ClearTimer(TimerHandle_Mashed); 109 | } 110 | 111 | FTimerDelegate Delegate_Mashed; 112 | Delegate_Mashed.BindUObject(this, &UActorInteractableComponentMash::OnInteractionFailedCallback); 113 | GetWorld()->GetTimerManager().SetTimer 114 | ( 115 | TimerHandle_Mashed, 116 | Delegate_Mashed, 117 | KeystrokeTimeThreshold, 118 | false 119 | ); 120 | 121 | ActualMashAmount++; 122 | 123 | OnKeyMashed.Broadcast(); 124 | } 125 | } 126 | 127 | void UActorInteractableComponentMash::InteractionStopped_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) 128 | { 129 | if (GetWorld()) 130 | { 131 | if (!GetWorld()->GetTimerManager().IsTimerActive(TimerHandle_Mashed)) 132 | { 133 | Super::InteractionStopped_Implementation(TimeStarted, CausingInteractor); 134 | } 135 | } 136 | } 137 | 138 | void UActorInteractableComponentMash::InteractionCanceled_Implementation() 139 | { 140 | Super::InteractionCanceled_Implementation(); 141 | 142 | CleanupComponent(); 143 | } 144 | 145 | int32 UActorInteractableComponentMash::GetMinMashAmountRequired() const 146 | { return MinMashAmountRequired; } 147 | 148 | void UActorInteractableComponentMash::SetMinMainAmountRequired(const int32 Value) 149 | { 150 | MinMashAmountRequired = FMath::Max(Value, 2); 151 | } 152 | 153 | float UActorInteractableComponentMash::GetKeystrokeTimeThreshold() const 154 | { return KeystrokeTimeThreshold; } 155 | 156 | void UActorInteractableComponentMash::SetKeystrokeTimeThreshold(const float Value) 157 | { 158 | KeystrokeTimeThreshold = FMath::Max(Value, 0.01f); 159 | } 160 | 161 | #undef LOCTEXT_NAMESPACE 162 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Components/Interactable/ActorInteractableComponentPress.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "Components/Interactable/ActorInteractableComponentPress.h" 5 | 6 | #if WITH_EDITOR 7 | 8 | #include "EditorHelper.h" 9 | #include "Misc/DataValidation.h" 10 | 11 | #endif 12 | 13 | #define LOCTEXT_NAMESPACE "InteractableComponentPress" 14 | 15 | UActorInteractableComponentPress::UActorInteractableComponentPress() 16 | { 17 | bInteractionHighlight = true; 18 | DefaultInteractableState = EInteractableStateV2::EIS_Awake; 19 | InteractionPeriod = -1.f; 20 | InteractableName = NSLOCTEXT("InteractableComponentPress", "Press", "Press"); 21 | } 22 | 23 | void UActorInteractableComponentPress::BeginPlay() 24 | { 25 | Super::BeginPlay(); 26 | 27 | Execute_SetInteractionPeriod(this, -1.f); 28 | 29 | Timer_Interaction.Invalidate(); 30 | } 31 | 32 | void UActorInteractableComponentPress::InteractionStarted_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) 33 | { 34 | Super::InteractionStarted_Implementation(TimeStarted, CausingInteractor); 35 | 36 | if (Execute_CanInteract(this)) 37 | { 38 | if (LifecycleMode == EInteractableLifecycle::EIL_Cycled) 39 | { 40 | if (Execute_TriggerCooldown(this)) return; 41 | } 42 | 43 | OnInteractionCompleted.Broadcast(TimeStarted, CausingInteractor); 44 | } 45 | } 46 | 47 | void UActorInteractableComponentPress::SetDefaults_Implementation() 48 | { 49 | Super::SetDefaults_Implementation(); 50 | 51 | InteractionPeriod = -1.f; 52 | } 53 | 54 | #if WITH_EDITOR 55 | 56 | void UActorInteractableComponentPress::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) 57 | { 58 | Super::PostEditChangeChainProperty(PropertyChangedEvent); 59 | 60 | const FName PropertyName = (PropertyChangedEvent.MemberProperty != nullptr) ? PropertyChangedEvent.GetPropertyName() : NAME_None; 61 | 62 | FString interactableName = GetName(); 63 | // Format Name 64 | { 65 | if (interactableName.Contains(TEXT("_GEN_VARIABLE"))) 66 | { 67 | interactableName.ReplaceInline(TEXT("_GEN_VARIABLE"), TEXT("")); 68 | } 69 | if(interactableName.EndsWith(TEXT("_C")) && interactableName.StartsWith(TEXT("Default__"))) 70 | { 71 | 72 | interactableName.RightChopInline(9); 73 | interactableName.LeftChopInline(2); 74 | } 75 | } 76 | 77 | if (PropertyName == TEXT("InteractionPeriod") && !(FMath::IsNearlyEqual(InteractionPeriod, -1.f))) 78 | { 79 | InteractionPeriod = -1.f; 80 | 81 | if (DebugSettings.EditorDebugMode) 82 | { 83 | const FText ErrorMessage = FText::FromString 84 | ( 85 | interactableName.Append(TEXT(": Interaction period for Press component cannot be changed!")) 86 | ); 87 | 88 | FEditorHelper::DisplayEditorNotification(ErrorMessage, SNotificationItem::CS_Fail, 5.f, 2.f, TEXT("Icons.Error")); 89 | } 90 | } 91 | } 92 | 93 | EDataValidationResult UActorInteractableComponentPress::IsDataValid(FDataValidationContext& Context) const 94 | { 95 | const EDataValidationResult SuperResult = Super::IsDataValid(Context); 96 | 97 | bool bAnyError = SuperResult == EDataValidationResult::Invalid; 98 | 99 | FString interactableName = GetName(); 100 | // Format Name 101 | { 102 | if (interactableName.Contains(TEXT("_GEN_VARIABLE"))) 103 | { 104 | interactableName.ReplaceInline(TEXT("_GEN_VARIABLE"), TEXT("")); 105 | } 106 | if(interactableName.EndsWith(TEXT("_C")) && interactableName.StartsWith(TEXT("Default__"))) 107 | { 108 | 109 | interactableName.RightChopInline(9); 110 | interactableName.LeftChopInline(2); 111 | } 112 | } 113 | 114 | if (!FMath::IsNearlyEqual(InteractionPeriod, -1.f)) 115 | { 116 | const FText ErrorMessage = FText::FromString 117 | ( 118 | interactableName.Append(TEXT(": InteractionPeriod must be -1.f!")) 119 | ); 120 | 121 | Context.AddError(ErrorMessage); 122 | bAnyError = true; 123 | } 124 | 125 | if (bAnyError && RequestEditorDefaults.IsBound()) 126 | { 127 | RequestEditorDefaults.Broadcast(); 128 | } 129 | 130 | return bAnyError ? EDataValidationResult::Invalid : SuperResult; 131 | } 132 | 133 | #endif 134 | 135 | #undef LOCTEXT_NAMESPACE 136 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Helpers/ActorInteractionFunctionLibrary.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "Helpers/ActorInteractionFunctionLibrary.h" 5 | 6 | #include "Helpers/ActorInteractionPluginLog.h" 7 | #include "Helpers/ActorInteractionPluginSettings.h" 8 | 9 | #include "Engine/DataTable.h" 10 | #include "Blueprint/UserWidget.h" 11 | #include "Helpers/MounteaInteractionSettingsConfig.h" 12 | 13 | 14 | UActorInteractionPluginSettings* UActorInteractionFunctionLibrary::GetInteractionSettings() 15 | { 16 | return GetMutableDefault(); 17 | } 18 | 19 | FInteractorBaseSettings UActorInteractionFunctionLibrary::GetDefaultInteractorSettings() 20 | { 21 | const UActorInteractionPluginSettings* Settings = GetMutableDefault(); 22 | if (!Settings) 23 | { 24 | LOG_ERROR(TEXT("Failed to get interaction settings: Settings returned nullptr.")); 25 | return FInteractorBaseSettings(); 26 | } 27 | 28 | UMounteaInteractionSettingsConfig* DefaultConfig = Settings->DefaultInteractionSystemConfig.LoadSynchronous(); 29 | if (DefaultConfig == nullptr) 30 | { 31 | LOG_ERROR(TEXT("Failed to get interaction settings: DefaultInteractionSystemConfig is nullptr.")); 32 | return FInteractorBaseSettings(); 33 | } 34 | 35 | if (!DefaultConfig) 36 | { 37 | LOG_ERROR(TEXT("Failed to load DefaultInteractionSystemConfig synchronously.")); 38 | return FInteractorBaseSettings(); 39 | } 40 | 41 | return DefaultConfig->InteractorDefaultSettings; 42 | } 43 | 44 | 45 | FInteractableBaseSettings UActorInteractionFunctionLibrary::GetDefaultInteractableSettings() 46 | { 47 | const UActorInteractionPluginSettings* Settings = GetMutableDefault(); 48 | if (!Settings) 49 | { 50 | LOG_ERROR(TEXT("Failed to get interaction settings: Settings returned nullptr.")); 51 | return FInteractableBaseSettings(); 52 | } 53 | 54 | UMounteaInteractionSettingsConfig* DefaultConfig = Settings->DefaultInteractionSystemConfig.LoadSynchronous(); 55 | if (DefaultConfig == nullptr) 56 | { 57 | LOG_ERROR(TEXT("Failed to get interaction settings: DefaultInteractionSystemConfig is nullptr.")); 58 | return FInteractableBaseSettings(); 59 | } 60 | 61 | if (!DefaultConfig) 62 | { 63 | LOG_ERROR(TEXT("Failed to load DefaultInteractionSystemConfig synchronously.")); 64 | return FInteractableBaseSettings(); 65 | } 66 | 67 | return DefaultConfig->InteractableBaseSettings; 68 | } 69 | 70 | 71 | float UActorInteractionFunctionLibrary::GetDefaultWidgetUpdateFrequency() 72 | { 73 | if (const UActorInteractionPluginSettings* Settings = GetMutableDefault()) 74 | { 75 | return Settings->GetWidgetUpdateFrequency(); 76 | } 77 | 78 | LOG_ERROR(TEXT("[GetDefaultWidgetUpdateFrequency] Cannot load ActorInteractionPluginSettings! Using hardcoded value.")) 79 | return 0.1f; 80 | } 81 | 82 | UDataTable* UActorInteractionFunctionLibrary::GetInteractableDefaultDataTable() 83 | { 84 | if (const UActorInteractionPluginSettings* Settings = GetMutableDefault()) 85 | { 86 | if (const auto FoundTable = Settings->GetInteractableDefaultDataTable().LoadSynchronous()) 87 | { 88 | return FoundTable; 89 | } 90 | } 91 | 92 | LOG_ERROR(TEXT("[GetInteractableDefaultDataTable] Cannot load ActorInteractionPluginSettings! Using null value.")) 93 | return nullptr; 94 | } 95 | 96 | TSubclassOf UActorInteractionFunctionLibrary::GetInteractableDefaultWidgetClass() 97 | { 98 | if (const UActorInteractionPluginSettings* Settings = GetMutableDefault()) 99 | { 100 | const TSubclassOf WidgetClass = Settings->GetInteractableDefaultWidgetClass().LoadSynchronous(); 101 | return WidgetClass; 102 | } 103 | 104 | LOG_ERROR(TEXT("[GetInteractableDefaultWidgetClass] Cannot load ActorInteractionPluginSettings! Using null value.")) 105 | return nullptr; 106 | } 107 | 108 | bool UActorInteractionFunctionLibrary::IsEditorDebugEnabled() 109 | { 110 | if (const UActorInteractionPluginSettings* Settings = GetMutableDefault()) 111 | { 112 | return Settings->IsEditorDebugEnabled(); 113 | } 114 | 115 | LOG_ERROR(TEXT("[GetInteractableDefaultWidgetClass] Cannot load ActorInteractionPluginSettings! Using null value.")) 116 | return false; 117 | } 118 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Helpers/ActorInteractionPluginSettings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Morse (Pavlicek) 2024. All Rights Reserved. 2 | 3 | #include "Helpers/ActorInteractionPluginSettings.h" 4 | 5 | #include "InputMappingContext.h" 6 | #include "Helpers/MounteaInteractionSettingsConfig.h" 7 | #include "Materials/MaterialInterface.h" 8 | 9 | UActorInteractionPluginSettings::UActorInteractionPluginSettings() : 10 | bEditorDebugEnabled(true), 11 | LogVerbosity(14), 12 | WidgetUpdateFrequency(0.1f) 13 | { 14 | CategoryName = TEXT("Mountea Framework"); 15 | SectionName = TEXT("Mountea Interaction System"); 16 | } 17 | 18 | TSoftClassPtr UActorInteractionPluginSettings::GetInteractableDefaultWidgetClass() const 19 | { 20 | { return InteractableDefaultWidgetClass; }; 21 | } 22 | 23 | UMaterialInterface* UActorInteractionPluginSettings::GetDefaultHighlightMaterial() const 24 | { 25 | if (DefaultInteractionSystemConfig.LoadSynchronous()) 26 | { 27 | return DefaultInteractionSystemConfig.LoadSynchronous()->InteractableBaseSettings.DefaultHighlightSetup.HighlightMaterial; 28 | } 29 | return nullptr; 30 | } 31 | 32 | UInputMappingContext* UActorInteractionPluginSettings::GetDefaultInputMappingContext() const 33 | { 34 | return InteractionInputMapping.LoadSynchronous(); 35 | } 36 | 37 | EMounteaInteractionLoggingVerbosity UActorInteractionPluginSettings::GetAllowedLoggVerbosity() const 38 | { 39 | return static_cast(LogVerbosity); 40 | } 41 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Helpers/MounteaInteractionHelperEvents.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "Helpers/MounteaInteractionHelperEvents.h" 5 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Helpers/MounteaInteractionSettingsConfig.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "Helpers/MounteaInteractionSettingsConfig.h" 5 | 6 | #include "CommonInputTypeEnum.h" 7 | 8 | FKeyOnDevicePair::FKeyOnDevicePair() 9 | : SupportedDeviceType(ECommonInputType::MouseAndKeyboard) 10 | { 11 | } 12 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Private/Helpers/MounteaInteractionSystemBFL.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Morse (Pavlicek) 2024. All Rights Reserved. 2 | 3 | 4 | #include "Helpers/MounteaInteractionSystemBFL.h" 5 | #include "Helpers/ActorInteractionPluginSettings.h" 6 | #include "Helpers/MounteaInteractionSettingsConfig.h" 7 | 8 | #include "CommonInputSubsystem.h" 9 | #include "CommonInputTypeEnum.h" 10 | 11 | #include "Framework/Application/SlateApplication.h" 12 | 13 | #include "GameFramework/Pawn.h" 14 | 15 | #include "Kismet/GameplayStatics.h" 16 | #include "Kismet/KismetSystemLibrary.h" 17 | 18 | #include "Internationalization/Regex.h" 19 | 20 | #include "Components/MeshComponent.h" 21 | 22 | #include "Engine/World.h" 23 | 24 | UMeshComponent* UMounteaInteractionSystemBFL::FindMeshByTag(const FName Tag, const AActor* Source) 25 | { 26 | if (!Source) return nullptr; 27 | 28 | TArray MeshComponents; 29 | Source->GetComponents(MeshComponents); 30 | 31 | for (const auto& Itr : MeshComponents) 32 | { 33 | if (Itr && Itr->ComponentHasTag(Tag)) 34 | { 35 | return Itr; 36 | } 37 | } 38 | 39 | return nullptr; 40 | } 41 | 42 | UMeshComponent* UMounteaInteractionSystemBFL::FindMeshByName(const FName Name, const AActor* Source) 43 | { 44 | if (!Source) return nullptr; 45 | 46 | TArray MeshComponents; 47 | Source->GetComponents(MeshComponents); 48 | 49 | for (const auto& Itr : MeshComponents) 50 | { 51 | if (Itr && Itr->GetName().Equals(Name.ToString())) 52 | { 53 | return Itr; 54 | } 55 | } 56 | 57 | return nullptr; 58 | } 59 | 60 | UPrimitiveComponent* UMounteaInteractionSystemBFL::FindPrimitiveByTag(const FName Tag, const AActor* Source) 61 | { 62 | if (!Source) return nullptr; 63 | 64 | TArray MeshComponents; 65 | Source->GetComponents(MeshComponents); 66 | 67 | for (const auto& Itr : MeshComponents) 68 | { 69 | if (Itr && Itr->ComponentHasTag(Tag)) 70 | { 71 | return Itr; 72 | } 73 | } 74 | 75 | return nullptr; 76 | } 77 | 78 | UPrimitiveComponent* UMounteaInteractionSystemBFL::FindPrimitiveByName(const FName Name, const AActor* Source) 79 | { 80 | if (!Source) return nullptr; 81 | 82 | TArray MeshComponents; 83 | Source->GetComponents(MeshComponents); 84 | 85 | for (const auto& Itr : MeshComponents) 86 | { 87 | if (Itr && Itr->GetName().Equals(Name.ToString())) 88 | { 89 | return Itr; 90 | } 91 | } 92 | 93 | return nullptr; 94 | } 95 | 96 | UActorInteractionPluginSettings* UMounteaInteractionSystemBFL::GetInteractionSystemSettings() 97 | { 98 | return GetMutableDefault(); 99 | } 100 | 101 | bool UMounteaInteractionSystemBFL::CanExecuteCosmeticEvents(const UWorld* WorldContext) 102 | { 103 | return !UKismetSystemLibrary::IsDedicatedServer(WorldContext); 104 | } 105 | 106 | FText UMounteaInteractionSystemBFL::ReplaceRegexInText(const FText& SourceText, const TMap& Replacements) 107 | { 108 | FString ResultString = SourceText.ToString(); 109 | 110 | for (const auto& Replacement : Replacements) 111 | { 112 | FString Placeholder = Replacement.Key; 113 | const FString& ReplacementString = Replacement.Value.ToString(); 114 | 115 | // Check if the placeholder is already in the ${action} format 116 | if (!Placeholder.StartsWith(TEXT("${")) && !Placeholder.EndsWith(TEXT("}"))) 117 | { 118 | Placeholder = FString::Printf(TEXT("\\$\\{%s\\}"), *Placeholder); 119 | } 120 | else 121 | { 122 | Placeholder = FString::Printf(TEXT("\\$\\{%s\\}"), *Placeholder.Mid(2, Placeholder.Len() - 3)); 123 | } 124 | 125 | FRegexPattern Pattern(Placeholder); 126 | FRegexMatcher Matcher(Pattern, ResultString); 127 | 128 | FString TempResultString; 129 | int32 LastPosition = 0; 130 | 131 | while (Matcher.FindNext()) 132 | { 133 | int32 MatchBeginning = Matcher.GetMatchBeginning(); 134 | int32 MatchEnding = Matcher.GetMatchEnding(); 135 | 136 | TempResultString.Append(ResultString.Mid(LastPosition, MatchBeginning - LastPosition)); 137 | TempResultString.Append(ReplacementString); 138 | 139 | LastPosition = MatchEnding; 140 | } 141 | 142 | TempResultString.Append(ResultString.Mid(LastPosition)); 143 | ResultString = TempResultString; 144 | } 145 | 146 | return FText::FromString(ResultString); 147 | } 148 | 149 | ULocalPlayer* UMounteaInteractionSystemBFL::FindLocalPlayer(AActor* ForActor) 150 | { 151 | if (!ForActor) 152 | return nullptr; 153 | 154 | if (!ForActor->GetWorld()) 155 | return nullptr; 156 | 157 | APlayerController* localPlayerController = Cast(ForActor); 158 | if (localPlayerController) 159 | { 160 | return localPlayerController->GetLocalPlayer(); 161 | } 162 | 163 | APawn* localPawn = Cast(ForActor); 164 | if (localPawn) 165 | { 166 | localPlayerController = localPawn->GetController(); 167 | if (localPlayerController) 168 | { 169 | return localPlayerController->GetLocalPlayer(); 170 | } 171 | } 172 | 173 | localPlayerController = ForActor->GetWorld()->GetFirstPlayerController(); 174 | if (localPlayerController) 175 | return FindLocalPlayer(localPlayerController); 176 | 177 | return nullptr; 178 | } 179 | 180 | bool UMounteaInteractionSystemBFL::IsGamePadConnected() 181 | { 182 | auto genericApplication = FSlateApplication::Get().GetPlatformApplication(); 183 | if (genericApplication.Get() != nullptr && genericApplication->IsGamepadAttached()) 184 | { 185 | return true; 186 | } 187 | return false; 188 | } 189 | 190 | ECommonInputType UMounteaInteractionSystemBFL::GetActiveInputType(APlayerController* PlayerController) 191 | { 192 | if (!PlayerController) 193 | return ECommonInputType::MouseAndKeyboard; 194 | 195 | const auto localPlayer = PlayerController->GetLocalPlayer(); 196 | if (!localPlayer) 197 | return ECommonInputType::MouseAndKeyboard; 198 | 199 | UCommonInputSubsystem* commonInputSubsystem = UCommonInputSubsystem::Get(localPlayer); 200 | if (!commonInputSubsystem) 201 | return ECommonInputType::MouseAndKeyboard; 202 | 203 | return commonInputSubsystem->GetCurrentInputType(); 204 | } 205 | 206 | bool UMounteaInteractionSystemBFL::IsInputKeyPairSupported(APlayerController* PlayerController, const FKey& InputKey, const FString& HardwareDeviceID, TSoftObjectPtr& FoundInputTexture) 207 | { 208 | const UActorInteractionPluginSettings* settings = GetMutableDefault(); 209 | if (!settings) 210 | return false; 211 | 212 | ULocalPlayer* localPlayer = FindLocalPlayer(PlayerController); 213 | if (!localPlayer) 214 | return false; 215 | 216 | const auto interactionConfig = settings->DefaultInteractionSystemConfig; 217 | if (!interactionConfig) 218 | return false; 219 | 220 | const auto interactionConfigRef = interactionConfig.LoadSynchronous(); 221 | if (!interactionConfigRef) 222 | return false; 223 | 224 | if (interactionConfigRef->MappingKeys.Num() == 0) 225 | return false; 226 | 227 | const FString platformName = UGameplayStatics::GetPlatformName(); 228 | const ECommonInputType activeInputType = GetActiveInputType(PlayerController); 229 | 230 | for (const auto& Itr : interactionConfigRef->MappingKeys) 231 | { 232 | if (InputKey != Itr.Key) 233 | continue; 234 | 235 | TPair testPair(activeInputType, platformName); 236 | 237 | const FKeyOnDevicePair* foundPair = Itr.Value.KeyPairs.FindByPredicate([&testPair, &HardwareDeviceID](const FKeyOnDevicePair& Pair) 238 | { 239 | if (Pair.BlacklistedDeviceIDs.IsEmpty()) 240 | { 241 | return Pair == testPair; 242 | } 243 | return Pair == testPair && !Pair.BlacklistedDeviceIDs.Contains(HardwareDeviceID); 244 | }); 245 | 246 | if (foundPair) 247 | { 248 | FoundInputTexture = foundPair->KeyTexture; 249 | return true; 250 | } 251 | } 252 | 253 | return false; 254 | } -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/ActorInteractionPlugin.h: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Morse (Pavlicek) 2024. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Modules/ModuleManager.h" 7 | #include "Styling/SlateStyle.h" 8 | 9 | class FActorInteractionPluginModule : public IModuleInterface 10 | { 11 | public: 12 | 13 | /** IModuleInterface implementation */ 14 | virtual void StartupModule() override; 15 | virtual void ShutdownModule() override; 16 | }; 17 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Components/Interactable/ActorInteractableComponentAutomatic.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "ActorInteractableComponentBase.h" 7 | #include "ActorInteractableComponentAutomatic.generated.h" 8 | 9 | /** 10 | * Actor Interactable Automatic Component 11 | * 12 | * Child class of Actor Interactable Base Component. 13 | * This component will automatically finish with no need to press any key. Useful for notification interactions, like spotting an object from distance. 14 | * 15 | * Implements ActorInteractableInterface. 16 | * Networking is not implemented. 17 | * 18 | * @see https://github.com/Mountea-Framework/ActorInteractionPlugin/wiki/Actor-Interactable-Component-Automatic 19 | */ 20 | UCLASS(ClassGroup=(Mountea), meta=(BlueprintSpawnableComponent, DisplayName = "Interactable Component Auto")) 21 | class ACTORINTERACTIONPLUGIN_API UActorInteractableComponentAutomatic : public UActorInteractableComponentBase 22 | { 23 | GENERATED_BODY() 24 | 25 | public: 26 | 27 | UActorInteractableComponentAutomatic(); 28 | 29 | protected: 30 | 31 | virtual void BeginPlay() override; 32 | 33 | virtual void OnInteractionCompletedCallback(); 34 | 35 | virtual void InteractableSelected_Implementation(const TScriptInterface& Interactable) override; 36 | 37 | virtual void InteractionStarted_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) override; 38 | virtual void InteractionStopped_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) override; 39 | 40 | public: 41 | 42 | virtual FInteractionStarted& GetOnInteractionStartedHandle() override; 43 | virtual FInteractionStopped& GetOnInteractionStoppedHandle() override; 44 | 45 | private: 46 | 47 | FInteractionStarted EmptyHandle_Started; 48 | FInteractionStopped EmptyHandle_Stopped; 49 | }; 50 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Components/Interactable/ActorInteractableComponentHold.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "ActorInteractableComponentBase.h" 7 | #include "ActorInteractableComponentHold.generated.h" 8 | 9 | /** 10 | * Actor Interactable Hold Component 11 | * 12 | * Child class of Actor Interactable Base Component. 13 | * This component requires to hold interaction key for specified period of time. 14 | * 15 | * Implements ActorInteractableInterface. 16 | * Networking is not implemented. 17 | * 18 | * @see https://github.com/Mountea-Framework/ActorInteractionPlugin/wiki/Actor-Interactable-Component-Hold 19 | */ 20 | UCLASS(ClassGroup=(Mountea), meta=(BlueprintSpawnableComponent, DisplayName = "Interactable Component Hold")) 21 | class ACTORINTERACTIONPLUGIN_API UActorInteractableComponentHold : public UActorInteractableComponentBase 22 | { 23 | GENERATED_BODY() 24 | 25 | public: 26 | 27 | UActorInteractableComponentHold(); 28 | 29 | protected: 30 | 31 | virtual void InteractionStarted_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) override; 32 | 33 | protected: 34 | 35 | UFUNCTION() 36 | void OnInteractionCompletedCallback(); 37 | }; 38 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Components/Interactable/ActorInteractableComponentHover.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "ActorInteractableComponentHold.h" 7 | #include "Components/ActorComponent.h" 8 | #include "ActorInteractableComponentHover.generated.h" 9 | 10 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCursorBeginsOverlap, UPrimitiveComponent*, PrimitiveComponent); 11 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnCursorStopsOverlap, UPrimitiveComponent*, PrimitiveComponent); 12 | 13 | UCLASS(ClassGroup=(Mountea), meta=(BlueprintSpawnableComponent, DisplayName = "Interactable Component Hover")) 14 | class ACTORINTERACTIONPLUGIN_API UActorInteractableComponentHover : public UActorInteractableComponentHold 15 | { 16 | GENERATED_BODY() 17 | 18 | public: 19 | 20 | UActorInteractableComponentHover(); 21 | 22 | protected: 23 | 24 | virtual void BeginPlay() override; 25 | 26 | virtual void BindCollisionShape_Implementation(UPrimitiveComponent* PrimitiveComponent) const override; 27 | virtual void UnbindCollisionShape_Implementation(UPrimitiveComponent* PrimitiveComponent) const override; 28 | 29 | virtual bool CanInteract_Implementation() const override; 30 | 31 | 32 | UFUNCTION() 33 | void OnHoverBeginsEvent(UPrimitiveComponent* PrimitiveComponent); 34 | UFUNCTION() 35 | void OnHoverStopsEvent(UPrimitiveComponent* PrimitiveComponent); 36 | 37 | protected: 38 | 39 | /** 40 | * Event called once collision is overlapped by Cursor. 41 | */ 42 | UPROPERTY(BlueprintAssignable, Category="Mountea|Interaction|Interactable") 43 | FOnCursorBeginsOverlap OnCursorBeginsOverlap; 44 | /** 45 | * Event called once collision is no longer overlapped by Cursor. 46 | */ 47 | UPROPERTY(BlueprintAssignable, Category="Mountea|Interaction|Interactable") 48 | FOnCursorStopsOverlap OnCursorStopsOverlap; 49 | 50 | protected: 51 | 52 | UPROPERTY(SaveGame, VisibleAnywhere, Category="MounteaInteraction|Read Only") 53 | UPrimitiveComponent* OverlappingComponent = nullptr; 54 | }; 55 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Components/Interactable/ActorInteractableComponentMash.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "ActorInteractableComponentBase.h" 7 | #include "ActorInteractableComponentMash.generated.h" 8 | 9 | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnInteractionFailed); 10 | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnKeyMashed); 11 | 12 | /** 13 | * Actor Interactable Mash Component 14 | * 15 | * Child class of Actor Interactable Base Component. 16 | * This component requires to press interaction key multiple times within specified time period. 17 | * This interaction can fail if the interaction key is not pressed enough times or time runs out. 18 | * 19 | * Implements ActorInteractableInterface. 20 | * Networking is not implemented. 21 | * 22 | * @see https://github.com/Mountea-Framework/ActorInteractionPlugin/wiki/Actor-Interactable-Component-Mash 23 | */ 24 | UCLASS(ClassGroup=(Mountea), meta=(BlueprintSpawnableComponent, DisplayName = "Interactable Component Mash")) 25 | class ACTORINTERACTIONPLUGIN_API UActorInteractableComponentMash : public UActorInteractableComponentBase 26 | { 27 | GENERATED_BODY() 28 | 29 | public: 30 | 31 | UActorInteractableComponentMash(); 32 | 33 | protected: 34 | 35 | virtual void BeginPlay() override; 36 | virtual void InteractionStarted_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) override; 37 | virtual void InteractionStopped_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) override; 38 | virtual void InteractionCanceled_Implementation() override; 39 | 40 | protected: 41 | 42 | /** 43 | * Event called from OnInteractionFailed 44 | */ 45 | UFUNCTION(BlueprintImplementableEvent, Category="Mountea|Interaction|Interactable") 46 | void OnInteractionFailedEvent(); 47 | UFUNCTION() 48 | virtual void InteractionFailed(); 49 | virtual void OnInteractionFailedCallback(); 50 | 51 | UFUNCTION() 52 | void OnInteractionCompletedCallback(); 53 | 54 | /** 55 | * Event called once Key is pressed. 56 | * Is the same as Interaction Started, but with more understandable name. 57 | */ 58 | UFUNCTION(BlueprintImplementableEvent, Category="Mountea|Interaction|Interactable") 59 | void OnKeyMashedEvent(); 60 | 61 | virtual void CleanupComponent() override; 62 | 63 | public: 64 | 65 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactable") 66 | int32 GetMinMashAmountRequired() const; 67 | UFUNCTION(BlueprintCallable, Category="Mountea|Interaction|Interactable") 68 | void SetMinMainAmountRequired(const int32 Value); 69 | 70 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactable") 71 | float GetKeystrokeTimeThreshold() const; 72 | UFUNCTION(BlueprintCallable, Category="Mountea|Interaction|Interactable") 73 | void SetKeystrokeTimeThreshold(const float Value); 74 | 75 | protected: 76 | 77 | /** 78 | * How many time the button must be pressed to accept the interaction as completed. 79 | */ 80 | UPROPERTY(SaveGame, EditAnywhere, BlueprintReadOnly, Category="MounteaInteraction|Required", meta=(Units = "times", UIMin = 2, ClampMin = 2)) 81 | int32 MinMashAmountRequired; 82 | 83 | /** 84 | * How much time it is allowed between each Key stroke before interaction fails. 85 | */ 86 | UPROPERTY(SaveGame, EditAnywhere, BlueprintReadOnly, Category="MounteaInteraction|Required", meta=(Units = "s", UIMin = 0.01, ClampMin = 0.01)) 87 | float KeystrokeTimeThreshold; 88 | 89 | protected: 90 | 91 | FTimerHandle TimerHandle_Mashed; 92 | 93 | /** 94 | * How many times the key was mashed. 95 | */ 96 | UPROPERTY(VisibleAnywhere, Category="MounteaInteraction|Read Only") 97 | int32 ActualMashAmount; 98 | 99 | protected: 100 | 101 | /** 102 | * Event called once Interaction Mash fails. 103 | * Either because of Time is out or not enough Key strokes are registered. 104 | * Calls OnInteractionFailedEvent. 105 | */ 106 | UPROPERTY(BlueprintAssignable, Category="Mountea|Interaction|Interactable") 107 | FOnInteractionFailed OnInteractionFailed; 108 | 109 | /** 110 | * Event called once Key is pressed. 111 | * Is the same as Interaction Started, but with more understandable name. 112 | */ 113 | UPROPERTY(BlueprintAssignable, Category="Mountea|Interaction|Interactable") 114 | FOnKeyMashed OnKeyMashed; 115 | }; -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Components/Interactable/ActorInteractableComponentPress.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "ActorInteractableComponentBase.h" 7 | #include "ActorInteractableComponentPress.generated.h" 8 | 9 | /** 10 | * Actor Interactable Press Component 11 | * 12 | * Child class of Actor Interactable Base Component. 13 | * This component requires to press interaction key. Interaction period is ignored. 14 | * 15 | * Implements ActorInteractableInterface. 16 | * Networking is not implemented. 17 | * 18 | * @see https://github.com/Mountea-Framework/ActorInteractionPlugin/wiki/Actor-Interactable-Component-Press 19 | */ 20 | UCLASS(ClassGroup=(Mountea), meta=(BlueprintSpawnableComponent, DisplayName = "Interactable Component Press")) 21 | class ACTORINTERACTIONPLUGIN_API UActorInteractableComponentPress : public UActorInteractableComponentBase 22 | { 23 | GENERATED_BODY() 24 | 25 | public: 26 | 27 | UActorInteractableComponentPress(); 28 | 29 | protected: 30 | 31 | virtual void BeginPlay() override; 32 | 33 | virtual void InteractionStarted_Implementation(const float& TimeStarted, const TScriptInterface& CausingInteractor) override; 34 | virtual void SetDefaults_Implementation() override; 35 | 36 | #if WITH_EDITOR 37 | virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override; 38 | virtual EDataValidationResult IsDataValid(FDataValidationContext& Context) const override; 39 | #endif 40 | 41 | }; 42 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Components/Interactor/ActorInteractorComponentOverlap.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Components/PrimitiveComponent.h" 7 | #include "ActorInteractorComponentBase.h" 8 | #include "ActorInteractorComponentOverlap.generated.h" 9 | 10 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCollisionShapeAdded, UPrimitiveComponent*, AddedComponent); 11 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCollisionShapeRemoved, UPrimitiveComponent*, RemovedComponent); 12 | 13 | /** 14 | * 15 | */ 16 | UCLASS(ClassGroup=(Mountea), meta=(BlueprintSpawnableComponent, DisplayName = "Interactor Component Overlap")) 17 | class ACTORINTERACTIONPLUGIN_API UActorInteractorComponentOverlap : public UActorInteractorComponentBase 18 | { 19 | GENERATED_BODY() 20 | 21 | public: 22 | // Sets default values for this component's properties 23 | UActorInteractorComponentOverlap(); 24 | 25 | protected: 26 | 27 | virtual void BeginPlay() override; 28 | 29 | virtual FString ToString_Implementation() const override; 30 | 31 | virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; 32 | 33 | public: 34 | 35 | virtual void SetupInteractorOverlap(); 36 | virtual void BindCollisions(); 37 | 38 | virtual void BindCollision(UPrimitiveComponent* Component); 39 | virtual void UnbindCollisions(); 40 | virtual void UnbindCollision(UPrimitiveComponent* Component); 41 | 42 | protected: 43 | 44 | /** 45 | * 46 | */ 47 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 48 | void ProcessOverlap(UPrimitiveComponent* OverlappedComponent,AActor* OtherActor, UPrimitiveComponent* OtherComp, const FHitResult& SweepResult, const bool bOverlapStarted); 49 | virtual void ProcessOverlap_Implementation(UPrimitiveComponent* OverlappedComponent,AActor* OtherActor, UPrimitiveComponent* OtherComp, const FHitResult& SweepResult, const bool bOverlapStarted); 50 | 51 | UFUNCTION() 52 | void StartInteractorOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); 53 | UFUNCTION() 54 | void StopInteractorOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); 55 | 56 | void HandleStartOverlap(UPrimitiveComponent* PrimitiveComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, const FHitResult& HitResult); 57 | void HandleEndOverlap(UPrimitiveComponent* PrimitiveComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp); 58 | 59 | public: 60 | 61 | /** 62 | * 63 | * @param CollisionComponent 64 | */ 65 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Interaction|Interactor") 66 | void AddCollisionComponent(UPrimitiveComponent* CollisionComponent); 67 | virtual void AddCollisionComponent_Implementation(UPrimitiveComponent* CollisionComponent); 68 | 69 | /** 70 | * 71 | * @param CollisionComponents 72 | */ 73 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Interaction|Interactor") 74 | void AddCollisionComponents(const TArray& CollisionComponents); 75 | virtual void AddCollisionComponents_Implementation(const TArray& CollisionComponents); 76 | 77 | /** 78 | * 79 | * @param CollisionComponent 80 | */ 81 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Interaction|Interactor") 82 | void RemoveCollisionComponent(UPrimitiveComponent* CollisionComponent); 83 | virtual void RemoveCollisionComponent_Implementation(UPrimitiveComponent* CollisionComponent); 84 | 85 | /** 86 | * 87 | * @param CollisionComponents 88 | */ 89 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="Mountea|Interaction|Interactor") 90 | void RemoveCollisionComponents(const TArray& CollisionComponents); 91 | virtual void RemoveCollisionComponents_Implementation(const TArray& CollisionComponents); 92 | 93 | /** 94 | * 95 | * @return 96 | */ 97 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactor") 98 | TArray GetCollisionComponents() const; 99 | 100 | protected: 101 | 102 | virtual void ProcessStateChanged() override; 103 | 104 | protected: 105 | 106 | UFUNCTION(Server, Unreliable) 107 | void AddCollisionComponent_Server(UPrimitiveComponent* CollisionComponent); 108 | 109 | UFUNCTION(Server, Unreliable) 110 | void AddCollisionComponents_Server(const TArray& CollisionComponents); 111 | 112 | UFUNCTION(Server, Unreliable) 113 | void RemoveCollisionComponent_Server(UPrimitiveComponent* CollisionComponent); 114 | 115 | UFUNCTION(Server, Unreliable) 116 | void RemoveCollisionComponents_Server(const TArray& CollisionComponents); 117 | 118 | UFUNCTION(Server, Reliable) 119 | void ProcessOverlap_Server(UPrimitiveComponent* OverlappedComponent,AActor* OtherActor, UPrimitiveComponent* OtherComp, const FHitResult& SweepResult, const bool bOverlapStarted); 120 | 121 | UFUNCTION(Server, Reliable) 122 | void StartInteractorOverlap_Server(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult); 123 | 124 | UFUNCTION(Server, Reliable) 125 | void StopInteractorOverlap_Server(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComp, int32 OtherBodyIndex); 126 | 127 | public: 128 | 129 | UPROPERTY(BlueprintAssignable, Category="Mountea|Interaction|Interactor") 130 | FCollisionShapeAdded OnCollisionShapeAdded; 131 | 132 | UPROPERTY(BlueprintAssignable, Category="Mountea|Interaction|Interactor") 133 | FCollisionShapeRemoved OnCollisionShapeRemoved; 134 | 135 | protected: 136 | 137 | UPROPERTY(EditAnywhere, Category="MounteaInteraction|Optional") 138 | TArray OverrideCollisionComponents; 139 | 140 | /** 141 | * A list of Collision Shapes that are used as interactors. 142 | * List is populated on Server Side only! 143 | */ 144 | UPROPERTY(Replicated, SaveGame, VisibleAnywhere, Category="MounteaInteraction|Read Only", meta=(DisplayThumbnail = false, ShowOnlyInnerProperties)) 145 | TArray> CollisionShapes; 146 | 147 | private: 148 | 149 | /** 150 | * Cached Collision Shape Settings. 151 | * Filled when Collision Shapes are registered. 152 | * Once Collision Shape is unregistered, it reads its cached settings and returns to pre-interaction Collision Settings. 153 | */ 154 | UPROPERTY(SaveGame, VisibleAnywhere, Category="MounteaInteraction|Read Only", meta=(DisplayThumbnail = false, ShowOnlyInnerProperties)) 155 | mutable TMap CachedCollisionShapesSettings; 156 | 157 | }; -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Components/Interactor/ActorInteractorComponentTrace.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "ActorInteractorComponentBase.h" 7 | #include "CollisionQueryParams.h" 8 | #include "Engine/HitResult.h" 9 | #include "ActorInteractorComponentTrace.generated.h" 10 | 11 | /** 12 | * 13 | */ 14 | UENUM(BlueprintType) 15 | enum class EMounteaTraceType : uint8 16 | { 17 | ETT_Precise UMETA(DisplayName = "Precise", Tooltip = "Raycast/Line Trace."), 18 | ETT_Loose UMETA(DisplayName = "Loose", Tooltip = "Cubecast/Cube Trace."), 19 | 20 | Default UMETA(hidden) 21 | }; 22 | 23 | /** 24 | * Interaction Tracing Data used easier data management. 25 | */ 26 | struct FInteractionTraceDataV2 27 | { 28 | FVector StartLocation; 29 | FVector EndLocation; 30 | FRotator TraceRotation; 31 | TArray HitResults; 32 | FCollisionQueryParams CollisionParams; 33 | ECollisionChannel CollisionChannel; 34 | 35 | // Default zero constructor 36 | FInteractionTraceDataV2() 37 | { 38 | StartLocation = FVector(); 39 | EndLocation = FVector(); 40 | TraceRotation = FRotator(); 41 | CollisionParams = FCollisionQueryParams(); 42 | CollisionChannel = ECC_Visibility; 43 | }; 44 | 45 | FInteractionTraceDataV2(const FVector& Start, const FVector& End, const FRotator Rotation, const FCollisionQueryParams& Params, const ECollisionChannel& Channel) 46 | { 47 | StartLocation = Start; 48 | EndLocation = End; 49 | TraceRotation = Rotation; 50 | CollisionParams = Params; 51 | CollisionChannel = Channel; 52 | }; 53 | }; 54 | 55 | #pragma region TracingData 56 | USTRUCT(BlueprintType) 57 | struct FTracingData 58 | { 59 | GENERATED_BODY() 60 | 61 | UPROPERTY(Category="MounteaInteraction|FTracingData", VisibleAnywhere, BlueprintReadWrite) 62 | EMounteaTraceType TracingType; 63 | UPROPERTY(Category="MounteaInteraction|FTracingData", VisibleAnywhere, BlueprintReadWrite) 64 | float TracingInterval; 65 | UPROPERTY(Category="MounteaInteraction|FTracingData", VisibleAnywhere, BlueprintReadWrite) 66 | float TracingRange; 67 | UPROPERTY(Category="MounteaInteraction|FTracingData", VisibleAnywhere, BlueprintReadWrite) 68 | float TracingShapeHalfSize; 69 | UPROPERTY(Category="MounteaInteraction|FTracingData", VisibleAnywhere, BlueprintReadWrite) 70 | uint8 bUsingCustomStartTransform : 1; 71 | UPROPERTY(Category="MounteaInteraction|FTracingData", VisibleAnywhere, BlueprintReadWrite) 72 | FTransform CustomTracingTransform; 73 | 74 | FTracingData() : 75 | TracingType(EMounteaTraceType::ETT_Loose), 76 | TracingInterval(0.01f), 77 | TracingRange(250.f), 78 | TracingShapeHalfSize(5.f), 79 | bUsingCustomStartTransform(false), 80 | CustomTracingTransform(FTransform()) 81 | {}; 82 | 83 | FTracingData 84 | ( 85 | EMounteaTraceType NewType, 86 | float NewInterval, 87 | float NewRange, 88 | float NewShapeHalfSize, 89 | bool bUse, 90 | FTransform NewTransform 91 | ) : 92 | TracingType(NewType), bUsingCustomStartTransform(bUse), CustomTracingTransform(NewTransform) 93 | { 94 | TracingInterval = FMath::Max(0.01f, NewInterval); 95 | TracingRange = FMath::Max(1.f, NewRange); 96 | TracingShapeHalfSize = FMath::Max(0.1f, NewShapeHalfSize); 97 | } 98 | 99 | inline bool operator==(const FTracingData& Other) const 100 | { 101 | return 102 | TracingType == Other.TracingType && 103 | FMath::IsNearlyEqual(TracingInterval, Other.TracingInterval) && 104 | FMath::IsNearlyEqual(TracingRange, Other.TracingRange) && 105 | FMath::IsNearlyEqual(TracingShapeHalfSize, Other.TracingShapeHalfSize) && 106 | bUsingCustomStartTransform == Other.bUsingCustomStartTransform && 107 | (bUsingCustomStartTransform && CustomTracingTransform.Equals(Other.CustomTracingTransform)) 108 | ; 109 | } 110 | 111 | inline bool operator!=(const FTracingData& Other) const 112 | { 113 | return !(*this==Other); 114 | } 115 | }; 116 | #pragma endregion 117 | 118 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FTracingDataChanged, const FTracingData&, NewTracingData, const FTracingData&, OldTracingData); 119 | DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnTraced); 120 | 121 | /** 122 | * 123 | */ 124 | UCLASS(ClassGroup=(Mountea), meta=(BlueprintSpawnableComponent, DisplayName = "Interactor Component Trace")) 125 | class ACTORINTERACTIONPLUGIN_API UActorInteractorComponentTrace : public UActorInteractorComponentBase 126 | { 127 | GENERATED_BODY() 128 | 129 | public: 130 | 131 | UActorInteractorComponentTrace(); 132 | 133 | protected: 134 | 135 | virtual void BeginPlay() override; 136 | 137 | public: 138 | 139 | /** 140 | * Disables Tracing. Can be Enabled again. Clears all timers. 141 | */ 142 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 143 | void DisableTracing(); 144 | virtual void DisableTracing_Implementation(); 145 | 146 | /** 147 | * Tries to enable Tracing. Could fail if non valid state. 148 | */ 149 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 150 | void EnableTracing(); 151 | virtual void EnableTracing_Implementation(); 152 | 153 | /** 154 | * Pauses Tracing if already active. 155 | */ 156 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 157 | void PauseTracing(); 158 | virtual void PauseTracing_Implementation(); 159 | 160 | /** 161 | * 162 | */ 163 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 164 | void ResumeTracing(); 165 | virtual void ResumeTracing_Implementation(); 166 | 167 | /** 168 | * Returns whether Tracing is allowed or not. 169 | */ 170 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 171 | bool CanTrace() const; 172 | virtual bool CanTrace_Implementation() const; 173 | 174 | /** 175 | * Returns Trace Type. 176 | */ 177 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactor") 178 | virtual EMounteaTraceType GetTraceType() const; 179 | 180 | /** 181 | * Sets Trace Type. 182 | * 183 | * @param NewTraceType Value to be set. 184 | */ 185 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 186 | void SetTraceType(const EMounteaTraceType& NewTraceType); 187 | virtual void SetTraceType_Implementation(const EMounteaTraceType& NewTraceType); 188 | 189 | /** 190 | * Returns Trace Interval in seconds. 191 | */ 192 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactor") 193 | virtual float GetTraceInterval() const; 194 | 195 | /** 196 | * Sets Trace Interval in seconds. 197 | * Clamped to be at least 0.01s. 198 | * 199 | * @param NewInterval Value to be set 200 | */ 201 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 202 | void SetTraceInterval(const float NewInterval); 203 | virtual void SetTraceInterval_Implementation(const float NewInterval); 204 | 205 | /** 206 | * Returns Trace Range in cm. 207 | */ 208 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactor") 209 | virtual float GetTraceRange() const; 210 | 211 | /** 212 | * Sets Trace Range in cm. 213 | * Clamped to be at least 1cm. 214 | * 215 | * @param NewRange Value to be set 216 | */ 217 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 218 | void SetTraceRange(const float NewRange); 219 | virtual void SetTraceRange_Implementation(const float NewRange); 220 | 221 | /** 222 | * Returns Trace Shape Half Size in cm. 223 | * Defines how precise tracing is when using Loose tracing type. 224 | */ 225 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactor") 226 | virtual float GetTraceShapeHalfSize() const; 227 | 228 | /** 229 | * Sets Trace Shape Half Size in cm. 230 | * Clamped to be at least 0.1cm. 231 | * 232 | * @param NewTraceShapeHalfSize Value to be set 233 | */ 234 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 235 | void SetTraceShapeHalfSize(const float NewTraceShapeHalfSize); 236 | virtual void SetTraceShapeHalfSize_Implementation(const float NewTraceShapeHalfSize); 237 | 238 | /** 239 | * Returns whether using Custom Trace Transform. 240 | */ 241 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactor") 242 | virtual bool GetUseCustomStartTransform() const; 243 | 244 | /** 245 | * Sets Using Custom Trace Start Transform. 246 | * 247 | * @param bUse Value to be set 248 | */ 249 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 250 | void SetUseCustomStartTransform(const bool bUse); 251 | virtual void SetUseCustomStartTransform_Implementation(const bool bUse); 252 | 253 | /** 254 | * Returns transient Tracing Data. 255 | * Structure of all Tracing Data at one place. 256 | * Updated every time any value is changed. 257 | */ 258 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactor") 259 | virtual FTracingData GetLastTracingData() const; 260 | 261 | /** 262 | * Sets Trace Start to specified location. 263 | * 264 | * @param TraceStart Value to be used as Custom Trace Start. 265 | */ 266 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 267 | void SetCustomTraceStart(const FTransform& TraceStart); 268 | virtual void SetCustomTraceStart_Implementation(const FTransform& TraceStart); 269 | 270 | /** 271 | * Returns current Custom Trace Start value. 272 | */ 273 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Interactor") 274 | virtual FTransform GetCustomTraceStart() const; 275 | 276 | protected: 277 | 278 | /** 279 | * 280 | */ 281 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 282 | void ProcessTrace(); 283 | virtual void ProcessTrace_Implementation(); 284 | virtual void ProcessTrace_Precise(FInteractionTraceDataV2& InteractionTraceData); 285 | virtual void ProcessTrace_Loose(FInteractionTraceDataV2& InteractionTraceData); 286 | 287 | /** 288 | * Function called after Trace has finished. 289 | * Could be called Twice: 290 | * * On Client 291 | * * On Server 292 | */ 293 | UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category="MounteaInteraction|Tracing") 294 | void PostTraced(); 295 | virtual void PostTraced_Implementation(); 296 | 297 | protected: 298 | 299 | UFUNCTION(Server, Reliable) 300 | void DisableTracing_Server(); 301 | UFUNCTION(Server, Reliable) 302 | void EnableTracing_Server(); 303 | UFUNCTION(Server, Reliable) 304 | void PauseTracing_Server(); 305 | UFUNCTION(Server, Reliable) 306 | void ResumeTracing_Server(); 307 | 308 | UFUNCTION(Server, Reliable) 309 | void ProcessTrace_Server(); 310 | 311 | UFUNCTION(Server, Unreliable) 312 | void SetTraceType_Server(const EMounteaTraceType& NewTraceType); 313 | 314 | UFUNCTION(Server, Unreliable) 315 | void SetTraceInterval_Server(float NewInterval); 316 | 317 | UFUNCTION(Server, Unreliable) 318 | void SetTraceRange_Server(float NewRange); 319 | 320 | UFUNCTION(Server, Unreliable) 321 | void SetTraceShapeHalfSize_Server(float NewTraceShapeHalfSize); 322 | 323 | UFUNCTION(Server, Unreliable) 324 | void SetUseCustomStartTransform_Server(bool bUse); 325 | 326 | UFUNCTION(Server, Unreliable) 327 | void SetCustomTraceStart_Server(const FTransform& TraceStart); 328 | 329 | UFUNCTION(Client, Unreliable) 330 | void PostTraced_Client(); 331 | 332 | protected: 333 | 334 | virtual void ProcessStateChanged() override; 335 | 336 | virtual FString ToString_Implementation() const override; 337 | 338 | virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override; 339 | 340 | #pragma region Variables 341 | 342 | protected: 343 | 344 | /** 345 | * Defines how precise the interaction is. 346 | * - Loose Tracing is using BoxTrace and does not require precision. 347 | * - Precise Tracing is using LineTrace and requires higher precision. Useful with smaller objects. 348 | */ 349 | UPROPERTY(Replicated, EditAnywhere, Category="MounteaInteraction|Required") 350 | EMounteaTraceType TraceType; 351 | 352 | /** 353 | * Optimization feature. 354 | * The frequency in seconds at which the Interaction function will be executed. 355 | * 356 | * Min value is 0.01 (1e-2) 357 | * Higher the value, less frequent tracing is and less performance is required. 358 | * Lower the value, more frequent tracing is and more performance is required. 359 | */ 360 | UPROPERTY(Replicated, EditAnywhere, Category="MounteaInteraction|Required", meta=(Units = "s", UIMin=0.01f, ClampMin=0.01f, DisplayName="Tick Interval (sec)")) 361 | float TraceInterval; 362 | 363 | /** 364 | * Defines the length of interaction tracing. 365 | * Higher the value, further items can be reached. 366 | * Min value: 0.01cm 367 | */ 368 | UPROPERTY(Replicated, EditAnywhere, Category="MounteaInteraction|Required", meta=(Units = "cm", UIMin=1, ClampMin=1, DisplayName="Interaction Range (cm)")) 369 | float TraceRange; 370 | 371 | /** 372 | * Defines half extend of Loose Tracing. 373 | * - Higher the value, less precise interaction is. 374 | * - Lower the value, more precise interaction is. 375 | */ 376 | UPROPERTY(Replicated, EditAnywhere, Category="MounteaInteraction|Required", meta=(Units = "cm", UIMin=0.1f, ClampMin=0.1f)) 377 | float TraceShapeHalfSize = 5.0f; 378 | 379 | /** 380 | * Defines whether Tracing starts at ActorEyesViewPoint (default) or at a given Location. 381 | */ 382 | UPROPERTY(Replicated, EditAnywhere, Category="MounteaInteraction|Required") 383 | uint8 bUseCustomStartTransform : 1; 384 | 385 | /** 386 | * Transform in World Space. 387 | * Suggested use: 388 | * - Update from Code/Blueprint to follow Socket, like Weapon Barrel 389 | * 390 | * Defines where does the Tracing start and what direction it follows. 391 | * Will be ignored if bUseCustomStartTransform is false. 392 | */ 393 | UPROPERTY(Replicated, VisibleAnywhere, Category="MounteaInteraction|Read Only", AdvancedDisplay, meta=(DisplayName="Trace Start (World Space Transform)")) 394 | FTransform CustomTraceTransform; 395 | 396 | /** 397 | * Structure of all Tracing Data at one place. 398 | * Updated every time any value is changed. 399 | */ 400 | UPROPERTY(Transient, VisibleAnywhere, Category="MounteaInteraction|Read Only") 401 | FTracingData LastTracingData; 402 | 403 | /** 404 | * Timer Handle. 405 | * Won't display any values in Blueprints. 406 | */ 407 | UPROPERTY(VisibleAnywhere, Category="MounteaInteraction|Read Only") 408 | FTimerHandle Timer_Ticking; 409 | 410 | #pragma endregion 411 | 412 | #pragma region Events 413 | 414 | protected: 415 | 416 | /** 417 | * Event called every time any Trace value has changed. 418 | * Will provide information about Old data and New data. Useful when debugging. 419 | */ 420 | UPROPERTY(BlueprintAssignable, Category="Mountea|Interaction|Interactor") 421 | FTracingDataChanged OnTraceDataChanged; 422 | 423 | /** 424 | * 425 | */ 426 | UPROPERTY(BlueprintAssignable, Category="Mountea|Interaction|Interactor") 427 | FOnTraced OnTraced; 428 | 429 | #pragma endregion 430 | 431 | #if WITH_EDITOR 432 | 433 | protected: 434 | 435 | virtual void DrawTracingDebugStart(FInteractionTraceDataV2& InteractionTraceData) const; 436 | virtual void DrawTracingDebugEnd(FInteractionTraceDataV2& InteractionTraceData) const; 437 | 438 | virtual void PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent) override; 439 | 440 | #endif 441 | }; -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Helpers/ActorInteractionFunctionLibrary.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | #include "Kismet/BlueprintFunctionLibrary.h" 8 | #include "ActorInteractionFunctionLibrary.generated.h" 9 | 10 | struct FInteractableBaseSettings; 11 | struct FInteractorBaseSettings; 12 | struct FInteractionHighlightSetup; 13 | class UDataTable; 14 | class UUserWidget; 15 | class UActorInteractionPluginSettings; 16 | 17 | /** 18 | * 19 | */ 20 | UCLASS() 21 | class ACTORINTERACTIONPLUGIN_API UActorInteractionFunctionLibrary : public UBlueprintFunctionLibrary 22 | { 23 | GENERATED_BODY() 24 | 25 | public: 26 | 27 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction", meta=(CompactNodeTitle="Default Interaction Settings")) 28 | static UActorInteractionPluginSettings* GetInteractionSettings(); 29 | 30 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction", meta=(CompactNodeTitle="Default Interaction Settings")) 31 | static FInteractorBaseSettings GetDefaultInteractorSettings(); 32 | 33 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction", meta=(CompactNodeTitle="Default Interaction Settings")) 34 | static FInteractableBaseSettings GetDefaultInteractableSettings(); 35 | 36 | /** 37 | * Returns Default Widget Update frequency. 38 | * Default value is 0.05. 39 | * 40 | * This value can be updated in Project Settings. 41 | */ 42 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction", meta=(CompactNodeTitle="Default Widget Frequncy")) 43 | static float GetDefaultWidgetUpdateFrequency(); 44 | 45 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction", meta=(CompactNodeTitle="Default Interactable Data")) 46 | static UDataTable* GetInteractableDefaultDataTable(); 47 | 48 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction", meta=(CompactNodeTitle="Default Interactable Widget")) 49 | static TSubclassOf GetInteractableDefaultWidgetClass(); 50 | 51 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction", meta=(CompactNodeTitle="Is Debug Enabled")) 52 | static bool IsEditorDebugEnabled(); 53 | }; 54 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Helpers/ActorInteractionPluginLog.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Morse (Pavlicek) 2024. All Rights Reserved. 2 | 3 | #include "Helpers/ActorInteractionPluginLog.h" 4 | 5 | #include "ActorInteractionPluginSettings.h" 6 | #include "MounteaInteractionGeneralDataTypes.h" 7 | #include "Engine/World.h" 8 | #include "Kismet/KismetSystemLibrary.h" 9 | 10 | // Log category definition 11 | DEFINE_LOG_CATEGORY(LogActorInteraction); 12 | 13 | void PrintInteractionLog(const ELogVerbosity::Type Verbosity, const FString& Message, FLinearColor Color, float Duration) 14 | { 15 | if (!GWorld) return; 16 | 17 | bool isVerbosityAllowed = false; 18 | 19 | if (const UActorInteractionPluginSettings* interactionSettings = GetDefault()) 20 | { 21 | const EMounteaInteractionLoggingVerbosity AllowedLogging = interactionSettings->GetAllowedLoggVerbosity(); 22 | 23 | switch (Verbosity) 24 | { 25 | case ELogVerbosity::Fatal: 26 | case ELogVerbosity::Error: 27 | isVerbosityAllowed = EnumHasAnyFlags(AllowedLogging, EMounteaInteractionLoggingVerbosity::Error); 28 | break; 29 | case ELogVerbosity::Warning: 30 | case ELogVerbosity::Verbose: 31 | isVerbosityAllowed = EnumHasAnyFlags(AllowedLogging, EMounteaInteractionLoggingVerbosity::Warning); 32 | break; 33 | case ELogVerbosity::Display: 34 | isVerbosityAllowed = EnumHasAnyFlags(AllowedLogging, EMounteaInteractionLoggingVerbosity::Info); 35 | break; 36 | case ELogVerbosity::VeryVerbose: 37 | isVerbosityAllowed = false; 38 | break; 39 | case ELogVerbosity::Log: 40 | isVerbosityAllowed = false; 41 | break; 42 | default: 43 | isVerbosityAllowed = false; 44 | break; 45 | } 46 | } 47 | 48 | if (isVerbosityAllowed) 49 | { 50 | #if WITH_EDITOR 51 | FMsg::Logf(__FILE__, __LINE__, LogActorInteraction.GetCategoryName(), Verbosity, TEXT("%s"), *Message); 52 | #endif 53 | 54 | UKismetSystemLibrary::PrintString(GWorld, Message, true, true, Color, Duration); 55 | } 56 | } -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Helpers/ActorInteractionPluginLog.h: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Morse (Pavlicek) 2024. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | // Log category definition 8 | ACTORINTERACTIONPLUGIN_API DECLARE_LOG_CATEGORY_EXTERN(LogActorInteraction, Display, All); 9 | 10 | // Forward declaration of the logging function 11 | void PrintInteractionLog(const ELogVerbosity::Type Verbosity, const FString& Message, FLinearColor Color, float Duration); 12 | 13 | // Logging macro definitions 14 | #define LOG_INFO(Format, ...) \ 15 | { \ 16 | FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \ 17 | PrintInteractionLog(ELogVerbosity::Log, FormattedMessage, FLinearColor(0.0f, 1.0f, 0.0f), 5.0f); \ 18 | } 19 | 20 | #define LOG_WARNING(Format, ...) \ 21 | { \ 22 | FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \ 23 | PrintInteractionLog(ELogVerbosity::Warning, FormattedMessage, FLinearColor(1.0f, 1.0f, 0.0f), 10.0f); \ 24 | } 25 | 26 | #define LOG_ERROR(Format, ...) \ 27 | { \ 28 | FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \ 29 | PrintInteractionLog(ELogVerbosity::Error, FormattedMessage, FLinearColor(1.0f, 0.0f, 0.0f), 15.0f); \ 30 | } -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Helpers/ActorInteractionPluginSettings.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "MounteaInteractionGeneralDataTypes.h" 7 | #include "Engine/DeveloperSettings.h" 8 | 9 | #include "ActorInteractionPluginSettings.generated.h" 10 | 11 | class UMounteaInteractionSettingsConfig; 12 | class UInputMappingContext; 13 | class UDataTable; 14 | class UMaterialInterface; 15 | class UUserWidget; 16 | 17 | /** 18 | * Mountea Interaction System global settings. 19 | */ 20 | UCLASS(config = MounteaSettings, defaultconfig, meta = (DisplayName = "Mountea Interaction System Settings")) 21 | class ACTORINTERACTIONPLUGIN_API UActorInteractionPluginSettings : public UDeveloperSettings 22 | { 23 | 24 | GENERATED_BODY() 25 | 26 | UActorInteractionPluginSettings(); 27 | 28 | public: 29 | 30 | UPROPERTY(config, BlueprintReadOnly, EditAnywhere, Category = "Interactor") 31 | TSoftObjectPtr DefaultInteractionSystemConfig; 32 | 33 | /** Defines whether in-editor debug is enabled. */ 34 | UPROPERTY(config, BlueprintReadOnly, EditAnywhere, Category="Editor") 35 | uint8 bEditorDebugEnabled : 1; 36 | 37 | /** 38 | * Defines logging level that is allowed to be shown. 39 | * Affects on-screen messages. 40 | */ 41 | UPROPERTY(config, EditDefaultsOnly, Category = "Logging", meta=(Bitmask, BitmaskEnum="/Script/ActorInteractionPlugin.EMounteaInteractionLoggingVerbosity")) 42 | uint8 LogVerbosity; 43 | 44 | /** Defines how often is the Interaction widget updated per second.*/ 45 | UPROPERTY(config, BlueprintReadOnly, EditAnywhere, Category = "Widgets", meta=(Units="s", UIMin=0.001, ClampMin=0.001)) 46 | float WidgetUpdateFrequency = 0.05f; 47 | 48 | /** Defines default Interactable Widget class.*/ 49 | UPROPERTY(config, BlueprintReadOnly, EditAnywhere, Category = "Widgets", meta=(AllowedClasses="/Script/UMG.UserWidget", MustImplement="/Script/ActorInteractionPlugin.ActorInteractionWidget")) 50 | TSoftClassPtr InteractableDefaultWidgetClass; 51 | 52 | /** Defines default DataTable which contains Interactable data values.*/ 53 | UPROPERTY(config, BlueprintReadOnly, EditAnywhere, Category = "Interaction Data", meta=(AllowedClasses = "/Script/Engine.DataTable")) 54 | TSoftObjectPtr InteractableDefaultDataTable; 55 | 56 | /** Defines default Interaction Mapping for Mountea Interaction System. */ 57 | UPROPERTY(config, BlueprintReadOnly, EditAnywhere, Category = "Input") 58 | TSoftObjectPtr InteractionInputMapping; 59 | 60 | /** Defines default Interaction Commands. Serves purpose of containing default commands. */ 61 | TSet InteractionWidgetCommands; 62 | 63 | #if WITH_EDITOR 64 | virtual FText GetSectionText() const override 65 | { 66 | return NSLOCTEXT("ActorInteractionPlugin", "MounteaSettingsDescription", "Mountea Interaction System"); 67 | } 68 | 69 | virtual FText GetSectionDescription() const override 70 | { 71 | return NSLOCTEXT("ActorInteractionPlugin", "MounteaSettingsDescription", "Default values for Mountea Plugins."); 72 | } 73 | 74 | virtual FName GetContainerName() const override 75 | { 76 | return "Project"; 77 | } 78 | #endif 79 | 80 | public: 81 | 82 | bool IsEditorDebugEnabled() const 83 | { return bEditorDebugEnabled; }; 84 | 85 | float GetWidgetUpdateFrequency() const 86 | { return WidgetUpdateFrequency; } 87 | 88 | TSoftObjectPtr GetInteractableDefaultDataTable() const 89 | { return InteractableDefaultDataTable; }; 90 | 91 | TSoftClassPtr GetInteractableDefaultWidgetClass() const; 92 | 93 | UMaterialInterface* GetDefaultHighlightMaterial() const; 94 | 95 | UInputMappingContext* GetDefaultInputMappingContext() const; 96 | 97 | EMounteaInteractionLoggingVerbosity GetAllowedLoggVerbosity() const; 98 | }; 99 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Helpers/MounteaInteractionGeneralDataTypes.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Pavlicek 2023 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "MounteaInteractionGeneralDataTypes.generated.h" 7 | 8 | UENUM(BlueprintType, meta = (Bitflags, UseEnumValuesAsMaskValuesInEditor = "true")) 9 | enum class EMounteaInteractionLoggingVerbosity : uint8 10 | { 11 | None = 0 UMETA(hidden), 12 | // Toggle Info On/Off. Info level provides most basic information. Color is green. 13 | Info = 1 << 0, 14 | // Toggle Warning On/Off. Warning level provides information about issues that might affect interaction, but are not blockers. 15 | Warning = 1 << 1, 16 | // Toggle Error On/Off. Error level provides information about issues that will block interaction. 17 | Error = 1 << 2 18 | }; 19 | ENUM_CLASS_FLAGS(EMounteaInteractionLoggingVerbosity) 20 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Helpers/MounteaInteractionHelperEvents.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "UObject/Object.h" 7 | #include "MounteaInteractionHelperEvents.generated.h" 8 | 9 | DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FInputActionConsumed, UInputAction*, ConsumedInput); 10 | 11 | UCLASS() 12 | class UMounteaInteractionHelperEvents : public UObject 13 | { 14 | GENERATED_BODY() 15 | 16 | public: 17 | 18 | }; 19 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Helpers/MounteaInteractionSettingsConfig.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "InteractionHelpers.h" 7 | #include "Engine/DataAsset.h" 8 | #include "InputCoreTypes.h" 9 | #include "MounteaInteractionSettingsConfig.generated.h" 10 | 11 | enum class ECommonInputType : uint8; 12 | struct FKey; 13 | 14 | /** 15 | * Represents a pairing of a key texture with a supported device type and platforms. 16 | */ 17 | USTRUCT(BlueprintType) 18 | struct FKeyOnDevicePair 19 | { 20 | GENERATED_BODY() 21 | 22 | /** The texture to display for the key. */ 23 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Input") 24 | TSoftObjectPtr KeyTexture; 25 | 26 | /** The type of device that supports this key. */ 27 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Input") 28 | ECommonInputType SupportedDeviceType; 29 | 30 | /** The platforms that support this key. */ 31 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Input") 32 | TArray SupportedPlatforms; 33 | 34 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Input") 35 | TArray BlacklistedDeviceIDs; 36 | 37 | FKeyOnDevicePair(); 38 | 39 | FKeyOnDevicePair(const TSoftObjectPtr& InKeyTexture, ECommonInputType InSupportedDeviceType, const TArray& InSupportedPlatforms) 40 | : KeyTexture(InKeyTexture), SupportedDeviceType(InSupportedDeviceType), SupportedPlatforms(InSupportedPlatforms) 41 | {} 42 | 43 | bool operator==(const FKeyOnDevicePair& Other) const 44 | { 45 | return 46 | SupportedDeviceType == Other.SupportedDeviceType && 47 | SupportedPlatforms == Other.SupportedPlatforms; 48 | } 49 | 50 | bool operator==(const TPair& InputPair) const 51 | { 52 | const ECommonInputType& InputType = InputPair.Key; 53 | const FString& Platform = InputPair.Value; 54 | 55 | return SupportedDeviceType == InputType && SupportedPlatforms.Contains(Platform); 56 | } 57 | 58 | bool operator!=(const FKeyOnDevicePair& Other) const 59 | { 60 | return !(*this == Other); 61 | } 62 | }; 63 | 64 | /** 65 | * Represents a collection of key-device pairs. 66 | */ 67 | USTRUCT(BlueprintType) 68 | struct FKeyOnDevice 69 | { 70 | GENERATED_BODY() 71 | 72 | /** The list of key-device pairs. */ 73 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Input", meta = (ForceInlineRow, TitleProperty="SupportedDeviceType")) 74 | TArray KeyPairs; 75 | 76 | FKeyOnDevice() {} 77 | 78 | FKeyOnDevice(const TArray& InKeyPairs) 79 | : KeyPairs(InKeyPairs) 80 | {} 81 | 82 | bool operator==(const FKeyOnDevice& Other) const 83 | { 84 | return KeyPairs == Other.KeyPairs; 85 | } 86 | 87 | bool operator!=(const FKeyOnDevice& Other) const 88 | { 89 | return !(*this == Other); 90 | } 91 | }; 92 | 93 | /** 94 | * 95 | */ 96 | UCLASS(ClassGroup=(Mountea), EditInlineNew, meta = (DisplayName = "Mountea Interaction System Settings Configuration"), autoexpandcategories=("Interactor","Interactable","Input")) 97 | class ACTORINTERACTIONPLUGIN_API UMounteaInteractionSettingsConfig : public UDataAsset 98 | { 99 | GENERATED_BODY() 100 | 101 | public: 102 | 103 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Interactor") 104 | FInteractorBaseSettings InteractorDefaultSettings; 105 | 106 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Interactable") 107 | FInteractableBaseSettings InteractableBaseSettings; 108 | 109 | UPROPERTY(BlueprintReadOnly, EditAnywhere, Category = "Input", meta=(ForceInlineRow)) 110 | TMap MappingKeys; 111 | }; 112 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Helpers/MounteaInteractionSystemBFL.h: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Morse (Pavlicek) 2024. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Kismet/BlueprintFunctionLibrary.h" 7 | #include "MounteaInteractionSystemBFL.generated.h" 8 | 9 | class UActorInteractionPluginSettings; 10 | enum class ECommonInputType : uint8; 11 | 12 | /** 13 | * 14 | */ 15 | UCLASS() 16 | class ACTORINTERACTIONPLUGIN_API UMounteaInteractionSystemBFL : public UBlueprintFunctionLibrary 17 | { 18 | GENERATED_BODY() 19 | 20 | public: 21 | /** 22 | * Finds a mesh component by tag within the specified actor. 23 | * 24 | * @param Tag The tag to search for. 25 | * @param Source The actor to search within. 26 | * @return The first mesh component found with the specified tag, or nullptr if none is found. 27 | */ 28 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 29 | static UMeshComponent* FindMeshByTag(const FName Tag, const AActor* Source); 30 | 31 | /** 32 | * Finds a mesh component by name within the specified actor. 33 | * 34 | * @param Name The name to search for. 35 | * @param Source The actor to search within. 36 | * @return The first mesh component found with the specified name, or nullptr if none is found. 37 | */ 38 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 39 | static UMeshComponent* FindMeshByName(const FName Name, const AActor* Source); 40 | 41 | /** 42 | * Finds a primitive component by tag within the specified actor. 43 | * 44 | * @param Tag The tag to search for. 45 | * @param Source The actor to search within. 46 | * @return The first primitive component found with the specified tag, or nullptr if none is found. 47 | */ 48 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 49 | static UPrimitiveComponent* FindPrimitiveByTag(const FName Tag, const AActor* Source); 50 | 51 | /** 52 | * Finds a primitive component by name within the specified actor. 53 | * 54 | * @param Name The name to search for. 55 | * @param Source The actor to search within. 56 | * @return The first primitive component found with the specified name, or nullptr if none is found. 57 | */ 58 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 59 | static UPrimitiveComponent* FindPrimitiveByName(const FName Name, const AActor* Source); 60 | 61 | /** 62 | * Retrieves the interaction system settings. 63 | * 64 | * @return The interaction system settings object. 65 | */ 66 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 67 | static UActorInteractionPluginSettings* GetInteractionSystemSettings(); 68 | 69 | /** 70 | * Determines if cosmetic events can be executed in the specified world context. 71 | * 72 | * @param WorldContext The world context to check. 73 | * @return True if cosmetic events can be executed, false otherwise. 74 | */ 75 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 76 | static bool CanExecuteCosmeticEvents(const UWorld* WorldContext); 77 | 78 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 79 | static FText ReplaceRegexInText(const FText& SourceText, const TMap& Replacements); 80 | 81 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 82 | static ULocalPlayer* FindLocalPlayer(AActor* ForActor); 83 | 84 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 85 | static bool IsGamePadConnected(); 86 | 87 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 88 | static ECommonInputType GetActiveInputType(class APlayerController* PlayerController); 89 | 90 | UFUNCTION(BlueprintCallable, BlueprintPure, Category="Mountea|Interaction|Helpers") 91 | static bool IsInputKeyPairSupported(class APlayerController* PlayerController, const FKey& InputKey, const FString& HardwareDeviceID, TSoftObjectPtr& FoundInputTexture); 92 | }; 93 | -------------------------------------------------------------------------------- /Source/ActorInteractionPlugin/Public/Interfaces/ActorInteractionWidget.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "UObject/Interface.h" 7 | #include "ActorInteractionWidget.generated.h" 8 | 9 | // This class does not need to be modified. 10 | UINTERFACE(BlueprintType, Blueprintable) 11 | class UActorInteractionWidget : public UInterface 12 | { 13 | GENERATED_BODY() 14 | }; 15 | 16 | class IActorInteractableInterface; 17 | 18 | /** 19 | * Interaction Widget Interface. 20 | * Implements basic Setters and Getters. 21 | * 22 | * This way every single Widget can be used as Interactable Widget. 23 | * Interface can be further extended in Blueprints. 24 | */ 25 | class ACTORINTERACTIONPLUGIN_API IActorInteractionWidget 26 | { 27 | GENERATED_BODY() 28 | 29 | public: 30 | 31 | /** 32 | * This function is called to execute a command on the interaction widget. 33 | * It can be used to send various commands and payloads to the interaction widget. 34 | * 35 | * @param Command The command to be executed on the interaction widget. 36 | * @param Payload The payload associated with the command, which can be any UObject. 37 | */ 38 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 39 | void InteractionWidgetCommand(const FString& Command, UObject* Payload); 40 | 41 | 42 | /** 43 | * This event should be called when you want to refresh UI data. 44 | */ 45 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 46 | void UpdateWidget(const TScriptInterface& InteractableInterface); 47 | 48 | /** 49 | * This event should be called when you want to Hide/Unhide the Widget. 50 | */ 51 | UFUNCTION(BlueprintCallable, BlueprintNativeEvent, Category="Mountea|InteractionWidget") 52 | void ToggleVisibility(); 53 | virtual void ToggleVisibility_Implementation() = 0; 54 | 55 | /** 56 | * Sets new Title Text. 57 | * @param NewTittle Title is usually Interactable Name. For example 'Treasure Chest'. 58 | */ 59 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 60 | void SetTitleText(const FString& NewTittle); 61 | /** 62 | * Returns Title Text. 63 | * Title is usually Interactable Name. For example 'Treasure Chest'. 64 | */ 65 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 66 | FString GetTitleText() const; 67 | 68 | /** 69 | * Sets new Action Text. 70 | * @param NewAction Action is usually what Interaction is supposed to happen. For example 'Hold' or 'Press'. 71 | */ 72 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 73 | void SetBodyText(const FString& NewAction); 74 | /** 75 | * Returns Action Text. 76 | * Action is usually what Interaction is supposed to happen. For example 'Hold' or 'Press'. 77 | */ 78 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 79 | FString GetBodyText() const; 80 | 81 | /** 82 | * Sets new Interaction Key from Text. 83 | * @param NewKey Platform dependant Key, if any is required. 84 | */ 85 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 86 | void SetKeyText(const FString& NewKey); 87 | /** 88 | * Returns Interaction Key as Text. 89 | * Interaction Key is platform dependant Key, if any is required. 90 | */ 91 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 92 | FString GetKeyText() const; 93 | 94 | /** 95 | * Sets progress to be visually displayed in UI. 96 | * UI should not be responsible for setting that progress itself! 97 | * @param NewProgress Value to be set as displayed Progress. 98 | */ 99 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 100 | void SetProgress(const float NewProgress); 101 | /** 102 | * Returns Interaction Progress. 103 | */ 104 | UFUNCTION(BlueprintCallable, BlueprintImplementableEvent, Category="Mountea|InteractionWidget") 105 | float GetProgress() const; 106 | }; 107 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/ActorInteractionPluginEditor.Build.cs: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | using System.IO; 4 | using UnrealBuildTool; 5 | 6 | public class ActorInteractionPluginEditor : ModuleRules 7 | { 8 | public ActorInteractionPluginEditor(ReadOnlyTargetRules Target) : base(Target) 9 | { 10 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 11 | 12 | PrecompileForTargets = PrecompileTargetsType.None; 13 | bPrecompile = false; 14 | bUsePrecompiled = false; 15 | 16 | PublicDependencyModuleNames.AddRange 17 | ( 18 | new string[] 19 | { 20 | "Core", 21 | "CoreUObject", 22 | 23 | "BlueprintGraph", 24 | 25 | "Engine", 26 | 27 | "KismetCompiler", 28 | "PropertyEditor", 29 | "UnrealEd", 30 | "Kismet" 31 | } 32 | ); 33 | 34 | PrivateDependencyModuleNames.AddRange 35 | ( 36 | new string[] 37 | { 38 | "ActorInteractionPlugin", 39 | "UnrealEd", 40 | "Projects", 41 | 42 | "Slate", 43 | "SlateCore", 44 | 45 | "AssetTools", 46 | 47 | "BlueprintGraph", 48 | "Kismet", 49 | 50 | "WebBrowser", 51 | "HTTP", 52 | "Json", 53 | "JsonUtilities", 54 | 55 | "EditorStyle", 56 | "DeveloperSettings", 57 | 58 | "MainFrame", 59 | "ToolMenus", 60 | "InputCore", 61 | 62 | "UMG", 63 | 64 | "GameplayTags", 65 | 66 | "WorkspaceMenuStructure" 67 | } 68 | ); 69 | 70 | 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/AssetActions/InteractableComponentAssetActions.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AssetTypeActions_Base.h" 7 | #include "Components/Interactable/ActorInteractableComponentBase.h" 8 | 9 | class FInteractableComponentAssetActions : public FAssetTypeActions_Base 10 | { 11 | public: 12 | virtual UClass* GetSupportedClass() const override { return UActorInteractableComponentBase::StaticClass(); }; 13 | virtual FText GetName() const override { return INVTEXT("Interactable Component"); }; 14 | virtual FColor GetTypeColor() const override { return FColor::Magenta; }; 15 | virtual uint32 GetCategories() override 16 | { 17 | if (FModuleManager::Get().IsModuleLoaded("AssetTools")) 18 | { 19 | return FAssetToolsModule::GetModule().Get().FindAdvancedAssetCategory(FName("MounteaInteraction")); 20 | } 21 | 22 | return EAssetTypeCategories::Misc; 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/AssetActions/InteractionSettingsConfig.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AssetTypeActions_Base.h" 7 | #include "Helpers/MounteaInteractionSettingsConfig.h" 8 | 9 | class FInteractionSettingsConfigAssetActions : public FAssetTypeActions_Base 10 | { 11 | public: 12 | virtual UClass* GetSupportedClass() const override { return UMounteaInteractionSettingsConfig::StaticClass(); }; 13 | virtual TArray& GetSubMenus() const override; 14 | virtual FText GetName() const override { return INVTEXT("Interaction Settings Config"); }; 15 | virtual FColor GetTypeColor() const override { return FColor::Cyan; }; 16 | virtual uint32 GetCategories() override 17 | { 18 | if (FModuleManager::Get().IsModuleLoaded("AssetTools")) 19 | { 20 | return FAssetToolsModule::GetModule().Get().FindAdvancedAssetCategory(FName("MounteaInteraction")); 21 | } 22 | 23 | return EAssetTypeCategories::Misc; 24 | }; 25 | }; 26 | 27 | inline TArray& FInteractionSettingsConfigAssetActions::GetSubMenus() const 28 | { 29 | static TArray AssetTypeActionSubMenu 30 | { 31 | FText::FromString("Configuration") 32 | }; 33 | return AssetTypeActionSubMenu; 34 | } 35 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/AssetActions/InteractorComponentAssetActions.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AssetTypeActions_Base.h" 7 | #include "Components/Interactor/ActorInteractorComponentBase.h" 8 | 9 | class FInteractorComponentAssetActions : public FAssetTypeActions_Base 10 | { 11 | public: 12 | virtual UClass* GetSupportedClass() const override { return UActorInteractorComponentBase::StaticClass(); }; 13 | virtual FText GetName() const override { return INVTEXT("Interactor Component"); }; 14 | virtual FColor GetTypeColor() const override { return FColor::Cyan; }; 15 | virtual uint32 GetCategories() override 16 | { 17 | if (FModuleManager::Get().IsModuleLoaded("AssetTools")) 18 | { 19 | return FAssetToolsModule::GetModule().Get().FindAdvancedAssetCategory(FName("MounteaInteraction")); 20 | } 21 | 22 | return EAssetTypeCategories::Misc; 23 | }; 24 | }; 25 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/DetailsPanel/MounteaInteractableBase_DetailsPanel.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024 2 | 3 | #include "MounteaInteractableBase_DetailsPanel.h" 4 | #include "DetailCategoryBuilder.h" 5 | #include "DetailLayoutBuilder.h" 6 | #include "DetailWidgetRow.h" 7 | #include "Components/Interactable/ActorInteractableComponentBase.h" 8 | #include "Widgets/Layout/SScaleBox.h" 9 | 10 | #define LOCTEXT_NAMESPACE "InteractableComponentsPanel" 11 | 12 | void MounteaInteractableBase_DetailsPanel::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) 13 | { 14 | TArray> ObjectsBeingCustomized; 15 | DetailBuilder.GetObjectsBeingCustomized(ObjectsBeingCustomized); 16 | 17 | // Only support one object being customized 18 | if (ObjectsBeingCustomized.Num() != 1) return; 19 | 20 | const TWeakObjectPtr weakComponent = Cast(ObjectsBeingCustomized[0].Get()); 21 | if (!weakComponent.IsValid()) return; 22 | 23 | EditingComponent = weakComponent.Get(); 24 | if (!EditingComponent) return; 25 | 26 | IDetailCategoryBuilder& ItrCategoryBuild = DetailBuilder.EditCategory(TEXT("MounteaInteraction"), FText::GetEmpty(), ECategoryPriority::Important); 27 | ItrCategoryBuild.AddCustomRow(LOCTEXT("InteractableComponentsPanel_Defaults", "Load Defaults"), false) 28 | .WholeRowWidget 29 | [ 30 | SNew(SBox) 31 | .HAlign(HAlign_Fill) 32 | [ 33 | SNew(SScaleBox) 34 | .HAlign(EHorizontalAlignment::HAlign_Fill) 35 | .Stretch(EStretch::ScaleToFit) 36 | [ 37 | SAssignNew(DefaultsButton, SButton) 38 | .HAlign(HAlign_Fill) 39 | .Text(LOCTEXT("InteractableComponentsPanel_Defaults_Text", "Load Defaults")) 40 | .ToolTipText(LOCTEXT("InteractableComponentsPanel_Defaults_Tooltip", "Overrides data with default values from Project Settings.\nProject Settings must be defined!")) 41 | .OnClicked(this, &MounteaInteractableBase_DetailsPanel::OnDefaultsClicked) 42 | .OnHovered(this, &MounteaInteractableBase_DetailsPanel::OnDefaultsHovered) 43 | .OnUnhovered(this, &MounteaInteractableBase_DetailsPanel::OnDefaultsHovered) 44 | 45 | ] 46 | ] 47 | ]; 48 | } 49 | 50 | FReply MounteaInteractableBase_DetailsPanel::OnDefaultsClicked() const 51 | { 52 | if (EditingComponent) 53 | { 54 | EditingComponent->SetDefaultValues(); 55 | 56 | if (SavedLayoutBuilder) SavedLayoutBuilder->ForceRefreshDetails(); 57 | 58 | return FReply::Handled(); 59 | } 60 | return FReply::Unhandled(); 61 | } 62 | 63 | void MounteaInteractableBase_DetailsPanel::OnDefaultsHovered() 64 | { 65 | 66 | } 67 | 68 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/DetailsPanel/MounteaInteractableBase_DetailsPanel.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024 2 | 3 | #pragma once 4 | 5 | #include "IDetailCustomization.h" 6 | 7 | class UActorInteractableComponentBase; 8 | 9 | class MounteaInteractableBase_DetailsPanel : public IDetailCustomization 10 | { 11 | typedef MounteaInteractableBase_DetailsPanel Self; 12 | 13 | public: 14 | // Makes a new instance of this detail layout class for a specific detail view requesting it 15 | static TSharedRef MakeInstance() { return MakeShared(); } 16 | 17 | // IDetailCustomization interface 18 | /** Called when details should be customized */ 19 | virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; 20 | 21 | FReply OnDefaultsClicked() const; 22 | void OnDefaultsHovered(); 23 | 24 | private: 25 | 26 | IDetailLayoutBuilder* SavedLayoutBuilder = nullptr; 27 | 28 | UActorInteractableComponentBase* EditingComponent = nullptr; 29 | 30 | TSharedPtr DefaultsButton; 31 | }; 32 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Factories/ActorInteractionClassViewerFilter.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "ClassViewerFilter.h" 6 | 7 | 8 | // Filter used in the class picker to only show non abstract children of class 9 | class FActorInteractionClassViewerFilter : public IClassViewerFilter 10 | { 11 | public: 12 | // All children of these classes will be included unless filtered out by another setting. 13 | TSet AllowedChildrenOfClasses; 14 | 15 | virtual bool IsClassAllowed(const FClassViewerInitializationOptions& InInitOptions, const UClass* InClass, TSharedRef InFilterFuncs) override 16 | { 17 | return !InClass->HasAnyClassFlags(DisallowedClassFlags) 18 | && InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InClass) != EFilterReturn::Failed; 19 | } 20 | 21 | virtual bool IsUnloadedClassAllowed(const FClassViewerInitializationOptions& InInitOptions, const TSharedRef InUnloadedClassData, TSharedRef< FClassViewerFilterFuncs > InFilterFuncs) override 22 | { 23 | return !InUnloadedClassData->HasAnyClassFlags(DisallowedClassFlags) 24 | && InFilterFuncs->IfInChildOfClassesSet(AllowedChildrenOfClasses, InUnloadedClassData) != EFilterReturn::Failed; 25 | } 26 | 27 | private: 28 | // Disallowed class flags. 29 | EClassFlags DisallowedClassFlags = CLASS_Deprecated; 30 | }; -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Factories/InteractableComponentAssetFactory.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | 4 | #include "InteractableComponentAssetFactory.h" 5 | 6 | #include "Utilities/ActorInteractionEditorUtilities.h" 7 | 8 | #include "Components/Interactable/ActorInteractableComponentBase.h" 9 | #include "Helpers/ActorInteractionFunctionLibrary.h" 10 | #include "Kismet2/KismetEditorUtilities.h" 11 | #include "Engine/DataTable.h" 12 | 13 | #define LOCTEXT_NAMESPACE "InteractableComponentAssetFactory" 14 | 15 | UInteractableComponentAssetFactory::UInteractableComponentAssetFactory(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) 16 | { 17 | bCreateNew = true; 18 | 19 | // true if the associated editor should be opened after creating a new object. 20 | bEditAfterNew = false; 21 | SupportedClass = UActorInteractableComponentBase::StaticClass(); 22 | 23 | // Default class 24 | ParentClass = SupportedClass; 25 | } 26 | 27 | bool UInteractableComponentAssetFactory::ConfigureProperties() 28 | { 29 | static const FText TitleText = FText::FromString(TEXT("Pick Parent Item Class for new Interactable Component Object")); 30 | ParentClass = nullptr; 31 | 32 | UClass* ChosenClass = nullptr; 33 | const bool bPressedOk = FActorInteractionEditorUtilities::PickChildrenOfClass(TitleText, ChosenClass, SupportedClass); 34 | if (bPressedOk) 35 | { 36 | ParentClass = ChosenClass; 37 | } 38 | 39 | return bPressedOk; 40 | } 41 | 42 | UObject* UInteractableComponentAssetFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) 43 | { 44 | // Something is not right! 45 | if (ParentClass == nullptr || !FKismetEditorUtilities::CanCreateBlueprintOfClass(ParentClass)) 46 | { 47 | FFormatNamedArguments Args; 48 | Args.Add(TEXT("ClassName"), ParentClass ? FText::FromString(ParentClass->GetName()) : NSLOCTEXT("UnrealEd", "Null", "(null)")); 49 | FMessageDialog::Open(EAppMsgType::Ok, FText::Format(NSLOCTEXT("UnrealEd", "CannotCreateBlueprintFromClass", "Cannot create a blueprint based on the class '{0}'."), Args)); 50 | return nullptr; 51 | } 52 | 53 | // Create new Blueprint 54 | return 55 | FKismetEditorUtilities::CreateBlueprint( 56 | ParentClass, 57 | InParent, 58 | Name, 59 | BPTYPE_Normal, 60 | UBlueprint::StaticClass(), 61 | UBlueprintGeneratedClass::StaticClass(), 62 | NAME_None 63 | ); 64 | } 65 | 66 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Factories/InteractableComponentAssetFactory.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Factories/Factory.h" 7 | #include "InteractableComponentAssetFactory.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class ACTORINTERACTIONPLUGINEDITOR_API UInteractableComponentAssetFactory : public UFactory 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | 19 | UInteractableComponentAssetFactory(const FObjectInitializer& ObjectInitializer); 20 | 21 | virtual bool ConfigureProperties() override; 22 | 23 | virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override; 24 | 25 | private: 26 | // Holds the template of the class we are building 27 | UPROPERTY() 28 | TSubclassOf ParentClass; 29 | }; 30 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Factories/InteractionSettingsConfigAssetFactory.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | 4 | #include "InteractionSettingsConfigAssetFactory.h" 5 | 6 | #include "Utilities/ActorInteractionEditorUtilities.h" 7 | 8 | #include "Helpers/MounteaInteractionSettingsConfig.h" 9 | #include "Kismet2/KismetEditorUtilities.h" 10 | 11 | #define LOCTEXT_NAMESPACE "ActorInteraction" 12 | 13 | UInteractionSettingsConfigAssetFactory::UInteractionSettingsConfigAssetFactory(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) 14 | { 15 | bCreateNew = true; 16 | 17 | // true if the associated editor should be opened after creating a new object. 18 | bEditAfterNew = false; 19 | SupportedClass = UMounteaInteractionSettingsConfig::StaticClass(); 20 | 21 | // Default class 22 | ParentClass = SupportedClass; 23 | } 24 | 25 | bool UInteractionSettingsConfigAssetFactory::ConfigureProperties() 26 | { 27 | static const FText TitleText = FText::FromString(TEXT("Pick Parent Item Class for new Interactor Component Object")); 28 | ParentClass = nullptr; 29 | 30 | UClass* ChosenClass = nullptr; 31 | const bool bPressedOk = FActorInteractionEditorUtilities::PickChildrenOfClass(TitleText, ChosenClass, SupportedClass); 32 | if (bPressedOk) 33 | { 34 | ParentClass = ChosenClass; 35 | } 36 | 37 | return bPressedOk; 38 | } 39 | 40 | UObject* UInteractionSettingsConfigAssetFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) 41 | { 42 | if (ParentClass == nullptr) 43 | ParentClass = UMounteaInteractionSettingsConfig::StaticClass(); 44 | 45 | // Something is not right! 46 | if (ParentClass == nullptr) 47 | { 48 | FFormatNamedArguments Args; 49 | Args.Add(TEXT("ClassName"), ParentClass ? FText::FromString(ParentClass->GetName()) : NSLOCTEXT("UnrealEd", "Null", "(null)")); 50 | FMessageDialog::Open(EAppMsgType::Ok, FText::Format(NSLOCTEXT("UnrealEd", "CannotCreateBlueprintFromClass", "Cannot create a asset based on the class '{0}'."), Args)); 51 | return nullptr; 52 | } 53 | 54 | return NewObject(InParent, ParentClass); 55 | } 56 | 57 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Factories/InteractionSettingsConfigAssetFactory.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Factories/Factory.h" 7 | #include "InteractionSettingsConfigAssetFactory.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class ACTORINTERACTIONPLUGINEDITOR_API UInteractionSettingsConfigAssetFactory : public UFactory 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | 19 | UInteractionSettingsConfigAssetFactory(const FObjectInitializer& ObjectInitializer); 20 | 21 | virtual bool ConfigureProperties() override; 22 | 23 | virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override; 24 | 25 | private: 26 | // Holds the template of the class we are building 27 | UPROPERTY() 28 | TSubclassOf ParentClass; 29 | }; 30 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Factories/InteractorComponentAssetFactory.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | 4 | #include "InteractorComponentAssetFactory.h" 5 | 6 | #include "Utilities/ActorInteractionEditorUtilities.h" 7 | 8 | #include "Components/Interactor/ActorInteractorComponentBase.h" 9 | #include "Kismet2/KismetEditorUtilities.h" 10 | 11 | #define LOCTEXT_NAMESPACE "ActorInteraction" 12 | 13 | UInteractorComponentAssetFactory::UInteractorComponentAssetFactory(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer) 14 | { 15 | bCreateNew = true; 16 | 17 | // true if the associated editor should be opened after creating a new object. 18 | bEditAfterNew = false; 19 | SupportedClass = UActorInteractorComponentBase::StaticClass(); 20 | 21 | // Default class 22 | ParentClass = SupportedClass; 23 | } 24 | 25 | bool UInteractorComponentAssetFactory::ConfigureProperties() 26 | { 27 | static const FText TitleText = FText::FromString(TEXT("Pick Parent Item Class for new Interactor Component Object")); 28 | ParentClass = nullptr; 29 | 30 | UClass* ChosenClass = nullptr; 31 | const bool bPressedOk = FActorInteractionEditorUtilities::PickChildrenOfClass(TitleText, ChosenClass, SupportedClass); 32 | if (bPressedOk) 33 | { 34 | ParentClass = ChosenClass; 35 | } 36 | 37 | return bPressedOk; 38 | } 39 | 40 | UObject* UInteractorComponentAssetFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) 41 | { 42 | // Something is not right! 43 | if (ParentClass == nullptr || !FKismetEditorUtilities::CanCreateBlueprintOfClass(ParentClass)) 44 | { 45 | FFormatNamedArguments Args; 46 | Args.Add(TEXT("ClassName"), ParentClass ? FText::FromString(ParentClass->GetName()) : NSLOCTEXT("UnrealEd", "Null", "(null)")); 47 | FMessageDialog::Open(EAppMsgType::Ok, FText::Format(NSLOCTEXT("UnrealEd", "CannotCreateBlueprintFromClass", "Cannot create a blueprint based on the class '{0}'."), Args)); 48 | return nullptr; 49 | } 50 | 51 | // Create new Blueprint 52 | return FKismetEditorUtilities::CreateBlueprint( 53 | ParentClass, 54 | InParent, 55 | Name, 56 | BPTYPE_Normal, 57 | UBlueprint::StaticClass(), 58 | UBlueprintGeneratedClass::StaticClass(), 59 | NAME_None 60 | ); 61 | } 62 | 63 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Factories/InteractorComponentAssetFactory.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Factories/Factory.h" 7 | #include "InteractorComponentAssetFactory.generated.h" 8 | 9 | /** 10 | * 11 | */ 12 | UCLASS() 13 | class ACTORINTERACTIONPLUGINEDITOR_API UInteractorComponentAssetFactory : public UFactory 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | 19 | UInteractorComponentAssetFactory(const FObjectInitializer& ObjectInitializer); 20 | 21 | virtual bool ConfigureProperties() override; 22 | 23 | virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override; 24 | 25 | private: 26 | // Holds the template of the class we are building 27 | UPROPERTY() 28 | TSubclassOf ParentClass; 29 | }; 30 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPCommands.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "AIntPCommands.h" 5 | 6 | #define LOCTEXT_NAMESPACE "ActorInteractionPluginEditorModule" 7 | 8 | void FAIntPCommands::RegisterCommands() 9 | { 10 | UI_COMMAND(PluginAction, "Support", "Opens Mountea Framework Support channel", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control|EModifierKey::Shift|EModifierKey::Alt, EKeys::X)); 11 | } 12 | 13 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPCommands.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "AIntPHelpStyle.h" 7 | 8 | 9 | class FAIntPCommands : public TCommands 10 | { 11 | public: 12 | 13 | FAIntPCommands() 14 | : TCommands(TEXT("AIntPSupport"), NSLOCTEXT("Contexts", "Support", "ActorInteraction Plugin"), NAME_None, FAIntPHelpStyle::GetStyleSetName()) 15 | { 16 | } 17 | 18 | // TCommands<> interface 19 | virtual void RegisterCommands() override; 20 | 21 | public: 22 | 23 | TSharedPtr< FUICommandInfo > PluginAction; 24 | }; 25 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | 4 | #include "AIntPHelpStyle.h" 5 | #include "Framework/Application/SlateApplication.h" 6 | #include "Styling/SlateStyleRegistry.h" 7 | #include "Slate/SlateGameResources.h" 8 | #include "Interfaces/IPluginManager.h" 9 | 10 | TSharedPtr< FSlateStyleSet > FAIntPHelpStyle::StyleInstance = nullptr; 11 | 12 | void FAIntPHelpStyle::Initialize() 13 | { 14 | if (!StyleInstance.IsValid()) 15 | { 16 | StyleInstance = Create(); 17 | FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance); 18 | } 19 | } 20 | 21 | void FAIntPHelpStyle::Shutdown() 22 | { 23 | FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); 24 | ensure(StyleInstance.IsUnique()); 25 | StyleInstance.Reset(); 26 | } 27 | 28 | void FAIntPHelpStyle::ReloadTextures() 29 | { 30 | if (FSlateApplication::IsInitialized()) 31 | { 32 | FSlateApplication::Get().GetRenderer()->ReloadTextureResources(); 33 | } 34 | } 35 | 36 | const ISlateStyle& FAIntPHelpStyle::Get() 37 | { 38 | return *StyleInstance; 39 | } 40 | 41 | FName FAIntPHelpStyle::GetStyleSetName() 42 | { 43 | static FName StyleSetName(TEXT("AIntPHelpStyle")); 44 | return StyleSetName; 45 | } 46 | 47 | #define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 48 | #define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 49 | #define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 50 | #define TTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".ttf") ), __VA_ARGS__ ) 51 | #define OTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".otf") ), __VA_ARGS__ ) 52 | 53 | const FVector2D Icon12x12(12.0f, 12.0f); 54 | const FVector2D Icon16x16(16.0f, 16.0f); 55 | const FVector2D Icon20x20(20.0f, 20.0f); 56 | const FVector2D Icon40x40(40.0f, 40.0f); 57 | 58 | TSharedRef FAIntPHelpStyle::Create() 59 | { 60 | TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("AIntPHelpStyle")); 61 | Style->SetContentRoot(IPluginManager::Get().FindPlugin("ActorInteractionPlugin")->GetBaseDir() / TEXT("Resources")); 62 | 63 | Style->Set("AIntPStyleSet.Interaction", new IMAGE_BRUSH(TEXT("InteractorIcon"), Icon40x40)); 64 | Style->Set("AIntPStyleSet.Launcher", new IMAGE_BRUSH(TEXT("MPLIcon"), Icon40x40)); 65 | 66 | Style->Set("AIntPStyleSet.PluginAction", new IMAGE_BRUSH(TEXT("Mountea_Logo"), Icon40x40)); 67 | Style->Set("AIntPStyleSet.PluginAction.Small", new IMAGE_BRUSH(TEXT("Help_Icon"), Icon20x20)); 68 | 69 | Style->Set("AIntPStyleSet.Help.Small", new IMAGE_BRUSH(TEXT("Help_Icon"), Icon16x16)); 70 | Style->Set("AIntPStyleSet.Help", new IMAGE_BRUSH(TEXT("Help_Icon"), Icon40x40)); 71 | 72 | Style->Set("AIntPStyleSet.Dialoguer.Small", new IMAGE_BRUSH(TEXT("Dialoguer_Icon"), Icon16x16)); 73 | Style->Set("AIntPStyleSet.Dialoguer", new IMAGE_BRUSH(TEXT("Dialoguer_Icon"), Icon40x40)); 74 | 75 | Style->Set("AIntPStyleSet.Wiki.Small", new IMAGE_BRUSH(TEXT("Wiki_Icon"), Icon16x16)); 76 | Style->Set("AIntPStyleSet.Wiki", new IMAGE_BRUSH(TEXT("Wiki_Icon"), Icon40x40)); 77 | 78 | Style->Set("AIntPStyleSet.Settings.Small", new IMAGE_BRUSH(TEXT("settings_icon"), Icon16x16)); 79 | Style->Set("AIntPStyleSet.Settings", new IMAGE_BRUSH(TEXT("settings_icon"), Icon40x40)); 80 | 81 | Style->Set("AIntPStyleSet.Youtube.Small", new IMAGE_BRUSH(TEXT("youtube_icon"), Icon16x16)); 82 | Style->Set("AIntPStyleSet.Youtube", new IMAGE_BRUSH(TEXT("youtube_icon"), Icon40x40)); 83 | 84 | Style->Set("AIntPStyleSet.Icon.Close", new IMAGE_BRUSH(TEXT("CloseIcon"), Icon16x16)); 85 | Style->Set("AIntPStyleSet.Icon.SupportDiscord", new IMAGE_BRUSH(TEXT("Help_Icon"), Icon16x16)); 86 | Style->Set("AIntPStyleSet.Icon.HeartIcon", new IMAGE_BRUSH(TEXT("HeartIcon"), Icon16x16)); 87 | Style->Set("AIntPStyleSet.Icon.UBIcon", new IMAGE_BRUSH(TEXT("UnrealBucketIcon"), Icon16x16)); 88 | Style->Set("AIntPStyleSet.Icon.MoneyIcon", new IMAGE_BRUSH(TEXT("MoneyIcon"), Icon16x16)); 89 | 90 | Style->Set("AIntPStyleSet.Tutorial", new IMAGE_BRUSH(TEXT("tutorialPage_icon"), Icon40x40)); 91 | return Style; 92 | } 93 | 94 | #undef IMAGE_BRUSH 95 | #undef BOX_BRUSH 96 | #undef BORDER_BRUSH 97 | #undef TTF_FONT 98 | #undef OTF_FONT -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Styling/SlateStyle.h" 7 | 8 | class FAIntPHelpStyle : public FAppStyle 9 | { 10 | public: 11 | 12 | static void Initialize(); 13 | 14 | static void Shutdown(); 15 | 16 | /** reloads textures used by slate renderer */ 17 | static void ReloadTextures(); 18 | 19 | /** @return The Slate style set for the Actor Interaction Plugin Help Button */ 20 | static const ISlateStyle& Get(); 21 | 22 | static const FSlateBrush* GetBrush(FName PropertyName) 23 | { 24 | const auto& Style = Get(); 25 | return Style.GetBrush(PropertyName); 26 | } 27 | 28 | static FName GetStyleSetName(); 29 | 30 | private: 31 | 32 | static TSharedRef< class FSlateStyleSet > Create(); 33 | 34 | private: 35 | 36 | static TSharedPtr< class FSlateStyleSet > StyleInstance; 37 | }; 38 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/HelpButton/InteractionSystemTutorialPage.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse 2024 2 | 3 | #include "InteractionSystemTutorialPage.h" 4 | 5 | #include "ContentBrowserModule.h" 6 | #include "IContentBrowserSingleton.h" 7 | #include "Widgets/Text/SRichTextBlock.h" 8 | #include "Widgets/Layout/SScrollBox.h" 9 | #include "Widgets/Layout/SBorder.h" 10 | #include "Widgets/Images/SImage.h" 11 | #include "Widgets/Layout/SBox.h" 12 | #include "Modules/ModuleManager.h" 13 | #include "ISettingsModule.h" 14 | 15 | void OpenSettingsPage(const FString& SettingsCategory) 16 | { 17 | ISettingsModule& SettingsModule = FModuleManager::LoadModuleChecked("Settings"); 18 | 19 | if (SettingsCategory == "Mountea") 20 | { 21 | SettingsModule.ShowViewer("Project", TEXT("Mountea Framework"), TEXT("Mountea Interaction System")); 22 | } 23 | else if (SettingsCategory == "Collision") 24 | { 25 | SettingsModule.ShowViewer("Project", TEXT("Engine"), TEXT("Collision")); 26 | } 27 | } 28 | 29 | void OpenContentBrowserFolder(const FString& FolderName) 30 | { 31 | FString PluginContentPath = TEXT("/ActorInteractionPlugin/") + FolderName; 32 | 33 | FContentBrowserModule& ContentBrowserModule = FModuleManager::LoadModuleChecked("ContentBrowser"); 34 | ContentBrowserModule.Get().SyncBrowserToFolders({ FolderName }); 35 | } 36 | 37 | void SInteractionSystemTutorialPage::Construct(const FArguments& InArgs) 38 | { 39 | FString arrowEmoji = TEXT("➡"); 40 | FString bookEmoji = TEXT("📖"); 41 | FString sparkleEmoji = TEXT("✨"); 42 | FString folderEmoji = TEXT("📂"); 43 | 44 | FString TitleMessage = FString(R"(Before You Start)"); 45 | 46 | FString IntroMessage = FString(R"( 47 | Before you start creating any super complex interactions, there are a few steps that must be done. 48 | In order to make everything work, you should set up default values and collision channels. 49 | So let's start with those annoying configurations before so we can focus on interactions later. 50 | )"); 51 | 52 | FString CollisionMessage = FString(R"(Collision Channels 53 | 54 | Interaction System can simply work out of the box with collision channels Engine contains by default, but it is much safer to use custom ones. 55 | This way you also have much finer control over your interactable objects. 56 | 57 | )") + arrowEmoji + FString(R"( Open Project Settings and open Collision category. 58 | Here you need to create collision channels for your needs. 59 | 60 | )") + sparkleEmoji + FString(R"( You can quickly open the settings here: Open Collision Settings 61 | )") + bookEmoji + FString(R"( Detailed guide here: Collision Channels Setup 62 | )"); 63 | 64 | FString InteractionMessage = FString(R"(Interaction Defaults 65 | 66 | )") + arrowEmoji + FString(R"( Open Project Settings and open Mountea Interaction System category. 67 | Default Interaction System Config must not be empty! 68 | 69 | )") + sparkleEmoji + FString(R"( You can quickly open the settings here: Open Mountea Interaction System Settings 70 | )") + bookEmoji + FString(R"( Detailed guide on Wiki page: Interaction Defaults Setup 71 | )") + folderEmoji + FString(R"( Default Config File is located here: Open Default Config Folder 72 | )"); 73 | 74 | FString ExampleFolderMessage = FString(R"( 75 | Example Content 76 | 77 | The Mountea Interaction System includes example assets to help you get started. 78 | )") + folderEmoji + FString(R"( Open the example assets folder: Open Example Folder 79 | )"); 80 | 81 | ChildSlot 82 | [ 83 | SNew(SBorder) 84 | .Padding(10) 85 | [ 86 | SNew(SScrollBox) 87 | 88 | // Title 89 | + SScrollBox::Slot() 90 | .Padding(10) 91 | [ 92 | SNew(SRichTextBlock) 93 | .Text(FText::FromString(TitleMessage)) 94 | .DecoratorStyleSet(&FCoreStyle::Get()) 95 | .AutoWrapText(true) 96 | + SRichTextBlock::HyperlinkDecorator(TEXT("browser"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 97 | { 98 | const FString* URL = Metadata.Find(TEXT("href")); 99 | if (URL) { FPlatformProcess::LaunchURL(**URL, nullptr, nullptr); } 100 | })) 101 | + SRichTextBlock::HyperlinkDecorator(TEXT("settings"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 102 | { 103 | const FString* Category = Metadata.Find(TEXT("href")); 104 | if (Category) { OpenSettingsPage(*Category); } 105 | })) 106 | ] 107 | 108 | // Intro 109 | + SScrollBox::Slot() 110 | .Padding(10) 111 | [ 112 | SNew(SRichTextBlock) 113 | .Text(FText::FromString(IntroMessage)) 114 | .DecoratorStyleSet(&FCoreStyle::Get()) 115 | .AutoWrapText(true) 116 | ] 117 | 118 | // Image Divider 119 | + SScrollBox::Slot() 120 | .Padding(FMargin(0, 5, 0, 5)) 121 | [ 122 | SNew(SBox) 123 | .HeightOverride(2) 124 | [ 125 | SNew(SImage) 126 | .Image(FCoreStyle::Get().GetBrush("WhiteBrush")) 127 | .ColorAndOpacity(FLinearColor(1, 1, 1, 0.3)) 128 | ] 129 | ] 130 | 131 | // Collision Channels 132 | + SScrollBox::Slot() 133 | .Padding(10) 134 | [ 135 | SNew(SRichTextBlock) 136 | .Text(FText::FromString(CollisionMessage)) 137 | .DecoratorStyleSet(&FCoreStyle::Get()) 138 | .AutoWrapText(true) 139 | + SRichTextBlock::HyperlinkDecorator(TEXT("browser"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 140 | { 141 | const FString* URL = Metadata.Find(TEXT("href")); 142 | if (URL) { FPlatformProcess::LaunchURL(**URL, nullptr, nullptr); } 143 | })) 144 | + SRichTextBlock::HyperlinkDecorator(TEXT("settings"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 145 | { 146 | const FString* Category = Metadata.Find(TEXT("href")); 147 | if (Category) { OpenSettingsPage(*Category); } 148 | })) 149 | ] 150 | 151 | // Image Divider 152 | + SScrollBox::Slot() 153 | .Padding(FMargin(0, 5, 0, 5)) 154 | [ 155 | SNew(SBox) 156 | .HeightOverride(2) 157 | [ 158 | SNew(SImage) 159 | .Image(FCoreStyle::Get().GetBrush("WhiteBrush")) 160 | .ColorAndOpacity(FLinearColor(1, 1, 1, 0.3)) 161 | ] 162 | ] 163 | 164 | // Interaction Defaults 165 | + SScrollBox::Slot() 166 | .Padding(10) 167 | [ 168 | SNew(SRichTextBlock) 169 | .Text(FText::FromString(InteractionMessage)) 170 | .DecoratorStyleSet(&FCoreStyle::Get()) 171 | .AutoWrapText(true) 172 | + SRichTextBlock::HyperlinkDecorator(TEXT("browser"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 173 | { 174 | const FString* URL = Metadata.Find(TEXT("href")); 175 | if (URL) { FPlatformProcess::LaunchURL(**URL, nullptr, nullptr); } 176 | })) 177 | + SRichTextBlock::HyperlinkDecorator(TEXT("settings"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 178 | { 179 | const FString* Category = Metadata.Find(TEXT("href")); 180 | if (Category) { OpenSettingsPage(*Category); } 181 | })) 182 | + SRichTextBlock::HyperlinkDecorator(TEXT("folder"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 183 | { 184 | const FString* FolderName = Metadata.Find(TEXT("href")); 185 | if (FolderName) 186 | { 187 | OpenContentBrowserFolder(*FolderName); 188 | } 189 | })) 190 | ] 191 | 192 | // Image Divider 193 | + SScrollBox::Slot() 194 | .Padding(FMargin(0, 5, 0, 5)) 195 | [ 196 | SNew(SBox) 197 | .HeightOverride(2) 198 | [ 199 | SNew(SImage) 200 | .Image(FCoreStyle::Get().GetBrush("WhiteBrush")) 201 | .ColorAndOpacity(FLinearColor(1, 1, 1, 0.3)) 202 | ] 203 | ] 204 | 205 | // Example Folder 206 | + SScrollBox::Slot() 207 | .Padding(10) 208 | [ 209 | SNew(SRichTextBlock) 210 | .Text(FText::FromString(ExampleFolderMessage)) 211 | .DecoratorStyleSet(&FCoreStyle::Get()) 212 | .AutoWrapText(true) 213 | + SRichTextBlock::HyperlinkDecorator(TEXT("browser"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 214 | { 215 | const FString* URL = Metadata.Find(TEXT("href")); 216 | if (URL) { FPlatformProcess::LaunchURL(**URL, nullptr, nullptr); } 217 | })) 218 | + SRichTextBlock::HyperlinkDecorator(TEXT("folder"), FSlateHyperlinkRun::FOnClick::CreateLambda([](const FSlateHyperlinkRun::FMetadata& Metadata) 219 | { 220 | const FString* FolderName = Metadata.Find(TEXT("href")); 221 | if (FolderName) 222 | { 223 | OpenContentBrowserFolder(*FolderName); 224 | } 225 | })) 226 | ] 227 | ] 228 | ]; 229 | } 230 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/HelpButton/InteractionSystemTutorialPage.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse 2024 2 | 3 | #pragma once 4 | 5 | #include "Widgets/SCompoundWidget.h" 6 | 7 | class SInteractionSystemTutorialPage : public SCompoundWidget 8 | { 9 | public: 10 | SLATE_BEGIN_ARGS(SInteractionSystemTutorialPage) {} 11 | SLATE_END_ARGS() 12 | 13 | void Construct(const FArguments& InArgs); 14 | 15 | private: 16 | FText GetTutorialText() const; 17 | }; 18 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Helpers/MounteaInteractionSystemEditorLog.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Pavlicek 2022. All Rights Reserved. 2 | 3 | #include "Helpers/MounteaInteractionSystemEditorLog.h" 4 | 5 | // Log category definition 6 | DEFINE_LOG_CATEGORY(LogActorInteractionEditor); 7 | 8 | void PrintInteractionEditorLog(const FString& Message, const FLinearColor Color, const float Duration) 9 | { 10 | if (GEditor) 11 | { 12 | GEditor->AddOnScreenDebugMessage(0, Duration, Color.ToFColor(true), Message); 13 | } 14 | } -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Helpers/MounteaInteractionSystemEditorLog.h: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Pavlicek 2022. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | // Log category definition 8 | ACTORINTERACTIONPLUGINEDITOR_API DECLARE_LOG_CATEGORY_EXTERN(LogActorInteractionEditor, Display, All); 9 | 10 | // Forward declaration of the logging function 11 | void PrintInteractionEditorLog(const FString& Message, const FLinearColor Color, const float Duration); 12 | 13 | // Logging macro definitions 14 | #define EDITOR_LOG_INFO(Format, ...) \ 15 | { \ 16 | FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \ 17 | UE_LOG(LogActorInteractionEditor, Log, TEXT("%s"), *FormattedMessage); \ 18 | PrintInteractionEditorLog(FormattedMessage, FLinearColor(0.0f, 1.0f, 0.0f), 5.0f); \ 19 | } 20 | 21 | #define EDITOR_LOG_WARNING(Format, ...) \ 22 | { \ 23 | FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \ 24 | UE_LOG(LogActorInteractionEditor, Warning, TEXT("%s"), *FormattedMessage); \ 25 | PrintInteractionEditorLog(FormattedMessage, FLinearColor(1.0f, 1.0f, 0.0f), 10.0f); \ 26 | } 27 | 28 | #define EDITOR_LOG_ERROR(Format, ...) \ 29 | { \ 30 | FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \ 31 | UE_LOG(LogActorInteractionEditor, Error, TEXT("%s"), *FormattedMessage); \ 32 | PrintInteractionEditorLog(FormattedMessage, FLinearColor(1.0f, 0.0f, 0.0f), 15.0f); \ 33 | } -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Popup/AIntPPopup.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024 2 | 3 | #pragma once 4 | #include "Framework/Text/SlateHyperlinkRun.h" 5 | 6 | namespace MounteaInteractionSystemPopup 7 | { 8 | struct FPluginVersion 9 | { 10 | FString PluginVersion; 11 | FString PluginVersionName; 12 | 13 | FPluginVersion(const FString& A, const FString& B) : PluginVersion(A), PluginVersionName(B) {}; 14 | }; 15 | } 16 | 17 | class AIntPPopup 18 | { 19 | public: 20 | static void Register(const FString& Changelog); 21 | static void Open(const FString& Changelog); 22 | static void OnBrowserLinkClicked(const FSlateHyperlinkRun::FMetadata& Metadata); 23 | 24 | static void FormatChangelog(FString& InChangelog); 25 | static void FormatTextWithTags(FString& SourceText, const FString& StartMarker, const FString& EndMarker, const FString& StartTag, const FString& EndTag); 26 | 27 | static MounteaInteractionSystemPopup::FPluginVersion GetPluginVersion(); 28 | }; 29 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Popup/AIntPPopupConfig.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024 2 | 3 | #pragma once 4 | 5 | #include "Engine/DeveloperSettings.h" 6 | #include "AIntPPopupConfig.generated.h" 7 | 8 | UCLASS(config = EditorPerProjectUserSettings) 9 | class UAIntPPopupConfig : public UDeveloperSettings 10 | { 11 | GENERATED_BODY() 12 | 13 | public: 14 | UAIntPPopupConfig() 15 | { 16 | } 17 | 18 | UPROPERTY(config) 19 | FString PluginVersionUpdate = ""; 20 | 21 | }; 22 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Settings/MounteaInteractionEditorSettings.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024 2 | 3 | 4 | #include "MounteaInteractionEditorSettings.h" 5 | 6 | UMounteaInteractionEditorSettings::UMounteaInteractionEditorSettings() : bAllowAutoGameplayTagsCheck(true) 7 | { 8 | CategoryName = TEXT("Mountea Framework"); 9 | SectionName = TEXT("Mountea Interaction System (Editor)"); 10 | } 11 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Settings/MounteaInteractionEditorSettings.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2024 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Engine/DeveloperSettings.h" 7 | #include "MounteaInteractionEditorSettings.generated.h" 8 | 9 | /** 10 | * Mountea Interaction System global settings. 11 | */ 12 | UCLASS(config = MounteaSettings, DefaultConfig, ProjectUserConfig) 13 | class ACTORINTERACTIONPLUGINEDITOR_API UMounteaInteractionEditorSettings : public UDeveloperSettings 14 | { 15 | GENERATED_BODY() 16 | 17 | public: 18 | 19 | UMounteaInteractionEditorSettings(); 20 | 21 | private: 22 | 23 | #pragma region GameplayTags 24 | 25 | /** 26 | * Allow automatic gameplay tag checks. 27 | * 28 | * If set to true, the system will automatically verify and update gameplay tags on engine startup. 29 | * Default is True. 30 | */ 31 | UPROPERTY(config, EditDefaultsOnly, Category = "GameplayTags", meta=(ConfigRestartRequired=true)) 32 | uint8 bAllowAutoGameplayTagsCheck : 1; 33 | 34 | /** 35 | * URL for the Gameplay Tags configuration file. 36 | * 37 | * This URL points to a remote file containing base gameplay tag definitions. 38 | * The system will use this URL to download and apply the tags if allowed. 39 | * Default: @link https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/master/Config/Tags/MounteaInteractionSystemTags.ini 40 | */ 41 | UPROPERTY(config, EditDefaultsOnly, Category = "GameplayTags", AdvancedDisplay, meta=(ConfigRestartRequired=true)) 42 | FString GameplayTagsURL = FString("https://raw.githubusercontent.com/Mountea-Framework/MounteaInteractionSystem/master/Config/Tags/MounteaInteractionSystemTags.ini"); 43 | 44 | #pragma endregion 45 | 46 | public: 47 | 48 | #pragma region GameplayTags_Getters 49 | 50 | bool AllowCheckTagUpdate() const 51 | { return bAllowAutoGameplayTagsCheck; }; 52 | 53 | FString GetGameplayTagsURL() const 54 | { return GameplayTagsURL; }; 55 | 56 | #pragma endregion 57 | 58 | #if WITH_EDITOR 59 | virtual FText GetSectionText() const override 60 | { 61 | return NSLOCTEXT("MounteaInteractionEditorSystem", "MounteaInteractionSettingsEditorSection", "Mountea Interaction System (Editor)"); 62 | } 63 | 64 | virtual FText GetSectionDescription() const override 65 | { 66 | return NSLOCTEXT("MounteaInteractionEditorSystem", "MounteaInteractionSettingsEditorDescription", "Default values for Mountea Plugins (Editor)."); 67 | } 68 | 69 | virtual FName GetContainerName() const override 70 | { 71 | return "Project"; 72 | } 73 | #endif 74 | }; 75 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Utilities/ActorInteractionEditorUtilities.cpp: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | 4 | #include "ActorInteractionEditorUtilities.h" 5 | 6 | #include "K2Node_Event.h" 7 | #include "Factories/ActorInteractionClassViewerFilter.h" 8 | #include "Kismet2/BlueprintEditorUtils.h" 9 | #include "Kismet2/KismetEditorUtilities.h" 10 | #include "Kismet2/SClassPickerDialog.h" 11 | 12 | bool FActorInteractionEditorUtilities::PickChildrenOfClass(const FText& TitleText, UClass*& OutChosenClass, UClass* Class) 13 | { 14 | // Create filter 15 | const TSharedPtr Filter = MakeShareable(new FActorInteractionClassViewerFilter); 16 | Filter->AllowedChildrenOfClasses.Add(Class); 17 | 18 | // Fill in options 19 | FClassViewerInitializationOptions Options; 20 | Options.Mode = EClassViewerMode::ClassPicker; 21 | Options.DisplayMode = EClassViewerDisplayMode::ListView; 22 | Options.ClassFilters.Add(Filter.ToSharedRef()); 23 | 24 | Options.bShowUnloadedBlueprints = true; 25 | Options.bExpandRootNodes = false; 26 | 27 | Options.NameTypeToDisplay = EClassViewerNameTypeToDisplay::Dynamic; 28 | 29 | return SClassPickerDialog::PickClass(TitleText, Options, OutChosenClass, Class); 30 | } 31 | 32 | UK2Node_Event* FActorInteractionEditorUtilities::BlueprintGetOrAddEvent(UBlueprint* Blueprint, FName EventName, 33 | UClass* EventClassSignature) 34 | { 35 | if (!Blueprint || Blueprint->BlueprintType != BPTYPE_Normal) 36 | { 37 | return nullptr; 38 | } 39 | 40 | // Find existing event 41 | if (UK2Node_Event* EventNode = BlueprintGetEvent(Blueprint, EventName, EventClassSignature)) 42 | { 43 | return EventNode; 44 | } 45 | 46 | // Create a New Event 47 | if (Blueprint->UbergraphPages.Num()) 48 | { 49 | int32 NodePositionY = 0; 50 | UK2Node_Event* NodeEvent = FKismetEditorUtilities::AddDefaultEventNode( 51 | Blueprint, 52 | Blueprint->UbergraphPages[0], 53 | EventName, 54 | EventClassSignature, 55 | NodePositionY 56 | ); 57 | NodeEvent->SetEnabledState(ENodeEnabledState::Enabled); 58 | NodeEvent->NodeComment = ""; 59 | NodeEvent->bCommentBubbleVisible = false; 60 | return NodeEvent; 61 | } 62 | 63 | return nullptr; 64 | } 65 | 66 | UK2Node_Event* FActorInteractionEditorUtilities::BlueprintGetEvent(UBlueprint* Blueprint, FName EventName, 67 | UClass* EventClassSignature) 68 | { 69 | if (!Blueprint || Blueprint->BlueprintType != BPTYPE_Normal) 70 | { 71 | return nullptr; 72 | } 73 | 74 | TArray AllEvents; 75 | FBlueprintEditorUtils::GetAllNodesOfClass(Blueprint, AllEvents); 76 | for (UK2Node_Event* EventNode : AllEvents) 77 | { 78 | if (EventNode->bOverrideFunction && EventNode->EventReference.GetMemberName() == EventName) 79 | { 80 | return EventNode; 81 | } 82 | } 83 | 84 | return nullptr; 85 | } 86 | 87 | UEdGraph* FActorInteractionEditorUtilities::BlueprintGetOrAddFunction(UBlueprint* Blueprint, FName FunctionName, 88 | UClass* FunctionClassSignature) 89 | { 90 | if (!Blueprint || Blueprint->BlueprintType != BPTYPE_Normal) 91 | { 92 | return nullptr; 93 | } 94 | 95 | // Find existing function 96 | if (UEdGraph* GraphFunction = BlueprintGetFunction(Blueprint, FunctionName, FunctionClassSignature)) 97 | { 98 | return GraphFunction; 99 | } 100 | 101 | // Create a new function 102 | UEdGraph* NewGraph = FBlueprintEditorUtils::CreateNewGraph(Blueprint, FunctionName, UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass()); 103 | FBlueprintEditorUtils::AddFunctionGraph(Blueprint, NewGraph, /*bIsUserCreated=*/ false, FunctionClassSignature); 104 | Blueprint->LastEditedDocuments.Add(NewGraph); 105 | return NewGraph; 106 | } 107 | 108 | UEdGraph* FActorInteractionEditorUtilities::BlueprintGetFunction(UBlueprint* Blueprint, FName FunctionName, 109 | UClass* FunctionClassSignature) 110 | { 111 | if (!Blueprint || Blueprint->BlueprintType != BPTYPE_Normal) 112 | { 113 | return nullptr; 114 | } 115 | 116 | // Find existing function 117 | for (UEdGraph* GraphFunction : Blueprint->FunctionGraphs) 118 | { 119 | if (FunctionName == GraphFunction->GetFName()) 120 | { 121 | return GraphFunction; 122 | } 123 | } 124 | 125 | // Find in the implemented Interfaces Graphs 126 | for (const FBPInterfaceDescription& Interface : Blueprint->ImplementedInterfaces) 127 | { 128 | for (UEdGraph* GraphFunction : Interface.Graphs) 129 | { 130 | if (FunctionName == GraphFunction->GetFName()) 131 | { 132 | return GraphFunction; 133 | } 134 | } 135 | } 136 | 137 | return nullptr; 138 | } 139 | -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Private/Utilities/ActorInteractionEditorUtilities.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | 7 | class UK2Node_Event; 8 | /** 9 | * 10 | */ 11 | class FActorInteractionEditorUtilities 12 | { 13 | public: 14 | 15 | // Helper function which defined what classes are available to class selector 16 | static bool PickChildrenOfClass(const FText& TitleText, UClass*& OutChosenClass, UClass* Class); 17 | 18 | // Adding pre-defined Events to BP 19 | static UK2Node_Event* BlueprintGetOrAddEvent(UBlueprint* Blueprint, FName EventName, UClass* EventClassSignature); 20 | static UK2Node_Event* BlueprintGetEvent(UBlueprint* Blueprint, FName EventName, UClass* EventClassSignature); 21 | 22 | // Adding pre-defined Functions to BP 23 | static UEdGraph* BlueprintGetOrAddFunction(UBlueprint* Blueprint, FName FunctionName, UClass* FunctionClassSignature); 24 | static UEdGraph* BlueprintGetFunction(UBlueprint* Blueprint, FName FunctionName, UClass* FunctionClassSignature); 25 | }; -------------------------------------------------------------------------------- /Source/ActorInteractionPluginEditor/Public/ActorInteractionPluginEditor.h: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Interfaces/IHttpRequest.h" 7 | #include "Modules/ModuleManager.h" 8 | 9 | class FSlateStyleSet; 10 | class FHttpModule; 11 | 12 | DECLARE_LOG_CATEGORY_EXTERN(ActorInteractionPluginEditor, All, All); 13 | 14 | class FActorInteractionPluginEditor : public IModuleInterface 15 | { 16 | public: 17 | 18 | /** IModuleInterface implementation */ 19 | virtual void StartupModule() override; 20 | virtual void ShutdownModule() override; 21 | 22 | // Handle Blueprint Events 23 | void HandleNewInteractorBlueprintCreated(UBlueprint* Blueprint); 24 | void HandleNewInteractableBlueprintCreated(UBlueprint* Blueprint); 25 | 26 | protected: 27 | 28 | bool DoesHaveValidTags() const; 29 | void RefreshGameplayTags(); 30 | void UpdateTagsConfig(const FString& NewContent); 31 | void CreateTagsConfig(const FString& NewContent); 32 | 33 | private: 34 | 35 | TSharedPtr InteractionSet; 36 | 37 | TSharedPtr InteractorComponentAssetActions; 38 | TSharedPtr InteractableComponentAssetActions; 39 | TSharedPtr InteractionConfigSettingsAssetAction; 40 | 41 | public: 42 | 43 | /** This function will be bound to Command. */ 44 | void PluginButtonClicked() const; 45 | void SettingsButtonClicked() const; 46 | void EditorSettingsButtonClicked() const; 47 | void WikiButtonClicked() const; 48 | void YoutubeButtonClicked() const; 49 | void DialoguerButtonClicked() const; 50 | void LauncherButtonClicked() const; 51 | 52 | private: 53 | 54 | void RegisterMenus(); 55 | TSharedRef MakeMounteaMenuWidget() const; 56 | 57 | void OnGetResponse(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful); 58 | UFUNCTION() void SendHTTPGet(); 59 | void OnGetResponse_Tags(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful); 60 | UFUNCTION() void SendHTTPGet_Tags(); 61 | 62 | void RegisterTabSpawners(const TSharedRef& TabManager); 63 | void TutorialButtonClicked() const; 64 | 65 | private: 66 | TSharedRef OnSpawnInteractionSystemTutorialTab(const FSpawnTabArgs& SpawnTabArgs); 67 | 68 | private: 69 | 70 | TSharedPtr PluginCommands; 71 | TArray RegisteredCustomClassLayouts; 72 | FHttpModule* Http; 73 | }; 74 | -------------------------------------------------------------------------------- /Source/InteractionEditorNotifications/InteractionEditorNotifications.build.cs: -------------------------------------------------------------------------------- 1 | // All rights reserved Dominik Morse (Pavlicek) 2021 2 | 3 | using System.IO; 4 | using UnrealBuildTool; 5 | 6 | public class InteractionEditorNotifications : ModuleRules 7 | { 8 | public InteractionEditorNotifications(ReadOnlyTargetRules Target) : base(Target) 9 | { 10 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 11 | 12 | PrecompileForTargets = PrecompileTargetsType.None; 13 | bPrecompile = false; 14 | bUsePrecompiled = false; 15 | 16 | PublicDependencyModuleNames.AddRange 17 | (new string[] 18 | { 19 | "Core", 20 | "CoreUObject", 21 | "Engine", 22 | "Slate", 23 | "SlateCore", 24 | "Projects" 25 | } 26 | ); 27 | } 28 | } -------------------------------------------------------------------------------- /Source/InteractionEditorNotifications/Private/EditorHelper.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Pavlicek 2022. All Rights Reserved. 2 | 3 | #include "EditorHelper.h" 4 | #include "Styling/SlateStyle.h" 5 | 6 | #if WITH_EDITOR 7 | #include "Framework/Notifications/NotificationManager.h" 8 | 9 | void FEditorHelper::DisplayEditorNotification(const FText DisplayText, const SNotificationItem::ECompletionState State, const float ExpireDuration, const float FadeOutDuration, const FName ImagePropertyName) 10 | { 11 | 12 | if (DisplayText.IsEmpty() || State == SNotificationItem::CS_None) return; 13 | 14 | 15 | FNotificationInfo NotificationInfo = FNotificationInfo(DisplayText); 16 | 17 | NotificationInfo.bFireAndForget = true; 18 | NotificationInfo.ExpireDuration = ExpireDuration; 19 | NotificationInfo.FadeOutDuration = FadeOutDuration; 20 | NotificationInfo.Image = FCoreStyle::Get().GetBrush(ImagePropertyName); 21 | 22 | FSlateNotificationManager::Get().AddNotification(NotificationInfo).Get()->SetCompletionState(State); 23 | 24 | } 25 | #endif -------------------------------------------------------------------------------- /Source/InteractionEditorNotifications/Private/InteractionEditorNotifications.cpp: -------------------------------------------------------------------------------- 1 | #include "InteractionEditorNotifications.h" 2 | 3 | DEFINE_LOG_CATEGORY(InteractionEditorNotifications); 4 | 5 | #define LOCTEXT_NAMESPACE "FInteractionEditorNotifications" 6 | 7 | void FInteractionEditorNotifications::StartupModule() 8 | { 9 | UE_LOG(InteractionEditorNotifications, Warning, TEXT("InteractionEditorNotifications module has been loaded")); 10 | } 11 | 12 | void FInteractionEditorNotifications::ShutdownModule() 13 | { 14 | UE_LOG(InteractionEditorNotifications, Warning, TEXT("InteractionEditorNotifications module has been unloaded")); 15 | } 16 | 17 | #undef LOCTEXT_NAMESPACE 18 | 19 | IMPLEMENT_MODULE(FInteractionEditorNotifications, InteractionEditorNotifications) -------------------------------------------------------------------------------- /Source/InteractionEditorNotifications/Public/EditorHelper.h: -------------------------------------------------------------------------------- 1 | // Copyright Dominik Pavlicek 2022. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include "CoreMinimal.h" 6 | #include "Widgets/Notifications/SNotificationList.h" 7 | 8 | #if WITH_EDITOR 9 | struct INTERACTIONEDITORNOTIFICATIONS_API FEditorHelper 10 | { 11 | /** Displays editor notification. */ 12 | static void DisplayEditorNotification(FText DisplayText, SNotificationItem::ECompletionState State, float ExpireDuration = 5.0f, float FadeOutDuration = 2.0f , const FName ImagePropertyName = TEXT("MessageLog.Warning")); 13 | }; 14 | #endif -------------------------------------------------------------------------------- /Source/InteractionEditorNotifications/Public/InteractionEditorNotifications.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Modules/ModuleManager.h" 4 | 5 | DECLARE_LOG_CATEGORY_EXTERN(InteractionEditorNotifications, All, All); 6 | 7 | class FInteractionEditorNotifications : public IModuleInterface 8 | { 9 | public: 10 | 11 | /* Called when the module is loaded */ 12 | virtual void StartupModule() override; 13 | 14 | /* Called when the module is unloaded */ 15 | virtual void ShutdownModule() override; 16 | }; --------------------------------------------------------------------------------