2Dゲームでプレイヤーがジョイスティック(Ultimate Joystick)で移動し、自動的に弾丸を発射する機能を実装する
目標: 2DゲームでプレイヤーがUltimate Joystickで移動し、自動的に弾丸を発射する機能を実装する。
使用アセット:
- Ultimate Joystick (ジョイスティック操作用)
Ultimate Joystick | Input Management | Unity Asset Store
Get the Ultimate Joystick package from Tank & Healer Studio and speed up your game development process. Find this & other Input Management options on the Unity ...
プロジェクト構成:
- Player (ゲームオブジェクト):
JoystickManager
スクリプト (移動制御)PlayerController
スクリプト (弾発射、向き制御)Rigidbody2D
コンポーネントSprite Renderer
コンポーネント- タグ:
Player
- レイヤー:
Player
(またはプレイヤー専用のレイヤー)
- FirePoint (空のゲームオブジェクト):
Player
オブジェクトの子オブジェクトとして配置- 弾丸の発射位置と向きを示す
- レイヤー:
Default
(またはプレイヤーと衝突しないレイヤー)
- Bullet (プレハブ):
Bullet
スクリプト (弾の移動、衝突判定)Rigidbody2D
コンポーネント (Gravity Scale
は 0 に設定)Circle Collider 2D
コンポーネント (Is Trigger
をオン)Sprite Renderer
コンポーネント- タグ: なし (または必要に応じて設定)
- レイヤー:
Bullet
(または弾丸専用のレイヤー)
- Enemy (プレハブ):
EnemyController
スクリプト (敵の移動)Enemy
スクリプト (敵の体力、ダメージ処理)Rigidbody2D
コンポーネントCollider2D
コンポーネントSprite Renderer
コンポーネント- タグ:
Enemy
- レイヤー:
Enemy
(または敵専用のレイヤー)
スクリプト:
1. JoystickManager.cs (プレイヤーの移動)
using UnityEngine;
public class JoystickManager : MonoBehaviour
{
RectTransform mytransform;
[SerializeField]
float movespeed = 300f;
void Start()
{
mytransform = GetComponent<RectTransform>();
}
void Update()
{
mytransform.position = mytransform.position + new Vector3(UltimateJoystick.GetHorizontalAxis("Movement"), UltimateJoystick.GetVerticalAxis("Movement"), 0) * movespeed * Time.deltaTime;
}
}
2. PlayerController.cs (プレイヤーの弾発射、向き制御)
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public GameObject bulletPrefab; // 弾丸のプレハブ
public Transform firePoint; // 弾丸の発射位置
public float fireRate = 0.5f; // 発射間隔(秒)
public AudioClip shootSound; // 発射時の効果音
public bool isFacingRight = true; // プレイヤーが右を向いているかどうか
private float nextFire = 0.0f; // 次に発射可能になる時間
void Update()
{
// 自動発射処理
if (Time.time > nextFire)
{
nextFire = Time.time + fireRate;
Shoot();
}
// プレイヤーの向きを更新
UpdateFacingDirection();
}
void Shoot()
{
// 弾丸を生成
Vector3 spawnPosition = firePoint.position;
spawnPosition.z = 0; // Z座標を0に設定
Instantiate(bulletPrefab, spawnPosition, firePoint.rotation);
// 効果音を再生
if (shootSound != null)
{
AudioSource.PlayClipAtPoint(shootSound, transform.position);
}
}
void UpdateFacingDirection()
{
// Joystickの水平方向の入力を取得
float horizontalInput = UltimateJoystick.GetHorizontalAxis("Movement");
// 入力方向に基づいてプレイヤーの向きを更新
if (horizontalInput > 0)
{
isFacingRight = true;
}
else if (horizontalInput < 0)
{
isFacingRight = false;
}
// プレイヤーのSpriteの向きを反転させる (必要に応じて)
if (isFacingRight)
{
transform.localScale = new Vector3(1, 1, 1); // 正面向き
}
else
{
transform.localScale = new Vector3(-1, 1, 1); // 反転
}
}
}
3. Bullet.cs (弾の移動、衝突判定)
using UnityEngine;
public class Bullet : MonoBehaviour
{
public float speed = 20f; // 弾丸の速度
public Rigidbody2D rb; // 弾丸のRigidbody2D
void Start()
{
Debug.Log("弾丸生成!");
// Rigidbody2Dコンポーネントを取得してrb変数に代入する
rb = GetComponent<Rigidbody2D>();
// プレイヤーの向きを取得
GameObject player = GameObject.FindGameObjectWithTag("Player");
if (player != null) {
PlayerController playerController = player.GetComponent<PlayerController>();
rb.velocity = playerController.isFacingRight ? transform.right * speed : -transform.right * speed;
} else {
rb.velocity = transform.right * speed;
}
}
void OnTriggerEnter2D(Collider2D hitInfo)
{
// 衝突したオブジェクトの情報を取得
Debug.Log(hitInfo.name);
// プレイヤーとの衝突を無視する
if (hitInfo.CompareTag("Player"))
{
return; // 何もせずに処理を抜ける
}
// 敵にダメージを与える処理 (例)
Enemy enemy = hitInfo.GetComponent<Enemy>();
if (enemy != null)
{
enemy.TakeDamage(20); // 20ダメージを与える (ダメージ量は必要に応じて変更)
}
// 弾丸自身を破棄
Destroy(gameObject);
}
}
4. Enemy.cs (敵の体力、ダメージ処理)
using UnityEngine;
public class Enemy : MonoBehaviour
{
public int health = 100; // 敵の体力
public void TakeDamage(int damage)
{
health -= damage;
if (health <= 0)
{
Die();
}
}
void Die()
{
// 敵が倒されたときの処理(例:アニメーション再生、アイテムドロップ、スコア加算など)
Debug.Log("Enemy Down!"); // とりあえずログ出力
Destroy(gameObject);
}
}
5. EnemyController.cs (敵キャラクターの動き)
using UnityEngine;
public class EnemyController : MonoBehaviour
{
public float speed = 2f; // 敵の移動速度
private Transform player; // 主人公のTransform
void Start()
{
// 主人公のゲームオブジェクトを探してTransformを取得
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update()
{
if (player != null)
{
// 主人公の方向を計算
Vector2 direction = (player.position - transform.position).normalized;
// 主人公に向かって移動
transform.position = Vector2.MoveTowards(transform.position, player.position, speed * Time.deltaTime);
// 敵の向きを主人公の方向に向ける (オプション)
UpdateFacingDirection(direction);
}
}
void UpdateFacingDirection(Vector2 direction)
{
// プレイヤーのSpriteの向きを反転させる (必要に応じて)
if (direction.x > 0)
{
transform.localScale = new Vector3(1, 1, 1); // 正面向き
}
else if (direction.x < 0)
{
transform.localScale = new Vector3(-1, 1, 1); // 反転
}
}
}
6. EnemySpawner.cs (敵キャラクターを発生)
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
public GameObject enemyPrefab; // 出現させる敵のプレハブ
public float spawnRadius = 5f; // 出現させる円の半径
public float spawnInterval = 2f; // 出現間隔(秒)
private Transform player; // 主人公のTransform
void Start()
{
// 主人公のゲームオブジェクトを探してTransformを取得
player = GameObject.FindGameObjectWithTag("Player").transform;
// 一定時間ごとに敵を出現させる
InvokeRepeating("SpawnEnemy", 0f, spawnInterval);
}
void SpawnEnemy()
{
if (player != null)
{
// 主人公の位置を中心に円周上のランダムな位置を計算
Vector2 randomCirclePoint = Random.insideUnitCircle.normalized * spawnRadius;
Vector3 spawnPosition = player.position + new Vector3(randomCirclePoint.x, randomCirclePoint.y, 0f);
// 敵を出現させる
GameObject newEnemy = Instantiate(enemyPrefab, spawnPosition, Quaternion.identity);
// Enemy スクリプトをアタッチ
newEnemy.AddComponent<Enemy>();
}
}
}
重要なポイント:
- レイヤー設定:
Player
,Bullet
,Enemy
など、オブジェクトの種類ごとに専用のレイヤーを作成し、適切に設定します。- Edit -> Project Settings -> Physics 2D の Layer Collision Matrix で、レイヤー間の衝突判定を制御します。特に、
Player
レイヤーとBullet
レイヤーが衝突しないように設定します。
- FirePoint:
FirePoint
は弾丸の発射位置と向きを決めるための空のゲームオブジェクトです。Player
オブジェクトの子オブジェクトとして作成し、適切な位置に配置します。
- 弾丸の生成:
PlayerController
のShoot()
関数でInstantiate()
を使用して弾丸プレハブを生成します。- 生成位置は
firePoint.position
、生成角度はfirePoint.rotation
を使用します。
- 弾丸の移動:
Bullet
スクリプトのStart()
関数で、Rigidbody2D
コンポーネントを取得し、rb.velocity
に速度を設定します。- プレイヤーの向き
isFacingRight
を参照して、弾丸の進行方向を決定します。
- 衝突判定:
Bullet
スクリプトのOnTriggerEnter2D()
関数で衝突判定を行います。hitInfo.CompareTag("Player")
でプレイヤーとの衝突を無視します。hitInfo.GetComponent<Enemy>()
で敵との衝突を判定し、Enemy
スクリプトのTakeDamage()
関数を呼び出してダメージを与えます。
- オブジェクトの破棄:
OnTriggerEnter2D()
内の最後で、Destroy(gameObject)
を呼び出して弾丸自身を破棄します。Enemy
スクリプトのDie()
関数で、敵が倒されたときにDestroy(gameObject)
を呼び出して敵を破棄します。