[Unity備忘録]キャラクターの左右向き差分を別画像にしたい


左右差分 欲しい!

本記事は、以下のような願いを力で解決した際の備忘録です。

  • Unity製2Dゲームでプレイアブルなキャラクターを左右に動かす時、それぞれ別画像にしたい(左右反転ではなく、別画像で逆向きにする)
  • アニメーション等は用いず、シンプルに画像1枚ずつを左右に割り当てたい
  • 目的以上の難しいことはとりあえず考えたくない

免責事項

筆者は、ある程度プログラミングの基本知識がある状態でUnityでの開発に挑戦し始めたという状況です。ですので、本記事に記すのは目標の機能を実装する最善の方法ではなく、学習過程の記録であるということをご了承ください。
また、とりあえず目標の実装を完成させることを第一にしており、至る所にリファクタリングの余地がある可能性があります。
そのような改善点を見つけた場合、温かい目で見守っていただくか優しいコメントをいただければ幸いです。

環境・前提条件

  • Windows10
  • Unity 2020.3.4f1
  • 作るゲームの最終目標 2D落ちものゲーム
  • 本記事での目標 キャラクターが左に動くときは左向き、右に動くときは右向きの画像をそれぞれ割り当て、プレイヤーの左右入力によって切り替えられるようにする

準備

本記事では、画像をspriteとして読み込み、SpriteRendererコンポーネントで指定するspriteをスクリプト内から切り替えることによって左右の画像の切り替えを実装します。
キャラクターの移動はRigidbody2Dコンポーネントのvelocityで移動速度を指定することによって実現します。

(1)左右それぞれの画像を用意

今回は以下のようなイラストを使用します。

(*MacOSで表示したスクリーンショットですが、開発環境は全てWindowsです。)
イラストはあらかじめ左右反転した際に位置がずれないように調整しておきました。

(2)Unityプロジェクトフォルダに追加

UnityプロジェクトフォルダにResourcesフォルダを作成し、そのフォルダ内に画像のデータを両方とも追加します。
このフォルダに追加しておくことで、あとでスクリプトから画像を取得する際に検索が楽になります。

(3)ゲームオブジェクトを準備

左右どちらかの画像をSceanにドラッグすることで操作するキャラクターのゲームオブジェクトを作成します。
ゲームオブジェクトが作成できたら、将来的に落ちものゲームになることを見据えて、BoxCollider2DとRigidbody2Dをアタッチします。
キャラクターの動きはプレイヤーからの入力でのみ発生させたいので、Rigidbody2DのGravityScaleは0に設定しておきます。

(4)スクリプトを準備

今回キャラクターにアタッチするスクリプト内で実装するべき内容は、以下の通りです。

  • 左右の画像を取得する
  • ゲーム開始時の向きの画像をセットする(ゲームオブジェクト作成時に初期の向きの画像をドラッグして作成していれば不要)
  • →が入力されたら右向きの画像を表示し、キャラを右に動かす
  • ←が入力されたら左向きの画像を表示し、キャラを左に動かす

今回はキャラクターの移動は左右のみとなるため、フラグで向きを管理します。

以下のようなpublic変数を用意します。

  • string left right (左右それぞれの画像名)
  • float speed (キャラが動く時の速さ=1入力で動く距離)

また、向きや移動を管理するため、次のような変数を用意します。

  • float x (移動量)
  • bool RightFlag (Trueで初期化し、右向きを基準とする)
  • Sprite player_r, player_l (画像をそれぞれspriteとしてもつ)
  • SpriteRenderer player_SR (左右でspriteを切り替える実装のため)
  • Rigidbody2D rbody (移動速度を指定するため)

実際の処理は以下のように実装しました。

CharacterControler.cs
public string right, left; // Inspectorウィンドウから設定
public float speed;  // Inspectorウィンドウから設定
float x = 0; // 移動量指定用
bool RightFlag = True; // 向き管理用
Sprite player_r, player_l;
SpriteRenderer playre_SR;
Rigidbody2D rbody;

void start()
{
  // 左右の画像をそれぞれspriteとして取得する
  player_r = Resources.Load<Sprite>(right);
  player_l = Resources.Load<Sprite>(left);
  // Rigidbody2D初期化
  rbody = this.GetComponent<Rigidbody2D>();
}

void Update()
{
  x = 0; // 入力がない時は移動量0
  if(Input.GetKey("right")){ // 右に移動する時
    RightFlag = true; // 右向きフラグをオンに設定
    x = speed; // 移動量を設定
  }
  if(Input.GetKey("left")){ // 左に移動する時
    RightFlag = false; // 右向きフラグをオフに設定
    x = -speed; // 移動量を設定(反対向きなので-で反転させている)
  }
}

void FixedUpdate()
{
  // RightFlagのT/Fで向きを判断
  if(RightFlag){ // 右に移動する時
    player_SR.sprite = player_r; // 右向きの画像のspriteを指定
  }else{ // 左に移動する時
    player_SR.sprite = player_l; // 左向きの画像のspriteを指定
  }
  rbody.velocity = new Vecter2(x, 0); // 移動量を指定
}

プレイヤーからのキー入力はUpdateメソッドで常に受け付けるようにし、実際にゲーム内のキャラクターを動かす処理にはフレームレートを固定するためにFixedUpdateメソッドを用います。

(5)スクリプトをゲームオブジェクトにアタッチ

(3)で用意したゲームオブジェクトに(4)で用意したスクリプトをアタッチします。
スクリプトアタッチ後はInspectorウィンドウから左右の画像名(right,left)と移動速度(speed)の値を忘れずに設定します。
実行し左右キーを入力すると、左右それぞれの画像に切り替わりながらキャラクターが移動します。

参考資料

  • 楽しく学ぶUnity2D超入門講座 森巧尚(マイナビ出版)

(Unityプロジェクト作成からキャラクターの操作等の基本的な内容を網羅しているお気に入りのテキストです。)

(おまけ)キャラクターの詳細が知りたい方へ

むぎむしゃをよろしくお願いします。