Skip to content

Commit 36bd4d7

Browse files
Merge branch '5.3' into 5.4_dev
2 parents 52e722b + 41f9df3 commit 36bd4d7

13 files changed

+312
-10
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,4 @@ DerivedDataCache/*
7979
.idea/*
8080
Config/UpdateConfig.ini
8181
*.zip
82+
*.png~

Resources/tutorialPage_icon.png

5.19 KB
Loading

Resources/youtube_icon.png

-4.18 KB
Loading

Source/ActorInteractionPlugin/Private/Components/Interactable/ActorInteractableComponentBase.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2220,7 +2220,7 @@ void UActorInteractableComponentBase::ResetDefaults()
22202220
void UActorInteractableComponentBase::PostEditChangeChainProperty(FPropertyChangedChainEvent& PropertyChangedEvent)
22212221
{
22222222
Super::PostEditChangeChainProperty(PropertyChangedEvent);
2223-
2223+
22242224
const FName PropertyName = (PropertyChangedEvent.MemberProperty != nullptr) ? PropertyChangedEvent.GetPropertyName() : NAME_None;
22252225

22262226
FString interactableName = GetName();

Source/ActorInteractionPlugin/Public/Helpers/ActorInteractionPluginLog.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// Log category definition
1111
DEFINE_LOG_CATEGORY(LogActorInteraction);
1212

13-
void PrintLog(const ELogVerbosity::Type Verbosity, const FString& Message, FLinearColor Color, float Duration)
13+
void PrintInteractionLog(const ELogVerbosity::Type Verbosity, const FString& Message, FLinearColor Color, float Duration)
1414
{
1515
if (!GWorld) return;
1616

Source/ActorInteractionPlugin/Public/Helpers/ActorInteractionPluginLog.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,23 @@
88
ACTORINTERACTIONPLUGIN_API DECLARE_LOG_CATEGORY_EXTERN(LogActorInteraction, Display, All);
99

1010
// Forward declaration of the logging function
11-
void PrintLog(const ELogVerbosity::Type Verbosity, const FString& Message, FLinearColor Color, float Duration);
11+
void PrintInteractionLog(const ELogVerbosity::Type Verbosity, const FString& Message, FLinearColor Color, float Duration);
1212

1313
// Logging macro definitions
1414
#define LOG_INFO(Format, ...) \
1515
{ \
1616
FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \
17-
PrintLog(ELogVerbosity::Log, FormattedMessage, FLinearColor(0.0f, 1.0f, 0.0f), 5.0f); \
17+
PrintInteractionLog(ELogVerbosity::Log, FormattedMessage, FLinearColor(0.0f, 1.0f, 0.0f), 5.0f); \
1818
}
1919

2020
#define LOG_WARNING(Format, ...) \
2121
{ \
2222
FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \
23-
PrintLog(ELogVerbosity::Warning, FormattedMessage, FLinearColor(1.0f, 1.0f, 0.0f), 10.0f); \
23+
PrintInteractionLog(ELogVerbosity::Warning, FormattedMessage, FLinearColor(1.0f, 1.0f, 0.0f), 10.0f); \
2424
}
2525

2626
#define LOG_ERROR(Format, ...) \
2727
{ \
2828
FString FormattedMessage = FString::Printf(Format, ##__VA_ARGS__); \
29-
PrintLog(ELogVerbosity::Error, FormattedMessage, FLinearColor(1.0f, 0.0f, 0.0f), 15.0f); \
29+
PrintInteractionLog(ELogVerbosity::Error, FormattedMessage, FLinearColor(1.0f, 0.0f, 0.0f), 15.0f); \
3030
}

Source/ActorInteractionPluginEditor/ActorInteractionPluginEditor.Build.cs

+3-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ public ActorInteractionPluginEditor(ReadOnlyTargetRules Target) : base(Target)
6161

6262
"UMG",
6363

64-
"GameplayTags"
64+
"GameplayTags",
65+
66+
"WorkspaceMenuStructure"
6567
}
6668
);
6769

Source/ActorInteractionPluginEditor/Private/ActorInteractionPluginEditor.cpp

+48-2
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
#include "AssetActions/InteractionSettingsConfig.h"
2626
#include "DetailsPanel/MounteaInteractableBase_DetailsPanel.h"
2727
#include "ISettingsModule.h"
28-
#include "PropertyEditorModule.h"
28+
#include "WorkspaceMenuStructure.h"
29+
#include "WorkspaceMenuStructureModule.h"
30+
#include "HelpButton/InteractionSystemTutorialPage.h"
2931
#include "Interfaces/IHttpResponse.h"
3032

3133
#include "Interfaces/IMainFrameModule.h"
@@ -51,7 +53,7 @@ void FActorInteractionPluginEditor::StartupModule()
5153

5254
// Register Category
5355
{
54-
FAssetToolsModule::GetModule().Get().RegisterAdvancedAssetCategory(FName("MounteaInteraction"), FText::FromString(TEXT("\U0001F539 Mountea Interaction")));
56+
FAssetToolsModule::GetModule().Get().RegisterAdvancedAssetCategory(FName("MounteaInteraction"), FText::FromString(TEXT("👉🏻 Mountea Interaction")));
5557
}
5658

5759
// Thumbnails and Icons
@@ -181,6 +183,11 @@ void FActorInteractionPluginEditor::StartupModule()
181183

182184
UToolMenus::RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FActorInteractionPluginEditor::RegisterMenus));
183185
}
186+
187+
// Register Tab Spawner
188+
{
189+
RegisterTabSpawners(FGlobalTabmanager::Get());
190+
}
184191
}
185192

186193
void FActorInteractionPluginEditor::ShutdownModule()
@@ -422,6 +429,31 @@ void FActorInteractionPluginEditor::LauncherButtonClicked() const
422429
}
423430
}
424431

432+
void FActorInteractionPluginEditor::RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager)
433+
{
434+
TabManager->RegisterTabSpawner("InteractionSystemTutorial",
435+
FOnSpawnTab::CreateRaw(this, &FActorInteractionPluginEditor::OnSpawnInteractionSystemTutorialTab))
436+
.SetDisplayName(FText::FromString("Interaction System Tutorial"))
437+
.SetTooltipText(FText::FromString("Learn about the Mountea Interaction System"))
438+
.SetGroup(WorkspaceMenu::GetMenuStructure().GetDeveloperToolsMiscCategory())
439+
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "InputBindingEditor.OutputLog"));
440+
}
441+
442+
TSharedRef<SDockTab> FActorInteractionPluginEditor::OnSpawnInteractionSystemTutorialTab(const FSpawnTabArgs& SpawnTabArgs)
443+
{
444+
return SNew(SDockTab)
445+
.TabRole(ETabRole::NomadTab)
446+
.Label(FText::FromString("Interaction System Tutorial"))
447+
[
448+
SNew(SInteractionSystemTutorialPage)
449+
];
450+
}
451+
452+
void FActorInteractionPluginEditor::TutorialButtonClicked() const
453+
{
454+
FGlobalTabmanager::Get()->TryInvokeTab(FName("InteractionSystemTutorial"));
455+
}
456+
425457
void FActorInteractionPluginEditor::RegisterMenus()
426458
{
427459
// Owner will be used for cleanup in call to UToolMenus::UnregisterOwner
@@ -479,6 +511,20 @@ void FActorInteractionPluginEditor::RegisterMenus()
479511
TSharedRef<SWidget> FActorInteractionPluginEditor::MakeMounteaMenuWidget() const
480512
{
481513
FMenuBuilder MenuBuilder(true, PluginCommands);
514+
MenuBuilder.BeginSection("MounteaMenu_Tools", LOCTEXT("MounteaMenuOptions_Tutorial", "Mountea Interaction Tutorial"));
515+
{
516+
MenuBuilder.AddMenuEntry(
517+
LOCTEXT("MounteaSystemEditor_TutorialButton_Label", "Interaction System Tutorial"),
518+
LOCTEXT("MounteaSystemEditor_TutorialButton_ToolTip", "📖 Open the Mountea Interaction System Tutorial"),
519+
FSlateIcon(FAIntPHelpStyle::GetStyleSetName(), "AIntPStyleSet.Tutorial"),
520+
FUIAction(
521+
FExecuteAction::CreateRaw(this, &FActorInteractionPluginEditor::TutorialButtonClicked)
522+
)
523+
);
524+
525+
};
526+
MenuBuilder.EndSection();
527+
482528
MenuBuilder.BeginSection("MounteaMenu_Tools", LOCTEXT("MounteaMenuOptions_Settings", "Mountea Interaction Settings"));
483529
{
484530
MenuBuilder.AddMenuEntry(

Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ TSharedRef<FSlateStyleSet> FAIntPHelpStyle::Create()
8787
Style->Set("AIntPStyleSet.Icon.UBIcon", new IMAGE_BRUSH(TEXT("UnrealBucketIcon"), Icon16x16));
8888
Style->Set("AIntPStyleSet.Icon.MoneyIcon", new IMAGE_BRUSH(TEXT("MoneyIcon"), Icon16x16));
8989

90+
Style->Set("AIntPStyleSet.Tutorial", new IMAGE_BRUSH(TEXT("tutorialPage_icon"), Icon40x40));
9091
return Style;
9192
}
9293

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
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<ISettingsModule>("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<FContentBrowserModule>("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"(<LargeText>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"(<RichTextBlock.BoldHighlight>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 <RichTextBlock.Italic>Project Settings</> and open <RichTextBlock.Italic>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: <a id="settings" href="Collision">Open Collision Settings</>
61+
)") + bookEmoji + FString(R"( Detailed guide here: <a id="browser" href="https://github.com/Mountea-Framework/MounteaInteractionSystem/wiki/How-to-Setup-Interaction#collision-channels-">Collision Channels Setup</>
62+
)");
63+
64+
FString InteractionMessage = FString(R"(<RichTextBlock.BoldHighlight>Interaction Defaults</>
65+
66+
)") + arrowEmoji + FString(R"( Open <RichTextBlock.Italic>Project Settings</> and open <RichTextBlock.Italic>Mountea Interaction System</> category.
67+
<RichTextBlock.BoldHighlight>Default Interaction System Config</> must <RichTextBlock.BoldHighlight>not</> be empty!
68+
69+
)") + sparkleEmoji + FString(R"( You can quickly open the settings here: <a id="settings" href="Mountea">Open Mountea Interaction System Settings</>
70+
)") + bookEmoji + FString(R"( Detailed guide on Wiki page: <a id="browser" href="https://github.com/Mountea-Framework/MounteaInteractionSystem/wiki/How-to-Setup-Interaction#interaction-defaults-">Interaction Defaults Setup</>
71+
)") + folderEmoji + FString(R"( Default Config File is located here: <a id="folder" href="/ActorInteractionPlugin/Config">Open Default Config Folder</>
72+
)");
73+
74+
FString ExampleFolderMessage = FString(R"(
75+
<RichTextBlock.BoldHighlight>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: <a id="folder" href="/ActorInteractionPlugin/Example">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+
}

0 commit comments

Comments
 (0)