Added GameObject.Null and Enabling/Disabling of Scripts #236

Merged
Pycorax merged 2 commits from SP3-6-c-scripting into main 2022-11-21 20:21:48 +08:00
7 changed files with 207 additions and 64 deletions

View File

@ -4,9 +4,9 @@
\par email: kahwei.tng\@digipen.edu \par email: kahwei.tng\@digipen.edu
\date Nov 7, 2021 \date Nov 7, 2021
\brief Contains the implementation of the EditorUI class. \brief Contains the implementation of the EditorUI class.
Copyright (C) 2021 DigiPen Institute of Technology. Copyright (C) 2021 DigiPen Institute of Technology.
Reproduction or disclosure of this file or its contents without the prior written consent Reproduction or disclosure of this file or its contents without the prior written consent
of DigiPen Institute of Technology is prohibited. of DigiPen Institute of Technology is prohibited.
*//*************************************************************************************/ *//*************************************************************************************/
// Precompiled Header // Precompiled Header
@ -57,10 +57,10 @@ namespace SHADE
{ {
const bool OPENED = ImGui::CollapsingHeader(title.c_str(), ImGuiTreeNodeFlags_DefaultOpen); const bool OPENED = ImGui::CollapsingHeader(title.c_str(), ImGuiTreeNodeFlags_DefaultOpen);
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
return OPENED; return OPENED;
} }
void SHEditorUI::SameLine() void SHEditorUI::SameLine()
{ {
ImGui::SameLine(); ImGui::SameLine();
@ -98,7 +98,7 @@ namespace SHADE
void SHEditorUI::EndTooltip() void SHEditorUI::EndTooltip()
{ {
ImGui::EndTooltip(); ImGui::EndTooltip();
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
@ -146,7 +146,7 @@ namespace SHADE
bool SHEditorUI::Selectable(const std::string& label) bool SHEditorUI::Selectable(const std::string& label)
{ {
return ImGui::Selectable(label.data()); return ImGui::Selectable(label.data());
} }
bool SHEditorUI::Selectable(const std::string& label, const char* icon) bool SHEditorUI::Selectable(const std::string& label, const char* icon)
@ -156,30 +156,41 @@ namespace SHADE
bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered) bool SHEditorUI::InputCheckbox(const std::string& label, bool& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::Checkbox("##", &value); return ImGui::Checkbox("##", &value);
} }
bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered) bool SHEditorUI::InputInt(const std::string& label, int& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::DragInt("##", &value, 0.001f, return ImGui::DragInt("##", &value, 0.001f,
std::numeric_limits<int>::min(), std::numeric_limits<int>::min(),
std::numeric_limits<int>::max(), std::numeric_limits<int>::max(),
"%d", "%d",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered) bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
{ {
int signedVal = static_cast<int>(value); int signedVal = static_cast<int>(value);
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
const bool CHANGED = InputInt("##", signedVal); const bool CHANGED = InputInt("##", signedVal);
if (CHANGED) if (CHANGED)
@ -191,15 +202,19 @@ namespace SHADE
} }
bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered) bool SHEditorUI::InputFloat(const std::string& label, float& value, bool* isHovered)
{ {
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::DragFloat("##", &value, 0.001f, return ImGui::DragFloat("##", &value, 0.001f,
std::numeric_limits<float>::lowest(), std::numeric_limits<float>::lowest(),
std::numeric_limits<float>::max(), std::numeric_limits<float>::max(),
"%.3f", "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue); ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered) bool SHEditorUI::InputDouble(const std::string& label, double& value, bool* isHovered)
{ {
@ -213,48 +228,56 @@ namespace SHADE
} }
bool SHEditorUI::InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered /*= nullptr*/) bool SHEditorUI::InputSlider(const std::string& label, int min, int max, int& value, bool* isHovered /*= nullptr*/)
{ {
if (!label.empty())
{
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::SliderInt("##", &value, }
static_cast<float>(min), static_cast<float>(max), "%d", if (isHovered)
ImGuiInputTextFlags_EnterReturnsTrue); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::SliderInt("##", &value,
static_cast<float>(min), static_cast<float>(max), "%d",
ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered /*= nullptr*/) bool SHEditorUI::InputSlider(const std::string& label, unsigned int min, unsigned int max, unsigned int& value, bool* isHovered /*= nullptr*/)
{ {
int val = static_cast<int>(value); int val = static_cast<int>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered); const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED) if (CHANGED)
{ {
value = static_cast<int>(val); value = static_cast<int>(val);
} }
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered) bool SHEditorUI::InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered)
{ {
if (!label.empty())
{
ImGui::Text(label.c_str()); ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
return ImGui::SliderFloat("##", &value, }
static_cast<float>(min), static_cast<float>(max), "%.3f", if (isHovered)
ImGuiInputTextFlags_EnterReturnsTrue); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::SliderFloat("##", &value,
static_cast<float>(min), static_cast<float>(max), "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
} }
bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered /*= nullptr*/) bool SHEditorUI::InputSlider(const std::string& label, double min, double max, double& value, bool* isHovered /*= nullptr*/)
{ {
float val = static_cast<float>(value); float val = static_cast<float>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered); const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED) if (CHANGED)
{ {
value = static_cast<double>(val); value = static_cast<double>(val);
} }
return CHANGED; return CHANGED;
} }
bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered) bool SHEditorUI::InputVec2(const std::string& label, SHVec2& value, bool* isHovered)
@ -264,7 +287,7 @@ namespace SHADE
} }
bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered) bool SHEditorUI::InputVec3(const std::string& label, SHVec3& value, bool* isHovered)
{ {
static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z"}; static const std::vector<std::string> COMPONENT_LABELS = { "X", "Y", "Z" };
return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, 0.1f, "%.3f", float{}, float{}, 0, isHovered); return SHEditorWidgets::DragN<float, 3>(label, COMPONENT_LABELS, { &value.x, &value.y, &value.z }, 0.1f, "%.3f", float{}, float{}, 0, isHovered);
} }
@ -272,9 +295,13 @@ namespace SHADE
{ {
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' }; std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str()); strcpy_s(buffer.data(), TEXT_FIELD_MAX_LENGTH, value.c_str());
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH); const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH);
if (CHANGED) if (CHANGED)
@ -286,7 +313,11 @@ namespace SHADE
bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull) bool SHEditorUI::InputGameObjectField(const std::string& label, uint32_t& value, bool* isHovered, bool alwaysNull)
{ {
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
@ -326,9 +357,13 @@ namespace SHADE
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v]; const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
bool b = false; bool b = false;
ImGui::Text(label.c_str()); if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered) if (isHovered)
*isHovered = ImGui::IsItemHovered(); *isHovered = ImGui::IsItemHovered();
ImGui::SameLine(); ImGui::SameLine();
if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None)) if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
{ {

View File

@ -117,6 +117,12 @@ namespace SHADE
// Header // Header
SHEditorUI::PushID(index); SHEditorUI::PushID(index);
bool enabled = script->Enabled;
if (SHEditorUI::InputCheckbox("", enabled))
{
script->Enabled = enabled;
}
SHEditorUI::SameLine();
if (SHEditorUI::CollapsingHeader(LABEL)) if (SHEditorUI::CollapsingHeader(LABEL))
{ {
SHEditorUI::PushID(LABEL); SHEditorUI::PushID(LABEL);

View File

@ -54,6 +54,14 @@ namespace SHADE
return GameObject(ENTITY_ID); return GameObject(ENTITY_ID);
} }
/*---------------------------------------------------------------------------------*/
/* Static Properties */
/*---------------------------------------------------------------------------------*/
GameObject GameObject::Null::get()
{
return GameObject();
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Properties */ /* Properties */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -62,6 +62,17 @@ namespace SHADE
/// <returns>GameObject that has the specified name. Null if not found.</returns> /// <returns>GameObject that has the specified name. Null if not found.</returns>
static System::Nullable<GameObject> Find(System::String^ name); static System::Nullable<GameObject> Find(System::String^ name);
/*-----------------------------------------------------------------------------*/
/* Static Properties */
/*-----------------------------------------------------------------------------*/
/// <summary>
/// Default empty GameObject.
/// </summary>
static property GameObject Null
{
GameObject get();
}
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Properties */ /* Properties */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -22,6 +22,36 @@ of DigiPen Institute of Technology is prohibited.
namespace SHADE namespace SHADE
{ {
/*---------------------------------------------------------------------------------*/
/* Properties */
/*---------------------------------------------------------------------------------*/
GameObject Script::Owner::get()
{
return owner;
}
GameObject Script::GameObject::get()
{
return owner;
}
bool Script::Enabled::get()
{
return enabled;
}
void Script::Enabled::set(bool value)
{
// Same, don't set
if (value == enabled)
return;
enabled = value;
// There's a change, so call the appropriate function
if (enabled)
OnEnable();
else
OnDisable();
}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Component Access Functions */ /* Component Access Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -104,11 +134,10 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* "All-time" Lifecycle Functions */ /* "All-time" Lifecycle Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Script::Initialize(GameObject newOwner) void Script::Initialize(SHADE::GameObject newOwner)
{ {
owner = newOwner; owner = newOwner;
} }
void Script::OnAttached() void Script::OnAttached()
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
@ -131,6 +160,12 @@ namespace SHADE
awake(); awake();
SAFE_NATIVE_CALL_END(this) SAFE_NATIVE_CALL_END(this)
} }
void Script::OnEnable()
{
SAFE_NATIVE_CALL_BEGIN
onEnable();
SAFE_NATIVE_CALL_END(this)
}
void Script::Start() void Script::Start()
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
@ -162,6 +197,12 @@ namespace SHADE
onDrawGizmos(); onDrawGizmos();
SAFE_NATIVE_CALL_END(this) SAFE_NATIVE_CALL_END(this)
} }
void Script::OnDisable()
{
SAFE_NATIVE_CALL_BEGIN
onDisable();
SAFE_NATIVE_CALL_END(this)
}
void Script::OnDestroy() void Script::OnDestroy()
{ {
SAFE_NATIVE_CALL_BEGIN SAFE_NATIVE_CALL_BEGIN
@ -228,6 +269,7 @@ namespace SHADE
/* Virtual Lifecycle Functions */ /* Virtual Lifecycle Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
void Script::awake() {} void Script::awake() {}
void Script::onEnable() {}
void Script::start() {} void Script::start() {}
void Script::fixedUpdate() {} void Script::fixedUpdate() {}
void Script::update() {} void Script::update() {}
@ -236,6 +278,7 @@ namespace SHADE
{ {
OnGizmosDrawOverriden = false; OnGizmosDrawOverriden = false;
} }
void Script::onDisable() {}
void Script::onDestroy() {} void Script::onDestroy() {}
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/

View File

@ -38,11 +38,28 @@ namespace SHADE
/* Properties */ /* Properties */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// GameObject that this Script belongs to. This is a legacy interface, use
/// GameObject instead.
/// </summary>
[System::ObsoleteAttribute("Use GameObject instead.", false)]
property SHADE::GameObject Owner
{
SHADE::GameObject get();
}
/// <summary>
/// GameObject that this Script belongs to. /// GameObject that this Script belongs to.
/// </summary> /// </summary>
property GameObject Owner property SHADE::GameObject GameObject
{ {
GameObject get() { return owner; } SHADE::GameObject get();
}
/// <summary>
/// Whether or not this Script should have it's update functions be executed.
/// </summary>
property bool Enabled
{
bool get();
void set(bool value);
} }
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@ -127,7 +144,7 @@ namespace SHADE
/// </summary> /// </summary>
/// <typeparam name="T"> /// <typeparam name="T">
/// Type of script to get. /// Type of script to get.
/// This needs to be a default constructable Script. /// This needs to be a default constructible Script.
/// </typeparam> /// </typeparam>
/// <returns>Reference to the script added</returns> /// <returns>Reference to the script added</returns>
generic<typename T> where T : ref class, Script generic<typename T> where T : ref class, Script
@ -206,7 +223,7 @@ namespace SHADE
/// <summary> /// <summary>
/// Used to initialize a Script with a GameObject. /// Used to initialize a Script with a GameObject.
/// </summary> /// </summary>
void Initialize(GameObject newOwner); void Initialize(SHADE::GameObject newOwner);
/// <summary> /// <summary>
/// Used to call onAttached(). This is called immediately when this script is /// Used to call onAttached(). This is called immediately when this script is
/// attached to a GameObject. /// attached to a GameObject.
@ -232,6 +249,11 @@ namespace SHADE
/// </summary> /// </summary>
void Start(); void Start();
/// <summary> /// <summary>
/// Used to call onEnable. This should be called right when a script is enabled
/// directly.
/// </summary>
void OnEnable();
/// <summary>
/// Used to call fixedUpdate(). This should be called in sync with Physics /// Used to call fixedUpdate(). This should be called in sync with Physics
/// update steps and thus in most cases will execute more than Update() will. /// update steps and thus in most cases will execute more than Update() will.
/// This will be called immediately before a Physics update step. /// This will be called immediately before a Physics update step.
@ -253,6 +275,11 @@ namespace SHADE
/// </summary> /// </summary>
void OnDrawGizmos(); void OnDrawGizmos();
/// <summary> /// <summary>
/// Used to call onDisable. This should be called right when a script is disabled
/// directly.
/// </summary>
void OnDisable();
/// <summary>
/// Used to call onDestroy(). This should be called at the end of the frame /// Used to call onDestroy(). This should be called at the end of the frame
/// where the attached GameObject or this script is destroyed directly or /// where the attached GameObject or this script is destroyed directly or
/// indirectly due to destruction of the owner. /// indirectly due to destruction of the owner.
@ -329,6 +356,10 @@ namespace SHADE
/// </summary> /// </summary>
virtual void awake(); virtual void awake();
/// <summary> /// <summary>
/// Called when this script is enabled.
/// </summary>
virtual void onEnable();
/// <summary>
/// Called on the first frame that the attached GameObject is active but always /// Called on the first frame that the attached GameObject is active but always
/// after Awake(). /// after Awake().
/// </summary> /// </summary>
@ -353,6 +384,10 @@ namespace SHADE
/// </summary> /// </summary>
virtual void onDrawGizmos(); virtual void onDrawGizmos();
/// <summary> /// <summary>
/// Called when this script is disabled.
/// </summary>
virtual void onDisable();
/// <summary>
/// Called just before the end of the frame where the attached GameObject or /// Called just before the end of the frame where the attached GameObject or
/// this script is destroyed directly or indirectly due to destruction of the /// this script is destroyed directly or indirectly due to destruction of the
/// owner. /// owner.
@ -403,7 +438,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
/* Data Members */ /* Data Members */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
GameObject owner; SHADE::GameObject owner;
bool enabled = true;
}; };
} }

View File

@ -528,7 +528,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value; ScriptList^ scripts = entity.Value;
for (int i = 0; i < scripts->Count; ++i) for (int i = 0; i < scripts->Count; ++i)
{ {
scripts[i]->FixedUpdate(); if (scripts[i]->Enabled)
scripts[i]->FixedUpdate();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
@ -546,7 +547,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value; ScriptList^ scripts = entity.Value;
for (int i = 0; i < scripts->Count; ++i) for (int i = 0; i < scripts->Count; ++i)
{ {
scripts[i]->Update(); if (scripts[i]->Enabled)
scripts[i]->Update();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
@ -564,7 +566,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value; ScriptList^ scripts = entity.Value;
for (int i = 0; i < scripts->Count; ++i) for (int i = 0; i < scripts->Count; ++i)
{ {
scripts[i]->LateUpdate(); if (scripts[i]->Enabled)
scripts[i]->LateUpdate();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")
@ -583,7 +586,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value; ScriptList^ scripts = entity.Value;
for (int i = 0; i < scripts->Count; ++i) for (int i = 0; i < scripts->Count; ++i)
{ {
scripts[i]->OnDrawGizmos(); if (scripts[i]->Enabled)
scripts[i]->OnDrawGizmos();
} }
} }
SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore") SAFE_NATIVE_CALL_END_N("SHADE_Managed.ScriptStore")