Added new Prefab C# type

This commit is contained in:
Antoine Pilote
2024-08-15 22:24:26 -04:00
parent 04926476d7
commit 58a179be4f
8 changed files with 181 additions and 14 deletions

View File

@@ -252,6 +252,59 @@ void NetScriptPanel::Draw(Nuake::Entity entity)
}
if (field.Type == Nuake::NetScriptExposedVarType::Prefab)
{
if (!field.Value.has_value() && field.DefaultValue.has_value())
{
field.Value = field.DefaultValue;
}
std::string prefabPath = "";
if (field.Value.has_value())
{
prefabPath = std::any_cast<std::string>(field.Value);
}
std::string buttonLabel;
if (!Nuake::FileSystem::FileExists(prefabPath))
{
buttonLabel = "File doesn't exist";
}
else if (prefabPath.empty())
{
buttonLabel = "Empty";
}
else
{
buttonLabel = prefabPath;
}
if (ImGui::Button(buttonLabel.c_str(), ImVec2(ImGui::GetContentRegionAvail().x, 0)))
{
const std::string& newPath = Nuake::FileDialog::OpenFile("Prefab file\0*.prefab");
const std::string& relativePath = Nuake::FileSystem::AbsoluteToRelative(newPath);
if (Nuake::FileSystem::FileExists(relativePath))
{
field.Value = relativePath;
}
}
if (ImGui::BeginDragDropTarget())
{
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Prefab"))
{
char* file = (char*)payload->Data;
const std::string filePath = Nuake::FileSystem::AbsoluteToRelative(std::string(file, 512));
if (Nuake::FileSystem::FileExists(filePath))
{
field.Value = filePath;
}
}
ImGui::EndDragDropTarget();
}
}
ImGui::TableNextColumn();
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(1, 1, 1, 0));

View File

@@ -16,6 +16,7 @@ namespace Nuake {
Double,
String,
Entity,
Prefab,
Vector2,
Vector3,
Vector4
@@ -71,6 +72,21 @@ namespace Nuake {
varJ["Value"] = std::any_cast<std::string>(e.Value);
varJ["DefaultValue"] = std::any_cast<std::string>(e.DefaultValue);
break;
case NetScriptExposedVarType::Prefab:
{
if (e.Value.has_value())
{
varJ["Value"] = std::any_cast<std::string>(e.Value);
varJ["DefaultValue"] = std::any_cast<std::string>(e.DefaultValue);
}
else
{
varJ["Value"] = "";
varJ["DefaultValue"] = "";
}
break;
}
case NetScriptExposedVarType::Vector2:
{
Vector2 value = std::any_cast<Vector2>(e.Value);
@@ -97,13 +113,17 @@ namespace Nuake {
}
case NetScriptExposedVarType::Entity:
{
int value = std::any_cast<int>(e.Value);
int value = -1;
if (e.Value.has_value())
{
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;
@@ -151,6 +171,12 @@ namespace Nuake {
exposedVar.Value = (double)exposedVarJson["Value"];
exposedVar.DefaultValue = (double)exposedVarJson["DefaultValue"];
break;
case NetScriptExposedVarType::Prefab:
{
exposedVar.Value = (std::string)exposedVarJson["Value"];
exposedVar.DefaultValue = (std::string)exposedVarJson["DefaultValue"];
break;
}
case NetScriptExposedVarType::String:
exposedVar.Value = (std::string)exposedVarJson["Value"];
exposedVar.DefaultValue = (std::string)exposedVarJson["DefaultValue"];

View File

@@ -24,11 +24,6 @@ namespace Nuake
{
void Entity::AddChild(Entity ent)
{
if(!IsValid())
{
return;
}
if ((int)m_EntityHandle != ent.GetHandle())
{
ent.GetComponent<ParentComponent>().HasParent = true;

View File

@@ -122,7 +122,7 @@ namespace Nuake
}
}
Entity currentEntity;
Entity currentEntity = Entity({(entt::entity)-1, this});
uint32_t currentSplitIndex = 1;
while (currentSplitIndex < splits.size())
{
@@ -145,6 +145,12 @@ namespace Nuake
}
}
// Not found
if (!currentEntity.IsValid())
{
return Entity({(entt::entity)-1, this});
}
// Then look through child of root entity
for (auto& child : currentEntity.GetComponent<ParentComponent>().Children)
{
@@ -571,11 +577,7 @@ namespace Nuake
auto entity = Entity{ e, this };
auto parentEntity = GetEntityByID(parentComponent.ParentID);
if (entity.IsValid())
{
parentEntity.AddChild(entity);
}
parentEntity.AddChild(entity);
}
// This will turn the deserialized entity ids into actual Entities.

View File

@@ -206,6 +206,23 @@ namespace Nuake {
return entity.IsValid();
}
int PrefabInstance(Coral::String path, Vector3 position, float qx, float qy, float qz, float qw)
{
if (!FileSystem::FileExists(path))
{
Logger::Log("Prefab path doesn't exist", ".net", CRITICAL);
}
const auto& prefab = Prefab::New(path);
Entity root = prefab->Root;
TransformComponent& transformComponent = root.GetComponent<TransformComponent>();
transformComponent.SetLocalPosition(position);
transformComponent.SetLocalRotation(Quat(qw, qx, qy, qz));
return root.GetHandle();
}
void TransformSetPosition(int entityId, float x, float y, float z)
{
Entity entity = { (entt::entity)(entityId), Engine::GetCurrentScene().get() };
@@ -369,6 +386,9 @@ namespace Nuake {
RegisterMethod("Entity.EntitySetNameIcall", &EntitySetName);
RegisterMethod("Entity.EntityIsValidIcall", &EntityIsValid);
// Prefab
RegisterMethod("Prefab.PrefabInstanceIcall", &PrefabInstance);
// Scene
RegisterMethod("Scene.GetEntityIcall", &GetEntity);
RegisterMethod("Scene.GetEntityScriptFromNameIcall", &GetEntityScriptFromName);

View File

@@ -180,6 +180,7 @@ namespace Nuake
const std::string absoluteAssemblyPath = FileSystem::Root + assemblyPath;
m_GameAssembly = m_LoadContext.LoadAssembly(absoluteAssemblyPath);
m_PrefabType = m_GameAssembly.GetType("Nuake.Net.Prefab");
auto& exposedFieldAttributeType = m_GameAssembly.GetType("Nuake.Net.ExposedAttribute");
for (auto& type : m_GameAssembly.GetTypes())
@@ -235,6 +236,10 @@ namespace Nuake
{
varType = ExposedVarTypes::Entity;
}
else if (typeName == "Nuake.Net.Prefab")
{
varType = ExposedVarTypes::Prefab;
}
if (varType != ExposedVarTypes::Unsupported)
{
@@ -341,6 +346,11 @@ namespace Nuake
int32_t handle;
};
break;
}
case ExposedVarTypes::Prefab:
{
break;
}
}
@@ -385,6 +395,23 @@ namespace Nuake
}
}
}
else if (exposedVarUserValue.Type == NetScriptExposedVarType::Prefab)
{
if (exposedVarUserValue.Value.has_value())
{
std::string path = std::any_cast<std::string>(exposedVarUserValue.Value);
if (FileSystem::FileExists(path))
{
// In the case where the entity doesnt have an instance, we create one
auto newPrefab = m_PrefabType.CreateInstance(Coral::String::New(path));
classInstance.SetFieldValue<Coral::ManagedObject>(exposedVarUserValue.Name, newPrefab);
}
else
{
Logger::Log("Invalid prefab exposed variable set", ".net", CRITICAL);
}
}
}
else
{
classInstance.SetFieldValue(exposedVarUserValue.Name, exposedVarUserValue.Value);

View File

@@ -24,6 +24,7 @@ namespace Nuake {
Double,
String,
Entity,
Prefab,
Vector2,
Vector3,
Vector4,
@@ -52,6 +53,7 @@ namespace Nuake {
const std::string m_ContextName = "NuakeEngineContext";
Coral::Type m_BaseEntityType;
Coral::Type m_PrefabType;
bool m_IsInitialized = false;
Coral::HostInstance* m_HostInstance;

View File

@@ -202,4 +202,46 @@ namespace Nuake.Net
return isValid;
}
}
public class Prefab
{
internal static unsafe delegate*<NativeString, Vector3, float, float, float, float, int> PrefabInstanceIcall;
string Path { get; set; }
public Prefab()
{
}
public Prefab(string path)
{
Path = path;
Engine.Log("Prefab instance created with path: " + path);
}
public Entity? Instance(Vector3 position = default, Quaternion quat = default)
{
int handle;
unsafe { handle = PrefabInstanceIcall(Path, position, quat.X, quat.Y, quat.Z, quat.W); }
if (handle == -1)
{
return null;
}
Entity entity = new Entity(handle);
return entity;
}
public static implicit operator bool(Prefab prefab)
{
if (object.ReferenceEquals(prefab, null))
{
return false;
}
return prefab.Path != string.Empty;
}
}
}