機能
組み込み機能
これらの機能はKCC内部実装の一部です。デフォルトの状態は KCCSettings.Features で定義され、KCCインスペクタでも設定可能です。
連続衝突検出 (CCD)
- 希望する速度に応じて動作を小さいステップに分割。
- 1ステップで移動できる最大距離は半径の25~75%で、
KCCSettings.CCDRadiusMultiplierプロパティで制御。 - 多くのケースで75%が妥当。KCCがジオメトリを通過する際に問題がある場合のみ、この値を下げてください。
CCDRadiusMultiplierを下げる前に、KCCSettings.MaxPenetrationStepsを増やしてみてください(ディペネーションの質が向上します)。
予測補正
- 予測位置誤差のスムーズな補正を可能にします。
- 予測エラーは、動きがクライアントとサーバー上で異なってシミュレートされるときに発生します。浮動小数点エラーの蓄積、物理エンジンの状態の違い、ゲームの状態による入力処理の違いなど、エラーの原因はさまざまです。
- もう1つのエラーの原因は、レンダリング更新予測と固定更新予測の結果が異なることです。
- この機能はビジュアル/レンダリングにのみ影響し、固定アップデートのデータはサーバーから受信した新しい状態にスナップします。
- この機能の強制/抑制は、次のレンダー更新の開始時に有効になります。
- 予測補正の速度は
KCCSettings.PredictionCorrectionSpeedで制御します。
次の図は、固定更新(赤)、レンダリング更新(緑)、予測補正(黄)の動作を示しています:
アンチジッター
- ジッターを滑らかにするためにレンダリング位置の距離の許容範囲を有効にします。
- 距離は
KCCSettings.AntiJitterDistanceで定義されます (横軸は X、縦軸は Y)。 - 値を大きくすると、移動方向を切り替えたときに顕著な遅延が発生し、キャラクタのビジュアルが地面と一致しなくなることがあります(ジャンプ後など)。
次の画像は、KCCとトランスフォームの位置をXZ平面上の点で表したトップダウンビューです。
- 緑色の点は
KCCData.TargetPositionに格納されている位置を表しています。これらはTransformコンポーネントと同期しています。 - 青い点は
KCCData.TargetPositionにのみ格納されている位置を表します。これらは以前の位置のアンチ・ジッター・エリア(灰色の円)内にあるため、Transformコンポーネントには同期されません。 KCCData.TargetPositionが現在のアンチジッターエリア(赤い矢印)の外側に移動すると、そのエリアはポイントに追従するので、距離内に留まり、新しい位置がTransformに同期されます。
フィーチャープロセッサ
これらの機能は個別に実装されているため、別の実装に置き換えたり、取り除いたりするのが非常に簡単です。
環境プロセッサ
- KCCアドオンに同梱されているデフォルトのプロセッサです。
- 接地状態と浮遊状態の動作を定義します。
- 地面の接線に沿った投影された動き。
- シンプルな加速度と摩擦モデル。
- カスタム重力。
- ジャンプ倍率。
IPrepareDataステージを実装。このステージでは6つのカスタム・ステージを実行し、目的の速度を細かく制御します(そのうちのいくつかはEnvironment Processor自体にも実装されています):ISetGravity-KCCData.Gravityを計算する専用ステージ。ISetDynamicVelocity-KCCData.DynamicVelocityを計算する専用ステージ。ISetKinematicDirection-KCCData.KinematicDirectionを計算する専用ステージ。ISetKinematicTangent-KCCData.KinematicTangentを計算する専用ステージ。
ISetKinematicSpeed-KCCData.KinematicSpeedを計算する専用ステージ。ISetKinematicVelocity-KCCData.KinematicVelocityを計算する専用ステージ。
IAfterMoveStepステージの実装 - 各移動ステップの後にプロパティを再計算するために使用されます(例えば、地面への運動速度の投影)。EnvironmentProcessorプレハブはAssetsPhotonPhusionAddonsKCCPrefabsにあります。
キャラクターの速度はこのプロセッサによって定義され、水、泥、氷のような様々な環境での挙動をシミュレートするためにシーンオブジェクトに使用することができます。
ステップアッププロセッサ
- 段差(水平方向の動きをブロックするジオメトリで、ある高さで歩行可能なサーフェス)を検出できるようにします。
- 段差が検出されると、KCC は接地するまで上方に移動します。
- 最大段差の高さは
Step Heightで定義します。 - 前方へのステップ確認距離は
Step Depthで制御します。 - 上方への移動は未適用の水平移動と等しくなります。
StepUpProcessorプレハブはAssetsPhotonFusionAddonsKCCPrefabsにあります。- 上方への移動の速度は水平方向の速度の損失を補正するために
Step Speedを乗算します。
次の画像は、段差を検出する処理です:
- 水平方向の障害物に阻まれた場合の上方確認。
- キャラクタの前方の空間が衝突しないかどうかを検出する前方チェック。
- 地面が歩けるかどうかの地面スナップチェック。
- 3つのチェックがすべてパスしている限り、キャラクターは上に移動。
グランドスナッププロセッサ
- 地面との接触が失われたとき(階段、不整地)、接地状態を維持できるようにする。
- 重力が十分でない場合、キャラクターを地面に近づける。
- 最大スナップ距離は
Snap Distanceで定義される。 - 地面への移動速度は
Snap Speedで指定する。 GroundSnapProcessorプレハブはAssetsPhotonFusionAddonsKCCPrefabsにある。
以下の画像は、グランドスナップの処理を示しています
以下のいずれかの条件が満たされるまで、キャラクターは仮想的に下に押し下げられます。
- キャラクターが歩行可能な地面にぶつかる => KCCは地面に接地したまま、地面に向かって移動している。
- キャラクターが歩けない地面にぶつかり、その上を滑ることができない => KCCは接地状態を失っている。
スナップ距離に達した場合 => KCCは接地状態を失っている。
プラットフォームプロセッサ
- プラットフォームオブジェクトを追跡し、位置や回転の変化を KCC に伝えます。
- ワールド空間とプラットフォーム空間の間を補間することで、KCC プロキシを追跡されたプラッ トフォームにスナップします。
- 各 KCC は一意の
PlatformProcessorインスタンスを持っている必要があります(たとえば、プレイヤープレファブの子オブジェクト)。 - ワールド空間からプラットフォーム空間への遷移時間は
PlatformSpaceTransitionDurationで定義されます。 - プラットフォーム空間からワールド空間への遷移時間は
WorldSpaceTransitionDurationで定義されます。 PlatformProcessorプレハブはAssetsPhotonAppdonsKCCPrefabsにあります。
典型的なセットアップに必要なステップは以下の通りです。
PlatformProcessorプレハブを子オブジェクトとしてPlayer/KCCプレハブの下にドラッグ&ドロップします。- KCC 設定の
Processorsプロパティにプロセッサインスタンスをリンクします。 - これで KCC はすべてのプラットフォームからの動きをトラッキングし、伝搬できるようになります。
プラットフォームを正しくトラッキングするには、いくつかの要件と制限があります:
プラットフォームを正しくトラッキングするには、いくつかの要件と制限があります。
- プラットフォームオブジェクトは
NetworkObjectとRigidbody(kinematic) コンポーネントを持っていること。 - プラットフォームスクリプトは
IPlatformインターフェイスを実装していること。 - プラットフォームスクリプトは KCC プロセッサであること。
- ホストモードでは、プラットフォームの移動がすべて(サーバーとクライアント)で予測されること。
- プラットフォームスクリプトの実行順序は
PlatformProcessorよりも下であること。
以下のコードはプラットフォームスクリプトの例です。
C#
[DefaultExecutionOrder(-1000)]
[RequireComponent(typeof(Rigidbody))]
public sealed class PlatformMovement : NetworkTRSPProcessor, IPlatform, IBeforeAllTicks
{
public Transform Transform;
public Rigidbody Rigidbody;
public override void Spawned()
{
// Enable simulation also for proxy object.
Runner.SetIsSimulated(Object, true);
}
public override void FixedUpdateNetwork()
{
CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation);
// Set network state of NetworkTRSP.
State.Position = nextPosition;
State.Rotation = nextRotation;
// Update engine components.
Transform.position = nextPosition;
Transform.rotation = nextRotation;
Rigidbody.position = nextPosition;
}
public override void Render()
{
CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation);
// Update only engine components, do not store in network state.
Transform.position = nextPosition;
Transform.rotation = nextRotation;
Rigidbody.position = nextPosition;
}
void IBeforeAllTicks.BeforeAllTicks(bool resimulation, int tickCount)
{
// Restore state of the object before simulation.
Transform.SetPositionAndRotation(State.Position, State.Rotation);
Rigidbody.position = State.Position;
}
private void CalculateNextState(out Vector3 nextPosition, out Quaternion nextRotation)
{
nextPosition = State.Position;
nextRotation = State.Rotation;
// Movement based on waypoints, AnimationClip, ...
}
}
スムーズでエラーのない動きの伝搬を得るためには、実行順序(IPlatform => PlatformProcessor => Player => KCC)を守ることが重要です。
- すべての
IPlatformスクリプトの更新 - 新しい位置/回転値を計算し、TransformとRigidbodyコンポーネントを更新します。 - すべての
PlatformProcessorスクリプトの更新 - トラッキングされたすべてのIPlatformオブジェクトの処理、KCC のTransformとKCCDataへの最終更新からのTransformの変更の伝搬。このステップの後、すべてのプラットフォームが処理され、文字が移動します。 - すべての
Playerスクリプトの更新 -KCCの移動のための入力値の設定。 - すべての
KCCスクリプトの更新 - 予測された移動と補間。
上記のプロセスにより、どのKCCもプラットフォームや他のKCCの最新の状態に確実に移動し、衝突します。
⚠️ プラットフォームの例はSample Projectにあります。
Back to top