宝箱の実装【UnityでVampire survivers 風のゲームを作ろう!第14回】

vampire survivors

UnityでVampire survivers 風のゲームを作ろう!#0【連載目次】

今回はチェストの実装をしていきます。
今回やることは
・チェストUIの作成
・チェストの作成
・チェストを落とす敵の追加
・EnemyGeneratorの変更

チェストUIの実装
まずはチェストを取得した時に表示されるUIを作成します。
このUIの中のボタンを押すことで、アイテムが生成されます。

Canvasの子要素としてもう一つCanvasを作成します。
名前をChestUIにします。今回作成するUIはすべてこのChestUIの子要素にしてください。

ChestUIにAddComponentからGraphic Raycasterを追加してください。(これがないとCanvasにあるUIをクリックできません)

その下に右クリック→UI>Panelを作成します。
Rect Transform
Left 50
Top 50
Pos Z 0
Right -1000
Bottom -1800
にします。

Imageより、Colorを474BFFに設定します。
AddComponentからShadowを追加します。
X10 Y-10にします。

そして次に画面を閉じるボタンを追加します。このボタンを押すことで、UI画面を閉じて、アイテムを生成します。Panelの子要素としてLegacy>Buttonを作成します。Button (Done)に名前を変えます。

RectTransform Pos X0 Y-760 Z0

Width 500 Height 140

ImageよりColor 5849FFに設定します。

AddComponentよりOutlineを追加します。
Effect Color FFDE00
Effect Distance X10 Y10にします。

ボタンの子要素になっているテキストを編集します。
Text欄をDoneに書き換えフォントも変えておきましょう。
Color ffffff
FontSize 80にします。

アイテム名の表示
UI>Legacy>Textでアイテムを表示するためのTextを作っておきます。
名前をItemNameにします。
RectTransform
Pos X 0 Y -500 Z0
Width 600 Height 150

TextをDroneに書き換えます。
Font Size120に設定します。
ParagraphのAlignmentを両方とも中央寄せに設定します。
FontもBangersに変えます。
RaycastTargetの☑は外します。

続いて、チェストが開かれた画像を配置します。


UI>Imageを選択します。
名前をOpenChestにします。
RectTransform
Pos X 0 Y -120 Z0
Width 500 Height 500
ImageのSourceImageにImageフォルダにあるOpenChestimgをアサインします。
RaycastTargetの☑は外します。

続いて、アイテムを表示する画像と、背景を設定します。
先に背景を設定します。
UI>Imageを選択、名前をBackにします。
Rect TransformをStretchにします。
Left 375 Top 460 Pos Z 0
Right -675 Bottom -760
Scale X1.2 Y1.2 Z 1にします。
RaycastTargetの☑は外します。

もし位置がおかしくなる場合は画像のような位置に合うように調整してください。

ImageよりColorは白にします。
透明度はAの数値を変えることで変更できます。
165に設定します。

アイテムを表示する画像を作ります。
UI>Imageを選択、名前をItemImageにします。
RectTransform
Pos X 0 Y 460 Z0
Width 400 Height400

Color Alphay値を165にします。

Image
Source Image Imagesフォルダより Droneを読み込ませます。

AddComopentよりShadowを追加します。
EffectColor を000000にして、透明度を128にします。
Effect DistanceをX5 Y-5にします。

BackよりもItemImageがヒエラルキーの並びで下になるようにしてください。
Unityでは下にあるオブジェクトが前面に表示される仕様となっています。

すべて設定し終わったらChestUIのCanvasのチェックマークを外すのを忘れないでください。

Buttonをクリックした時に処理するスクリプトを書いていきます。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ChestItemScript : MonoBehaviour
{
    [SerializeField] StatusData statusdata;
    [SerializeField] GameObject DronePrefab;
    [SerializeField] GameObject AmpoulePrefab;


    [SerializeField] StatusData statusdata;
    [SerializeField] GameObject DronePrefab;
    [SerializeField] GameObject AmpoulePrefab;
    [SerializeField] GameObject LevelUPUI;
    public Image Imagename;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        
    }
    public void Onclick()
    {
        Imagename = this.gameObject.GetComponent<Image>();
        Debug.Log(Imagename.sprite.name);
        if (Imagename.sprite.name == "DroneImg")
        {
            Debug.Log("ドローンを選択");
            var Drone = Instantiate(DronePrefab, transform.position, transform.rotation);

        }
        if (Imagename.sprite.name == "AmpouleImg")
        {
            Debug.Log("聖水を選択");
            var Ampoule = Instantiate(AmpoulePrefab, transform.psition, transform.rotation);
        }
        if (Imagename.sprite.name == "PunchImg")
        {
            Debug.Log("パンチを選択");
            statusdata.ATK++;
        }
        Time.timeScale = 1;
        LevelUPUI.GetComponent<Canvas>().enabled = false;

    }


ヒエラルキー上でCrate>Emptyでオブジェクトを作っていきます。
GameManegerと名前を付け、ChestItemScriptをアタッチします。
DronePrefabとAmpoulePrefab、statusdataにPlayerStatusをアサインします。

Imagename.sprite.nameで画像自体の名前を取得し、その画像にあった処理を実装しています。

Button(Done)のインスペクターにあるButtonのOn Clickを編集していきます。
ヒエラルキー上からGameManegerをドラッグ&ドロップします。
ChestItemScript>Onclickを選択します。

チェスト自体の実装

プレイヤーがチェストに触れることで、チェストUIが開きます。

Imagesフォルダの中のChestのPixels Per Unit を1000にします。

ImagesフォルダからChestをヒエラルキー上にドラッグ&ドロップします。
当たり判定の為に、AddComponentからBoxCollitder2DとRigidbody2Dを追加します。
重力の影響や周りのオブジェクトにぶつかって動くことがないようにRigidbody2DのBodyTipeをKinematicにします。

まずはChestUIを作成していきます。

ChestScriptを作成します。
持たせる機能は
・プレイヤーが触れた場合、アイテム取得UIを表示する
・エフェクトを発生させる
・画面外でチェストが生成され場合、画面内に移動させる

の三つです。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Chest : MonoBehaviour
{
    [SerializeField]
    GameObject ChestUI;

    [SerializeField]
    GameObject confetti;

    Image itemimage;
    Text ItemName;
    [SerializeField] Sprite imageDrone;
    [SerializeField] Sprite imageAmpoule;
    Vector2 confettiPos;

    int start = 0;
    int end = 2;
    List<int> numbers = new List<int>();
    int argmentrnd;
    Vector2 InitialPos;
    // Start is called before the first frame update
    void Start()
    {
        ChestUI= GameObject.Find ("ChestUI");//ChestUIを検索させる
        confettiPos =new Vector2(0,0);
        itemimage = GameObject.Find("ItemImage").GetComponent<Image>();
        ItemName = GameObject.Find("ItemName").GetComponent<Text>();
        InitialPos = this.transform.position;
        //初期設定 (ドロップ位置が画面の外の時に画面内に移動させる)
        if (InitialPos.x < -3) {
            InitialPos.x =-2.3f;
            this.transform.position= InitialPos;
        }
        if (InitialPos.x > 3)
        {
            InitialPos.x = 2.3f;
            this.transform.position = InitialPos;
        }
        if (InitialPos.y < -5)
        {
            InitialPos.y = -4.5f;
            this.transform.position = InitialPos;
        }
        if (InitialPos.y  >5)
        {
            InitialPos.y = 4.5f;
            this.transform.position = InitialPos;
        }
    }

    // Update is called once per frame
    void Update()
    {
       
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        if (other.gameObject.tag == "Player")
        {
            Debug.Log("チェストをゲット");

            argmentrnd = Random.Range(0,2);
            if (argmentrnd == 0) {
                itemimage.sprite=imageDrone;
                ItemName.text = ("Drone");
            }
            if (argmentrnd== 1)
            {
                Debug.Log(argmentrnd);
                itemimage.sprite = imageAmpoule;
                ItemName.text = ("Ampoule");
            }

            ChestUI.gameObject.GetComponent<Canvas>().enabled = true;
            Time.timeScale = 0;//ポーズをする
            var confe = Instantiate(confetti, confettiPos, transform.rotation);
            Destroy(this.gameObject);

        }
    }
}

confettiにアサインするためのParticleSystemを作っていきます。
PrefabフォルダにあるLevelUpParticleをCtrl+Dで複製して、名前をChestParticleに変えます。
StartColorを615E41に変えます。

ChestにChestParticleをアサインします。
imageDrone
imageAmpoule
にそれぞれImagesフォルダの中にあるDroneImgとAmpouleImgをアサインします。
ChestをPrefabフォルダに入れます。

なぜChestUIなどのオブジェクトをアサインせずにGameObject.Findで検索させているかというと、Prefabにあるオブジェクトにヒエラルキー上にあるオブジェクトをアサインすることが出来ないからです。

ドロップアイテムの実装続いて、チェストをドロップする敵の実装を行っていきます。

EnemyScriptを書き換えていきます。ChestPrefabをアサインしている敵だけがアイテムをドロップするようにします。


using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class EnemyScript : MonoBehaviour
{

GameObject Player;
Vector3 PlayerPos;
[SerializeField] StatusData statusdata;
[SerializeField] Chest Chest_Prefab;
public bool once = true;
[SerializeField] GameObject punchefect;☑
Vector3 punchpos;☑

int HP;
bool MUTEKI;//攻撃を受けるかどうかの切り替えを行う
private float currentTime = 0f;
float LifetimeCount = 0f;
Vector3 diff;//プレイヤーとの距離を測るための
Vector3 vector;
private Rigidbody2D rb;

 void Update(){

	~省略~
	
	    if (MUTEKI)//攻撃を受けてから0.2秒後にする処理
        {
            currentTime += Time.deltaTime;
            if (currentTime > statusdata.SPAN )
            {
                currentTime = 0f;
                MUTEKI = false;//無敵状態終わらせる
                rb.velocity = new Vector2(0, 0);//ノックバックをとめる 
		punchefect.GetComponent<SpriteRenderer>().enabled = false; //ヒットマーク画像を非表示に戻す
            }
            
        }

	 if (HP <= 0)//HPが0以下になったら消える
        {
	  punchpos = this.transform.position;
            punchpos.z = -2f;
            punchefect.transform.position = punchpos;
            punchefect.GetComponent<SpriteRenderer>().enabled = true;

		LifetimeCount += Time.deltaTime;
            if (LifetimeCount > Lifetime)
            {
			 for (int i=0; statusdata.EXP > i; i++) {
                        var EXP = Instantiate(EXP_prefab, transform.position, transform.rotation);
			if(Chest_Prefab!=null){
			var Chest = Instantiate(Chest_Prefab, transform.position, transform.rotation);}
                	 }
		Destroy(this.gameObject);
	  }
}

~省略~

Chest_Prefab!=nullでChestPrefabをアサインされている敵だけがアイテムを落とすようにしました。

Prefabフォルダの中にあるEnemy2をCtrl+Dで複製します。名前をEnemy2(Chest)にします。Enemy2(Chest)のChestPrefabにPrefabフォルダからPrefabをアサインします。

EnemyGeneratorScript


using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class EnemyGeneratorScript : MonoBehaviour
{
[SerializeField]
private GameObject EnemyPrefab;//生成する用の敵キャラPrefabを読み込む
[SerializeField]
    private GameObject enemychestPrefab;
[SerializeField]
private GameObject EliteenemyPrefab;
GameObject Player;
Vector2 PlayerPos;//キャラクターの位置を代入する変数
private float currentTime = 0f;
private float span =3f;
//生成される方向を決める乱数用の変数
int rndUD;(上下)
int rndLR;//(左右)
Vector2 enemyspwnPos;//生成される位置

public bool Chest1;
public bool Chest2;
public bool Chest3;
void Start()
    {
Player  = GameObject.FindGameObjectWithTag("Player");//Playerというタグを検索し、見つかったオブジェクトを代入する
    }
void Update(){
	currentTime += Time.deltaTime;//時間経過をcurrentTimeに代入し時間を測る

	if (Time.time<90f) {
        if (currentTime > span)//spanで設定した3秒を越えたら処理を実行
        {
	  EnemyGenerate(EnemyPrefab);
            currentTime = 0f;
	 }
	if (Time.time > 20&&Chest1== false){
		Chest1=true;
		EnemyGenerate(enemychestPrefab);
		currentTime = 0f;
	}
	}
	if (90f<Time.time) { 
		 if (currentTime > span)//3秒ごと
            {
                // Debug.Log(span);
                EnemyGenerate(ElitenemyPrefab);
                currentTime = 0f;
            }
	if (Time.time > 120f && Chest2 == false)
            {
                Chest2 = true;
                EnemyGenerate(enemychestPrefab);
                currentTime = 0f;
            }
	}
}

~省略~

EnemyGeneratorのenemychestPrefabにEnemy2(Chest)をアサインします。

一定時間が経過した時にチェストを持っている敵が出現するようにしました。
出現条件を変えて完全ランダムにしてもいいと思います。

UnityでVampire survivers 風のゲームを作ろう!第10回時間経過で敵を強くする

↑この時に作ったStatusDataをアサインして強敵にしてもいいと思います。


実際に、敵が落としたチェストを拾ってみてください。

UIが表示されていたら成功です。
次回はボスの実装と倒した時の演出などを作っていきます。

コメント

タイトルとURLをコピーしました