添加bd
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
#if GRAPH_DESIGNER
|
||||
/// ---------------------------------------------
|
||||
/// Behavior Designer
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
namespace Opsive.BehaviorDesigner.Editor.Controls.NodeViews
|
||||
{
|
||||
using Opsive.Shared.Editor.UIElements.Controls;
|
||||
using Opsive.BehaviorDesigner.Runtime;
|
||||
using Opsive.BehaviorDesigner.Runtime.Components;
|
||||
using Opsive.BehaviorDesigner.Runtime.Tasks;
|
||||
using Opsive.GraphDesigner.Editor;
|
||||
using Opsive.GraphDesigner.Editor.Controls.NodeViews;
|
||||
using Opsive.GraphDesigner.Editor.Elements;
|
||||
using Opsive.GraphDesigner.Editor.Events;
|
||||
using Opsive.GraphDesigner.Runtime;
|
||||
using Unity.Entities;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
/// <summary>
|
||||
/// Adds UI elements within the event node.
|
||||
/// </summary>
|
||||
[ControlType(typeof(IEventNode))]
|
||||
public class EventNodeViewControl : NodeViewBase
|
||||
{
|
||||
private const string c_DarkSuccessIconGUID = "240eed9b6e6dc004f94216f1e9fcc390";
|
||||
private const string c_LightSuccessIconGUID = "cf3f27e8ca1f20f4680890e078c7613a";
|
||||
private const string c_DarkFailureIconGUID = "8d159db7a8da43e41a50a77e43cfd6ba";
|
||||
private const string c_LightFailureIconGUID = "c3622912d9f7bcd41a54a95add672423";
|
||||
|
||||
private IEventNode m_Node;
|
||||
private GraphWindow m_GraphWindow;
|
||||
private BehaviorTree m_BehaviorTree;
|
||||
private EventNode m_EventNode;
|
||||
|
||||
private Image m_ExecutionStatusIcon;
|
||||
private Texture m_SuccessIcon;
|
||||
private Texture m_FailureIcon;
|
||||
|
||||
/// <summary>
|
||||
/// Addes the UIElements for the specified runtime node to the editor Node within the graph.
|
||||
/// </summary>
|
||||
/// <param name="graphWindow">A reference to the GraphWindow.</param>
|
||||
/// <param name="parent">The parent UIElement that should contain the node UIElements.</param>
|
||||
/// <param name="node">The node that the control represents.</param>
|
||||
public override void AddNodeView(GraphWindow graphWindow, VisualElement parent, object node)
|
||||
{
|
||||
graphWindow.rootVisualElement.styleSheets.Add(Shared.Editor.Utility.EditorUtility.LoadAsset<StyleSheet>("9c6834c10d404ac4b95be745f4411f96")); // TaskStyles.uss
|
||||
|
||||
m_Node = node as IEventNode;
|
||||
m_GraphWindow = graphWindow;
|
||||
m_BehaviorTree = m_GraphWindow.Graph as BehaviorTree;
|
||||
m_EventNode = parent.GetFirstAncestorOfType<EventNode>();
|
||||
|
||||
// AddNodeView can be called multiple times. Ensure there is only one execution status image.
|
||||
var previousExecutionStatus = m_EventNode.Q("event-execution-status");
|
||||
if (previousExecutionStatus != null) {
|
||||
previousExecutionStatus.parent.Remove(previousExecutionStatus);
|
||||
}
|
||||
m_ExecutionStatusIcon = new Image();
|
||||
m_ExecutionStatusIcon.name = "event-execution-status";
|
||||
parent.parent.Add(m_ExecutionStatusIcon); // The execution status icon should be placed behind every node element.
|
||||
m_ExecutionStatusIcon.SendToBack();
|
||||
|
||||
m_SuccessIcon = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkSuccessIconGUID : c_LightSuccessIconGUID);
|
||||
m_FailureIcon = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkFailureIconGUID : c_LightFailureIconGUID);
|
||||
|
||||
m_ExecutionStatusIcon.RegisterCallback<AttachToPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.RegisterEvent(GraphEventType.WindowUpdate, UpdateNode);
|
||||
});
|
||||
m_ExecutionStatusIcon.RegisterCallback<DetachFromPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.UnregisterEvent(GraphEventType.WindowUpdate, UpdateNode);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the node with the current execution status icon.
|
||||
/// </summary>
|
||||
private void UpdateNode()
|
||||
{
|
||||
if (m_BehaviorTree == null || m_BehaviorTree.Entity == Entity.Null || m_Node.ConnectedIndex == ushort.MaxValue || !m_BehaviorTree.World.EntityManager.Exists(m_BehaviorTree.Entity)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var connectedNode = m_GraphWindow.Graph.LogicNodes[m_Node.ConnectedIndex];
|
||||
// The tree may not be initialized.
|
||||
if (connectedNode.RuntimeIndex == ushort.MaxValue) {
|
||||
return;
|
||||
}
|
||||
var taskComponents = m_BehaviorTree.World.EntityManager.GetBuffer<TaskComponent>(m_BehaviorTree.Entity);
|
||||
var taskComponent = taskComponents[connectedNode.RuntimeIndex];
|
||||
if (taskComponent.Status == TaskStatus.Success) {
|
||||
m_ExecutionStatusIcon.image = m_SuccessIcon;
|
||||
} else if (taskComponent.Status == TaskStatus.Failure) {
|
||||
m_ExecutionStatusIcon.image = m_FailureIcon;
|
||||
} else if (m_ExecutionStatusIcon.image != null) {
|
||||
m_ExecutionStatusIcon.image = null;
|
||||
}
|
||||
|
||||
if (m_ExecutionStatusIcon.image != null) {
|
||||
m_ExecutionStatusIcon.style.width = m_ExecutionStatusIcon.image.width;
|
||||
}
|
||||
|
||||
if (taskComponent.Status == TaskStatus.Running || taskComponent.Status == TaskStatus.Queued) {
|
||||
m_EventNode.SetColorState(ColorState.Active, 0);
|
||||
} else {
|
||||
var nodeIndex = m_GraphWindow.GraphEditor.GetNodeIndex(m_Node);
|
||||
m_EventNode.SetColorState(m_GraphWindow.Graph.IsNodeEnabled(false, nodeIndex) ? ColorState.Default : ColorState.Disabled, 0.5f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6c90fafbcac7a174c9d9b765d9065ef0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "Opsive.BehaviorDesigner.Editor.Controls.NodeViews",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:734d92eba21c94caba915361bd5ac177",
|
||||
"GUID:d8b63aba1907145bea998dd612889d6b",
|
||||
"GUID:e0cd26848372d4e5c891c569017e11f1",
|
||||
"GUID:bbb15c76beca87041af309d0035105a2",
|
||||
"GUID:27cb7fd045e5bb44f8c617ce69325b1d",
|
||||
"GUID:f9fbcd65fc33f6847b0f124cf7e891b6",
|
||||
"GUID:97a55b351d7460f4f87d2ad07066bf4e",
|
||||
"GUID:cf0567158f87e3c4c9be32bb870ec7b9",
|
||||
"GUID:e9319bc8ab9315745bdf80aeffa01d6d"
|
||||
],
|
||||
"includePlatforms": [
|
||||
"Editor"
|
||||
],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.entities",
|
||||
"expression": "1.3.5",
|
||||
"define": "UNITY_ENTITIES"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 98e4b74cf0784f4458e03260557a6cc4
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
#if GRAPH_DESIGNER
|
||||
/// ---------------------------------------------
|
||||
/// Behavior Designer
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
namespace Opsive.BehaviorDesigner.Editor.Controls.NodeViews
|
||||
{
|
||||
using Opsive.GraphDesigner.Editor;
|
||||
using Opsive.GraphDesigner.Editor.Events;
|
||||
using Opsive.GraphDesigner.Runtime;
|
||||
using Opsive.BehaviorDesigner.Runtime;
|
||||
using Opsive.BehaviorDesigner.Runtime.Systems;
|
||||
using Opsive.BehaviorDesigner.Runtime.Tasks.Decorators;
|
||||
using Opsive.Shared.Editor.UIElements.Controls;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
/// <summary>
|
||||
/// Implements TypeControlBase for the PriorityEvaluator type.
|
||||
/// </summary>
|
||||
[ControlType(typeof(PriorityEvaluator))]
|
||||
public class PriorityEvaluatorNodeViewControl : TaskNodeViewControl
|
||||
{
|
||||
private BehaviorTree m_BehaviorTree;
|
||||
private ILogicNode m_Node;
|
||||
private ushort m_PriorityEvaluatorComponentIndex = ushort.MaxValue;
|
||||
|
||||
private Label m_PriorityValueLabel;
|
||||
|
||||
/// <summary>
|
||||
/// Addes the UIElements for the specified runtime node to the editor Node within the graph.
|
||||
/// </summary>
|
||||
/// <param name="graphWindow">A reference to the GraphWindow.</param>
|
||||
/// <param name="parent">The parent UIElement that should contain the node UIElements.</param>
|
||||
/// <param name="node">The node that the control represents.</param>
|
||||
public override void AddNodeView(GraphWindow graphWindow, VisualElement parent, object node)
|
||||
{
|
||||
base.AddNodeView(graphWindow, parent, node);
|
||||
|
||||
if (!Application.isPlaying) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_BehaviorTree = graphWindow.Graph as BehaviorTree;
|
||||
m_Node = node as ILogicNode;
|
||||
|
||||
parent.RegisterCallback<AttachToPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.RegisterEvent(GraphEventType.WindowUpdate, UpdateUtilityValue);
|
||||
});
|
||||
parent.RegisterCallback<DetachFromPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.UnregisterEvent(GraphEventType.WindowUpdate, UpdateUtilityValue);
|
||||
});
|
||||
|
||||
m_PriorityValueLabel = new Label();
|
||||
m_PriorityValueLabel.style.alignSelf = Align.Center;
|
||||
parent.Add(m_PriorityValueLabel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the utility value.
|
||||
/// </summary>
|
||||
private void UpdateUtilityValue()
|
||||
{
|
||||
if (m_BehaviorTree == null || m_BehaviorTree.Entity == Entity.Null || m_Node.RuntimeIndex == ushort.MaxValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
var taskObjectComponents = m_BehaviorTree.World.EntityManager.GetBuffer<TaskObjectComponent>(m_BehaviorTree.Entity);
|
||||
if (m_PriorityEvaluatorComponentIndex == ushort.MaxValue) {
|
||||
// Find the corresponding index of the TaskObject.
|
||||
for (int i = 0; i < taskObjectComponents.Length; ++i) {
|
||||
if (taskObjectComponents[i].Index == m_Node.RuntimeIndex) {
|
||||
m_PriorityEvaluatorComponentIndex = (ushort)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_PriorityEvaluatorComponentIndex == ushort.MaxValue) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var priorityEvaluator = m_BehaviorTree.GetTask(taskObjectComponents[m_PriorityEvaluatorComponentIndex].Index) as PriorityEvaluator;
|
||||
if (priorityEvaluator == null) {
|
||||
return;
|
||||
}
|
||||
m_PriorityValueLabel.text = "Value: " + priorityEvaluator.GetPriorityValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a9387930721f1dd42909d2053f5063ef
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,134 @@
|
||||
#if GRAPH_DESIGNER
|
||||
/// ---------------------------------------------
|
||||
/// Behavior Designer
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
namespace Opsive.BehaviorDesigner.Editor.Controls.NodeViews
|
||||
{
|
||||
using Opsive.GraphDesigner.Editor;
|
||||
using Opsive.BehaviorDesigner.Runtime.Tasks;
|
||||
using Opsive.Shared.Editor.UIElements.Controls;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Implements TypeControlBase for the StackedTask type.
|
||||
/// </summary>
|
||||
[ControlType(typeof(StackedTask))]
|
||||
public class StackedTaskNodeViewControl : TaskNodeViewControl
|
||||
{
|
||||
private const float c_ActiveIconRotationSpeed = 30;
|
||||
|
||||
/// <summary>
|
||||
/// Displays information about the nested task within the Stacked Task.
|
||||
/// </summary>
|
||||
private class TaskView : VisualElement
|
||||
{
|
||||
private const string c_DarkActiveIconGUID = "1230b934cbd748345b13125468a34720";
|
||||
private const string c_LightActiveIconGUID = "e57f179ee476f274dbe537179e67bf04";
|
||||
|
||||
private int m_Index;
|
||||
private Image m_ActiveImage;
|
||||
private float m_CurrentRotation;
|
||||
|
||||
/// <summary>
|
||||
/// TaskView constructor.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the task.</param>
|
||||
/// <param name="task">A reference to the task.</param>
|
||||
public TaskView(int index, Task task)
|
||||
{
|
||||
m_Index = index;
|
||||
|
||||
var horizontalLayout = new VisualElement();
|
||||
horizontalLayout.AddToClassList("horizontal-layout");
|
||||
horizontalLayout.style.height = 18;
|
||||
var label = new Label(task.ToString());
|
||||
label.style.flexGrow = 1;
|
||||
horizontalLayout.Add(label);
|
||||
m_ActiveImage = new Image();
|
||||
m_ActiveImage.image = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkActiveIconGUID : c_LightActiveIconGUID);
|
||||
m_ActiveImage.style.width = 16;
|
||||
m_ActiveImage.style.height = 16;
|
||||
m_ActiveImage.style.display = DisplayStyle.None;
|
||||
horizontalLayout.Add(m_ActiveImage);
|
||||
|
||||
Add(horizontalLayout);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the status of the task.
|
||||
/// </summary>
|
||||
/// <param name="activeIndex">The index that is active.</param>
|
||||
public void UpdateStatus(int activeIndex)
|
||||
{
|
||||
m_ActiveImage.style.display = (m_Index == activeIndex ? DisplayStyle.Flex : DisplayStyle.None);
|
||||
if (m_Index == activeIndex) {
|
||||
if (Application.isPlaying) {
|
||||
m_CurrentRotation += c_ActiveIconRotationSpeed;
|
||||
m_ActiveImage.style.rotate = new Rotate(Angle.Degrees(m_CurrentRotation));
|
||||
}
|
||||
} else {
|
||||
m_CurrentRotation = 0f;
|
||||
m_ActiveImage.style.rotate = new Rotate(Angle.Degrees(0f));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private StackedTask m_StackedTask;
|
||||
private TaskView[] m_TaskViews;
|
||||
|
||||
/// <summary>
|
||||
/// Addes the UIElements for the specified runtime node to the editor Node within the graph.
|
||||
/// </summary>
|
||||
/// <param name="graphWindow">A reference to the GraphWindow.</param>
|
||||
/// <param name="parent">The parent UIElement that should contain the node UIElements.</param>
|
||||
/// <param name="node">The node that the control represents.</param>
|
||||
public override void AddNodeView(GraphWindow graphWindow, VisualElement parent, object node)
|
||||
{
|
||||
base.AddNodeView(graphWindow, parent, node);
|
||||
|
||||
m_StackedTask = node as StackedTask;
|
||||
if (m_StackedTask.Tasks == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var tasks = m_StackedTask.Tasks;
|
||||
m_TaskViews = new TaskView[tasks.Length];
|
||||
for (int i = 0; i < tasks.Length; ++i) {
|
||||
var task = m_StackedTask.Tasks[i];
|
||||
// The task no longer exists. Replace it.
|
||||
if (task == null) {
|
||||
tasks[i] = new UnknownTask();
|
||||
m_StackedTask.Tasks = tasks;
|
||||
}
|
||||
m_TaskViews[i] = new TaskView(i, m_StackedTask.Tasks[i]);
|
||||
parent.Add(m_TaskViews[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method which updates the node with the current execution status.
|
||||
/// </summary>
|
||||
/// <returns>The status of the task.</returns>
|
||||
protected override TaskStatus UpdateNodeInternal()
|
||||
{
|
||||
var activeIndex = -1;
|
||||
TaskStatus status;
|
||||
if ((status = base.UpdateNodeInternal()) == TaskStatus.Running && m_StackedTask.Tasks.Length > 1) {
|
||||
activeIndex = m_StackedTask.ActiveIndex;
|
||||
for (int i = 0; i < m_TaskViews.Length; ++i) {
|
||||
m_TaskViews[i].UpdateStatus(activeIndex);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < m_TaskViews.Length; ++i) {
|
||||
m_TaskViews[i].UpdateStatus(activeIndex);
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 40ae380983a04824fb14ea4a89343e87
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,288 @@
|
||||
#if GRAPH_DESIGNER
|
||||
/// ---------------------------------------------
|
||||
/// Behavior Designer
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
namespace Opsive.BehaviorDesigner.Editor.Controls.NodeViews
|
||||
{
|
||||
using Opsive.Shared.Editor.UIElements.Controls;
|
||||
using Opsive.BehaviorDesigner.Runtime;
|
||||
using Opsive.BehaviorDesigner.Runtime.Components;
|
||||
using Opsive.BehaviorDesigner.Runtime.Tasks;
|
||||
using Opsive.GraphDesigner.Editor;
|
||||
using Opsive.GraphDesigner.Editor.Controls.NodeViews;
|
||||
using Opsive.GraphDesigner.Editor.Elements;
|
||||
using Opsive.GraphDesigner.Editor.Events;
|
||||
using Opsive.GraphDesigner.Runtime;
|
||||
using Unity.Entities;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
/// <summary>
|
||||
/// Adds UI elements within the task node.
|
||||
/// </summary>
|
||||
[ControlType(typeof(IAction))]
|
||||
[ControlType(typeof(IConditional))]
|
||||
[ControlType(typeof(IComposite))]
|
||||
[ControlType(typeof(IDecorator))]
|
||||
public class TaskNodeViewControl : NodeViewBase
|
||||
{
|
||||
private const string c_DarkConditionalAbortLowerPriorityIconGUID = "ba6528926e3f4f7438d3b9737f595ec6";
|
||||
private const string c_LightConditionalAbortLowerPriorityIconGUID = "20be04a2e46cb9d40b601dccdfbe153b";
|
||||
private const string c_DarkConditionalAbortSelfIconGUID = "ff3ba64f23e708645b24cc7509b5ebe5";
|
||||
private const string c_LightConditionalAbortSelfIconGUID = "5d44e66bacdbe51408dd30e519c2b318";
|
||||
private const string c_DarkConditionalAbortBothIconGUID = "1c01950cc0f1c994cb5ff3576969ebbf";
|
||||
private const string c_LightConditionalAbortBothIconGUID = "90b22fc04519bdb44b4d83665e86381d";
|
||||
|
||||
private const string c_DarkSuccessIconGUID = "240eed9b6e6dc004f94216f1e9fcc390";
|
||||
private const string c_LightSuccessIconGUID = "cf3f27e8ca1f20f4680890e078c7613a";
|
||||
private const string c_DarkSuccessReevaluateIconGUID = "0a5037ce131729b4fa0ffa9e1e13d387";
|
||||
private const string c_LightSuccessReevaluateIconGUID = "bba6bdc3af0aac44dadd1ca3a8485b05";
|
||||
private const string c_DarkFailureIconGUID = "8d159db7a8da43e41a50a77e43cfd6ba";
|
||||
private const string c_LightFailureIconGUID = "c3622912d9f7bcd41a54a95add672423";
|
||||
private const string c_DarkFailureReevaluateIconGUID = "26de8afeb313fd84291f98e68db44df7";
|
||||
private const string c_LightFailureReevaluateIconGUID = "5a6d713911c8ec3488639e2934329033";
|
||||
|
||||
private ILogicNode m_Node;
|
||||
private GraphWindow m_GraphWindow;
|
||||
private BehaviorTree m_BehaviorTree;
|
||||
|
||||
private Image m_ExecutionStatusIcon;
|
||||
private Image m_ConditionalAbortIcon;
|
||||
private LogicNode m_LogicNode;
|
||||
|
||||
private Texture m_SuccessIcon;
|
||||
private Texture m_SuccessReevaluateIcon;
|
||||
private Texture m_FailureIcon;
|
||||
private Texture m_FailureReevaluateIcon;
|
||||
|
||||
/// <summary>
|
||||
/// Addes the UIElements for the specified runtime node to the editor Node within the graph.
|
||||
/// </summary>
|
||||
/// <param name="graphWindow">A reference to the GraphWindow.</param>
|
||||
/// <param name="parent">The parent UIElement that should contain the node UIElements.</param>
|
||||
/// <param name="node">The node that the control represents.</param>
|
||||
public override void AddNodeView(GraphWindow graphWindow, VisualElement parent, object node)
|
||||
{
|
||||
graphWindow.rootVisualElement.styleSheets.Add(Shared.Editor.Utility.EditorUtility.LoadAsset<StyleSheet>("9c6834c10d404ac4b95be745f4411f96")); // TaskStyles.uss
|
||||
|
||||
m_Node = node as ILogicNode;
|
||||
m_GraphWindow = graphWindow;
|
||||
m_BehaviorTree = m_GraphWindow.Graph as BehaviorTree;
|
||||
m_LogicNode = parent.GetFirstAncestorOfType<LogicNode>();
|
||||
|
||||
if (node is IConditionalAbortParent conditionalAbortParent) {
|
||||
m_ConditionalAbortIcon = new Image();
|
||||
m_ConditionalAbortIcon.name = "conditional-abort-icon";
|
||||
parent.parent.Add(m_ConditionalAbortIcon);
|
||||
SetConditionalAbortIcon(conditionalAbortParent);
|
||||
|
||||
m_ConditionalAbortIcon.RegisterCallback<AttachToPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.RegisterEvent<object>(GraphEventType.NodeValueUpdated, UpdateNodeValue);
|
||||
});
|
||||
m_ConditionalAbortIcon.RegisterCallback<DetachFromPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.UnregisterEvent<object>(GraphEventType.NodeValueUpdated, UpdateNodeValue);
|
||||
});
|
||||
}
|
||||
|
||||
// Subtree references can click into its references.
|
||||
if (m_Node is ISubtreeReference) {
|
||||
m_LogicNode.RegisterCallback<MouseDownEvent>(OnSubtreeRferenceMouseDown);
|
||||
}
|
||||
|
||||
// AddNodeView can be called multiple times. Ensure there is only one execution status image.
|
||||
var previousExecutionStatus = m_LogicNode.Q("execution-status");
|
||||
if (previousExecutionStatus != null) {
|
||||
previousExecutionStatus.parent.Remove(previousExecutionStatus);
|
||||
}
|
||||
m_ExecutionStatusIcon = new Image();
|
||||
m_ExecutionStatusIcon.name = "execution-status";
|
||||
parent.parent.Add(m_ExecutionStatusIcon); // The execution status icon should be placed behind every node element.
|
||||
m_ExecutionStatusIcon.SendToBack();
|
||||
|
||||
m_SuccessIcon = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkSuccessIconGUID : c_LightSuccessIconGUID);
|
||||
m_SuccessReevaluateIcon = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkSuccessReevaluateIconGUID : c_LightSuccessReevaluateIconGUID);
|
||||
m_FailureIcon = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkFailureIconGUID : c_LightFailureIconGUID);
|
||||
m_FailureReevaluateIcon = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkFailureReevaluateIconGUID : c_LightFailureReevaluateIconGUID);
|
||||
|
||||
m_ExecutionStatusIcon.RegisterCallback<AttachToPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.RegisterEvent(GraphEventType.WindowUpdate, UpdateNode);
|
||||
m_GraphWindow.OnSelectionChange += OnSelectionChange;
|
||||
});
|
||||
m_ExecutionStatusIcon.RegisterCallback<DetachFromPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.UnregisterEvent(GraphEventType.WindowUpdate, UpdateNode);
|
||||
m_GraphWindow.OnSelectionChange -= OnSelectionChange;
|
||||
});
|
||||
OnSelectionChange(Selection.activeObject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the conditional abort icon.
|
||||
/// </summary>
|
||||
/// <param name="conditionalAbortParent">The conditional abort node.</param>
|
||||
private void SetConditionalAbortIcon(IConditionalAbortParent conditionalAbortParent)
|
||||
{
|
||||
if (conditionalAbortParent.AbortType == ConditionalAbortType.LowerPriority) {
|
||||
m_ConditionalAbortIcon.image = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkConditionalAbortLowerPriorityIconGUID : c_LightConditionalAbortLowerPriorityIconGUID);
|
||||
} else if (conditionalAbortParent.AbortType == ConditionalAbortType.Self) {
|
||||
m_ConditionalAbortIcon.image = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkConditionalAbortSelfIconGUID : c_LightConditionalAbortSelfIconGUID);
|
||||
} else if (conditionalAbortParent.AbortType == ConditionalAbortType.Both) {
|
||||
m_ConditionalAbortIcon.image = Shared.Editor.Utility.EditorUtility.LoadAsset<Texture>(EditorGUIUtility.isProSkin ? c_DarkConditionalAbortBothIconGUID : c_LightConditionalAbortBothIconGUID);
|
||||
} else {
|
||||
m_ConditionalAbortIcon.image = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A value has been updated for the specified node.
|
||||
/// </summary>
|
||||
/// <param name="node">The node that has been updated.</param>
|
||||
private void UpdateNodeValue(object node)
|
||||
{
|
||||
if (node != m_Node) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetConditionalAbortIcon(node as IConditionalAbortParent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the node with the current execution status.
|
||||
/// </summary>
|
||||
private void UpdateNode()
|
||||
{
|
||||
UpdateNodeInternal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal method which updates the node with the current execution status.
|
||||
/// </summary>
|
||||
/// <returns>The status of the task.</returns>
|
||||
protected virtual TaskStatus UpdateNodeInternal()
|
||||
{
|
||||
if (m_BehaviorTree == null || m_BehaviorTree.Entity == Entity.Null || m_Node.RuntimeIndex == ushort.MaxValue || !m_BehaviorTree.World.EntityManager.Exists(m_BehaviorTree.Entity)) {
|
||||
// The task is no longer active. Reset the status while keeping the previous execution state.
|
||||
m_LogicNode.SetColorState(m_GraphWindow.GraphEditor.IsNodeHierarchyEnabled(m_Node) ? ColorState.Default : ColorState.Disabled, 0.5f);
|
||||
if (m_ExecutionStatusIcon.image != null) {
|
||||
if (m_ExecutionStatusIcon.image == m_SuccessReevaluateIcon) {
|
||||
m_ExecutionStatusIcon.image = m_SuccessIcon;
|
||||
} else if (m_ExecutionStatusIcon.image == m_FailureReevaluateIcon) {
|
||||
m_ExecutionStatusIcon.image = m_FailureIcon;
|
||||
}
|
||||
m_ExecutionStatusIcon.style.width = m_ExecutionStatusIcon.image.width;
|
||||
}
|
||||
return TaskStatus.Inactive;
|
||||
}
|
||||
|
||||
var taskComponents = m_BehaviorTree.World.EntityManager.GetBuffer<TaskComponent>(m_BehaviorTree.Entity);
|
||||
var taskComponent = taskComponents[m_Node.RuntimeIndex];
|
||||
if (taskComponent.Status == TaskStatus.Success) {
|
||||
if (taskComponent.Reevaluate) {
|
||||
m_ExecutionStatusIcon.image = m_SuccessReevaluateIcon;
|
||||
} else {
|
||||
m_ExecutionStatusIcon.image = m_SuccessIcon;
|
||||
}
|
||||
} else if (taskComponent.Status == TaskStatus.Failure) {
|
||||
if (taskComponent.Reevaluate) {
|
||||
m_ExecutionStatusIcon.image = m_FailureReevaluateIcon;
|
||||
} else {
|
||||
m_ExecutionStatusIcon.image = m_FailureIcon;
|
||||
}
|
||||
} else if (m_ExecutionStatusIcon.image != null) {
|
||||
m_ExecutionStatusIcon.image = null;
|
||||
}
|
||||
|
||||
if (m_ExecutionStatusIcon.image != null) {
|
||||
m_ExecutionStatusIcon.style.width = m_ExecutionStatusIcon.image.width;
|
||||
}
|
||||
|
||||
if (taskComponent.Status == TaskStatus.Running || taskComponent.Status == TaskStatus.Queued) {
|
||||
m_LogicNode.SetColorState(ColorState.Active, 0);
|
||||
} else {
|
||||
m_LogicNode.SetColorState(m_GraphWindow.GraphEditor.IsNodeHierarchyEnabled(m_Node) ? ColorState.Default : ColorState.Disabled, 0.5f);
|
||||
}
|
||||
return taskComponent.Status;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enables or disables the NodeView.
|
||||
/// </summary>
|
||||
/// <param name="enable">True if the NodeView is enabled.</param>
|
||||
public override void SetEnabled(bool enable)
|
||||
{
|
||||
if (m_ConditionalAbortIcon != null) {
|
||||
m_ConditionalAbortIcon.SetEnabled(enable);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The mouse has been pressed.
|
||||
/// </summary>
|
||||
/// <param name="evt">The event that triggered the press.</param>
|
||||
private void OnSubtreeRferenceMouseDown(MouseDownEvent evt)
|
||||
{
|
||||
if (evt.clickCount != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
var subtreeReference = m_Node as ISubtreeReference;
|
||||
if (subtreeReference.Subtrees == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < subtreeReference.Subtrees.Length; ++i) {
|
||||
var subtree = subtreeReference.Subtrees[i];
|
||||
if (subtree == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Selection.activeObject = subtree;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The GraphWindow selection has changed.
|
||||
/// </summary>
|
||||
/// <param name="selection">The new selection.</param>
|
||||
private void OnSelectionChange(UnityEngine.Object selection)
|
||||
{
|
||||
if (!Application.isPlaying || m_BehaviorTree == null || m_BehaviorTree.Entity == Entity.Null || !m_BehaviorTree.enabled || !m_BehaviorTree.Baked) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The behavior tree was baked. Ensure the BehaviorTree component is pointing to the correct Entity.
|
||||
var worlds = World.All;
|
||||
var foundEntity = false;
|
||||
for (int i = 0; i < worlds.Count; ++i) {
|
||||
var defaultEntities = worlds[i].EntityManager.GetAllEntities(Unity.Collections.Allocator.Temp);
|
||||
if (defaultEntities != null) {
|
||||
var originalGuid = m_BehaviorTree.World.EntityManager.GetComponentData<EntityGuid>(m_BehaviorTree.Entity);
|
||||
|
||||
foreach (var defaultEntity in defaultEntities) {
|
||||
if (worlds[i].EntityManager.HasComponent<EntityGuid>(defaultEntity)) {
|
||||
var entityGuid = worlds[i].EntityManager.GetComponentData<EntityGuid>(defaultEntity);
|
||||
if (originalGuid.OriginatingId == entityGuid.OriginatingId) {
|
||||
m_BehaviorTree.World = worlds[i];
|
||||
m_BehaviorTree.Entity = defaultEntity;
|
||||
foundEntity = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
defaultEntities.Dispose();
|
||||
if (foundEntity) {
|
||||
m_BehaviorTree.Baked = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34ab799a714c2db4ab2d69566510bfc4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
#if GRAPH_DESIGNER
|
||||
/// ---------------------------------------------
|
||||
/// Behavior Designer
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
namespace Opsive.BehaviorDesigner.Editor.Controls.NodeViews
|
||||
{
|
||||
using Opsive.GraphDesigner.Editor;
|
||||
using Opsive.GraphDesigner.Editor.Events;
|
||||
using Opsive.GraphDesigner.Runtime;
|
||||
using Opsive.BehaviorDesigner.Runtime;
|
||||
using Opsive.BehaviorDesigner.Runtime.Systems;
|
||||
using Opsive.BehaviorDesigner.Runtime.Tasks.Decorators;
|
||||
using Opsive.Shared.Editor.UIElements.Controls;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
/// <summary>
|
||||
/// Implements TypeControlBase for the UtilityEvaluator type.
|
||||
/// </summary>
|
||||
[ControlType(typeof(UtilityEvaluator))]
|
||||
public class UtilityEvaluatorNodeViewControl : TaskNodeViewControl
|
||||
{
|
||||
private BehaviorTree m_BehaviorTree;
|
||||
private ILogicNode m_Node;
|
||||
private ushort m_UtilityEvaluatorComponentIndex = ushort.MaxValue;
|
||||
|
||||
private Label m_UtilityValueLabel;
|
||||
|
||||
/// <summary>
|
||||
/// Addes the UIElements for the specified runtime node to the editor Node within the graph.
|
||||
/// </summary>
|
||||
/// <param name="graphWindow">A reference to the GraphWindow.</param>
|
||||
/// <param name="parent">The parent UIElement that should contain the node UIElements.</param>
|
||||
/// <param name="node">The node that the control represents.</param>
|
||||
public override void AddNodeView(GraphWindow graphWindow, VisualElement parent, object node)
|
||||
{
|
||||
base.AddNodeView(graphWindow, parent, node);
|
||||
|
||||
if (!Application.isPlaying) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_BehaviorTree = graphWindow.Graph as BehaviorTree;
|
||||
m_Node = node as ILogicNode;
|
||||
|
||||
parent.RegisterCallback<AttachToPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.RegisterEvent(GraphEventType.WindowUpdate, UpdateUtilityValue);
|
||||
});
|
||||
parent.RegisterCallback<DetachFromPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.UnregisterEvent(GraphEventType.WindowUpdate, UpdateUtilityValue);
|
||||
});
|
||||
|
||||
m_UtilityValueLabel = new Label();
|
||||
m_UtilityValueLabel.style.alignSelf = Align.Center;
|
||||
parent.Add(m_UtilityValueLabel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the utility value.
|
||||
/// </summary>
|
||||
private void UpdateUtilityValue()
|
||||
{
|
||||
if (m_BehaviorTree == null || m_BehaviorTree.Entity == Entity.Null || m_Node.RuntimeIndex == ushort.MaxValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
var taskObjectComponents = m_BehaviorTree.World.EntityManager.GetBuffer<TaskObjectComponent>(m_BehaviorTree.Entity);
|
||||
if (m_UtilityEvaluatorComponentIndex == ushort.MaxValue) {
|
||||
// Find the corresponding index of the TaskObject.
|
||||
for (int i = 0; i < taskObjectComponents.Length; ++i) {
|
||||
if (taskObjectComponents[i].Index == m_Node.RuntimeIndex) {
|
||||
m_UtilityEvaluatorComponentIndex = (ushort)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_UtilityEvaluatorComponentIndex == ushort.MaxValue) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var utilityEvaluator = m_BehaviorTree.GetTask(taskObjectComponents[m_UtilityEvaluatorComponentIndex].Index) as UtilityEvaluator;
|
||||
if (utilityEvaluator == null) {
|
||||
return;
|
||||
}
|
||||
m_UtilityValueLabel.text = "Value: " + System.Math.Round(utilityEvaluator.GetUtilityValue(), 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a1a209242018ecc418ad24f5427f88f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,111 @@
|
||||
#if GRAPH_DESIGNER
|
||||
/// ---------------------------------------------
|
||||
/// Behavior Designer
|
||||
/// Copyright (c) Opsive. All Rights Reserved.
|
||||
/// https://www.opsive.com
|
||||
/// ---------------------------------------------
|
||||
namespace Opsive.BehaviorDesigner.Editor.Controls.NodeViews
|
||||
{
|
||||
using Opsive.BehaviorDesigner.Runtime;
|
||||
using Opsive.BehaviorDesigner.Runtime.Components;
|
||||
using Opsive.BehaviorDesigner.Runtime.Tasks.Actions;
|
||||
using Opsive.GraphDesigner.Editor;
|
||||
using Opsive.GraphDesigner.Editor.Events;
|
||||
using Opsive.GraphDesigner.Runtime;
|
||||
using Opsive.Shared.Editor.UIElements.Controls;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
/// <summary>
|
||||
/// Implements TypeControlBase for the Wait type.
|
||||
/// </summary>
|
||||
[ControlType(typeof(Wait))]
|
||||
public class WaitNodeViewControl : TaskNodeViewControl
|
||||
{
|
||||
private BehaviorTree m_BehaviorTree;
|
||||
private ILogicNode m_Node;
|
||||
private ushort m_WaitComponentIndex = ushort.MaxValue;
|
||||
private ProgressBar m_ProgressBar;
|
||||
|
||||
/// <summary>
|
||||
/// Addes the UIElements for the specified runtime node to the editor Node within the graph.
|
||||
/// </summary>
|
||||
/// <param name="graphWindow">A reference to the GraphWindow.</param>
|
||||
/// <param name="parent">The parent UIElement that should contain the node UIElements.</param>
|
||||
/// <param name="node">The node that the control represents.</param>
|
||||
public override void AddNodeView(GraphWindow graphWindow, VisualElement parent, object node)
|
||||
{
|
||||
base.AddNodeView(graphWindow, parent, node);
|
||||
|
||||
if (!Application.isPlaying) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_BehaviorTree = graphWindow.Graph as BehaviorTree;
|
||||
m_Node = node as ILogicNode;
|
||||
|
||||
parent.RegisterCallback<AttachToPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.RegisterEvent(GraphEventType.WindowUpdate, UpdateWaitProgress);
|
||||
});
|
||||
parent.RegisterCallback<DetachFromPanelEvent>(c =>
|
||||
{
|
||||
GraphEventHandler.UnregisterEvent(GraphEventType.WindowUpdate, UpdateWaitProgress);
|
||||
});
|
||||
|
||||
m_ProgressBar = new ProgressBar();
|
||||
parent.Add(m_ProgressBar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the wait progress bar.
|
||||
/// </summary>
|
||||
private void UpdateWaitProgress()
|
||||
{
|
||||
if (m_BehaviorTree == null || m_BehaviorTree.Entity == Entity.Null || m_Node.RuntimeIndex == ushort.MaxValue) {
|
||||
m_ProgressBar.style.display = DisplayStyle.None;
|
||||
return;
|
||||
}
|
||||
|
||||
var waitComponents = m_BehaviorTree.World.EntityManager.GetBuffer<WaitComponent>(m_BehaviorTree.Entity);
|
||||
if (m_WaitComponentIndex == ushort.MaxValue) {
|
||||
// Find the corresponding index of the WaitComponent.
|
||||
for (int i = 0; i < waitComponents.Length; ++i) {
|
||||
if (waitComponents[i].Index == m_Node.RuntimeIndex) {
|
||||
m_WaitComponentIndex = (ushort)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_WaitComponentIndex == ushort.MaxValue) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var waitComponent = waitComponents[m_WaitComponentIndex];
|
||||
if (waitComponent.PauseTime != 0) {
|
||||
return;
|
||||
}
|
||||
m_ProgressBar.highValue = (float)waitComponent.WaitDuration;
|
||||
|
||||
var taskComponents = m_BehaviorTree.World.EntityManager.GetBuffer<TaskComponent>(m_BehaviorTree.Entity);
|
||||
var elapsed = -1f;
|
||||
if (taskComponents[m_Node.RuntimeIndex].Status == Runtime.Tasks.TaskStatus.Running) {
|
||||
elapsed = Mathf.Clamp(Time.time - (float)waitComponent.StartTime, 0, (float)waitComponent.WaitDuration);
|
||||
m_ProgressBar.value = elapsed;
|
||||
} else if (taskComponents[m_Node.RuntimeIndex].Status == Runtime.Tasks.TaskStatus.Success) {
|
||||
elapsed = (float)waitComponent.WaitDuration;
|
||||
m_ProgressBar.value = elapsed;
|
||||
} else if (taskComponents[m_Node.RuntimeIndex].Status == Runtime.Tasks.TaskStatus.Inactive) {
|
||||
m_ProgressBar.value = 0;
|
||||
}
|
||||
|
||||
m_ProgressBar.title = (elapsed >= 0 ? System.Math.Round(elapsed, 2).ToString() + "/" : string.Empty) + System.Math.Round(waitComponent.WaitDuration, 2).ToString() + "s";
|
||||
if (m_ProgressBar.style.display == DisplayStyle.None) {
|
||||
m_ProgressBar.style.display = DisplayStyle.Flex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c971440ad87a6904daefedbbbd9b5cd4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user