前回までの記事でカードを持って動かせるようになりましたね!!
見てない人は前回の記事参考↓
今回は実際のカードデータを反映していくよ!!
前回までのカードはただの仮置きのデータなので、今回から本物のデータを持たせて、表示させるよ!
完成形としてはこんな感じ↓
今回から実際にカードを作っていくので、楽しいぞー!!笑
というわけで行くぞ!!
Contents
【作業全体の説明】カードデータ作成と反映
まずはザックリ今回の作業の流れを説明します。
①4つクラスを作る
②コードを書く
③Unity側の設定をする(アタッチ等)
ザックリ言うとこれだけ。
ただこの今回作る4つのコードってのがめっちゃ大事で、それぞれのスクリプトがそれぞれの役割を持ってます。
表にまとめるとこんな感じ↓
【クラス名】 | 【役割】 |
---|---|
Card Entity | カードデータそのもの |
CardVeiw | カードの見た目を管理する |
CardModel | カードのデータを管理する |
Card Controller | カード全体を管理する |
ここがよく分からないまま進むと後々「ん?何言ってんのこいつ?( ˘ω˘ )ワケワカラン」ってなるので、なんとなくでいいから「このスクリプトはこの役割だからこの処理をやってるのね。」って理解しながら進めてね。
コードの作成&記入
まずはスクリプトを4つ作ろう!
4つの名前はこれね↓
- CardEntity
- CardModel
- CardView
- CardController
こんな感じに無事4つ分作れたら、早速コードを記入していこう!!
とりあえず丸々コピペで大丈夫だよ!
CardEntityのコードはこれ↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 int power; public Sprite icon; } |
CardModelのコードはこれ↓
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; using System; public class CardModel { public int cardId; public string name; public int cost; public int power; public Sprite icon; public CardModel(int cardID) { CardEntity cardEntity = Resources.Load<CardEntity>("CardEntityList/Card" + cardID); cardId = cardEntity.cardId; name = cardEntity.name; cost = cardEntity.cost; power = cardEntity.power; icon = cardEntity.icon; } } |
CardViewのコードはこれ↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CardView : MonoBehaviour { [SerializeField] Text nameText, powerText, costText; [SerializeField] Image iconImage; public void Show(CardModel cardModel) // cardModelのデータ取得と反映 { nameText.text = cardModel.name; powerText.text = cardModel.power.ToString(); costText.text = cardModel.cost.ToString(); iconImage.sprite = cardModel.icon; } } |
※(2024/04/22 追記)
TextMeshProを使いたい場合は下記のコードをコピペして使ってください!
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 nameText, powerText, costText; [SerializeField] Image iconImage; public void Show(CardModel cardModel) // cardModelのデータ取得と反映 { nameText.text = cardModel.name; powerText.text = cardModel.power.ToString(); costText.text = cardModel.cost.ToString(); iconImage.sprite = cardModel.icon; } } |
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); // 表示 } } |
無事全部に張り付けられたかな??
どこかしらにエラーとか出てないか軽く確認して、特にエラーがなければ次にいくよ!
コード追記
次は前に作ったGameManagerスクリプトに対しても、ちょっと追記をしていくよ!
たぶん今は、以前に書いた
Instantiate(cardPrefab, playerHand);
とかが書いてあるので、
Startメソッドに書いてある処理は全部消していいよ!
そしたら以下の様にコードを書き換えよう↓
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 GameManager : MonoBehaviour { [SerializeField] CardController cardPrefab; [SerializeField] Transform playerHand, playerField, enemyField; void Start() { StartGame(); } void StartGame() { CardController card = Instantiate(cardPrefab, playerHand); card.Init(1); } } |
詳細はあとで説明するけど、
要はゲーム実行したらStartGameメソッドが動いて、
Card1ってカードを出すよ!って処理をしてるよ。
Unity側の設定
コードが書けたらUnity側の設定をやってこう!!
やることとしては2つだけ!
・カードの作成
・アタッチ
ではやっていこう!!
カードの作成
では今回の一番楽しいところ!!
実際のカードを作ってくよ!!
と言いたいところだけど、
その前にフォルダを作ったりちょっとした前準備をしてくよ。
手順に沿って作ってこう↓
まずはカードデータとかを保存するフォルダを作るよ。
※まず「Assets」フォルダに移動してね!!
①「+」をクリック
②「Folder」をクリック
③「Resources」という名前を付ける
④「Resources」フォルダにCardプレハブをドラッグ&ドロップ
⑤「Resources」フォルダをダブルクリックして、中に入ろう
①先ほどの手順と同じく「CardEntityList」フォルダを作る
②「CardEntityList」フォルダをダブルクリックして中に入る
ここからカードデータを作ってくよ!!
①「+」をクリック
②「Create CardEntity」をクリックする
③こんな感じのが出来る(Unityのバージョンによって多少見た目に違いがあるかも)
④出来たやつの名前を「Card1」に変える
①クリックして、パラメータを画像通りに設定しよう
②「◎」みたいなのをクリックする
③アイコンはこれを選択する
これで1枚目のカードが完成!!!
同じ手順で今度は「Card2」を作ろう。
ちなみに新しく作るときは、Card1をクリックして、「Ctrl+D」でコピー出来るよ。
こんな感じになればOK!!
アタッチ
次はさっき作ったコードをCardプレハブにアタッチしよう!
①「Card」プレハブをクリック
②「AddComponent」をクリックして、「CardController」と「CardView」を検索して、選択する
③「CardController」と「CardView」の二つが張り付けばOK!
④「OpenPrefab」をクリックしよう
①Card(左側)から「Name」を、左の「NameText」に張り付ける。
②この貼り付けを「Cast」「Power」「Image」も同じように行う
ここまで出来たら最後に「GameManagerオブジェクト」にCardプレハブをアタッチしよう!!
①「GameManager」オブジェクトをクリック
②Cardプレハブをドラッグ&ドロップ
③こんな感じに「CardPrefab」に張り付けばOK!!
ではゲームを実行してみよう!!
今までとは違うカードが出てきた!!!!
他の種類のカードを出すには??
ひとまず新しく作ったカードを表示することは出来るようになったけど、まだ1種類のカードしか出せてない!!
というわけで他のカードも出せるようにしていくよ!
GameManagerにコードを追記して、Card2も出せるようにしていこう。
※オレンジ部分を追記してね↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { (省略) void StartGame() { CardController card = Instantiate(cardPrefab, playerHand); card.Init(1); CardController card2 = Instantiate(cardPrefab, playerHand); card2.Init(2); CardController card3 = Instantiate(cardPrefab, playerHand); card3.Init(2); CardController card4 = Instantiate(cardPrefab, playerHand); card4.Init(1); CardController card5 = Instantiate(cardPrefab, playerField); card5.Init(2); CardController card6 = Instantiate(cardPrefab, playerField); card6.Init(1); } } |
これで実行すると、
自分のフィールドに2番目に作ったカードも出てきた!!
これはどうやったかと言うと、下のコードの処理によるもの。
CardController card2 = Instantiate(cardPrefab, playerHand);
≪和訳:PlayerHandにCardPrefabを出しますよ。そして出したものを「card2」としますよ。≫
card2.Init(2);
≪和訳:card2は「Card2」として表示させますよ。≫
(以下、何度か繰り返し)
Initの後ろの()の中の数字が、さっき作ったCard1とかCard2を指してるので、ここを書き換えることで好きなカードを出せるようになる!!ってことだね。
例えば、Initの()の中に「1」と書いて、
Instantiate(cardPrefab, playerField)と書き換えたら、
Card1のカードが、自分のフィールドに出る。
ってことだね。
まあ好きなようにいじってみるとわかると思うよ!!
要はこれを書いていけばどんどん色んなカードを好きな場所に出せるようになる!!ってことですな!
、、、でもこれいちいち書くの面倒くない??
「CreatCard」メソッドの作成をしよう
というわけで、カードを作りだす処理をメソッド(関数)にしてまとめよう!!
オレンジの部分が変わってるので、張り替えて実行してみよう↓
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 |
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameManager : MonoBehaviour { [SerializeField] CardController cardPrefab; [SerializeField] Transform playerHand, playerField, enemyField; void Start() { StartGame(); } void StartGame() { CreateCard(1, playerHand); CreateCard(2, playerHand); CreateCard(2, playerHand); CreateCard(1, playerHand); CreateCard(2, playerField); CreateCard(1, playerField); } void CreateCard(int cardID, Transform place) { CardController card = Instantiate(cardPrefab, place); card.Init(cardID); } } |
さっきと同じようになったかな??
でもさっきよりスッキリしたコードになってるよね!
これは「何度も繰り返す処理」をCreatCardと言うメソッドにしたことで、何度も同じようなコードを書かずに済んだから。ってことだね。
なので今後も何度も同じ処理をするような場合は、メソッドにまとめちゃった方がいいよ!
コードの詳細は次で説明してきます!!
コードの解説
今回はいろいろ出てきたので、ざっくりと説明していくよ!!
いきなり読んでも初心者の人はたぶん全部は理解できないと思うけど、
「20%くらい分かったわ!!」で全然OK!!
分かんなくて手が止まっちゃう事の方が勿体ないので、雰囲気だけ掴めれば次にドンドン進んでいって大丈夫だよ!!やってる内にそのうち分かるようになるから。笑
ではいくぞ!!
「CardEntity」について
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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 int power; public Sprite icon; } |
このスクリプトは、
カードデータそのもの!!
「どういうことだよ!!!」って人は、下記のオレンジ部分のコードを追記してみよう↓
1 2 3 4 5 6 7 8 9 10 11 |
public class CardEntity : ScriptableObject { public int cardId; public new string name; public int cost; public int power; public Sprite icon; public string rarity; } |
例えばだけど、Rarity(レアリティ)を付けてみる。
コードを追記したら、カードデータを見に行くと。
パラメータが増えてる!!!!
というわけ。(Legendは勝手に書いただけね。笑)
なのでカードのデータをいじりたかったらCardEntityをいじればいい。ってことですな。
※後で戻しておいてね!!
「CardModel」について
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; using System; public class CardModel { public int cardId; public string name; public int cost; public int power; public Sprite icon; public CardModel(int cardID) // データを受け取り、その処理 { CardEntity cardEntity = Resources.Load<CardEntity>("CardEntityList/Card" + cardID); // CardEntityのパス cardId = cardEntity.cardId; name = cardEntity.name; cost = cardEntity.cost; power = cardEntity.power; icon = cardEntity.icon; } } |
このスクリプトは、
バトル中のカードデータを管理してるもの!!
カードのデータ自体はCardEntityが持ってるけど、
- 自分のカードなのか、敵のカードなのか
- 攻撃できる状態なのか、召喚酔いしてるのか
- 手札のカードなのか、フィールドに出てるのか
っていうバトル中のデータに関してはバトルによって変わるじゃん??
そういうバトル中のデータを持ってるのがCardModel。
だから今後、「このカードは召喚酔いしてるから攻撃できない」とか「自分のカードなのか、敵のカードなのか」とかいうのは、CardModelが管理していくよ!!
「CardView」について
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class CardView : MonoBehaviour { [SerializeField] Text nameText, powerText, costText; [SerializeField] Image iconImage; public void Show(CardModel cardModel) // cardModelのデータ取得と反映 { nameText.text = cardModel.name; powerText.text = cardModel.power.ToString(); costText.text = cardModel.cost.ToString(); iconImage.sprite = cardModel.icon; } } |
このスクリプトは、
バトル中のカードの見た目を管理してるもの!
CardEntityからカードデータそのものを受け取って、CardModelでそのカードデータを持ってても、ゲームの画面に表示されないと意味ないよね。
そこで名前とか、パワーとか色んなデータを表示してるのが、このCardView。
今後出てくる、「攻撃できる状態のカードを光らせる。」という処理はここが管理することになるよ!!
「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); // 表示 } } |
このスクリプトは、
今までのカードに関係するスクリプトをまとめるもの!
という認識でOK
これから出てくるカードは全てCardControllerを使って処理していくよ。
「GameManager」について
1 2 3 4 5 6 7 8 9 10 11 12 |
void StartGame() { CreateCard(1, playerHand); CreateCard(2, playerField); } void CreateCard(int cardID, Transform place) { CardController card = Instantiate(cardPrefab, place); card.Init(cardID); } |
GameManagerは、今回追記した処理の説明をしてくよ。
今回大事になるのが、CreatCardメソッド!!
CreatCardメソッドってのは、8~12行目のやつね。
このメソッドは何をしてるのかというと、
「カード番号(int cardID)と場所(Transform place)を教えたら、その通りカードを出します!!」
って処理をしてるよ。
日本語で言うと、
CreateCard(出したいカードの名前(番号), 出したいカードの場所)
ってこと。
このCreatCardの後ろの()の中の値を「引数」っていうんだけど、いまいち分かんない人は「C# メソッド(関数)」「C# 引数」とかで軽く調べた方がいいかも!!
以上!!!
ものすごくザックリとした説明だったけど分かったかな??
もうちょっと説明が必要なところがあったらコメント下さい!
【演習】カードの作成と表示
では最後に理解度チェックとして演習をやっていこう!!
演習としては、
コードでこの状況を作ってみよう!!↓
ヒントとしては、
・新しいカードを作って、
・カードをそれぞれ表示させる。
って処理が必要だね。
ではやってみよう!!
【演習】答え合わせ
出来たかな??
答えとしては、
Card3を作って、StartGameメソッドに下の処理を突っ込むだけ!
1 2 3 4 5 6 7 8 |
void StartGame() { CreateCard(3, playerHand); CreateCard(1, playerHand); CreateCard(2, playerHand); CreateCard(2, playerField); CreateCard(3, playerField); } |
こんな感じで、今回は細かいコードの中身より、それを使って好きなカードを作って、それを好きな場所に表示できるようになれればOKだよ!!
まとめ
今回で好きなカードを作って、好きなように出せるようになったね!!
次の記事ではデッキを作って、ドローフェイズやターンエンドなど、ターン制御部分を作っていくよ!!
どんどんカードゲームっぽくなって楽しくなるね!!
楽しみながらちょっとずつ作ってこ!
ではでは今回はここまで!!
あ、あと最後に。
一言でもコメント頂けるとめっちゃやる気が上がります!
そして更新頻度も上がります。笑
どんな質問でも、ご指摘でも歓迎ですのでお気軽どうぞ!
ってなわけで今回は終わりっ!!
また次回!!
次の記事↓
前の記事↓
参考にさせて頂いた動画
[Unityゲーム開発講座] シャドバ風!?カードゲームの作り方 #1 UIの実装
毎回毎回分かりやすい解説をしてくださってありがとうございます。
本当に先生と呼ばせていただきたいです!
次回の解説も楽しみに待っています!!
>こゆのさん
コメントありがとうございます!
せ、先生だと、、、!!
嬉しいです。笑(=´∀`)
ちょっと複雑になってきましたけど、大丈夫そうですかね??
少しずつ理解しながら一緒に作っていきましょう!
すいません、CreatCardEntityをCardEntityListの中に出すことができません
Assetの中にResourcesを作成し、その中にCardEntityListを作るところまではできました。
その後、CardEntityListを開き+ボタンを押したのですがCreatCardEntityがどこにも見つかりませんでした。
バージョンによっては名前が変わるなどあるのでしょうか?
>トキムネさん
コメントありがとうございます。
「+」を押しても「Create CardEntity」ボタンが出てこないっていう事ですね!
こちらで事象を試してみましたが再現しなかったです。。
他にも同じようなことが起きたってコメントもないですしね~。。(-ω-) ンー
とりあえず言えることしては、
「+」を押したら出てくるはずの「Create CardEntity」ボタンは、
「CardEntity」クラスの5行目の[CreateAssetMenu(fileName = “CardEintity”, menuName = “Create CardEntity”)]のコードによって作成されるボタンです。
つまりこのコードを消したら僕の「Create CardEntity」ボタンも消えます。
なのでその行にスペルミス等ないか確認してみて下さい!
(あとはちゃんとコードを保存出来てるか、Unity側が読み込むまでちょっと待つとかかなぁ。。)
大変参考になります!ありがとうございます!
>CardEntityListを開き+ボタンを押したのですがCreatCardEntityがどこにも見つかりませんでした。
→ こちら自分の方でも再現されたのですが、game画面側の再生停止ボタンが「■」になっていたのを再クリックしたらCreatCardEntityが出てくるようになりました。
unity側でC#が実行されてない認識なのかも(?)
※他に困っている方がいたら参考まで
コメント失礼します。いつもゲーム制作の参考にさせてもらってます。
質問なのですが、
Cardプレハブにアタッチする際に「Add Component」で「CardController」と検索しても出てこず、アタッチすることが出来ないでいます。「CardView」はアタッチすることが出来ました。
ご教授いただければ幸いです。
>はじめさん
コメントありがとうございます。
コメント反映されてますよ!
すみません、こちらで承認しないと見えないようになってるんです。。笑
では本題の「CardController」がアタッチ出来ない件ですが、
コードの名前にスペルミスが無いかを確認してもらえますか?
「CardController」コードの5行目、
public class CardController : MonoBehaviour の、
このclaasの後ろの名前(CardController)と、コードの名前が一致してないとアタッチ出来ないです。
もう一度コピペ等して、間違いがないように張り直してみてから、アタッチ出来るか確認してみて下さい!!
お返事遅れまして申し訳ございません。
ご回答ありがとうございます。
コードを何度も確認しましたが、ミスはなさそうです。こちらのサイトのコードをコピペして何度も試してみましたが、アタッチすることが出来ないです。
クラス名とコードが一致していないとアタッチすることが出来ないとのことですので、クラス名からコピペしたり、その逆にコード名からコピペしたりしましたが、やはりアタッチすることが出来ないですね・・・。
ほかに何か問題があるかもしれないので、もう一度一から作り直してみたいと考えております。
>はじめさん
んー、、、力になれずすみません。。(´-ω-`)
初めから作り直すのは1回目と違って、
作業の意味を理解した上で作ることになるので、めちゃくちゃはじめさんの力にはなると思います。
大丈夫だと思いますが、また同じように作っていただいた後も事象が再発するようならまたコメント下さい!
全面的にこちらでも記事を見直しますので!
うまく進めることを祈っています。
ミジンコさん
ご解答ありがとうございます。
念のため確認したいのですが、CardEntityはScriptの中に作るのであっていますよね?
フォルダの名前等確認したのですが、やはりCreateCardEntityは出てきません。
あと、CardEntityの5行目、fileName =CardE「i」ntityになってませんか?
>トキムネさん
>CardEntityはScriptの中に作るのであっていますよね?
あってはいますが、メニューに「CreateCardEntity」が出てくるかどうかとは関係無いですね。。
>あと、CardEntityの5行目、fileName =CardE「i」ntityになってませんか?
これに関してはそうですね。間違ってます。笑
ただこれは「CreateCardEntity」を押した時に作られるファイル名なので、今回の事象とは関係無さそうなので黙ってました。
気になるようでしたら直してしまって大丈夫です!記事の方も後で直しておきます!
とりあえず色々やってはみましたが、ちょっと分からないです。。すみません、、
一応やったことは記事にまとめたので参考に見てみてください→ http://yuus01.info/game-make/no-createcardentity/
あとは「ScriptableObject 作り方」って調べてみて下さい、、なにか参考になることが見つかるかも知れないです!
今回から動きが出てきてカードゲームっぽくなり
すごく面白く感じました!
プログラムも細かいところは省いて
教えすぎていないのですごく分かりやすいです!
>もっけさん
Unity始めてから3日目(?)でめちゃめちゃ進んでますね、、!笑(゚Д゚)スゴイ
まさに「何も知らない初心者の方にもカードゲームが作れるように!」って思いながら書いている記事なので、実際の感想が聞けてありがたいです。
多少内容としては難しくなっていきますが、「とりあえずよく分かんないけど作った(‘ω’)」でも十分力になるので、変に止まらないでガリガリ進めていって下さい!
お世話になっております。
コードの作成&記入で
GameManager に
CardController card = Instantiate(cardPrefab, playerHand);
とありますが、Instantiateの戻り値はGameObjectですのでコンパイルエラーになるのではないでしょうか?
するならば
CardController card = Instantiate(cardPrefab, playerHand).GetComponent();
や
GameObject obj = Instantiate(cardPrefab, playerHand);
CardController card = obj.GetComponent();
となると思うのですが、いかがでしょうか?
>yukiさん
コメントありがとうございます。
いえ、コンパイルエラーにはならないですよ!
Instantiateは生成元のオブジェクトと同じ型を返すので!
なので逆に、
GameObject obj = Instantiate(cardPrefab, playerHand);
とした場合は、
「cardPrefabはCardController型なのでGameObject形に変換できません。」
といったエラーが出るはずです。
※CardController card = Instantiate(cardPrefab, playerHand).GetComponent(); の方なら大丈夫です!
あくまで「こっちの方がシンプルで分かりやすいかな」と思ってこう書いてるだけなので、
yukiさん的にそっちの方が明示的で分かりやすいのあれば、そちらに書き直して頂いて全然いいですよ!
ここ参考になると思います↓
参考URL:https://teratail.com/questions/173027
最近Unityを勉強し始めたので、頓珍漢な質問でしたらすいません。
CardプレファブをGameManagerで宣言した
[SerializeField] CardController cardPrefab;
になんで設定できるのか分かりません。
CardプレファブはGameObjectだから、
[SerializeField] GameObject cardPrefab;
になるのではないでしょうか?
Unity的にはCardプレファブにコンポーネントとしてCardController が張り付けてあればOKということでしょうか?
たかみなさん、コメントありがとうございます!
なぜCardController型の変数cardPrefabに、
GameObject型であるはずのCardプレハブを設定出来るのか。ということですね?
>Unity的にはCardプレファブにコンポーネントとしてCardController が張り付けてあればOKということでしょうか?
(ざっくりですが)その理解であってます。アタッチされてれば、その型で宣言した変数に設定出来ます。
ご認識の通りCardプレハブはGameObjectなので、GameObject型でもいいのですが、
基本的にCardプレハブはCardController型で扱いたいので、CardController型で宣言し直してる。ってだけです!
(と言う説明でいいですかね、、?(゚ω゚))
※GameObject型でも下記の記載をすれば、CardController型として使えます。()
cardPrefab.GetComponent
↑ ジェネリクスの <> がコメント投稿するときえてしまいますが、
補っていただければと
みじんこさま
回答ありがとうございます。
InstantiateにGameObject以外を書けることを知らなかったというのもあるのですが、
見直したところ、こちらでは
> CardController cardPrefab;
ではなく
GameObject cardPrefab;
と書いてしまっていたの原因でした。(カスタマイズしていたため)
お手数をおかけいたしまして申し訳ないです。
>yukiさん
なるほど!だからエラーが出てたんですね!
いえいえ、こちらも勉強になったので気にしないで下さい~
お世話になっております。この記事で楽しく作らせていただいております。
Card View スクリプトに各々のtextなどをアタッチするところで、なにもアタッチすることができません。原因は何でしょうか?
解決しました。textmeshproを使っていて、それの変数を用意しないといけなかったみたいです。
>よし行くぞうさん
おっとすみません、
自己解決されたようでなによりです!
確かにtextmeshproを使ってると、ちょこちょこ動きが違うところが出てくるかもしれませんが、読み換えて対応頂けると幸いです!
>よし行くぞうさん
おっとすみません、
自己解決されたようでなによりです!
確かにtextmeshproを使ってると、ちょこちょこ動きが違うところが出てくるかもしれませんが、読み換えて対応頂けると幸いです!
すみません、このtextmeshproを使った場合、アタッチが行えないのですが
具体的なやり方わかりますでしょうか・・・
CardViewクラス に using TMPro を追加して [SerializeField] TextMeshProUGUI cardNumText にしたのですが
CardViewにTextMeshProがアタッチできない状態です・・・
すみません、自己解決しました。
失礼いたしました。
> sususuさん
解決したみたいで良かったです!
また何かあればコメント下さい!(返信遅いですが、、)
最近TCGを作りだしていて非常に参考にさせていただいてます。
非常にわかりやすくてとてもお世話になってます!
>LIBRAさん
コメントありがとうございます!
頑張って書いて良かったなあ(*´ω`)
ちょっとまだ完結してないですが、長い目で待っててください!(笑)
とても分かりやすくて参考になってます!こんな素晴らしい記事を書けるなんて本当にすごいと思います!!応援してます!
>かしわさん
めちゃくちゃ褒めていただきありがとうございます!笑
記事の作成頑張ります!!(=´∀`)
object reference not set to an instance of an object というエラーでデフォルトのカードしか表示されません。原因わかりますでしょうか?
>春さん
あー、アタッチのし忘れ等で良く出てくるエラーですね。
恐らく怪しいのはこの辺りかと、、↓
・アタッチのし忘れ
・フォルダ名の間違い
・コード、クラス名などのスペルミス
この辺りは手順が多いので、解説をよく見ながらもう一回確認してみて下さいー!
コメント失礼します。
何とかここまで来れましたがガンナーが出てこないです。エレファントが一体出るだけす。
コードのエラーは出てはいません。
何が考えられるでしょうか?
追記:とても楽しく勉強させていただいてます。
お身体に気を付けて更新頑張ってください。
>やめたらんすさん
ゲームを実行した時に、Unity側のConsole画面にもエラーは出てないですか?
たぶん「何かしらの値を参照できないよ~」ってエラーが出てると思います。
カードのデータが反映されないエラーは、
・コードのスペルミス
・フォルダのスペルミス
・なにかしらの手順を飛ばしてる
この辺りかな~とは思います。
なので間違えないように注意しながら、
もう一度、解説部分をよく確認してもらえますか?
(あそこら辺の手順多いのでちょっと大変ですけど、、)
追伸:
楽しく出来るのが一番大事ですね!笑
ありがとうございます。のんびり書いてます~(・ω・)
Create CardEntityをして作るときに文章をカードに入れようと思ってるのですが、そのカードの説明で改行などをできるようにするにはどうすればよいでしょうか?
>じゃがすけさん
あー、確かにこのまま改行しようとしても出来ないですよね(笑)
コードに一言書けば改行出来る様になりますが、
単に教えるだけだとじゃがすけさんの力にならないので、調べてやってみて下さい!
ヒントとしては「Inspecter」「改行」辺りですかね。
調べてみたら、先人たちが書いてる記事が見つかると思います!
それでも無理そう、分からなそうなら、またコメント下さい。
(出来た場合も書いてくれると、ありがたいです!)
出来ました!ありがとうございます!!!!!!!
【自分がハマった穴】なぜかCardViewがAsset階層にもできてしまっており、コンパイラエラーになっていた。検索の AllMaterials からCardViewを探して片方を削除したらうまいこといった。
最近このサイトを見つけましたありがとうございます頑張れそうです。
コメントありがとうございます。(・ω・)
ゲーム作れるようになるとめっちゃ楽しいですよ!
一緒に頑張りましょう!
はじめまして.
このサイトを見つけて参考にさせていただいています!
いつもありがとうございます.
cardIDを基にどこにどのカードが置かれているかをDebag.Logで表示させようと思ったのですが,うまくいきません.
Debug.Log(cardPrefab.cardID)
だとか
private CardEntitiy entity;
(略)
Debag.Log(entitiy.cardID)
とかやってもうまく表示されず,Nullしか返ってきません.
どのようにすればDebag.Logに表示されるようになるかわかりますか?
どうぞよろしくお願いします.
>さっどさん
返信めっちゃ遅くなってすみません、、、!!
んー、例えばですが、
以下の様にすればカードIDを表示できます↓
これでプレイヤーの手札のカードのリストを取得();
CardController[] playerHandCardList = playerHand.GetComponentsInChildren
これでプレイヤーの手札の0番目のカードのIDをログに表示
Debug.Log(playerHandCardList[0].model.cardID);
これをリストの枚数分For文で回してたものを、
各フィールドにも同じように実装すれば、
どこにどのカードが置いてあるかを表示できると思います!
各カードのデータの取得については記事の⑨で出てくるので、
上記の方法で「よくわからん!!!」って場合は一旦⑨まで進めていただければと!
それでもまだ「不明じゃあ!!」って場合はまたコメントで聞いて下さい!
CardViewに何もアタッチできないのですがどうすれば良いのでしょうか。
すみません、解決しました。
>しーさん
解決できたみたいで良かったです!!(/・ω・)/
コメント失礼します。cardViewに何もアタッチできない場合はどうすればいいんでしょうか。
アタッチは出来たのですが、いざ再生した時にカードのグラフィックがおかしくなってしまいます。
反対方向にねじれて赤い×マークが出てしまって、
文字の位置などがおかしくなります。
わかりやすく助かります
>kmさん
コメントありがとうございます!!
不明点あれば気軽に聞いてくださいー!
毎日少しずつ進めさせていただいてます。
カードゲームを作る上で知りたい内容が分かってきてとても楽しいです。最後まで続けていけそうです。
>ふぇっとち~ねさん
楽しみながら作れているみたいでよかったです!(*´∀`)
その辺りから、ややこしい部分も増えてきますが、ゆっくり進めていってくださいー!
とてもわかりやすい解説ありがとうございます!勉強になりました!
1つ質問があります。
カードのPOWERをプレイ中に数字を変えることは可能なのでしょうか?
敵を倒すとパワーアップするような事ができたらと思い試行錯誤していますがなかなか上手くできません。
何かヒントでもあれば教えていただきたいです。
>shuuuさん
コメントありがとうございます!
>カードのPOWERをプレイ中に数字を変えることは可能なのでしょうか?
これは可能です。
カードの内部データは変化しているのに、表示に反映されていない。ということであれば、
Init関数の中で使っているview.Show(model)を、敵を倒した後などに使ってみてください。
カードの見た目にデータが反映されるはずです!
この説明でいまいち分からなければ、またコメントくださいー!!
とてもわかりやすく見させていただいています
今回作ったScriptにNo monoBehaviour script in the file or their names do not match in the file と表示されadd componentに表示されません
よろしければ直し方を教えていただきたいです
横からすみません。
自分もエラーが出たのですが、GameManagerのスクリプトの7行目のGameObjectの部分をCardControllerにして
[SerializeField] GameObject cardPrefab;
↓
[SerializeField] CardController cardPrefab;
CardControllerが付いているCardのプレファブをGameManagerのcardPrefabのところにアタッチし直したらいけました。
違ってたらすみません。
>シータさん
返信遅くなってすみません!
匿名さんから返信が来ている通りの手順で出来るようになるかと思いますが、出来るようになりました??
いつもお世話になっております!
とてもわかりやすい解説なのですが、つまづきかけた点が1つだけあったので、記事に書き加えてほしいことがあります。
GameManagerのスクリプトの7行目について、第3回の記事では
[SerializeField] GameObject cardPrefab;
なのですが、今回
[SerializeField] CardController cardPrefab;
とGameObjectからCardControllerに変わったので、黄色の強調表示を追加して、前のスクリプトから変更したことを明示してほしいです!
初心者でも理解しやすくて、自分の他にも参考にしている方が多くいらっしゃる素晴らしい記事だと思うので、他の方がここでつまづかないようにお手数ですがよろしくお願いします…!
>匿名さん
コメントありがとうございます!!
確かにハイライトが抜けてましたね、、指摘箇所修正しました!
自分だけだとどうしても気付けない部分もあるので、こうしたご指摘はとてもありがたいです。また何かあれば教えてください!
あとシータさんへの返信もありがとうございました!
返信が遅いもので、、すごく助かります(´∀`=)
はじめまして
こちらのサイトに大変助けられております
1点質問があるのですが、カードの種類を数百種類作成したいと考えておりまして、上記のようにプレハブを1つ1つとコピペして作成するのは管理上も大変だと思い、データベースやCSVファイルから名前やパワーなどを参照して作成する方法はごぞんじないでしょうか?
よろしくお願いします
> だよもんさん
コメントありがとうございます!!( ´∀`)
確かに記事内で解説してる方法だと数百種類のカードを作るのは厳しいですよね。笑
あるにはありますけど、コメントに書き切れるような内容ではないので「スクリプタブルオブジェクト CSV」で検索してみてください!
他の方のブログか何かで分かりやすく解説してくれてるものがあるかと思うので!
(本サイトでもそのうち書こうとは思ってますが、なにぶんブログを書く時間が少ないもので。。。)
textMeshproを使っているためアタッチができないのですがどうすればよろしいですか?
>無限会社さん
textMeshpro用にコードを書き換えてもアタッチ出来ないですか??
アタッチはできましたがカードの種類が変わらなくどのコードを変えればよいのかわからないです
すみません。スクリプトにエラーが全く出ていないのですが、カードが一枚の1種類しかでてきません。どうやったら複数枚複数種類でますでしょうか・
>ななふしさん
恐らくですがスクリプト側ではなく、Unity側にエラーが出てるはずです。
まずはそちらを確認してみてください。
状況から見るに、設定したカードのデータがUnity側に反映出来てないっぽいですね。
(よくあるのは、カードプレハブへのアタッチし忘れとか、、??)
記事の解説通りに実施出来ていれば表示されるはずなので、もう一度確認してみてください!
cardviewに4つの項目を貼り付ける行程でマークが出て貼り付ける事ができません。それまでの行程でエラーは無いのですが何が問題なのでしょうか?
んー、なんでしょう、、
Card Parefabのcardviewに貼り付け出来てないってことですよね??(C#コード自体にではなく)
翻訳機を使いました。
こんにちは、最近tcgゲームを作ってみるために関連文を探していて発見するようになって一生懸命学んでいます。 ありがとうございます。でも
“他の種類のカードを出すには??” 部分で問題が発生しました。
CardEntityListにCard1、Card2を作り、CardEntityListに挿入し、
他の種類のカードを出すには??のgamemangerコードを追加しますと、
エラーが出てしまいます。
なぜでしょうか?
NullReferenceException: Object reference not set to an instance of an object
CardView.Show (CardModel cardModel) (at Assets/Scripts/CardView.cs:16)
CardController.Init (System.Int32 cardID) (at Assets/Scripts/CardController.cs:18)
GameManager.CreateCard (System.Int32 cardID, UnityEngine.Transform place) (at Assets/Scripts/GameManager.cs:28)
GameManager.StartGame () (at Assets/Scripts/GameManager.cs:17)
GameManager.Start () (at Assets/Scripts/GameManager.cs:12)
該当するエラーです。
自ら解決することができました。
自己解決出来たみたいでよかったですー!
また何かあればコメントください!
GameManagerの追記の部分でエラーを吐く悪い子がいるんです
コピペした上でそうなってるので、オイラは一体どうしたら・・・
教えてくださいミジンコ先生。いや、師範!
Assets\Script\GameManager.cs(18,14): error CS1061: ‘CardController’ does not contain a definition for ‘Init’ and no accessible extension method ‘Init’ accepting a first argument of type ‘CardController’ could be found (are you missing a using directive or an assembly reference?)
こんな感じのエラーメッセージががが・・・
これは解決できたんです!CardController君が悪さしてたみたいで・・・。でも、今度はアタッチできなくなりました・・・なんでや!
今日やっとできました
みじんこさん、楽しく読ませてもらっています。
Java開発経験者で、C#は扱ったことがなかったのですが、記事が非常に読みやすく参考にさせていただいています。
今後の活動も応援してます(^^)
>ななしさん
コメントありがとうございます!
ななしさんのご参考になれたのなら良かったです!( ´∀`)
今後もちまちま更新していくので、お暇な時にでも覗いてください〜
私のような、プログラムのpも知らない人間でも理解できる最高の記事。
これはありがたきコメント( ˘ω˘ )アリガタヤー
Card ViewにName,Power,Costがアタッチ出来ません。
imageはアタッチできました。
Name,Power,Costができない理由を教えてもらいたいです!
バージョンはUnity 2021.3.12f1です。
テキストメッシュプロ使ってたりしますか??
もしそうであれば、記事内で解説してる型と違うのでアタッチ出来ないかと思います!
ありがとうございました!
テキストメッシュプロを使っておUI→Legacy→Textの方でやるとアタッチ出来ました!
これで進めます〜!頑張ります!
PlayerHandにはカードが4枚でてきたのですがPlayerFieldにカードが2枚でてきません
解説お願いします!
GameManagerのPlayerFieldとEnemyFieldは紐付けはしています。
んー、解説通りに作っていれば出てくるはずですが、何か変えながら作ったりしてますか??
もしくは何かしらエラーが出ていたりしないですか?
はじめまして!!
めちゃくちゃ参考にさせて頂いてます。
もの凄くわかりやすくて、まずゲームを作ってみようという気になっています。
まだギリギリついていけてますが、これからどうなることやら・・・。
ゆっくり進めて行きます。
始めました。参考にさせていただきます。
はじめまして
参考にさせていただいております。
つまづいたポイントなのですが、
inspectorのopenを実行してもCardModelが表示されません。
エラーメッセージは、
All compiler errors have to be fixed before you can enter playmode!
UnityEditor.SceneView:ShowCompileErrorNotification ()
と表示されます。
すべてコピペで一旦は形になればと思いましたが、動作しませんでした。
どのような原因と解決方法が考えられますか?
進捗です
cardIDでエラーが発生しています
色々調べてみてますが解決方法が不明です
NullReferenceException: Object reference not set to an instance of an object
CardModel..ctor (System.Int32 cardID) (at Assets/Scripts/CardModel.cs:18)
CardController.Init (System.Int32 cardID) (at Assets/Scripts/CardController.cs:17)
GameManager.CreateCard (System.Int32 cardID, UnityEngine.Transform place) (at Assets/Scripts/GameManager.cs:28)
GameManager.StartGame () (at Assets/Scripts/GameManager.cs:17)
GameManager.Start () (at Assets/Scripts/GameManager.cs:12)
cardIDがなにかおかしいのは分かります
どうおかしくて何を変更(修正)すればいいのかがわかりません
おそらくCardModelかGameManagerが何かしら適切でないことによって、cardIDが取得できない状態にあると考えました。
publicをprivateなどに変更したりも試みましたが解決の緒が全く見えませんでした;;
解決しました
全部
半分は思い違い
完璧な理解まではいっていないでしょうが、ここに書いてある通りのことをして、ちゃんと書いてある通りの結果が出力されているので達成感を覚えています。
プログラムに関して何も学んでこなかった私でもちゃんとパート5まで辿り着けています。非常に理解しやすい記事だと思います。
>ららあさん
コメントありがとうございます!
応用編もご購入頂きありがとうございます( ´∀`)
ららあさんのゲーム作りのお力になれた様で良かったです!
完全に理解は出来ていなくても、自分の好きな様にパラメータをいじるだけどんどん理解は深まっていくと思いますので、楽しみながらゲーム作りを進めていってくださいね!
はじめまして。
カードゲームを作りたいと思い、参考にさせていただいています。
そしてなんとか第5回なでたどり着いたわけですが、アタッチの項目にあります④「OpenPrefab」が見つからずに困っています。スクロールしても見当たらず、解説方法がわからないのですが、何かご教授願えないでしょうか。
④「OpenPrefab」は依然として見つかりませんでしたが、そのあとの
①Card(左側)から「Name」を、左の「NameText」に張り付ける。
②この貼り付けを「Cast」「Power」「Image」も同じように行う
から5回の最後まで問題なくできましたので一応解決?いたしました。
手札にカードが1枚しか生成されません。エラーコードを見る限りcardviewスクリプトとcardmodelスクリプトに問題がありそうですが、何が問題なのかわかりません。確認ですが、cardmodelはどこにもアタッチしてないですよね?
エラー:NullReferenceException:Object reference not set to an instance of an object CardView.Show(CardModel cardmodel)(at Assets/Scripts/CardView.cs:18)
>手札にカードが1枚しか生成されません。
んー、カードの1枚目を生成するときにエラーが起きてるので、2枚目を生成する処理が動いてないんだと思います。
パッと見ですが、何かしらのアタッチ忘れに見えますね。(`・ω・´)
(at Assets/Scripts/CardView.cs:18)とあるので、CardViewの18行目の処理を見てもらってもいいですか?
多分、CardViewに何かしらのアタッチ忘れがありそうです。
ちなみに生成される1枚のカードは、
生成されるカードはCard1としてデータを作成したものが生成出来てますか?(記事で言う「ガンナー」を出せてますか??)
恐らくエラーの感じを見ると、
プレハブとして作ったカード(ここでいう「エレファント」)が出てるような気がします。
>cardmodelはどこにもアタッチしてないですよね?
はい、cardmodelはアタッチしないです。
はじめまして。
この記事の内容に関して、いくつか質問があります。
まず1つ目。カード自体は生成されるのですが、なぜか指定したカードIDから1つズレた物が生成されます。( CreateCard(1, playerHand);と入れているのに対してカードIDが2のものが生成される)
カードの生成の仕方の箇所に関しては本記事のコードの全てをコピペしたものですので、1つズレて生成される原因がわからない状態です。また、他のスクリプトでCardIDやCordIDの変数を使っておらず、他の箇所で影響を食らっているとは考えられにくいです。どうすれば正しいIDで生成できるようになるでしょうか?
2つ目です。カードの大半を事前に自作しており、本記事でパワーとコストに当たるステータスを内部で持たせておきながら、ゲーム画面には表示させない場合は、CardViewのスクリプトで
powerText.text = cardModel.power.ToString();
costText.text = cardModel.cost.ToString();
の2つを削除し、UIのTextを削除するだけでよろしいのでしょうか?
>まず1つ目。カード自体は生成されるのですが、なぜか指定したカードIDから1つズレた物が生成されます。
んー、記事のコードと同じ内容であれば、コードは多分問題ないので、
CardEntityListの中にあるCardの番号がズレている可能性が高いので確認してみてください!
試しにCreateCardメソッドの中に下記のデバックコードを入れてみて、生成してるカードのIDを確認してみてください(card.Initの下あたり)。
Debug.Log(card.model.cardId);
多分、コード上ではズレてないと思います。
>2つ目です。(以下略)
そのやり方でやってみて、何かエラーが出てる感じですかね??
エラーが出ていなくて、想定通りに動いているなら問題ないかと!
迅速な対応ありがとうございます。ズレていることに関しましては、デバッグでのコメントを見た結果、コード自体も1ズレている状態でした。
が、試しに全てのカードIDの内部値を-1してずらしてみると、今度はエラーがでてしまい、そもそも生成されないという状態になってしまいました。
一度前の記事を読み返して、他におかしなところがないか確認してから様子を観ようと思います。
あらら、コードもズレてたんですね!
そしたらデバックログを入れたところで、IDの数字を-1すればいいように見えますけど、
そうするとエラーが出ちゃってるんですかね??
はい、一旦確認していただいて、
お力になれそうなところがあれば、またコメントください!!
お久しぶりです。その後ですが、上記の件ズレていた件に関しまして、どうやらCreate CardEntityにて生成したリストに書きこんだIDではなく、そのリストの名前の数字を参照して反映されているようでした。
当時カードIDとリストの数字にズレがあった為、反映がずれる現象に陥ってたようです。
しかし、このままでは各リストがどのカードの内容なのかが一目でわかりにくく、非常に開発中非常に不便に感じてしまいます。
本ページで作成したスクリプトは全て見直してはいるのですが、解決策が見つかりません。
修正する方法はないでしょうか?
よろしくお願いいたします。
> その後ですが、上記の件ズレていた件に関しまして、どうやらCreate CardEntityにて生成したリストに書きこんだIDではなく、そのリストの名前の数字を参照して反映されているようでした。
これはそうですね。その認識であってます。
CardEntityのコードは、CardEntityListフォルダの中に入っているCardXの「X」を参照してるので、ズレてるわけではないです。
記事の中でもCardXの「X」の値とCardIDの値は合わせるようにしてるので、記事内容と同じように作っているのであればズレることはないと思ってます。
> しかし、このままでは各リストがどのカードの内容なのかが一目でわかりにくく、非常に開発中非常に不便に感じてしまいます。
この質問の意図が分かりかねてるのですが、IDのずれと関係ありますかね??
CardXの値とCardIDの値を同じにすれば問題ないかと思いますが。
有用な記事をありがとうございます!
質問です。
textMeshproを使っているのですが、コードをどのように書き換えればよいか、具体的に教えていただくことは可能でしょうか?
よろしくお願いいたします。
>有用な記事をありがとうございます!
ユミヅキさん、こちらこそコメントありがとうございます!( ´∀`)
>textMeshproを使っているのですが、コードをどのように書き換えればよいか、具体的に教えていただくことは可能でしょうか?
今のUnityだとtextMeshproがデフォルトですもんね。。(古い内容ですみません、、近いうちに書き換えます。。)
コードの書き換えについて、記事内容を更新したので、コードをコピペして確認してみてください!
迅速な対応、本当にありがとうございます!
うまくいきました!
コメント失礼します。
“オブジェクト参照がオブジェクトCardModel(CardID)のインスタンスに設定されていません”というエラーが出てCard1,Car2が出てきません。解決方法はありますか?
んーー、コードを記事通り間違えずにコピペ出来ているのは前提とすると、
見た感じ恐らく、「CardEntity」の中のCardのデータファイルの名前がミスってるか、
CardEntityなどのファイル名がミスってるっぽく見えますね。
⑤の記事内容をそのまま実施すれば出来るはずなので、もう一度よく確認しながら実施してみてください!
アドバイスありがとうございます。
やり直した結果card1,2でました。
原因はResourcesのフォルダーの名前が間違ってたことでした。
上手く行ったみたいでよかったです!
やっぱりその辺りでしたか(`・ω・´)
1文字でも違うと上手くいかないことが多いので、
ミスらないようにコピペしながら進めると良きかもです!
コメント失礼します。
実行すると、GameManagerのCard PrefabがNoneとなり
The Object you want to instantiate is null.
とエラーが出てしまいます。
アドバイスをいただけると幸いです。
あー、ありがちですよね。笑
多分プレハブがちゃんとアタッチ出来てないので、
カードプレハブをアタッチするところの記事をよく見返して正しくアタッチし直してみてください!
※僕も過去に同じように悩んでた形跡がありました。。。笑
”The prefab you want to instantiate is null.”とかいう謎エラーに躓き、人は成長していくんだなぁ。【ゲーム制作記 5日目】