こんにちは、みじんこと申します。
本記事では前記事から引き続き、Unityでのガチャ(パック)機能の実装方法を説明します。
そちらをまだ見ていない方は、実施後にこの記事に進んで頂けると良きかと思います!
本記事では③のガチャ機能における「カードの種類の実装」を解説していきます。
- 前準備とカードの作成
- カードとパックの生成実装
- カードの種類の実装
- カードのランダム生成機能の実装
- カードの移動アニメーションの実装
- カード詳細パネルの実装
- ショップの実装
本記事の完成形としてはこんな感じですね。
今回は4種類のカードデータを作って、画面上に生成していきます。
今回もばちばちコードを書いていきますが、
ざっくりと分かりやすく説明していくので、初心者の方も安心してください!
それでは早速やっていきましょう。
今回も張り切っていこう!!
Contents
【実装概要】本記事で実装する内容について
まずは今回の記事でやっていくことを理解していきましょう!
今回実装する内容について
今回はカードの種類を実装していきますが、この流れにて実装していきます。
- カードの種類を実装するコードの記載
- 指定した種類のカードを生成する
- 【演習】色んな種類のカードを生成する
今のままだと、カードプレハブをそのまま生成することしか出来ないので、
①で、カードの種類を実装する設定をして、
②で、①で作ったコードを使ってゲーム上に生成していきます。
③で、最後に勉強がてら演習で指定通りのカードを生成してもらいます!
それでは今回は、こんな流れでやっていきます!!
手順①:カードの種類を実装する
1-1.新規スクリプトを作る
それでは早速やっていきましょう。
カード種類の実装の為にはいくつか新規のスクリプトが必要なので、
下記の名前のスクリプトを4つ作成しましょう。
- CardEntity
- CardModel
- CardController
- CardView
1-2.コードの記載
では今作ったスクリプトに順番にコードを書いていきましょう。
まずは「CardEntity」に下記を丸ごとコピー!
1 2 3 4 5 6 7 8 9 10 11 12 13 |
using System.Collections; using System.Collections.Generic; using UnityEngine; [CreateAssetMenu(fileName = "CardEntity", menuName = "Create CardEntity")] public class CardEntity : ScriptableObject { public int cardId; public new string name; public int cost; public Sprite cardImage; } |
次は「CardModel」を下記を丸ごとコピー。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class CardModel { public int cardId; public string name; public int cost; public Sprite cardImage; public CardModel(int cardID) // データを受け取り、その処理 { CardEntity cardEntity = Resources.Load<CardEntity>("CardEntityList/Card" + cardID); cardId = cardEntity.cardId; name = cardEntity.name; cost = cardEntity.cost; cardImage = cardEntity.cardImage; } } |
次は「CardController」を下記を丸ごとコピー。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class CardController : MonoBehaviour { public CardView view; // カードの見た目の処理 public CardModel model; // カードのデータを処理 private void Awake() { view = GetComponent<CardView>(); } public void Init(int cardID) // カードを生成した時に呼ばれる関数 { model = new CardModel(cardID); // カードデータを生成 view.Show(model); // 表示 } } |
最後に「CardView」を下記を丸ごとコピー。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro; public class CardView : MonoBehaviour { [SerializeField] TextMeshProUGUI costText; [SerializeField] TextMeshProUGUI nameText; [SerializeField] Image iconImage; public void Show(CardModel cardModel) // cardModelのデータ取得と反映 { nameText.text = cardModel.name; iconImage.sprite = cardModel.cardImage; costText.text = cardModel.cost.ToString(); } } |
無事に4つのコードを記入して、保存出来たかな??
できたら次に進みましょう!
【コード解説】記載したコードについて
それではゲーム実行に進む前に、今記入したコードの内容を解説していくよ!
ただ今回は記載した内容が多くて全部解説すると逆に分かりづらいように思うので、
ざっくり「何をしているのか」だけを説明していきます!
今回4つのスクリプトを作ったかと思いますが、
下記の「それぞれこんな役割をしている」ってことだけ分かっていればOKです。
スクリプト名 | 役割 |
---|---|
CardEntity | カード自体のデータ |
CardController | CardModelとCardViewをまとめてる |
CardModel | ゲーム実行中のカードのデータを持ってる |
CardView | ゲーム実行中のカードの見た目の管理をしてる |
図で描くとこんな感じ!(あんまり字が綺麗じゃないのはご愛嬌( ̄  ̄))
ここの実装については全部説明しようとすると、
オブジェクト指向とかの話に踏み込んでだいぶややこしいことになるので、
ここはひとまず、細かいコードの中身は置いておいて、何をやっているのかが分かってればOKです!
1-3.Unity側の設定
さてコードの記入は出来たので、Unity側の設定をしていきましょう!
Cardプレハブの設定
以前に作ったカードプレハブの設置を変更する必要があるので、
下記の手順でプレハブを開いて設定していきましょう。
- Cardプレハブを選択
- 「Open Prefab」をクリック
これでプレハブの設定を変更出来るようになったので、続けて実施。
- Cardを選択
- 「AddComponent」を押して、「CardController」と「CardView」を追加する
- 「CardImage」「NameText」「CostText」の3つをCardViewのそれぞれにアタッチ!!
これでカードプレハブの設定は完了です!!
カードデータの作成
それではお待ちかねのカードデータの作成をしていきましょう!
■カード画像の保存
まずは作成するカードに使うイラストを用意しましょう。
カードのイラスト用に画像を3つ載せておくので、こちらをPCに保存してください!(他の画像でもOK)
【画像1】
【画像2】
【画像3】
本記事にてゲーム開発用に画像を提供していますが、その画像については画像生成AIのモデル「AnyOrangeMix」を用いて、本ブログの筆者にて作成されたものです。
著作権フリーではありませんので、他のゲームへの転用等はお断りさせて頂きます。
※「この記事を見てこんなゲーム作れたよー!!」などの作成したゲーム自体の画像や動画のアップロードなどは問題ありませんので、SNSでの投稿等して頂いて大丈夫です。
そしたら、Unity上のImageフォルダに保存しましょう。
保存できたらOK!!
■カードデータの作成
では最後にカードデータの作成をしていきましょう!!
まずはカードデータを置いておくフォルダを作成しましょう。
Assetsフォルダの配下に「Resources」フォルダを作成!
その「Resources」フォルダの中に「CardEntityList」をさらに作成。
そのフォルダの中に入って、データを作っていきます。
- 「Create」をクリック
- 「Create CardEntity」をクリックしたら、「CardEntity」ってのが作られる。
そしたら「CardEntity」を設定していきます。
- 「CardEntity」を「Card0」に名前を変更する
- パラメータを変更する
ここでちょっとだけ説明しておくと、
今「Card0」のデータを作る時に、下記のパラメータを設定したよね。
- カードIDを「0」
- カードの名前を「FireDragon」
- コストを「5」
- カードの画像を「ドラゴンの画像」
後でカードを生成していくけど、その時にカードIDを指定したときに、
このデータを参照して、そのカードに反映していく!ってイメージを持ってくれればOK。
ではUnityの設定に戻ります。
- さっきと同じやり方で、「Card1」「Card2」「Card3」を作る
- 「Card1」のパラメータを設定
残りの「Card2」「Card3」も設定もしましょう。
「Card2」はこっち。
「Card3」はこちら。
これでカードデータの作成は完了!!お疲れ様!
手順②:指定した種類のカードを生成する
さてカードデータを作成しましたが、
そのカードを生成するコードを書かないとカードを生成されないので、
この手順では指定のカードを生成していきます!!
2-1.コードの記載
ではまずはコードを書いていきましょう。
GameManagerスクリプトを下記のコードに変更しましょう。
※ハイライト部分を追記、修正するか。丸ごとコピペでもOK。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { [SerializeField] CardController cardPrefab; // カードプレハブ [SerializeField] GameObject cardPackPrefab; // カードパックプレハブ [SerializeField] Transform openedCardTrans; // 開封したカードの生成場所 [SerializeField] Transform cardPackTrans; // カードパックの生成場所 private void Start() { // カードパックをcackPackTransに生成する //Instantiate(cardPackPrefab, cardPackTrans); for (int i = 0; i < 8; i++) { // cardPrefabをopenedCardTransに生成する CardController card = Instantiate(cardPrefab, openedCardTrans); card.Init(1); } } } |
コードの解説
今回変更した箇所は3箇所ですね。
それぞれざっと説明していきます!
■カードプレハブの「型」の変更
元々はカードプレハブの型は「GameObject」だったけど、「CardController型」に変更したってだけ!
さっきコードの役割で軽く説明したけど、CardController型でカードプレハブを処理することで、カードプレハブにカードのデータを反映させることが出来るようになるよ。
■パック生成コードをコメントアウト
//Instantiate(cardPackPrefab, cardPackTrans);
今回はパックの生成が邪魔になるので、コメントアウトして実行されないようにしてるだけ。
■カードID1番のカードの生成
CardController card = Instantiate(cardPrefab, openedCardTrans);
card.Init(1);
ここが今回の肝です!!
前回の記事で、Instantiateなんちゃらって書くと、カードプレハブが生成出来るよ!って解説したよね。
ここではその生成したプレハブに対して、カードのデータを反映させたいので、
「CardController card = Instantiateなんちゃら」っていうのは、
CardController型の「card」に、その生成したカードプレハブを入れ込んでる!!
って認識でOK。
そんでその後、その「card」でInitメソッド(指定した番号のカードのデータを反映するメソッド)を実行してカードのデータを反映させる!っていう処理をしてます。
2-2.Unity側の設定
カードプレハブの設定が外れてるのでアタッチし直しましょう。
- GameManagerをクリック
- Cardプレハブをドラッグしてアタッチ!!
2-3.ゲームの実行
それではゲームを実行しましょう!
カードIDが1番のカードが8枚生成されてる!!
ってなればOKです。
2-3.コードの整理
今のままでコードの処理としては問題ないけど、
このままだと若干分かりづらいコードになっているので、
コードの整理をしておきましょう。
GameManagerスクリプトが下記のコードになるように、ハイライトした場所を修正!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { [SerializeField] CardController cardPrefab; // カードプレハブ //// [SerializeField] GameObject cardPackPrefab; // カードパックプレハブ [SerializeField] Transform openedCardTrans; // 開封したカードの生成場所 [SerializeField] Transform cardPackTrans; // カードパックの生成場所 private void Start() { // カードパックをcackPackTransに生成する //Instantiate(cardPackPrefab, cardPackTrans); // パックを開封する OpenPack(); } // パックを開封するメソッド void OpenPack() { // 8枚カードを生成する for (int i = 0; i < 8; i++) { CreateCard(1, openedCardTrans); // } } // カードを生成するメソッド void CreateCard(int cardId, Transform trans) { // cardPrefabをopenedCardTransに生成する CardController card = Instantiate(cardPrefab, trans); card.Init(cardId); } } |
修正出来たら保存しましょう。
コードの説明
今整理したコードについて、ちょっと説明しておきます。
変更したのは下記の部分で、やってることはこんな感じです。
【意訳】ゲームを実行したら、OpenPackメソッドを実行!
private void Start()
{
OpenPack();
}
void OpenPack()
{
【意訳】CreateCardの処理を8回繰り返すよ
for (int i = 0; i < 8; i++)
{
【意訳】CreateCardメソッドでカードID1番のカードを生成するよ
CreateCard(1, openedCardTrans);
}
}
【意訳】カードを作るメソッド(生成したいカードのID、生成したいカードの場所)
void CreateCard(int cardId, Transform trans)
{
CardController card = Instantiate(cardPrefab, trans);
card.Init(cardId);
}
今までの処理は全部Startメソッドに書かれていたので、
それぞれの処理をメソッドに分けて書き直してみました。
今のところはまだコードの量が少ないから恩恵はあんまりだけど、
コードの量が増えれば増えるほど、コードの整理は大事になっていくので、
分かりやすいコードを目指して書いていきましょう!
【演習】色んなカードを生成してみる
さて最後にやっていきます、今回の演習はこちら!!
4種類のカードをこの順番で生成してみましょう。
ヒントなしで出来ますかね??
まずは自力で頑張ってみましょう!٩( ‘ω’ )و
【答え合わせ】色んなカードを生成する
ではでは皆さま実装出来ましたかね??
早速ですが、答え合わせをしていきましょう。
【答え合わせ】コードについて
まずは今回の演習の肝になるコードを説明します。
指定した番号のカードを生成するコードはこちらでしたよね??
CreateCard(カードID番号, openedCardTrans);
なので、下記のこの順番でカードを生成するには「0,1,2,3,0,1,2,3」の順番でカードを生成すればOK!
コードで書くとこんな感じ!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
(省略) public class GameManager : MonoBehaviour { (省略) // パックを開封するメソッド void OpenPack() { // 8枚カードを生成する for (int i = 0; i < 2; i++) { CreateCard(0, openedCardTrans); CreateCard(1, openedCardTrans); CreateCard(2, openedCardTrans); CreateCard(3, openedCardTrans); } } (省略) } |
※演習で見せた画面にするためのコードは1つではないので、あくまでこちらは1つの例です。
画面通りに実施出来ていれば、自力で書いたコードが一緒じゃなくても大丈夫です!
ではゲームを実行してみましょう。
このようにカードが生成されましたよね??
それではOK!!
今回の解説はここまで!お疲れ様でした( ´∀`)
【終わりに】カード種類の実装
今回の記事も、最後まで読んでいただきありがとうございました。
今回やったカードデータの作成のやり方は他のデータの作り方にも使える便利なものなので、
やりながら使い方を覚えていきましょう!
それでは今回の記事もここで終わり!!
もし追加で説明して欲しいことなどあれば、コメントください!
ではまた次回!!
【次の記事】
今日はここまで
わかりやすい解説ありがとうございます!
データ保存回りの解説は今後の予定にありますでしょうか?
ガチャを引いた後所有物一覧を開いたら所持していてゲームを再起動してもそのまま保持される等です。
返信遅くなってすみません!
他の記事にもコメントありがとうございます( ´∀`)
順調に進められているようでよかったです。
今の所はデータ保存の解説を書く予定はないですが、必要な機能ではあるのでいつかは書くかもです。。
ちょっと慣れが必要ですが、PlayerPrefsの機能を使えばデータ保存出来るので、調べてみると良きかもです!!
こんにちは、貴殿のブログにお世話になりながらガチャの実装を目指している者です。
ブログ内のコードを使い制作を進めているのですが、四つのスクリプトを作成した以降の流れの中で、ゲームを実行すると「object reference not set to an instance」とのエラーが出て、カードが一枚しか表示されません。
文言的に「CardModel」の「cardID」に引っかかっているようなのですが、ブログ内の解説を見ても、検索にかけてみても解決策が分からず頓挫している状態です。
どうか解決策があればご教示していただきたく、コメント失礼させていただきました。
よろしくお願いいたします。
コメント失礼します。
現在カードのフレームを使わずカードイラストのみでこの記事まで進めています。
前回の記事の部分までは手順通りに進み、正しく動作したものの、この記事の「Cardプレハブの設定」の部分から「CardImage」「NameText」「CostText」を作成していないため進めることができなくなってしまいました。
上の部分をスキップしたものの、今度はカードが一つも表示されなくなっていました…
この場合はどのように作成したらいいのでしょうか?
不明点があれば返信で追記していきます。
ご教示いただけると幸いです。よろしくお願いいたします。