お世話になっております。
MovementModeがFallingの際のTwoWallAdjustの挙動について質問があります。
UCharacterMovementComponentのPhysFallingにおいて、1フレーム内の移動で壁に接触しスライド処理が行われ、そのスライド先にさらに別の壁が存在する場合、移動先はTwoWallAdjustによって決定されます。
TwoWallAdjustでは、2つの壁が成す角度が鋭角か鈍角かによって処理が分岐しており
- 鋭角の場合:2つの壁の法線の外積方向へ元の移動ベクトルを射影した移動
- 鈍角の場合:ComputeSlideVectorによる移動計算
という挙動になります。
ここで、後者の「鈍角」のケースでは、UCharacterMovementComponentによるComputeSlideVectorのオーバーライド実装により、MovementModeがFallingの場合はHandleSlopeBoostingが呼び出され、元の上昇速度を超えないように制御されます。
しかし、前者の「鋭角」のケースでは、このHandleSlopeBoosting相当の処理が行われていません。
その結果、MovementModeがFallingの状態で、鋭角かつ傾斜のある隅に継続して衝突し続けると、キャラクターが上方向に押し上げられる挙動が発生します。
特に、加速度が大きい場合や、SetVelocityで毎フレーム水平方向の速度を与えている場合に顕著に上方向へ加速します(加速度が小さい場合は発生しません)。
一方で、鈍角の隅に衝突し続ける場合は、このような問題は発生しません。
以上を踏まえ、以下の点について確認させてください。
- この挙動は意図された仕様でしょうか
- それとも、鋭角ケースにHandleSlopeBoosting相当の処理が入っていないのは実装漏れでしょうか
ご確認のほど、よろしくお願いいたします。
[Attachment Removed]
お世話になっております。
お問い合わせありがとうございます。
本件について社内の開発チームとも協議しましたが、意図的なものとは考えられず、不具合(実装漏れ)と思われます。
社内のバグトラッカーに起票し、Public Issue化を申請しました。承認後、下記URLより対応状況を追跡いただける予定です。
https://issues.unrealengine.com/issue/UE\-373688
暫定的な回避策をご提供できればと思うのですが、
鈍角・鋭角のケース分けが上位クラス側に閉じて書かれた判定であるのに対して、HandleSlopeBoosting()は下位のUCharacterMovementComponentクラスの独自実装であり、これが別関数のオーバーライドを経由して呼び出されるという構図となっていることから、一旦、UCharacterMovementComponent::TwoWallAdjust() で IsFalling() 状態を拾って回避コードを適用するのがリスクの少ないアプローチではないかと考えております。
void UCharacterMovementComponent::TwoWallAdjust(FVector& WorldSpaceDelta, const FHitResult& Hit, const FVector& OldHitNormal) const
{
const FVector InDelta = WorldSpaceDelta;
Super::TwoWallAdjust(WorldSpaceDelta, Hit, OldHitNormal);
if (IsMovingOnGround())
{
// 省略
}
+ else if (IsFalling())
+ {
+ // 「鈍角」ケースではHandleSlopeBoosting()が二回適用されるが、
+ // 一度目の適用範囲にとどまるため、影響はない
+ WorldSpaceDelta = HandleSlopeBoosting(WorldSpaceDelta, InDelta, 1.f - Hit.Time, Hit.Normal, Hit);
+ }
}
取り急ぎご返信申し上げます。
以上、よろしくお願いいたします。
[Attachment Removed]
ご回答ありがとうございます。
不具合(実装漏れ)とのこと、承知いたしました。
不具合が修正されるまでは、ご提示頂いた暫定回避策を参考に、対応を進めていきます。
[Attachment Removed]
ご確認ありがとうございます。
あらかじめ詳細に実装を解析いただいており、おかげさまでスムーズに社内確認を進めることができました。
大変恐縮ですが、上述のパッチも含め、修正までの間何らかの方法で問題を回避していただければと思います。
それではチケット管理の都合上、一旦本件はCloseさせていただこうと思います。
なにか不具合が生じましたら、コメントをご追記いただくか、改めてEPSにご投稿をいただければと存じます。
以上、よろしくお願いいたします。
[Attachment Removed]