Merge remote-tracking branch 'origin/1.6' into 1.7

This commit is contained in:
Wojtek Figat
2023-07-09 11:55:50 +02:00
25 changed files with 315 additions and 176 deletions

Binary file not shown.

BIN
Content/Editor/Gizmo/Material.flax (Stored with Git LFS)

Binary file not shown.

BIN
Content/Editor/TexturePreviewMaterial.flax (Stored with Git LFS)

Binary file not shown.

View File

@@ -3,7 +3,7 @@
"Version": {
"Major": 1,
"Minor": 6,
"Build": 6343
"Build": 6344
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",

View File

@@ -41,7 +41,17 @@ namespace FlaxEditor.CustomEditors.Editors
}
else
{
element.CustomControl.Value = (Color)Values[0];
var value = Values[0];
if (value is Color asColor)
element.CustomControl.Value = asColor;
else if (value is Color32 asColor32)
element.CustomControl.Value = asColor32;
else if (value is Float4 asFloat4)
element.CustomControl.Value = asFloat4;
else if (value is Double4 asDouble4)
element.CustomControl.Value = (Float4)asDouble4;
else if (value is Vector4 asVector4)
element.CustomControl.Value = asVector4;
}
}
}

View File

@@ -390,7 +390,6 @@ namespace FlaxEditor.CustomEditors.Editors
if (addTagDropPanel.IsClosed)
{
Debug.Log("Hit");
nameTextBox.BorderColor = Color.Transparent;
nameTextBox.BorderSelectedColor = FlaxEngine.GUI.Style.Current.BackgroundSelected;
return;

View File

@@ -363,7 +363,6 @@ namespace FlaxEditor.Surface.ContextMenu
Profiler.BeginEvent("VisjectCM.RemoveGroup");
if (group.Archetypes.Count == 0)
{
Debug.Log("Remove");
_groups.RemoveAt(i);
group.Dispose();
}

View File

@@ -618,7 +618,7 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
// Return
case 5:
{
auto& scope = ThreadStacks.Get().Stack->Scope;
auto scope = ThreadStacks.Get().Stack->Scope;
scope->FunctionReturn = tryGetValue(node->GetBox(1), Value::Zero);
break;
}
@@ -634,7 +634,7 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
else
{
// Evaluate method parameter value from the current scope
auto& scope = ThreadStacks.Get().Stack->Scope;
auto scope = ThreadStacks.Get().Stack->Scope;
int32 index = boxBase->ID - 1;
if (index < scope->Parameters.Length())
value = scope->Parameters.Get()[index];
@@ -1138,7 +1138,7 @@ void VisualScriptExecutor::ProcessGroupFlow(Box* boxBase, Node* node, Value& val
break;
}
int32 arrayIndex = 0;
for (; iteratorIndex < scope->ReturnedValues.Count(); arrayIndex++)
for (; arrayIndex < scope->ReturnedValues.Count(); arrayIndex++)
{
const auto& e = scope->ReturnedValues[arrayIndex];
if (e.NodeId == node->ID && e.BoxId == 1)

View File

@@ -113,6 +113,7 @@ void String::Append(const char* chars, int32 count)
Platform::MemoryCopy(_data, oldData, oldLength * sizeof(Char));
StringUtils::ConvertANSI2UTF16(chars, _data + oldLength, count, _length);
_length += oldLength;
_data[_length] = 0;
Platform::Free(oldData);

View File

@@ -399,7 +399,7 @@ namespace FlaxEngine.Interop
}
numElements = managed.Length;
ManagedArray managedArray = ManagedArray.AllocatePooledArray<TUnmanagedElement>(managed.Length);
return (TUnmanagedElement*)ManagedHandle.ToIntPtr(managedArray, GCHandleType.Weak);
return (TUnmanagedElement*)ManagedHandle.ToIntPtr(managedArray, GCHandleType.Normal);
}
public static ReadOnlySpan<T> GetManagedValuesSource(T[] managed) => managed;

View File

@@ -770,6 +770,13 @@ namespace FlaxEngine.Interop
field.field.SetValue(fieldOwner, value);
}
[UnmanagedCallersOnly]
internal static int FieldGetOffset(ManagedHandle fieldHandle)
{
FieldHolder field = Unsafe.As<FieldHolder>(fieldHandle.Target);
return (int)Marshal.OffsetOf(field.field.DeclaringType, field.field.Name);
}
[UnmanagedCallersOnly]
internal static void FieldGetValue(ManagedHandle fieldOwnerHandle, ManagedHandle fieldHandle, IntPtr valuePtr)
{
@@ -778,6 +785,15 @@ namespace FlaxEngine.Interop
field.toNativeMarshaller(field.field, fieldOwner, valuePtr, out int fieldOffset);
}
[UnmanagedCallersOnly]
internal static IntPtr FieldGetValueBoxed(ManagedHandle fieldOwnerHandle, ManagedHandle fieldHandle)
{
object fieldOwner = fieldOwnerHandle.Target;
FieldHolder field = Unsafe.As<FieldHolder>(fieldHandle.Target);
object fieldValue = field.field.GetValue(fieldOwner);
return Invoker.MarshalReturnValueGeneric(field.field.FieldType, fieldValue);
}
[UnmanagedCallersOnly]
internal static void WriteArrayReference(ManagedHandle arrayHandle, IntPtr valueHandle, int index)
{
@@ -924,7 +940,7 @@ namespace FlaxEngine.Interop
if (nativeType.IsClass)
size = sizeof(IntPtr);
else
size = Marshal.SizeOf(nativeType);
size = GetTypeSize(nativeType);
return size;
}

View File

@@ -1095,7 +1095,10 @@ namespace FlaxEngine.Interop
{
try
{
size = Marshal.SizeOf(type);
var marshalType = type;
if (type.IsEnum)
marshalType = type.GetEnumUnderlyingType();
size = Marshal.SizeOf(marshalType);
}
catch
{

View File

@@ -1337,6 +1337,20 @@ Actor* Actor::FindActor(const MClass* type, const StringView& name) const
return nullptr;
}
Actor* Actor::FindActor(const MClass* type, const Tag& tag) const
{
CHECK_RETURN(type, nullptr);
if (GetClass()->IsSubClassOf(type) && HasTag(tag))
return const_cast<Actor*>(this);
for (auto child : Children)
{
const auto actor = child->FindActor(type, tag);
if (actor)
return actor;
}
return nullptr;
}
Script* Actor::FindScript(const MClass* type) const
{
CHECK_RETURN(type, nullptr);

View File

@@ -269,6 +269,17 @@ namespace FlaxEngine
{
return FindActor(typeof(T), name) as T;
}
/// <summary>
/// Tries to find actor of the given type and tag in this actor hierarchy (checks this actor and all children hierarchy).
/// </summary>
/// <param name="tag">A tag on the object.</param>
/// <typeparam name="T">Type of the object.</typeparam>
/// <returns>Actor instance if found, null otherwise.</returns>
public T FindActor<T>(Tag tag) where T : Actor
{
return FindActor(typeof(T), tag) as T;
}
/// <summary>
/// Searches for all actors of a specific type in this actor children list.

View File

@@ -739,6 +739,14 @@ public:
/// <returns>Actor instance if found, null otherwise.</returns>
API_FUNCTION() Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type, const StringView& name) const;
/// <summary>
/// Tries to find the actor of the given type and tag in this actor hierarchy.
/// </summary>
/// <param name="type">Type of the actor to search for. Includes any actors derived from the type.</param>
/// <param name="tag">The tag of the actor to search for.</param>
/// <returns>Actor instance if found, null otherwise.</returns>
API_FUNCTION() Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type, const Tag& tag) const;
/// <summary>
/// Tries to find the actor of the given type in this actor hierarchy (checks this actor and all children hierarchy).
/// </summary>
@@ -759,6 +767,17 @@ public:
{
return (T*)FindActor(T::GetStaticClass(), name);
}
/// <summary>
/// Tries to find the actor of the given type and tag in this actor hierarchy (checks this actor and all children hierarchy).
/// </summary>
/// <param name="tag">The tag of the actor to search for.</param>
/// <returns>Actor instance if found, null otherwise.</returns>
template<typename T>
FORCE_INLINE T* FindActor(const Tag& tag) const
{
return (T*)FindActor(T::GetStaticClass(), tag);
}
/// <summary>
/// Tries to find the script of the given type in this actor hierarchy (checks this actor and all children hierarchy).

View File

@@ -726,116 +726,6 @@ int32 Level::GetLayerIndex(const StringView& layer)
return result;
}
Actor* FindActorRecursive(Actor* node, const Tag& tag)
{
if (node->HasTag(tag))
return node;
Actor* result = nullptr;
for (Actor* child : node->Children)
{
result = FindActorRecursive(child, tag);
if (result)
break;
}
return result;
}
void FindActorsRecursive(Actor* node, const Tag& tag, const bool activeOnly, Array<Actor*>& result)
{
if (activeOnly && !node->GetIsActive())
return;
if (node->HasTag(tag))
result.Add(node);
for (Actor* child : node->Children)
FindActorsRecursive(child, tag, activeOnly, result);
}
void FindActorsRecursiveByParentTags(Actor* node, const Array<Tag>& tags, const bool activeOnly, Array<Actor*>& result)
{
if (activeOnly && !node->GetIsActive())
return;
for (Tag tag : tags)
{
if (node->HasTag(tag))
{
result.Add(node);
break;
}
}
for (Actor* child : node->Children)
FindActorsRecursiveByParentTags(child, tags, activeOnly, result);
}
Actor* Level::FindActor(const Tag& tag, Actor* root)
{
PROFILE_CPU();
if (root)
return FindActorRecursive(root, tag);
Actor* result = nullptr;
for (Scene* scene : Scenes)
{
result = FindActorRecursive(scene, tag);
if (result)
break;
}
return result;
}
void FindActorRecursive(Actor* node, const Tag& tag, Array<Actor*>& result)
{
if (node->HasTag(tag))
result.Add(node);
for (Actor* child : node->Children)
FindActorRecursive(child, tag, result);
}
Array<Actor*> Level::FindActors(const Tag& tag, const bool activeOnly, Actor* root)
{
PROFILE_CPU();
Array<Actor*> result;
if (root)
{
FindActorsRecursive(root, tag, activeOnly, result);
}
else
{
ScopeLock lock(ScenesLock);
for (Scene* scene : Scenes)
FindActorsRecursive(scene, tag, activeOnly, result);
}
return result;
}
Array<Actor*> Level::FindActorsByParentTag(const Tag& parentTag, const bool activeOnly, Actor* root)
{
PROFILE_CPU();
Array<Actor*> result;
const Array<Tag> subTags = Tags::GetSubTags(parentTag);
if (subTags.Count() == 0)
{
return result;
}
if (subTags.Count() == 1)
{
result = FindActors(subTags[0], activeOnly, root);
return result;
}
if (root)
{
FindActorsRecursiveByParentTags(root, subTags, activeOnly, result);
}
else
{
ScopeLock lock(ScenesLock);
for (Scene* scene : Scenes)
FindActorsRecursiveByParentTags(scene, subTags, activeOnly, result);
}
return result;
}
void Level::callActorEvent(ActorEventType eventType, Actor* a, Actor* b)
{
PROFILE_CPU();
@@ -1505,6 +1395,143 @@ Actor* Level::FindActor(const MClass* type, const StringView& name)
return result;
}
Actor* FindActorRecursive(Actor* node, const Tag& tag)
{
if (node->HasTag(tag))
return node;
Actor* result = nullptr;
for (Actor* child : node->Children)
{
result = FindActorRecursive(child, tag);
if (result)
break;
}
return result;
}
Actor* FindActorRecursiveByType(Actor* node, const MClass* type, const Tag& tag)
{
CHECK_RETURN(type, nullptr);
if (node->HasTag(tag) && node->GetClass()->IsSubClassOf(type))
return node;
Actor* result = nullptr;
for (Actor* child : node->Children)
{
result = FindActorRecursiveByType(child, type, tag);
if (result)
break;
}
return result;
}
void FindActorsRecursive(Actor* node, const Tag& tag, const bool activeOnly, Array<Actor*>& result)
{
if (activeOnly && !node->GetIsActive())
return;
if (node->HasTag(tag))
result.Add(node);
for (Actor* child : node->Children)
FindActorsRecursive(child, tag, activeOnly, result);
}
void FindActorsRecursiveByParentTags(Actor* node, const Array<Tag>& tags, const bool activeOnly, Array<Actor*>& result)
{
if (activeOnly && !node->GetIsActive())
return;
for (Tag tag : tags)
{
if (node->HasTag(tag))
{
result.Add(node);
break;
}
}
for (Actor* child : node->Children)
FindActorsRecursiveByParentTags(child, tags, activeOnly, result);
}
Actor* Level::FindActor(const Tag& tag, Actor* root)
{
PROFILE_CPU();
if (root)
return FindActorRecursive(root, tag);
Actor* result = nullptr;
for (Scene* scene : Scenes)
{
result = FindActorRecursive(scene, tag);
if (result)
break;
}
return result;
}
Actor* Level::FindActor(const MClass* type, const Tag& tag, Actor* root)
{
CHECK_RETURN(type, nullptr);
if (root)
return FindActorRecursiveByType(root, type, tag);
Actor* result = nullptr;
ScopeLock lock(ScenesLock);
for (int32 i = 0; result == nullptr && i < Scenes.Count(); i++)
result = Scenes[i]->FindActor(type, tag);
return result;
}
void FindActorRecursive(Actor* node, const Tag& tag, Array<Actor*>& result)
{
if (node->HasTag(tag))
result.Add(node);
for (Actor* child : node->Children)
FindActorRecursive(child, tag, result);
}
Array<Actor*> Level::FindActors(const Tag& tag, const bool activeOnly, Actor* root)
{
PROFILE_CPU();
Array<Actor*> result;
if (root)
{
FindActorsRecursive(root, tag, activeOnly, result);
}
else
{
ScopeLock lock(ScenesLock);
for (Scene* scene : Scenes)
FindActorsRecursive(scene, tag, activeOnly, result);
}
return result;
}
Array<Actor*> Level::FindActorsByParentTag(const Tag& parentTag, const bool activeOnly, Actor* root)
{
PROFILE_CPU();
Array<Actor*> result;
const Array<Tag> subTags = Tags::GetSubTags(parentTag);
if (subTags.Count() == 0)
{
return result;
}
if (subTags.Count() == 1)
{
result = FindActors(subTags[0], activeOnly, root);
return result;
}
if (root)
{
FindActorsRecursiveByParentTags(root, subTags, activeOnly, result);
}
else
{
ScopeLock lock(ScenesLock);
for (Scene* scene : Scenes)
FindActorsRecursiveByParentTags(scene, subTags, activeOnly, result);
}
return result;
}
Script* Level::FindScript(const MClass* type)
{
CHECK_RETURN(type, nullptr);

View File

@@ -77,6 +77,18 @@ namespace FlaxEngine
{
return FindActor(typeof(T), name) as T;
}
/// <summary>
/// Tries to find actor of the given type and tag in a root actor or all loaded scenes.
/// </summary>
/// <param name="tag">A tag on the object.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// <typeparam name="T">Type of the object.</typeparam>
/// <returns>Found actor or null.</returns>
public static T FindActor<T>(Tag tag, Actor root = null) where T : Actor
{
return FindActor(typeof(T), tag, root) as T;
}
/// <summary>
/// Tries to find actor with the given ID in all loaded scenes. It's very fast O(1) lookup.

View File

@@ -371,6 +371,41 @@ public:
/// <returns>Actor instance if found, null otherwise.</returns>
API_FUNCTION() static Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type, const StringView& name);
/// <summary>
/// Tries to find the actor with the given tag (returns the first one found).
/// </summary>
/// <param name="tag">The tag of the actor to search for.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// <returns>Found actor or null.</returns>
API_FUNCTION() static Actor* FindActor(const Tag& tag, Actor* root = nullptr);
/// <summary>
/// Tries to find the actor of the given type and tag in all the loaded scenes.
/// </summary>
/// <param name="type">Type of the actor to search for. Includes any actors derived from the type.</param>
/// <param name="tag">The tag of the actor to search for.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// <returns>Actor instance if found, null otherwise.</returns>
API_FUNCTION() static Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type, const Tag& tag, Actor* root = nullptr);
/// <summary>
/// Tries to find the actors with the given tag (returns all found).
/// </summary>
/// <param name="tag">The tag of the actor to search for.</param>
/// <param name="activeOnly">Find only active actors.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// <returns>Found actors or empty if none.</returns>
API_FUNCTION() static Array<Actor*> FindActors(const Tag& tag, const bool activeOnly = false, Actor* root = nullptr);
/// <summary>
/// Search actors using a parent parentTag.
/// </summary>
/// <param name="parentTag">The tag to search actors with subtags belonging to this tag</param>
/// <param name="activeOnly">Find only active actors.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// <returns>Returns all actors that have subtags belonging to the given parent parentTag</returns>
API_FUNCTION() static Array<Actor*> FindActorsByParentTag(const Tag& parentTag, const bool activeOnly = false, Actor* root = nullptr);
/// <summary>
/// Tries to find the actor of the given type in all the loaded scenes.
/// </summary>
@@ -392,6 +427,18 @@ public:
return (T*)FindActor(T::GetStaticClass(), name);
}
/// <summary>
/// Tries to find the actor of the given type and tag in a root actor or all the loaded scenes.
/// <param name="tag">The tag of the actor to search for.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// </summary>
/// <returns>Actor instance if found, null otherwise.</returns>
template<typename T>
FORCE_INLINE static T* FindActor(const Tag& tag, Actor* root = nullptr)
{
return (T*)FindActor(T::GetStaticClass(), tag, root);
}
/// <summary>
/// Tries to find the script of the given type in all the loaded scenes.
/// </summary>
@@ -481,33 +528,6 @@ public:
/// </summary>
API_FUNCTION() static int32 GetLayerIndex(const StringView& layer);
public:
/// <summary>
/// Tries to find the actor with the given tag (returns the first one found).
/// </summary>
/// <param name="tag">The tag of the actor to search for.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// <returns>Found actor or null.</returns>
API_FUNCTION() static Actor* FindActor(const Tag& tag, Actor* root = nullptr);
/// <summary>
/// Tries to find the actors with the given tag (returns all found).
/// </summary>
/// <param name="tag">The tag of the actor to search for.</param>
/// <param name="activeOnly">Find only active actors.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// <returns>Found actors or empty if none.</returns>
API_FUNCTION() static Array<Actor*> FindActors(const Tag& tag, const bool activeOnly = false, Actor* root = nullptr);
/// <summary>
/// Search actors using a parent parentTag.
/// </summary>
/// <param name="parentTag">The tag to search actors with subtags belonging to this tag</param>
/// <param name="activeOnly">Find only active actors.</param>
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
/// <returns>Returns all actors that have subtags belonging to the given parent parentTag</returns>
API_FUNCTION() static Array<Actor*> FindActorsByParentTag(const Tag& parentTag, const bool activeOnly = false, Actor* root = nullptr);
private:
// Actor API
enum class ActorEventType

View File

@@ -157,14 +157,16 @@ void SceneRendering::UpdateActor(Actor* a, int32& key)
const int32 category = a->_drawCategory;
ScopeLock lock(Locker);
auto& list = Actors[category];
if (list.IsEmpty())
if (list.Count() <= key) // Ignore invalid key softly
return;
auto& e = list[key];
ASSERT_LOW_LAYER(a == e.Actor);
for (auto* listener : _listeners)
listener->OnSceneRenderingUpdateActor(a, e.Bounds);
e.LayerMask = a->GetLayerMask();
e.Bounds = a->GetSphere();
if (e.Actor == a)
{
for (auto* listener : _listeners)
listener->OnSceneRenderingUpdateActor(a, e.Bounds);
e.LayerMask = a->GetLayerMask();
e.Bounds = a->GetSphere();
}
}
void SceneRendering::RemoveActor(Actor* a, int32& key)
@@ -172,14 +174,16 @@ void SceneRendering::RemoveActor(Actor* a, int32& key)
const int32 category = a->_drawCategory;
ScopeLock lock(Locker);
auto& list = Actors[category];
if (list.HasItems())
if (list.Count() > key) // Ignore invalid key softly (eg. list after batch clear during scene unload)
{
auto& e = list[key];
ASSERT_LOW_LAYER(a == e.Actor);
for (auto* listener : _listeners)
listener->OnSceneRenderingRemoveActor(a);
e.Actor = nullptr;
e.LayerMask = 0;
auto& e = list.Get()[key];
if (e.Actor == a)
{
for (auto* listener : _listeners)
listener->OnSceneRenderingRemoveActor(a);
e.Actor = nullptr;
e.LayerMask = 0;
}
}
key = -1;
}

View File

@@ -125,6 +125,7 @@ WindowBase::~WindowBase()
{
ASSERT(!RenderTask);
ASSERT(!_swapChain);
WindowsManager::Unregister((Window*)this);
}
bool WindowBase::IsMain() const

View File

@@ -25,7 +25,6 @@ WindowsManagerService WindowsManagerServiceInstance;
Window* WindowsManager::GetByNativePtr(void* handle)
{
Window* result = nullptr;
WindowsLocker.Lock();
for (int32 i = 0; i < Windows.Count(); i++)
{
@@ -36,7 +35,6 @@ Window* WindowsManager::GetByNativePtr(void* handle)
}
}
WindowsLocker.Unlock();
return result;
}
@@ -61,7 +59,7 @@ void WindowsManagerService::Update()
// Update windows
const float deltaTime = Time::Update.UnscaledDeltaTime.GetTotalSeconds();
WindowsManager::WindowsLocker.Lock();
for (auto& win : WindowsManager::Windows)
for (Window* win : WindowsManager::Windows)
{
if (win && win->IsVisible())
win->OnUpdate(deltaTime);
@@ -74,7 +72,7 @@ void WindowsManagerService::Dispose()
// Close remaining windows
WindowsManager::WindowsLocker.Lock();
auto windows = WindowsManager::Windows;
for (auto& win : windows)
for (Window* win : windows)
{
win->Close(ClosingReason::EngineExit);
}

View File

@@ -182,7 +182,7 @@ const char* StringUtils::Find(const char* str, const char* toFind)
void StringUtils::ConvertANSI2UTF16(const char* from, Char* to, int32 fromLength, int32& toLength)
{
if (fromLength)
toLength = mbstowcs(to, from, fromLength);
toLength = (int32)mbstowcs(to, from, fromLength);
else
toLength = 0;
}

View File

@@ -1163,8 +1163,8 @@ MType* MField::GetType() const
int32 MField::GetOffset() const
{
MISSING_CODE("TODO: MField::GetOffset"); // TODO: MField::GetOffset
return 0;
static void* FieldGetOffsetPtr = GetStaticMethodPointer(TEXT("FieldGetOffset"));
return CallStaticMethod<int32, void*>(FieldGetOffsetPtr, _handle);
}
void MField::GetValue(MObject* instance, void* result) const
@@ -1175,8 +1175,8 @@ void MField::GetValue(MObject* instance, void* result) const
MObject* MField::GetValueBoxed(MObject* instance) const
{
MISSING_CODE("TODO: MField::GetValueBoxed"); // TODO: MField::GetValueBoxed
return nullptr;
static void* FieldGetValueBoxedPtr = GetStaticMethodPointer(TEXT("FieldGetValueBoxed"));
return CallStaticMethod<MObject*, void*, void*>(FieldGetValueBoxedPtr, instance, _handle);
}
void MField::SetValue(MObject* instance, void* value) const

View File

@@ -26,6 +26,7 @@
#define FEATURE_LEVEL_ES3_1 2
#define FEATURE_LEVEL_SM4 3
#define FEATURE_LEVEL_SM5 4
#define FEATURE_LEVEL_SM6 5
#if !defined(FEATURE_LEVEL)
#error "Invalid platform defines"
#endif

View File

@@ -199,7 +199,11 @@ namespace Flax.Build
if (rid == ridFallback)
ridFallback = "";
if (string.IsNullOrEmpty(dotnetPath))
dotnetPath = "/usr/share/dotnet/";
{
dotnetPath = "/usr/lib/dotnet/";
if (!Directory.Exists(dotnetPath))
dotnetPath = "/usr/share/dotnet/";
}
break;
}
case TargetPlatform.Mac: