using sc.modeling.splines.runtime; using Simulator.Data; using System.Collections.Generic; using System; using UnityEngine; using UnityEngine.Splines; using UVC.Data.Core; public enum conveyorType { partial, overall } public class ConveyorComponent : ComponentBase { public List ConveyorQueue = new List(); public Stack WaitingQueue = new Stack(); public List mesher = new List(); SplineContainer spline; float duration = 3f; public conveyorType type = conveyorType.overall; public int segmentCount = 10; public float borderEpsilon = 1e-4f; bool[] occupancy; ConveyorPath conveyorPath; public event Action onConveyorClicked; // Start is called once before the first execution of Update after the MonoBehaviour is created void Start() { spline = GetComponent(); occupancy = new bool[Mathf.Max(1, segmentCount)]; EntityManager.Instance.OnEntityDestroyed += UnSetEntity; } // Update is called once per frame void Update() { /* if (Input.GetKeyDown(KeyCode.G)) { GameObject target = GameObject.CreatePrimitive(PrimitiveType.Cube); var cTraget = target.AddComponent(); cTraget.Progress = 0f; ConveyorQueue.Add(cTraget); } if (Input.GetKeyDown(KeyCode.S)) { // 출구에서 한 개 배출 if (WaitingQueue.Count > 0) { var target = WaitingQueue.Pop(); Destroy(target.gameObject); } } if (type == conveyorType.overall) { if (WaitingQueue.Count < 1) { SetProgress(Time.deltaTime / duration); MoveOnConveyor(); } } else // partial { SetProgress(Time.deltaTime / duration); MoveOnConveyor(); } */ SetProgress(Time.deltaTime / duration); MoveOnConveyor(); } public void SetComponent(ConveyorPath conveyorData) { this.conveyorPath = conveyorData; onConveyorClicked += FindAnyObjectByType().SetProertyWindow; var box=gameObject.AddComponent(); box.isTrigger = true; } void SetConveyorEntity(Entity entity) { var cTarget = entity.gameObject.GetComponent(); cTarget.transform.SetParent(this.transform, worldPositionStays: false); cTarget.Progress = 0f; ConveyorQueue.Add(cTarget); } public void SetModelData(DataObject datas) { var data = datas.GetDataObject("data"); var entityId = data.GetString("entity_id_original"); var entity = EntityManager.Instance.GetEntity(entityId,this); if (entity == null) { Debug.Log(entityId); Debug.Log(entity); } duration = (float)data.GetFloat("travel_time"); SetConveyorEntity(entity); } public void UnSetEntity(Entity entity) { var cTarget = entity.gameObject.GetComponent(); if (ConveyorQueue.Contains(cTarget)) { ConveyorQueue.Remove(cTarget); } } public void UnSetModelData(DataObject datas) { var data = datas.GetDataObject("data"); var entityId = data.GetString("entity_id_original"); var entity = EntityManager.Instance.GetEntity(entityId,this); var cTarget = entity.gameObject.GetComponent(); if (ConveyorQueue.Contains(cTarget)) { ConveyorQueue.Remove(cTarget); } } void SetProgress(float progress) { if (ConveyorQueue.Count == 0) return; if (type == conveyorType.overall) { foreach (var target in ConveyorQueue) { target.Progress += progress; if (target.Progress > 1f) target.Progress = 1f; } } else { PartialAdvance(progress); } } void MoveOnConveyor() { Spline s = spline.Splines[0]; for (int i = ConveyorQueue.Count - 1; i >= 0; i--) { var target = ConveyorQueue[i]; Vector3 localPos = SplineUtility.EvaluatePosition(s, target.Progress); target.transform.position = localPos; target.transform.position += new Vector3(0, 1f, -0.275f); if (target.Progress >= 1f) { ConveyorQueue.RemoveAt(i); WaitingQueue.Push(target); } } } void PartialAdvance(float delta) { ConveyorQueue.Sort((a, b) => b.Progress.CompareTo(a.Progress)); int cellCount = Mathf.Max(1, segmentCount); float cell = 1f / cellCount; if (occupancy == null || occupancy.Length != cellCount) occupancy = new bool[cellCount]; System.Array.Clear(occupancy, 0, occupancy.Length); if (WaitingQueue.Count > 0) occupancy[cellCount - 1] = true; foreach (var t in ConveyorQueue) { float desired = Mathf.Min(1f, t.Progress + delta); int currCell = CellIndex(t.Progress, cellCount); int wantCell = CellIndex(desired, cellCount); int allowedCell = currCell; for (int c = currCell + 1; c <= wantCell && c < cellCount; c++) { if (occupancy[c]) break; allowedCell = c; } float maxProg = Mathf.Min(desired, CellEnd(allowedCell, cellCount) - borderEpsilon); if (allowedCell == cellCount - 1) maxProg = Mathf.Min(desired, 1f); t.Progress = Mathf.Clamp01(maxProg); int newCell = CellIndex(t.Progress, cellCount); occupancy[newCell] = true; } } int CellIndex(float progress, int cellCount) { float cell = 1f / cellCount; int idx = Mathf.FloorToInt(progress / cell); return Mathf.Clamp(idx, 0, cellCount - 1); } float CellEnd(int cellIndex, int cellCount) { float cell = 1f / cellCount; return (cellIndex + 1) * cell; } void UpdateKnot(BezierKnot knot, int index, int splineIndex) { spline.Splines[splineIndex].SetKnot(index, knot); } void UpdateMesh() { foreach (var m in mesher) { m.Rebuild(); } } public override void getpath() { onConveyorClicked?.Invoke(conveyorPath); } }