Merge remote-tracking branch 'origin/master' into 1.9

This commit is contained in:
Wojtek Figat
2024-08-16 14:52:57 +02:00
47 changed files with 345 additions and 96 deletions

View File

@@ -80,7 +80,7 @@ namespace FlaxEditor.Content
// Translate asset type name
var typeName = TypeName;
string[] typeNamespaces = typeName.Split('.');
if (typeNamespaces.Length != 0 && typeNamespaces.Length != 0)
if (typeNamespaces.Length != 0 && typeNamespaces[typeNamespaces.Length - 1].Length != 0)
{
typeName = Utilities.Utils.GetPropertyNameUI(typeNamespaces[typeNamespaces.Length - 1]);
}

View File

@@ -208,7 +208,7 @@ namespace FlaxEditor.CustomEditors.Editors
else
{
// Draw info
Render2D.DrawText(style.FontMedium, Type != null ? $"None ({Utilities.Utils.GetPropertyNameUI(Type.ToString())})" : "-", nameRect, isEnabled ? Color.OrangeRed : Color.DarkOrange, TextAlignment.Near, TextAlignment.Center);
Render2D.DrawText(style.FontMedium, Type != null ? $"None ({Utilities.Utils.GetPropertyNameUI(Type.ToString())})" : "-", nameRect, isEnabled ? style.ForegroundGrey : style.ForegroundGrey.AlphaMultiplied(0.75f), TextAlignment.Near, TextAlignment.Center);
}
// Draw picker button

View File

@@ -22,7 +22,7 @@ namespace FlaxEditor.GUI.Dialogs
/// <summary>
/// The parent window.
/// </summary>
protected Window _window;
protected volatile Window _window;
/// <summary>
/// The dialog result.

View File

@@ -89,6 +89,9 @@ namespace FlaxEditor.Surface
private static NodesCache _nodesCache = new NodesCache(IterateNodesCache);
/// <inheritdoc />
public override bool UseContextMenuDescriptionPanel => true;
/// <summary>
/// The state machine editing context menu.
/// </summary>

View File

@@ -156,7 +156,7 @@ namespace FlaxEditor.Surface.Archetypes
Title = "Lerp",
Description = "Performs a linear interpolation",
Flags = NodeFlags.AllGraphs,
Size = new Float2(110, 60),
Size = new Float2(150, 60),
ConnectionsHints = ConnectionsHint.Numeric,
IndependentBoxes = new[] { 0, 1 },
DependentBoxes = new[] { 3 },

View File

@@ -25,6 +25,9 @@ namespace FlaxEditor.Surface
/// <inheritdoc />
public override bool CanLivePreviewValueChanges => false;
/// <inheritdoc />
public override bool UseContextMenuDescriptionPanel => true;
/// <inheritdoc />
public override string GetTypeName(ScriptType type)
{

View File

@@ -24,6 +24,9 @@ namespace FlaxEditor.Surface
/// </summary>
public FlaxEditor.Surface.Archetypes.Particles.ParticleEmitterNode RootNode => _rootNode;
/// <inheritdoc />
public override bool UseContextMenuDescriptionPanel => true;
/// <inheritdoc />
public ParticleEmitterSurface(IVisjectSurfaceOwner owner, Action onSave, FlaxEditor.Undo undo)
: base(owner, onSave, undo)

View File

@@ -8,6 +8,7 @@ using System.Reflection;
using System.Text;
using FlaxEditor.CustomEditors;
using FlaxEditor.CustomEditors.Elements;
using FlaxEditor.Options;
using FlaxEditor.Scripting;
using FlaxEditor.Utilities;
using FlaxEngine.Utilities;
@@ -71,7 +72,12 @@ namespace FlaxEditor.Surface
}
// By name
return string.Compare(x.DisplayName, y.DisplayName, StringComparison.InvariantCulture);
if (Editor.Instance.Options.Options.General.ScriptMembersOrder == GeneralOptions.MembersOrder.Alphabetical)
{
return string.Compare(x.DisplayName, y.DisplayName, StringComparison.InvariantCulture);
}
// Keep same order
return 0;
}
}

View File

@@ -492,7 +492,7 @@ namespace FlaxEditor.Surface
Focus();
return true;
}
if (_rightMouseDown || (_middleMouseDown && _middleMouseDown))
if (_rightMouseDown || _middleMouseDown)
{
// Start navigating
StartMouseCapture();

View File

@@ -197,6 +197,12 @@ namespace FlaxEditor.Tools.Foliage
{
PaintEnd();
}
// Increase or decrease brush size with scroll
if (Input.GetKey(KeyboardKeys.Shift) && !Input.GetMouseButton(MouseButton.Right))
{
Mode.CurrentBrush.Size += dt * Mode.CurrentBrush.Size * Input.Mouse.ScrollDelta * 5f;
}
// Perform detailed tracing to find cursor location for the foliage placement
var mouseRay = Owner.MouseRay;

View File

@@ -113,6 +113,7 @@ namespace FlaxEditor.Tools.Terrain
}
_createTerrainButton.Clicked += OnCreateNewTerrainClicked;
OnSelectionChanged();
}
private void OnSceneLoaded(Scene arg1, Guid arg2)
@@ -159,6 +160,7 @@ namespace FlaxEditor.Tools.Terrain
}
_noTerrainPanel.Visible = terrain == null;
_modes.Visible = !_noTerrainPanel.Visible;
}
private void InitSculptMode()

View File

@@ -151,7 +151,7 @@ namespace FlaxEditor.Tools.Terrain
}
// Increase or decrease brush size with scroll
if (Input.GetKey(KeyboardKeys.Shift))
if (Input.GetKey(KeyboardKeys.Shift) && !Input.GetMouseButton(MouseButton.Right))
{
Mode.CurrentBrush.Size += dt * Mode.CurrentBrush.Size * Input.Mouse.ScrollDelta * 5f;
}

View File

@@ -159,7 +159,7 @@ namespace FlaxEditor.Tools.Terrain
}
// Increase or decrease brush size with scroll
if (Input.GetKey(KeyboardKeys.Shift))
if (Input.GetKey(KeyboardKeys.Shift) && !Input.GetMouseButton(MouseButton.Right))
{
Mode.CurrentBrush.Size += dt * Mode.CurrentBrush.Size * Input.Mouse.ScrollDelta * 5f;
}

View File

@@ -79,7 +79,7 @@ namespace FlaxEditor.Utilities
value = Convert.ToInt32(value);
else if (type.Type == typeof(long))
value = Convert.ToInt64(value);
else if (type.Type == typeof(int))
else if (type.Type == typeof(ushort))
value = Convert.ToUInt16(value);
else if (type.Type == typeof(uint))
value = Convert.ToUInt32(value);

View File

@@ -1612,7 +1612,7 @@ namespace FlaxEditor.Viewport
_input.IsPanning = !isAltDown && mbDown && !rbDown;
_input.IsRotating = !isAltDown && !mbDown && rbDown;
_input.IsMoving = !isAltDown && mbDown && rbDown;
_input.IsZooming = wheelInUse && !_input.IsShiftDown;
_input.IsZooming = wheelInUse && !(_input.IsShiftDown || (!ContainsFocus && FlaxEngine.Input.GetKey(KeyboardKeys.Shift)));
_input.IsOrbiting = isAltDown && lbDown && !mbDown && !rbDown;
// Control move speed with RMB+Wheel

View File

@@ -12,6 +12,7 @@ using FlaxEditor.Viewport.Previews;
using FlaxEditor.Windows.Assets;
using FlaxEngine;
using FlaxEngine.GUI;
using Utils = FlaxEditor.Utilities.Utils;
namespace FlaxEditor.Viewport
{
@@ -62,6 +63,7 @@ namespace FlaxEditor.Viewport
private UpdateDelegate _update;
private readonly ViewportDebugDrawData _debugDrawData = new ViewportDebugDrawData(32);
private readonly List<Actor> _debugDrawActors = new List<Actor>();
private PrefabSpritesRenderer _spritesRenderer;
private IntPtr _tempDebugDrawContext;
@@ -623,14 +625,44 @@ namespace FlaxEditor.Viewport
DebugDraw.DrawActors(new IntPtr(actors), _debugDrawData.ActorsCount, false);
}
}
// Debug draw all actors in prefab
// Debug draw all actors in prefab and collect actors
var viewFlags = Task.ViewFlags;
var collectActors = (viewFlags & ViewFlags.PhysicsDebug) != 0 || (viewFlags & ViewFlags.LightsDebug) != 0;
_debugDrawActors.Clear();
foreach (var child in SceneGraphRoot.ChildNodes)
{
if (child is not ActorNode actorNode || !actorNode.Actor)
continue;
DebugDraw.DrawActorsTree(actorNode.Actor);
var actor = actorNode.Actor;
if (collectActors)
Utils.GetActorsTree(_debugDrawActors, actor);
DebugDraw.DrawActorsTree(actor);
}
// Draw physics debug
if ((viewFlags & ViewFlags.PhysicsDebug) != 0)
{
foreach (var actor in _debugDrawActors)
{
if (actor is Collider c && c.IsActiveInHierarchy)
{
DebugDraw.DrawColliderDebugPhysics(c, renderContext.View);
}
}
}
// Draw lights debug
if ((viewFlags & ViewFlags.LightsDebug) != 0)
{
foreach (var actor in _debugDrawActors)
{
if (actor is Light l && l.IsActiveInHierarchy)
DebugDraw.DrawLightDebug(l, renderContext.View);
}
}
_debugDrawActors.Clear();
}
}
}

View File

@@ -1,11 +1,13 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using FlaxEditor.CustomEditors;
using FlaxEditor.SceneGraph;
using FlaxEditor.Viewport;
using FlaxEngine;
using FlaxEngine.GUI;
namespace FlaxEditor.Windows
@@ -19,6 +21,8 @@ namespace FlaxEditor.Windows
{
private IEnumerable<object> undoRecordObjects;
private readonly Dictionary<Guid, float> _actorScrollValues = new Dictionary<Guid, float>();
/// <inheritdoc />
public override bool UseLayoutData => true;
@@ -57,9 +61,42 @@ namespace FlaxEditor.Windows
Presenter.GetUndoObjects += GetUndoObjects;
Presenter.Features |= FeatureFlags.CacheExpandedGroups;
VScrollBar.ValueChanged += OnScrollValueChanged;
Editor.SceneEditing.SelectionChanged += OnSelectionChanged;
}
/// <inheritdoc />
public override void OnSceneLoaded(Scene scene, Guid sceneId)
{
base.OnSceneLoaded(scene, sceneId);
// Clear scroll values if new scene is loaded non additively
if (Level.ScenesCount > 1)
return;
_actorScrollValues.Clear();
}
private void OnScrollValueChanged()
{
if (Editor.SceneEditing.SelectionCount > 1)
return;
// Clear first 10 scroll values to keep the memory down. Dont need to cache very single value in a scene. We could expose this as a editor setting in the future.
if (_actorScrollValues.Count >= 20)
{
int i = 0;
foreach (var e in _actorScrollValues)
{
if (i >= 10)
break;
_actorScrollValues.Remove(e.Key);
i += 1;
}
}
_actorScrollValues[Editor.SceneEditing.Selection[0].ID] = VScrollBar.TargetValue;
}
private IEnumerable<object> GetUndoObjects(CustomEditorPresenter customEditorPresenter)
{
return undoRecordObjects;
@@ -75,6 +112,10 @@ namespace FlaxEditor.Windows
undoRecordObjects = Editor.SceneEditing.Selection.ConvertAll(x => x.UndoRecordObject).Distinct();
var objects = Editor.SceneEditing.Selection.ConvertAll(x => x.EditableObject).Distinct();
Presenter.Select(objects);
// Set scroll value of window if it exists
if (Editor.SceneEditing.SelectionCount == 1)
VScrollBar.TargetValue = _actorScrollValues.GetValueOrDefault(Editor.SceneEditing.Selection[0].ID, 0);
}
/// <inheritdoc />

View File

@@ -2237,8 +2237,9 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
{
// Start playing animation
bucket.Index = i;
bucket.TimePosition = 0.0f;
bucket.BlendInPosition = 0.0f;
// Keep bucket time position and blend in time for if blending between two anims in the same slot.
bucket.TimePosition = bucket.TimePosition;
bucket.BlendInPosition = bucket.BlendInPosition;
bucket.BlendOutPosition = 0.0f;
bucket.LoopsDone = 0;
bucket.LoopsLeft = slot.LoopCount;
@@ -2248,6 +2249,12 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
if (bucket.Index == -1 || !slots[bucket.Index].Animation->IsLoaded())
{
value = tryGetValue(node->GetBox(1), Value::Null);
// Reset times if time is left over from playing between different anims in the same slot.
if (bucket.BlendInPosition > 0)
{
bucket.TimePosition = 0;
bucket.BlendInPosition = 0;
}
return;
}
}
@@ -2256,12 +2263,6 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
auto& slot = slots[bucket.Index];
Animation* anim = slot.Animation;
ASSERT(slot.Animation && slot.Animation->IsLoaded());
if (slot.Reset)
{
// Start from the begining
slot.Reset = false;
bucket.TimePosition = 0.0f;
}
const float deltaTime = slot.Pause ? 0.0f : context.DeltaTime * slot.Speed;
const float length = anim->GetLength();
const bool loop = bucket.LoopsLeft != 0;
@@ -2285,6 +2286,57 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
// Speed is accounted for in the new time pos, so keep sample speed at 1
value = SampleAnimation(node, loop, length, 0.0f, bucket.TimePosition, newTimePos, anim, 1);
bucket.TimePosition = newTimePos;
// On animation slot stop
if (slot.Reset)
{
// Blend between last anim and new anim if found, otherwise blend back to input.
Animation* sAnim = nullptr;
for (int32 i = 0; i < slots.Count(); i++)
{
if (bucket.Index == i)
continue;
auto& s = slots[i];
if (s.Animation && s.Name == slotName)
{
sAnim = s.Animation;
}
}
float oldTimePos = bucket.BlendOutPosition;
bucket.BlendOutPosition += deltaTime;
bucket.BlendInPosition = bucket.BlendOutPosition;
const float alpha = bucket.BlendOutPosition / slot.BlendOutTime;
if (sAnim != nullptr)
{
auto sValue = SampleAnimation(node, false, sAnim->GetLength(), 0.0f, oldTimePos, bucket.BlendInPosition, sAnim, 1);
//value = SampleAnimationsWithBlend(node, false, length, 0.0f, bucket.TimePosition, newTimePos, anim, sAnim, 1, 1, alpha);
value = Blend(node, value, sValue, alpha, AlphaBlendMode::HermiteCubic);
}
else
{
auto input = tryGetValue(node->GetBox(1), Value::Null);
value = Blend(node, value, input, alpha, AlphaBlendMode::HermiteCubic);
}
if (bucket.BlendOutPosition >= slot.BlendOutTime)
{
// Start from the beginning or the blend in position if next anim found.
slot.Animation = nullptr;
slot.Reset = false;
if (!sAnim)
{
bucket.TimePosition = 0;
bucket.BlendInPosition = 0;
}
else
{
bucket.TimePosition = bucket.BlendInPosition;
}
}
break;
}
if (bucket.LoopsLeft == 0 && slot.BlendOutTime > 0.0f && length - slot.BlendOutTime < bucket.TimePosition)
{
// Blend out

View File

@@ -196,6 +196,7 @@ bool AudioService::Init()
LOG(Info, "Audio system initialization... (backend: {0})", AudioBackend::Name());
EnableHRTF = settings->EnableHRTF;
if (AudioBackend::Init())
{
LOG(Warning, "Failed to initialize audio backend.");

View File

@@ -313,6 +313,7 @@ void AudioSource::PlayInternal()
{
AudioBackend::Source::Play(SourceID);
_isActuallyPlayingSth = true;
_startingToPlay = true;
}
#if USE_EDITOR
@@ -394,6 +395,30 @@ void AudioSource::Update()
AudioBackend::Source::VelocityChanged(SourceID, _velocity);
}
// Reset starting to play value once time is greater than zero
if (_startingToPlay && GetTime() > 0.0f)
{
_startingToPlay = false;
}
if (!UseStreaming() && Math::NearEqual(GetTime(), 0.0f) && _isActuallyPlayingSth && !_startingToPlay)
{
int32 queuedBuffers;
AudioBackend::Source::GetQueuedBuffersCount(this, queuedBuffers);
if (queuedBuffers)
{
if (GetIsLooping())
{
Stop();
Play();
}
else
{
Stop();
}
}
}
// Skip other update logic if it's not valid streamable source
if (!UseStreaming() || SourceID == 0)
return;

View File

@@ -56,6 +56,7 @@ private:
bool _allowSpatialization;
bool _isActuallyPlayingSth = false;
bool _startingToPlay = false;
bool _needToUpdateStreamingBuffers = false;
States _state = States::Stopped;

View File

@@ -662,13 +662,13 @@ bool FlaxStorage::LoadAssetChunk(FlaxChunk* chunk)
if (!failed)
{
stream->SetPosition(chunk->LocationInFile.Address);
if (!stream->HasError())
break;
}
if (!stream->HasError())
break;
}
}
if (stream->HasError())
if (!stream || stream->HasError())
{
failed = true;
UnlockChunks();

View File

@@ -94,8 +94,8 @@ namespace FlaxEngine
throw new ArgumentOutOfRangeException(nameof(values), "There must be sixteen and only four input values for Matrix2x2.");
M11 = values[0];
M12 = values[1];
M21 = values[3];
M22 = values[4];
M21 = values[2];
M22 = values[3];
}
/// <summary>

View File

@@ -289,7 +289,7 @@ void Quaternion::Billboard(const Float3& objectPosition, const Float3& cameraPos
Quaternion Quaternion::FromDirection(const Float3& direction)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), Quaternion::Identity);
Quaternion orientation;
if (Float3::Dot(direction, Float3::Up) >= 0.999f)
{

View File

@@ -57,6 +57,7 @@ using Real = System.Single;
using System;
using System.Globalization;
using System.Runtime.CompilerServices;
using FlaxEngine.Assertions;
namespace FlaxEngine
{
@@ -77,6 +78,7 @@ namespace FlaxEngine
{
Position = position;
Direction = direction;
Assert.IsTrue(Direction.IsNormalized, "The Ray Direction was not normalized");
}
/// <summary>

View File

@@ -46,7 +46,7 @@ public:
: Position(position)
, Direction(direction)
{
ASSERT(Direction.IsNormalized());
CHECK_DEBUG(Direction.IsNormalized());
}
public:

View File

@@ -324,15 +324,14 @@ public:
{
if (length <= 0)
return;
if (Base::Length() == 0)
auto prev = Base::_data;
const auto prevLength = Base::_length;
if (prevLength == 0 || prev == nullptr)
{
Copy(data, length);
return;
}
auto prev = Base::_data;
const auto prevLength = Base::_length;
Base::_length = prevLength + length;
Base::_data = (T*)Allocator::Allocate(Base::_length * sizeof(T));

View File

@@ -2702,8 +2702,8 @@ void Variant::SetAsset(Asset* asset)
SetType(VariantType(VariantType::Asset));
if (AsAsset)
{
asset->OnUnloaded.Unbind<Variant, &Variant::OnAssetUnloaded>(this);
asset->RemoveReference();
AsAsset->OnUnloaded.Unbind<Variant, &Variant::OnAssetUnloaded>(this);
AsAsset->RemoveReference();
}
AsAsset = asset;
if (asset)

View File

@@ -27,6 +27,8 @@
#include "Engine/Render2D/FontAsset.h"
#if USE_EDITOR
#include "Editor/Editor.h"
#include "Engine/Level/Actors/Light.h"
#include "Engine/Physics/Colliders/Collider.h"
#endif
// Debug draw service configuration
@@ -950,9 +952,26 @@ void DebugDraw::DrawActorsTree(Actor* actor)
actor->TreeExecute(function);
}
#if USE_EDITOR
void DebugDraw::DrawColliderDebugPhysics(Collider* collider, RenderView& view)
{
if (!collider)
return;
collider->DrawPhysicsDebug(view);
}
void DebugDraw::DrawLightDebug(Light* light, RenderView& view)
{
if (!light)
return;
light->DrawLightsDebug(view);
}
#endif
void DebugDraw::DrawAxisFromDirection(const Vector3& origin, const Vector3& direction, float size, float duration, bool depthTest)
{
ASSERT(direction.IsNormalized());
CHECK_DEBUG(direction.IsNormalized());
const auto rot = Quaternion::FromDirection(direction);
const Vector3 up = (rot * Vector3::Up);
const Vector3 forward = (rot * Vector3::Forward);
@@ -978,7 +997,7 @@ void DebugDraw::DrawRay(const Vector3& origin, const Vector3& direction, const C
void DebugDraw::DrawRay(const Vector3& origin, const Vector3& direction, const Color& color, float length, float duration, bool depthTest)
{
ASSERT(direction.IsNormalized());
CHECK_DEBUG(direction.IsNormalized());
if (isnan(length) || isinf(length))
return;
DrawLine(origin, origin + (direction * length), color, duration, depthTest);

View File

@@ -8,6 +8,9 @@
#include "Engine/Core/Math/Color.h"
#include "Engine/Core/Types/Span.h"
struct RenderView;
class Collider;
class Light;
struct RenderContext;
class GPUTextureView;
class GPUContext;
@@ -70,9 +73,23 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
/// <summary>
/// Draws the debug shapes for the given actor and the actor's children
/// </summary>
/// /// <param name="actor">The actor to start drawing at.</param>
/// <param name="actor">The actor to start drawing at.</param>
API_FUNCTION() static void DrawActorsTree(Actor* actor);
#if USE_EDITOR
/// <summary>
/// Draws the physics debug shapes for the given collider. Editor Only
/// </summary>
/// <param name="collider">The collider to draw.</param>
/// <param name="view">The render view to draw in.</param>
API_FUNCTION() static void DrawColliderDebugPhysics(Collider* collider, RenderView& view);
/// <summary>
/// Draws the light debug shapes for the given light. Editor Only
/// </summary>
/// <param name="light">The light debug to draw.</param>
/// <param name="view">The render view to draw in.</param>
API_FUNCTION() static void DrawLightDebug(Light* light, RenderView& view);
#endif
/// <summary>
/// Draws the lines axis from direction.
/// </summary>

View File

@@ -199,6 +199,7 @@ void GameBaseImpl::OnMainWindowClosed()
// Request engine exit
Globals::IsRequestingExit = true;
Engine::RequestingExit();
}
void GameBaseImpl::OnPostRender(GPUContext* context, RenderContext& renderContext)

View File

@@ -70,6 +70,7 @@ Action Engine::LateFixedUpdate;
Action Engine::Draw;
Action Engine::Pause;
Action Engine::Unpause;
Action Engine::RequestingExit;
Window* Engine::MainWindow = nullptr;
int32 Engine::Main(const Char* cmdLine)
@@ -259,10 +260,12 @@ void Engine::RequestExit(int32 exitCode)
{
Globals::IsRequestingExit = true;
Globals::ExitCode = exitCode;
RequestingExit();
}
#else
Globals::IsRequestingExit = true;
Globals::ExitCode = exitCode;
RequestingExit();
#endif
}

View File

@@ -79,6 +79,11 @@ public:
/// </summary>
static Action Unpause;
/// <summary>
/// Event called when the engine is requesting exit.
/// </summary>
API_EVENT() static Action RequestingExit;
public:
/// <summary>

View File

@@ -59,9 +59,19 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Globals);
// True if fatal error occurred (engine is exiting)
static bool FatalErrorOccurred;
// True if engine need to be closed
// True if engine needs to be closed
static bool IsRequestingExit;
/// <summary>
/// True if engine needs to be closed
/// </summary>
API_PROPERTY() FORCE_INLINE static bool GetIsRequestingExit() { return IsRequestingExit; }
/// <summary>
/// True if fatal error occurred (engine is exiting)
/// </summary>
API_PROPERTY() FORCE_INLINE static bool GetFatalErrorOccurred() { return FatalErrorOccurred; }
// Exit code
static int32 ExitCode;

View File

@@ -996,37 +996,37 @@ public:
/// <summary>
/// Called when actor parent gets changed.
/// </summary>
virtual void OnParentChanged();
API_FUNCTION() virtual void OnParentChanged();
/// <summary>
/// Called when actor transform gets changed.
/// </summary>
virtual void OnTransformChanged();
API_FUNCTION() virtual void OnTransformChanged();
/// <summary>
/// Called when actor active state gets changed.
/// </summary>
virtual void OnActiveChanged();
API_FUNCTION() virtual void OnActiveChanged();
/// <summary>
/// Called when actor active in tree state gets changed.
/// </summary>
virtual void OnActiveInTreeChanged();
API_FUNCTION() virtual void OnActiveInTreeChanged();
/// <summary>
/// Called when order in parent children array gets changed.
/// </summary>
virtual void OnOrderInParentChanged();
API_FUNCTION() virtual void OnOrderInParentChanged();
/// <summary>
/// Called when actor static flag gets changed.
/// </summary>
virtual void OnStaticFlagsChanged();
API_FUNCTION() virtual void OnStaticFlagsChanged();
/// <summary>
/// Called when layer gets changed.
/// </summary>
virtual void OnLayerChanged();
API_FUNCTION() virtual void OnLayerChanged();
/// <summary>
/// Called when adding object to the game.

View File

@@ -506,7 +506,7 @@ void AnimatedModel::StopSlotAnimation(const StringView& slotName, Animation* ani
{
if (slot.Animation == anim && slot.Name == slotName)
{
slot.Animation = nullptr;
//slot.Animation = nullptr; // TODO: make an immediate version of this method and set the animation to nullptr.
slot.Reset = true;
break;
}

View File

@@ -71,7 +71,7 @@ void Collider::SetContactOffset(float value)
bool Collider::RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance) const
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
resultHitDistance = MAX_float;
if (_shape == nullptr)
return false;
@@ -80,7 +80,7 @@ bool Collider::RayCast(const Vector3& origin, const Vector3& direction, float& r
bool Collider::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, float maxDistance) const
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
if (_shape == nullptr)
return false;
return PhysicsBackend::RayCastShape(_shape, _transform.Translation, _transform.Orientation, origin, direction, hitInfo, maxDistance);

View File

@@ -154,10 +154,6 @@ protected:
/// </summary>
void RemoveStaticActor();
#if USE_EDITOR
virtual void DrawPhysicsDebug(RenderView& view);
#endif
private:
void OnMaterialChanged();
@@ -169,6 +165,10 @@ public:
void ClosestPoint(const Vector3& point, Vector3& result) const final;
bool ContainsPoint(const Vector3& point) const final;
#if USE_EDITOR
virtual void DrawPhysicsDebug(RenderView& view);
#endif
protected:
// [PhysicsColliderActor]
void OnEnable() override;

View File

@@ -235,91 +235,91 @@ bool Physics::LineCastAll(const Vector3& start, const Vector3& end, Array<RayCas
bool Physics::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->RayCast(origin, direction, maxDistance, layerMask, hitTriggers);
}
bool Physics::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->RayCast(origin, direction, hitInfo, maxDistance, layerMask, hitTriggers);
}
bool Physics::RayCastAll(const Vector3& origin, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->RayCastAll(origin, direction, results, maxDistance, layerMask, hitTriggers);
}
bool Physics::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->BoxCast(center, halfExtents, direction, rotation, maxDistance, layerMask, hitTriggers);
}
bool Physics::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->BoxCast(center, halfExtents, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
}
bool Physics::BoxCastAll(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->BoxCastAll(center, halfExtents, direction, results, rotation, maxDistance, layerMask, hitTriggers);
}
bool Physics::SphereCast(const Vector3& center, const float radius, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->SphereCast(center, radius, direction, maxDistance, layerMask, hitTriggers);
}
bool Physics::SphereCast(const Vector3& center, const float radius, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->SphereCast(center, radius, direction, hitInfo, maxDistance, layerMask, hitTriggers);
}
bool Physics::SphereCastAll(const Vector3& center, const float radius, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->SphereCastAll(center, radius, direction, results, maxDistance, layerMask, hitTriggers);
}
bool Physics::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->CapsuleCast(center, radius, height, direction, rotation, maxDistance, layerMask, hitTriggers);
}
bool Physics::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->CapsuleCast(center, radius, height, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
}
bool Physics::CapsuleCastAll(const Vector3& center, const float radius, const float height, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->CapsuleCastAll(center, radius, height, direction, results, rotation, maxDistance, layerMask, hitTriggers);
}
bool Physics::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->ConvexCast(center, convexMesh, scale, direction, rotation, maxDistance, layerMask, hitTriggers);
}
bool Physics::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->ConvexCast(center, convexMesh, scale, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
}
bool Physics::ConvexCastAll(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return DefaultScene->ConvexCastAll(center, convexMesh, scale, direction, results, rotation, maxDistance, layerMask, hitTriggers);
}
@@ -520,91 +520,91 @@ bool PhysicsScene::LineCastAll(const Vector3& start, const Vector3& end, Array<R
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::RayCast(_scene, origin, direction, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::RayCast(_scene, origin, direction, hitInfo, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::RayCastAll(const Vector3& origin, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::RayCastAll(_scene, origin, direction, results, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::BoxCast(_scene, center, halfExtents, direction, rotation, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::BoxCast(_scene, center, halfExtents, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::BoxCastAll(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::BoxCastAll(_scene, center, halfExtents, direction, results, rotation, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::SphereCast(const Vector3& center, const float radius, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::SphereCast(_scene, center, radius, direction, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::SphereCast(const Vector3& center, const float radius, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::SphereCast(_scene, center, radius, direction, hitInfo, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::SphereCastAll(const Vector3& center, const float radius, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::SphereCastAll(_scene, center, radius, direction, results, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::CapsuleCast(_scene, center, radius, height, direction, rotation, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::CapsuleCast(_scene, center, radius, height, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::CapsuleCastAll(const Vector3& center, const float radius, const float height, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::CapsuleCastAll(_scene, center, radius, height, direction, results, rotation, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::ConvexCast(_scene, center, convexMesh, scale, direction, rotation, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::ConvexCast(_scene, center, convexMesh, scale, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
}
bool PhysicsScene::ConvexCastAll(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
return PhysicsBackend::ConvexCastAll(_scene, center, convexMesh, scale, direction, results, rotation, maxDistance, layerMask, hitTriggers);
}

View File

@@ -271,6 +271,7 @@ void PlatformBase::Fatal(const Char* msg, void* context)
Globals::FatalErrorOccurred = true;
Globals::IsRequestingExit = true;
Globals::ExitCode = -1;
Engine::RequestingExit();
// Collect crash info (platform-dependant implementation that might collect stack trace and/or create memory dump)
{

View File

@@ -35,7 +35,7 @@
#endif
#if ENABLE_ASSERTION
// Performs hard assertion of the expression. Crashes the engine and inserts debugger break in case of expression fail.
// Performs a hard assertion of the expression. Crashes the engine and triggers a debugger break if the expression fails.
#define ASSERT(expression) \
if (!(expression)) \
{ \
@@ -46,24 +46,40 @@
Platform::Assert(#expression, __FILE__, __LINE__); \
}
#else
// Performs a hard assertion of the expression. Crashes the engine and triggers a debugger break if the expression fails.
#define ASSERT(expression) ((void)0)
#endif
#if ENABLE_ASSERTION_LOW_LAYERS
// Performs a hard assertion of the expression. Crashes the engine and triggers a debugger break if the expression fails.
#define ASSERT_LOW_LAYER(x) ASSERT(x)
#else
// Performs a hard assertion of the expression. Crashes the engine and triggers a debugger break if the expression fails.
#define ASSERT_LOW_LAYER(x)
#endif
// Performs soft check of the expression. Logs the expression fail to log and returns the function call.
// Performs a soft check of the expression. Logs the expression failure and returns from the function call.
#define CHECK(expression) \
if (!(expression)) \
{ \
Platform::CheckFailed(#expression, __FILE__, __LINE__); \
return; \
}
// Performs a soft check of the expression. Logs the expression failure and returns from the function call using the given return value.
#define CHECK_RETURN(expression, returnValue) \
if (!(expression)) \
{ \
Platform::CheckFailed(#expression, __FILE__, __LINE__); \
return returnValue; \
}
#if ENABLE_ASSERTION
// Performs a soft check of the expression. Logs the expression failure and returns from the function call.
#define CHECK_DEBUG(expression) CHECK(expression)
// Performs a soft check of the expression. Logs the expression failure and returns from the function call using the given return value.
#define CHECK_RETURN_DEBUG(expression, returnValue) CHECK_RETURN(expression, returnValue)
#else
// Performs a soft check of the expression. Logs the expression failure and returns from the function call.
#define CHECK_DEBUG(expression) ((void)0)
// Performs a soft check of the expression. Logs the expression failure and returns from the function call using the given return value.
#define CHECK_RETURN_DEBUG(expression, returnValue) ((void)0)
#endif

View File

@@ -130,7 +130,7 @@ public:
}
/// <summary>
/// Gets the terrain LODs distribution parameter. Adjusts terrain chunks transitions distances. Use lower value to increase terrain quality or higher value to increase performance. Default value is 0.75.
/// Gets the terrain LODs distribution parameter. Adjusts terrain chunks transitions distances. Use lower value to increase terrain quality or higher value to increase performance.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(70), DefaultValue(0.6f), Limit(0, 5, 0.01f), EditorDisplay(\"Terrain\", \"LOD Distribution\")")
FORCE_INLINE float GetLODDistribution() const
@@ -139,7 +139,7 @@ public:
}
/// <summary>
/// Sets the terrain LODs distribution parameter. Adjusts terrain chunks transitions distances. Use lower value to increase terrain quality or higher value to increase performance. Default value is 0.75.
/// Sets the terrain LODs distribution parameter. Adjusts terrain chunks transitions distances. Use lower value to increase terrain quality or higher value to increase performance.
/// </summary>
API_PROPERTY() void SetLODDistribution(float value);

View File

@@ -1963,7 +1963,7 @@ bool TerrainPatch::UpdateCollision()
bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance) const
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
if (_physicsShape == nullptr)
return false;
Vector3 shapePos;
@@ -1974,7 +1974,7 @@ bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, floa
bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, Vector3& resultHitNormal, float maxDistance) const
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
if (_physicsShape == nullptr)
return false;
Vector3 shapePos;
@@ -1992,7 +1992,7 @@ bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, floa
bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, TerrainChunk*& resultChunk, float maxDistance) const
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
if (_physicsShape == nullptr)
return false;
Vector3 shapePos;
@@ -2030,7 +2030,7 @@ bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, floa
bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, float maxDistance) const
{
ASSERT(direction.IsNormalized());
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
if (_physicsShape == nullptr)
return false;
Vector3 shapePos;

View File

@@ -77,7 +77,7 @@ namespace FlaxEngine.GUI
/// </summary>
public void Hide()
{
_window.Show();
_window.Hide();
}
/// <summary>

View File

@@ -17,7 +17,7 @@ MMethod* UICanvas_PostDeserialize = nullptr;
MMethod* UICanvas_Enable = nullptr;
MMethod* UICanvas_Disable = nullptr;
#if USE_EDITOR
MMethod* UICanvas_OnActiveInTreeChanged = nullptr;
MMethod* UICanvas_ActiveInTreeChanged = nullptr;
#endif
MMethod* UICanvas_EndPlay = nullptr;
MMethod* UICanvas_ParentChanged = nullptr;
@@ -49,7 +49,7 @@ UICanvas::UICanvas(const SpawnParams& params)
UICanvas_Enable = mclass->GetMethod("Enable");
UICanvas_Disable = mclass->GetMethod("Disable");
#if USE_EDITOR
UICanvas_OnActiveInTreeChanged = mclass->GetMethod("OnActiveInTreeChanged");
UICanvas_ActiveInTreeChanged = mclass->GetMethod("ActiveInTreeChanged");
#endif
UICanvas_EndPlay = mclass->GetMethod("EndPlay");
UICanvas_ParentChanged = mclass->GetMethod("ParentChanged");
@@ -182,7 +182,7 @@ void UICanvas::OnTransformChanged()
void UICanvas::OnActiveInTreeChanged()
{
UICANVAS_INVOKE(OnActiveInTreeChanged);
UICANVAS_INVOKE(ActiveInTreeChanged);
// Base
Actor::OnActiveInTreeChanged();

View File

@@ -777,7 +777,7 @@ namespace FlaxEngine
}
#if FLAX_EDITOR
internal void OnActiveInTreeChanged()
internal void ActiveInTreeChanged()
{
if (RenderMode == CanvasRenderMode.ScreenSpace && _editorRoot != null && _guiRoot != null)
{

View File

@@ -156,6 +156,7 @@ namespace Flax.Build.Bindings
// Numbers
if (float.TryParse(value, out _) || (value[value.Length - 1] == 'f' && float.TryParse(value.Substring(0, value.Length - 1), out _)))
{
value = value.Replace(".f", ".0f");
// If the value type is different than the value (eg. value is int but the field is float) then cast it for the [DefaultValue] attribute
if (valueType != null && attribute)
return $"({GenerateCSharpNativeToManaged(buildData, valueType, caller)}){value}";
@@ -179,7 +180,7 @@ namespace Flax.Build.Bindings
foreach (var vectorType in CSharpVectorTypes)
{
if (value.Length > vectorType.Length + 4 && value.StartsWith(vectorType) && value[vectorType.Length] == '(')
return $"typeof({vectorType}), \"{value.Substring(vectorType.Length + 1, value.Length - vectorType.Length - 2).Replace("f", "")}\"";
return $"typeof({vectorType}), \"{value.Substring(vectorType.Length + 1, value.Length - vectorType.Length - 2).Replace(".f", ".0").Replace("f", "")}\"";
}
return null;