2023年9月26日火曜日

ヴァンパイアサバイバーズ風ゲーム「ギルガメサバイバー」の開発日記#1

ギルガメサバイバー

 おはこんばんちわ!ギルガメです!

最近好きなYoutuberがVampire Survivors(ヴァンパイアサバイバーズ)にハマっていてちょっとどういうものか作ってみたくなりました。


まだまだベースの部分ですが作ってみました。ヴァンパイアサバイバーズ自体は2Dですが3Dで作ってみました。時間ができたら2Dにしていこうかな。


やってみたことは下記になります。

  • プロジェクトの作成
  • プレイヤーの作成(プレイヤーの移動スクリプト)
  • 弾の発射地点
  • 弾のプレハブ
  • 敵の作成
  • 当たり判定の設定

コードを共有します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour
{
public Transform player; // プレイヤーのTransform
public Vector3 offset; // プレイヤーとカメラとのオフセット
public float smoothSpeed = 0.125f; // カメラの移動スムーズネス
void Start()
{
// プレイヤーのTransformを見つける
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void LateUpdate()
{
// プレイヤーの現在位置にオフセットを加えた位置を計算
Vector3 desiredPosition = player.position + offset;
// スムーズにカメラを移動
Vector3 smoothedPosition = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
transform.position = smoothedPosition;
// プレイヤーを中央にキープ(角度は変更しない)
Vector3 lookAtPosition = player.position;
// transform.LookAt(lookAtPosition);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
public float health = 100.0f;
public float speed = 3.0f;
public float damage = 10.0f; // 敵のダメージ力
public Transform player;
private float lastDamageTime = 0.0f; // 最後にダメージを与えた時間
public float damageDelay = 1.0f; // ダメージを与える間隔(秒)
void Start()
{
player = GameObject.FindGameObjectWithTag("Player").transform;
}
void Update()
{
Vector3 direction = (player.position - transform.position).normalized;
transform.position += direction * speed * Time.deltaTime;
}
void OnTriggerStay(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
if (Time.time - lastDamageTime > damageDelay)
{
PlayerController playerController = other.gameObject.GetComponent<PlayerController>();
if (playerController != null)
{
playerController.TakeDamage(damage);
lastDamageTime = Time.time;
}
}
}
}
public void TakeDamage(float damage)
{
health -= damage;
if (health <= 0)
{
Destroy(gameObject);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawner : MonoBehaviour
{
public List<GameObject> enemyPrefabs; // 敵のプレファブのリスト
public float spawnRate = 5.0f; // 敵を生成する間隔(秒)
public float timeToChangeEnemy = 30.0f; // 敵の種類を変更する間隔(秒)
public float spawnDistance = 50.0f; // カメラからの敵の生成距離
private float elapsedTime = 0.0f; // ゲーム開始からの経過時間
private float lastSpawnTime = 0.0f; // 最後に敵を生成した時間
private int currentEnemyIndex = 0; // 現在の敵のインデックス
void Update()
{
elapsedTime += Time.deltaTime;
// 敵の種類を変更する時間が来た場合
if (elapsedTime > timeToChangeEnemy * (currentEnemyIndex + 1) && currentEnemyIndex < enemyPrefabs.Count - 1)
{
currentEnemyIndex++;
}
// 敵を生成する時間が来た場合
if (elapsedTime - lastSpawnTime > spawnRate)
{
SpawnEnemy();
lastSpawnTime = elapsedTime;
}
}
void SpawnEnemy()
{
// プレイヤーの位置を取得
Vector3 playerPosition = Camera.main.transform.position;
// ランダムな方向を計算
Vector3 randomDirection = Random.insideUnitSphere.normalized;
// カメラから一定の距離離れた位置を計算
Vector3 spawnPosition = playerPosition + randomDirection * spawnDistance;
// Y座標を0.5fに設定して、敵が地面にいるようにする
spawnPosition.y = 0.5f;
// 敵を生成
GameObject enemyToSpawn = enemyPrefabs[currentEnemyIndex];
Instantiate(enemyToSpawn, spawnPosition, Quaternion.identity);
}
}
view raw EnemySpawner.cs hosted with ❤ by GitHub
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float speed = 5.0f;
public GameObject projectile;
public Transform firePoint;
public float health = 100.0f; // プレイヤーのHP
private Camera mainCamera; // シーン内のメインカメラ
void Start()
{
mainCamera = Camera.main; // メインカメラを取得
}
void Update()
{
// マウスカーソルの方向を向く
LookAtCursor();
}
void LookAtCursor()
{
// マウスのスクリーン座標を取得
Vector3 mousePosition = Input.mousePosition;
// マウスのスクリーン座標をワールド座標に変換
Vector3 mouseWorldPosition = mainCamera.ScreenToWorldPoint(new Vector3(mousePosition.x, mousePosition.y, mainCamera.transform.position.y - transform.position.y));
// プレイヤーがマウスカーソルの方向を向くように回転
Vector3 directionToLook = mouseWorldPosition - transform.position;
directionToLook.y = 0; // y軸の回転は固定
firePoint.transform.rotation = Quaternion.LookRotation(directionToLook);
float horizontalInput = Input.GetAxis("Horizontal");
float verticalInput = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(horizontalInput, 0, verticalInput);
transform.Translate(movement * speed * Time.deltaTime);
// 左クリックで弾を発射
if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0))
{
Instantiate(projectile, firePoint.position, firePoint.rotation);
}
}
public void TakeDamage(float damage)
{
health -= damage;
if (health <= 0)
{
// プレイヤーが死亡したときの処理(例:ゲームオーバー画面の表示)
Debug.Log("Player is dead!");
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Projectile : MonoBehaviour
{
public float speed = 10.0f;
public float damage = 20.0f;
void Update()
{
// プロジェクトルを前方に移動
transform.Translate(Vector3.forward * speed * Time.deltaTime);
// カメラの枠から出たかどうかをチェック
if (!IsObjectVisible(GetComponent<Renderer>()))
{
Destroy(gameObject);
}
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Enemy"))
{
Debug.Log("Hit enemy!");
EnemyController enemy = other.gameObject.GetComponent<EnemyController>();
if (enemy != null)
{
enemy.TakeDamage(damage);
}
Destroy(gameObject);
}
}
// オブジェクトがカメラの視野内にあるかどうかを判定
bool IsObjectVisible(Renderer renderer)
{
Plane[] planes = GeometryUtility.CalculateFrustumPlanes(Camera.main);
return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);
}
}
view raw Projectile.cs hosted with ❤ by GitHub



プレイヤーのスクリプトではプレイヤーの移動をWASDや矢印キーで動けるようにして、マウスのカーソルに弾の発射方向を向けるようにします。マウスの左クリックで弾を発射します。

敵はプレイヤーのある範囲から生成するようにしています。敵にはプレイヤーに接触した時に与えるダメージとHPを設定して弾が当たっ時にHPが0になった時に破壊します。


下記でシンプルですが遊べます。


ギルガメサバイバーver0.1


次は弾の種類、ミサイルだったり増やしてみようかな。

最後まで読んでいただきありがとうございます!
これからもギルガメを応援していただけるよ嬉しいです!



0 件のコメント:

コメントを投稿