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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Unity

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

Q&A

解決済

2回答

662閲覧

スクリプトコピペしたのにエラーになる

退会済みユーザー

退会済みユーザー

総合スコア0

Unity

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

0グッド

0クリップ

投稿2020/01/15 06:28

現状

ボタンでスコアモードとタイムモードに切り替えるようにしてそれぞれのシーンに移動するようにした
ゲームジェネレーターでゲーム進行管理している
タイムのほうはタイムゲームジェネレーターに名前変更した(ほかのオブジェクトはすべてコピペ)
始めるとスコアのほうは正常にできるがタイムのほうにするとエラーが出る

NullReferenceException: Object reference not set to an instance of an object
TimeGameManager.Start () (at Assets/Scripts/TimeGameManager.cs:38)

NullReferenceException: Object reference not set to an instance of an object
TimeGameManager.LateUpdate () (at Assets/Scripts/TimeGameManager.cs:53)

実現したいこと

タイムモードでもゲームオーバーになってほしいのとタイムが減らない

該当コード

```unity scoreコード public class GameManager : MonoBehaviour { //ゲームステート enum State { Ready, Play, GameOver } State state; int score;//スコア int coin;//コイン public Text StateLabel; public Text scoreLabel; public Text coinLabel; public Text endscoreLabel; public Text endcoinLabel; public GameObject EnemyGenerator;//敵生成オブジェ public GameObject CoinGenerator;//Coin生成オブジェ PlayerCotroller playcon; GameObject Player; public GameObject Title;//タイトルボタン public GameObject Retry;//タイトルボタン private float count; // Start is called before the first frame update void Start() { //開始時にRedayステート開始 Ready(); Player = GameObject.FindWithTag("Playercon"); playcon = Player.GetComponent<PlayerCotroller>(); Time.timeScale = 1; PlayerPrefs.SetInt("NowScore", 0); } void LateUpdate() { //ステートごとにイベント監視 switch (state) { case State.Ready://タッチしたらゲームスタート if (Input.GetButtonDown("Fire1")||Input.GetKeyDown("space")) GameStart(); break; case State.Play://車が破壊されたらゲームオーバー if (playcon.IsDead()) GameOver(); break; case State.GameOver: count += Time.deltaTime; if (count >= 1.0f) { Time.timeScale = 0; Title.gameObject.SetActive(true);//タイトルボタン表示 StateLabel.gameObject.SetActive(false); scoreLabel.gameObject.SetActive(false); coinLabel.gameObject.SetActive(false); if (Input.GetKeyDown("space")) { //ゲームシーンを読み込み SceneManager.LoadScene("Game"); } if (Input.GetKeyDown("right")||Input.GetKeyDown("left")) { //タイトルシーンを読み込み SceneManager.LoadScene("Title"); } } break; } } // Update is called once per frame void Update() { } void Ready() { state = State.Ready; //オブジェクトを無効にする EnemyGenerator.SetActive(false); CoinGenerator.SetActive(false); //ラベル更新 scoreLabel.text = "Score : " + 0; StateLabel.gameObject.SetActive(true); StateLabel.text = "READY"; coinLabel.text = "Coin : " + 0; } void GameStart() { state = State.Play; //オブジェクトを有効にする EnemyGenerator.SetActive(true); CoinGenerator.SetActive(true); //ラベル更新 StateLabel.gameObject.SetActive(false); StateLabel.text = ""; } void GameOver() { state = State.GameOver; //ラベル更新 StateLabel.gameObject.SetActive(true); //オブジェクトを無効にする EnemyGenerator.SetActive(false); CoinGenerator.SetActive(false); StateLabel.text = "GAMEOVER"; //ハイスコアを更新 if (PlayerPrefs.GetInt("ScoreHighScore") < score) { PlayerPrefs.SetInt("ScoreHighScore", score); } PlayerPrefs.SetInt("Totalcoin", coin + PlayerPrefs.GetInt("Totalcoin")); endscoreLabel.text = "Score : " + score; endcoinLabel.text = "Coin : " + coin; } public void IncreaseScore() { if (playcon.IsDead()) return; score += 50; //スコア更新 scoreLabel.text = "Score : " + score; PlayerPrefs.SetInt("NowScore", score); } public void IncreasePlayerScore() { if (playcon.IsDead()) return; score += 10; //スコア更新 scoreLabel.text = "Score : " + score; PlayerPrefs.SetInt("NowScore", score); } public void IncreasCoin() { if (playcon.IsDead()) return; coin++; coinLabel.text = "Coin : " + coin; } public void OnClick() { //タイトルシーンを読み込み SceneManager.LoadScene("Title"); } public void OnRetry() { SceneManager.LoadScene(SceneManager.GetActiveScene().name); } }

unity

1timeコード 2 3public class TimeGameManager : MonoBehaviour 4{ 5 //ゲームステート 6 enum State 7 { 8 Ready, Play, GameOver 9 } 10 State state; 11 int score;//スコア 12 int coin;//コイン 13 float time; 14 public Text StateLabel; 15 public Text scoreLabel; 16 public Text coinLabel; 17 public Text endscoreLabel; 18 public Text endcoinLabel; 19 public Text TimeLabel; 20 public GameObject EnemyGenerator;//敵生成オブジェ 21 public GameObject CoinGenerator;//Coin生成オブジェ 22 PlayerCotroller playcon; 23 GameObject Player; 24 public GameObject Title;//タイトルボタン 25 public GameObject Retry;//タイトルボタン 26 private float count; 27 28 // Start is called before the first frame update 29 void Start() 30 { 31 //開始時にRedayステート開始 32 Ready(); 33 Player = GameObject.FindWithTag("Playercon"); 34////////////////////////////////////////////////////////////////////// 35 //38 playcon = Player.GetComponent<PlayerCotroller>(); 36//////////////////////////////////////////////////////////////////////////// 37 Time.timeScale = 1; 38 PlayerPrefs.SetInt("NowScore", 0); 39 time = 60; 40 } 41 42 void LateUpdate() 43 { 44 //ステートごとにイベント監視 45 switch (state) 46 { 47 case State.Ready://タッチしたらゲームスタート 48 if (Input.GetButtonDown("Fire1") || Input.GetKeyDown("space")) GameStart(); 49 break; 50 case State.Play://車が破壊されたらゲームオーバー 51/////////////////////////////////////////////////////////////////////////////////// 52 //53 if (playcon.IsDead()|| time<=0) GameOver(); 53////////////////////////////////////////////////////////////////////////////////////// 54 break; 55 case State.GameOver: 56 count += Time.deltaTime; 57 if (count >= 1.0f) 58 { 59 Time.timeScale = 0; 60 Title.gameObject.SetActive(true);//タイトルボタン表示 61 StateLabel.gameObject.SetActive(false); 62 scoreLabel.gameObject.SetActive(false); 63 coinLabel.gameObject.SetActive(false); 64 if (Input.GetKeyDown("space")) 65 { 66 //ゲームシーンを読み込み 67 SceneManager.LoadScene("Game"); 68 } 69 if (Input.GetKeyDown("right") || Input.GetKeyDown("left")) 70 { 71 //タイトルシーンを読み込み 72 SceneManager.LoadScene("Title"); 73 } 74 } 75 break; 76 } 77 } 78 79 // Update is called once per frame 80 void Update() 81 { 82 83 } 84 85 void Ready() 86 { 87 state = State.Ready; 88 //オブジェクトを無効にする 89 EnemyGenerator.SetActive(false); 90 CoinGenerator.SetActive(false); 91 //ラベル更新 92 scoreLabel.text = "Score : " + 0; 93 StateLabel.gameObject.SetActive(true); 94 StateLabel.text = "READY"; 95 coinLabel.text = "Coin : " + 0; 96 } 97 void GameStart() 98 { 99 state = State.Play; 100 //オブジェクトを有効にする 101 EnemyGenerator.SetActive(true); 102 CoinGenerator.SetActive(true); 103 //ラベル更新 104 StateLabel.gameObject.SetActive(false); 105 StateLabel.text = ""; 106 time = time * Time.deltaTime * -1; 107 } 108 void GameOver() 109 { 110 state = State.GameOver; 111 //ラベル更新 112 StateLabel.gameObject.SetActive(true); 113 //オブジェクトを無効にする 114 EnemyGenerator.SetActive(false); 115 CoinGenerator.SetActive(false); 116 StateLabel.text = "GAMEOVER"; 117 //ハイスコアを更新 118 if (PlayerPrefs.GetInt("ScoreHighScore") < score) 119 { 120 PlayerPrefs.SetInt("ScoreHighScore", score); 121 } 122 PlayerPrefs.SetInt("Totalcoin", coin + PlayerPrefs.GetInt("Totalcoin")); 123 endscoreLabel.text = "Score : " + score; 124 endcoinLabel.text = "Coin : " + coin; 125 126 } 127 128 public void IncreaseScore() 129 { 130 if (playcon.IsDead()) return; 131 score += 50; 132 //スコア更新 133 scoreLabel.text = "Score : " + score; 134 PlayerPrefs.SetInt("NowScore", score); 135 } 136 public void IncreasePlayerScore() 137 { 138 if (playcon.IsDead()) return; 139 score += 10; 140 //スコア更新 141 scoreLabel.text = "Score : " + score; 142 PlayerPrefs.SetInt("NowScore", score); 143 } 144 public void IncreasCoin() 145 { 146 if (playcon.IsDead()) return; 147 coin++; 148 coinLabel.text = "Coin : " + coin; 149 } 150 151 public void IncreaseTime() 152 { 153 time++; 154 TimeLabel.text = "Time : " + time; 155 } 156 157 public void OnClick() 158 { 159 //タイトルシーンを読み込み 160 SceneManager.LoadScene("Title"); 161 } 162 163 public void OnRetry() 164 { 165 SceneManager.LoadScene(SceneManager.GetActiveScene().name); 166 } 167} 168

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

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

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

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

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

guest

回答2

0

・原因
オブジェクトのコピペをどの様な手順で行ったのか判りませんがPlayerオブジェクトのタグを"Playercon"に設定出来ていない為、37行目でNullが返されているかと思われます。

・解決法
1.タイムモードのシーンに切り替えてPlayerオブジェクトを選択
2.InspectorからTagをPlayerconにする
3.シーンを保存

これでコメントアウトしている箇所のエラーは消えるのではないでしょうか。

投稿2020/01/15 06:50

編集2020/01/15 10:25
Hawn

総合スコア1222

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

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

退会済みユーザー

退会済みユーザー

2020/01/15 07:06

元のゲームシーンからタイムゲームシーンを新しく作ってオブジェクトそれにコピペしました 確認したのですがプレイヤーコンはインスタンスで出しいてるのでタグは設定できています
Hawn

2020/01/15 07:34 編集

インスタンスで生成している場合はそのオブジェクトが生成される前にコードが実行されてNullエラーが出ています。 生成待ちなどの修正する必要があります。 生成と取得を並列に行うのはバグの温床になるので設計の時点で避けて下さい。
退会済みユーザー

退会済みユーザー

2020/01/15 08:31

なるほど 同じコードで違うシーンだとエラーにならないのはなぜでしょうか?
Hawn

2020/01/15 08:37 編集

キャッシュが出来た後はスクリプト実行順序の違いで差がでます。
退会済みユーザー

退会済みユーザー

2020/01/15 08:41

わかりました キャラ生成をawakeにすると治りました
Hawn

2020/01/15 09:02 編集

Awakeの方がStartより実行が早いのでそれで取り敢えずは直りますね。
guest

0

ベストアンサー

キャラ生成をawakeにして順番変えると治った

投稿2020/01/15 08:41

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Tto777

2020/01/15 08:48

動けば良いという段階かもしれませんがそういう修正は止めた方が良いですよ。
退会済みユーザー

退会済みユーザー

2020/01/15 09:13

そうなんですか? なぜやめといたほうがいいのでしょうか
Y0241-N

2020/01/17 04:56

後にまた同じような問題が発生する可能性が高いからですね。 今回のエラー原因は生成と取得が同時に発生して起きていたようですが、今仮にAwakeでStart前に生成するようにして問題を回避していますよね。 しかし、これはあくまで応急処置であり、今後何らかの都合でAwakeではなくStartもしくは任意のタイミングで初期生成しなければならなくなった場合に同じ問題が発生する可能性は高いですよね。 なので、スクリプトを設計する際は処理の流れを考えながら設計し、変更できるようにしておくことが予期せぬエラーの回避に繋がるので、そういう修正は好ましくないわけです。 横やり失礼しました。
退会済みユーザー

退会済みユーザー

2020/01/17 05:10

どういった方法があるのかヒントもらえないでしょうか 勉強になるのでありがたいです!
Y0241-N

2020/01/17 05:33

例えば、今回のように複数のスクリプトから同じオブジェクトやスクリプトにアクセスすることが予想できるのであれば、取得を一つのスクリプトに任せ、他のスクリプトはあらかじめ取得された物を使用するように設計すれば取得のタイミングによるエラーを防げます。 これはシングルトンと呼ばれる考え方で、「そのゲームオブジェクトがシーンに1つしか存在しないことを保証するための仕組み」となっています。
退会済みユーザー

退会済みユーザー

2020/01/17 05:42

軽く調べてみたのですが難しそうです笑 よく調べてみます 今回の場合キャラ生成と参照が同時になっていたのをシングルトンの考え方を使えばどう言う風になったのでしょうか
Y0241-N

2020/01/17 05:52

先に述べたように、Script1で virtual void Awake(){取得}とし、Script2,3などでoverride void Awake(){base.Awake();}という風にすると実際に取得の処理を行っているのはScript1のみなので取得のタイミングは一つに絞られます。 このオーバーライドをする際にもとのScript1をどのように参照するかは様々ですが、name spaceでusingできるようにしたり、classを継承したりするのがいいんじゃないでしょうか。
退会済みユーザー

退会済みユーザー

2020/01/17 05:57

なるほど オーバーライド勉強では見ましたが調べたことなかったです たくさんの説明ありがとうございます! これからjavaを勉強する機会があるのでそれまでにデザインパターンを見ておきます ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問