Skip to content

向きとアクションの自動制御

キャラクターを動かすとき、移動のたびに「進む方向に体を向ける」 「歩き/走りのアニメーションに切り替える」処理を自分で書くのは 面倒です。a3jsには、これを自動化する2つの機能があります。

  • 自動向き調整setAutoDirection(true))— 移動方向が正面に なるように回転を自動でコントロールします。
  • 自動アクション切り替えsetAutoAction(true))— 現在の スピードに応じて、止まる・歩く・走るのアクションが自動で 切り替わります。

この機能が使える条件

どちらの機能もオブジェクトの速度getLinearVelocity())を 元に動作するため、速度の情報が得られるモードでしか機能しません。

setAutoDirection()が使える条件は以下の通りです。

  • モードがSimplePhysicsDynamicCharacterSmoothSmoothBillboardFollowのいずれかであること。 KinematicCharacterモードは物理系ですが速度の情報が得られない ため使えません。Defaultなどその他のモードでも機能しません。

setAutoAction()が使える条件は以下の通りです。

  • setAutoDirection()の条件に加えて、ActionObject (GLTF・Acerola3D)のインスタンスであること。
  • ActionObjectが持つhaltActionNamewalkActionNamerunActionNameminWalkSpeedminRunSpeedプロパティが 正しく設定されていること。一部のAcerola3Dフォーマットの 3Dモデルはこれらの情報をメタデータで持っているので、 自動で設定されます。

ObjectA3.setAutoDirection()

移動方向(速度ベクトルの向き)が正面になるように、オブジェクトの 回転を毎フレーム自動調整します。上方向はupVector (デフォルトはY軸)を基準にするので、地面の上を動き回る キャラクターが自然に進行方向を向くようになります。

ActionObject.setAutoAction()

現在のスピードに応じてsetState()を自動で呼び出します。 切り替えのしきい値とアクション名はプロパティで変更できます。

  • スピードがminWalkSpeed(デフォルト0.1m/s)未満 → haltActionName(デフォルト'default'
  • スピードがminRunSpeed(デフォルト1.0m/s)未満 → walkActionName(デフォルト'walk'
  • それ以上 → runActionName(デフォルト'run'
js
player.minRunSpeed = 2.0;        // 走りに切り替わる速さを変更
player.walkActionName = 'Walking'; // モデルのアクション名に合わせる

サンプル

3秒ごとに停止(0m/s)→歩き(0.5m/s)→走り(4m/s)と速さを 変えながら円を描くように動くサンプルです。速さに応じて アニメーションが切り替わり、常に進行方向を向くことを確認して ください。

js
import * as a3 from 'a3js';

await a3.initPhysics();
const view = new a3.Window(600,300);
view.camera.setPosition(0,2,5);
view.camera.lookAt(0,0,0);

const ground = new a3.Box(30,1,30,"red");
ground.setPosition(0,-0.5,0);
ground.setMode('SimplePhysics',{rigidBody:'fixed'});
view.scene.add(ground);

const player = await new a3.Acerola3D('/a3js/assets/vesma9.a3').ready;
player.setMode('DynamicCharacter');
view.scene.add(player);
player.setAutoAction(true);    // 速度に応じてアクションを自動切り替え
player.setAutoDirection(true); // 進行方向を自動で向く

// 3秒ごとに 停止(0m/s)→歩き(0.5m/s)→走り(4m/s) と
// 速さを変えながら円を描くように速度を与える
let t = 0;
while (true) {
  t += await view.waitForRender();
  const speed = [0, 0.5, 4][Math.floor(t/3)%3];
  player.setLinearVelocity(speed*Math.cos(10*t/(2*Math.PI)),0,
                           speed*Math.sin(10*t/(2*Math.PI)));
}

実戦的な使用例はTPSのサンプルプログラムを 参照してください。プレイヤーにsetAutoAction()、敵ロボットに setAutoDirection()を使っています。

詳細はAPIドキュメントを 参照してください。