Added support for null GameObjects (loading is buggy)
This commit is contained in:
parent
7e1a909709
commit
ddd93a85f4
|
@ -256,4 +256,7 @@
|
|||
Color: {x: 1, y: 1, z: 1, w: 1}
|
||||
Layer: 4294967295
|
||||
Strength: 0.25
|
||||
Scripts: ~
|
||||
Scripts:
|
||||
- Type: PickAndThrow
|
||||
throwForce: [100, 200, 100]
|
||||
item: 1
|
|
@ -288,7 +288,7 @@ namespace SHADE
|
|||
return CHANGED;
|
||||
}
|
||||
|
||||
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered)
|
||||
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull)
|
||||
{
|
||||
ImGui::Text(label.c_str());
|
||||
if (isHovered)
|
||||
|
@ -296,7 +296,7 @@ namespace SHADE
|
|||
ImGui::SameLine();
|
||||
SHEntity* entity = SHEntityManager::GetEntityByID(value);
|
||||
std::ostringstream oss;
|
||||
if (entity)
|
||||
if (!alwaysNull && entity)
|
||||
{
|
||||
oss << value << ": " << entity->name;
|
||||
}
|
||||
|
@ -314,6 +314,13 @@ namespace SHADE
|
|||
SHDragDrop::EndTarget();
|
||||
}
|
||||
}
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Clear"))
|
||||
{
|
||||
value = MAX_EID;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
|
|
@ -313,8 +313,12 @@ namespace SHADE
|
|||
/// <param name="label">Label used to identify this widget.</param>
|
||||
/// <param name="value">Reference to the variable to store the result.</param>
|
||||
/// <param name="isHovered>If set, stores the hover state of this widget.</param>
|
||||
/// <param name="alwaysNull>
|
||||
/// If set, the field displayed will always be blank regardless of specified
|
||||
/// GameObject.
|
||||
/// </param>
|
||||
/// <returns>True if the value was changed.</returns>
|
||||
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr);
|
||||
static bool InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered = nullptr, bool alwaysNull = false);
|
||||
/// <summary>
|
||||
/// Creates a combo box for enumeration input.
|
||||
/// </summary>
|
||||
|
|
|
@ -290,9 +290,14 @@ namespace SHADE
|
|||
{
|
||||
GameObject gameObj = safe_cast<GameObject>(field->GetValue(object));
|
||||
uint32_t entityId = gameObj.GetEntity();
|
||||
if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered))
|
||||
if (SHEditorUI::InputGameObjectField(Convert::ToNative(field->Name), entityId, &isHovered, !gameObj))
|
||||
{
|
||||
GameObject newVal = GameObject(entityId);
|
||||
if (entityId != MAX_EID)
|
||||
{
|
||||
// Null GameObject set
|
||||
newVal = GameObject(entityId);
|
||||
}
|
||||
field->SetValue(object, newVal);
|
||||
registerUndoAction(object, field, newVal, gameObj);
|
||||
}
|
||||
|
|
|
@ -36,10 +36,12 @@ namespace SHADE
|
|||
|
||||
void GameObject::Destroy(GameObject obj)
|
||||
{
|
||||
if (!obj.valid)
|
||||
throw gcnew System::NullReferenceException("Attempted to destroy a null GameObject.");
|
||||
SHEntityManager::DestroyEntity(static_cast<EntityID>(obj.GetEntity()));
|
||||
}
|
||||
|
||||
System::Nullable<GameObject> GameObject::Find(System::String ^ name)
|
||||
System::Nullable<GameObject> GameObject::Find(System::String^ name)
|
||||
{
|
||||
// Search the GameObjectLibrary for an Entity with the specified name
|
||||
const auto ENTITY_ID = SHEntityManager::GetEntityByName(Convert::ToNative(name));
|
||||
|
@ -56,15 +58,21 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
System::String^ GameObject::Name::get()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return Convert::ToCLI(GetNativeEntity().name);
|
||||
|
||||
}
|
||||
bool GameObject::IsActiveSelf::get()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return GetNativeEntity().GetActive();
|
||||
}
|
||||
bool GameObject::IsActiveInHierarchy::get()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
auto node = SHSceneManager::GetCurrentSceneGraph().GetNode(GetEntity());
|
||||
if (!node)
|
||||
{
|
||||
|
@ -75,28 +83,34 @@ namespace SHADE
|
|||
}
|
||||
Entity GameObject::EntityId::get()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return entity;
|
||||
}
|
||||
GameObject^ GameObject::Parent::get()
|
||||
{
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
const auto* ROOT = SCENE_GRAPH.GetRoot();
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
const auto* ROOT = SCENE_GRAPH.GetRoot();
|
||||
|
||||
const auto* NODE = SCENE_GRAPH.GetNode(entity);
|
||||
if (NODE == nullptr)
|
||||
throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString());
|
||||
const auto* NODE = SCENE_GRAPH.GetNode(entity);
|
||||
if (NODE == nullptr)
|
||||
throw gcnew System::InvalidOperationException("Unable to retrieve SceneGraphNode for Entity " + entity.ToString());
|
||||
|
||||
const auto* PARENT = NODE->GetParent();
|
||||
return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr;
|
||||
const auto* PARENT = NODE->GetParent();
|
||||
return PARENT != ROOT ? gcnew GameObject(PARENT->GetEntityID()) : nullptr;
|
||||
}
|
||||
void GameObject::Parent::set(GameObject^ newParent)
|
||||
{
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
const auto& SCENE_GRAPH = SHSceneManager::GetCurrentSceneGraph();
|
||||
|
||||
if (newParent == nullptr)
|
||||
SCENE_GRAPH.SetParent(entity, nullptr);
|
||||
else
|
||||
SCENE_GRAPH.SetParent(entity, newParent->EntityId);
|
||||
if (newParent == nullptr)
|
||||
SCENE_GRAPH.SetParent(entity, nullptr);
|
||||
else
|
||||
SCENE_GRAPH.SetParent(entity, newParent->EntityId);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -104,10 +118,14 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
void GameObject::SetName(System::String^ name)
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
GetNativeEntity().name = Convert::ToNative(name);
|
||||
}
|
||||
void GameObject::SetActive(bool active)
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
GetNativeEntity().SetActive(active);
|
||||
}
|
||||
|
||||
|
@ -117,30 +135,40 @@ namespace SHADE
|
|||
generic <typename T>
|
||||
T GameObject::AddComponent()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return ECS::AddComponent<T>(entity);
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
T GameObject::GetComponent()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return ECS::GetComponent<T>(entity);
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
T GameObject::GetComponentInChildren()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return ECS::GetComponentInChildren<T>(entity);
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
T GameObject::EnsureComponent()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return ECS::EnsureComponent<T>(entity);
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
void GameObject::RemoveComponent()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
ECS::RemoveComponent<T>(entity);
|
||||
}
|
||||
|
||||
|
@ -150,30 +178,40 @@ namespace SHADE
|
|||
generic <typename T>
|
||||
T GameObject::AddScript()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return ScriptStore::AddScript<T>(entity);
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
T GameObject::GetScript()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return ScriptStore::GetScript<T>(entity);
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
T GameObject::GetScriptInChildren()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return ScriptStore::GetScriptInChildren<T>(entity);
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
System::Collections::Generic::IEnumerable<T>^ GameObject::GetScripts()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
return ScriptStore::GetScripts<T>(entity);
|
||||
}
|
||||
|
||||
generic <typename T>
|
||||
void GameObject::RemoveScript()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
ScriptStore::RemoveScript<T>(entity);
|
||||
}
|
||||
|
||||
|
@ -181,13 +219,15 @@ namespace SHADE
|
|||
/* Constructors */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
GameObject::GameObject(const SHEntity& entity)
|
||||
: entity { entity.GetEID() }
|
||||
, children{ gcnew System::Collections::ArrayList }
|
||||
: entity{ entity.GetEID() }
|
||||
, children{ gcnew System::Collections::ArrayList }
|
||||
, valid{ true }
|
||||
{}
|
||||
|
||||
GameObject::GameObject(Entity entity)
|
||||
: entity { entity }
|
||||
, children{ gcnew System::Collections::ArrayList }
|
||||
: entity{ entity }
|
||||
, children{ gcnew System::Collections::ArrayList }
|
||||
, valid{ true }
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
@ -195,6 +235,8 @@ namespace SHADE
|
|||
/*---------------------------------------------------------------------------------*/
|
||||
SHEntity& GameObject::GetNativeEntity()
|
||||
{
|
||||
if (!valid)
|
||||
throw gcnew System::NullReferenceException();
|
||||
SHEntity* nativeEntity = SHEntityManager::GetEntityByID(entity);
|
||||
if (nativeEntity == nullptr)
|
||||
throw gcnew System::InvalidOperationException("[GameObject] Unable to obtain native Entity for GameObject.");
|
||||
|
@ -202,12 +244,20 @@ namespace SHADE
|
|||
return *nativeEntity;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
GameObject::operator bool(GameObject gameObj)
|
||||
{
|
||||
return gameObj.valid;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* IEquatable */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
bool GameObject::Equals(GameObject other)
|
||||
{
|
||||
return entity == other.entity;
|
||||
return (!valid && !other.valid) || entity == other.entity;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -29,8 +29,8 @@ namespace SHADE
|
|||
/* Class Definitions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Lightweight object for an PlushieEngine Entity that allows for easy access
|
||||
/// to Component and Script operations.
|
||||
/// Lightweight object for an Entity that allows for easy access to Component and
|
||||
/// Script operations.
|
||||
/// </summary>
|
||||
public value class GameObject : public System::IEquatable<GameObject>
|
||||
{
|
||||
|
@ -98,8 +98,8 @@ namespace SHADE
|
|||
/// </summary>
|
||||
property GameObject^ Parent
|
||||
{
|
||||
GameObject^ get();
|
||||
void set(GameObject^);
|
||||
GameObject^ get();
|
||||
void set(GameObject^);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
@ -247,12 +247,22 @@ namespace SHADE
|
|||
/// <returns>Native Entity object that this GameObject represents.</returns>
|
||||
SHEntity& GetNativeEntity();
|
||||
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Operator Overloads */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/// <summary>
|
||||
/// Implicit conversion operator to enable checking if a GameObject is valid.
|
||||
/// </summary>
|
||||
/// <param name="gameObj">GameObjects to check.</param>
|
||||
static operator bool(GameObject gameObj);
|
||||
|
||||
private:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
Entity entity;
|
||||
System::Collections::ArrayList^ children;
|
||||
bool valid;
|
||||
|
||||
public:
|
||||
/*-----------------------------------------------------------------------------*/
|
||||
|
|
|
@ -171,7 +171,7 @@ namespace SHADE
|
|||
else if (fieldInfo->FieldType == GameObject::typeid)
|
||||
{
|
||||
GameObject gameObj = safe_cast<GameObject>(fieldInfo->GetValue(object));
|
||||
fieldNode = gameObj.GetEntity();
|
||||
fieldNode = gameObj ? gameObj.GetEntity() : MAX_EID;
|
||||
}
|
||||
else // Not any of the supported types
|
||||
{
|
||||
|
@ -250,7 +250,9 @@ namespace SHADE
|
|||
}
|
||||
else if (fieldInfo->FieldType == GameObject::typeid)
|
||||
{
|
||||
fieldInfo->SetValue(object, GameObject(node.as<uint32_t>()));
|
||||
const uint32_t EID = node.as<uint32_t>();
|
||||
fieldInfo->SetValue(object, EID == MAX_EID ? GameObject() : GameObject(EID));
|
||||
Debug::LogError(std::to_string(EID));
|
||||
}
|
||||
else // Not any of the supported types
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue