using Thousandto.Core.Asset; using Thousandto.Core.Base; using UnityEngine; namespace Thousandto.Code.Logic.WarningField { //新的警示圈系统 public partial class NewWarningFiled : MonoBehaviour { #region//静态变量 //圆形资源 private static GameObject _roundResGo = null; private const float _roundRadious = 0.1f; //矩形资源 private static GameObject _rectResGo = null; private const float _rectWidth = 0.1f; private const float _rectHeight = 0.1f; //扇形资源 private static GameObject _fanShapedLeftResGo = null; private static GameObject _fanShapedCenterResGo = null; private static GameObject _fanShapedRightResGo = null; private const float _fanShapeRadious = 0.1f; private const float _fanShapeAngle = 30f; private static bool _isLoadedRes = false; #endregion #region//共有函数 public static void LoadAllRes() { if (_isLoadedRes) return; _isLoadedRes = true; var vfx1 = new FGameObjectVFX(ModelTypeCode.OtherVFX, 901, true, false); vfx1.OnLoadFinishedCallBack = (fgo) => { if (fgo != null) { _roundResGo = fgo.RealGameObject; //GameObject.DontDestroyOnLoad(_roundResGo); } }; var vfx2 = new FGameObjectVFX(ModelTypeCode.OtherVFX, 902, true, false); vfx2.OnLoadFinishedCallBack = (fgo) => { if (fgo != null) { _rectResGo = fgo.RealGameObject; //GameObject.DontDestroyOnLoad(_rectResGo); } }; var vfx3 = new FGameObjectVFX(ModelTypeCode.OtherVFX, 903, true, false); vfx3.OnLoadFinishedCallBack = (fgo) => { if (fgo != null) { _fanShapedLeftResGo = fgo.RealGameObject; //GameObject.DontDestroyOnLoad(_fanShapedLeftResGo); } }; var vfx4 = new FGameObjectVFX(ModelTypeCode.OtherVFX, 904, true, false); vfx4.OnLoadFinishedCallBack = (fgo) => { if (fgo != null) { _fanShapedCenterResGo = fgo.RealGameObject; //GameObject.DontDestroyOnLoad(_fanShapedCenterResGo); } }; var vfx5 = new FGameObjectVFX(ModelTypeCode.OtherVFX, 905, true, false); vfx5.OnLoadFinishedCallBack = (fgo) => { if (fgo != null) { _fanShapedRightResGo = fgo.RealGameObject; //GameObject.DontDestroyOnLoad(_fanShapedRightResGo); } }; } #if UNITY_EDITOR public static void LoadAllResEditor() { if (_isLoadedRes) return; _isLoadedRes = true; var path = AssetUtils.GetModelAssetPath(ModelTypeCode.OtherVFX, 901); _roundResGo = ResourcesEx.Load(path, typeof(GameObject)) as GameObject; path = AssetUtils.GetModelAssetPath(ModelTypeCode.OtherVFX, 902); _rectResGo = ResourcesEx.Load(path, typeof(GameObject)) as GameObject; path = AssetUtils.GetModelAssetPath(ModelTypeCode.OtherVFX, 903); _fanShapedLeftResGo = ResourcesEx.Load(path, typeof(GameObject)) as GameObject; path = AssetUtils.GetModelAssetPath(ModelTypeCode.OtherVFX, 904); _fanShapedCenterResGo = ResourcesEx.Load(path, typeof(GameObject)) as GameObject; path = AssetUtils.GetModelAssetPath(ModelTypeCode.OtherVFX, 905); _fanShapedRightResGo = ResourcesEx.Load(path, typeof(GameObject)) as GameObject; } #endif public static NewWarningFiled AddRectWarningField(GameObject owner, float width, float height, float startDis, float aniTime = 1f, MyFunc getHeightFunc = null) { if (owner == null) return null; var warningField = UnityUtils.RequireComponent(owner); if (warningField == null) return null; //尝试加载资源,防止资源未加载 LoadAllRes(); if (_rectResGo == null) { return null; } var instGo = GameObject.Instantiate(_rectResGo) as GameObject; warningField.AddInstGos(instGo); warningField.AniMoveTime = aniTime; warningField.InnerPercent = startDis / height; instGo.transform.parent = owner.transform; instGo.SetActive(true); UnityUtils.Reset(instGo.transform); var matrix = Matrix4x4.Scale(new Vector3(width / _rectWidth, 1f, height / _rectHeight)); CalculationMesh(owner.transform, matrix, getHeightFunc); return warningField; } public static NewWarningFiled AddFanShapedWarningField(GameObject owner, float angle, float radius, float startDis, float aniTime = 1f, MyFunc getHeightFunc = null) { if (owner == null) return null; var warningField = UnityUtils.RequireComponent(owner); if (warningField == null) return null; //尝试加载资源,防止资源未加载 LoadAllRes(); if (_fanShapedLeftResGo == null || _fanShapedCenterResGo == null || _fanShapedRightResGo == null) { return null; } var fcount = angle / _fanShapeAngle; if (fcount % 1 != 0) { fcount += 1; } int count = (int)fcount - 2; warningField.AniMoveTime = aniTime; var leftEulerY = -(angle - _fanShapeAngle) / 2; var leftGo = GameObject.Instantiate(_fanShapedLeftResGo) as GameObject; leftGo.transform.parent = owner.transform; UnityUtils.Reset(leftGo.transform); leftGo.transform.localEulerAngles = new Vector3(0f, leftEulerY, 0f); warningField.AddInstGos(leftGo); leftGo.SetActive(true); var rightGo = GameObject.Instantiate(_fanShapedRightResGo) as GameObject; rightGo.transform.parent = owner.transform; UnityUtils.Reset(rightGo.transform); rightGo.transform.localEulerAngles = new Vector3(0f, (angle - _fanShapeAngle) / 2, 0f); warningField.AddInstGos(rightGo); rightGo.SetActive(true); angle -= 60f; for (int i = 0; i < count; ++i) { var centerGo = GameObject.Instantiate(_fanShapedCenterResGo) as GameObject; centerGo.transform.parent = owner.transform; UnityUtils.Reset(centerGo.transform); centerGo.transform.localEulerAngles = new Vector3(0f, leftEulerY + (i + 1) * _fanShapeAngle, 0f); warningField.AddInstGos(centerGo); centerGo.SetActive(true); } warningField.InnerPercent = startDis / radius; var matrix = Matrix4x4.Scale(new Vector3(radius / _fanShapeRadious, 1f, radius / _fanShapeRadious)); CalculationMesh(owner.transform, matrix, getHeightFunc); return warningField; } public static NewWarningFiled AddRoundWarningField(GameObject owner, float radius, float startDis, float aniTime = 1f, MyFunc getHeightFunc = null) { if (owner == null) return null; var warningField = UnityUtils.RequireComponent(owner); if (warningField == null) return null; //尝试加载资源,防止资源未加载 LoadAllRes(); if (_roundResGo == null) { return null; } var instGo = GameObject.Instantiate(_roundResGo) as GameObject; warningField.AddInstGos(instGo); warningField.AniMoveTime = aniTime; instGo.transform.parent = owner.transform; UnityUtils.Reset(instGo.transform); instGo.SetActive(true); warningField.InnerPercent = startDis / radius; var matrix = Matrix4x4.Scale(new Vector3(radius / _roundRadious, 1f, radius / _roundRadious)); CalculationMesh(owner.transform, matrix, getHeightFunc); return warningField; } private static void CalculationMesh(Transform owner, Matrix4x4 scaleMatrix, MyFunc getHeightFunc) { var meshs = owner.GetComponentsInChildren(); if (meshs == null) return; float frontHeight = owner.position.y + 0.15f; for (int i = 0; i < meshs.Length; ++i) { var worldMatrix = meshs[i].transform.worldToLocalMatrix; var curMatrix = meshs[i].transform.localToWorldMatrix * scaleMatrix; if (meshs[i] != null && meshs[i].mesh != null) { var vertices = meshs[i].mesh.vertices; for (int j = 0; j < vertices.Length; ++j) { if (getHeightFunc != null) { vertices[j] = getHeightFunc(curMatrix.MultiplyPoint3x4(vertices[j])); if (Mathf.Abs(frontHeight - vertices[j].y) > 2f) { vertices[j].y = frontHeight; } frontHeight = vertices[j].y; vertices[j] = worldMatrix.MultiplyPoint3x4(vertices[j]); } else { vertices[j] = scaleMatrix.MultiplyPoint3x4(vertices[j]); } } meshs[i].mesh.vertices = vertices; } } } public static void DeleteWarningField(GameObject go) { var sector = go.GetComponentsInChildren(); if (sector != null) { for (int i = 0; i < sector.Length; ++i) { sector[i].DestoryField(); } } } #endregion } }