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
\date Nov 7, 2021
\brief Contains the implementation of the EditorUI class.
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.
*//*************************************************************************************/
// Precompiled Header
@ -57,10 +57,10 @@ namespace SHADE
{
const bool OPENED = ImGui::CollapsingHeader(title.c_str(), ImGuiTreeNodeFlags_DefaultOpen);
if (isHovered)
*isHovered = ImGui::IsItemHovered();
*isHovered = ImGui::IsItemHovered();
return OPENED;
}
void SHEditorUI::SameLine()
{
ImGui::SameLine();
@ -98,7 +98,7 @@ namespace SHADE
void SHEditorUI::EndTooltip()
{
ImGui::EndTooltip();
ImGui::EndTooltip();
}
/*-----------------------------------------------------------------------------------*/
@ -146,7 +146,7 @@ namespace SHADE
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)
@ -156,30 +156,41 @@ namespace SHADE
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)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
*isHovered = ImGui::IsItemHovered();
return ImGui::Checkbox("##", &value);
}
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)
*isHovered = ImGui::IsItemHovered();
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::DragInt("##", &value, 0.001f,
std::numeric_limits<int>::min(),
std::numeric_limits<int>::max(),
"%d",
ImGuiInputTextFlags_EnterReturnsTrue);
std::numeric_limits<int>::min(),
std::numeric_limits<int>::max(),
"%d",
ImGuiInputTextFlags_EnterReturnsTrue);
}
bool SHEditorUI::InputUnsignedInt(const std::string& label, unsigned int& value, bool* isHovered)
{
int signedVal = static_cast<int>(value);
ImGui::Text(label.c_str());
if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered)
*isHovered = ImGui::IsItemHovered();
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
const bool CHANGED = InputInt("##", signedVal);
if (CHANGED)
@ -191,15 +202,19 @@ namespace SHADE
}
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)
*isHovered = ImGui::IsItemHovered();
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::DragFloat("##", &value, 0.001f,
std::numeric_limits<float>::lowest(),
std::numeric_limits<float>::max(),
"%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
std::numeric_limits<float>::lowest(),
std::numeric_limits<float>::max(),
"%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
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*/)
{
if (!label.empty())
{
ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::SliderInt("##", &value,
static_cast<float>(min), static_cast<float>(max), "%d",
ImGuiInputTextFlags_EnterReturnsTrue);
}
if (isHovered)
*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*/)
{
int val = static_cast<int>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED)
{
value = static_cast<int>(val);
}
int val = static_cast<int>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED)
{
value = static_cast<int>(val);
}
return CHANGED;
return CHANGED;
}
bool SHEditorUI::InputSlider(const std::string& label, float min, float max, float& value, bool* isHovered)
{
if (!label.empty())
{
ImGui::Text(label.c_str());
if (isHovered)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
return ImGui::SliderFloat("##", &value,
static_cast<float>(min), static_cast<float>(max), "%.3f",
ImGuiInputTextFlags_EnterReturnsTrue);
}
if (isHovered)
*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*/)
{
float val = static_cast<float>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED)
{
value = static_cast<double>(val);
}
float val = static_cast<float>(value);
const bool CHANGED = InputSlider(label, min, max, val, isHovered);
if (CHANGED)
{
value = static_cast<double>(val);
}
return CHANGED;
return CHANGED;
}
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)
{
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);
}
@ -272,9 +295,13 @@ namespace SHADE
{
std::array<char, TEXT_FIELD_MAX_LENGTH> buffer = { '\0' };
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)
*isHovered = ImGui::IsItemHovered();
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
const bool CHANGED = ImGui::InputText("##", &buffer[0], TEXT_FIELD_MAX_LENGTH);
if (CHANGED)
@ -286,7 +313,11 @@ namespace SHADE
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)
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
@ -326,9 +357,13 @@ namespace SHADE
const std::string& INITIAL_NAME = v >= static_cast<int>(enumNames.size()) ? "Unknown" : enumNames[v];
bool b = false;
ImGui::Text(label.c_str());
if (!label.empty())
{
ImGui::Text(label.c_str());
ImGui::SameLine();
}
if (isHovered)
*isHovered = ImGui::IsItemHovered();
*isHovered = ImGui::IsItemHovered();
ImGui::SameLine();
if (ImGui::BeginCombo("##", INITIAL_NAME.c_str(), ImGuiComboFlags_None))
{

View File

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

View File

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

View File

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

View File

@ -22,6 +22,36 @@ of DigiPen Institute of Technology is prohibited.
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 */
/*---------------------------------------------------------------------------------*/
@ -104,11 +134,10 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
/* "All-time" Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
void Script::Initialize(GameObject newOwner)
void Script::Initialize(SHADE::GameObject newOwner)
{
owner = newOwner;
}
void Script::OnAttached()
{
SAFE_NATIVE_CALL_BEGIN
@ -131,6 +160,12 @@ namespace SHADE
awake();
SAFE_NATIVE_CALL_END(this)
}
void Script::OnEnable()
{
SAFE_NATIVE_CALL_BEGIN
onEnable();
SAFE_NATIVE_CALL_END(this)
}
void Script::Start()
{
SAFE_NATIVE_CALL_BEGIN
@ -162,6 +197,12 @@ namespace SHADE
onDrawGizmos();
SAFE_NATIVE_CALL_END(this)
}
void Script::OnDisable()
{
SAFE_NATIVE_CALL_BEGIN
onDisable();
SAFE_NATIVE_CALL_END(this)
}
void Script::OnDestroy()
{
SAFE_NATIVE_CALL_BEGIN
@ -228,6 +269,7 @@ namespace SHADE
/* Virtual Lifecycle Functions */
/*---------------------------------------------------------------------------------*/
void Script::awake() {}
void Script::onEnable() {}
void Script::start() {}
void Script::fixedUpdate() {}
void Script::update() {}
@ -236,6 +278,7 @@ namespace SHADE
{
OnGizmosDrawOverriden = false;
}
void Script::onDisable() {}
void Script::onDestroy() {}
/*---------------------------------------------------------------------------------*/

View File

@ -38,11 +38,28 @@ namespace SHADE
/* Properties */
/*-----------------------------------------------------------------------------*/
/// <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.
/// </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>
/// <typeparam name="T">
/// Type of script to get.
/// This needs to be a default constructable Script.
/// This needs to be a default constructible Script.
/// </typeparam>
/// <returns>Reference to the script added</returns>
generic<typename T> where T : ref class, Script
@ -206,7 +223,7 @@ namespace SHADE
/// <summary>
/// Used to initialize a Script with a GameObject.
/// </summary>
void Initialize(GameObject newOwner);
void Initialize(SHADE::GameObject newOwner);
/// <summary>
/// Used to call onAttached(). This is called immediately when this script is
/// attached to a GameObject.
@ -232,6 +249,11 @@ namespace SHADE
/// </summary>
void Start();
/// <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
/// update steps and thus in most cases will execute more than Update() will.
/// This will be called immediately before a Physics update step.
@ -253,6 +275,11 @@ namespace SHADE
/// </summary>
void OnDrawGizmos();
/// <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
/// where the attached GameObject or this script is destroyed directly or
/// indirectly due to destruction of the owner.
@ -329,6 +356,10 @@ namespace SHADE
/// </summary>
virtual void awake();
/// <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
/// after Awake().
/// </summary>
@ -353,6 +384,10 @@ namespace SHADE
/// </summary>
virtual void onDrawGizmos();
/// <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
/// this script is destroyed directly or indirectly due to destruction of the
/// owner.
@ -403,7 +438,8 @@ namespace SHADE
/*-----------------------------------------------------------------------------*/
/* Data Members */
/*-----------------------------------------------------------------------------*/
GameObject owner;
SHADE::GameObject owner;
bool enabled = true;
};
}

View File

@ -528,7 +528,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value;
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")
@ -546,7 +547,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value;
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")
@ -564,7 +566,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value;
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")
@ -583,7 +586,8 @@ namespace SHADE
ScriptList^ scripts = entity.Value;
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")