// using UnityEngine; // using System.Collections.Generic; // // namespace NBF // { // public class LureTrajectorySimulator : MonoBehaviour // { // [Header("基础参数")] public int maxSimulationSteps = 1000; // public float simulationDuration = 10f; // public float timeStep = 0.02f; // // [Header("抛投力度")] public float minThrowPower = 15f; // public float maxThrowPower = 45f; // // [Header("空气阻力参数")] [Tooltip("阻力系数,非流线钓饵建议 0.8~1.2")] // public float dragCoefficient = 0.2f; // // [Tooltip("迎风面积,0.005m² ≈ 5cm²")] public float lureArea = 0.001f; // // // public List CalculateTrajectory(FishingLureCastInput input, Vector3 startPosition, // Vector3 castDirection) // { // List trajectory = new List(); // // Vector3 position = startPosition; // Vector3 direction = castDirection.normalized; // float throwPower = Mathf.Lerp(minThrowPower, maxThrowPower, input.power); // Vector3 velocity = direction * throwPower; // // float lureMass = input.lureWeight / 1000f; // 转 kg // Vector3 windDir = input.windDirection.normalized; // float windStrength = input.windStrength; // // float currentTime = 0f; // int steps = 0; // // while (currentTime < simulationDuration && steps < maxSimulationSteps) // { // if (position.y <= 0f) break; // // // 模拟风力逐渐生效 // float windInfluenceFactor = Mathf.Clamp01(currentTime / 1.5f); // 1.5秒内增长 // Vector3 windVelocity = windDir * windStrength * windInfluenceFactor; // // // 真实空气阻力模型 // Vector3 relVelocity = velocity - windVelocity; // // // 空气阻力 // float dragMag = 0.5f * PhysicsHelper.AirDensity * // relVelocity.sqrMagnitude * // dragCoefficient * lureArea; // // // // --- 钓线空气阻力模拟 --- // // 假设飞行中展开的线长度近似为当前位置的XZ平面长度 // float lineLength = Vector3.Distance(new Vector3(position.x, 0, position.z), // new Vector3(startPosition.x, 0, startPosition.z)); // float lineRadius = input.lineDiameter / 2000f; // mm转m再除以2得到半径 // // // 钓线的迎风面积估算:长度 * 直径 // float lineArea = lineLength * (lineRadius * 2f); // 近似为圆柱体侧面积的一部分 // // // 简化模型:线的附加空气阻力方向与当前速度方向相反 // float lineDragMag = 0.5f * PhysicsHelper.AirDensity * velocity.sqrMagnitude * dragCoefficient * // lineArea; // Vector3 lineDragForce = -velocity.normalized * lineDragMag; // // // Vector3 dragForce = -relVelocity.normalized * dragMag; // // // 合力 = 重力 + 空气阻力 // // Vector3 acceleration = (Physics.gravity + dragForce / lureMass); // Vector3 totalForce = dragForce + lineDragForce; // // 合力 = 重力 + 空气阻力 + 线阻力 // Vector3 acceleration = (Physics.gravity + totalForce / lureMass); // // // velocity += acceleration * timeStep; // position += velocity * timeStep; // // trajectory.Add(position); // currentTime += timeStep; // steps++; // } // // return trajectory; // } // // // // 示例调用 // private List _trajectory; // // private int _windIndex; // // public List Test(Transform cameraTransform) // { // Vector3[] directions = // { // Vector3.forward, // Vector3.back, // Vector3.right, // Vector3.left, // (Vector3.forward + Vector3.right).normalized, // (Vector3.forward + Vector3.left).normalized, // (Vector3.back + Vector3.right).normalized, // (Vector3.back + Vector3.left).normalized // }; // // FishingLureCastInput baseInput = new FishingLureCastInput // { // power = 1f, // lureWeight = 2.2f, // windStrength = 0f, // 风力大小 // lineDiameter = 0.14f // }; // // // Vector3 startPos = cameraTransform.position; // Vector3 throwDir = cameraTransform.forward.normalized; // // baseInput.windDirection = directions[_windIndex]; // _trajectory = CalculateTrajectory(baseInput, startPos, throwDir); // _trajectory = SimplifyTrajectoryRDP(_trajectory, 0.1f); // _windIndex++; // if (_windIndex >= directions.Length) // { // _windIndex = 0; // } // // var length = CalculateTrajectoryLength(_trajectory); // var distance = CalculateHorizontalDistance(_trajectory); // Debug.LogError($"轨迹点位数={_trajectory.Count} length={length} distance={distance}"); // SceneSettings.Instance.LineRenderer.startWidth = 0.1f; // SceneSettings.Instance.LineRenderer.endWidth = 0.1f; // SceneSettings.Instance.LineRenderer.positionCount = _trajectory.Count; // SceneSettings.Instance.LineRenderer.useWorldSpace = true; // SceneSettings.Instance.LineRenderer.SetPositions(_trajectory.ToArray()); // return _trajectory; // } // // /// // /// 计算轨迹总长度(线的实际长度) // /// // public float CalculateTrajectoryLength(List trajectory) // { // if (trajectory == null || trajectory.Count < 2) // return 0f; // // float totalLength = 0f; // for (int i = 1; i < trajectory.Count; i++) // { // totalLength += Vector3.Distance(trajectory[i - 1], trajectory[i]); // } // // return totalLength; // } // // /// // /// 计算水平距离(XZ平面上的直线距离) // /// // public float CalculateHorizontalDistance(List trajectory) // { // if (trajectory == null || trajectory.Count == 0) // return 0f; // // Vector3 startPoint = trajectory[0]; // Vector3 endPoint = trajectory[trajectory.Count - 1]; // // // 将Y坐标设为相同(地面高度) // startPoint.y = 0; // endPoint.y = 0; // // return Vector3.Distance(startPoint, endPoint); // } // // private void OnDrawGizmos() // { // if (_trajectory == null) return; // // Gizmos.color = Color.cyan; // for (int i = 0; i < _trajectory.Count - 1; i++) // { // Gizmos.DrawLine(_trajectory[i], _trajectory[i + 1]); // } // // if (_trajectory.Count > 0) // { // Gizmos.color = Color.green; // Gizmos.DrawSphere(_trajectory[0], 0.1f); // // Gizmos.color = Color.red; // Gizmos.DrawSphere(_trajectory[_trajectory.Count - 1], 0.1f); // // for (int i = 1; i < _trajectory.Count; i += 10) // { // Gizmos.color = Color.Lerp(Color.green, Color.red, i / (float)_trajectory.Count); // Gizmos.DrawSphere(_trajectory[i], 0.05f); // } // } // } // // // public static List SimplifyTrajectoryRDP(List points, float tolerance) // { // if (points == null || points.Count < 3) // return new List(points); // // List result = new List(); // SimplifySection(points, 0, points.Count - 1, tolerance, result); // result.Add(points[points.Count - 1]); // return result; // } // // private static void SimplifySection(List points, int start, int end, float tolerance, // List result) // { // if (end <= start + 1) // return; // // float maxDistance = -1f; // int index = -1; // Vector3 startPoint = points[start]; // Vector3 endPoint = points[end]; // // for (int i = start + 1; i < end; i++) // { // float distance = PerpendicularDistance(points[i], startPoint, endPoint); // if (distance > maxDistance) // { // maxDistance = distance; // index = i; // } // } // // if (maxDistance > tolerance) // { // SimplifySection(points, start, index, tolerance, result); // result.Add(points[index]); // SimplifySection(points, index, end, tolerance, result); // } // } // // private static float PerpendicularDistance(Vector3 point, Vector3 lineStart, Vector3 lineEnd) // { // if (lineStart == lineEnd) return Vector3.Distance(point, lineStart); // Vector3 projected = Vector3.Project(point - lineStart, lineEnd - lineStart); // Vector3 closest = lineStart + projected; // return Vector3.Distance(point, closest); // } // } // // public static class PhysicsHelper // { // public const float AirDensity = 1.225f; // } // }