Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

キネマティックキャラクター(2D)

はじめに

はい、奇妙な名前に聞こえますね。「キネマティック・キャラクター」それは、何ですか?名前の理由は、物理エンジンが出てきたときに、それらが(主に衝突応答を扱ったため)「ダイナミクス」エンジンと呼ばれたからです。ダイナミクスエンジンを使ってキャラクターコントローラーを作ろうとする試みは数多く行われましたが、思ったほど簡単ではありませんでした。Godotには、(2d/platformerのデモで見ることができるように)色々と発見できるダイナミックキャラクターコントローラーの最高の実装の1つがありますが、それを使用するには、かなりのレベルのスキルと物理エンジンの理解(または試行錯誤の忍耐)が必要です。

Havokなどの一部の物理エンジンは、最適なオプションとしてダイナミックキャラクターコントローラーに誓いをたてているように見えますが、他の物理エンジン(PhysX)は、むしろキネマティックコントローラーを促進します。

だから、違いは何ですか?:

  • ダイナミックキャラクターコントローラーは、無限慣性テンソルを持つリジットボディを使用します。 回転できないリジットボディです。 物理エンジンは常にオブジェクトの移動と衝突を許可し、その後、すべて一緒に衝突を解決します。これにより、ダイナミックキャラクターコントローラーは、プラットフォーマーデモで見られるように、他の物理オブジェクトとシームレスに対話できます。 ただし、これらの相互作用は常に予測できるとは限りません。 衝突は解決するために複数のフレームを必要とする可能性があるため、いくつかの衝突はわずかにずれているように見える場合があります。 これらの問題は修正できますが、ある程度のスキルが必要です。

  • キネマティックキャラクターコントローラーは、常に非衝突状態で始まり、常に非衝突状態に移行すると想定されています。 衝突状態で開始した場合、リジットボディのように自身を解放しようとしますが、これは例外であり、ルールではありません。 これにより、制御と動作がより予測可能になり、プログラムが簡単になります。 ただし、欠点としては、コードで手動で行わない限り、他の物理オブジェクトと直接やり取りすることはできません。

この短いチュートリアルでは、キネマティックキャラクターコントローラーに焦点を当てます。 基本的に、衝突を処理する昔ながらの方法です。内部では必ずしも単純ではありませんが、よく隠されており、素晴らしくシンプルなAPIとして提示されています。

Physics process

To manage the logic of a kinematic body or character, it is always advised to use physics process, because it's called before physics step and its execution is in sync with physics server, also it is called the same amount of times per second, always. This makes physics and motion calculation work in a more predictable way than using regular process, which might have spikes or lose precision if the frame rate is too high or too low.

extends CharacterBody2D

func _physics_process(delta):
    pass

シーンの設定

テスト用に、ここにシーンがあります(タイルマップチュートリアルから): kinematic_character_2d_starter.zip。 キャラクターの新しいシーンを作成します。 ロボットスプライトを使用して、次のようなシーンを作成します:

../../_images/kbscene.webp

CollisionShape2Dノードの横に警告アイコンがあります。 それは、形状を定義していないためです。 CollisionShape2Dのshapeプロパティで新しいCircleShape2Dを作成します。 <CircleShape2D>をクリックしてオプションに移動し、半径を30に設定します:

../../_images/kbradius.webp

注: 物理のチュートリアルで前述したように、物理エンジンはほとんどの種類の形状のスケールを処理できないため(コリジョンポリゴン、プレーン、セグメントのみが機能します)、シェイプのパラメーター(半径など)を拡大縮小するのではなく、常に値を変更してください。スケールが形状のスケールに影響するため、同じことがキネマティック/リジッド/スタティックボディ自体にも当てはまります。

ここで、キャラクターのスクリプトを作成します。上記の例として使用したスクリプトがベースとして機能するはずです。

最後に、タイルマップでそのキャラクターシーンをインスタンス化し、マップシーンをメインのシーンにします。再生を押すと実行されます。

../../_images/kbinstance.webp

キネマティック キャラクタの移動

キャラクターシーンに戻り、スクリプトを開くと、魔法が始まります! キネマティックボディはデフォルトでは何もしませんが、CharacterBody2D.move_and_collide() という便利な関数があります。 この関数は、Vector2 を引数として取り、その運動を キネマティックボディに適用しようとします。 衝突が発生した場合、衝突の瞬間に停止します。

それでは、スプライトが床に当たるまで下に移動しましょう:

extends CharacterBody2D

func _physics_process(delta):
    move_and_collide(Vector2(0, 1)) # Move down 1 pixel per physics frame

その結果、キャラクターは移動しますが、床に当たるとすぐに停止します。 かなりクールですね?

次のステップでは、ミックスに重力を追加します。これにより、通常のゲームキャラクターのように動作します:

extends CharacterBody2D

const GRAVITY = 200.0

func _physics_process(delta):
    velocity.y += delta * GRAVITY

    var motion = velocity * delta
    move_and_collide(motion)

これでキャラクターがスムーズに落ちます。 方向キーをタッチして、左右に歩いてみましょう。(少なくとも速度の場合)使用されている値はピクセル/秒であることに注意してください。

これにより、左右キーを押すことで基本的な歩行サポートが追加されます:

extends CharacterBody2D

const GRAVITY = 200.0
const WALK_SPEED = 200

func _physics_process(delta):
    velocity.y += delta * GRAVITY

    if Input.is_action_pressed("ui_left"):
        velocity.x = -WALK_SPEED
    elif Input.is_action_pressed("ui_right"):
        velocity.x =  WALK_SPEED
    else:
        velocity.x = 0

    # "move_and_slide" already takes delta time into account.
    move_and_slide()

そして、それを試してみてください。

これはプラットフォーマーにとって良い出発点です。 より完全なデモは、エンジンとともに配布されるデモzip、または https://github.com/godotengine/godot-demo-projects/tree/master/2d/kinematic_character にあります。