diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 5687951..9ad99a8 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index 9fac849..e005884 100644 Binary files a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo and b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo differ diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json index 2aa2ecd..514468d 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -96,7 +96,7 @@ "RelativeDocumentMoniker": "Flyover\\ThingclassFlyOver.cs", "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs", "RelativeToolTip": "Flyover\\ThingclassFlyOver.cs", - "ViewState": "AgIAAC0CAAAAAAAAAAAawCUCAAANAAAAAAAAAA==", + "ViewState": "AgIAAJUCAAAAAAAAAAAawKMCAAAFAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2025-10-29T14:17:06.867Z", "EditorCaption": "" diff --git a/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs b/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs index 4898c18..f181d55 100644 --- a/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs +++ b/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs @@ -31,6 +31,13 @@ namespace ArachnaeSwarm public float fadeOutStartProgress = 0.7f; // 开始淡出的进度阈值(0-1) public float defaultFadeOutDuration = 1.5f; // 默认淡出持续时间(仅用于销毁) + // 进场动画相关 - 新增 + public float approachDuration = 1.0f; // 进场动画持续时间(秒) + public float currentApproachTime = 0f; // 当前进场动画时间 + public bool approachCompleted = false; // 进场动画是否完成 + public float approachOffsetDistance = 3f; // 进场偏移距离(格) + public bool useApproachAnimation = true; // 是否使用进场动画 + // 伴飞相关 public float escortScale = 1f; // 伴飞缩放比例 public bool isEscort = false; // 是否是伴飞 @@ -54,23 +61,84 @@ namespace ArachnaeSwarm public Pawn caster; // 施法者引用 - // 属性 + // 属性 - 修改后的 DrawPos,包含进场动画 public override Vector3 DrawPos { get { - // 线性插值计算当前位置 + // 线性插值计算基础位置 Vector3 start = startPosition.ToVector3(); Vector3 end = endPosition.ToVector3(); + Vector3 basePos = Vector3.Lerp(start, end, currentProgress); // 添加高度偏移 - Vector3 basePos = Vector3.Lerp(start, end, currentProgress); basePos.y = altitude; + // 应用进场动画偏移 + if (useApproachAnimation && !approachCompleted) + { + basePos = ApplyApproachAnimation(basePos); + } + return basePos; } } + // 进场动画位置计算 + private Vector3 ApplyApproachAnimation(Vector3 basePos) + { + float approachProgress = currentApproachTime / approachDuration; + + // 使用缓动函数让移动更自然 + float easedProgress = EasingFunction(approachProgress, EasingType.OutCubic); + + // 计算偏移方向(飞行方向的反方向) + Vector3 approachDirection = -MovementDirection.normalized; + + // 计算偏移量:从最大偏移逐渐减少到0 + float currentOffset = approachOffsetDistance * (1f - easedProgress); + + // 应用偏移 + Vector3 offsetPos = basePos + approachDirection * currentOffset; + + return offsetPos; + } + + // 缓动函数 - 让动画更自然 + private float EasingFunction(float t, EasingType type) + { + switch (type) + { + case EasingType.OutCubic: + return 1f - Mathf.Pow(1f - t, 3f); + case EasingType.OutQuad: + return 1f - (1f - t) * (1f - t); + case EasingType.OutSine: + return Mathf.Sin(t * Mathf.PI * 0.5f); + default: + return t; + } + } + + // 缓动类型枚举 + private enum EasingType + { + Linear, + OutQuad, + OutCubic, + OutSine + } + + // 新增:进场动画进度(0-1) + public float ApproachProgress + { + get + { + if (approachCompleted) return 1f; + return Mathf.Clamp01(currentApproachTime / approachDuration); + } + } + public override Graphic Graphic { get @@ -203,6 +271,13 @@ namespace ArachnaeSwarm Scribe_Values.Look(ref fadeOutStartProgress, "fadeOutStartProgress", 0.7f); Scribe_Values.Look(ref defaultFadeOutDuration, "defaultFadeOutDuration", 1.5f); + // 进场动画数据保存 - 新增 + Scribe_Values.Look(ref approachDuration, "approachDuration", 1.0f); + Scribe_Values.Look(ref currentApproachTime, "currentApproachTime", 0f); + Scribe_Values.Look(ref approachCompleted, "approachCompleted", false); + Scribe_Values.Look(ref approachOffsetDistance, "approachOffsetDistance", 3f); + Scribe_Values.Look(ref useApproachAnimation, "useApproachAnimation", true); + Scribe_References.Look(ref caster, "caster"); Scribe_References.Look(ref faction, "faction"); } @@ -230,6 +305,21 @@ namespace ArachnaeSwarm fadeOutCompleted = false; fadeOutDuration = 0f; + // 重置进场动画状态 - 新增 + currentApproachTime = 0f; + approachCompleted = false; + + // 从 ModExtension 加载进场动画配置 + var extension = def.GetModExtension(); + if (extension != null) + { + useApproachAnimation = extension.useApproachAnimation; + approachDuration = extension.approachDuration; + approachOffsetDistance = extension.approachOffsetDistance; + } + + Log.Message($"FlyOver approach animation: {useApproachAnimation}, duration: {approachDuration}s, offset: {approachOffsetDistance}"); + // 开始飞行音效 if (playFlyOverSound && def.skyfaller?.floatingSound != null) { @@ -247,6 +337,18 @@ namespace ArachnaeSwarm if (!hasStarted || hasCompleted) return; + // 更新进场动画 - 新增 + if (useApproachAnimation && !approachCompleted) + { + currentApproachTime += 1f / 60f; + if (currentApproachTime >= approachDuration) + { + approachCompleted = true; + currentApproachTime = approachDuration; + Log.Message("FlyOver approach animation completed"); + } + } + // 更新淡入效果 if (!fadeInCompleted) { @@ -529,7 +631,8 @@ namespace ArachnaeSwarm // 工具方法:创建飞越物体 public static FlyOver MakeFlyOver(ThingDef flyOverDef, IntVec3 start, IntVec3 end, Map map, float speed = 1f, float height = 10f, ThingOwner contents = null, - float fadeInDuration = 1.5f, float defaultFadeOutDuration = 1.5f, Pawn casterPawn = null) + float fadeInDuration = 1.5f, float defaultFadeOutDuration = 1.5f, Pawn casterPawn = null, + bool useApproachAnimation = true, float approachDuration = 1.0f, float approachOffsetDistance = 3f) // 新增参数 { FlyOver flyOver = (FlyOver)ThingMaker.MakeThing(flyOverDef); flyOver.startPosition = start; @@ -539,6 +642,11 @@ namespace ArachnaeSwarm flyOver.fadeInDuration = fadeInDuration; flyOver.defaultFadeOutDuration = defaultFadeOutDuration; flyOver.caster = casterPawn; + + // 进场动画参数 - 新增 + flyOver.useApproachAnimation = useApproachAnimation; + flyOver.approachDuration = approachDuration; + flyOver.approachOffsetDistance = approachOffsetDistance; // 简化派系设置 - 直接设置 faction 字段 if (casterPawn != null && casterPawn.Faction != null) @@ -561,10 +669,9 @@ namespace ArachnaeSwarm Log.Message($"FlyOver created: {flyOver} from {start} to {end} at altitude {height}, Faction: {flyOver.faction?.Name ?? "NULL"}"); return flyOver; } - } - // ModExtension 配置 + // 扩展的 ModExtension 配置 - 新增进场动画参数 public class FlyOverShadowExtension : DefModExtension { public string customShadowPath; @@ -584,5 +691,10 @@ namespace ArachnaeSwarm public float fadeOutDistanceFactor = 0.01f; public float ActuallyHeight = 150f; + + // 进场动画配置 - 新增 + public bool useApproachAnimation = true; + public float approachDuration = 1.0f; + public float approachOffsetDistance = 3f; } }