主题
冲锋遇静态碰撞停止
适用于 SCE Unit/Ability 游戏的 Surface2D 冲锋。复用现有单位,由服务端效果和 Mover 控制移动,客户端由框架同步。
先选对碰撞体系
Surface2D 的静态碰撞来自场景保存时烘焙的地形/装饰物碰撞,以及手绘碰撞格。摆放一个可见模型或 StaticMesh 并不能证明它在这套静态碰撞中。该路线与 Volumetric3D 的模型物理碰撞配置不同。
用场景编辑器或 Terrain MCP 编辑障碍,显式保存场景后再调试。手绘碰撞查询只读手绘层,不能用空查询结果否定烘焙地形/装饰物碰撞。
配置效果和单位
在项目源数编中创建/继承 GameDataEffectLaunchMissile,或在已有 GameData 初始化代码中注册。不要改 DataGenerated 来配置技能。继承冲刺模板时,检查模板的实体命中和距离参数并显式覆盖;数组的最终值应读回确认。
| 字段 | 推荐配置 | 作用 |
|---|---|---|
Method | UseExistingMissile | 移动已有单位 |
WhichUnit.Value | Caster | 复用施法者本人 |
LaunchLocation.Value / LaunchTargetType | Caster / Unit | 从本人当前位置发射 |
TargetLocation.Value / 效果 TargetType | MainTarget / Point | 使用技能给出的目标点 |
FixedRange | 例如 800 | 将方向转换为固定距离终点 |
FixedRangeOffsetByUnitRadius | false | 示例距离不额外加单位半径 |
Speed | 例如 1200 | 冲锋速度 |
FinishArriveRadius | 示例为 0 | 终点到达容差,按玩法调整 |
StickToGround | true | 贴地冲锋 |
TurnToDirection | true | 朝冲锋方向转向 |
DoStaticCollision | true | 检测静态障碍并停止效果 |
StaticMask | [Unwalkable, Cliff] | 示例中的悬崖碰撞配置,按项目障碍类型选择 |
DoImpactEntity / ImpactEffect | false / null | 仅测静态障碍时,排除实体命中影响 |
主角 GameDataUnit.UpdateFlags.AllowMover 必须为 true。技能 GameDataAbilityExecute.Effect 指向此效果;方向技能可使用 AbilityTargetType.Vector,并关闭自动索敌以保留玩家指定方向。Ability.Range 不代替效果的 FixedRange。
纯代码效果示例(dashLink 为项目声明的效果 GameLink,在 GameData 初始化中使用):
csharp
using GameCore.BaseType;
using GameCore.Execution.Data;
using GameCore.Struct;
_ = new GameDataEffectLaunchMissile(dashLink)
{
Method = EffectLaunchMissileMethod.UseExistingMissile,
WhichUnit = new() { Value = TargetLocation.Caster },
LaunchLocation = new() { Value = TargetLocation.Caster },
LaunchTargetType = TargetType.Unit,
TargetLocation = new() { Value = TargetLocation.MainTarget },
TargetType = TargetType.Point,
FixedRange = static (_) => 800f,
FixedRangeOffsetByUnitRadius = false,
Speed = static (_) => 1200f,
FinishArriveRadius = static (_) => 0f,
StickToGround = true,
TurnToDirection = true,
DoStaticCollision = true,
StaticMask = [StaticCollisionMask.Unwalkable, StaticCollisionMask.Cliff],
DoImpactEntity = false,
ImpactEffect = null,
};默认 StaticMask 是 [Unflyable],并非地面冲锋的通用配置。需要拦截悬崖时显式包含 Cliff,其它障碍按项目实际遮挡类别配置并验证。运行时使用 StaticCollisionMask 枚举名;Terrain MCP 的 collision_flags 是场景原生位值,不要把其数值直接复制为运行时枚举。
停止与收尾
开启 DoStaticCollision 后,LaunchMissile 会在 Mover 的静态碰撞事件中停止效果,无需额外写每帧检测或把主角销毁。UseExistingMissile 移除 Mover 时保留原单位;CreateMissile 是新建投射物的另一条路线。
ImpactEffect 用于实体命中,不用于静态障碍。正常到达执行 CompleteEffect;碰撞停止属于中断,不应期待 CompleteEffect 收尾。需要正常到达或中断都清理的状态/表现时,使用持续效果的 FinalEffect;需要区分停止原因时再设计对应响应。
验收与排查
- 复用一个编辑器,在项目副本中放置可见悬崖或明确的碰撞区域。显式保存场景并重新打开,确认障碍仍存在,再编译调试。
- 空地冲锋应接近配置距离;朝障碍冲锋应明显提前停止。记录服务端起止位置/距离,检查停止后的 Mover 和主角是否仍有效,并确认可以再次施放。
- 对悬崖、项目装饰物和手绘碰撞分别测试,不以其中一类通过代替全部碰撞类型验收。停止距离取决于项目配置和障碍布局,不使用样例距离作为固定阈值。
- 若穿过障碍,先查场景是否保存、调试是否加载同一场景、最终效果是否启用
DoStaticCollision、掩码是否覆盖障碍类别。仅看到模型或仅查询手绘层不足以判断。 - 若不移动,查
AllowMover、WhichUnit、发射位置和目标解析;若提前命中单位,查继承的DoImpactEntity、ImpactMaxCount和ImpactEffect。
编译问题看项目 Server-Debug.log / Client-Debug.log;对局行为看编辑器 logs/server / logs/client。场景保存和重新编译是不同步骤,不能用编译成功代替场景落盘验证。
更多投射物模式见 ProjectilePatterns。