using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using XED.VirtualFactory; namespace XED { public class VirtualFactoryManager : MonoBehaviour { public List stackerCranes = new(); public AGVManager agvManager; public AGVMap agvMap; public PortMap portMap; public List loads = new(); public Product prf_Load; public AGVNode startNode; public bool stackerHasEmptyCell; public int maxAGVCount = 4; public enum FactoryNeeds { NeedAGV, NeedLoad, NeedStackerInputLoad, NeedStackerInput, } public bool agvIsLack; public bool loadIsLack; public List needs = new(); public event Action scanningAction; public event Action solutionAction; public override void AfterAwake() { agvMap = FindSingle(); portMap = FindSingle(); agvManager = FindSingle(); stackerCranes = FindObjectsByType(UnityEngine.FindObjectsSortMode.None).ToList(); scanningAction += CheckAGVCount; scanningAction += CheckStackerSpace; scanningAction += CheckStackerInput; } private void CheckStackerInput() { foreach (var stacker in stackerCranes) { if (!stacker.hasEmptyCell) continue; if (stacker.inputPort.isEmpty) { Debug.Log("Need Stacker Input Load"); needs.Add(FactoryNeeds.NeedStackerInputLoad); return; } Debug.Log($"Need Stacker Input"); needs.Add(FactoryNeeds.NeedStackerInput); return; } } private void Update() { ScanningVirtualFactory(); Solutioning(); } void ScanningVirtualFactory() { scanningAction?.Invoke(); } void Solutioning() { foreach(var n in needs) { switch (n) { case FactoryNeeds.NeedAGV: solutionAction += GenerateAGV; break; case FactoryNeeds.NeedLoad: solutionAction += GenerateLoad; break; case FactoryNeeds.NeedStackerInputLoad: solutionAction += DeliveryStackerInputLoad; break; } } solutionAction?.Invoke(); solutionAction = null; needs.Clear(); } private void DeliveryStackerInputLoad() { if (!agvManager.TryGetIdleAGV(out var agvWorker)) { return; } if(!portMap.TryGetFullGeneratePort(out var generatePort)) { return; } if(!agvMap.TryGetEmptyInputPortNode(out var inputPortNode)) { return; } var startNode = agvWorker.currentNode; var generateNode = generatePort.GetComponent(); var getLoadPath = agvMap.FindPath(startNode, generateNode); var inputLoadPath = agvMap.FindPath(generateNode, inputPortNode); agvWorker.AddAction(new AGVMoveAction(getLoadPath)); agvWorker.AddAction(new AGVLoadAction(generatePort)); agvWorker.AddAction(new AGVMoveAction(inputLoadPath)); agvWorker.AddAction(new AGVUnloadAction(inputPortNode.loader)); } private void GenerateLoad() { if(portMap.TryGetEmptyGeneratePort(out var port)) { Debug.Log($"GenerateLoad"); var newLoad = Instantiate(prf_Load); port.Load(newLoad); loads.Add(newLoad); } } private void GenerateAGV() { Debug.Log($"GenerateAGV"); var newAGV = agvManager.CreateEmptyAGV(); newAGV.ForceSet(startNode); } void CheckStackerSpace() { if (stackerCranes.Sum(sc => sc.cells.Count()) == loads.Count) return; foreach (var stacker in stackerCranes) { if (stacker.hasEmptyCell) { Debug.Log($"Need Stacker Load"); needs.Add(FactoryNeeds.NeedLoad); return; } } } void CheckAGVCount() { Debug.Log($"CheckAGVCount"); if (maxAGVCount > agvManager.agvs.Count) { needs.Add(FactoryNeeds.NeedAGV); } else { scanningAction -= CheckAGVCount; } } } }