Partial Entity Exposed field implementation

This commit is contained in:
Antoine Pilote
2024-08-13 23:54:51 -04:00
parent 318b646d61
commit 9b9f5d111d
6 changed files with 117 additions and 17 deletions

View File

@@ -208,6 +208,41 @@ void NetScriptPanel::Draw(Nuake::Entity entity)
field.Value = currentValue;
}
if (field.Type == Nuake::NetScriptExposedVarType::Entity)
{
if (!field.Value.has_value())
{
field.Value = field.DefaultValue;
}
int entityId = std::any_cast<int>(field.Value);
auto entity = Nuake::Engine::GetCurrentScene()->GetEntityByID(entityId);
bool invalid = !entity.IsValid();
std::string buttonLabel;
if (invalid)
{
buttonLabel = "Invalid Entity*";
}
else
{
buttonLabel = entity.GetComponent<Nuake::NameComponent>().Name;
}
ImGui::Button(buttonLabel.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0));
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("ENTITY"))
{
Nuake::Entity payload_entity = *(const Nuake::Entity*)payload->Data;
field.Value = payload_entity.GetID();
}
ImGui::EndDragDropTarget();
}
}
ImGui::TableNextColumn();
}
}

View File

@@ -139,7 +139,6 @@ namespace Nuake {
Overlay();
ImGuizmo::BeginFrame();
ImGuizmo::SetOrthographic(false);
ImVec2 regionAvail = ImGui::GetContentRegionAvail();
@@ -321,7 +320,7 @@ namespace Nuake {
if (!Engine::IsPlayMode() && ImGui::GetIO().WantCaptureMouse && m_IsHoveringViewport && Input::IsMouseButtonPressed(GLFW_MOUSE_BUTTON_1) && !ImGuizmo::IsUsing() && m_IsViewportFocused)
{
const auto windowPosNuake = Vector2(windowPos.x, windowPos.y);
auto& gbuffer = Engine::GetCurrentScene()->m_SceneRenderer->GetGBuffer();
auto pixelPos = Input::GetMousePosition() - windowPosNuake;
@@ -367,6 +366,8 @@ namespace Nuake {
}
ImGui::End();
}
void EditorInterface::DrawStatusBar()
@@ -671,15 +672,17 @@ namespace Nuake {
bool open = ImGui::TreeNodeEx(name.c_str(), base_flags);
if(nameComponent.IsPrefab && e.HasComponent<PrefabComponent>())
bool isDragging = false;
if (nameComponent.IsPrefab && e.HasComponent<PrefabComponent>())
{
ImGui::PopStyleColor();
else
if (ImGui::BeginDragDropSource())
{
ImGui::SetDragDropPayload("ENTITY", (void*)&e, sizeof(Entity));
ImGui::Text(name.c_str());
ImGui::EndDragDropSource();
}
}
else if (ImGui::BeginDragDropSource())
{
ImGui::SetDragDropPayload("ENTITY", (void*)&e, sizeof(Entity));
ImGui::Text(name.c_str());
ImGui::EndDragDropSource();
}
if (ImGui::BeginDragDropTarget())
{
@@ -706,7 +709,7 @@ namespace Nuake {
ImGui::EndDragDropTarget();
}
if (ImGui::IsItemClicked())
if (!isDragging && ImGui::IsItemHovered() && ImGui::IsMouseReleased(0))
Selection = EditorSelection(e);
if (ImGui::BeginPopupContextItem())
@@ -1785,7 +1788,7 @@ namespace Nuake {
}
ImGui::End();
std::string title = ICON_FA_TREE + std::string(" Hierarchy");
std::string title = ICON_FA_TREE + std::string(" Hierarchy");
if (ImGui::Begin(title.c_str()))
{
std::string searchQuery = "";

View File

@@ -95,6 +95,15 @@ namespace Nuake {
varJ["DefaultValue"][2] = value.z;
break;
}
case NetScriptExposedVarType::Entity:
{
int value = std::any_cast<int>(e.Value);
varJ["Value"] = value;
value = std::any_cast<int>(e.DefaultValue);
varJ["DefaultValue"] = value;
break;
}
default:
varJ["Value"] = 0;
break;
@@ -150,12 +159,10 @@ namespace Nuake {
{
float x = exposedVarJson["Value"][0];
float y = exposedVarJson["Value"][1];
exposedVar.Value = Vector2(x, y);
x = exposedVarJson["DefaultValue"][0];
y = exposedVarJson["DefaultValue"][1];
exposedVar.DefaultValue = Vector2(x, y);
break;
}
@@ -170,6 +177,16 @@ namespace Nuake {
y = exposedVarJson["DefaultValue"][1];
z = exposedVarJson["DefaultValue"][2];
exposedVar.DefaultValue = Vector3(x, y, z);
break;
}
case NetScriptExposedVarType::Entity:
{
int x = exposedVarJson["Value"];
exposedVar.Value = x;
x = exposedVarJson["DefaultValue"];
exposedVar.DefaultValue = x;
break;
}
default:
exposedVar.DefaultValue = 0;

View File

@@ -181,6 +181,8 @@ namespace Nuake
const std::string baseTypeName = std::string(type->GetBaseType().GetFullName());
if (baseTypeName == "Nuake.Net.Entity")
{
m_BaseEntityType = type->GetBaseType();
auto typeSplits = String::Split(type->GetFullName(), '.');
std::string shortenedTypeName = typeSplits[typeSplits.size() - 1];
@@ -223,6 +225,10 @@ namespace Nuake
{
varType = ExposedVarTypes::Vector3;
}
else if (typeName == "Nuake.Net.Entity")
{
varType = ExposedVarTypes::Entity;
}
if (varType != ExposedVarTypes::Unsupported)
{
@@ -323,12 +329,20 @@ namespace Nuake
}
case ExposedVarTypes::Entity:
{
exposedVar.Value = classInstance.GetFieldValue<int>(varName);
struct EntityWrapper
{
int32_t id;
int32_t handle;
};
exposedVar.Value = classInstance.GetFieldValue<EntityWrapper>(varName).id;
break;
}
}
}
m_EntityToManagedObjects.emplace(entity.GetID(), classInstance);
// Override with user values set in the editor.
for (auto& exposedVarUserValue : component.ExposedVar)
{
@@ -338,13 +352,39 @@ namespace Nuake
Coral::String coralString = Coral::String::New(stringValue);
classInstance.SetFieldValue(exposedVarUserValue.Name, coralString);
}
else if (exposedVarUserValue.Type == NetScriptExposedVarType::Entity)
{
int entityId = std::any_cast<int>(exposedVarUserValue.Value);
Entity scriptEntity = entity.GetScene()->GetEntityByID(entityId);
if (scriptEntity.IsValid())
{
if (HasEntityScriptInstance(scriptEntity))
{
// In the case the entity has a script & instance, we pass that.
// This gives access to the objects scripts.
auto scriptInstance = GetEntityScript(scriptEntity);
classInstance.SetFieldValue<Coral::ManagedObject>(exposedVarUserValue.Name, scriptInstance);
}
else
{
// In the case where the entity doesnt have an instance, we create one
auto newEntity = m_BaseEntityType.CreateInstance();
newEntity.SetPropertyValue("ECSHandle", scriptEntity.GetHandle());
newEntity.SetPropertyValue("ID", scriptEntity.GetID());
classInstance.SetFieldValue<Coral::ManagedObject>(exposedVarUserValue.Name, newEntity);
}
}
else
{
Logger::Log("Invalid entity exposed variable set", ".net", CRITICAL);
}
}
else
{
classInstance.SetFieldValue(exposedVarUserValue.Name, exposedVarUserValue.Value);
}
}
m_EntityToManagedObjects.emplace(entity.GetID(), classInstance);
}
Coral::ManagedObject ScriptingEngineNet::GetEntityScript(const Entity& entity)

View File

@@ -51,6 +51,7 @@ namespace Nuake {
const std::string m_NetDirectory = ".net";
const std::string m_ContextName = "NuakeEngineContext";
Coral::Type m_BaseEntityType;
bool m_IsInitialized = false;
Coral::HostInstance* m_HostInstance;

View File

@@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
@@ -17,6 +18,7 @@ namespace Nuake.Net
Vector3 Position;
}
[StructLayout(LayoutKind.Sequential)]
public class Entity
{
internal static unsafe delegate*<int, int, bool> EntityHasComponentIcall;
@@ -49,8 +51,10 @@ namespace Nuake.Net
NAVMESH
}
public int ID { get; set; }
public int ECSHandle { get; set; }
public virtual void OnInit() { }
public virtual void OnUpdate(float dt) { }
public virtual void OnFixedUpdate(float dt) { }