Group all BP categories/components under ASTERION|PS_Editor + fix Content Browser freeze

- All UFUNCTION/UPROPERTY Category prefix changed from "PS Editor" to "ASTERION|PS_Editor"
- Components ClassGroup changed to "ASTERION|PS Editor" (sub-hierarchy in Add Component menu)
- Create Spawnable Blueprint: defer asset loading until menu click
  (was loading all meshes on right-click, causing 30s freeze)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-17 16:29:41 +02:00
parent cd43ae6adc
commit 4354b8c96e
14 changed files with 86 additions and 83 deletions

View File

@@ -57,7 +57,7 @@ public:
virtual void UpdateVisualization() override; virtual void UpdateVisualization() override;
UFUNCTION(BlueprintCallable, Category = "PS Editor|Spline") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor|Spline")
virtual void UpdateSplineMaterials() override; virtual void UpdateSplineMaterials() override;
// ---- Handle interaction (IPS_Editor_SplineEditable) ---- // ---- Handle interaction (IPS_Editor_SplineEditable) ----

View File

@@ -20,11 +20,11 @@ public:
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
protected: protected:
/** Icon visible in the editor viewport. Override the sprite in a derived Blueprint if needed. */ /** Icon visible in the editor viewport. Override the sprite in a derived Blueprint if needed. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TObjectPtr<class UBillboardComponent> SpriteComponent; TObjectPtr<class UBillboardComponent> SpriteComponent;
/** Arrow showing the view direction in the editor viewport. */ /** Arrow showing the view direction in the editor viewport. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TObjectPtr<class UArrowComponent> ArrowComponent; TObjectPtr<class UArrowComponent> ArrowComponent;
#endif #endif
}; };

View File

@@ -18,41 +18,41 @@ class PS_EDITOR_API UPS_Editor_GameInstanceSubsystem : public UGameInstanceSubsy
public: public:
/** Scenario name to load on the next level. Set by PROSERVE or Play button, consumed on load. */ /** Scenario name to load on the next level. Set by PROSERVE or Play button, consumed on load. */
UPROPERTY(BlueprintReadWrite, Category = "PS Editor") UPROPERTY(BlueprintReadWrite, Category = "ASTERION|PS_Editor")
FString PendingScenarioName; FString PendingScenarioName;
/** Base level name associated with the pending scenario. */ /** Base level name associated with the pending scenario. */
UPROPERTY(BlueprintReadWrite, Category = "PS Editor") UPROPERTY(BlueprintReadWrite, Category = "ASTERION|PS_Editor")
FString PendingBaseLevel; FString PendingBaseLevel;
/** Last scenario/base level edited. Persists after consume — used by ReturnToEditor. */ /** Last scenario/base level edited. Persists after consume — used by ReturnToEditor. */
UPROPERTY(BlueprintReadOnly, Category = "PS Editor") UPROPERTY(BlueprintReadOnly, Category = "ASTERION|PS_Editor")
FString LastEditedScenarioName; FString LastEditedScenarioName;
UPROPERTY(BlueprintReadOnly, Category = "PS Editor") UPROPERTY(BlueprintReadOnly, Category = "ASTERION|PS_Editor")
FString LastEditedBaseLevel; FString LastEditedBaseLevel;
/** Name of the editor map to return to. Set this once at startup. */ /** Name of the editor map to return to. Set this once at startup. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
FString EditorMapName; FString EditorMapName;
/** True when the Play button was pressed (gameplay mode). False when just loading/editing a scenario. */ /** True when the Play button was pressed (gameplay mode). False when just loading/editing a scenario. */
UPROPERTY(BlueprintReadWrite, Category = "PS Editor") UPROPERTY(BlueprintReadWrite, Category = "ASTERION|PS_Editor")
bool bIsPlayMode = false; bool bIsPlayMode = false;
/** Set pending scenario + base level (for opening the editor or gameplay). */ /** Set pending scenario + base level (for opening the editor or gameplay). */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
void SetPendingScenario(const FString& ScenarioName, const FString& BaseLevel); void SetPendingScenario(const FString& ScenarioName, const FString& BaseLevel);
/** Consume the pending scenario (reads and clears). */ /** Consume the pending scenario (reads and clears). */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
FString ConsumePendingScenario(); FString ConsumePendingScenario();
/** Open the editor with the current pending scenario + base level. */ /** Open the editor with the current pending scenario + base level. */
UFUNCTION(BlueprintCallable, Category = "PS Editor", meta = (WorldContext = "WorldContextObject")) UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor", meta = (WorldContext = "WorldContextObject"))
void OpenEditor(const UObject* WorldContextObject); void OpenEditor(const UObject* WorldContextObject);
/** Return to the editor, keeping the current base level and scenario. */ /** Return to the editor, keeping the current base level and scenario. */
UFUNCTION(BlueprintCallable, Category = "PS Editor", meta = (WorldContext = "WorldContextObject")) UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor", meta = (WorldContext = "WorldContextObject"))
void ReturnToEditor(const UObject* WorldContextObject); void ReturnToEditor(const UObject* WorldContextObject);
}; };

View File

@@ -17,6 +17,6 @@ public:
APS_Editor_GameMode(); APS_Editor_GameMode();
/** Whether the editor is currently in edit mode (vs play/preview mode). */ /** Whether the editor is currently in edit mode (vs play/preview mode). */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
bool bIsEditMode = true; bool bIsEditMode = true;
}; };

View File

@@ -30,48 +30,48 @@ class PS_EDITOR_API APS_Editor_PlayerController : public APlayerController
public: public:
APS_Editor_PlayerController(); APS_Editor_PlayerController();
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
UPS_Editor_SelectionManager* GetSelectionManager() const { return SelectionManager; } UPS_Editor_SelectionManager* GetSelectionManager() const { return SelectionManager; }
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
UPS_Editor_UndoManager* GetUndoManager() const { return UndoManager; } UPS_Editor_UndoManager* GetUndoManager() const { return UndoManager; }
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
UPS_Editor_SpawnManager* GetSpawnManager() const { return SpawnManager; } UPS_Editor_SpawnManager* GetSpawnManager() const { return SpawnManager; }
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
UPS_Editor_SceneSerializer* GetSceneSerializer() const { return SceneSerializer; } UPS_Editor_SceneSerializer* GetSceneSerializer() const { return SceneSerializer; }
/** Master catalog grouping all sub-catalogs (Tools, Characters, Props...). */ /** Master catalog grouping all sub-catalogs (Tools, Characters, Props...). */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TObjectPtr<UPS_Editor_MasterCatalog> MasterCatalogAsset; TObjectPtr<UPS_Editor_MasterCatalog> MasterCatalogAsset;
/** Current base level for scene save/load filtering. Auto-detected at startup, switchable via UI. */ /** Current base level for scene save/load filtering. Auto-detected at startup, switchable via UI. */
UPROPERTY(BlueprintReadWrite, Category = "PS Editor") UPROPERTY(BlueprintReadWrite, Category = "ASTERION|PS_Editor")
FString CurrentBaseLevel; FString CurrentBaseLevel;
/** Fired when the editor Close button is pressed (after optional save). /** Fired when the editor Close button is pressed (after optional save).
* Bind this in Blueprint to override the default behavior (quit application). * Bind this in Blueprint to override the default behavior (quit application).
* If nothing is bound, the application exits. */ * If nothing is bound, the application exits. */
UPROPERTY(BlueprintAssignable, Category = "PS Editor") UPROPERTY(BlueprintAssignable, Category = "ASTERION|PS_Editor")
FOnEditorClosed OnEditorClosed; FOnEditorClosed OnEditorClosed;
/** Call to close the editor. Broadcasts OnEditorClosed; if unbound, quits the app. */ /** Call to close the editor. Broadcasts OnEditorClosed; if unbound, quits the app. */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
void CloseEditor(); void CloseEditor();
// ---- Simulate Mode ---- // ---- Simulate Mode ----
/** Start simulation: enable AI, store actor positions, disable saving. */ /** Start simulation: enable AI, store actor positions, disable saving. */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
void StartSimulation(); void StartSimulation();
/** Stop simulation: disable AI, restore actor positions, re-enable saving. */ /** Stop simulation: disable AI, restore actor positions, re-enable saving. */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
void StopSimulation(); void StopSimulation();
/** True while simulation is running. */ /** True while simulation is running. */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
bool IsSimulating() const { return bSimulating; } bool IsSimulating() const { return bSimulating; }
/** Load a base level as sublevel for visual context. Unloads previous sublevel. /** Load a base level as sublevel for visual context. Unloads previous sublevel.
@@ -80,7 +80,7 @@ public:
* If empty, LevelName is used as-is (legacy behavior). * If empty, LevelName is used as-is (legacy behavior).
* @param ExtraSublevels Additional sublevels to load alongside (e.g. always-loaded streaming levels). * @param ExtraSublevels Additional sublevels to load alongside (e.g. always-loaded streaming levels).
*/ */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
void LoadBaseLevelAsSublevel(const FString& LevelName, const FString& MapPath, const TArray<FString>& ExtraSublevels); void LoadBaseLevelAsSublevel(const FString& LevelName, const FString& MapPath, const TArray<FString>& ExtraSublevels);
/** Overload without extra sublevels. */ /** Overload without extra sublevels. */
@@ -88,7 +88,7 @@ public:
// ---- Editor Mode (Normal / SplinePlacement) ---- // ---- Editor Mode (Normal / SplinePlacement) ----
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
EPS_Editor_EditorMode GetEditorMode() const { return EditorMode; } EPS_Editor_EditorMode GetEditorMode() const { return EditorMode; }
/** Enter point-placement mode for any actor implementing IPS_Editor_PointPlaceable. */ /** Enter point-placement mode for any actor implementing IPS_Editor_PointPlaceable. */

View File

@@ -45,7 +45,7 @@ public:
* @param bStripEditorComponents If true, removes SpawnableComponent and EditableComponent after spawn (cleaner for gameplay). * @param bStripEditorComponents If true, removes SpawnableComponent and EditableComponent after spawn (cleaner for gameplay).
* @return True if the scene was loaded successfully. * @return True if the scene was loaded successfully.
*/ */
UFUNCTION(BlueprintCallable, Category = "PS Editor", meta = (WorldContext = "WorldContextObject")) UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor", meta = (WorldContext = "WorldContextObject"))
static bool LoadScene(const UObject* WorldContextObject, const FString& SceneName, TArray<AActor*>& OutActors, static bool LoadScene(const UObject* WorldContextObject, const FString& SceneName, TArray<AActor*>& OutActors,
bool bStripEditorComponents = true, EPS_Editor_SceneLoadFilter Filter = EPS_Editor_SceneLoadFilter::All); bool bStripEditorComponents = true, EPS_Editor_SceneLoadFilter Filter = EPS_Editor_SceneLoadFilter::All);
@@ -59,37 +59,37 @@ public:
/** /**
* Get the directory where scenes are stored. * Get the directory where scenes are stored.
*/ */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
static FString GetScenesDirectory(); static FString GetScenesDirectory();
/** /**
* Get the full file path for a scene name. * Get the full file path for a scene name.
*/ */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
static FString GetSceneFilePath(const FString& SceneName); static FString GetSceneFilePath(const FString& SceneName);
/** Get the full file path for a scene name and its base level. Uses level-specific subdirectory. */ /** Get the full file path for a scene name and its base level. Uses level-specific subdirectory. */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
static FString GetSceneFilePathForLevel(const FString& SceneName, const FString& LevelName); static FString GetSceneFilePathForLevel(const FString& SceneName, const FString& LevelName);
/** /**
* Get all saved scene names. Optionally filter by level name. * Get all saved scene names. Optionally filter by level name.
* @param LevelFilter If not empty, only return scenes associated with this level. * @param LevelFilter If not empty, only return scenes associated with this level.
*/ */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
static TArray<FString> GetSavedSceneNames(const FString& LevelFilter = TEXT("")); static TArray<FString> GetSavedSceneNames(const FString& LevelFilter = TEXT(""));
/** /**
* Get the level name associated with a saved scene (reads the JSON header without spawning). * Get the level name associated with a saved scene (reads the JSON header without spawning).
*/ */
UFUNCTION(BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor")
static FString GetSceneLevelName(const FString& SceneName); static FString GetSceneLevelName(const FString& SceneName);
/** /**
* Returns true while a scene is being loaded (actors are being spawned from JSON). * Returns true while a scene is being loaded (actors are being spawned from JSON).
* Use in BeginPlay to skip default initialization — wait for OnPropertiesLoaded instead. * Use in BeginPlay to skip default initialization — wait for OnPropertiesLoaded instead.
*/ */
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "PS Editor") UFUNCTION(BlueprintCallable, BlueprintPure, Category = "ASTERION|PS_Editor")
static bool IsLoadingFromScene(const AActor* Actor); static bool IsLoadingFromScene(const AActor* Actor);
/** Static flag: true while SceneLoader or SceneSerializer is spawning actors. */ /** Static flag: true while SceneLoader or SceneSerializer is spawning actors. */
@@ -99,13 +99,13 @@ public:
static bool bIsEditorModeActive; static bool bIsEditorModeActive;
/** Returns true if the PS_Editor runtime editor is currently active. Callable from any BP. */ /** Returns true if the PS_Editor runtime editor is currently active. Callable from any BP. */
UFUNCTION(BlueprintCallable, BlueprintPure, Category = "PS Editor") UFUNCTION(BlueprintCallable, BlueprintPure, Category = "ASTERION|PS_Editor")
static bool IsInEditorMode() { return bIsEditorModeActive; } static bool IsInEditorMode() { return bIsEditorModeActive; }
/** /**
* Get all saved scenes for the current level. * Get all saved scenes for the current level.
*/ */
UFUNCTION(BlueprintCallable, Category = "PS Editor", meta = (WorldContext = "WorldContextObject")) UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor", meta = (WorldContext = "WorldContextObject"))
static TArray<FString> GetSavedSceneNamesForCurrentLevel(const UObject* WorldContextObject); static TArray<FString> GetSavedSceneNamesForCurrentLevel(const UObject* WorldContextObject);
private: private:

View File

@@ -25,47 +25,47 @@ class PS_EDITOR_API IPS_Editor_ChildMovable
public: public:
/** Number of movable sub-elements. */ /** Number of movable sub-elements. */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
int32 GetMovableChildCount() const; int32 GetMovableChildCount() const;
/** World location of the sub-element at the given index. */ /** World location of the sub-element at the given index. */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
FVector GetChildLocation(int32 Index) const; FVector GetChildLocation(int32 Index) const;
/** Move the sub-element at the given index to a new world position. */ /** Move the sub-element at the given index to a new world position. */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
void MoveChild(int32 Index, const FVector& NewWorldPosition); void MoveChild(int32 Index, const FVector& NewWorldPosition);
/** Return all sub-element positions (used for undo snapshots). */ /** Return all sub-element positions (used for undo snapshots). */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
TArray<FVector> GetAllChildLocations() const; TArray<FVector> GetAllChildLocations() const;
/** Restore all sub-element positions (used for undo). */ /** Restore all sub-element positions (used for undo). */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
void SetAllChildLocations(const TArray<FVector>& Positions); void SetAllChildLocations(const TArray<FVector>& Positions);
/** Index of the sub-element under the cursor ray (-1 if none). /** Index of the sub-element under the cursor ray (-1 if none).
* Implement with sphere-ray intersection or any hit detection that suits your visuals. */ * Implement with sphere-ray intersection or any hit detection that suits your visuals. */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
int32 GetChildIndexUnderCursor(const FVector& RayOrigin, const FVector& RayDirection) const; int32 GetChildIndexUnderCursor(const FVector& RayOrigin, const FVector& RayDirection) const;
/** Show or hide visual handles for the sub-elements. */ /** Show or hide visual handles for the sub-elements. */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
void SetChildHandlesVisible(bool bVisible); void SetChildHandlesVisible(bool bVisible);
/** Highlight a specific sub-element (e.g. change handle color). */ /** Highlight a specific sub-element (e.g. change handle color). */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
void HighlightChild(int32 Index); void HighlightChild(int32 Index);
/** Clear all sub-element highlights. */ /** Clear all sub-element highlights. */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
void ClearChildHighlight(); void ClearChildHighlight();
/** Export sub-element positions to the CustomProperties map for scene saving. */ /** Export sub-element positions to the CustomProperties map for scene saving. */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
void ExportChildLocations(TMap<FString, FString>& OutProperties) const; void ExportChildLocations(TMap<FString, FString>& OutProperties) const;
/** Import sub-element positions from the CustomProperties map on scene load. */ /** Import sub-element positions from the CustomProperties map on scene load. */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor|Child Movable") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor|Child Movable")
void ImportChildLocations(const TMap<FString, FString>& Properties); void ImportChildLocations(const TMap<FString, FString>& Properties);
}; };

View File

@@ -15,25 +15,25 @@ struct FPS_Editor_EditablePropertyEntry
/** /**
* Property path: "ComponentName.PropertyName" or just "PropertyName" for actor-level. * Property path: "ComponentName.PropertyName" or just "PropertyName" for actor-level.
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
FName Path; FName Path;
/** Display name override for the runtime editor UI. If empty, the property name is used. */ /** Display name override for the runtime editor UI. If empty, the property name is used. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
FString DisplayName; FString DisplayName;
/** /**
* If true, calls OnEditorPropertiesChanged (IPS_Editor_EditableInterface) * If true, calls OnEditorPropertiesChanged (IPS_Editor_EditableInterface)
* after changing this property, so the actor can re-run its initialization logic. * after changing this property, so the actor can re-run its initialization logic.
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
bool bNeedsReinit = false; bool bNeedsReinit = false;
/** /**
* If true, the actor is destroyed and respawned with all current properties applied, * If true, the actor is destroyed and respawned with all current properties applied,
* then OnEditorPropertiesChanged is called. Use when reinit alone is not enough. * then OnEditorPropertiesChanged is called. Use when reinit alone is not enough.
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
bool bNeedsRespawn = false; bool bNeedsRespawn = false;
}; };
@@ -46,7 +46,7 @@ struct FPS_Editor_EditablePropertyEntry
* 2. Pick a property from "Add Property" (filtered to that component) * 2. Pick a property from "Add Property" (filtered to that component)
* 3. It auto-adds to "Editable Properties" as "Component.Property" * 3. It auto-adds to "Editable Properties" as "Component.Property"
*/ */
UCLASS(ClassGroup = (PSEditor), meta = (BlueprintSpawnableComponent, DisplayName = "PS Editor Editable")) UCLASS(ClassGroup = "ASTERION|PS Editor", meta = (BlueprintSpawnableComponent, DisplayName = "PS Editor Editable"))
class PS_EDITOR_API UPS_Editor_EditableComponent : public UActorComponent class PS_EDITOR_API UPS_Editor_EditableComponent : public UActorComponent
{ {
GENERATED_BODY() GENERATED_BODY()

View File

@@ -27,21 +27,21 @@ public:
* The new value is already applied when this is called. * The new value is already applied when this is called.
* @param PropertyPath The property that changed (e.g. "CharacterType" or "MyComponent.SomeProperty"). * @param PropertyPath The property that changed (e.g. "CharacterType" or "MyComponent.SomeProperty").
*/ */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor")
void OnEditorPropertyChanged(const FString& PropertyPath); void OnEditorPropertyChanged(const FString& PropertyPath);
/** /**
* Called when a property with bNeedsReinit is changed. * Called when a property with bNeedsReinit is changed.
* The new value is already applied. Use this to re-run initialization logic. * The new value is already applied. Use this to re-run initialization logic.
*/ */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor")
void OnEditorNeedsReinit(); void OnEditorNeedsReinit();
/** /**
* Called on the NEW actor after a respawn triggered by bNeedsRespawn. * Called on the NEW actor after a respawn triggered by bNeedsRespawn.
* All properties have been applied. Use this for post-respawn setup. * All properties have been applied. Use this for post-respawn setup.
*/ */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor")
void OnEditorNeedsRespawn(); void OnEditorNeedsRespawn();
/** /**
@@ -49,7 +49,7 @@ public:
* Fires both in editor (SceneSerializer) and in gameplay (SceneLoader). * Fires both in editor (SceneSerializer) and in gameplay (SceneLoader).
* Use this to re-initialize your actor based on the loaded property values. * Use this to re-initialize your actor based on the loaded property values.
*/ */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor")
void OnPropertiesLoaded(); void OnPropertiesLoaded();
/** /**
@@ -57,7 +57,7 @@ public:
* Use this to show/hide editor-only helpers (VR guides, placement aids, debug visuals, etc.). * Use this to show/hide editor-only helpers (VR guides, placement aids, debug visuals, etc.).
* @param bIsEditing True when entering edit mode, false when leaving (Play, return to game). * @param bIsEditing True when entering edit mode, false when leaving (Play, return to game).
*/ */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor")
void OnEditorModeChanged(bool bIsEditing); void OnEditorModeChanged(bool bIsEditing);
/** /**
@@ -65,7 +65,7 @@ public:
* Use this to update visuals dynamically based on property changes, animate helpers, etc. * Use this to update visuals dynamically based on property changes, animate helpers, etc.
* @param DeltaTime Time since last frame. * @param DeltaTime Time since last frame.
*/ */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor")
void OnEditorTick(float DeltaTime); void OnEditorTick(float DeltaTime);
/** /**
@@ -75,6 +75,6 @@ public:
* @param PropertyPath The property path (e.g. "WeaponName" or "MyComponent.WeaponType"). * @param PropertyPath The property path (e.g. "WeaponName" or "MyComponent.WeaponType").
* @return List of option strings. Empty = use default widget. * @return List of option strings. Empty = use default widget.
*/ */
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "PS Editor") UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "ASTERION|PS_Editor")
TArray<FString> GetCustomOptionsForProperty(const FString& PropertyPath) const; TArray<FString> GetCustomOptionsForProperty(const FString& PropertyPath) const;
}; };

View File

@@ -14,7 +14,7 @@ struct FPS_Editor_SpawnEntry
GENERATED_BODY() GENERATED_BODY()
/** The Blueprint class to spawn. Must have a PS_Editor_SpawnableComponent for name/category. */ /** The Blueprint class to spawn. Must have a PS_Editor_SpawnableComponent for name/category. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TSubclassOf<AActor> ActorClass; TSubclassOf<AActor> ActorClass;
}; };
@@ -34,12 +34,12 @@ class PS_EDITOR_API UPS_Editor_SpawnCatalog : public UPrimaryDataAsset
public: public:
/** List of spawnable actors. */ /** List of spawnable actors. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TArray<FPS_Editor_SpawnEntry> Entries; TArray<FPS_Editor_SpawnEntry> Entries;
#if WITH_EDITOR #if WITH_EDITOR
/** Captures UE-generated thumbnails for all Blueprints in the catalog and assigns them to their SpawnableComponents. */ /** Captures UE-generated thumbnails for all Blueprints in the catalog and assigns them to their SpawnableComponents. */
UFUNCTION(CallInEditor, Category = "PS Editor") UFUNCTION(CallInEditor, Category = "ASTERION|PS_Editor")
void CaptureAllThumbnails(); void CaptureAllThumbnails();
#endif #endif
}; };
@@ -55,18 +55,18 @@ struct FPS_Editor_BaseLevelEntry
GENERATED_BODY() GENERATED_BODY()
/** Display name shown in the editor UI and used for scene filtering. */ /** Display name shown in the editor UI and used for scene filtering. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
FString DisplayName; FString DisplayName;
/** /**
* Full map path used for OpenLevel and sublevel loading. * Full map path used for OpenLevel and sublevel loading.
* Example: "/Game/Maps/Warehouse" * Example: "/Game/Maps/Warehouse"
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
FString MapPath; FString MapPath;
/** Thumbnail image shown in the BaseLevel selection popup. */ /** Thumbnail image shown in the BaseLevel selection popup. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TObjectPtr<UTexture2D> Thumbnail; TObjectPtr<UTexture2D> Thumbnail;
/** /**
@@ -75,7 +75,7 @@ struct FPS_Editor_BaseLevelEntry
* but not automatically loaded when the base level is a sublevel itself. * but not automatically loaded when the base level is a sublevel itself.
* Full map paths, e.g. "/Game/Maps/Warehouse_Lighting" * Full map paths, e.g. "/Game/Maps/Warehouse_Lighting"
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TArray<FString> AdditionalSublevels; TArray<FString> AdditionalSublevels;
/** /**
@@ -83,7 +83,7 @@ struct FPS_Editor_BaseLevelEntry
* Their entries are merged with the global catalogs (MasterCatalog::Catalogs). * Their entries are merged with the global catalogs (MasterCatalog::Catalogs).
* Empty = only global catalogs are shown. * Empty = only global catalogs are shown.
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TArray<TObjectPtr<UPS_Editor_SpawnCatalog>> Catalogs; TArray<TObjectPtr<UPS_Editor_SpawnCatalog>> Catalogs;
}; };
@@ -99,7 +99,7 @@ class PS_EDITOR_API UPS_Editor_MasterCatalog : public UPrimaryDataAsset
public: public:
/** Sub-catalogs to load. Each one contributes its entries to the runtime spawn UI. */ /** Sub-catalogs to load. Each one contributes its entries to the runtime spawn UI. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TArray<TObjectPtr<UPS_Editor_SpawnCatalog>> Catalogs; TArray<TObjectPtr<UPS_Editor_SpawnCatalog>> Catalogs;
/** /**
@@ -107,6 +107,6 @@ public:
* DisplayName is used for UI display and scene filtering. * DisplayName is used for UI display and scene filtering.
* MapPath is the full package path for OpenLevel (e.g. "/Game/Maps/Warehouse"). * MapPath is the full package path for OpenLevel (e.g. "/Game/Maps/Warehouse").
*/ */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "PS Editor") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ASTERION|PS_Editor")
TArray<FPS_Editor_BaseLevelEntry> BaseLevels; TArray<FPS_Editor_BaseLevelEntry> BaseLevels;
}; };

View File

@@ -8,7 +8,7 @@
* Marker component for Blueprints that can be spawned via the PS_Editor catalogue. * Marker component for Blueprints that can be spawned via the PS_Editor catalogue.
* Add this component to any Blueprint to make it appear in the runtime spawn catalogue. * Add this component to any Blueprint to make it appear in the runtime spawn catalogue.
*/ */
UCLASS(ClassGroup = (PSEditor), meta = (BlueprintSpawnableComponent, DisplayName = "PS Editor Spawnable")) UCLASS(ClassGroup = "ASTERION|PS Editor", meta = (BlueprintSpawnableComponent, DisplayName = "PS Editor Spawnable"))
class PS_EDITOR_API UPS_Editor_SpawnableComponent : public UActorComponent class PS_EDITOR_API UPS_Editor_SpawnableComponent : public UActorComponent
{ {
GENERATED_BODY() GENERATED_BODY()

View File

@@ -29,7 +29,7 @@ public:
virtual int32 GetCurrentPointCount() const override { return GetNumPoints(); } virtual int32 GetCurrentPointCount() const override { return GetNumPoints(); }
/** Get the underlying USplineComponent (for AI path following, etc.). */ /** Get the underlying USplineComponent (for AI path following, etc.). */
UFUNCTION(BlueprintCallable, Category = "PS Editor|Spline") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor|Spline")
USplineComponent* GetSplineComponent() const { return SplineComp; } USplineComponent* GetSplineComponent() const { return SplineComp; }
/** Spline display color (override in Blueprint subclasses for variants). */ /** Spline display color (override in Blueprint subclasses for variants). */
@@ -73,7 +73,7 @@ public:
virtual void UpdateVisualization() override; virtual void UpdateVisualization() override;
/** Re-apply SplineColor to materials (call after changing SplineColor at runtime). */ /** Re-apply SplineColor to materials (call after changing SplineColor at runtime). */
UFUNCTION(BlueprintCallable, Category = "PS Editor|Spline") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor|Spline")
virtual void UpdateSplineMaterials() override; virtual void UpdateSplineMaterials() override;
// ---- Handle interaction ---- // ---- Handle interaction ----

View File

@@ -17,7 +17,7 @@ class PS_EDITOR_API APS_Editor_HUD : public AHUD
public: public:
/** Returns the main editor widget instance. */ /** Returns the main editor widget instance. */
UFUNCTION(BlueprintCallable, Category = "PS Editor|UI") UFUNCTION(BlueprintCallable, Category = "ASTERION|PS_Editor|UI")
UPS_Editor_MainWidget* GetMainWidget() const { return MainWidget; } UPS_Editor_MainWidget* GetMainWidget() const { return MainWidget; }
protected: protected:

View File

@@ -44,28 +44,31 @@ static TSharedRef<FExtender> OnExtendContentBrowserAssetSelectionMenu(const TArr
if (!bAllAreMesh) return Extender; if (!bAllAreMesh) return Extender;
TArray<UObject*> SelectedObjects; // Defer asset loading until the user actually clicks the menu item
for (const FAssetData& Asset : SelectedAssets) TArray<FAssetData> SelectedAssetsCopy = SelectedAssets;
{
if (UObject* Obj = Asset.GetAsset())
{
SelectedObjects.Add(Obj);
}
}
Extender->AddMenuExtension( Extender->AddMenuExtension(
"GetAssetActions", "GetAssetActions",
EExtensionHook::After, EExtensionHook::After,
nullptr, nullptr,
FMenuExtensionDelegate::CreateLambda([SelectedObjects](FMenuBuilder& MenuBuilder) FMenuExtensionDelegate::CreateLambda([SelectedAssetsCopy](FMenuBuilder& MenuBuilder)
{ {
MenuBuilder.BeginSection("PSEditor", NSLOCTEXT("PSEditor", "PSEditorMenu", "PS Editor")); MenuBuilder.BeginSection("PSEditor", NSLOCTEXT("PSEditor", "PSEditorMenu", "PS Editor"));
MenuBuilder.AddMenuEntry( MenuBuilder.AddMenuEntry(
NSLOCTEXT("PSEditor", "CreateSpawnableBP", "Create Spawnable Blueprint"), NSLOCTEXT("PSEditor", "CreateSpawnableBP", "Create Spawnable Blueprint"),
NSLOCTEXT("PSEditor", "CreateSpawnableBPTooltip", "Create a Blueprint with PS_Editor Spawnable + Editable components from this mesh"), NSLOCTEXT("PSEditor", "CreateSpawnableBPTooltip", "Create a Blueprint with PS_Editor Spawnable + Editable components from this mesh"),
FSlateIcon(), FSlateIcon(),
FUIAction(FExecuteAction::CreateLambda([SelectedObjects]() FUIAction(FExecuteAction::CreateLambda([SelectedAssetsCopy]()
{ {
// Load assets now (on-demand, not on menu open)
TArray<UObject*> SelectedObjects;
for (const FAssetData& Asset : SelectedAssetsCopy)
{
if (UObject* Obj = Asset.GetAsset())
{
SelectedObjects.Add(Obj);
}
}
FPS_Editor_BlueprintFromMesh::OnCreateBlueprintFromMesh(SelectedObjects); FPS_Editor_BlueprintFromMesh::OnCreateBlueprintFromMesh(SelectedObjects);
})) }))
); );