Main/Assets/Code/Logic/WarningFiled/NewWarningFiled.cs
2025-01-25 04:38:09 +08:00

270 lines
10 KiB
C#

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<Vector3, Vector3> getHeightFunc = null)
{
if (owner == null)
return null;
var warningField = UnityUtils.RequireComponent<NewWarningFiled>(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<Vector3, Vector3> getHeightFunc = null)
{
if (owner == null)
return null;
var warningField = UnityUtils.RequireComponent<NewWarningFiled>(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<Vector3, Vector3> getHeightFunc = null)
{
if (owner == null)
return null;
var warningField = UnityUtils.RequireComponent<NewWarningFiled>(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<Vector3, Vector3> getHeightFunc)
{
var meshs = owner.GetComponentsInChildren<MeshFilter>();
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<NewWarningFiled>();
if (sector != null)
{
for (int i = 0; i < sector.Length; ++i)
{
sector[i].DestoryField();
}
}
}
#endregion
}
}