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}");
}
}
}
}