diff --git a/Assets/11.PointCloudTools/Editor.meta b/Assets/11.PointCloudTools/Editor.meta new file mode 100644 index 0000000..6602468 --- /dev/null +++ b/Assets/11.PointCloudTools/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 858218743db24324ea70f5aabd5a59e1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Editor/Script.meta b/Assets/11.PointCloudTools/Editor/Script.meta new file mode 100644 index 0000000..49a42b1 --- /dev/null +++ b/Assets/11.PointCloudTools/Editor/Script.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 28b0336be33262a499bd2d0271e6ce4d +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime.meta b/Assets/11.PointCloudTools/Runtime.meta new file mode 100644 index 0000000..d97cd25 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 07b86d86f93839748931b2c738d8392e +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script.meta b/Assets/11.PointCloudTools/Runtime/Script.meta new file mode 100644 index 0000000..86733f0 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 534adf1a70225b147b60b06e492b6ef3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointCloud.Runtime.asmdef b/Assets/11.PointCloudTools/Runtime/Script/PointCloud.Runtime.asmdef new file mode 100644 index 0000000..4e9ec77 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointCloud.Runtime.asmdef @@ -0,0 +1,18 @@ +{ + "name": "PointCloud.Runtime", + "rootNamespace": "", + "references": [ + "GUID:6055be8ebefd69e48b49212b09b47b2f", + "GUID:f3fa071c399c4383a9ff8115e53dfefc", + "GUID:f51ebe6a0ceec4240a699833d6309b23" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointCloud.Runtime.asmdef.meta b/Assets/11.PointCloudTools/Runtime/Script/PointCloud.Runtime.asmdef.meta new file mode 100644 index 0000000..6a50b04 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointCloud.Runtime.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9255f5abe57e6154b9d700de650dced1 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointCloudService.cs b/Assets/11.PointCloudTools/Runtime/Script/PointCloudService.cs new file mode 100644 index 0000000..76f9b86 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointCloudService.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Main; +using UnityEngine; + +public static class PointCloudService +{ + private static readonly Dictionary Services = new Dictionary(); + + static PointCloudService() + { + Services.Clear(); + + } + public static void RegisterService(T service) + { + var type = typeof(T); + if (Services.ContainsKey(type)) + { + Services[type] = service; + } + else + { + Services.Add(type, service); + } + } + + public static T GetService() + { + var type = typeof(T); + if (Services.TryGetValue(type, out var service)) + { + return (T)service; + } + else + { + // 抛出异常或返回空服务 + throw new Exception($"Service of type 【{type}】 not found, please check if the service is registered."); + } + } + public static void UnregisterService() + { + var type = typeof(T); + if (Services.ContainsKey(type)) + { + Services.Remove(type); + } + } + public static void ClearServices() + { + Services.Clear(); + } +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointCloudService.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointCloudService.cs.meta new file mode 100644 index 0000000..8dfcaf7 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointCloudService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9f427d12273ddf14e8e82d29eabbec83 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem.meta new file mode 100644 index 0000000..6d39a06 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 18def5e1e37d03a438b2e1240ff6fb78 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data.meta new file mode 100644 index 0000000..239d685 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 08e4dd259b2cfef419fa885222c533b1 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data/PointGatherData.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data/PointGatherData.cs new file mode 100644 index 0000000..d728c39 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data/PointGatherData.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using Main; +using Sirenix.OdinInspector; +using UnityEditor; +using UnityEngine; +using UnityEngine.Serialization; + +[CreateAssetMenu(fileName = "PointGatherData", menuName = "Evo/Create PointGatherData")] +public class PointGatherData : SerializedScriptableObject +{ + + /// + /// 碰撞盒是否渲染 + /// + public bool isGizmo = false; + +#if UNITY_EDITOR + + + [Button("一键生成坐标数据")] + public void CreatPosData() + { + ZoneController[] zoneControllers = FindObjectsOfType(true); + PointController[] pointControllers = FindObjectsOfType(true); + for (int i = 0; i < ZoneDatas.Count; i++) + { + ZoneData zoneData = ZoneDatas[i]; + + foreach (var zoneController in zoneControllers) + { + if (zoneController.name == zoneData.name) + { + zoneData.transformData.position = zoneController.transform.localPosition; + zoneData.transformData.rotation = zoneController.transform.localEulerAngles; + zoneData.transformData.scale = zoneController.transform.localScale; + } + } + + + for (int j = 0; j < zoneData.pointDatas.Count; j++) + { + PointData pointData = zoneData.pointDatas[j]; + + + foreach (var pointController in pointControllers) + { + if (pointController.name == pointData.name) + { + pointData.colliderData.position = pointController.transform.localPosition; + pointData.colliderData.rotation = pointController.transform.localEulerAngles; + pointData.colliderData.scale = pointController.transform.localScale; + + var collider = pointController.transform.Find("collisionbox"); + pointData.colliderData.colPosition = collider.localPosition; + pointData.colliderData.colRotation = collider.localEulerAngles; + pointData.colliderData.colScale = collider.localScale; + } + } + } + } + + EditorUtility.SetDirty(this); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } + +#endif + + + public List ZoneDatas; + + + +} + +/// +/// 区域数据 +/// +[Serializable] +public class ZoneData +{ + public string id; + public string name; + [BoxGroup("坐标数据"), HideLabel][ReadOnly] public TransformData transformData; + + + //[HideLabel] public ColliderData colliderData; + + + public List pointDatas; + + public ZoneData() + { + transformData = new TransformData(); + pointDatas = new List(); + } +} + +/// +/// 点位数据 +/// +[Serializable] +public class PointData +{ + public int order; + public string id; + public bool isTigger = true; + public string name; + [HideLabel][ReadOnly] public ColliderData colliderData; +} + +/// +/// 点位数据 +/// +[Serializable] +public struct TransformData +{ + public Vector3 position; + public Vector3 rotation; + public Vector3 scale; +} + +/// +/// 点位数据 +/// +[Serializable] +public struct ColliderData +{ + [BoxGroup("碰撞点坐标数据"), HideLabel] public Vector3 position; + [BoxGroup("碰撞点坐标数据"), HideLabel] public Vector3 rotation; + [BoxGroup("碰撞点坐标数据"), HideLabel] public Vector3 scale; + [BoxGroup("包围盒数据"), HideLabel] public Vector3 colPosition; + [BoxGroup("包围盒数据"), HideLabel] public Vector3 colRotation; + [BoxGroup("包围盒数据"), HideLabel] public Vector3 colScale; +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data/PointGatherData.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data/PointGatherData.cs.meta new file mode 100644 index 0000000..e1f0714 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Data/PointGatherData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 79b808b96820ad546951a6859e2a99be +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo.meta new file mode 100644 index 0000000..d5b5631 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 01775802bfc184743916af27066a85dd +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/BoxColliderGizmo.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/BoxColliderGizmo.cs new file mode 100644 index 0000000..7e2e9a2 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/BoxColliderGizmo.cs @@ -0,0 +1,131 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class BoxColliderGizmo : MonoBehaviour { + void Start() { + + } + // Update is called once per frame + void OnRenderObject() { + var colliders = gameObject.GetComponents(); + if (colliders == null) { + return; + } + CreateLineMaterial(); + lineMaterial.SetPass(0); + GL.PushMatrix(); + GL.MultMatrix(transform.localToWorldMatrix); + + for (int i = 0; i < colliders.Length; i++) { + var col = colliders[i]; + var c = col.center; + var size = col.size; + float rx = size.x / 2f; + float ry = size.y / 2f; + float rz = size.z / 2f; + Vector3 p0, p1, p2, p3; + Vector3 p4, p5, p6, p7; + p0 = c + new Vector3(-rx,-ry,rz); + p1 = c + new Vector3(rx, -ry, rz); + p2 = c + new Vector3(rx, -ry, -rz); + p3 = c + new Vector3(-rx, -ry, -rz); + + p4 = c + new Vector3(-rx, ry, rz); + p5 = c + new Vector3(rx, ry, rz); + p6 = c + new Vector3(rx, ry, -rz); + p7 = c + new Vector3(-rx, ry, -rz); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p0); + GL.Vertex(p1); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p1); + GL.Vertex(p2); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p2); + GL.Vertex(p3); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p0); + GL.Vertex(p3); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p4); + GL.Vertex(p5); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p5); + GL.Vertex(p6); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p6); + GL.Vertex(p7); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p4); + GL.Vertex(p7); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p0); + GL.Vertex(p4); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p1); + GL.Vertex(p5); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p2); + GL.Vertex(p6); + GL.End(); + + GL.Begin(GL.LINES); + GL.Color(Color.red); + GL.Vertex(p3); + GL.Vertex(p7); + GL.End(); + } + GL.PopMatrix(); + } + + static Material lineMaterial; + static void CreateLineMaterial() { + if (!lineMaterial) { + // Unity has a built-in shader that is useful for drawing + // simple colored things. + Shader shader = Shader.Find("Hidden/Internal-Colored"); + lineMaterial = new Material(shader); + lineMaterial.hideFlags = HideFlags.HideAndDontSave; + // Turn on alpha blending + lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); + lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + // Turn backface culling off + lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off); + // Turn off depth writes + lineMaterial.SetInt("_ZWrite", 0); + } + } +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/BoxColliderGizmo.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/BoxColliderGizmo.cs.meta new file mode 100644 index 0000000..de999ef --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/BoxColliderGizmo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67b37331afa91f6418b142c26b0ba6fa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/CapsuleColliderGizmo.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/CapsuleColliderGizmo.cs new file mode 100644 index 0000000..f6458f8 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/CapsuleColliderGizmo.cs @@ -0,0 +1,108 @@ +using UnityEditor; +using UnityEngine; + +[RequireComponent(typeof(CapsuleCollider))] +public class CapsuleColliderGizmo : MonoBehaviour +{ + [Tooltip("Gizmo显示颜色")] public Color gizmoColor = new Color(0, 1, 0, 0.3f); + + [Tooltip("是否始终显示Gizmo")] public bool alwaysShow = true; + + private CapsuleCollider capsuleCollider; + + private void Awake() + { + capsuleCollider = GetComponent(); + } + + private void OnDrawGizmos() + { +# if UNITY_EDITOR + if (!alwaysShow && !Selection.Contains(gameObject)) return; +#endif + DrawCapsuleGizmo(); + } + + private void OnDrawGizmosSelected() + { + if (alwaysShow) return; + DrawCapsuleGizmo(); + } + + private void DrawCapsuleGizmo() + { + if (capsuleCollider == null) + { + capsuleCollider = GetComponent(); + if (capsuleCollider == null) return; + } + + Gizmos.color = gizmoColor; + + // 获取胶囊体的参数 + Vector3 center = transform.TransformPoint(capsuleCollider.center); + float radius = capsuleCollider.radius * Mathf.Max(transform.lossyScale.x, transform.lossyScale.z); + float height = capsuleCollider.height * transform.lossyScale.y; + int direction = capsuleCollider.direction; + + // 计算胶囊体的两个半球中心 + Vector3 halfHeight = Vector3.zero; + switch (direction) + { + case 0: // X轴 + halfHeight = Vector3.right * (height / 2 - radius); + radius = capsuleCollider.radius * Mathf.Max(transform.lossyScale.y, transform.lossyScale.z); + break; + case 1: // Y轴 + halfHeight = Vector3.up * (height / 2 - radius); + radius = capsuleCollider.radius * Mathf.Max(transform.lossyScale.x, transform.lossyScale.z); + break; + case 2: // Z轴 + halfHeight = Vector3.forward * (height / 2 - radius); + radius = capsuleCollider.radius * Mathf.Max(transform.lossyScale.x, transform.lossyScale.y); + break; + } + + Vector3 topCenter = center + halfHeight; + Vector3 bottomCenter = center - halfHeight; + + // 绘制胶囊体的圆柱部分 + if (height > radius * 2) + { + DrawCylinder(topCenter, bottomCenter, radius, 16); + } + + // 绘制上下两个半球 + Gizmos.DrawSphere(topCenter, radius); + Gizmos.DrawSphere(bottomCenter, radius); + } + + // 添加自定义圆柱绘制方法 + private void DrawCylinder(Vector3 topCenter, Vector3 bottomCenter, float radius, int segments) + { + Vector3 up = (topCenter - bottomCenter).normalized; + Vector3 right = Vector3.Cross(up, Vector3.forward).normalized; + if (right.sqrMagnitude < 0.01f) + right = Vector3.Cross(up, Vector3.right).normalized; + Vector3 forward = Vector3.Cross(up, right).normalized; + + for (int i = 0; i < segments; i++) + { + float angle = (i / (float)segments) * Mathf.PI * 2; + float nextAngle = ((i + 1) / (float)segments) * Mathf.PI * 2; + + Vector3 topPoint = topCenter + (Mathf.Cos(angle) * right + Mathf.Sin(angle) * forward) * radius; + Vector3 topNextPoint = topCenter + (Mathf.Cos(nextAngle) * right + Mathf.Sin(nextAngle) * forward) * radius; + Vector3 bottomPoint = bottomCenter + (Mathf.Cos(angle) * right + Mathf.Sin(angle) * forward) * radius; + Vector3 bottomNextPoint = + bottomCenter + (Mathf.Cos(nextAngle) * right + Mathf.Sin(nextAngle) * forward) * radius; + + // 绘制侧面竖线 + Gizmos.DrawLine(topPoint, bottomPoint); + // 绘制顶部环线 + Gizmos.DrawLine(topPoint, topNextPoint); + // 绘制底部环线 + Gizmos.DrawLine(bottomPoint, bottomNextPoint); + } + } +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/CapsuleColliderGizmo.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/CapsuleColliderGizmo.cs.meta new file mode 100644 index 0000000..9b79076 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/CapsuleColliderGizmo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 8094e78c655752e4b8ed71f3f146a258 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/MeshColliderGizmo.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/MeshColliderGizmo.cs new file mode 100644 index 0000000..13e9d4b --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/MeshColliderGizmo.cs @@ -0,0 +1,151 @@ +using UnityEngine; +using System.Collections.Generic; + +[RequireComponent(typeof(MeshCollider))] +public class MeshColliderGizmo : MonoBehaviour +{ + [Tooltip("Gizmo显示颜色")] + public Color lineColor = new Color(0, 1, 1, 0.8f); + + [Tooltip("线框宽度")] + public float lineWidth = 1.0f; + + [Tooltip("是否在运行时显示")] + public bool showInPlayMode = true; + + [Tooltip("是否只显示边缘")] + public bool showEdgesOnly = true; + + private MeshCollider _meshCollider; + private Mesh _mesh; + private List _vertices = new List(); + private List _triangles = new List(); + private List _linePoints = new List(); + private Material _glMaterial; + private Matrix4x4 _localToWorldMatrix; + + private void Awake() + { + _meshCollider = GetComponent(); + InitializeMeshData(); + InitializeGLMaterial(); + } + + private void InitializeMeshData() + { + // 尝试获取网格数据 + MeshFilter meshFilter = GetComponent(); + if (meshFilter != null && meshFilter.sharedMesh != null) + { + _mesh = meshFilter.sharedMesh; + } + else if (_meshCollider.sharedMesh != null) + { + _mesh = _meshCollider.sharedMesh; + } + + if (_mesh != null) + { + _vertices.Clear(); + _triangles.Clear(); + _mesh.GetVertices(_vertices); + _mesh.GetTriangles(_triangles, 0); + GenerateLinePoints(); + } + else + { + Debug.LogWarning("未找到有效的Mesh资源", this); + } + } + + private void InitializeGLMaterial() + { + // 创建用于GL绘制的材质 + _glMaterial = new Material(Shader.Find("Hidden/Internal-Colored")); + _glMaterial.hideFlags = HideFlags.HideAndDontSave; + _glMaterial.SetInt("ZWrite", 0); + _glMaterial.SetInt("ZTest", (int)UnityEngine.Rendering.CompareFunction.Always); + } + + private void GenerateLinePoints() + { + if (showEdgesOnly) + { + // 只显示边缘线(去重处理) + HashSet edgeSet = new HashSet(); + _linePoints.Clear(); + + for (int i = 0; i < _triangles.Count; i += 3) + { + AddEdge(_triangles[i], _triangles[i + 1], edgeSet); + AddEdge(_triangles[i + 1], _triangles[i + 2], edgeSet); + AddEdge(_triangles[i + 2], _triangles[i], edgeSet); + } + } + else + { + // 显示所有三角形线 + _linePoints.Clear(); + for (int i = 0; i < _triangles.Count; i += 3) + { + _linePoints.Add(_vertices[_triangles[i]]); + _linePoints.Add(_vertices[_triangles[i + 1]]); + _linePoints.Add(_vertices[_triangles[i + 1]]); + _linePoints.Add(_vertices[_triangles[i + 2]]); + _linePoints.Add(_vertices[_triangles[i + 2]]); + _linePoints.Add(_vertices[_triangles[i]]); + } + } + } + + private void AddEdge(int v1, int v2, HashSet edgeSet) + { + // 创建唯一的边ID,避免重复 + long edgeId = (long)Mathf.Min(v1, v2) << 32 | Mathf.Max(v1, v2); + if (edgeSet.Contains(edgeId)) return; + + edgeSet.Add(edgeId); + _linePoints.Add(_vertices[v1]); + _linePoints.Add(_vertices[v2]); + } + + private void Update() + { + _localToWorldMatrix = transform.localToWorldMatrix; + } + + private void OnRenderObject() + { + if (!showInPlayMode || _mesh == null || _linePoints.Count == 0 || _glMaterial == null) + return; + + // 设置材质和颜色 + _glMaterial.SetPass(0); + GL.PushMatrix(); + GL.MultMatrix(_localToWorldMatrix); + GL.Color(lineColor); + + // 设置线宽 + GL.Begin(GL.LINES); + for (int i = 0; i < _linePoints.Count; i++) + { + GL.Vertex(_linePoints[i]); + } + GL.End(); + + GL.PopMatrix(); + } + + // 编辑器下的Gizmo预览 +#if UNITY_EDITOR + private void OnDrawGizmos() + { + if (!Application.isPlaying && _mesh != null) + { + Gizmos.color = lineColor; + Gizmos.matrix = transform.localToWorldMatrix; + Gizmos.DrawWireMesh(_mesh); + } + } +#endif +} diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/MeshColliderGizmo.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/MeshColliderGizmo.cs.meta new file mode 100644 index 0000000..38a38de --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/MeshColliderGizmo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1be297c9ec995924f872cde2f236e42a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/SphereColliderGizmo.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/SphereColliderGizmo.cs new file mode 100644 index 0000000..a4e3c52 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/SphereColliderGizmo.cs @@ -0,0 +1,75 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class SphereColliderGizmo : MonoBehaviour { + void Start() { + + } + // Update is called once per frame + void OnRenderObject() { + // 添加SphereCollider处理 + var sphereColliders = gameObject.GetComponents(); + if (sphereColliders != null) { + CreateLineMaterial(); + lineMaterial.SetPass(0); + GL.PushMatrix(); + GL.MultMatrix(transform.localToWorldMatrix); + + foreach (var col in sphereColliders) { + float radius = col.radius; + Vector3 scale = transform.lossyScale; + // 计算最大缩放值 + float maxScale = Mathf.Max(scale.x, scale.y, scale.z); + float scaledRadius = radius * maxScale; + + Vector3 center = col.center; + + // 绘制三个方向的圆环 + DrawCircle(center, Vector3.up, Vector3.forward, scaledRadius); + DrawCircle(center, Vector3.forward, Vector3.up, scaledRadius); + DrawCircle(center, Vector3.right, Vector3.up, scaledRadius); + } + GL.PopMatrix(); + } + + // 原来的BoxCollider代码保持不变... + var colliders = gameObject.GetComponents(); + // ... 后续BoxCollider的绘制代码保持不变 ... + } + +// 新增辅助方法绘制圆形 + void DrawCircle(Vector3 center, Vector3 normal, Vector3 axis, float radius) { + int segments = 32; + float angle = 0f; + + GL.Begin(GL.LINE_STRIP); + GL.Color(Color.red); + + for (int i = 0; i <= segments; i++) { + Vector3 point = center; + point += (axis * Mathf.Cos(angle) + Vector3.Cross(normal, axis) * Mathf.Sin(angle)) * radius; + GL.Vertex(point); + angle += Mathf.PI * 2f / segments; + } + GL.End(); + } + + static Material lineMaterial; + static void CreateLineMaterial() { + if (!lineMaterial) { + // Unity has a built-in shader that is useful for drawing + // simple colored things. + Shader shader = Shader.Find("Hidden/Internal-Colored"); + lineMaterial = new Material(shader); + lineMaterial.hideFlags = HideFlags.HideAndDontSave; + // Turn on alpha blending + lineMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); + lineMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); + // Turn backface culling off + lineMaterial.SetInt("_Cull", (int)UnityEngine.Rendering.CullMode.Off); + // Turn off depth writes + lineMaterial.SetInt("_ZWrite", 0); + } + } +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/SphereColliderGizmo.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/SphereColliderGizmo.cs.meta new file mode 100644 index 0000000..3e544f6 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/Gizmo/SphereColliderGizmo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 4b3d66befec6a284da8001399bdb0d8c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/PointController.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/PointController.cs new file mode 100644 index 0000000..3f472d2 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/PointController.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using Cysharp.Threading.Tasks; +using Main; +using Stary.Evo; +using TMPro; +using UnityEngine; + +namespace Main +{ + public class PointController : MonoBehaviour + { + public string pointType; + public bool isTigger; + public ZoneController ZoneController; + private MeshCollider collider; + private IUnRegister _onTriggerEnterUnRegister; + + public Action OnColliderEnter; + + public async void Init(ZoneController ZoneController, PointData pointData) + { + this.gameObject.SetActive(false); + this.ZoneController = ZoneController; + var titleMesh = this.transform.Find("Title").GetComponent(); + titleMesh.text = pointData.name; + var numMesh = titleMesh.transform.Find("Num").GetComponent(); + numMesh.text = ConvertToCircledNumber(pointData.order); + name = pointData.id; + isTigger = pointData.isTigger; + pointType = pointData.id; + //根据数据设置zone 碰撞盒 + transform.localPosition = pointData.colliderData.position; + transform.localRotation = Quaternion.Euler(pointData.colliderData.rotation); + transform.localScale = pointData.colliderData.scale; + collider = transform.Find("collisionbox").GetComponent(); + collider.transform.localPosition = pointData.colliderData.colPosition; + collider.transform.localRotation = Quaternion.Euler(pointData.colliderData.colRotation); + collider.transform.localScale = pointData.colliderData.colScale; + if (PointCloudService.GetService().IsGizmo()) + { + collider.GetOrAddComponent(); + } + + _onTriggerEnterUnRegister = collider.OnTriggerEnterEvent(OnPointTriggerEnterEvent); + } + + + public void OnPointTriggerEnterEvent(Collider collider) + { + if (!isTigger) + return; + if (PointCloudService.GetService().CurrentPointType == pointType) + return; + + if (collider.gameObject.CompareTag("GameController")) + { + if (ZoneController != null) + { + //隐藏当前点,显示其余点 + ZoneController.CurrentPointActiveHideOrShow(this, false); + } + else + { + this.gameObject.SetActive(false); + } + + + PointCloudService.GetService().OpenDomain(this.name); + + OnColliderEnter?.Invoke(collider); + + PointCloudService.GetService().CurrentPointType = pointType; + Debug.Log($"【{name}】OnPointTriggerEnterEvent"); + } + } + + + private static string ConvertToCircledNumber(int number) + { + // 检查数字是否在1-20范围内 + if (number < 1 || number > 20) + { + return number.ToString(); // 超出范围则返回原数字 + } + + // Unicode中①对应的编码是0x2460,依次递增 + char circledChar = (char)(0x2460 + number - 1); + return circledChar.ToString(); + } + } +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/PointController.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/PointController.cs.meta new file mode 100644 index 0000000..85aaac5 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/PointController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1d999e82fdea4ce287a59f805605e760 +timeCreated: 1744884916 \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneController.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneController.cs new file mode 100644 index 0000000..587cbf5 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneController.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using Cysharp.Threading.Tasks; +using Stary.Evo; +using UnityEngine; + +namespace Main +{ + public class ZoneController : MonoBehaviour + { + public string pointType; + + public List pointControllerEntities; + + /// + /// 大区域网格碰撞 + /// + private MeshCollider bigMeshCollider; + + //大区域范围进入事件 + public IUnRegister _onBigMeshColliderStayUnRegister; + public IUnRegister _onBigMeshColliderExitUnRegister; + public IUnRegister _onBigMeshColliderEnterUnRegister; + + public Action OnColliderStay; + public Action OnColliderExit; + public Action OnColliderEnter; + + public async UniTask Init(ZoneData zoneData) + { + name = zoneData.name; + pointType = name; + + //根据数据设置zone 碰撞盒 + transform.localPosition = zoneData.transformData.position; + transform.localRotation = Quaternion.Euler(zoneData.transformData.rotation); + transform.localScale = zoneData.transformData.scale; + + pointControllerEntities = new List(zoneData.pointDatas.Count); + + await UniTask.CompletedTask; + } + + public void InitMeshCollider(MeshCollider bigMeshCollider) + { + this.bigMeshCollider = bigMeshCollider; + + _onBigMeshColliderStayUnRegister = bigMeshCollider.OnTriggerStayEvent(OnBigMeshColliderStayEvent); + + _onBigMeshColliderExitUnRegister = bigMeshCollider.OnTriggerExitEvent(OnBigMeshColliderExitEvent); + + _onBigMeshColliderEnterUnRegister = bigMeshCollider.OnTriggerEnterEvent(OnBigMeshColliderEnterEvent); + } + + private void OnBigMeshColliderStayEvent(Collider collider) + { + PointCloudService.GetService().HideBigMeshColliderStayUnRegister(); + OnBigMeshColliderEnterEvent(collider); + OnColliderStay?.Invoke(collider); + } + + private void OnBigMeshColliderEnterEvent(Collider collider) + { + if (PointCloudService.GetService().CurrentZoneType == pointType) + return; + + if (collider.gameObject.CompareTag("GameController")) + { + Debug.Log($"collider:【{collider.name}】 point:【{name}】 OnBigMeshColliderEnterEvent"); + + PointCloudService.GetService().OpenNextZonePoint(this); + + // ActiveAllPointHideOrShow(true); + bigMeshCollider.transform.parent.Find("Arrow").gameObject.SetActive(true); + + OnColliderEnter?.Invoke(collider); + + PointCloudService.GetService().CurrentZoneType = pointType; + //this.GetSystem().HideBigMeshColliderStayUnRegister(_onBigMeshColliderStayUnRegister); + } + } + + private void OnBigMeshColliderExitEvent(Collider collider) + { + if (collider.gameObject.CompareTag("GameController")) + { + Debug.Log($"collider:【{collider.name}】 point:【{name}】 OnBigMeshColliderExitEvent"); + bigMeshCollider.transform.parent.Find("Arrow").gameObject.SetActive(false); + OnColliderExit?.Invoke(collider); + } + } + + /// + /// 打开区域的点位 + /// + /// 是否打开 + /// 是否打开当前触发点位 + public void ActiveAllPointHideOrShow(bool force = true, bool isOpenCurrentDomain = true) + { + foreach (var controller in pointControllerEntities) + { + if (force == false) + { + controller.gameObject.SetActive(false); + } + else + { + if (isOpenCurrentDomain) + { + controller.gameObject.SetActive(true); + } + else + { + if (PointCloudService.GetService().CurrentPointType == controller.name) + { + controller.gameObject.SetActive(false); + } + else + { + controller.gameObject.SetActive(true); + } + } + } + } + } + + public void CurrentPointActiveHideOrShow(PointController controller, bool force = true) + { + foreach (var controllerEntity in pointControllerEntities) + { + if (controllerEntity == controller) + { + controller.gameObject.SetActive(force); + } + else + { + controllerEntity.gameObject.SetActive(!force); + } + } + } + } +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneController.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneController.cs.meta new file mode 100644 index 0000000..7045356 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneController.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5f2837f45bfd4347b76957e11fd63f6b +timeCreated: 1744876130 \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneGatherData.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneGatherData.cs new file mode 100644 index 0000000..1c28f98 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneGatherData.cs @@ -0,0 +1,114 @@ +using System.Collections; +using System.Collections.Generic; +using Cysharp.Threading.Tasks; +using Stary.Evo; +using UnityEngine; + +namespace Main +{ + public interface IZoneData + { + ZoneData[] GetZoneDataAll(); + ZoneData GetZoneData(string domain); + PointData GetPointData(string zoneDomain, string pointDomain); + bool IsGizmo(); + } + + + public class ZoneGatherData : IZoneData + { + private PointGatherData _pointGatherData; + + + public ZoneGatherData(PointGatherData pointGatherData) + { + _pointGatherData = pointGatherData; + } + + /// + /// 通过id获取区域数据 + /// + /// + /// + public ZoneData[] GetZoneDataAll() + { + if (_pointGatherData != null) + { + for (int i = 0; i < _pointGatherData.ZoneDatas.Count; i++) + { + return _pointGatherData.ZoneDatas.ToArray(); + } + + Debug.LogWarning($"UnityEvo:PointGatherData is null"); + } + else + { + Debug.LogError("UnityEvo:PointGatherData is null"); + } + + return default; + } + + public bool IsGizmo() + { + if (_pointGatherData != null) + { + return _pointGatherData.isGizmo; + } + + return false; + } + + + /// + /// 通过id获取区域数据 + /// + /// + /// + public ZoneData GetZoneData(string domain) + { + if (_pointGatherData != null) + { + for (int i = 0; i < _pointGatherData.ZoneDatas.Count; i++) + { + if (_pointGatherData.ZoneDatas[i].name == domain) + { + return _pointGatherData.ZoneDatas[i]; + } + } + + Debug.LogWarning($"UnityEvo:{domain}在PointGatherData is null"); + } + else + { + Debug.LogError("UnityEvo:PointGatherData is null"); + } + + return default; + } + + + public PointData GetPointData(string zoneDomain, string pointDomain) + { + ZoneData zoneData = GetZoneData(zoneDomain); + if (zoneData.pointDatas != null) + { + for (int i = 0; i < zoneData.pointDatas.Count; i++) + { + if (zoneData.pointDatas[i].name == pointDomain) + { + return zoneData.pointDatas[i]; + } + } + + Debug.LogWarning($"UnityEvo:{pointDomain}在PointGatherData.zoneData.pointDatas is null"); + } + else + { + Debug.LogError("UnityEvo:PointGatherData.zoneData.pointDatas is null"); + } + + return default; + } + } +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneGatherData.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneGatherData.cs.meta new file mode 100644 index 0000000..dbf6ad8 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneGatherData.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23cb528afab304d429cd1873c3ec2281 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneSystemBase.cs b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneSystemBase.cs new file mode 100644 index 0000000..4d42574 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneSystemBase.cs @@ -0,0 +1,376 @@ +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}"); + } + } + } +} \ No newline at end of file diff --git a/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneSystemBase.cs.meta b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneSystemBase.cs.meta new file mode 100644 index 0000000..a9ecb85 --- /dev/null +++ b/Assets/11.PointCloudTools/Runtime/Script/PointSystem/ZoneSystemBase.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c0daf3dc0256eff458e570c61418625b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/11.PointCloudTools/package.json b/Assets/11.PointCloudTools/package.json new file mode 100644 index 0000000..d4bcc97 --- /dev/null +++ b/Assets/11.PointCloudTools/package.json @@ -0,0 +1,16 @@ +{ + "name": "com.staryevo.codechecker", + "version": "1.0.0", + "displayName": "09.CodeChecker", + "description": "代码检查工具", + "unity": "2021.3", + "unityRelease": "30f1", + "keywords": [ + "unity", + "scirpt" + ], + "author": { + "name": "staryEvo", + "url": "https://www.unity3d.com" + } +} diff --git a/Assets/11.PointCloudTools/package.json.meta b/Assets/11.PointCloudTools/package.json.meta new file mode 100644 index 0000000..c77251f --- /dev/null +++ b/Assets/11.PointCloudTools/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 72ff42479d0b7fc43bb5800cdba5b608 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: