过程存档

This commit is contained in:
2025-05-08 12:23:51 +08:00
parent 094b436246
commit d3d400d75b
4 changed files with 407 additions and 153 deletions
+120 -122
View File
@@ -132,16 +132,116 @@ GameObject:
serializedVersion: 6
m_Component:
- component: {fileID: 472731664}
- component: {fileID: 472731663}
- component: {fileID: 472731662}
- component: {fileID: 472731665}
- component: {fileID: 472731666}
- component: {fileID: 472731667}
- component: {fileID: 472731668}
m_Layer: 0
m_Name: GameObject
m_Name: LakeLineDrawer
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &472731662
--- !u!4 &472731664
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 472731661}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0.01, y: 0.52, z: -0.05}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!65 &472731665
BoxCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 472731661}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 1
serializedVersion: 3
m_Size: {x: 7.82, y: 1, z: 7.13}
m_Center: {x: 0, y: 0, z: 0}
--- !u!64 &472731666
MeshCollider:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 472731661}
m_Material: {fileID: 0}
m_IncludeLayers:
serializedVersion: 2
m_Bits: 0
m_ExcludeLayers:
serializedVersion: 2
m_Bits: 0
m_LayerOverridePriority: 0
m_IsTrigger: 0
m_ProvidesContacts: 0
m_Enabled: 0
serializedVersion: 5
m_Convex: 0
m_CookingOptions: 30
m_Mesh: {fileID: 0}
--- !u!114 &472731667
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 472731661}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4f1d20068959374280197d2f664e3b9, type: 3}
m_Name:
m_EditorClassIdentifier:
useCullingMasks: 0
fieldSize: 6.75
pointCount: 30
pointSize: 0.05
lineWidth: 0.01
noiseScale: 0.3
waveHeight: 1
waveSpeed: 0.2
timeScale: 1
rippleStrength: 2
rippleDuration: 1.5
rippleSpreadSpeed: 6
rippleSharpness: 2
rippleDelay: 0
playerPos: {x: 10, y: 7}
moveCooldown: 0.5
playerBounceHeight: 1.5
obstacles:
- {x: 17, y: 18}
- {x: 7, y: 13}
- {x: 16, y: 12}
- {x: 18, y: 12}
- {x: 20, y: 12}
- {x: 12, y: 4}
- {x: 23, y: 4}
- {x: 18, y: 4}
- {x: 25, y: 21}
- {x: 7, y: 21}
--- !u!114 &472731668
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
@@ -154,54 +254,18 @@ MonoBehaviour:
m_Name:
m_EditorClassIdentifier:
useCullingMasks: 0
fieldSize: 6.47
pointCount: 25
fieldSize: 6.75
pointCount: 30
pointSize: 0.05
lineWidth: 0.01
noiseScale: 0.52
waveHeight: 0.71
noiseScale: 0.3
waveHeight: 1
waveSpeed: 0.2
timeScale: 1
radialFrequency: 0.5
radialStrength: 1
--- !u!114 &472731663
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 472731661}
m_Enabled: 0
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: efc77758b3964bb47b33d516c7e80f62, type: 3}
m_Name:
m_EditorClassIdentifier:
useCullingMasks: 0
lineThickness: 0.0066
lineColor: {r: 0, g: 1, b: 0.24640584, a: 1}
seed: 0
lineCount: 100
branchesMin: 1
branchesMax: 5
branchLengthMin: 0.25
branchLengthMax: 1
maxAngDeviation: 1.0471976
use3D: 0
--- !u!4 &472731664
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 472731661}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 1.0485426, y: 3.0641944, z: -2.6293025}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
rippleStrength: 2
rippleDuration: 1.5
rippleSpreadSpeed: 6
rippleSharpness: 2
--- !u!1 &519420028
GameObject:
m_ObjectHideFlags: 0
@@ -214,6 +278,7 @@ GameObject:
- component: {fileID: 519420031}
- component: {fileID: 519420029}
- component: {fileID: 519420030}
- component: {fileID: 519420033}
m_Layer: 0
m_Name: Main Camera
m_TagString: MainCamera
@@ -339,92 +404,25 @@ Transform:
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
--- !u!1 &619394800
GameObject:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
serializedVersion: 6
m_Component:
- component: {fileID: 619394802}
- component: {fileID: 619394801}
m_Layer: 0
m_Name: Global Light 2D
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &619394801
--- !u!114 &519420033
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 619394800}
m_GameObject: {fileID: 519420028}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 073797afb82c5a1438f328866b10b3f0, type: 3}
m_Script: {fileID: 11500000, guid: c49b4cc203aa6414fae5c798d1d0e7d6, type: 3}
m_Name:
m_EditorClassIdentifier:
m_ComponentVersion: 1
m_LightType: 4
m_BlendStyleIndex: 0
m_FalloffIntensity: 0.5
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Intensity: 1
m_LightVolumeIntensity: 1
m_LightVolumeIntensityEnabled: 0
m_ApplyToSortingLayers: 00000000
m_LightCookieSprite: {fileID: 0}
m_DeprecatedPointLightCookieSprite: {fileID: 0}
m_LightOrder: 0
m_AlphaBlendOnOverlap: 0
m_OverlapOperation: 0
m_NormalMapDistance: 3
m_NormalMapQuality: 2
m_UseNormalMap: 0
m_ShadowIntensityEnabled: 0
m_ShadowIntensity: 0.75
m_ShadowVolumeIntensityEnabled: 0
m_ShadowVolumeIntensity: 0.75
m_LocalBounds:
m_Center: {x: 0, y: -0.00000011920929, z: 0}
m_Extent: {x: 0.9985302, y: 0.99853027, z: 0}
m_PointLightInnerAngle: 360
m_PointLightOuterAngle: 360
m_PointLightInnerRadius: 0
m_PointLightOuterRadius: 1
m_ShapeLightParametricSides: 5
m_ShapeLightParametricAngleOffset: 0
m_ShapeLightParametricRadius: 1
m_ShapeLightFalloffSize: 0.5
m_ShapeLightFalloffOffset: {x: 0, y: 0}
m_ShapePath:
- {x: -0.5, y: -0.5, z: 0}
- {x: 0.5, y: -0.5, z: 0}
- {x: 0.5, y: 0.5, z: 0}
- {x: -0.5, y: 0.5, z: 0}
--- !u!4 &619394802
Transform:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 619394800}
serializedVersion: 2
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
m_Children: []
m_Father: {fileID: 0}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_EventMask:
serializedVersion: 2
m_Bits: 4294967295
m_MaxRayIntersections: 0
--- !u!1660057539 &9223372036854775807
SceneRoots:
m_ObjectHideFlags: 0
m_Roots:
- {fileID: 519420032}
- {fileID: 619394802}
- {fileID: 472731664}
@@ -0,0 +1,262 @@
using UnityEngine;
using Shapes;
using System.Collections.Generic;
[ExecuteAlways]
public class EmoMazeDrawer : ImmediateModeShapeDrawer
{
[Header("场设置")]
public float fieldSize = 20f;
public int pointCount = 30;
public float pointSize = 0.15f;
public float lineWidth = 0.03f;
[Header("波动参数")]
public float noiseScale = 0.3f;
public float waveHeight = 1.5f;
public float waveSpeed = 1f;
public float timeScale = 1f;
[Header("涟漪参数")]
public float rippleStrength = 2f;
public float rippleDuration = 1.5f;
public float rippleSpreadSpeed = 6f;
public float rippleSharpness = 2f;
public float rippleDelay = 0.25f;
[Header("迷宫设置")]
public Vector2Int playerPos = new Vector2Int(1, 1);
public float moveCooldown = 0.2f;
public float playerBounceHeight = 1.5f;
public List<Vector2Int> obstacles = new List<Vector2Int>();
private float lastMoveTime = -999f;
private Vector3[] points;
private float time;
// 涟漪记录结构体
private struct Ripple
{
public Vector2 position;
public float startTime;
public float delay;
}
private struct RippleResult
{
public float heightOffset;
public float brightnessBoost;
}
private List<Ripple> ripples = new List<Ripple>();
private void Update()
{
// 时间更新(Play模式下使用 Time.time
time = Application.isPlaying ? Time.time * timeScale : Time.realtimeSinceStartup * timeScale;
if (Application.isPlaying)
{
HandleInput();
ripples.RemoveAll(r => Time.time - r.startTime > rippleDuration + rippleDelay);
}
}
private void HandleInput()
{
if (Time.time - lastMoveTime < moveCooldown) return;
Vector2Int dir = Vector2Int.zero;
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow)) dir = Vector2Int.up;
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow)) dir = Vector2Int.down;
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow)) dir = Vector2Int.left;
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)) dir = Vector2Int.right;
if (dir != Vector2Int.zero)
{
Vector2Int newPos = playerPos + dir;
if (IsInBounds(newPos) && !IsBlocked(newPos))
{
playerPos = newPos;
lastMoveTime = Time.time;
}
else
{
Vector3 world = GridToWorld(newPos);
AddRipple(world.x, world.z); // 产生“碰撞弹开”的涟漪
}
}
}
private bool IsInBounds(Vector2Int pos) =>
pos.x >= 0 && pos.y >= 0 && pos.x < pointCount && pos.y < pointCount;
private bool IsBlocked(Vector2Int pos)
{
foreach (var obs in obstacles)
{
if (Vector2Int.Distance(obs, pos) <= 1f) return true;
}
return false;
}
private void AddRipple(float x, float z)
{
ripples.Add(new Ripple
{
position = new Vector2(x, z),
startTime = Time.time,
delay = rippleDelay
});
}
private RippleResult GetRippleEffect(float x, float z, float currentTime)
{
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);
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 = currentTime * waveSpeed * freq;
noise += Mathf.PerlinNoise(nx + nt, nz + nt) * amp;
amp *= 0.5f;
freq *= 2f;
}
return noise * waveHeight;
}
private Vector3 GridToWorld(Vector2Int pos)
{
float step = fieldSize / (pointCount - 1);
float half = fieldSize * 0.5f;
float x = -half + pos.x * step;
float z = -half + pos.y * step;
return new Vector3(x, 0, z);
}
public override void DrawShapes(Camera cam)
{
using (Draw.Command(cam))
{
Draw.ResetAllDrawStates();
Draw.LineGeometry = LineGeometry.Volumetric3D;
Draw.Thickness = lineWidth;
float step = fieldSize / (pointCount - 1);
float halfSize = fieldSize * 0.5f;
if (points == null || points.Length != pointCount * pointCount)
points = new Vector3[pointCount * pointCount];
for (int i = 0; i < pointCount; i++)
{
for (int j = 0; j < pointCount; j++)
{
float x = -halfSize + j * step;
float z = -halfSize + i * step;
float baseHeight = GetHeight(x, z, time);
if (IsNearObstacle(new Vector2Int(j, i)))
baseHeight += playerBounceHeight;
RippleResult ripple = GetRippleEffect(x, z, Time.time);
float finalY = baseHeight + ripple.heightOffset;
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);
}
}
// 绘制线连接点
for (int i = 0; i < pointCount; i++)
{
for (int j = 0; j < pointCount; j++)
{
int index = i * pointCount + j;
Vector3 current = points[index];
if (j < pointCount - 1)
DrawLine(current, points[index + 1]);
if (i < pointCount - 1)
DrawLine(current, points[index + pointCount]);
}
}
// 玩家显示
Vector3 playerWorld = GridToWorld(playerPos);
playerWorld.y = points[playerPos.y * pointCount + playerPos.x].y + 0.3f;
Draw.Sphere(playerWorld, pointSize * 1.5f, Color.yellow);
}
}
private void DrawLine(Vector3 a, Vector3 b)
{
float avgY = (a.y + b.y) * 0.5f;
float lineDepth = (avgY + waveHeight) / (waveHeight * 2f);
Color lineColor = Color.Lerp(Color.cyan, new Color(0, 0.5f, 1f, 0.3f), lineDepth);
Draw.Line(a, b, lineWidth * (1f - lineDepth * 0.5f), lineColor);
}
private bool IsNearObstacle(Vector2Int pos)
{
foreach (var o in obstacles)
{
if (Vector2Int.Distance(o, pos) <= 1f)
return true;
}
return false;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f4f1d20068959374280197d2f664e3b9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -18,11 +18,10 @@ public class LakeLineDrawer : ImmediateModeShapeDrawer
public float timeScale = 1f;
[Header("涟漪参数")]
public float rippleStrength = 2f;
public float rippleDuration = 1.5f;
public float rippleSpreadSpeed = 6f;
public float rippleSharpness = 2f;
public float rippleDelay = 0.25f; // ⏱️ 新增:扩散延迟(秒)
public float rippleStrength = 2f; // 尖刺强度
public float rippleDuration = 1.5f; // 持续时间
public float rippleSpreadSpeed = 6f; // 扩散速度
public float rippleSharpness = 2f; // 尖刺锐度
private Vector3[] points;
private float time;
@@ -31,7 +30,6 @@ public class LakeLineDrawer : ImmediateModeShapeDrawer
{
public Vector2 position;
public float startTime;
public float delay;
}
private struct RippleResult
@@ -55,13 +53,12 @@ public class LakeLineDrawer : ImmediateModeShapeDrawer
ripples.Add(new Ripple
{
position = new Vector2(hitPos.x, hitPos.z),
startTime = Time.time,
delay = rippleDelay
startTime = Time.time
});
}
}
ripples.RemoveAll(r => Time.time - r.startTime > rippleDuration + rippleDelay);
ripples.RemoveAll(r => Time.time - r.startTime > rippleDuration);
}
private RippleResult GetRippleEffect(float x, float z, float currentTime)
@@ -72,30 +69,17 @@ public class LakeLineDrawer : ImmediateModeShapeDrawer
foreach (var ripple in ripples)
{
float elapsed = currentTime - ripple.startTime;
float spread = elapsed * rippleSpreadSpeed;
float dist = Vector2.Distance(new Vector2(x, z), ripple.position);
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
float t = Mathf.Clamp01(elapsed / rippleDuration);
float ease = Mathf.Sin(t * Mathf.PI);
rippleOffset += spike * rippleStrength * ease;
continue;
}
float spike = Mathf.Exp(-Mathf.Pow(dist - spread, 2f) * rippleSharpness);
rippleOffset += spike * rippleStrength * ease;
// 扩散阶段
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;
float bright = Mathf.Exp(-Mathf.Pow((dist - spread) * 0.5f, 2f));
brightness += bright * ease;
}
return new RippleResult
@@ -149,7 +133,6 @@ public class LakeLineDrawer : ImmediateModeShapeDrawer
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;