前提・実現したいこと
時間経過によって、ブロックの数を増やし、スピードを速くしたいと考えています。
製作途中でエラーが発生したため、解決方法を教えていただきたいです。
この問題が解決した後は、BlockMgrを更に増やしたいと考えています。
発生している問題
一定時間経つと、ブッロクが作れなくなる。
(初めの8秒程度はエラーは発生しません)
エラーコード
MissingReferenceException: The object of type 'GameObject' has been destroyed but you are still trying to access it. Your script should either check if it is null or you should not destroy the object. UnityEngine.Object.Internal_InstantiateSingle (UnityEngine.Object data, UnityEngine.Vector3 pos, UnityEngine.Quaternion rot) (at <10564ed154d647e194bef4aef8878649>:0) UnityEngine.Object.Instantiate (UnityEngine.Object original, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) (at <10564ed154d647e194bef4aef8878649>:0) UnityEngine.Object.Instantiate[T] (T original, UnityEngine.Vector3 position, UnityEngine.Quaternion rotation) (at <10564ed154d647e194bef4aef8878649>:0) BlockMgr2.Update () (at Assets/Scripts/BlockMgr2.cs:51)
該当のソースコード
c#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class BlockMgr : MonoBehaviour 6{ 7 // 生成するBlockオブジェクト 8 public GameObject block; 9 10 // 0になったらBlockオブジェクトを生成 11 float _timer = 0; 12 // トータルの経過時間を保持 13 float _totalTime = 0; 14 // ①ブロック生成回数 15 int _cnt = 0; 16 17 void Start() 18 { 19 20 } 21 22 void Update() 23 { 24 // 経過時間を差し引く 25 _timer -= Time.deltaTime; 26 // トータル時間を加算 27 _totalTime += Time.deltaTime; 28 29 if (_timer < 0) 30 { 31 // 0になったのでBlock生成 32 // BlockMgrの場所から生成 33 Vector3 position = transform.position; 34 // ※上下(±3)のランダムな位置に出現させる 35 position.y = Random.Range(-3, 5); 36 // プレハブをもとにBlock生成 37 GameObject obj = Instantiate(block, position, Quaternion.identity); 38 // Blockオブジェクトの「Block」スクリプトを取得する 39 Block blockScript = obj.GetComponent<Block>(); 40 // 速度を計算して設定 41 // 基本速度100に、経過時間x10を加える 42 float speed = 100 + (_totalTime * 10); 43 blockScript.SetSpeed(-speed); // 左方向なのでマイナス 44 45 // ②生成回数をカウントアップ 46 _cnt++; 47 if (_cnt % 10 < 3) 48 { 49 // 0.1秒後にまた生成する 50 _timer += 0.1f; 51 } 52 else 53 { 54 // 1秒後にまた生成する 55 _timer += 1; 56 } 57 } 58 } 59}
c#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class BlockMgr2 : MonoBehaviour 6{ 7 // 生成するBlockオブジェクト 8 public GameObject block; 9 10 // 0になったらBlockオブジェクトを生成 11 float _timer = 0; 12 // トータルの経過時間を保持 13 float _totalTime = 0; 14 // ①ブロック生成回数 15 int _cnt = 0; 16 17 18 19 bool _isStart = false; 20 21 void Start() 22 { 23 Invoke("second", 3); 24 } 25 26 void second() 27 { 28 _isStart = true; 29 } 30 31 32 void Update() 33 { 34 if (!_isStart) 35 { 36 return; 37 } 38 // 経過時間を差し引く 39 _timer -= Time.deltaTime; 40 // トータル時間を加算 41 _totalTime += Time.deltaTime; 42 43 if (_timer < 0) 44 { 45 // 0になったのでBlock生成 46 // BlockMgrの場所から生成 47 Vector3 position = transform.position; 48 // ※上下(±3)のランダムな位置に出現させる 49 position.y = Random.Range(-3, 5); 50 // プレハブをもとにBlock生成 51 GameObject obj = Instantiate(block, position, Quaternion.identity); 52 // Blockオブジェクトの「Block」スクリプトを取得する 53 Block blockScript = obj.GetComponent<Block>(); 54 // 速度を計算して設定 55 // 基本速度100に、経過時間x10を加える 56 float speed = 100 + (_totalTime * 10); 57 blockScript.SetSpeed(-speed); // 左方向なのでマイナス 58 59 // ②生成回数をカウントアップ 60 _cnt++; 61 if (_cnt % 10 < 3) 62 { 63 // 0.1秒後にまた生成する 64 _timer += 0.1f; 65 } 66 else 67 { 68 // 1秒後にまた生成する 69 _timer += 1; 70 } 71 } 72 } 73} 74
c#
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5// ブロック 6public class Block : MonoBehaviour 7{ 8 Rigidbody2D _rigidbody; 9 float _speed = -100; // 移動速度 10 11 void Start() 12 { 13 // 物理挙動コンポーネントを取得 14 _rigidbody = GetComponent<Rigidbody2D>(); 15 // 力を加える 16 _rigidbody.AddForce(new Vector2(_speed, 0)); 17 18 } 19 20 void Update() 21 { 22 Vector2 position = transform.position; 23 if (position.x < GetLeft()) 24 { 25 Destroy(gameObject); // 画面外に出たので消す. 26 } 27 } 28 29 float GetLeft() 30 { 31 // 画面の左下のワールド座標を取得する 32 Vector2 min = Camera.main.ViewportToWorldPoint(Vector2.zero); 33 return min.x; 34 } 35 36 public void SetSpeed(float speed) 37 { 38 _speed = speed; 39 } 40 41 42}
###追記(Block.cs)
Block.csのUpdate関数内のdestroyを削除したらエラーは起こりませんでした。
c#
1void Update() 2 { 3 Vector2 position = transform.position; 4 if (position.x < GetLeft()) 5 { 6 //Destroy(gameObject); // 画面外に出たので消す. 7 } 8 }
補足情報(FW/ツールのバージョンなど)
unity20203.1f1
エラーメッセージを読みましょう。「Destroyされたオブジェクトにアクセスしようとしている」というエラーが「at Assets/Scripts/BlockMgr2.cs:51」、つまりBlockMgr2の51行目で起こっています。
その行を見るに「block」がどこかでDestroyしていそうです。対象のオブジェクトが最初からシーン上にありBlockクラスUpdate内Destroyで消えている可能性が高そうですがどうなっていますか? 他の理由で消えていたりしませんか?
追記に書かせていただきました。
ただ、重くなるとは思うので思うので、別の方法で画面外に出た場合のブロック削除方法を教えていただきたいです。
回答1件
あなたの回答
tips
プレビュー