碰撞系統開發指南
LCC Unity SDK 內建了一套碰撞系統,重點解決碰撞體構建與碰撞檢測的加速問題,也就是碰撞性能問題。Unity Collider 系統無法應付超大場景下的實時檢測。
LCC Unity SDK 採用自建碰撞系統,不再借助 Unity 提供的 MeshCollider 組件及相關能力,因此不能直接對 Unity 場景中的 GameObject 產生作用。其域創新(XGrids)官方生成的 LCC 數據格式( LCC Studio )在重建時會同時生成用於碰撞的 Mesh 數據,SDK 利用這份碰撞數據快速高效地構建場景碰撞。由於是自建碰撞系統,使用碰撞功能需要調用 SDK 提供的相應方法來實現。
注意:
SDK 內建碰撞系統與 Unity Collider 碰撞系統不兼容,無法直接作用於 Unity 中的
Rigidbody對象。數字人等角色的碰撞需要通過 SDK 的檢測方法自行驅動(見下文「數字人碰撞實現方式」)。如果是固定場景,也可以將 Mesh 數據提取出來提前烘焙成 NavMesh ,可與 Unity Collider 碰撞系統實現兼容,詳見 NavMesh 指南。
數據前置條件
碰撞檢測功能生效的前提是場景帶有對應的碰撞數據。早期版本重建的數據可能不包含碰撞數據,此時調用 SetColliderEnable(true) 會返回 false,後續所有檢測方法都不可用。
因此在開啟碰撞後,請務必檢查返回值:
bool ok = renderer.SetColliderEnable(true);
if (!ok)
{
Debug.LogWarning("當前數據不含碰撞體,無法開啟碰撞檢測");
}
基本使用流程
碰撞功能的基本使用流程分三步:
- 通過
Load()方法加載場景數據。 - 在加載完成回調中,通過
SetColliderEnable(true)開啟碰撞。 - 通過各類檢測方法(
RaycastMesh/IntersectsSphere/IntersectsCapsule)進行碰撞檢測。
// 1. 加載場景
renderer.Load(dataPath, onProgress: null, onComplete: () =>
{
// 2. 加載完成後開啟碰撞
if (renderer.SetColliderEnable(true))
{
colliderReady = true;
}
});
void Update()
{
if (!colliderReady) return;
// 3. 每幀進行碰撞檢測
var capsule = new Capsule(footPos, headPos, 0.3f);
if (m_manager.IntersectsCapsule(capsule, out Vector3 delta))
{
characterController.Move(delta);
}
}
說明:
SetColliderEnable()是Renderer的方法,檢測方法(RaycastMesh/IntersectsSphere/IntersectsCapsule/Raycast)掛在LCCManager上。請分別在對應對象上調用。

碰撞系統基本使用流程
數字人碰撞實現方式
由於 SDK 碰撞系統不作用於 Unity 的 Rigidbody,數字人(角色)的碰撞需要用檢測方法自行驅動。常見做法有三種:
- 雙射線檢測:使用
RaycastMesh()向下、向前各發射一條射線,通過射線返回結果判斷能否行走(向下探地面、向前探障礙)。 - 膠囊體檢測:使用
IntersectsCapsule()檢測數字人所在的膠囊體與碰撞網格是否相交,判定能否行走。重載版本的_delta返回下一個可安全到達的點的偏移量。 - 球體檢測:使用
IntersectsSphere()檢測數字人所在的球體與碰撞網格是否相交,判定能否行走。重載版本的_delta同樣返回可安全到達點的偏移量。

數字人碰撞的三種實現方式
RaycastMesh 與 Raycast 的取捨
SDK 提供兩類射線檢測方法,用途不同:
| 方法 | 檢測對象 | 精度 | 速度 | 適用場景 |
|---|---|---|---|---|
RaycastMesh() | 碰撞網格(Collider 數據) | 相對較低 | 快 | 數字人碰撞、逐幀檢測 |
Raycast() | 高斯基元(不依賴碰撞網格) | 相對較高 | 慢 | 測量類應用 |
Raycast() 直接對高斯基元進行射線檢測,精度更高,但速度慢,不建議每幀調用,因此不適合做數字人碰撞,只適合做測量類使用。數字人碰撞應優先使用依賴碰撞網格的 RaycastMesh()。
相關 API
以下碰撞相關方法中,SetColliderEnable() 掛在 Renderer 上,其餘檢測方法掛在 LCCManager 上。所有檢測方法都需要在場景加載完成後、且成功調用 SetColliderEnable(true) 之後才可用。
SetColliderEnable
// 返回值:bool → true=設置成功,false=數據不含碰撞體或實例未激活
public bool SetColliderEnable(bool _enable)
開關碰撞體功能。啟用後 IntersectsSphere / IntersectsCapsule / RaycastMesh 才可用。
| 參數 | 類型 | 說明 |
|---|---|---|
_enable | bool | 是否啟用碰撞體 |
調用示例:
bool ok = renderer.SetColliderEnable(true);
if (!ok) Debug.LogWarning("數據不含碰撞體");
說明:
- 數據必須包含碰撞(Mesh)數據,否則返回
false。 - 需要
Renderer處於激活狀態。
RaycastMesh(屏幕座標)
// 返回值:bool → true=命中
public bool RaycastMesh(Vector3 mousePos, out HitResult _finalResult, float _distance= 70.0f)
從屏幕座標發射射線檢測碰撞網格。使用 Collider 數據檢測,比 Raycast 更快但精度較低。
| 參數 | 類型 | 說明 |
|---|---|---|
mousePos | Vector3 | 屏幕座標 |
_finalResult | out HitResult | 命中結果 |
_distance | float | 最大檢測距離,默認 70.0 |
調用示例:
if (m_manager.RaycastMesh(Input.mousePosition, out HitResult hit))
{
Debug.Log(hit.hitPos);
}
說明:
- 需要先成功開啟碰撞。
- 需先調用
SetColliderEnable(true)。
RaycastMesh(Ray + Bounds)
// 返回值:bool → true=命中
public bool RaycastMesh(Ray ray, out HitResult result, out Bounds hitBounds, float maxDist = 70.0f)
使用自定義 Ray 進行碰撞網格檢測,同時返回命中節點的包圍盒信息。
| 參數 | 類型 | 說明 |
|---|---|---|
ray | Ray | 射線 |
result | out HitResult | 命中結果 |
hitBounds | out Bounds | 命中節點的包圍盒(命中的 LOD 節點包圍盒) |
maxDist | float | 最大檢測距離,默認 70.0 |
調用示例:
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (m_manager.RaycastMesh(ray, out HitResult hit, out Bounds bounds))
{
Debug.Log(bounds.center);
}
說明:
- 需要先成功開啟碰撞。
- 雙射線檢測(向下、向前)判斷數字人能否行走時常用此方法。
IntersectsSphere
// 返回值:bool → true=相交
public bool IntersectsSphere(Sphere sphere)
// 返回值:bool → true=相交
public bool IntersectsSphere(Sphere sphere, out Vector3 delta)
檢測球體與碰撞網格是否相交。第二個重載額外返回穿透向量 delta(推出方向與距離),可用於計算下一個可安全到達的點。
| 參數 | 類型 | 說明 |
|---|---|---|
sphere | Sphere | 待檢測的球體 |
delta | out Vector3 | 穿透向量(推出方向和距離) |
調用示例:
var sphere = new Sphere(transform.position, 0.5f);
if (m_manager.IntersectsSphere(sphere, out Vector3 delta))
{
transform.position += delta;
}
說明:
- 需要先成功開啟碰撞。
- 需先調用
SetColliderEnable(true)。 - 遍歷所有激活的
Renderer。
IntersectsCapsule
// 返回值:bool → true=相交
public bool IntersectsCapsule(Capsule capsule)
// 返回值:bool → true=相交
public bool IntersectsCapsule(Capsule capsule, out Vector3 delta)
檢測膠囊體與碰撞網格是否相交。常用於角色控制器碰撞檢測。第二個重載返回穿透向量 delta,可作為數字人下一個可安全到達的點偏移。
| 參數 | 類型 | 說明 |
|---|---|---|
capsule | Capsule | 待檢測的膠囊體 |
delta | out Vector3 | 穿透向量 |
調用示例:
var capsule = new Capsule(footPos, headPos, 0.3f);
if (m_manager.IntersectsCapsule(capsule, out Vector3 delta))
{
characterController.Move(delta);
}
說明:
- 需要數據包含碰撞節點。
- 需先調用
SetColliderEnable(true)。 - 適合第一人稱 / 第三人稱角色碰撞。
Raycast
// 返回值:bool → true=命中
public bool Raycast(Ray _ray, out HitResult _finalResult)
使用自定義 Ray 對高斯基元進行射線檢測,遍歷所有激活的 Renderer 返回最近命中。不依賴碰撞網格,精度較高但速度慢。
| 參數 | 類型 | 說明 |
|---|---|---|
_ray | Ray | 射線 |
_finalResult | out HitResult | 命中結果 |
調用示例:
Ray ray = new Ray(origin, direction);
if (m_manager.Raycast(ray, out HitResult hit))
{
Debug.Log(hit.hitPos);
}
說明:
- 不依賴碰撞網格,無需
SetColliderEnable。 - 精度較高但速度慢,不建議每幀調用,適合測量類應用,不適合數字人碰撞。
HitResult
上述檢測方法的命中結果通過 HitResult 結構體返回:
public struct HitResult {
public bool isHit; // 是否命中
public float distance; // 距離
public Vector3 hitPos; // 命中點世界座標(字段名為 hitPos,非 position)
public Vector3 normal; // 命中法線
public float hitAlpha; // 被擊中橢球的 Alpha
public float dist2Origin; // 到射線源的距離
public float scale; // 橢球 scale
}
注意:
命中點世界座標的字段名是
hitPos,不是position;請按實際字段名訪問。