これはドリコム Advent Calendar 2016 12日目です。
クライアントエンジニアの道家です。
コンシューマーゲームの開発経験を経て、iOS/Android向けのゲーム開発をしています。
今日はゲームで出てくるアニメーション/モーションを扱う上で、知っておくと幸せになれるようなお話をさせて頂こうと思います。
まずはじめに
主に海外では「アニメーション」という言葉は2Dの動きの事を指し、「モーション」というと3Dや演者の動作の事をさす事が多いのですが、人によっては結構意味合いが違う事がよくあります。
本記事ではゲームで扱うアニメーション/モーションの総称としてゲームモーションという言葉を使わせて頂きます。
本題
さて本題です。
ゲームでは下記のような用途でゲームモーションを作ります。
- キャラクターの動き
- UIの動き
- 背景/配置物の動き
- エフェクトの動き
そしてこれらを使ってゲームを開発していくとある需要が生まれます。
動きの特定のタイミングで何かをしたい
たとえば、特定のタイミングのみキャラクターは無敵になる たとえば、キャラクターが足を地面につける瞬間音を出したい たとえば、ボタンを押して光った瞬間に文字を出したい |
この需要はゲームでは多いので今回はその実装を行う際の考え方/データの作り方のお話をします。
用途に分けて定義
基本的にゲームモーションは、タイムラインで動きが制御されており、
「1秒間で何をどれくらい動かす」という情報でできています。
その為、プログラムコードとしては「時間を指定/取得して動作を作ればよい」となるので、その通りそのまま実装を行うのが手っ取り早いです。
ですが、「何をしたいのか」で扱う情報が代わることが多く、全てが特有の情報になってしまい管理や作業ミスの元になりやすい為、情報の整理が必要になってきます。
自分が良く使ってる整理方法が以下のようなものになります。
■タイミング
-
一回だけのタイミングが欲しいのか?
→その瞬間だけ音を鳴らす等 -
継続してのタイミング欲しいのか?
→特定の「期間」エフェクトを表示したい等
■影響度
-
自己のデータにだけ影響を及ぼすのか
→動いているキャラクターがゲーム上無敵状態になる等 -
他のデータに影響を及ぼすのか
→エフェクトを生成する、音を生成、物体を動かす
■分岐
-
状況によって行う事が違う
→キャラクターが地面に足を付くときに足音を鳴らしたいが、
地面がコンクリートならコンクリートの音、土なら土の音を鳴らす必要がある等
これらを意識しておく事で、整理がつけやすくなると思います。
これらを踏まえた上で内容に沿った外部データのテーブルを用意する事で、データ入力の分業化等が行え、エンジニアが専属担当者がなきながら情報を設定する・・・という事を軽減できると思います。
判定処理は企画職、エフェクト/サウンドはデザイナー職、プログラム都合はエンジニア職、など分担して設定すると楽です。
■1キャラクターのゲームモーションに紐づいたデータ例
Data | sec | event | id | durationTime | comment |
---|---|---|---|---|---|
walk | 0.2 | se | se_005 | 0 | 右足の音 |
walk | 0.4 | se | se_006 | 0 | 左足の音 |
jump | 0.1 | se | se_010 | 0 | 地面をける音 |
jump | 0.1 | footstep | big | 0 | 土ぼこり。地面を蹴る強さと、 地面の種類でエフェクトを変更 |
atk_normal | 0.6 | hit | atk_hit | 0 | 攻撃HIT処理 |
atk_normal | 0.3 | effect | ef_ch_008 | 0.4 | ビームエフェクト、0.4秒間出続ける |
atk_normal | 0.4 | state | invincible | 0.4 | 0.4秒間無敵 |
※data = ゲームモーションの名前
※sec=ゲームモーションの再生時間
※event=secの秒数の時に何を行うか
※durationTime=どのらくらいの期間状態を維持するか
よくある困った現象:処理順序
少しゲームコアな処理の話になりますが、ゲームモーションから発生した情報は処理の順序が問題になりがちです。
ゲームモーションの時間が来た瞬間に該当の処理を作っている場合は、1フレームの処理内の処理順序が 「ゲームモーションの情報更新 → キャラクターの情報更新」という流れの場合、
1.キャラクター が無敵になる
↓
2.無敵になったキャラクターはダメージを受けない
このようなケースでは問題ないのですが、同様の順序で次のことを行った時に少し問題が発生します。
1.キャラクターの位置にエフェクトを発生
↓
2.キャラクターが動く
という事が発生してまい「キャラクターにかっこいいエフェクト被せたのにズレてる!」という意図しない問題が発生する事があります。
このような場合は処理の順序を変えてやるか、ゲームモーションからの情報に関しては、受け口と処理のタイミングを別に設けると解決する場合は多いです。
(キャラクターが複数居た場合も「どのキャラクターの処理を優先するのか?」という場合にも対応できるのでお勧めです。)
最後に
なんだか例題がキャラクターのデータに絞った話になってしまいましたが、ゲームモーションを扱う上での考え方のお話でした。
実際にはゲームに則した形で実装する事になるので例題はあくまで例なのですが、「特定のタイミングで何かをしたい」というのはゲームモーションを扱っている場合は必ず出る需要なので、見越した上で実装・プログラムコードの作成を行うと幸せにコーディングが行えると思います。