diff --git a/Assets/Scripts/MiniGame/HuoShan/Emo/LakeLineDrawer.cs b/Assets/Scripts/MiniGame/HuoShan/Emo/LakeLineDrawer.cs index e6f96df43..bc39da3b8 100644 --- a/Assets/Scripts/MiniGame/HuoShan/Emo/LakeLineDrawer.cs +++ b/Assets/Scripts/MiniGame/HuoShan/Emo/LakeLineDrawer.cs @@ -1,9 +1,8 @@ -using System.Collections.Generic; using UnityEngine; using Shapes; +using System.Collections.Generic; [ExecuteAlways] -[RequireComponent(typeof(MeshCollider))] public class LakeLineDrawer : ImmediateModeShapeDrawer { [Header("场设置")] @@ -19,92 +18,122 @@ public class LakeLineDrawer : ImmediateModeShapeDrawer public float timeScale = 1f; [Header("涟漪参数")] - public float rippleStrength = 1.5f; - public float rippleRadius = 2f; - public float rippleDuration = 2f; + public float rippleStrength = 2f; + public float rippleDuration = 1.5f; + public float rippleSpreadSpeed = 6f; + public float rippleSharpness = 2f; + public float rippleDelay = 0.25f; // ⏱️ 新增:扩散延迟(秒) private Vector3[] points; private float time; - // 涟漪记录 - private List rippleCenters = new List(); - private List rippleTimes = new List(); + private struct Ripple + { + public Vector2 position; + public float startTime; + public float delay; + } + + private struct RippleResult + { + public float heightOffset; + public float brightnessBoost; + } + + private List ripples = new List(); private void Update() { - // 运行中才响应点击 + time = Application.isPlaying ? Time.time * timeScale : 0f; + if (Application.isPlaying && Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out RaycastHit hit)) { - // 将点击点转换为局部坐标 - Vector3 localPos = transform.InverseTransformPoint(hit.point); - rippleCenters.Add(new Vector2(localPos.x, localPos.z)); - rippleTimes.Add(time); + Vector3 hitPos = hit.point; + ripples.Add(new Ripple + { + position = new Vector2(hitPos.x, hitPos.z), + startTime = Time.time, + delay = rippleDelay + }); } } - // 清除过时涟漪 - if (Application.isPlaying) - { - for (int i = rippleCenters.Count - 1; i >= 0; i--) - { - if (time - rippleTimes[i] > rippleDuration) - { - rippleCenters.RemoveAt(i); - rippleTimes.RemoveAt(i); - } - } - } + ripples.RemoveAll(r => Time.time - r.startTime > rippleDuration + rippleDelay); } - private float GetNoise(float x, float z, float t) + private RippleResult GetRippleEffect(float x, float z, float currentTime) { - float noise = 0f; + float rippleOffset = 0f; + float brightness = 0f; + + foreach (var ripple in ripples) + { + float elapsed = currentTime - ripple.startTime; + + if (elapsed < ripple.delay) + { + // 尖刺阶段,不扩散,只在中心显示尖刺 + float dist = Vector2.Distance(new Vector2(x, z), ripple.position); + float spike = Mathf.Exp(-dist * rippleSharpness); // 尖锐程度 + float ease = Mathf.Sin((elapsed / ripple.delay) * Mathf.PI * 0.5f); // easeIn + + rippleOffset += spike * rippleStrength * ease; + continue; + } + + // 扩散阶段 + float spreadElapsed = elapsed - ripple.delay; + float spread = spreadElapsed * rippleSpreadSpeed; + float dist2 = Vector2.Distance(new Vector2(x, z), ripple.position); + float t = Mathf.Clamp01(spreadElapsed / rippleDuration); + float ease2 = Mathf.Sin(t * Mathf.PI); + + float spike2 = Mathf.Exp(-Mathf.Pow(dist2 - spread, 2f) * rippleSharpness); + rippleOffset += spike2 * rippleStrength * ease2; + + float bright = Mathf.Exp(-Mathf.Pow((dist2 - spread) * 0.5f, 2f)); + brightness += bright * ease2; + } + + return new RippleResult + { + heightOffset = rippleOffset, + brightnessBoost = brightness + }; + } + + private float GetHeight(float x, float z, float currentTime) + { + float noise = 0; float amp = 1f; float freq = 1f; + for (int i = 0; i < 3; i++) { float nx = x * freq * noiseScale; float nz = z * freq * noiseScale; - float nt = t * waveSpeed * freq; + float nt = currentTime * waveSpeed * freq; noise += Mathf.PerlinNoise(nx + nt, nz + nt) * amp; amp *= 0.5f; freq *= 2f; } - float ripple = 0f; - for (int i = 0; i < rippleCenters.Count; i++) - { - Vector2 center = rippleCenters[i]; - float rippleTime = t - rippleTimes[i]; - if (rippleTime > rippleDuration) continue; - - float dist = Vector2.Distance(new Vector2(x, z), center); - if (dist > rippleRadius) continue; - - float nd = dist / rippleRadius; - float rippleVal = Mathf.Sin((1f - nd) * Mathf.PI * 2f - rippleTime * 4f) * (1f - nd); - ripple += rippleVal * rippleStrength * (1f - rippleTime / rippleDuration); - } - - return (noise + ripple) * waveHeight; + return noise * waveHeight; } public override void DrawShapes(Camera cam) { using (Draw.Command(cam)) { - time = Application.isPlaying ? Time.time * timeScale : 0f; - Draw.ResetAllDrawStates(); Draw.LineGeometry = LineGeometry.Volumetric3D; Draw.Thickness = lineWidth; - Draw.Color = Color.cyan; float step = fieldSize / (pointCount - 1); - float half = fieldSize * 0.5f; + float halfSize = fieldSize * 0.5f; if (points == null || points.Length != pointCount * pointCount) points = new Vector3[pointCount * pointCount]; @@ -113,10 +142,26 @@ public class LakeLineDrawer : ImmediateModeShapeDrawer { for (int j = 0; j < pointCount; j++) { - float x = -half + j * step; - float z = -half + i * step; - float y = GetNoise(x, z, time); - points[i * pointCount + j] = new Vector3(x, y, z); + float x = -halfSize + j * step; + float z = -halfSize + i * step; + + float baseHeight = GetHeight(x, z, time); + RippleResult ripple = GetRippleEffect(x, z, Time.time); + float finalY = baseHeight + ripple.heightOffset; + + // float shake = ripple.brightnessBoost > 0.01f ? Mathf.Sin(Time.time * 30f + x + z) * 0.02f : 0f; + Vector3 pos = new Vector3(x, finalY, z); + + points[i * pointCount + j] = pos; + + float depth = (finalY + waveHeight) / (waveHeight * 2f); + float brightness = Mathf.Clamp01(1f + ripple.brightnessBoost); + float pointScale = pointSize * (1f - depth * 0.5f); + + Color baseColor = Color.Lerp(new Color(0.5f, 1f, 1f), new Color(0f, 0.5f, 1f), depth); + baseColor *= brightness; + + Draw.Sphere(pos, pointScale, baseColor); } } @@ -127,12 +172,6 @@ public class LakeLineDrawer : ImmediateModeShapeDrawer int index = i * pointCount + j; Vector3 current = points[index]; - float depth = (current.y + waveHeight) / (waveHeight * 2f); - float scale = pointSize * (1f - depth * 0.5f); - Color pointColor = Color.Lerp(new Color(0.5f, 1f, 1f), new Color(0f, 0.3f, 1f, 0.5f), depth); - - Draw.Sphere(current, scale, pointColor); - if (j < pointCount - 1) { Vector3 next = points[index + 1];