2025-11-04 11:02:02 +09:00
|
|
|
using sc.modeling.splines.runtime;
|
2025-12-24 17:36:01 +09:00
|
|
|
using Simulator.Data;
|
2025-11-04 11:02:02 +09:00
|
|
|
using System.Collections.Generic;
|
2025-12-24 17:36:01 +09:00
|
|
|
using System;
|
2025-11-04 11:02:02 +09:00
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.Splines;
|
|
|
|
|
using UVC.Data.Core;
|
|
|
|
|
|
|
|
|
|
public enum conveyorType
|
|
|
|
|
{
|
|
|
|
|
partial,
|
|
|
|
|
overall
|
|
|
|
|
}
|
|
|
|
|
public class ConveyorComponent : ComponentBase
|
|
|
|
|
{
|
|
|
|
|
public List<ConveyorTarget> ConveyorQueue = new List<ConveyorTarget>();
|
|
|
|
|
public Stack<ConveyorTarget> WaitingQueue = new Stack<ConveyorTarget>();
|
|
|
|
|
public List<SplineMesher> mesher = new List<SplineMesher>();
|
|
|
|
|
SplineContainer spline;
|
|
|
|
|
float duration = 3f;
|
|
|
|
|
|
|
|
|
|
public conveyorType type = conveyorType.overall;
|
2025-12-08 10:59:29 +09:00
|
|
|
public int segmentCount = 10;
|
|
|
|
|
public float borderEpsilon = 1e-4f;
|
|
|
|
|
bool[] occupancy;
|
2025-11-04 11:02:02 +09:00
|
|
|
|
2025-12-24 17:36:01 +09:00
|
|
|
ConveyorPath conveyorPath;
|
|
|
|
|
public event Action<ConveyorPath> onConveyorClicked;
|
2025-11-04 11:02:02 +09:00
|
|
|
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
|
|
|
|
void Start()
|
|
|
|
|
{
|
|
|
|
|
spline = GetComponent<SplineContainer>();
|
|
|
|
|
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<ConveyorTarget>();
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-24 17:36:01 +09:00
|
|
|
public void SetComponent(ConveyorPath conveyorData)
|
|
|
|
|
{
|
|
|
|
|
this.conveyorPath = conveyorData;
|
|
|
|
|
onConveyorClicked += FindAnyObjectByType<ConveyorProperty>().SetProertyWindow;
|
|
|
|
|
var box=gameObject.AddComponent<BoxCollider>();
|
|
|
|
|
box.isTrigger = true;
|
|
|
|
|
}
|
2025-11-04 11:02:02 +09:00
|
|
|
void SetConveyorEntity(Entity entity)
|
|
|
|
|
{
|
|
|
|
|
var cTarget = entity.gameObject.GetComponent<ConveyorTarget>();
|
|
|
|
|
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<ConveyorTarget>();
|
|
|
|
|
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<ConveyorTarget>();
|
|
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-12-24 17:36:01 +09:00
|
|
|
|
|
|
|
|
public override void getpath()
|
|
|
|
|
{
|
|
|
|
|
onConveyorClicked?.Invoke(conveyorPath);
|
|
|
|
|
}
|
2025-11-04 11:02:02 +09:00
|
|
|
}
|