目次
その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つ作られました。
- キー入力
Input
に従ってVelocity
を更新するシステム - AIによって決められた
MoveTarget
に従ってVelocity
を更新するシステム - アニメーションに従って
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),
);
この様に、最後にアニメーションによる更新を呼ぶようにします。
次回は、これまで作ったコンポーネントやシステムを、一度振り返って、オブジェクト指向による設計とどう違うか、見てみたいと思います。