using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Threading.Tasks; using Cysharp.Threading.Tasks; using Stary.Evo; using UnityEngine; namespace Main { public interface IZoneSystem { string CurrentZoneType { get; set; } string CurrentPointType { get; set; } /// /// 当进去区域的最后一个小点位的区域范围时,开启下一区域的第一个小点位 和 关闭上一区域的最后一个小点位 /// public void OpenNextZonePoint(ZoneController zoneController); void HideBigMeshColliderStayUnRegister(); void OpenDomain(string domainName); /// /// 绑定区域碰撞事件 /// /// 区域名称 /// 进入事件 /// 停留事件 /// 退出事件 void AddOnZoneColliderEvent(string zoneId, Action onColliderEnter = null, Action onColliderStay = null, Action onColliderExit = null); /// /// 绑定点位碰撞事件 /// /// 点位名称 /// 进入事件 void AddOnPointColliderEvent(string pointId, Action onColliderEnter = null); } public abstract class ZoneSystemBase : IZoneSystem { private ZoneController[] zoneControllers; private List pointControllers = new List(); /// /// mask遮罩大点位触发区域 /// private MeshCollider[] _meshBigColliders; /// /// 当前在的区域范围 /// public string CurrentZoneType { get; set; } /// /// 当前触发的点位 /// public string CurrentPointType { get; set; } /// /// 初始化点位物体 /// /// public abstract Task InitZonePoint(); /// /// 初始化区域 /// /// public abstract Task InitZoneMask(); /// /// 初始化区域数据 /// /// public abstract Task InitZoneData(); public ZoneSystemBase(Transform parent) { CreatZone(parent); } /// /// 创建zone碰撞盒 /// private async UniTask CreatZone(Transform parent) { //检测环境是否正常 if (!HasValidGameController()) { // 抛出异常或返回空服务 Debug.LogError( $"请检查相机环境 1、是否存在GameController物体 2、是否存在BoxCollider,3、GameController物体的tag是否为GameController"); } //读取配置文件 var pointGatherData = await InitZoneData(); if (pointGatherData == null) { Debug.LogError("点位数据为空,请先初始化点位数据"); } PointCloudService.RegisterService(new ZoneGatherData(pointGatherData)); var zoneDatas = PointCloudService.GetService().GetZoneDataAll(); zoneControllers = new ZoneController[zoneDatas.Length]; //加载遮罩数据 var zoneMask = await InitZoneMask(); if (zoneMask == null) { Debug.LogError("区域遮罩碰撞体为空,请先初始化区域遮罩碰撞体"); } var zoneMaskTransform = GameObject.Instantiate(zoneMask, parent); _meshBigColliders = zoneMaskTransform.transform.Find("AreaDetermination") .GetComponentsInChildren(); //初始化点位物体 var zonePoint = await InitZonePoint(); if (zonePoint == null) { Debug.LogError("点位物体为空,请先初始化点位物体"); } //生成区域 for (int i = 0; i < zoneDatas.Length; i++) { var zoneGo = new GameObject(zoneDatas[i].name, typeof(ZoneController)); zoneGo.Parent(parent); // //ip漫游点位数据赋值 // this.GetSystem().AddPointData(new DigitalHumanPointData() // { // pointType = Enum.Parse(zoneDatas[i].name), // pointTransform = zoneColliderPoint.transform // }); var zoneController = zoneGo.GetComponent(); zoneControllers[i] = zoneController; await zoneController.Init(zoneDatas[i]); //生成点位 var pointDatas = zoneDatas[i].pointDatas; foreach (var pointData in pointDatas) { var pointGo = GameObject.Instantiate(zonePoint, zoneGo.transform); PointController pointController = pointGo.GetOrAddComponent(); zoneController.pointControllerEntities.Add(pointController); pointControllers.Add(pointController); pointController.Init(zoneController, pointData); } } for (int i = 0; i < zoneControllers.Length; i++) { var bigMeshCollider = _meshBigColliders[i]; zoneControllers[i].InitMeshCollider(bigMeshCollider); bigMeshCollider.transform.parent.Find("Arrow").gameObject.SetActive(false); } } /// /// 当进去区域的最后一个小点位的区域范围时,开启下一区域的第一个小点位 和 关闭上一区域的最后一个小点位 /// public void OpenNextZonePoint(ZoneController zoneController) { int currentIndex = 0; for (int i = 0; i < zoneControllers.Length; i++) { if (zoneControllers[i] != zoneController) { //先关闭所有点位 zoneControllers[i].ActiveAllPointHideOrShow(false); } else { zoneControllers[i].ActiveAllPointHideOrShow(true, false); currentIndex = i; } } int nextIndex = currentIndex + 1; if (nextIndex < zoneControllers.Length) { //开启下一区域的第一个小点位 zoneControllers[nextIndex] .CurrentPointActiveHideOrShow( zoneControllers[nextIndex].pointControllerEntities.First(), true); } int lastIndex = currentIndex - 1; if (lastIndex >= 0) { //开启上一区域的最后一个小点位 zoneControllers[lastIndex] .CurrentPointActiveHideOrShow(zoneControllers[lastIndex].pointControllerEntities.Last(), true); } } /// /// 进入当前区域时,关闭当前区域时间,打开别的区域事件 /// public void HideBigMeshColliderStayUnRegister() { foreach (var zoneController in zoneControllers) { zoneController._onBigMeshColliderStayUnRegister.UnRegister(); } } public void OpenDomain(string domainName) { // if (_entrance != null) // { // _entrance.OpenDomain(domainName, OpenDomainType.PointCloud); InitializeHybridClREntrance(domainName); // } // else // { // Debug.LogError("UnityEvo:HybridClREntrance is null"); // } } /// /// 绑定区域碰撞事件 /// /// 区域名称 /// 进入事件 /// 停留事件 /// 退出事件 public void AddOnZoneColliderEvent(string zoneId, Action onColliderEnter = null, Action onColliderStay = null, Action onColliderExit = null) { foreach (var zoneController in zoneControllers) { if (zoneController.name == zoneId) { if (onColliderEnter != null) { zoneController.OnColliderEnter += onColliderEnter; } if (onColliderStay != null) { zoneController.OnColliderStay += onColliderStay; } if (onColliderExit != null) { zoneController.OnColliderExit += onColliderExit; } break; } } } /// /// 绑定点位碰撞事件 /// /// 点位名称 /// 进入事件 public void AddOnPointColliderEvent(string pointId, Action onColliderEnter = null) { foreach (var pointController in pointControllers) { if (pointController.name == pointId) { if (onColliderEnter != null) { pointController.OnColliderEnter += onColliderEnter; } break; } } } /// /// 检测指定Camera下是否存在符合条件的GameController /// /// 是否存在符合条件的物体 private bool HasValidGameController() { var targetCamera = Camera.main; if (targetCamera == null) return false; // 获取相机下所有子物体(包括 inactive 物体) Transform[] allChildren = targetCamera.GetComponentsInChildren(true); foreach (Transform child in allChildren) { // 跳过相机自身 if (child == targetCamera.transform) continue; GameObject obj = child.gameObject; // 检查名称、标签和碰撞体 if (obj.name == "GameController" && obj.CompareTag("GameController") && obj.TryGetComponent(out _)) { return true; } } return false; } private void InitializeHybridClREntrance(string domainName) { GameObject entrance = GameObject.Find("LoadDll"); if (entrance == null) { Debug.LogError("未找到LoadDll物体"); return; } try { // 替换为实际程序集名称和类完整名 string assemblyName = "stary.hotfixupdate.main"; // 例如:"HybridCLR.Runtime" string typeFullName = "Stary.Evo.HybridClREntrance"; // 例如:"HybridCLR.HybridClREntrance" // 加载程序集并获取类型 Assembly assembly = Assembly.Load(assemblyName); // 已加载的程序集(延续之前的assembly变量) Type hybridType = assembly.GetType(typeFullName); if (hybridType == null) { Debug.LogError("未找到HybridClREntrance类型"); return; } // 反射调用GameObject.GetComponent方法 MethodInfo getComponentMethod = typeof(GameObject).GetMethod("GetComponent", Type.EmptyTypes); MethodInfo genericMethod = getComponentMethod?.MakeGenericMethod(hybridType); var _entrance = genericMethod?.Invoke(entrance, null); if (_entrance == null) { // 若组件不存在,可反射调用AddComponent添加 MethodInfo addComponentMethod = typeof(GameObject).GetMethod("AddComponent", Type.EmptyTypes); MethodInfo genericAddMethod = addComponentMethod.MakeGenericMethod(hybridType); _entrance = genericAddMethod.Invoke(entrance, null); } // 步骤2:获取实例类型并调用方法 Type componentType = _entrance.GetType(); MethodInfo targetMethod = componentType.GetMethod( "OpenDomain", // 替换为实际方法名 new[] { typeof(string), typeof(string) } // 替换为方法参数类型 ); if (targetMethod == null) { Debug.LogError($"组件{componentType.Name}中未找到目标方法"); return; } targetMethod.Invoke(_entrance, new[] { domainName, "PointCloud" }); } catch (Exception ex) { Debug.LogError($"反射操作失败: {ex.Message}"); } } } }