using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEditor.Experimental.GraphView; using System.Linq; using UnityEditor; using UnityEngine.UIElements; using System; namespace AI.BT { public class FlowEdge : Edge { public bool EnableFlow { get => _isFlowEnabled; set { if(_isFlowEnabled != value) { _isFlowEnabled = value; if(_isFlowEnabled ) { Add(m_FlowImage); } else { Remove(m_FlowImage); } } } } private double m_PhaseStartTime; private double m_PhaseDuration; private float m_FlowSpeed = 150f; private float m_PhaseLength; private int m_PhaseIndex; private float _FlowSize = 6f; private float m_CurrentPhaseLength; private bool _isFlowEnabled; private readonly Image m_FlowImage; public float FlowSize { get => _FlowSize; set { _FlowSize = value; m_FlowImage.style.width = new Length(_FlowSize, LengthUnit.Pixel); m_FlowImage.style.height = new Length(_FlowSize, LengthUnit.Pixel); } } public FlowEdge() { var radius = new Length(FlowSize / 2, LengthUnit.Pixel); m_FlowImage = new Image() { name = "flow-image", style = { width = new Length(FlowSize, LengthUnit.Pixel), height = new Length(FlowSize, LengthUnit.Pixel), borderTopLeftRadius = radius, borderBottomLeftRadius = radius, borderBottomRightRadius = radius, borderTopRightRadius = radius, backgroundColor = new StyleColor(Color.white) } }; edgeControl.RegisterCallback<GeometryChangedEvent>(OnEdgeGeometryChanged); } private void OnEdgeGeometryChanged(GeometryChangedEvent evt) { m_PhaseIndex = 0; m_PhaseStartTime = EditorApplication.timeSinceStartup; m_CurrentPhaseLength = Vector2.Distance(edgeControl.controlPoints[m_PhaseIndex], edgeControl.controlPoints[m_PhaseIndex + 1]); m_PhaseDuration = m_PhaseLength / m_FlowSpeed; } public void UpdateFlow() { var progress = (EditorApplication.timeSinceStartup - m_PhaseStartTime) / m_PhaseDuration; Vector3 start = edgeControl.controlPoints[m_PhaseIndex]; Vector3 end = edgeControl.controlPoints[m_PhaseIndex + 1]; var flowPos = Vector2.Lerp(start, end, (float)progress); m_FlowImage.transform.position = flowPos - Vector2.one * FlowSize / 2; if(progress >= 0.99999f) { m_PhaseIndex++; if(m_PhaseIndex >= edgeControl.controlPoints.Length - 1) { m_PhaseIndex = 0; } m_PhaseStartTime = EditorApplication.timeSinceStartup; m_CurrentPhaseLength = Vector2.Distance(edgeControl.controlPoints[m_PhaseIndex], edgeControl.controlPoints[m_PhaseIndex + 1]); m_PhaseDuration = m_CurrentPhaseLength / m_FlowSpeed; } } } }