// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. #pragma once #include "Engine/Scripting/ScriptingObject.h" #include "Engine/Core/ISerializable.h" #include "Engine/Core/Collections/Array.h" class SceneTicking; class ScriptsFactory; class Actor; class Script; class Joint; class Scene; class Prefab; class PrefabInstanceData; class SceneObject; class PrefabManager; class Level; /// /// Scene objects setup data container used for BeginPlay callback. /// class SceneBeginData { public: /// /// The joints to create after setup. /// Array JointsToCreate; /// /// Called when scene objects setup is done. /// void OnDone(); }; /// /// The actors collection lookup type (id -> actor). /// typedef Dictionary ActorsLookup; #define DECLARE_SCENE_OBJECT(type) \ DECLARE_SCRIPTING_TYPE(type) #define DECLARE_SCENE_OBJECT_ABSTRACT(type) \ DECLARE_SCRIPTING_TYPE_NO_SPAWN(type); \ static type* Spawn(const SpawnParams& params) { return nullptr; } \ explicit type(const SpawnParams& params) #define DECLARE_SCENE_OBJECT_NO_SPAWN(type) \ DECLARE_SCRIPTING_TYPE_NO_SPAWN(type) /// /// Base class for objects that are parts of the scene (actors and scripts). /// API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API SceneObject : public ScriptingObject, public ISerializable { DECLARE_SCRIPTING_TYPE_NO_SPAWN(SceneObject); friend PrefabInstanceData; friend Actor; friend Level; friend ScriptsFactory; friend SceneTicking; public: typedef ScriptingObject Base; // Scene Object lifetime flow: // - Create // - Is created from code: // - Post Spawn // - otherwise: // - Deserialize (more than once for prefab instances) // - Post Load // - Begin Play // - End Play // - Destroy protected: Actor* _parent; Guid _prefabID; Guid _prefabObjectID; /// /// Initializes a new instance of the class. /// /// The object initialization parameters. SceneObject(const SpawnParams& params); public: /// /// Finalizes an instance of the class. /// ~SceneObject(); public: /// /// Determines whether object is during play (spawned/loaded and fully initialized). /// API_PROPERTY() FORCE_INLINE bool IsDuringPlay() const { return (Flags & ObjectFlags::IsDuringPlay) == ObjectFlags::IsDuringPlay; } /// /// Returns true if object has a parent assigned. /// API_PROPERTY() FORCE_INLINE bool HasParent() const { return _parent != nullptr; } /// /// Gets the parent actor (or null if object has no parent). /// API_PROPERTY(Attributes="HideInEditor") FORCE_INLINE Actor* GetParent() const { return _parent; } /// /// Sets the parent actor. /// /// The new parent. API_PROPERTY() FORCE_INLINE void SetParent(Actor* value) { SetParent(value, true); } /// /// Sets the parent actor. /// /// The new parent. /// True if can break prefab link on changing the parent. API_FUNCTION() virtual void SetParent(Actor* value, bool canBreakPrefabLink) = 0; /// /// Gets the scene object ID. /// /// The scene object ID. virtual const Guid& GetSceneObjectId() const = 0; /// /// Gets zero-based index in parent actor children list (scripts or child actors). /// /// The order in parent. API_PROPERTY(Attributes="HideInEditor") virtual int32 GetOrderInParent() const = 0; /// /// Sets zero-based index in parent actor children list (scripts or child actors). /// /// The new order in parent. API_PROPERTY() virtual void SetOrderInParent(int32 index) = 0; public: /// /// Gets a value indicating whether this object has a valid linkage to the prefab asset. /// API_PROPERTY() FORCE_INLINE bool HasPrefabLink() const { return _prefabID.IsValid(); } /// /// Gets the prefab asset ID. Empty if no prefab link exists. /// API_PROPERTY() FORCE_INLINE Guid GetPrefabID() const { return _prefabID; } /// /// Gets the ID of the object within a prefab that is used for synchronization with this object. Empty if no prefab link exists. /// API_PROPERTY() FORCE_INLINE Guid GetPrefabObjectID() const { return _prefabObjectID; } /// /// Links scene object instance to the prefab asset and prefab object. Warning! This applies to the only this object (not scripts or child actors). /// /// The prefab asset identifier. /// The prefab object identifier. API_FUNCTION(Attributes="NoAnimate") virtual void LinkPrefab(const Guid& prefabId, const Guid& prefabObjectId); /// /// Breaks the prefab linkage for this object, all its scripts, and all child actors. /// API_FUNCTION(Attributes="NoAnimate") virtual void BreakPrefabLink(); /// /// Gets the path containing name of this object and all parent objects in tree hierarchy separated with custom separator character (/ by default). Can be used to identify this object in logs. /// /// The character to separate the names. /// The full name path. API_FUNCTION() String GetNamePath(Char separatorChar = '/') const; public: /// /// Called after object loading or spawning to initialize the object (eg. call OnAwake for scripts) but before BeginPlay. Initialization should be performed only within a single SceneObject (use BeginPlay to initialize with a scene). /// virtual void Initialize() = 0; /// /// Called when adding object to the game. /// /// The initialization data (e.g. used to collect joints to link after begin). virtual void BeginPlay(SceneBeginData* data) = 0; /// /// Called when removing object from the game. /// virtual void EndPlay() = 0; public: // [ISerializable] void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; };