using Simulator.Data; using Simulator.Model; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UVC.Data.Core; public class SourceComponent : ComponentBase { SourceDataClass sourceData=new SourceDataClass(); SourceModelData sourceModelData=new SourceModelData(); public List entitySocket; List possessEntities=new List(); public int count=0; public int index = 0; public void SetComponent(SourceDataClass sourceData) { this.sourceData = sourceData; data = sourceData; } void IncreaseCount() { count++; if (count >= entitySocket.Count) { index++; count = 0; } } void PlaceNext(Entity entity) { if (entitySocket == null || entitySocket.Count == 0) { Debug.LogWarning("[SourceComponent] entitySocket이 비어있습니다. 배치를 건너뜁니다."); return; } // 현재 소켓이 비어있으면 다음 유효 소켓을 찾는다(안전장치) int guard = 0; while ((entitySocket[count] == null) && guard < entitySocket.Count) { IncreaseCount(); guard++; } if (entitySocket[count] == null) { Debug.LogWarning("[SourceComponent] 사용 가능한 소켓이 없습니다. 배치를 건너뜁니다."); return; } // 부모/로컬 트랜스폼 설정 entity.transform.SetParent(entitySocket[count].transform, worldPositionStays: false); // Z방향으로 적층(원래 로직 유지) float stepZ = EntityManager.Instance.ObjectSize.z; entity.transform.localPosition = new Vector3(0f, 0f, stepZ * index); entity.transform.localRotation = Quaternion.identity; if (!possessEntities.Contains(entity)) possessEntities.Add(entity); IncreaseCount(); } public override void GetModelData(DataObject modelData) { // total_entity 업데이트(참조용) sourceModelData.total_entity = modelData.GetDataObject("data").GetInt("total_entity") ?? 0; // entity_ids -> 여러 개 동시 스폰 var datas = modelData.GetDataObject("data"); var entityIds = datas["entity_ids"].ConvertTo>(); if (entityIds == null || entityIds.Count == 0) { Debug.LogWarning("[SourceComponent] entity_ids가 비어있습니다."); return; } // 여러 개를 한 번에 스폰 var entities = EntityManager.Instance.SpawnEntites(entityIds,this); if (entities == null || entities.Count == 0) { return; } // 배치 foreach (var e in entities) { if (e == null) continue; PlaceNext(e); } // (선택) 총계 갱신 // sourceModelData.total_entity += entities.Count; // 필요 시 해제 } public override void DecreaseEntity(Entity entity) { possessEntities.Remove(entity); ReflowEntities(); } public void ReflowEntities() { // 위치 인덱스 초기화 count = 0; index = 0; // 🔑 핵심: 스냅샷을 만든 뒤 원본을 비우고, 스냅샷 기반으로 재배치 // 이렇게 하면 순회 중 리스트 수정으로 인한 예외가 발생하지 않습니다. var snapshot = new List(possessEntities.Count); foreach (var e in possessEntities) { if (e != null) snapshot.Add(e); } possessEntities.Clear(); foreach (var e in snapshot) { PlaceNext(e); // 여기서 다시 possessEntities에 안전하게 채워짐 } } }