【m】11.PointCloudTools 上传
This commit is contained in:
8
Assets/11.PointCloudTools/Editor.meta
Normal file
8
Assets/11.PointCloudTools/Editor.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 858218743db24324ea70f5aabd5a59e1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/11.PointCloudTools/Editor/Script.meta
Normal file
8
Assets/11.PointCloudTools/Editor/Script.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 28b0336be33262a499bd2d0271e6ce4d
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/11.PointCloudTools/Runtime.meta
Normal file
8
Assets/11.PointCloudTools/Runtime.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07b86d86f93839748931b2c738d8392e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/11.PointCloudTools/Runtime/Script.meta
Normal file
8
Assets/11.PointCloudTools/Runtime/Script.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 534adf1a70225b147b60b06e492b6ef3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9255f5abe57e6154b9d700de650dced1
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<Type, object> Services = new Dictionary<Type, object>();
|
||||
|
||||
static PointCloudService()
|
||||
{
|
||||
Services.Clear();
|
||||
|
||||
}
|
||||
public static void RegisterService<T>(T service)
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (Services.ContainsKey(type))
|
||||
{
|
||||
Services[type] = service;
|
||||
}
|
||||
else
|
||||
{
|
||||
Services.Add(type, service);
|
||||
}
|
||||
}
|
||||
|
||||
public static T GetService<T>()
|
||||
{
|
||||
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<T>()
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (Services.ContainsKey(type))
|
||||
{
|
||||
Services.Remove(type);
|
||||
}
|
||||
}
|
||||
public static void ClearServices()
|
||||
{
|
||||
Services.Clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f427d12273ddf14e8e82d29eabbec83
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18def5e1e37d03a438b2e1240ff6fb78
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 08e4dd259b2cfef419fa885222c533b1
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 碰撞盒是否渲染
|
||||
/// </summary>
|
||||
public bool isGizmo = false;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
|
||||
[Button("一键生成坐标数据")]
|
||||
public void CreatPosData()
|
||||
{
|
||||
ZoneController[] zoneControllers = FindObjectsOfType<ZoneController>(true);
|
||||
PointController[] pointControllers = FindObjectsOfType<PointController>(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<ZoneData> ZoneDatas;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 区域数据
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class ZoneData
|
||||
{
|
||||
public string id;
|
||||
public string name;
|
||||
[BoxGroup("坐标数据"), HideLabel][ReadOnly] public TransformData transformData;
|
||||
|
||||
|
||||
//[HideLabel] public ColliderData colliderData;
|
||||
|
||||
|
||||
public List<PointData> pointDatas;
|
||||
|
||||
public ZoneData()
|
||||
{
|
||||
transformData = new TransformData();
|
||||
pointDatas = new List<PointData>();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点位数据
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PointData
|
||||
{
|
||||
public int order;
|
||||
public string id;
|
||||
public bool isTigger = true;
|
||||
public string name;
|
||||
[HideLabel][ReadOnly] public ColliderData colliderData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点位数据
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public struct TransformData
|
||||
{
|
||||
public Vector3 position;
|
||||
public Vector3 rotation;
|
||||
public Vector3 scale;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点位数据
|
||||
/// </summary>
|
||||
[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;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79b808b96820ad546951a6859e2a99be
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01775802bfc184743916af27066a85dd
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<BoxCollider >();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67b37331afa91f6418b142c26b0ba6fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<CapsuleCollider>();
|
||||
}
|
||||
|
||||
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<CapsuleCollider>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8094e78c655752e4b8ed71f3f146a258
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<Vector3> _vertices = new List<Vector3>();
|
||||
private List<int> _triangles = new List<int>();
|
||||
private List<Vector3> _linePoints = new List<Vector3>();
|
||||
private Material _glMaterial;
|
||||
private Matrix4x4 _localToWorldMatrix;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_meshCollider = GetComponent<MeshCollider>();
|
||||
InitializeMeshData();
|
||||
InitializeGLMaterial();
|
||||
}
|
||||
|
||||
private void InitializeMeshData()
|
||||
{
|
||||
// 尝试获取网格数据
|
||||
MeshFilter meshFilter = GetComponent<MeshFilter>();
|
||||
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<long> edgeSet = new HashSet<long>();
|
||||
_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<long> 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
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1be297c9ec995924f872cde2f236e42a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<SphereCollider>();
|
||||
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>();
|
||||
// ... 后续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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4b3d66befec6a284da8001399bdb0d8c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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<Collider> OnColliderEnter;
|
||||
|
||||
public async void Init(ZoneController ZoneController, PointData pointData)
|
||||
{
|
||||
this.gameObject.SetActive(false);
|
||||
this.ZoneController = ZoneController;
|
||||
var titleMesh = this.transform.Find("Title").GetComponent<TextMeshPro>();
|
||||
titleMesh.text = pointData.name;
|
||||
var numMesh = titleMesh.transform.Find("Num").GetComponent<TextMeshPro>();
|
||||
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<MeshCollider>();
|
||||
collider.transform.localPosition = pointData.colliderData.colPosition;
|
||||
collider.transform.localRotation = Quaternion.Euler(pointData.colliderData.colRotation);
|
||||
collider.transform.localScale = pointData.colliderData.colScale;
|
||||
if (PointCloudService.GetService<IZoneData>().IsGizmo())
|
||||
{
|
||||
collider.GetOrAddComponent<MeshColliderGizmo>();
|
||||
}
|
||||
|
||||
_onTriggerEnterUnRegister = collider.OnTriggerEnterEvent(OnPointTriggerEnterEvent);
|
||||
}
|
||||
|
||||
|
||||
public void OnPointTriggerEnterEvent(Collider collider)
|
||||
{
|
||||
if (!isTigger)
|
||||
return;
|
||||
if (PointCloudService.GetService<IZoneSystem>().CurrentPointType == pointType)
|
||||
return;
|
||||
|
||||
if (collider.gameObject.CompareTag("GameController"))
|
||||
{
|
||||
if (ZoneController != null)
|
||||
{
|
||||
//隐藏当前点,显示其余点
|
||||
ZoneController.CurrentPointActiveHideOrShow(this, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
|
||||
PointCloudService.GetService<IZoneSystem>().OpenDomain(this.name);
|
||||
|
||||
OnColliderEnter?.Invoke(collider);
|
||||
|
||||
PointCloudService.GetService<IZoneSystem>().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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d999e82fdea4ce287a59f805605e760
|
||||
timeCreated: 1744884916
|
||||
@@ -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<PointController> pointControllerEntities;
|
||||
|
||||
/// <summary>
|
||||
/// 大区域网格碰撞
|
||||
/// </summary>
|
||||
private MeshCollider bigMeshCollider;
|
||||
|
||||
//大区域范围进入事件
|
||||
public IUnRegister _onBigMeshColliderStayUnRegister;
|
||||
public IUnRegister _onBigMeshColliderExitUnRegister;
|
||||
public IUnRegister _onBigMeshColliderEnterUnRegister;
|
||||
|
||||
public Action<Collider> OnColliderStay;
|
||||
public Action<Collider> OnColliderExit;
|
||||
public Action<Collider> 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<PointController>(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<IZoneSystem>().HideBigMeshColliderStayUnRegister();
|
||||
OnBigMeshColliderEnterEvent(collider);
|
||||
OnColliderStay?.Invoke(collider);
|
||||
}
|
||||
|
||||
private void OnBigMeshColliderEnterEvent(Collider collider)
|
||||
{
|
||||
if (PointCloudService.GetService<IZoneSystem>().CurrentZoneType == pointType)
|
||||
return;
|
||||
|
||||
if (collider.gameObject.CompareTag("GameController"))
|
||||
{
|
||||
Debug.Log($"collider:【{collider.name}】 point:【{name}】 OnBigMeshColliderEnterEvent");
|
||||
|
||||
PointCloudService.GetService<IZoneSystem>().OpenNextZonePoint(this);
|
||||
|
||||
// ActiveAllPointHideOrShow(true);
|
||||
bigMeshCollider.transform.parent.Find("Arrow").gameObject.SetActive(true);
|
||||
|
||||
OnColliderEnter?.Invoke(collider);
|
||||
|
||||
PointCloudService.GetService<IZoneSystem>().CurrentZoneType = pointType;
|
||||
//this.GetSystem<IZoneSystem>().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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开区域的点位
|
||||
/// </summary>
|
||||
/// <param name="force">是否打开</param>
|
||||
/// <param name="isOpenCurrentDomain">是否打开当前触发点位</param>
|
||||
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<IZoneSystem>().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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f2837f45bfd4347b76957e11fd63f6b
|
||||
timeCreated: 1744876130
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过id获取区域数据
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 通过id获取区域数据
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23cb528afab304d429cd1873c3ec2281
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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; }
|
||||
|
||||
/// <summary>
|
||||
/// 当进去区域的最后一个小点位的区域范围时,开启下一区域的第一个小点位 和 关闭上一区域的最后一个小点位
|
||||
/// </summary>
|
||||
public void OpenNextZonePoint(ZoneController zoneController);
|
||||
|
||||
void HideBigMeshColliderStayUnRegister();
|
||||
void OpenDomain(string domainName);
|
||||
|
||||
/// <summary>
|
||||
/// 绑定区域碰撞事件
|
||||
/// </summary>
|
||||
/// <param name="zoneId">区域名称</param>
|
||||
/// <param name="onColliderEnter">进入事件</param>
|
||||
/// <param name="onColliderStay">停留事件</param>
|
||||
/// <param name="onColliderExit">退出事件</param>
|
||||
void AddOnZoneColliderEvent(string zoneId, Action<Collider> onColliderEnter = null,
|
||||
Action<Collider> onColliderStay = null, Action<Collider> onColliderExit = null);
|
||||
|
||||
/// <summary>
|
||||
/// 绑定点位碰撞事件
|
||||
/// </summary>
|
||||
/// <param name="pointId">点位名称</param>
|
||||
/// <param name="onColliderEnter">进入事件</param>
|
||||
void AddOnPointColliderEvent(string pointId, Action<Collider> onColliderEnter = null);
|
||||
}
|
||||
|
||||
public abstract class ZoneSystemBase : IZoneSystem
|
||||
{
|
||||
private ZoneController[] zoneControllers;
|
||||
private List<PointController> pointControllers = new List<PointController>();
|
||||
|
||||
/// <summary>
|
||||
/// mask遮罩大点位触发区域
|
||||
/// </summary>
|
||||
private MeshCollider[] _meshBigColliders;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当前在的区域范围
|
||||
/// </summary>
|
||||
public string CurrentZoneType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前触发的点位
|
||||
/// </summary>
|
||||
public string CurrentPointType { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 初始化点位物体
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Task<GameObject> InitZonePoint();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化区域
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Task<GameObject> InitZoneMask();
|
||||
|
||||
/// <summary>
|
||||
/// 初始化区域数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Task<PointGatherData> InitZoneData();
|
||||
|
||||
|
||||
public ZoneSystemBase(Transform parent)
|
||||
{
|
||||
CreatZone(parent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建zone碰撞盒
|
||||
/// </summary>
|
||||
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<IZoneData>(new ZoneGatherData(pointGatherData));
|
||||
|
||||
var zoneDatas = PointCloudService.GetService<IZoneData>().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<MeshCollider>();
|
||||
//初始化点位物体
|
||||
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<IDigitalHuman>().AddPointData(new DigitalHumanPointData()
|
||||
// {
|
||||
// pointType = Enum.Parse<PointType>(zoneDatas[i].name),
|
||||
// pointTransform = zoneColliderPoint.transform
|
||||
// });
|
||||
var zoneController = zoneGo.GetComponent<ZoneController>();
|
||||
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<PointController>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 当进去区域的最后一个小点位的区域范围时,开启下一区域的第一个小点位 和 关闭上一区域的最后一个小点位
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 进入当前区域时,关闭当前区域时间,打开别的区域事件
|
||||
/// </summary>
|
||||
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");
|
||||
// }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定区域碰撞事件
|
||||
/// </summary>
|
||||
/// <param name="zoneId">区域名称</param>
|
||||
/// <param name="onColliderEnter">进入事件</param>
|
||||
/// <param name="onColliderStay">停留事件</param>
|
||||
/// <param name="onColliderExit">退出事件</param>
|
||||
public void AddOnZoneColliderEvent(string zoneId, Action<Collider> onColliderEnter = null,
|
||||
Action<Collider> onColliderStay = null, Action<Collider> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 绑定点位碰撞事件
|
||||
/// </summary>
|
||||
/// <param name="pointId">点位名称</param>
|
||||
/// <param name="onColliderEnter">进入事件</param>
|
||||
public void AddOnPointColliderEvent(string pointId, Action<Collider> onColliderEnter = null)
|
||||
{
|
||||
foreach (var pointController in pointControllers)
|
||||
{
|
||||
if (pointController.name == pointId)
|
||||
{
|
||||
if (onColliderEnter != null)
|
||||
{
|
||||
pointController.OnColliderEnter += onColliderEnter;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测指定Camera下是否存在符合条件的GameController
|
||||
/// </summary>
|
||||
/// <returns>是否存在符合条件的物体</returns>
|
||||
private bool HasValidGameController()
|
||||
{
|
||||
var targetCamera = Camera.main;
|
||||
if (targetCamera == null) return false;
|
||||
|
||||
// 获取相机下所有子物体(包括 inactive 物体)
|
||||
Transform[] allChildren = targetCamera.GetComponentsInChildren<Transform>(true);
|
||||
|
||||
foreach (Transform child in allChildren)
|
||||
{
|
||||
// 跳过相机自身
|
||||
if (child == targetCamera.transform) continue;
|
||||
|
||||
GameObject obj = child.gameObject;
|
||||
// 检查名称、标签和碰撞体
|
||||
if (obj.name == "GameController" &&
|
||||
obj.CompareTag("GameController") &&
|
||||
obj.TryGetComponent<BoxCollider>(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}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c0daf3dc0256eff458e570c61418625b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
16
Assets/11.PointCloudTools/package.json
Normal file
16
Assets/11.PointCloudTools/package.json
Normal file
@@ -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"
|
||||
}
|
||||
}
|
||||
7
Assets/11.PointCloudTools/package.json.meta
Normal file
7
Assets/11.PointCloudTools/package.json.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 72ff42479d0b7fc43bb5800cdba5b608
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user