Localize benchmark adapter text

This commit is contained in:
JSD\13999
2026-06-13 14:44:46 +08:00
parent 2ff0dfd6bd
commit 5849bd6dd9
3 changed files with 65 additions and 62 deletions

View File

@@ -12,7 +12,7 @@ namespace FishROV.AvoidanceBenchmark
private AvoidanceBenchmarkConfig config; private AvoidanceBenchmarkConfig config;
private bool initialized; private bool initialized;
public string Name => "RVO2 / RVO2-3D"; public string Name => "RVO2 / RVO2-3D 本地避障";
public bool IsAvailable => bridge != null && bridge.IsAvailable; public bool IsAvailable => bridge != null && bridge.IsAvailable;
public string Status => bridge != null public string Status => bridge != null
? bridge.Status ? bridge.Status
@@ -86,7 +86,7 @@ namespace FishROV.AvoidanceBenchmark
private sealed class Rvo2ReflectionBridge private sealed class Rvo2ReflectionBridge
{ {
public const string MissingPackageStatus = public const string MissingPackageStatus =
"RVO2 package/source not found. Place the RVO2 or RVO2-3D C# source/package in Assets or Packages with a Simulator type such as RVO.Simulator; this adapter will bind by reflection."; "未检测到 RVO2/RVO2-3D 源码或包;请把 C# 版本 RVO2 放到 Assets Packages,并提供类似 RVO.Simulator 的 Simulator 类型。当前退回基线移动。";
private static readonly string[] SimulatorTypeNames = private static readonly string[] SimulatorTypeNames =
{ {
@@ -154,7 +154,7 @@ namespace FishROV.AvoidanceBenchmark
var simulator = CreateOrGetSimulator(simulatorType); var simulator = CreateOrGetSimulator(simulatorType);
if (simulator == null) if (simulator == null)
{ {
return Unavailable("RVO2 Simulator type was found, but no singleton instance or public constructor could be used."); return Unavailable("已找到 RVO2 Simulator 类型,但无法取得单例实例,也没有可用的公开无参构造函数。当前退回基线移动。");
} }
var vector2Type = FindType(simulatorType, "RVO.Vector2", "RVO2.Vector2"); var vector2Type = FindType(simulatorType, "RVO.Vector2", "RVO2.Vector2");
@@ -163,7 +163,7 @@ namespace FishROV.AvoidanceBenchmark
var agentVectorType = use3D ? vector3Type : vector2Type; var agentVectorType = use3D ? vector3Type : vector2Type;
if (agentVectorType == null) if (agentVectorType == null)
{ {
return Unavailable("RVO2 Simulator type was found, but no supported RVO.Vector2 or RVO.Vector3 type was found."); return Unavailable("已找到 RVO2 Simulator 类型,但未找到可支持的 RVO.Vector2 RVO.Vector3 类型。当前退回基线移动。");
} }
var addAgent = FindMethod(simulatorType, "addAgent", "AddAgent", new[] { agentVectorType }); var addAgent = FindMethod(simulatorType, "addAgent", "AddAgent", new[] { agentVectorType });
@@ -176,7 +176,7 @@ namespace FishROV.AvoidanceBenchmark
if (addAgent == null || setAgentPrefVelocity == null || getAgentVelocity == null || doStep == null) if (addAgent == null || setAgentPrefVelocity == null || getAgentVelocity == null || doStep == null)
{ {
return Unavailable("RVO2 Simulator type was found, but required methods addAgent, setAgentPrefVelocity, getAgentVelocity, and doStep were not all available."); return Unavailable("已找到 RVO2 Simulator 类型,但缺少 addAgentsetAgentPrefVelocitygetAgentVelocity doStep 等必要方法。当前退回基线移动。");
} }
var bridge = new Rvo2ReflectionBridge( var bridge = new Rvo2ReflectionBridge(
@@ -185,7 +185,7 @@ namespace FishROV.AvoidanceBenchmark
vector2Type, vector2Type,
vector3Type, vector3Type,
use3D, use3D,
use3D ? "RVO2-3D reflection adapter active" : "RVO2 reflection adapter active", use3D ? "RVO2-3D 已通过反射接入。" : "RVO2 已通过反射接入。",
addAgent, addAgent,
setAgentPrefVelocity, setAgentPrefVelocity,
doStep, doStep,
@@ -207,7 +207,7 @@ namespace FishROV.AvoidanceBenchmark
} }
catch (Exception exception) catch (Exception exception)
{ {
Debug.LogWarning($"RVO2 addAgent failed: {exception.Message}"); Debug.LogWarning($"RVO2 添加 Agent 失败:{exception.Message}");
return -1; return -1;
} }
} }
@@ -220,7 +220,7 @@ namespace FishROV.AvoidanceBenchmark
} }
catch (Exception exception) catch (Exception exception)
{ {
Debug.LogWarning($"RVO2 setAgentPrefVelocity failed: {exception.Message}"); Debug.LogWarning($"RVO2 设置期望速度失败:{exception.Message}");
} }
} }
@@ -233,7 +233,7 @@ namespace FishROV.AvoidanceBenchmark
} }
catch (Exception exception) catch (Exception exception)
{ {
Debug.LogWarning($"RVO2 doStep failed: {exception.Message}"); Debug.LogWarning($"RVO2 模拟步进失败:{exception.Message}");
} }
} }
@@ -246,7 +246,7 @@ namespace FishROV.AvoidanceBenchmark
} }
catch (Exception exception) catch (Exception exception)
{ {
Debug.LogWarning($"RVO2 getAgentVelocity failed: {exception.Message}"); Debug.LogWarning($"RVO2 获取 Agent 速度失败:{exception.Message}");
return Vector3.zero; return Vector3.zero;
} }
} }
@@ -259,7 +259,7 @@ namespace FishROV.AvoidanceBenchmark
} }
catch (Exception exception) catch (Exception exception)
{ {
Debug.LogWarning($"RVO2 clear/reset failed: {exception.Message}"); Debug.LogWarning($"RVO2 清理/重置失败:{exception.Message}");
} }
} }

View File

@@ -11,7 +11,7 @@ namespace FishROV.AvoidanceBenchmark
private bool hasNavMeshData; private bool hasNavMeshData;
private int fallbackAgentCount; private int fallbackAgentCount;
public string Name => "Unity NavMeshAgent"; public string Name => "Unity NavMeshAgent 对照组";
public bool IsAvailable => hasNavMeshData; public bool IsAvailable => hasNavMeshData;
public string Status public string Status
@@ -20,15 +20,15 @@ namespace FishROV.AvoidanceBenchmark
{ {
if (!hasNavMeshData) if (!hasNavMeshData)
{ {
return "No runtime NavMesh data found; falling back to baseline movement. Bake a NavMesh or enable com.unity.ai.navigation and build a runtime NavMeshSurface."; return "未检测到运行时 NavMesh 数据;当前退回基线移动。请先烘焙 NavMesh或启用 com.unity.ai.navigation 并构建运行时 NavMeshSurface";
} }
if (fallbackAgentCount > 0) if (fallbackAgentCount > 0)
{ {
return $"Using NavMeshAgent for {navAgents.Count} agents; {fallbackAgentCount} agents could not be placed on the NavMesh and use baseline movement."; return $"NavMeshAgent 已接管 {navAgents.Count} 个对象;{fallbackAgentCount} 个对象无法放到 NavMesh 上,使用基线移动。";
} }
return $"Using Unity NavMeshAgent avoidance for {navAgents.Count} agents."; return $"Unity NavMeshAgent 避障已接管 {navAgents.Count} 个对象。";
} }
} }

View File

@@ -1,73 +1,76 @@
# Local Avoidance Benchmark Notes # 本地避障压测说明
## Goal ## 目标
This Unity project is a controlled benchmark for local avoidance frameworks. The only intended variable between framework branches is the implementation selected by `AvoidanceFrameworkKind` and created through `AvoidanceAdapterRegistry`. 这个 Unity 工程用于横向压测本地避障方案。不同方案之间唯一应该变化的变量,是 `AvoidanceFrameworkKind` 选择后由 `AvoidanceAdapterRegistry` 创建的 adapter。
## Shared Runtime Surface ## 共享运行入口
- Scene: `Assets/Scenes/AvoidancePerfDemo.unity` - 场景:`Assets/Scenes/AvoidancePerfDemo.unity`
- Entry point: `AvoidancePerfBootstrap` - 入口脚本:`AvoidancePerfBootstrap`
- Game view debug panel: - Game 视口调试面板:
- framework selection - 避障方案选择
- scenario selection - 测试场景选择
- 2D / 2.5D / 3D mode - 2D / 2.5D / 3D 模式
- view mode switching - 观察视角切换
- fish count presets and slider - 小鱼数量预设和滑条
- pause / resume / reset - 暂停 / 继续 / 重置
- average FPS, 1% low FPS, simulation ms, GC allocation - 平均 FPS1% Low FPS、模拟耗时、GC 分配
- Shared agent representation: runtime-created cubes and capsules. - 表现对象:运行时创建的 Cube 和 Capsule
- Shared scenarios: - 共享场景:
- Free Swim - 自由巡游
- Cross Flow - 对向穿流
- Shark Charge - 鲨鱼冲群
- Narrow Passage - 狭窄通道
- Dense Circle Stress - 圆阵高压
## Adapter Boundary ## Adapter 边界
Framework branches should keep benchmark logic stable and make changes primarily under: 框架接入应主要修改:
```text ```text
Assets/Scripts/Benchmark/FrameworkAdapters/ Assets/Scripts/Benchmark/FrameworkAdapters/
``` ```
Adapter implementations may add package-specific components to created agents, but should not change: adapter 可以给运行时创建的对象追加框架自己的组件,但不应改变:
- scenario generation - 场景生成逻辑
- fish/shark count presets - 小鱼/鲨鱼数量档
- debug panel controls - Game 视口调试控件
- metric names - 指标名称
- camera/view modes - 相机/视角模式
- spawn parameters unless the framework requires a narrowly documented compatibility adjustment - spawn 参数,除非框架确实需要很小且有文档说明的兼容调整
## Current Baseline ## 当前基线
`NoAvoidanceAdapter` is the control group. It moves agents directly by preferred velocity and does not perform avoidance. `NoAvoidanceAdapter` 是对照基线:只按期望速度移动,不做避障。
The A* RVO, RVO2, and Unity NavMesh adapters are selected through the same debug panel so their behavior can be compared under the same scene, count, camera, and metrics. A* RVORVO2Unity NavMesh 都通过同一个调试面板选择,用同一套场景、数量、相机和指标进行对比。
## A* Pathfinding Project Pro RVO Adapter ## A* Pathfinding Project Pro RVO Adapter
`AstarRvoAdapter` is isolated under `Assets/Scripts/Benchmark/FrameworkAdapters/` and is selected only by `AvoidanceFrameworkKind.AstarRvo`. `AstarRvoAdapter` 位于 `Assets/Scripts/Benchmark/FrameworkAdapters/`,由 `AvoidanceFrameworkKind.AstarRvo` 选择。
- It uses reflection to find `Pathfinding.RVO.RVOController` and `Pathfinding.RVO.RVOSimulator`, so the project still compiles when A* Pathfinding Project Pro is not imported. - adapter 通过反射查找 `Pathfinding.RVO.RVOController` `Pathfinding.RVO.RVOSimulator`,所以没有导入 A* Pro 时工程仍可编译。
- When the A* Pro RVO types are missing, the Game view status reports the missing package and the agents fall back to baseline preferred-velocity movement. - 如果缺少 A* Pro RVO 类型Game 视口状态会提示缺包,并退回基线移动。
- When available, the adapter creates one runtime `RVOSimulator`, adds `RVOController` components to benchmark-created agents, feeds each preferred velocity into A* RVO, and writes the reflected avoidance velocity back through `BenchmarkAgent.ApplyVelocity`. - 如果类型存在adapter 会创建运行时 `RVOSimulator`,给 benchmark 对象添加 `RVOController`,把期望速度送入 A* RVO再把反射得到的避障速度写回 `BenchmarkAgent.ApplyVelocity`
- The shared benchmark scene, HUD, scenarios, count presets, metrics, and camera logic remain unchanged; the adapter is the only intended variable for this branch. - 共享场景、HUD、数量档、指标和相机逻辑不变。
## RVO2 / RVO2-3D Adapter ## RVO2 / RVO2-3D Adapter
`Rvo2Adapter` is intentionally a reflection adapter. The benchmark must compile even when no RVO2 package or source is present. `Rvo2Adapter` 是反射 adapter。没有 RVO2 源码或包时,工程仍可编译。
- Without RVO2 source/package, selecting `Rvo2` creates the same benchmark primitives and reports the missing package in the Game view `Status` line. - 如果缺少 RVO2/RVO2-3D选择 `RVO2` 时会创建同样的 benchmark 对象,并在 Game 视口状态中提示缺包,随后退回基线移动。
- To enable the real framework, place a C# RVO2 or RVO2-3D implementation under `Assets/` or add it as a package under `Packages/`. - 要启用真实框架,需要把 C# 版本 RVO2/RVO2-3D 放到 `Assets/` `Packages/`
- The adapter looks for a simulator type such as `RVO.Simulator`, `RVO2.Simulator`, `RVO3D.Simulator`, or `RVO.Simulator3D`. - adapter 会查找类似 `RVO.Simulator``RVO2.Simulator``RVO3D.Simulator``RVO.Simulator3D` 的 Simulator 类型。
- The required simulator methods are `addAgent`/`AddAgent`, `setAgentPrefVelocity`/`SetAgentPrefVelocity`, `getAgentVelocity`/`GetAgentVelocity`, and `doStep`/`DoStep`. - 必要方法包括 `addAgent` / `AddAgent``setAgentPrefVelocity` / `SetAgentPrefVelocity``getAgentVelocity` / `GetAgentVelocity``doStep` / `DoStep`
- 2D and 2.5D modes bind to an RVO `Vector2` style type and map Unity `x/z` to RVO `x/y`. 3D mode binds to an RVO `Vector3` style type when available. - 2D 2.5D 使用 RVO Vector2 风格类型,把 Unity `x/z` 映射到 RVO `x/y`3D 模式在可用时绑定 Vector3 风格类型。
## Unity NavMesh Adapter Notes ## Unity NavMesh Adapter
`UnityNavMeshAdapter` uses the built-in `UnityEngine.AI.NavMeshAgent` API when NavMesh data is already available at runtime. The benchmark scene creates its fish and shark primitives dynamically, so a normal empty runtime cube scene may not have baked NavMesh data. In that case the adapter reports the missing NavMesh in the HUD status and falls back to baseline movement instead of adding invalid `NavMeshAgent` components. `UnityNavMeshAdapter` 使用内置 `UnityEngine.AI.NavMeshAgent` 做对照组。
To exercise Unity's NavMesh avoidance path, provide NavMesh data before selecting `UnityNavMesh`. A baked scene NavMesh is sufficient. If the project should build the benchmark floor at runtime, enable `com.unity.ai.navigation` and add a runtime `NavMeshSurface` setup before the adapter initializes. - benchmark 场景里的鱼和鲨鱼是运行时创建的对象,空场景默认不会有可用 NavMesh。
- 没有运行时 NavMesh 数据时adapter 会在 Game 视口状态中提示,并退回基线移动,不会添加无效 `NavMeshAgent`
- 如果要测试 Unity NavMesh 避障,需要在选择 `NavMesh` 前提供 NavMesh 数据;烘焙场景 NavMesh 即可。
- 如果希望运行时生成 benchmark 地面 NavMesh需要启用 `com.unity.ai.navigation` 并补 `NavMeshSurface` 构建流程。