Unityで別シーンのオブジェクトにアタッチされているスクリプト内のメソッドを使用したい
ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。
Unityでゲームを作成しています
リザルト画面にゲームのスコアを表示したいので、そのためのメソッドを作成しておりましたが、恐らく別シーンのスクリプトの参照がうまくいっていません
詳しい状況の説明ですが
『シーン_ゲーム画面(昼)』というシーンの「GameControler_Hiru」という空のオブジェクトに、〈GameControl_Hiru〉というスクリプトをアタッチ
『シーン_ゲーム画面(昼)』というシーンの「障害物」というオブジェクトに、〈CabeBig〉というスクリプトをアタッチ
『シーン_リザルト画面』というシーンの「GameControler_Result」というオブジェクトに、〈Result〉というスクリプトをアタッチしております。
やりたいこととしては、『シーン_ゲーム画面(昼)』内で障害物に主人公が当たった場合に、〈CabeBig〉スクリプト内の≪OnCollisionStay2D≫メソッドで〈GameControl_Hiru〉スクリプト内の≪SendScore≫メソッドを呼び出し、≪SendScore≫メソッドで、別シーンの〈Result〉スクリプト内の≪get_score≫メソッドを呼び出しスコアを橋渡ししたいと思っています
発生している問題・エラーメッセージ
NullReferenceException: Object reference not set to an instance of an object GameControl_Hiru.SendScore () (at Assets/スクリプト/ゲーム画面(昼)/GameControl_Hiru.cs:127) CabeBig.OnCollisionStay2D (UnityEngine.Collision2D col) (at Assets/スクリプト/CabeBig.cs:36)
該当のソースコード
C
1CabeBigスクリプト 2 3using System.Collections; 4using System.Collections.Generic; 5using UnityEngine; 6using UnityEngine.SceneManagement; 7 8public class CabeBig : MonoBehaviour 9{ 10 private GameObject player; 11 12 // Start is called before the first frame update 13 void Start() 14 { 15 player = GameObject.Find("プレハブ_紙飛行機"); 16 } 17 18 // Update is called once per frame 19 void Update() 20 { 21 Vector3 playerPos = player.transform.position; 22 Vector3 thisPos = this.transform.position; 23 24 if (playerPos.y - thisPos.y < -4) 25 { 26 Destroy(this.gameObject); 27 } 28 29 } 30 31 void OnCollisionStay2D(Collision2D col) 32 { 33 if (col.gameObject.name == "プレハブ_紙飛行機") 34 { 35 if (SceneManager.GetActiveScene().name == "シーン_ゲーム画面(昼)") 36 { 37 GameObject game_root = GameObject.Find("GameControler_Hiru"); 38 game_root.GetComponent<GameControl_Hiru>().SendScore(); 39 } 40 else 41 { 42 GameObject game_root = GameObject.Find("GameControler"); 43 game_root.GetComponent<GameControl_Yoru>().SendScore(); 44 } 45 } 46 } 47} 48 49-------------------------------------------------------- 50GameControl_Hiruスクリプト 51 52using System; 53using System.Collections; 54using System.Collections.Generic; 55using System.Diagnostics; 56using UnityEngine; 57using UnityEngine.UI; 58using UnityEngine.SceneManagement; 59 60public class GameControl_Hiru : MonoBehaviour 61{ 62 63 public GameObject prefab_cloude; 64 public GameObject prefab_coin; 65 public GameObject prefab_cabe; 66 public GameObject prefab_cabe2; 67 68 public double OldplayerPos; 69 70 private GameObject player; 71 72 private float timer = 0.0f; 73 public int score = 0; 74 public Text textTimer; 75 76 public int Coin = 0; 77 public Text textCoin; 78 79 // Start is called before the first frame update 80 void Start() 81 { 82 player = GameObject.Find("プレハブ_紙飛行機"); 83 Vector3 playerPos = player.transform.position; 84 OldplayerPos = playerPos.y; 85 } 86 87 // Update is called once per frame 88 void Update() 89 { 90 timer += Time.deltaTime; 91 score = (int)timer; 92 textTimer.text = score.ToString(); 93 94 Vector3 playerPos = player.transform.position; 95 96 if (UnityEngine.Random.Range(0, 300) == 0) 97 { 98 CreateCloude(); 99 } 100 101 if (UnityEngine.Random.Range(0, 3000) == 0) 102 { 103 CreateCoin(); 104 105 } 106 107 if (OldplayerPos - playerPos.y >= 4) 108 { 109 CreateCabe(); 110 OldplayerPos = playerPos.y; 111 } 112 113 } 114 115 private void CreateCloude() 116 { 117 118 Vector3 playerPos = player.transform.position; 119 120 GameObject cloude = Instantiate(prefab_cloude); 121 122 cloude.transform.position = new Vector3(UnityEngine.Random.Range(-200, 200) / 100.0f, playerPos.y - 8, 1); 123 124 } 125 126 private void CreateCoin() 127 { 128 129 Vector3 playerPos = player.transform.position; 130 131 GameObject coin = Instantiate(prefab_coin); 132 133 coin.transform.position = new Vector3(UnityEngine.Random.Range(-200, 200) / 100.0f, playerPos.y - 8, 1); 134 135 } 136 137 private void CreateCabe() 138 { 139 140 Vector3 playerPos = player.transform.position; 141 142 int randomValue = UnityEngine.Random.Range(0, 3); 143 144 UnityEngine.Debug.Log(randomValue); 145 146 if (randomValue == 0) 147 { 148 GameObject cabe = Instantiate(prefab_cabe); 149 GameObject cabe2 = Instantiate(prefab_cabe); 150 151 cabe.transform.position = new Vector3(1.59f, playerPos.y - 8 - 0.625f, 0); 152 cabe2.transform.position = new Vector3(-1.59f, playerPos.y - 8 - 0.625f, 0); 153 } 154 else if (randomValue == 1) 155 { 156 GameObject cabe = Instantiate(prefab_cabe2); 157 158 cabe.transform.position = new Vector3(-0.86f, playerPos.y - 8 - 0.625f, 0); 159 } 160 else 161 { 162 GameObject cabe = Instantiate(prefab_cabe2); 163 164 cabe.transform.position = new Vector3(0.86f, playerPos.y - 8 - 0.625f, 0); 165 } 166 } 167 168 public void PlusCoin() 169 { 170 Coin++; 171 textCoin.text = Coin.ToString(); 172 173 } 174 175 public void SendScore() 176 { 177 UnityEngine.Debug.Log(6); 178 GameObject.Find("GameControler_Result").GetComponent<Result>().get_score(score, Coin); 179 UnityEngine.Debug.Log(7); 180 SceneManager.LoadScene("シーン_リザルト画面"); 181 } 182} 183 184-------------------------------------------------------- 185Resultスクリプト 186 187using System; 188using System.Collections; 189using System.Collections.Generic; 190using System.Diagnostics; 191using UnityEngine; 192using UnityEngine.UI; 193using UnityEngine.SceneManagement; 194 195public class Result : MonoBehaviour 196{ 197 198 public int score = 0; 199 private int coin = 0; 200 private int total_score = 0; 201 static private int [] high_score = { 0, 0, 0 }; 202 203 public Text Now_Score; 204 public Text Now_Coin; 205 public Text Now_Total_Score; 206 public Text High_Score1; 207 public Text High_Score2; 208 public Text High_Score3; 209 210 void Start() 211 { 212 213 } 214 215 void Update() 216 { 217 if (Input.GetMouseButtonDown(0) || Input.GetKeyDown("left") || Input.GetKeyDown("a") || Input.GetMouseButtonDown(1) || Input.GetKeyDown("right") || Input.GetKeyDown("d")) 218 { 219 SceneManager.LoadScene("シーン_ゲーム開始画面"); 220 } 221 } 222 223 public void get_score(int a, int b) 224 { 225 score = a; 226 coin = b; 227 score_record(); 228 } 229 230 public void score_record() 231 { 232 total_score = score * (1 + coin); 233 if (total_score > high_score[0]) 234 { 235 high_score[2] = high_score[1]; 236 high_score[1] = high_score[0]; 237 high_score[0] = total_score; 238 } 239 else if (total_score > high_score[1]) 240 { 241 high_score[2] = high_score[1]; 242 high_score[1] = total_score; 243 } 244 else if (total_score > high_score[2]) 245 { 246 high_score[2] = total_score; 247 } 248 } 249}
試したこと
障害物はいくつか種類があるのですが(スクリプトの内容はおおむね同じ)、どの障害物にあたってもうまくいきません
GameControl_Hiruスクリプト内のSendScoreスクリプトを以下のようにしてどこまでちゃんと動いているか確認したところ、
public void SendScore()
{
UnityEngine.Debug.Log(6);
GameObject.Find("GameControler_Result").GetComponent<Result>().get_score(score, Coin);
UnityEngine.Debug.Log(7);
SceneManager.LoadScene("シーン_リザルト画面");
}
デバッグログには6しか表示されませんし、当然シーンも変更されませんでした
public void SendScore()
{
UnityEngine.Debug.Log(6);
//GameObject.Find("GameControler_Result").GetComponent<Result>().get_score(score, Coin);
UnityEngine.Debug.Log(7);
SceneManager.LoadScene("シーン_リザルト画面");
}
としてゲームオブジェクトに触る部分をコメントアウトした場合、6,7ともに表示されシーンも変更されます
よって良くない部分がこの部分であると判断しました
public void SendScore()
{
UnityEngine.Debug.Log(7);
GameObject Go = GameObject.Find("GameControler_Result");
UnityEngine.Debug.Log(8);
Go.GetComponent<Result>().get_score(score, Coin);
UnityEngine.Debug.Log(9);
SceneManager.LoadScene("シーン_リザルト画面");
}
一行で横着したのが良くないと思い以上のようにオブジェクトに触る部分を変更した場合、7,8まで表示されます
‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
恐らくシーンをまたぐのが良くないと思い同じシーン内にTryというスクリプトを新たに作り、それをGameControler_Hiruオブジェクトにアタッチしてみました
Tryスクリプトの内容は以下です
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Try : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
} // Update is called once per frame void Update() { } public void sample1(){ Debug.Log(10); }
}
そのうえでGameControl_Hiruスクリプトを以下のように変更しました
public void SendScore()
{
GameObject.Find("GameControler_Hiru").GetComponent<Try>().sample1();
SceneManager.LoadScene("シーン_リザルト画面");
}
この場合、デバッグログにちゃんと10と出てくれますし、シーン変更もされます
上記から恐らく別シーンのスクリプトに触れるのに問題が発生していると考えます
scoreをstaticにして橋渡ししても、結局別シーンのスクリプトに触れない問題は解決されないので、あくまでメソッドを使ってスコアを橋渡ししたいと思っています
とても初歩的な内容だとは思いますが、やり方をご教授願えればと思います
補足情報(FW/ツールのバージョンなど)
UnityはUnity 2019.4.11f1 (64-bit)というものを使用しています
https://drive.google.com/file/d/15xqjHUvS_VX4qWAgGutcG4wTh6vxsds_/view?usp=sharing
ファイルは上記リンクからダウンロードできます
どうぞよろしくお願いします
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。