diff --git a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs
index 17999d772..e89c80372 100644
--- a/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs
+++ b/Source/Editor/CustomEditors/Editors/AssetRefEditor.cs
@@ -33,7 +33,12 @@ namespace FlaxEditor.CustomEditors.Editors
[CustomEditor(typeof(Asset)), DefaultEditor]
public class AssetRefEditor : CustomEditor
{
- private AssetPicker _picker;
+ ///
+ /// The asset picker used to get a reference to an asset.
+ ///
+ public AssetPicker Picker;
+
+ private bool _isRefreshing;
private ScriptType _valueType;
///
@@ -44,7 +49,7 @@ namespace FlaxEditor.CustomEditors.Editors
{
if (HasDifferentTypes)
return;
- _picker = layout.Custom().CustomControl;
+ Picker = layout.Custom().CustomControl;
_valueType = Values.Type.Type != typeof(object) || Values[0] == null ? Values.Type : TypeUtils.GetObjectType(Values[0]);
var assetType = _valueType;
@@ -66,7 +71,7 @@ namespace FlaxEditor.CustomEditors.Editors
{
// Generic file picker
assetType = ScriptType.Null;
- _picker.FileExtension = assetReference.TypeName;
+ Picker.FileExtension = assetReference.TypeName;
}
else
{
@@ -78,23 +83,25 @@ namespace FlaxEditor.CustomEditors.Editors
}
}
- _picker.AssetType = assetType;
- _picker.Height = height;
- _picker.SelectedItemChanged += OnSelectedItemChanged;
+ Picker.AssetType = assetType;
+ Picker.Height = height;
+ Picker.SelectedItemChanged += OnSelectedItemChanged;
}
private void OnSelectedItemChanged()
{
+ if (_isRefreshing)
+ return;
if (typeof(AssetItem).IsAssignableFrom(_valueType.Type))
- SetValue(_picker.SelectedItem);
+ SetValue(Picker.SelectedItem);
else if (_valueType.Type == typeof(Guid))
- SetValue(_picker.SelectedID);
+ SetValue(Picker.SelectedID);
else if (_valueType.Type == typeof(SceneReference))
- SetValue(new SceneReference(_picker.SelectedID));
+ SetValue(new SceneReference(Picker.SelectedID));
else if (_valueType.Type == typeof(string))
- SetValue(_picker.SelectedPath);
+ SetValue(Picker.SelectedPath);
else
- SetValue(_picker.SelectedAsset);
+ SetValue(Picker.SelectedAsset);
}
///
@@ -104,16 +111,18 @@ namespace FlaxEditor.CustomEditors.Editors
if (!HasDifferentValues)
{
+ _isRefreshing = true;
if (Values[0] is AssetItem assetItem)
- _picker.SelectedItem = assetItem;
+ Picker.SelectedItem = assetItem;
else if (Values[0] is Guid guid)
- _picker.SelectedID = guid;
+ Picker.SelectedID = guid;
else if (Values[0] is SceneReference sceneAsset)
- _picker.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID);
+ Picker.SelectedItem = Editor.Instance.ContentDatabase.FindAsset(sceneAsset.ID);
else if (Values[0] is string path)
- _picker.SelectedPath = path;
+ Picker.SelectedPath = path;
else
- _picker.SelectedAsset = Values[0] as Asset;
+ Picker.SelectedAsset = Values[0] as Asset;
+ _isRefreshing = false;
}
}
}
diff --git a/Source/Editor/CustomEditors/Editors/ModelInstanceEntryEditor.cs b/Source/Editor/CustomEditors/Editors/ModelInstanceEntryEditor.cs
index a08a254d4..277f9ecb0 100644
--- a/Source/Editor/CustomEditors/Editors/ModelInstanceEntryEditor.cs
+++ b/Source/Editor/CustomEditors/Editors/ModelInstanceEntryEditor.cs
@@ -1,6 +1,8 @@
// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using FlaxEditor.CustomEditors.Elements;
+using FlaxEditor.CustomEditors.GUI;
+using FlaxEditor.Scripting;
using FlaxEngine;
namespace FlaxEditor.CustomEditors.Editors
@@ -13,6 +15,11 @@ namespace FlaxEditor.CustomEditors.Editors
{
private GroupElement _group;
private bool _updateName;
+ private int _entryIndex;
+ private bool _isRefreshing;
+ private MaterialBase _material;
+ private ModelInstanceActor _modelInstance;
+ private AssetRefEditor _materialEditor;
///
public override void Initialize(LayoutElementsContainer layout)
@@ -21,47 +28,122 @@ namespace FlaxEditor.CustomEditors.Editors
var group = layout.Group("Entry");
_group = group;
+ if (ParentEditor == null)
+ return;
+ var entry = (ModelInstanceEntry)Values[0];
+ var entryIndex = ParentEditor.ChildrenEditors.IndexOf(this);
+ var materialLabel = new PropertyNameLabel("Material");
+ materialLabel.TooltipText = "The mesh surface material used for the rendering.";
+ if (ParentEditor.ParentEditor?.Values[0] is ModelInstanceActor modelInstance)
+ {
+ _entryIndex = entryIndex;
+ _modelInstance = modelInstance;
+ var slots = modelInstance.MaterialSlots;
+ if (entry.Material == slots[entryIndex].Material)
+ {
+ // Ensure that entry with default material set is set back to null
+ modelInstance.SetMaterial(entryIndex, null);
+ }
+ _material = modelInstance.GetMaterial(entryIndex);
+ var defaultValue = GPUDevice.Instance.DefaultMaterial;
+ if (slots[entryIndex].Material)
+ {
+ // Use default value set on asset (eg. Model Asset)
+ defaultValue = slots[entryIndex].Material;
+ }
+
+ // Create material picker
+ var materialValue = new CustomValueContainer(new ScriptType(typeof(MaterialBase)), _material, (instance, index) => _material, (instance, index, value) => _material = value as MaterialBase);
+ var materialEditor = (AssetRefEditor)_group.Property(materialLabel, materialValue);
+ materialEditor.Values.SetDefaultValue(defaultValue);
+ materialEditor.RefreshDefaultValue();
+ materialEditor.Picker.SelectedItemChanged += OnSelectedMaterialChanged;
+ _materialEditor = materialEditor;
+ }
+
base.Initialize(group);
}
+ private void OnSelectedMaterialChanged()
+ {
+ if (_isRefreshing)
+ return;
+ _isRefreshing = true;
+ var slots = _modelInstance.MaterialSlots;
+ var material = _materialEditor.Picker.SelectedAsset as MaterialBase;
+ var defaultMaterial = GPUDevice.Instance.DefaultMaterial;
+ var value = (ModelInstanceEntry)Values[0];
+ var prevMaterial = value.Material;
+ if (!material)
+ {
+ // Fallback to default material
+ _materialEditor.Picker.SelectedAsset = defaultMaterial;
+ value.Material = defaultMaterial;
+ }
+ else if (material == slots[_entryIndex].Material)
+ {
+ // Asset default material
+ value.Material = null;
+ }
+ else if (material == defaultMaterial && !slots[_entryIndex].Material)
+ {
+ // Default material while asset has no set as well
+ value.Material = null;
+ }
+ else
+ {
+ // Custom material
+ value.Material = material;
+ }
+ if (prevMaterial != value.Material)
+ SetValue(value);
+ _isRefreshing = false;
+ }
+
+ ///
+ protected override void SpawnProperty(LayoutElementsContainer itemLayout, ValueContainer itemValues, ItemInfo item)
+ {
+ // Skip material member as it is overridden
+ if (item.Info.Name == "Material" && _materialEditor != null)
+ return;
+ base.SpawnProperty(itemLayout, itemValues, item);
+ }
+
///
public override void Refresh()
{
+ // Update panel title to match material slot name
if (_updateName &&
_group != null &&
ParentEditor?.ParentEditor != null &&
ParentEditor.ParentEditor.Values.Count > 0)
{
var entryIndex = ParentEditor.ChildrenEditors.IndexOf(this);
- if (ParentEditor.ParentEditor.Values[0] is StaticModel staticModel)
+ if (ParentEditor.ParentEditor.Values[0] is ModelInstanceActor modelInstance)
{
- var model = staticModel.Model;
- if (model && model.IsLoaded)
+ var slots = modelInstance.MaterialSlots;
+ if (slots != null && slots.Length > entryIndex)
{
- var slots = model.MaterialSlots;
- if (slots != null && slots.Length > entryIndex)
- {
- _group.Panel.HeaderText = "Entry " + slots[entryIndex].Name;
- _updateName = false;
- }
- }
- }
- else if (ParentEditor.ParentEditor.Values[0] is AnimatedModel animatedModel)
- {
- var model = animatedModel.SkinnedModel;
- if (model && model.IsLoaded)
- {
- var slots = model.MaterialSlots;
- if (slots != null && slots.Length > entryIndex)
- {
- _group.Panel.HeaderText = "Entry " + slots[entryIndex].Name;
- _updateName = false;
- }
+ _updateName = false;
+ _group.Panel.HeaderText = "Entry " + slots[entryIndex].Name;
}
}
}
+ // Refresh currently selected material
+ _material = _modelInstance.GetMaterial(_entryIndex);
+
base.Refresh();
}
+
+ ///
+ protected override void Deinitialize()
+ {
+ _material = null;
+ _modelInstance = null;
+ _materialEditor = null;
+
+ base.Deinitialize();
+ }
}
}
diff --git a/Source/Editor/Gizmo/SelectionOutline.cs b/Source/Editor/Gizmo/SelectionOutline.cs
index ccc4bdd27..1374c7247 100644
--- a/Source/Editor/Gizmo/SelectionOutline.cs
+++ b/Source/Editor/Gizmo/SelectionOutline.cs
@@ -178,6 +178,8 @@ namespace FlaxEditor.Gizmo
if (selection[i] is ActorNode actorNode && actorNode.Actor != null)
CollectActors(actorNode.Actor);
}
+ if (_actors.Count == 0)
+ return;
// Render selected objects depth
Renderer.DrawSceneDepth(context, task, customDepth, _actors);
diff --git a/Source/Engine/Content/Assets/MaterialBase.h b/Source/Engine/Content/Assets/MaterialBase.h
index bca70b6da..070347348 100644
--- a/Source/Engine/Content/Assets/MaterialBase.h
+++ b/Source/Engine/Content/Assets/MaterialBase.h
@@ -27,7 +27,6 @@ public:
///
/// Returns true if material is an material instance.
///
- /// True if it's a material instance, otherwise false.
virtual bool IsMaterialInstance() const = 0;
public:
diff --git a/Source/Engine/Core/Types/Variant.cpp b/Source/Engine/Core/Types/Variant.cpp
index 8232d415f..973e494f1 100644
--- a/Source/Engine/Core/Types/Variant.cpp
+++ b/Source/Engine/Core/Types/Variant.cpp
@@ -2796,6 +2796,122 @@ String Variant::ToString() const
}
}
+void Variant::Inline()
+{
+ VariantType::Types type = VariantType::Null;
+ byte data[sizeof(Matrix)];
+ if (Type.Type == VariantType::Structure && AsBlob.Data && AsBlob.Length <= sizeof(Matrix))
+ {
+ for (int32 i = 2; i < VariantType::MAX; i++)
+ {
+ if (StringUtils::Compare(Type.TypeName, InBuiltTypesTypeNames[i]) == 0)
+ {
+ type = (VariantType::Types)i;
+ break;
+ }
+ }
+ if (type == VariantType::Null)
+ {
+ // Aliases
+ if (StringUtils::Compare(Type.TypeName, "FlaxEngine.Vector2") == 0)
+ type = VariantType::Types::Vector2;
+ else if (StringUtils::Compare(Type.TypeName, "FlaxEngine.Vector3") == 0)
+ type = VariantType::Types::Vector3;
+ else if (StringUtils::Compare(Type.TypeName, "FlaxEngine.Vector4") == 0)
+ type = VariantType::Types::Vector4;
+ }
+ if (type != VariantType::Null)
+ Platform::MemoryCopy(data, AsBlob.Data, AsBlob.Length);
+ }
+ if (type != VariantType::Null)
+ {
+ switch (type)
+ {
+ case VariantType::Bool:
+ *this = *(bool*)data;
+ break;
+ case VariantType::Int:
+ *this = *(int32*)data;
+ break;
+ case VariantType::Uint:
+ *this = *(uint32*)data;
+ break;
+ case VariantType::Int64:
+ *this = *(int64*)data;
+ break;
+ case VariantType::Uint64:
+ *this = *(uint64*)data;
+ break;
+ case VariantType::Float:
+ *this = *(float*)data;
+ break;
+ case VariantType::Double:
+ *this = *(double*)data;
+ break;
+ case VariantType::Float2:
+ *this = *(Float2*)data;
+ break;
+ case VariantType::Float3:
+ *this = *(Float3*)data;
+ break;
+ case VariantType::Float4:
+ *this = *(Float4*)data;
+ break;
+ case VariantType::Color:
+ *this = *(Color*)data;
+ break;
+ case VariantType::Guid:
+ *this = *(Guid*)data;
+ break;
+ case VariantType::BoundingBox:
+ *this = Variant(*(BoundingBox*)data);
+ break;
+ case VariantType::BoundingSphere:
+ *this = *(BoundingSphere*)data;
+ break;
+ case VariantType::Quaternion:
+ *this = *(Quaternion*)data;
+ break;
+ case VariantType::Transform:
+ *this = Variant(*(Transform*)data);
+ break;
+ case VariantType::Rectangle:
+ *this = *(Rectangle*)data;
+ break;
+ case VariantType::Ray:
+ *this = Variant(*(Ray*)data);
+ break;
+ case VariantType::Matrix:
+ *this = Variant(*(Matrix*)data);
+ break;
+ case VariantType::Int2:
+ *this = *(Int2*)data;
+ break;
+ case VariantType::Int3:
+ *this = *(Int3*)data;
+ break;
+ case VariantType::Int4:
+ *this = *(Int4*)data;
+ break;
+ case VariantType::Int16:
+ *this = *(int16*)data;
+ break;
+ case VariantType::Uint16:
+ *this = *(uint16*)data;
+ break;
+ case VariantType::Double2:
+ *this = *(Double2*)data;
+ break;
+ case VariantType::Double3:
+ *this = *(Double3*)data;
+ break;
+ case VariantType::Double4:
+ *this = *(Double4*)data;
+ break;
+ }
+ }
+}
+
bool Variant::CanCast(const Variant& v, const VariantType& to)
{
if (v.Type == to)
@@ -3682,6 +3798,7 @@ void Variant::AllocStructure()
const ScriptingType& type = typeHandle.GetType();
AsBlob.Length = type.Size;
AsBlob.Data = Allocator::Allocate(AsBlob.Length);
+ Platform::MemoryClear(AsBlob.Data, AsBlob.Length);
type.Struct.Ctor(AsBlob.Data);
}
else if (typeName == "System.Int16" || typeName == "System.UInt16")
diff --git a/Source/Engine/Core/Types/Variant.h b/Source/Engine/Core/Types/Variant.h
index 7745307c3..9776c8e0b 100644
--- a/Source/Engine/Core/Types/Variant.h
+++ b/Source/Engine/Core/Types/Variant.h
@@ -359,6 +359,9 @@ public:
void SetAsset(Asset* asset);
String ToString() const;
+ // Inlines potential value type into in-built format (eg. Vector3 stored as Structure, or String stored as ManagedObject).
+ void Inline();
+
FORCE_INLINE Variant Cast(const VariantType& to) const
{
return Cast(*this, to);
diff --git a/Source/Engine/Engine/NativeInterop.Unmanaged.cs b/Source/Engine/Engine/NativeInterop.Unmanaged.cs
index 17b8b73af..57454ad1e 100644
--- a/Source/Engine/Engine/NativeInterop.Unmanaged.cs
+++ b/Source/Engine/Engine/NativeInterop.Unmanaged.cs
@@ -244,7 +244,25 @@ namespace FlaxEngine.Interop
@namespace = NativeAllocStringAnsi(type.Namespace ?? ""),
typeAttributes = (uint)type.Attributes,
};
- *assemblyHandle = GetAssemblyHandle(type.Assembly);
+
+ Assembly assembly = null;
+ if (type.IsGenericType && !type.Assembly.IsCollectible)
+ {
+ // The owning assembly of a generic type with type arguments referencing
+ // collectible assemblies must be one of the collectible assemblies.
+ foreach (var genericType in type.GetGenericArguments())
+ {
+ if (genericType.Assembly.IsCollectible)
+ {
+ assembly = genericType.Assembly;
+ break;
+ }
+ }
+ }
+ if (assembly == null)
+ assembly = type.Assembly;
+
+ *assemblyHandle = GetAssemblyHandle(assembly);
}
[UnmanagedCallersOnly]
diff --git a/Source/Engine/Graphics/GPUDevice.h b/Source/Engine/Graphics/GPUDevice.h
index 4dbcf6d06..422e554a0 100644
--- a/Source/Engine/Graphics/GPUDevice.h
+++ b/Source/Engine/Graphics/GPUDevice.h
@@ -238,7 +238,7 @@ public:
///
/// Gets the default material.
///
- MaterialBase* GetDefaultMaterial() const;
+ API_PROPERTY() MaterialBase* GetDefaultMaterial() const;
///
/// Gets the default material (Deformable domain).
diff --git a/Source/Engine/Level/Actors/AnimatedModel.cpp b/Source/Engine/Level/Actors/AnimatedModel.cpp
index 5a7150bac..2ff681628 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.cpp
+++ b/Source/Engine/Level/Actors/AnimatedModel.cpp
@@ -1066,6 +1066,14 @@ void AnimatedModel::Deserialize(DeserializeStream& stream, ISerializeModifier* m
DrawModes |= DrawPass::GlobalSurfaceAtlas;
}
+const Span AnimatedModel::GetMaterialSlots() const
+{
+ const auto model = SkinnedModel.Get();
+ if (model && !model->WaitForLoaded())
+ return ToSpan(model->MaterialSlots);
+ return Span();
+}
+
MaterialBase* AnimatedModel::GetMaterial(int32 entryIndex)
{
if (SkinnedModel)
diff --git a/Source/Engine/Level/Actors/AnimatedModel.h b/Source/Engine/Level/Actors/AnimatedModel.h
index 8fe85d114..d070d99a2 100644
--- a/Source/Engine/Level/Actors/AnimatedModel.h
+++ b/Source/Engine/Level/Actors/AnimatedModel.h
@@ -384,6 +384,7 @@ public:
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
+ const Span GetMaterialSlots() const override;
MaterialBase* GetMaterial(int32 entryIndex) override;
bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) override;
bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override;
diff --git a/Source/Engine/Level/Actors/ModelInstanceActor.h b/Source/Engine/Level/Actors/ModelInstanceActor.h
index 346a13b0d..e92b7cba6 100644
--- a/Source/Engine/Level/Actors/ModelInstanceActor.h
+++ b/Source/Engine/Level/Actors/ModelInstanceActor.h
@@ -52,6 +52,11 @@ public:
///
API_PROPERTY() void SetEntries(const Array& value);
+ ///
+ /// Gets the material slots array set on the asset (eg. model or skinned model asset).
+ ///
+ API_PROPERTY(Sealed) virtual const Span GetMaterialSlots() const = 0;
+
///
/// Gets the material used to draw the meshes which are assigned to that slot (set in Entries or model's default).
///
diff --git a/Source/Engine/Level/Actors/SplineModel.cpp b/Source/Engine/Level/Actors/SplineModel.cpp
index 44f0676d4..2640bd84b 100644
--- a/Source/Engine/Level/Actors/SplineModel.cpp
+++ b/Source/Engine/Level/Actors/SplineModel.cpp
@@ -341,6 +341,14 @@ void SplineModel::OnParentChanged()
OnSplineUpdated();
}
+const Span SplineModel::GetMaterialSlots() const
+{
+ const auto model = Model.Get();
+ if (model && !model->WaitForLoaded())
+ return ToSpan(model->MaterialSlots);
+ return Span();
+}
+
MaterialBase* SplineModel::GetMaterial(int32 entryIndex)
{
if (Model)
diff --git a/Source/Engine/Level/Actors/SplineModel.h b/Source/Engine/Level/Actors/SplineModel.h
index 238e1cc5a..654268ec6 100644
--- a/Source/Engine/Level/Actors/SplineModel.h
+++ b/Source/Engine/Level/Actors/SplineModel.h
@@ -115,6 +115,7 @@ public:
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
void OnParentChanged() override;
+ const Span GetMaterialSlots() const override;
MaterialBase* GetMaterial(int32 entryIndex) override;
void UpdateBounds() override;
diff --git a/Source/Engine/Level/Actors/StaticModel.cpp b/Source/Engine/Level/Actors/StaticModel.cpp
index 75c272cce..d5c7e0e3e 100644
--- a/Source/Engine/Level/Actors/StaticModel.cpp
+++ b/Source/Engine/Level/Actors/StaticModel.cpp
@@ -543,6 +543,14 @@ void StaticModel::Deserialize(DeserializeStream& stream, ISerializeModifier* mod
}
}
+const Span StaticModel::GetMaterialSlots() const
+{
+ const auto model = Model.Get();
+ if (model && !model->WaitForLoaded())
+ return ToSpan(model->MaterialSlots);
+ return Span();
+}
+
MaterialBase* StaticModel::GetMaterial(int32 entryIndex)
{
if (Model)
diff --git a/Source/Engine/Level/Actors/StaticModel.h b/Source/Engine/Level/Actors/StaticModel.h
index 78a0440fd..2e932096e 100644
--- a/Source/Engine/Level/Actors/StaticModel.h
+++ b/Source/Engine/Level/Actors/StaticModel.h
@@ -166,6 +166,7 @@ public:
bool IntersectsItself(const Ray& ray, Real& distance, Vector3& normal) override;
void Serialize(SerializeStream& stream, const void* otherObj) override;
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
+ const Span GetMaterialSlots() const override;
MaterialBase* GetMaterial(int32 entryIndex) override;
bool IntersectsEntry(int32 entryIndex, const Ray& ray, Real& distance, Vector3& normal) override;
bool IntersectsEntry(const Ray& ray, Real& distance, Vector3& normal, int32& entryIndex) override;
diff --git a/Source/Engine/Renderer/Renderer.cs b/Source/Engine/Renderer/Renderer.cs
index bfb81a84c..71dca424b 100644
--- a/Source/Engine/Renderer/Renderer.cs
+++ b/Source/Engine/Renderer/Renderer.cs
@@ -17,10 +17,13 @@ namespace FlaxEngine
[Unmanaged]
public static void DrawSceneDepth(GPUContext context, SceneRenderTask task, GPUTexture output, List customActors)
{
- if (customActors.Count == 0)
- return;
- var temp = CollectionsMarshal.AsSpan(customActors).ToArray(); // FIXME
- var tempCount = temp.Length;
+ Actor[] temp = null;
+ int tempCount = 0;
+ if (customActors != null && customActors.Count != 0)
+ {
+ temp = CollectionsMarshal.AsSpan(customActors).ToArray(); // FIXME
+ tempCount = temp.Length;
+ }
Internal_DrawSceneDepth(FlaxEngine.Object.GetUnmanagedPtr(context), FlaxEngine.Object.GetUnmanagedPtr(task), FlaxEngine.Object.GetUnmanagedPtr(output), temp, ref tempCount);
}
@@ -32,7 +35,14 @@ namespace FlaxEngine
[Unmanaged]
public static void DrawActors(ref RenderContext renderContext, List customActors)
{
- DrawActors(ref renderContext, Utils.ExtractArrayFromList(customActors));
+ Actor[] temp = null;
+ int tempCount = 0;
+ if (customActors != null && customActors.Count != 0)
+ {
+ temp = CollectionsMarshal.AsSpan(customActors).ToArray(); // FIXME
+ tempCount = temp.Length;
+ }
+ Internal_DrawActors(ref renderContext, temp, ref tempCount);
}
}
}
diff --git a/Source/Engine/Scripting/Scripting.cpp b/Source/Engine/Scripting/Scripting.cpp
index e2d709653..bbfa802f1 100644
--- a/Source/Engine/Scripting/Scripting.cpp
+++ b/Source/Engine/Scripting/Scripting.cpp
@@ -476,12 +476,28 @@ bool Scripting::Load()
// Load FlaxEngine
const String flaxEnginePath = Globals::BinariesFolder / TEXT("FlaxEngine.CSharp.dll");
- if (((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly->Load(flaxEnginePath))
+ auto* flaxEngineModule = (NativeBinaryModule*)GetBinaryModuleFlaxEngine();
+ if (flaxEngineModule->Assembly->Load(flaxEnginePath))
{
LOG(Error, "Failed to load FlaxEngine C# assembly.");
return true;
}
+ // Insert type aliases for vector types that don't exist in C++ but are just typedef (properly redirect them to actual types)
+ // TODO: add support for automatic typedef aliases setup for scripting module to properly lookup type from the alias typename
+#if USE_LARGE_WORLDS
+ flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector2"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Double2"];
+ flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector3"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Double3"];
+ flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector4"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Double4"];
+#else
+ flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector2"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Float2"];
+ flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector3"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Float3"];
+ flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector4"] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Float4"];
+#endif
+ flaxEngineModule->ClassToTypeIndex[flaxEngineModule->Assembly->GetClass("FlaxEngine.Vector2")] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector2"];
+ flaxEngineModule->ClassToTypeIndex[flaxEngineModule->Assembly->GetClass("FlaxEngine.Vector3")] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector3"];
+ flaxEngineModule->ClassToTypeIndex[flaxEngineModule->Assembly->GetClass("FlaxEngine.Vector4")] = flaxEngineModule->TypeNameToTypeIndex["FlaxEngine.Vector4"];
+
#if USE_EDITOR
// Skip loading game modules in Editor on startup - Editor loads them later during splash screen (eg. after first compilation)
static bool SkipFirstLoad = true;
diff --git a/Source/Engine/Visject/VisjectGraph.cpp b/Source/Engine/Visject/VisjectGraph.cpp
index 37154e09f..ca4495f67 100644
--- a/Source/Engine/Visject/VisjectGraph.cpp
+++ b/Source/Engine/Visject/VisjectGraph.cpp
@@ -675,6 +675,10 @@ void VisjectExecutor::ProcessGroupPacking(Box* box, Node* node, Value& value)
}
}
}
+
+ // For in-built structures try to convert it into internal format for better comparability with the scripting
+ value.Inline();
+
break;
}
// Unpack Structure
diff --git a/Source/Engine/Visject/VisjectGraph.h b/Source/Engine/Visject/VisjectGraph.h
index 238823afd..0d841f3d4 100644
--- a/Source/Engine/Visject/VisjectGraph.h
+++ b/Source/Engine/Visject/VisjectGraph.h
@@ -246,6 +246,7 @@ public:
void ProcessGroupCollections(Box* box, Node* node, Value& value);
protected:
+ void InlineVariantStruct(Variant& v);
virtual Value eatBox(Node* caller, Box* box) = 0;
virtual Graph* GetCurrentGraph() const = 0;