だいぶお待たせしましたが、
⑦⑧で出した演習の答え合わせをします!!
⑨以降の記事では今回の答えを踏まえたコードで進んでいくので、
- 分からなくてスルーした人
- 分かったから自分のコードを書いた人
は今回の答えを追記してから先に進んでね!!
(自分でコードを書いた人は、答えを見たうえで「こっちの方が良いんじゃね??」ってのがあれば教えて下さい!!)
ではいこう!!!
⑦の演習の答え合わせ
まずなんの問題だったか忘れてると思うので振り返ると、
- 味方同士でバトル出来ること
- 手札に攻撃出来ること
の2つのバグを直す問題だったよね??
実装出来た人はマジで素晴らしい。
もはやこの解説記事読む必要ないやろ!!ってレベル
(完全に演習のレベル設定ミスりました。ごめんなさい。)
ってな訳で、これは完璧に出来なくても全然大丈夫!
「こうやんじゃね?? いや、こうかな?!(・ω・´)」っていう、
実際に作るときの悩む楽しさ(?)を感じてほしかったのよ!!笑
と、言い訳はここまでにして本題に行くよ!
【要点】バグ修正の要点2つ
今回大事なるのは、この2つ!!
- カード1枚1枚が、敵 or 味方の情報を持ってること
- 味方同士ならバトルしないようにすること
この2つを実装して、バグの修正をしていくよ!
では行こう!!
① カードに敵味方のデータを持たせる
では早速コードの追記をしていこう
CardModelにオレンジ部分を追記しよう(全部貼り付けても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 25 26 27 28 29 30 31 |
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 bool PlayerCard = false; public bool canAttack = false; public CardModel(int cardID, bool playerCard) // データを受け取り、その処理 { CardEntity cardEntity = Resources.Load<CardEntity>("CardEntityList/Card" + cardID); // CardEntityのパス cardId = cardEntity.cardId; name = cardEntity.name; cost = cardEntity.cost; power = cardEntity.power; icon = cardEntity.icon; PlayerCard = playerCard; } } |
これを追記したことによって、
カード一枚一枚が、PlayerCard=falseというデータを持つようになったよ!
要は普通にカードを出すと、デフォルトで敵カードになる状態ってこと。
そしたらCardControllerの「Initメソッド」も修正↓
1 2 3 4 5 |
public void Init(int cardID, bool playerCard) // カードを生成した時に呼ばれる関数 { model = new CardModel(cardID, playerCard); // カードデータを生成 view.Show(model); // 表示 } |
これでInitメソッド(カードを生成する関数)を呼んだときに、
味方のカードか敵のカードなのかを引数で決めることが出来るようになったよ!!
そしたらInitメソッドを使っているGamaManagerの「CreateCardメソッド」でエラーが出てくるので、下の様に修正しよう↓
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
void CreateCard(int cardID, Transform place) { CardController card = Instantiate(cardPrefab, place); // Playerの手札に生成されたカードはPlayerのカードとする if (place == playerHand) { card.Init(cardID, true); } else { card.Init(cardID, false); } } |
これで
・手札のカードは全てPlayerのカード
・手札以外に作られたカードは全てEnemyのカード
という状況を実装できたね!!
※現状、フィールドに出てるPlayerのカードは、全て手札から出てきたカードなので、フィールドのカードに対しても属性を変更するような処理は必要ないよ。
② 味方同士のバトル処理を止める
あとはまあぶっちゃけ簡単。
バトル処理のところで「PlayerCard値が一緒だったらバトルする前に処理を止める」って処理を追記するだけだね!
GamaManagerの「CardBattleメソッド」にオレンジ部分を追記しよう↓
1 2 3 4 5 6 7 8 9 10 11 |
public void CardBattle(CardController attackCard, CardController defenceCard) { // 攻撃カードと攻撃されるカードが同じプレイヤーのカードならバトルしない if (attackCard.model.PlayerCard == defenceCard.model.PlayerCard) { return; } (省略) } |
これで完成!!
ではゲームを実行してみよう!
フィールドの味方同士はもちろん、手札のカードにも攻撃できなくなったかな??
あくまで今の僕の実装方法なので、違うやり方でも全然OK!!
「もっといい方法があるよー!!」ってひとは教えてくだいさいな!
では次に行こう!!
⑧の演習の答え合わせ
こっちの演習内容としては、
- モンスターに攻撃しても枠が消えない
というバグの修正だったよね!!
これは正直ほぼ答え合わせも要らないと思うけど、一応解説!!
追記内容と解説
今回のバグを修正するには、
カード同士でバトルした後に「緑の枠を見えなくする」という処理を追記すればいいだけ!
なのでGamaManagerの「CardBattleメソッド」にオレンジ部分を追記しよう↓
1 2 3 4 5 6 7 8 |
public void CardBattle(CardController attackCard, CardController defenceCard) { (省略) attackCard.model.canAttack = false; attackCard.view.SetCanAttackPanel(false); } |
こんだけ!!
ではゲームを実行してみよう!
敵のカードに攻撃した後、緑の枠が消えるようになったかな??
なってたらOK!!
ここまでのバグ修正演習は完了です!!
次回の記事からはまた普通の解説記事に戻るので、少々お待ちをー!
次はマナポイントを実装していくよ!!
ではまた!!
次の記事↓
前の記事↓
こんにちは。
Unityを学ぶためにブログを拝見して、この章の内容までは何とか無事にたどり着きました。
一記事を作るだけでも大変だと思いますが、次の章を楽しみに待っております。
その間、別記事でオススメされていた本で勉強しようと思います。
色々とありがとうございます。
>はるひさん
コメントありがとうございます!
別記事も読んでいただきありがとうございます、体系的に学べるので本で勉強するのはおすすめですね( ´∀`)
ただ(ここの解説と比べると、)本の解説ってちょっと難しいよな〜と思う所もあるので、良ければ本で勉強してみた感想など教えていただけると幸いです!
Unity初心者です。
ずっとカードゲームを作りたいと思っていますが、何からすればいいかわかりません。偶然このブログを見つけ、これをきっかけにゲーム作り始めました。
解説はとてもわかりやすいです!次の記事も楽しみにしています!
>かすみさん
コメントありがとうございます!
解説が分かりやすく伝わってるようで安心しました( ´∀`)
ゲーム制作頑張って下さいねー!
初めまして、Unity初心者のものです
いつもこちらのサイトにはお世話になっています^^
突然の相談失礼します。
NullReferenceException: Object reference not set to an instance of an object
CardModel..ctor (System.Int32 cardID, System.Boolean playerCard) (at Assets/Script/CardModel.cs:22)
CardController.Init (System.Int32 cardID, System.Boolean playerCard) (at Assets/Script/CardController.cs:17)
GameManager.CreateCard (System.Int32 cardID, UnityEngine.Transform place) (at Assets/Script/GameManager.cs:55)
GameManager.EnemyTurn () (at Assets/Script/GameManager.cs:124)
GameManager.TurnCalc () (at Assets/Script/GameManager.cs:94)
GameManager.ChangeTurn () (at Assets/Script/GameManager.cs:101)
テストプレイ時にこのようなエラーが出てしまったのですが、そもそも何がダメになっているのかがわかっていないです
お忙しい中でしょうがご指導いただけますと幸いです
んー、何でしょうね、、??
NullReferenceExceptionは9割型、[SerializeField]で定義したものに対してアタッチしてないのが原因なので、
何かアタッチし忘れてるものがないか調べて貰えますか?
アタッチ忘れではなさそうなら、エラーが出る前に何をしたかを教えてもらえると、原因が分かるかもです!
エラーが出る直前に書いたコードが原因なことがほぼ原因かと思われるので!!
アタッチのし忘れは心当たりがなかったのでエラーが出る前の行動を調べたところ、講座⑥のGameManagerへの追記を行った段階で
NullReferenceException: Object reference not set to an instance of an object
CardModel..ctor (System.Int32 cardID) (at Assets/Script/CardModel.cs:18)
CardController.Init (System.Int32 cardID) (at Assets/Script/CardController.cs:17)
GameManager.CreateCard (System.Int32 cardID, UnityEngine.Transform place) (at Assets/Script/GameManager.cs:30)
GameManager.DrawCard (UnityEngine.Transform hand) (at Assets/Script/GameManager.cs:44)
GameManager.SetStartHand () (at Assets/Script/GameManager.cs:51)
GameManager.StartGame () (at Assets/Script/GameManager.cs:21)
GameManager.Start () (at Assets/Script/GameManager.cs:15)
が出たので、この当たりではないかなと思っています
引き続きご指導のほうお願いします
んーー、、アタッチじゃないとしたらなんでしょうね。。。
エラーを見たところ、DrawCardメソッドで手札にカードを作成する時に、何かしらの情報を取得出来なくて起きてるエラーっぽいので、
CreateCardメソッドで渡してる引数が実際には存在しないカードのIDになってる。とかが怪しそうに見えます。
記事の通りに作っていればエラーは出ないように作っているので、自分なりに作り替えてる箇所や、間違えている箇所がないかを確認してみてください!
初めまして!
最近こちらの記事参考にさせて頂いてコツコツカードゲームを制作しております。
どちゃくそわかりやすくてサクサク進められてますありがとうございます!
>味方同士でバトル出来ること
こちらの解決方法について、
①「AttackedCard」に以下を追加
// ドロップしたフィールドを取得
Transform parent = GetComponent();
Transform battlePlace = parent.transform.parent;
// バトルする
GameManager.instance.CardBattle(attackCard, defenceCard, battlePlace);// 引数battlePlace追加
②「GameManager」のCardBattleに以下を追加
public void CardBattle(CardController attackCard, CardController defenceCard, Transform battlePlace)// 引数battlePlace追加
// ドロップしたフィールドが敵フィールドでない場合、攻撃しないで処理終了する
if (battlePlace != enemyField)
{
return;
}
上記の処理にしてみたのですが、問題点などありますか…?
エラーは出ずに思った通りの動きにはなってます!
激辛ポン酢さん、はじめまして!
サクサク進められているようで、よかったです( ´∀`)
敵味方のフラグでなくて、カードの親要素で判定するってやり方ですね。
全然そのやり方で問題ないと思いますよ!
ただ敵が自分のカードに攻撃する場合にも「CardBattle」メソッドは使うので、
その時にそのやり方だと若干懸念があるかも??って感じですかね。
(実際に確かめてないので、なんとも言えないですが、、)
なんにせよ自力で考えた内容をコメント頂けるだけで、ありがたいです!
激辛ポン酢さんのカードゲーム制作を応援しております(`・ω・´)