ユニティーを使用した2D格闘ゲームの作り方のメモです。ゲーム制作の参考にしていただければ嬉しいです。トグルボタンをクリックすると記事が表示されます。小さくて見ずらい画像はクリックで拡大できます。
使用素材
アセットストアからこちらの素材を使用して作成しました。
メインカメラの設定
バックグラウンドの色などを変更しました。

タイルパレットを配置
TilemapにTilemapcolider2Dとcompositecoliderを追加しておきます。
Tilemapcolider2Dのused by compositeのチェックを入れると、
Tilemapcoliderのつなぎ目が無くなります。
rigidbody2DのBodytypeはstaticにしておきます。

キャラクターを配置する
アセットに入っているSpriteから好きなものをヒエラルキーウィンドウにドラッグ&ドロップします。
複数選択してドラッグ&ドロップすることでAnimationを同時に作成することができます。
私はHeavyBandit_4~7、LightBandit_4~7をドラッグ&ドロップしてanimetionを作成しました。

キャラクターの向き、位置を調整しました。

作成したキャラクターに物理演算と当たり判定用のコンポーネントを付けていきます。
rigidbody2DとBoxcolider2Dを追加します。
colider(当たり判定)のサイズを調整します。

ドラッグ&ドロップした時にanimetionを作成しているので、再生するとキャラクターが動きます。
アニメーションの速度変更
Unityを使用した2D格闘ゲームの作り方のメモです。
プレイヤーの移動
プレイヤー用のC#スクリプトを作成します。名前はPlayerManagerにしました。
作成したスクリプトをPlayerにアタッチします。
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
//移動速度
public float moveSpeed = 3f;
Rigidbody2D rb;
void Start()
{
//rigidbody2Dを取得
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
//方向キー左右で動くようにする
float x = Input.GetAxisRaw("Horizontal");
//移動方向によってプレイヤーの向きを変える
if (x > 0)
{
transform.localScale = new Vector3(1, 1, 1);
}
if (x < 0)
{
transform.localScale = new Vector3(-1, 1, 1);
}
rb.velocity = new Vector2(x*moveSpeed, rb.velocity.y);
}
}
Playerの回転防止でrigidbody2Dのfreezerotation.zにチェックを入れておきます。

キーボードの←→キーでプレイヤーが移動するようになり、向きも変わるようになりました。
移動アニメーションの作成
移動アニメーションの切り替え
プレイヤーのアニメーションコントローラーをダブルクリックするとアニメーターウィンドウが開きます。


Heavybanditを右クリックしてMakeTransitionでHeavybandit_Runに矢印を繋げます。
Heavybandit_Run側からも同じように矢印を繋げます。

繋がっている矢印をクリックしてhasexitTimeのチェックを外します。

transitionDurationを0にします。

paramatersタブの+ボタンからfloat変数を作ります。

Speedが0.1より早い場合HeavybanditからHeavybandit_Runに切り替わり、
0.1より小さければHeavybandit_RunからHeavybanditに戻るように設定します。
MakeTransitionで繋げた矢印を選択してConditionsを設定します


コードからSpeedの数値を変更してアニメーションを切り替えます。
PlayerManagerにコードを追加します。
Animator animator;
void Start()
{
animator = GetComponent<Animator>();
}
void Update()
{
animator.SetFloat("Speed",Mathf.Abs(x));
}
移動すると走るアニメーションに切り替わります。
敵に攻撃できるようにする
Playerの子オブジェクトに空のオブジェクトを作成します。
名前はAttackPointにしました。

AttackPointの位置を剣の中心の位置まで移動させておきます。

敵のレイヤーをEnemyに設定しておきます。

スクリプトでSpaceキーで攻撃できるようにして、
Attackポイントが敵に当たったらダメージ判定(ログを表示)するようにします。
AttackPointが見ずらいので円を表示するようにします。
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
//移動速度
public float moveSpeed = 3f;
Rigidbody2D rb;
Animator animator;
//アタックポイント
public Transform attackPoint;
//当たり判定の半径
public float attackRadius;
//レイヤー
public LayerMask enemyLayer;
void Start()
{
//rigidbody2Dを取得
rb = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
void Update()
{
//SpaceキーでAttackを実行
if (Input.GetKeyDown(KeyCode.Space))
{
Attack();
}
//移動用関数
Move();
}
private void Attack()
{
//アタックポイントが敵に当たったら攻撃
Collider2D[] hitEnemys = Physics2D.OverlapCircleAll(attackPoint.position,attackRadius,enemyLayer);
foreach (Collider2D hitEnemy in hitEnemys)
{
Debug.Log(hitEnemy.gameObject.name + "に攻撃");
}
}
private void OnDrawGizmos()
{
//アタックポイントに円を表示する
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(attackPoint.position,attackRadius);
}
void Move()
{
//方向キー左右で動くようにする
float x = Input.GetAxisRaw("Horizontal");
//移動方向によってプレイヤーの向きを変える
if (x > 0)
{
transform.localScale = new Vector3(1, 1, 1);
}
if (x < 0)
{
transform.localScale = new Vector3(-1, 1, 1);
}
animator.SetFloat("Speed", Mathf.Abs(x));
rb.velocity = new Vector2(x * moveSpeed, rb.velocity.y);
}
}
Playerのinspector画面からAttackPointと大きさとレイヤーを設定します。

敵に近づいてSpaceキーを押すとログが表示されるようになりました。
アニメーションを作る
Heavybanditの19~23を複数選択してプレイヤーにドラッグ&ドロップしモーションを作成します。

適の攻撃を受けたときのモーションを作成します。
lightbandit32と33を複数選択してEnemyにドラッグ&ドロップします。
攻撃モーションに切り替える
パラメーターの+ボタンからトリガーを作成します。

攻撃モーションに移行する矢印を選択してhasexitTimeのチェックを外します。
transitionDurationを0にします。

ConditionをAttackに設定します。

攻撃モーションにから戻るほうの矢印を設定します。
transitionDurationを0にします。
トリガーにチェックを入れると攻撃モーションが再生されるようになりました。
攻撃した時に操作できるようにコードを追加します。
private void Attack()
{
animator.SetTrigger("Attack");
}
攻撃した時にモーションが再生されるようになりました。
攻撃を受けたときのモーション切り替え
パラメーターの+ボタンからトリガーを作成します。

ダメージモーションに移行する矢印を選択してhasexitTimeのチェックを外します。
transitionDurationを0にします。
ConditionをDamageに設定します。

ダメージモーションから戻る矢印を選択してtransitionDurationを0にします。
敵のコード
C#スクリプトを作成します。名前はEnemyManagerにしました。
作成したスクリプトをEnemyにアタッチします。
public class EnemyManager : MonoBehaviour
{
Animator animator;
void Start()
{
animator= GetComponent<Animator>();
}
public void OnDamage()
{
animator.SetTrigger("Damage");
}
}
PlayerManagerのAttackでEnemyManagerのOnDamageを呼び出します。
private void Attack()
{
animator.SetTrigger("Attack");
//アタックポイントが敵に当たったら攻撃
Collider2D[] hitEnemys = Physics2D.OverlapCircleAll(attackPoint.position,attackRadius,enemyLayer);
foreach (Collider2D hitEnemy in hitEnemys)
{
Debug.Log(hitEnemy.gameObject.name + "に攻撃");
hitEnemy.GetComponent<EnemyManager>().OnDamage();
}
}
攻撃を受けたモーションに切り替わるようになりました。
HPが無くなったら倒れる
他のアニメーションと同じように倒れるアニメーションを作成します。
lightbandit35を使用しました。
アニメーターを開いて矢印を付けてDieトリガーを作成します。

矢印を選択してhasexitTimeのチェックを外します。
transitionDurationを0にします。
counditionsにDieを設定します。

Hpと攻撃力の実装
Playerに攻撃力EnemyにHpを実装してHpが無くなったら倒れるようにコードを追加します。
using UnityEngine;
public class PlayerManager : MonoBehaviour
{
//移動速度
public float moveSpeed = 3f;
Rigidbody2D rb;
Animator animator;
//アタックポイント
public Transform attackPoint;
//当たり判定の半径
public float attackRadius;
//レイヤー
public LayerMask enemyLayer;
//攻撃力
int at = 1;
void Start()
{
//rigidbody2Dを取得
rb = GetComponent<Rigidbody2D>();
animator = GetComponent<Animator>();
}
void Update()
{
//SpaceキーでAttackを実行
if (Input.GetKeyDown(KeyCode.Space))
{
Attack();
}
//移動用関数
Move();
}
private void Attack()
{
animator.SetTrigger("Attack");
//アタックポイントが敵に当たったら攻撃
Collider2D[] hitEnemys = Physics2D.OverlapCircleAll(attackPoint.position,attackRadius,enemyLayer);
foreach (Collider2D hitEnemy in hitEnemys)
{
Debug.Log(hitEnemy.gameObject.name + "に攻撃");
hitEnemy.GetComponent<EnemyManager>().OnDamade(at);
}
}
private void OnDrawGizmos()
{
//アタックポイントに円を表示する
Gizmos.color = Color.yellow;
Gizmos.DrawWireSphere(attackPoint.position,attackRadius);
}
void Move()
{
//方向キー左右で動くようにする
float x = Input.GetAxisRaw("Horizontal");
//移動方向によってプレイヤーの向きを変える
if (x > 0)
{
transform.localScale = new Vector3(1, 1, 1);
}
if (x < 0)
{
transform.localScale = new Vector3(-1, 1, 1);
}
animator.SetFloat("Speed", Mathf.Abs(x));
rb.velocity = new Vector2(x * moveSpeed, rb.velocity.y);
}
}
using UnityEngine;
public class EnemyManager : MonoBehaviour
{
Animator animator;
public int hp = 3;
void Start()
{
animator= GetComponent<Animator>();
}
public void OnDamade(int damage)
{
//プレイヤーの攻撃力をHpから引く
hp -= damage;
animator.SetTrigger("Damage");
//Hpが0以下なら倒れる
if (hp <= 0)
{
Die();
}
}
private void Die()
{
//倒れるアニメーション
hp= 0;
animator.SetTrigger("Die");
}
}
Hpが無くなったら倒れるようになりました。