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

# Conflicts:
#	Flax.flaxproj
#	Source/Editor/Cooker/Steps/DeployDataStep.cpp
This commit is contained in:
Wojtek Figat
2023-12-20 00:39:15 +01:00
92 changed files with 1509 additions and 776 deletions

View File

@@ -493,7 +493,15 @@ namespace FlaxEditor.Surface.Archetypes
{
TypeID = 10,
Title = "Blend Additive",
Description = "Blend animation poses (with additive mode)",
Description =
"Blend animation poses (with additive mode)" +
"\n" +
"\nNote: " +
"\nOrder of nodes matters, because Additive animation is appplayed on top of curent frame." +
"\n" +
"\nTip for blender users:" +
"\nInside NLA the the order is bottom (first node in flax) to the top (last node in flax)" +
"\nu need to place it in this order to get correct resoults",
Flags = NodeFlags.AnimGraph,
Size = new Float2(170, 80),
DefaultValues = new object[]

View File

@@ -755,6 +755,29 @@ namespace FlaxEditor.Surface.Archetypes
}
}
/// <inheritdoc />
public override void OnDeleted(SurfaceNodeActions action)
{
// Unlink from the current parent (when deleted by user)
var node = Node;
if (node != null)
{
if (action == SurfaceNodeActions.User)
{
var decorators = node.DecoratorIds;
decorators.Remove(ID);
node.DecoratorIds = decorators;
}
else
{
node._decorators = null;
node.ResizeAuto();
}
}
base.OnDeleted(action);
}
public override void OnSurfaceCanEditChanged(bool canEdit)
{
base.OnSurfaceCanEditChanged(canEdit);

View File

@@ -19,6 +19,7 @@ namespace FlaxEditor.Surface.Undo
private ushort _typeId;
private Float2 _nodeLocation;
private object[] _nodeValues;
private SurfaceNodeActions _actionType = SurfaceNodeActions.User; // Action usage flow is first to apply user effect such as removing/adding node, then we use Undo type so node can react to this
public AddRemoveNodeAction(SurfaceNode node, bool isAdd)
{
@@ -38,6 +39,7 @@ namespace FlaxEditor.Surface.Undo
Add();
else
Remove();
_actionType = SurfaceNodeActions.Undo;
}
/// <inheritdoc />
@@ -67,8 +69,8 @@ namespace FlaxEditor.Surface.Undo
else if (_nodeValues != null && _nodeValues.Length != 0)
throw new InvalidOperationException("Invalid node values.");
node.Location = _nodeLocation;
context.OnControlLoaded(node, SurfaceNodeActions.Undo);
node.OnSurfaceLoaded(SurfaceNodeActions.Undo);
context.OnControlLoaded(node, _actionType);
node.OnSurfaceLoaded(_actionType);
context.MarkAsModified();
}
@@ -89,7 +91,7 @@ namespace FlaxEditor.Surface.Undo
// Remove node
context.Nodes.Remove(node);
context.OnControlDeleted(node, SurfaceNodeActions.Undo);
context.OnControlDeleted(node, _actionType);
context.MarkAsModified();
}

View File

@@ -837,7 +837,7 @@ namespace FlaxEditor.Surface
actions.Add(action);
}
Undo.AddAction(new MultiUndoAction(actions, nodes.Count == 1 ? "Remove node" : "Remove nodes"));
AddBatchedUndoAction(new MultiUndoAction(actions, nodes.Count == 1 ? "Remove node" : "Remove nodes"));
}
}

View File

@@ -62,6 +62,19 @@ namespace FlaxEditor.Surface
return true;
}
private string GetBoxDebuggerTooltip(ref Editor.VisualScriptLocal local)
{
if (string.IsNullOrEmpty(local.ValueTypeName))
{
if (string.IsNullOrEmpty(local.Value))
return string.Empty;
return local.Value;
}
if (string.IsNullOrEmpty(local.Value))
return $"({local.ValueTypeName})";
return $"{local.Value}\n({local.ValueTypeName})";
}
/// <inheritdoc />
public override void OnNodeBreakpointEdited(SurfaceNode node)
{
@@ -95,7 +108,7 @@ namespace FlaxEditor.Surface
ref var local = ref state.Locals[i];
if (local.BoxId == box.ID && local.NodeId == box.ParentNode.ID)
{
text = $"{local.Value ?? string.Empty} ({local.ValueTypeName})";
text = GetBoxDebuggerTooltip(ref local);
return true;
}
}
@@ -107,7 +120,7 @@ namespace FlaxEditor.Surface
ref var local = ref state.Locals[i];
if (local.BoxId == connectedBox.ID && local.NodeId == connectedBox.ParentNode.ID)
{
text = $"{local.Value ?? string.Empty} ({local.ValueTypeName})";
text = GetBoxDebuggerTooltip(ref local);
return true;
}
}
@@ -123,9 +136,33 @@ namespace FlaxEditor.Surface
BoxId = box.ID,
};
var script = ((Windows.Assets.VisualScriptWindow)box.Surface.Owner).Asset;
if (Editor.Internal_EvaluateVisualScriptLocal(Object.GetUnmanagedPtr(script), ref local))
if (Editor.EvaluateVisualScriptLocal(script, ref local))
{
text = $"{local.Value ?? string.Empty} ({local.ValueTypeName})";
// Check if got no value (null)
if (string.IsNullOrEmpty(local.ValueTypeName) && string.Equals(local.Value, "null", StringComparison.Ordinal))
{
var connections = box.Connections;
if (connections.Count == 0 && box.Archetype.ValueIndex >= 0 && box.ParentNode.Values != null && box.Archetype.ValueIndex < box.ParentNode.Values.Length)
{
// Special case when there is no value but the box has no connection and uses default value
var defaultValue = box.ParentNode.Values[box.Archetype.ValueIndex];
if (defaultValue != null)
{
local.Value = defaultValue.ToString();
local.ValueTypeName = defaultValue.GetType().FullName;
}
}
else if (connections.Count == 1)
{
// Special case when there is no value but the box has a connection with valid value to try to use it instead
box = connections[0];
local.NodeId = box.ParentNode.ID;
local.BoxId = box.ID;
Editor.EvaluateVisualScriptLocal(script, ref local);
}
}
text = GetBoxDebuggerTooltip(ref local);
return true;
}
}