こんにちは、今日はユニティの話です。
現在「楽しい2Dゲームの作り方ーUnityで始めるゲーム開発入門ー」という本と、ネットで調べつつ2Dのゲームを勉強しています。
素材は、ユニティちゃんのHP(https://unity-chan.com/)から借りています。

この作品はユニティちゃんライセンス条項の元に提供されています
© Unity Technologies Japan/UCL
今回は、タイトルの通り「ジャンプモーション」で起こった問題の解決法についてお知らせしたいと思います。
なお、今回はユニティーのアニメーションクリップの機能は使用していません(まだ、勉強したてなので、そこまで手が回ってないです…)。
今回の目的
今回は、キャラクターの
待機時 
歩行時 
ジャンプ上昇中 
ジャンプ落下中 
のモーションを、動作に合わせてモーションをつけていこうとしています。
問題点
問題になったのは、ジャンプの上昇中のモーションが適用されないということ。
スペースを押すとジャンプし、ジャンプの上昇中のモーションを適用しようとしていましたが、モーションがなぜか適用されませんでした。
スペースを押すとジャンプはするのですが、画像が待機中モーションのまま上に飛ぶ、という状態です。
何度かDebug.Logで、ジャンプ中のモーションに使用している変数(jumpUp)に何が入っているのか確かめたところ、まったくコード内にない文字列「jump_up」が入っていました。
はじめは、アニメーションクリップの中の各アニメーションの名前やゲームオブジェクトの名前が適用されているのではないかと疑いましたが、そこにも「jump_up」という文字列は見当たりませんでした。

原因は、この画像(👆)の右下にありました。
具体的に言うと、インスペクターの下側。
プレイヤーにアタッチしたC#の設定部分にありました。

コード内で宣言した変数を、ユニティの編集画面で更新できる機能があるのですが、変数のjumpUpの値が、おそらく、コードを描き始めたときに最初に代入したjump_upという文字列が入ったままになっていました。
もしかすると、インスペクター内の変数の値は、コードエディター(VSCなど)で書き直しても、自動的に更新はされないのでは?
試しに、speedの値をコードエディタで変えてみましたが、インスペクターでのspeedの値は「3」のままでした。
もしかしたら、私の環境のせいかもしれませんが。
もし、同じような問題が起きている場合は、ユニティーの編集画面のインスペクターを確認してみるのもいいかもしれません。
私自身の備忘録のためにもここに記しておきます。
ここまでお読みくださりありがとうございました!
今回のコード
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerContrroller : MonoBehaviour
{
Rigidbody2D rbody;
float axisH = 0.0f;
public float speed = 3.0f;
public float scale = 5.0f;
public float jump = 9.0f; //ジャンプ力
public LayerMask groundLayer; //着地できるレイヤー
bool goJump = false; //ジャンプ開始フラグ
bool onGround = false; //地面に立っているフラグ
bool fallBody = false; //落下判定の変数
bool riseBody = false; //上昇判定
// bool jLanding = false; //ジャンプ着地フラグの一つ
//アニメーション対応
Animator animator;//アニメーター
public string stopAnime = "idol"; //待機状態
public string moveAnime = "run01";
public string jumpAnime = "jump_sequence";
public string jumpUp = "jump";
public string jumpFall = "jump_fall";
public string jumpMir = "jump_midAir";
public string jumpLanding = "landing";
public string fallAnime = "fall";
// public string goalAnime = "";
// public string moveAnime = "";
public string nowAnime = "";
public string oldAnime = "";
private Transform _transform;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
//rbodyにRigidbody2Dを代入
rbody = this.GetComponent<Rigidbody2D>();
//animator の代入
animator = GetComponent<Animator>();
nowAnime = stopAnime;
oldAnime = stopAnime;
// transformに毎回アクセスすると重いので、キャッシュしておく
_transform = transform;
}
// Update is called once per frame
void Update() //変数の入力
{
//水平方向の入力をチェックする
axisH = Input.GetAxisRaw("Horizontal");
//向き
if (axisH > 0.0f)
{
//右移動
transform.localScale = new Vector2(scale,scale);
}
else if (axisH < 0.0f)
{
//左移動
transform.localScale = new Vector2(-scale,scale); //左右反転
}
//キャラクターをジャンプさせる
if (Input.GetButtonDown("Jump"))
{
Jump(); //ジャンプ関数
}
if (rbody.linearVelocity.y < 0)
{
fallBody = true;
riseBody = false;
}
else if (rbody.linearVelocity.y >= 0) {
fallBody = false;
riseBody = true;
}
// else if (rbody.linearVelocity.y == 0) {
// jLanding = true;
// }
}
void FixedUpdate() //変数によって動作を変化させる(移動などの物理処理を使う変化)
{
//地上判定
onGround = Physics2D.Linecast(transform.position, transform.position - (transform.up * 1.0f), groundLayer);
Debug.DrawLine(transform.position,transform.position - (transform.up * 1.0f), Color.red);
if (onGround || axisH != 0) //地上の上 もしくは 速度がある 場合に横移動run01
{
//速度を更新する
rbody.linearVelocity = new Vector2(axisH * speed, rbody.linearVelocity.y);
}
if (onGround && goJump) //地面の上 で ジャンプキーの検出
{
//ジャンプさせる
Vector2 jumpPw = new Vector2(0, jump); // ジャンプさせるベクトルを定義
rbody.AddForce(jumpPw, ForceMode2D.Impulse); //瞬間的な力を加える
goJump = false; //ジャンプフラグを初期化
}
if (onGround) //地面の上
{
if (axisH == 0 )
{
nowAnime = stopAnime; //停止中
Debug.Log("停止開始!!");
Debug.Log(nowAnime);
Debug.Log(oldAnime);
Debug.Log("停止終了!!");
}
else
{
nowAnime = moveAnime; //移動
Debug.Log("移動開始!!");
Debug.Log(nowAnime);
Debug.Log("移動終了!!");
}
}
else //空中にいるとき
{
if (riseBody == true) { //上昇中
nowAnime = jumpUp;
Debug.Log("上昇開始!!!");
Debug.Log(nowAnime);
Debug.Log(oldAnime);
Debug.Log("上昇終了!!!");
}
else if (fallBody == true) { //落下中
nowAnime = fallAnime;
Debug.Log("下降開始!!!");
Debug.Log(nowAnime);
Debug.Log(oldAnime);
Debug.Log("下降終了!!!");
}
}
if (nowAnime != oldAnime)//実際にアニメーションを動かす部分
{
oldAnime = nowAnime;
animator.Play(nowAnime); //アニメーション再生
}
}
//ジャンプ関数
public void Jump ()
{
goJump = true;
}
}
コードの一部は書籍「たのしい2Dゲームの作り方 Unityで始めるゲーム開発入門」(著:STUDIO SHIN 発行人:佐々木 幹夫 出版:株式会社 翔泳社)において記載されているコードを参考にしています。
アニメーションクリップ

参考文献
STUDIO SHIN(スタジオ シン)(2021)『たのしい2Dゲームの作り方 Unityではじめるゲーム開発入門』 翔泳社

コメント