質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

2018閲覧

(Unity)シャッフルしたカードを並べたいのですがNullReferenceExceptionがでてしまいます。

Naoto96

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2020/05/19 01:04

前提・実現したいこと

プログラミング初心者です。
作り方を載せてくださっているサイトのやり方やスクリプトを丸々真似して、Unityで試験的にカードゲームを作っています。52枚のシャッフルしたカードを1枚目から順に横に並べるための操作をしている途中です。スクリプトや手順を全部真似しているつもりなのですが、実行するとNullReferenceExceptionが出てしまいます。

ネットでエラーメッセージについて調べてみたのですが、この場合は何がNullになってしまっているのか、初心者の自分の力だけでは分かりませんでした。

どこに原因があるのか、何がNullになってしまっているのかを教えていただきたいです。

ご回答宜しくお願い致します。

【参考にさせていただいたサイトのURL】https://tomoarch.com/2019/04/10/unityでできるみんなが知りたいカードゲーム作りの/
https://tomoarch.com/2018/09/12/カードゲームをunityとcで作りたい%EF%BC%9Aカードシャッフ/

発生している問題・エラーメッセージ

NullReferenceException:Object reference not set to an instance of an object
Deck+<GetCards>d__1.MoveNext()(at Assets/Scripts/Deck.cs:10)
DeckView.ShowCards()(at.Assets/Scripts/Deck.cs:26)
DeckView.Start()(at Assets/Scripts/DeckView.cs:19)

該当のソースコード

Deck.cs
【参考にさせて頂いたサイトのページ】https://tomoarch.com/2018/09/12/カードゲームをunityとcで作りたい%EF%BC%9Aカードシャッフ/

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Deck : MonoBehaviour 6{ 7 List<int> cards; 8 public IEnumerable<int> GetCards() 9 { 10 foreach (int i in cards) //10行目 11 { 12 yield return i; 13 } 14 } 15 16 public void Shuffle() 17 { 18 if (cards == null) 19 { 20 cards = new List<int>(); 21 } 22 else 23 { 24 cards.Clear(); 25 } 26 27 for (int i = 0; i < 52; i++) 28 { 29 cards.Add(i); 30 } 31 32 int n = cards.Count; 33 while (n > 1) 34 { 35 n--; 36 int k = Random.Range(0, n + 1); 37 int temp = cards[k]; 38 cards[k] = cards[n]; 39 cards[n] = temp; 40 } 41 } 42 void Start() 43 { 44 Shuffle(); 45 } 46 47}

DeckView.cs
【参考にさせて頂いたサイトのページ】https://tomoarch.com/2018/09/13/カードゲームをunityとcで作りたい%EF%BC%9Aカードシャッフ-2/

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5[RequireComponent(typeof(Deck))] 6 7public class DeckView : MonoBehaviour 8{ 9 Deck deck; 10 public Vector3 start; 11 public float cardOffset; 12 13 14 public GameObject cardPrefab; 15 16 void Start() 17 { 18 deck = GetComponent<Deck>(); 19 ShowCards(); //19行目 20 } 21 22 void ShowCards() 23 { 24 int cardCount = 0; 25 26 foreach(int i in deck.GetCards()) //26行目 27 { 28 float co = cardOffset * cardCount; 29 30 GameObject cardCopy = (GameObject)Instantiate(cardPrefab); 31 Vector3 temp = start + new Vector3(co, 0f); 32 cardCopy.transform.position = temp; 33 34 CardModel cardModel = cardCopy.GetComponent<CardModel>(); 35 cardModel.cardIndex = i; 36 cardModel.ToggleFace(true); 37 38 cardCount++; 39 40 } 41 } 42 43} 44

試したこと

スクリプトやUnity上の手順を何回も確認してみたのですが、サイトと同じことをやっているつもりなのにうまくいきませんでした。

エラーコードについてネットで調べてみて、ある程度理解できたのですが、自分だけでは今回の場合に適用できませんでした。

最初は2019.3.12f1のバージョンでやっていたので、もしかしたらバージョンの違いかと思い2018.3.7f1でやってみても結果は変わりませんでした。

補足情報(FW/ツールのバージョンなど)

(Windows 10)
・Unity 2019.3.12f1
・Unity 2018.3.7f1
・Visual Studio Code

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

Start関数の呼び出し順はランダム(と言われてる)なので、
DeckViewのStart関数が先に呼ばれた場合、Shuffle関数が呼ばれる前に、GetCards関数が呼ばれ、
結果的にcards配列が初期化される前に呼ばれているのが原因だと思われます。

投稿2020/05/19 01:13

yuuyu

総合スコア1139

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Naoto96

2020/05/19 01:27

迅速なご回答ありがとうございます! 呼ばれる順番に着目していませんでした。今一度そこに気を付けて確認してみます。
Naoto96

2020/05/19 01:48

Deck.csのStartをAwakeに変更したら解決しました。ご回答してくださったyuuyu様ありがとうございました。 "Awake"を用いて一番最初に"Shuffle"をして、"cards"配列を初期化した状態で、"Start"関数を呼び、次に"GetCards"を呼ぶということなんですね。良く理解することができました。次からは呼ばれる順番に注意してプログラミングを進めていきたいと思います。 迅速なご対応ありがとうございました。
guest

0

多分DeckViewdeckがnullです。
deck = GetComponent<Deck>();に失敗している気がするので、この次の行に
Debug.Log(deck);と入れて取得出来ているか確認してみてください。
(同じオブジェクトにDeckコンポーネントを付け忘れているとかだと思います)


↑かと思いましたがエラー発生箇所的にyuuyuさんの回答の方が正しそうです。
DeckStart()Awake()にしてみてください。

投稿2020/05/19 01:10

編集2020/05/19 01:16
sakura_hana

総合スコア11427

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Naoto96

2020/05/19 01:25

迅速なご回答ありがとうございます! 早速確認してみたのですが、 UnityEngine.Debug:Log(Object)DeckView(Deck) UnityEngine.Debug:Log(Object) と出ました。 DeckViewというObjectにDeck(Script)とDeckView(Script)を付けている状態です。 この状態で間違いはないでしょうか? ご回答宜しくお願いします。
Naoto96

2020/05/19 01:47

Deck.csのStartをAwakeに変更したら解決しました。ご回答してくださったsakura_hana様ありがとうございました。 "Awake"を用いて一番最初に"Shuffle"をして、"cards"配列を初期化した状態で、"Start"関数を呼び、次に"GetCards"を呼ぶということなんですね。良く理解することができました。次からは呼ばれる順番に注意してプログラミングを進めていきたいと思います。 迅速なご対応ありがとうございました。
sakura_hana

2020/05/19 01:57

解決して何よりです。 Debug.Logについて、状態はそれでOKです。 もしnullの場合は「Null」と出るので、これを使うとどこがnullなのか自分で調べられます。 変数の中身を確認する他、本当にその部分に到達しているのかのチェックが出来るので次回以降はまずこれを使ってデバッグしてみてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問