Entity¶
增加或删除component
template<typename T, typename... Args>
T& AddOrReplaceComponent(Args&&... args)
{
T& component = m_Scene->m_Registry.emplace_or_replace<T>(m_EntityHandle, std::forward<Args>(args)...);
m_Scene->OnComponentAdded<T>(*this, component);
return component;
}
const std::string& GetName() { return GetComponent<TagComponent>().Tag; }
Scene¶
static Ref<Scene> Copy(Ref<Scene> other);
void DuplicateEntity(Entity entity);
复制组件,复制场景¶
/// <summary>
/// 复制component
/// </summary>
/// <typeparam name="Component"></typeparam>
/// <param name="dst"></param>
/// <param name="src"></param>
/// <param name="enttMap"></param>
template<typename Component>
static void CopyComponent(entt::registry& dst, entt::registry& src, const std::unordered_map<UUID, entt::entity>& enttMap)
{
auto view = src.view<Component>();
for (auto e : view)
{
UUID uuid = src.get<IDComponent>(e).ID;
HZ_CORE_ASSERT(enttMap.find(uuid) != enttMap.end());
entt::entity dstEnttID = enttMap.at(uuid);
auto& component = src.get<Component>(e);
dst.emplace_or_replace<Component>(dstEnttID, component);
}
}
//复制component如果存在的话
template<typename Component>
static void CopyComponentIfExists(Entity dst, Entity src)
{
if (src.HasComponent<Component>())
dst.AddOrReplaceComponent<Component>(src.GetComponent<Component>());
}
//复制场景
Ref<Scene> Scene::Copy(Ref<Scene> other)
{
Ref<Scene> newScene = CreateRef<Scene>();
newScene->m_ViewportWidth = other->m_ViewportWidth;
newScene->m_ViewportHeight = other->m_ViewportHeight;
auto& srcSceneRegistry = other->m_Registry;
auto& dstSceneRegistry = newScene->m_Registry;
std::unordered_map<UUID, entt::entity> enttMap;
// Create entities in new scene
auto idView = srcSceneRegistry.view<IDComponent>();
for (auto e : idView)
{
UUID uuid = srcSceneRegistry.get<IDComponent>(e).ID;
const auto& name = srcSceneRegistry.get<TagComponent>(e).Tag;
Entity newEntity = newScene->CreateEntityWithUUID(uuid, name);
enttMap[uuid] = (entt::entity)newEntity;
}
// Copy components (except IDComponent and TagComponent)
CopyComponent<TransformComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<SpriteRendererComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<CameraComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<NativeScriptComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<Rigidbody2DComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
CopyComponent<BoxCollider2DComponent>(dstSceneRegistry, srcSceneRegistry, enttMap);
return newScene;
}
复制(并创建)实体¶
void Scene::DuplicateEntity(Entity entity)
{
std::string name = entity.GetName();
Entity newEntity = CreateEntity(name);
CopyComponentIfExists<TransformComponent>(newEntity, entity);
CopyComponentIfExists<SpriteRendererComponent>(newEntity, entity);
CopyComponentIfExists<CameraComponent>(newEntity, entity);
CopyComponentIfExists<NativeScriptComponent>(newEntity, entity);
CopyComponentIfExists<Rigidbody2DComponent>(newEntity, entity);
CopyComponentIfExists<BoxCollider2DComponent>(newEntity, entity);
}
SceneHierachyPanel¶
主要加了个上下文的判断
EditorLayer¶
主要是下面这些功能: - 保存场景: - 序列化场景 - onDuplicateEntity 同时提供如下变量: - m_EditorScene; - std::filesystem::path m_EditorScenePath;
改按键¶
ctrl+shift+S保存到,ctrl+s保存上下文,ctrl+d复制实体
case Key::S:
{
if (control)
{
if (shift)
SaveSceneAs();
else
SaveScene();
}
break;
}
// Scene Commands
case Key::D:
{
if (control)
OnDuplicateEntity();
break;
}
openScene¶
如果不为编辑模式,则停止编辑模式
if (m_SceneState != SceneState::Edit)
OnSceneStop();
if (serializer.Deserialize(path.string()))
{
m_EditorScene = newScene;
m_EditorScene->OnViewportResize((uint32_t)m_ViewportSize.x, (uint32_t)m_ViewportSize.y);
m_SceneHierarchyPanel.SetContext(m_EditorScene);
m_ActiveScene = m_EditorScene;
m_EditorScenePath = path;
};
SaveScene as¶
编辑器路径缓存就直接保存,否则。。
void EditorLayer::SaveScene()
{
if (!m_EditorScenePath.empty())
SerializeScene(m_ActiveScene, m_EditorScenePath);
else
SaveSceneAs();
}
SaveScene as¶
win窗口式保存
void EditorLayer::SaveSceneAs()
{
std::string filepath = FileDialogs::SaveFile("CryDust Scene (*.crydust)\0*.crydust\0");
if (!filepath.empty())
{
SerializeScene(m_ActiveScene, filepath);
m_EditorScenePath = filepath;
}
}
void EditorLayer::SerializeScene(Ref<Scene> scene, const std::filesystem::path& path)
{
SceneSerializer serializer(scene);
serializer.Serialize(path.string());
}
OnscenePlay¶
设置状态,拷贝一个新场景,并开启运行时,新的资源栏设置为当前上下文
void EditorLayer::OnScenePlay()
{
m_SceneState = SceneState::Play;
m_ActiveScene = Scene::Copy(m_EditorScene);
m_ActiveScene->OnRuntimeStart();
m_SceneHierarchyPanel.SetContext(m_ActiveScene);
}
OnsceneStop¶
设置状态,运行时停止,切换到编辑器的scene,并设置上下文
void EditorLayer::OnSceneStop()
{
m_SceneState = SceneState::Edit;
m_ActiveScene->OnRuntimeStop();
m_ActiveScene = m_EditorScene;
m_SceneHierarchyPanel.SetContext(m_ActiveScene);
}
复制实体¶
如果不是编辑场景直接不管,是的话就复制
void EditorLayer::OnDuplicateEntity()
{
if (m_SceneState != SceneState::Edit)
return;
Entity selectedEntity = m_SceneHierarchyPanel.GetSelectedEntity();
if (selectedEntity)
m_EditorScene->DuplicateEntity(selectedEntity);
}