#region AI优化 using System.Collections; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.ResourceManagement.AsyncOperations; using Unity.Collections; using Unity.Jobs; using Unity.Burst; public class MonsterMoveLine { public static Dictionary dic_BezierCurveDatas = new Dictionary(); public static List curves = new List(); public class BezierCurveData { public string name; public Vector2 start; public List controlPoints = new List(); public Vector2 end; } public static async Task LoadBezier() { await LoadBezierTxtAsync("MoveLine"); } public static async Task UnLoadBezier() { await UnLoadBezierTxtAsync("MoveLine"); } public static async Task LoadSingleBezierTxtAsync(string path) { AsyncOperationHandle handle = Addressables.LoadAssetAsync(path); await handle.Task; var lines = handle.Result.text.Split('\n'); foreach (var line in lines) { if (string.IsNullOrWhiteSpace(line)) continue; var parts = line.Split(';'); BezierCurveData curve = new BezierCurveData(); curve.name = parts[0]; List points = new List(); for (int i = 1; i < parts.Length; i++) { points.Add(ParseVector(parts[i])); } curve.start = points[0]; if (points.Count > 1) curve.end = points[points.Count - 1]; for (int i = 1; i < points.Count - 1; i++) curve.controlPoints.Add(points[i]); curves.Add(curve); dic_BezierCurveDatas.Add(curve.name, curve); } } public static async Task LoadBezierTxtAsync(string path) { List keys = new List(); keys.Add(path); keys.Add(GameManager.Instance.gameData.currGameType.ToString()); AsyncOperationHandle> handles = Addressables.LoadAssetsAsync( keys, null, Addressables.MergeMode.Intersection); await handles.Task; foreach (var text in handles.Result) { var lines = text.text.Split('\n'); foreach (var line in lines) { if (string.IsNullOrWhiteSpace(line)) continue; var parts = line.Split(';'); BezierCurveData curve = new BezierCurveData(); curve.name = parts[0]; List points = new List(); for (int i = 1; i < parts.Length; i++) { points.Add(ParseVector(parts[i])); } curve.start = points[0]; if (points.Count > 1) curve.end = points[points.Count - 1]; for (int i = 1; i < points.Count - 1; i++) curve.controlPoints.Add(points[i]); curves.Add(curve); // 改成索引器赋值,避免重复 key 报错 dic_BezierCurveDatas[curve.name] = curve; } } Debug.Log("曲线读取完成共" + dic_BezierCurveDatas.Count + "条"); } public static async Task UnLoadBezierTxtAsync(string path) { List keys = new List(); keys.Add(path); keys.Add(GameManager.Instance.gameData.currGameType.ToString()); AsyncOperationHandle> handles = Addressables.LoadAssetsAsync(keys, null, Addressables.MergeMode.Intersection); await handles.Task; foreach (var text in handles.Result) { var lines = text.text.Split('\n'); foreach (var line in lines) { if (string.IsNullOrWhiteSpace(line)) continue; var parts = line.Split(';'); string curveName = parts[0]; // 如果字典里有该曲线,移除 if (dic_BezierCurveDatas.ContainsKey(curveName)) { dic_BezierCurveDatas.Remove(curveName); } // 从列表中移除对应曲线 curves.RemoveAll(c => c.name == curveName); } } // 释放 Addressables 资源 Addressables.Release(handles); Debug.Log("曲线卸载完成,剩余曲线数量:" + dic_BezierCurveDatas.Count); } private static Vector2 ParseVector(string s) { var xy = s.Split(','); return new Vector2(float.Parse(xy[0]), float.Parse(xy[1])); } public BezierCurveData bezierCurveData; public float moveTime; public float moveSpeed; public void Init(BezierCurveData bezierCurveData, float Time) { this.bezierCurveData = bezierCurveData; this.moveTime = Time; Debug.Log($"初始化曲线 {this.bezierCurveData.name} ,移动时间 {moveTime}"); } /// /// 使用 Job 计算 B样条点 /// public Vector2 GetBezierPointJob(float t) { if (t>moveTime) { t=moveTime; } t = t / moveTime; List pts = new List(); pts.Add(bezierCurveData.start); pts.AddRange(bezierCurveData.controlPoints); pts.Add(bezierCurveData.end); var controlPoints = new NativeArray(pts.ToArray(), Allocator.TempJob); var result = new NativeArray(1, Allocator.TempJob); var job = new BSplineJob { controlPoints = controlPoints, t = t, result = result }; JobHandle handle = job.Schedule(); handle.Complete(); Vector2 worldPos = CoordinateTransformation.CanvasToWorld(result[0], UIManager.Instance.uiRoot.GetComponent(), Camera.main); controlPoints.Dispose(); result.Dispose(); return worldPos; } // Job 结构体 [BurstCompile] public struct BSplineJob : IJob { [ReadOnly] public NativeArray controlPoints; public float t; public NativeArray result; public void Execute() { var temp = new NativeArray(controlPoints.Length, Allocator.Temp); controlPoints.CopyTo(temp); int count = temp.Length; while (count > 1) { for (int i = 0; i < count - 1; i++) { temp[i] = Vector2.Lerp(temp[i], temp[i + 1], t); } count--; } result[0] = temp[0]; temp.Dispose(); } } } #endregion #region zijixie //using System.Collections; //using System.Collections.Generic; //using System.IO; //using System.Threading.Tasks; //using UnityEngine; //using UnityEngine.AddressableAssets; //using UnityEngine.ResourceManagement.AsyncOperations; //public class MonsterMoveLine //{ // public static Dictionary dic_BezierCurveDatas = new Dictionary(); // public static List curves = new List(); // public class BezierCurveData // { // public string name; // public Vector2 start; // public List controlPoints = new List(); // public Vector2 end; // } // public static async void LoadBezier() // { // await LoadBezierTxtAsync("MoveLine"); // } // /// // /// 读取曲线数据 读取单个 // /// // /// // /// // public static async Task LoadSingleBezierTxtAsync(string path) // { // AsyncOperationHandle handle = Addressables.LoadAssetAsync(path); // await handle.Task; // var lines = handle.Result.text.Split('\n'); // foreach (var line in lines) // { // if (string.IsNullOrWhiteSpace(line)) continue; // var parts = line.Split(';'); // BezierCurveData curve = new BezierCurveData(); // // 第一个是曲线名 // curve.name = parts[0]; // // 后面所有都是点 // List points = new List(); // for (int i = 1; i < parts.Length; i++) // { // points.Add(ParseVector(parts[i])); // } // // 第一个点是 start // curve.start = points[0]; // if (points.Count > 1) // { // // 最后一个点是 end // curve.end = points[points.Count - 1]; // } // // 中间的都是 controlPoints // for (int i = 1; i < points.Count - 1; i++) // { // curve.controlPoints.Add(points[i]); // } // curves.Add(curve); // dic_BezierCurveDatas.Add(curve.name, curve); // } // } // /// // /// 读取曲线数据 游戏开始时在awake调用aa包 // /// // /// // /// // public static async Task LoadBezierTxtAsync(string path) // { // List keys = new List(); // keys.Add(path); // keys.Add(GameManager.Instance.gameData.currGameType.ToString()); // AsyncOperationHandle> handles = Addressables.LoadAssetsAsync(keys, null, Addressables.MergeMode.Intersection); // await handles.Task; // foreach (var text in handles.Result) // { // var lines = text.text.Split('\n'); // foreach (var line in lines) // { // if (string.IsNullOrWhiteSpace(line)) continue; // var parts = line.Split(';'); // BezierCurveData curve = new BezierCurveData(); // // 第一个是曲线名 // curve.name = parts[0]; // // 后面所有都是点 // List points = new List(); // for (int i = 1; i < parts.Length; i++) // { // points.Add(ParseVector(parts[i])); // } // // 第一个点是 start // curve.start = points[0]; // if (points.Count > 1) // { // // 最后一个点是 end // curve.end = points[points.Count - 1]; // } // // 中间的都是 controlPoints // for (int i = 1; i < points.Count - 1; i++) // { // curve.controlPoints.Add(points[i]); // } // curves.Add(curve); // dic_BezierCurveDatas.Add(curve.name, curve); // } // } // Debug.Log("曲线读取完成共" + dic_BezierCurveDatas.Count + "条"); // } // private static Vector2 ParseVector(string s) // { // var xy = s.Split(','); // return new Vector2(float.Parse(xy[0]), float.Parse(xy[1])); // } // public BezierCurveData bezierCurveData; // public float moveTime; // public float moveSpeed; // public void Init(BezierCurveData bezierCurveData, float Time) // { // this.bezierCurveData = bezierCurveData; // this.moveTime = time; // Debug.Log($"初始化曲线 {this.bezierCurveData.name} ,移动时间 {moveTime}"); // } // /// // /// 获取曲线上的点 // /// // /// // /// // public Vector2 GetBezierPoint(float t) // { // t = t / moveTime; // BezierCurveData curve = bezierCurveData; // List points = new List(); // points.Add(curve.start); // points.AddRange(curve.controlPoints); // points.Add(curve.end); // return DeCasteljau_BY(points, t % 1); // } // /// // /// 贝塞尔 // /// // /// // /// // /// // private Vector2 DeCasteljau_BSE(List points, float t) // { // while (points.Count > 1) // { // List next = new List(); // for (int i = 0; i < points.Count - 1; i++) // { // next.Add(Vector2.Lerp(points[i], points[i + 1], t)); // } // points = next; // } // return CoordinateTransformation.CanvasToWorld(points[0], UIManager.Instance.uiRoot.GetComponent(), Camera.main); // } // /// // /// B样 // /// // /// // /// // /// // private Vector2 DeCasteljau_BY(List points, float t) // { // // 方法A:保持德卡斯特里奥算法(推荐,数值更稳定) // while (points.Count > 1) // { // List next = new List(); // for (int i = 0; i < points.Count - 1; i++) // { // next.Add(Vector2.Lerp(points[i], points[i + 1], t)); // } // points = next; // } // return CoordinateTransformation.CanvasToWorld(points[0], // UIManager.Instance.uiRoot.GetComponent(), Camera.main); // /* 方法B:伯恩斯坦多项式形式(标准贝塞尔公式)- 如果要用这个替换上面的循环 // int n = points.Count - 1; // Vector2 result = Vector2.zero; // for (int i = 0; i <= n; i++) // { // float bernstein = BinomialCoefficient(n, i) * Mathf.Pow(t, i) * Mathf.Pow(1 - t, n - i); // result += points[i] * bernstein; // } // return CoordinateTransformation.CanvasToWorld(result, // UIManager.Instance.uiRoot.GetComponent(), Camera.main); // */ // } // // 计算二项式系数 // private float BinomialCoefficient(int n, int k) // { // float result = 1f; // for (int i = 1; i <= k; i++) // { // result *= (float)(n - k + i) / i; // } // return result; // } //} #endregion