LoginSignup
2
0

More than 3 years have passed since last update.

Rust + Entity Component System で仕様変更に強いゲーム設計 その5-2~ やられアニメーション

Last updated at Posted at 2020-03-04

目次

その1 〜 序文
その2 〜 キャラの移動
その3−1 〜 コンポーネントの設計
その3−2 〜 システムの設計
その3−3 〜 メイン部分
その4−1 〜 剣を表示
その4−2 〜 アニメーションコンポーネント
その4-3 〜 アニメーションを動かす
その5-1~ あたり判定
【イマココ】その5-2~ やられアニメーション
その6 〜 これまでの振り返り

やられアニメーション

それでは、攻撃を受けたときに再生される、やられアニメーションを実装しています。
今回のやられアニメーションは、一定距離、後ろに下がる、というものです。

やられアニメーションの特殊な点は、「アニメーションに伴う移動」を実装する必要がある、ということです。
なぜなら、アニメーションデータ自体はデザイナーが作成するものですが、それをそのまま再生するだけでは、ゲームロジック内で管理されているキャラの位置情報が変化しないからです。
アニメーションに仕込まれた「移動量」にしたがって、ゲームロジック上の位置も変化させなければなりません。

そのために、CharacterAnimFrameに、move_forwardというフィールドを追加しました。
そのフレームでの移動量(前方がプラス方向)を表します。

#[derive(Default, Clone)]
pub(crate) struct CharacterAnimFrame {
    pub radius_scale: f32,
    pub weapon_direction: f32,
    pub move_forward: f32,  //追加
}

システム側では、アニメーション中にこの値があったら、キャラのVelocityを上書きします。

impl SystemProcess
    for System<CContainer<Velocity>, (&CContainer<CharacterView>, &CContainer<CharacterAnimator>)>
{
    fn process(velocities: &mut Self::Update, (views, animators): &Self::Refer) {
        velocities
            .iter_mut()
            .zip_entity2(views, animators)
            .for_each(|(_, velocity, view, animator)| {
                if let Some(val) = animator.value() {
                    if val.move_forward != 0f32 {
                        velocity.x = view.direction.cos() * val.move_forward;
                        velocity.y = view.direction.sin() * val.move_forward;
                    }
                }
            });
    }
}

さて、これまでで、Velocityを更新するシステムは、3つ作られました。

  1. キー入力Inputに従ってVelocityを更新するシステム
  2. AIによって決められたMoveTargetに従ってVelocityを更新するシステム
  3. アニメーションに従ってVelocityを更新するシステム

1はプレイヤーキャラ用、2は敵用、3はプレイヤー、敵どちらも使います。
アニメーションによる移動は、キー入力や敵AIによる移動より、優先されなければなりません。
(やられ中は操作できない、という仕様にしたいので)
よって、これらを呼ぶ順番は

        System::process(&mut self.velocities, &self.inputs);
        System::process(&mut self.velocities, &(&self.positions, &self.move_targets));
        System::process(
            &mut self.velocities,
            &(&self.character_views, &self.character_animators),
        );

この様に、最後にアニメーションによる更新を呼ぶようにします。

次回は、これまで作ったコンポーネントやシステムを、一度振り返って、オブジェクト指向による設計とどう違うか、見てみたいと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0