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

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

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

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

Q&A

1回答

1966閲覧

Unity2DのゲームアプリでBGMと複数SEを併用した際に起こるバグについてのご相談

naki888

総合スコア12

C#

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

0グッド

0クリップ

投稿2020/07/09 06:06

前提・実現したいこと

UnityでC#を使用し、参考書を見ながらゲームアプリを作成しています。

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

GameSceneのなかでBGMと3つのSE(スクリプトから操作しようと考えています)をゲーム中に鳴らそうとしたところ、BGMはなるのですが、SEの部分がプログラムの中でバグとして扱われ、ゲームの進行が中断されてしまいます。

AudioClip getScoreSEを鳴らす際のバグは、タッチしてもアプリが反応せず、アイテムが取れなくなります。
if文の中にAudioClip getScoreSEの文を移しても、音はならず、アイテムのカウントがされません。

AudioClip levelUpSEの時点で煙のエフェクトが出ている段階でエラーで画面が停止してしまいます。

大変お手数ですがご教示いただければ幸いです。

エラーメッセージ

NullReferenceException:Object reference not set to an instance of an object

該当のソースコード

下記該当コードをソースコードから抜粋します

public AudioClip getScoreSE; public AudioClip levelUpSE; public AudioClip clearSE; private AudioSource audioSource;

//こちらのAudioSourceにはUnityの方で別途BGMをクリップを設定しています。

void Start()
{
audioSource = this.gameObject.GetComponent<AudioSource>();
currentOrb = 10;

public void GetOrb(int getScore)
{

audioSource.PlayOneShot(getScoreSE); if (score < nextScore) { score += getScore; void TempleLevelUpEffect() { GameObject smoke = (GameObject)Instantiate(smokePrefab); smoke.transform.SetParent(canvasGame.transform, false); smoke.transform.SetSiblingIndex(2); audioSource.PlayOneShot(levelUpSE);

void ClearEffect()
{
GameObject kusudama = (GameObject)Instantiate(kusudamaPrefab);
kusudama.transform.SetParent(canvasGame.transform, false);

audioSource.PlayOneShot(clearSE);

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using System; 6 7public class GameManager : MonoBehaviour 8{ 9 private const int MAX_ORB = 10; 10 private const int RESPAWN_TIME = 1; 11 private const int MAX_LEVEL = 2; 12 13 public GameObject orbPrefab; 14 public GameObject smokePrefab; 15 public GameObject kusudamaPrefab; 16 public GameObject canvasGame; 17 public GameObject textScore; 18 public GameObject imageTemple; 19 20 public AudioClip getScoreSE; 21 public AudioClip levelUpSE; 22 public AudioClip clearSE; 23 24 25 private int score = 0; 26 private int nextScore = 10; 27 28 private int currentOrb = 0; 29 private int templeLevel = 0; 30 31 32 private DateTime lastDateTime; 33 34 private int[] nextScoreTable = new int[] { 10, 100, 1000 }; 35 36 private AudioSource audioSource; 37 38 39 40 // Start is called before the first frame update 41 void Start() 42 { 43 audioSource = this.gameObject.GetComponent<AudioSource>(); 44 currentOrb = 10; 45 46 for(int i = 0; i < currentOrb; i++) 47 { 48 CreateOrb(); 49 } 50 lastDateTime = DateTime.UtcNow; 51 52 nextScore = nextScoreTable[templeLevel]; 53 imageTemple.GetComponent<TempleManager>().SetTemplePicture(templeLevel); 54 imageTemple.GetComponent<TempleManager>().SetTempleScale(score, nextScore); 55 56 57 RefreshScoreText(); 58 } 59 60 // Update is called once per frame 61 void Update() 62 { 63 if(currentOrb < MAX_ORB) 64 { 65 TimeSpan timeSpan = DateTime.UtcNow - lastDateTime; 66 if(timeSpan >= TimeSpan.FromSeconds(RESPAWN_TIME)) 67 { 68 while(timeSpan >= TimeSpan.FromSeconds(RESPAWN_TIME)) 69 { 70 CreateNewOrb(); 71 timeSpan -= TimeSpan.FromSeconds(RESPAWN_TIME); 72 } 73 } 74 } 75 76 77 } 78 79 public void CreateNewOrb() 80 { 81 lastDateTime = DateTime.UtcNow; 82 if(currentOrb >= MAX_ORB) 83 { 84 return; 85 } 86 CreateOrb(); 87 currentOrb++; 88 89 } 90 91 92 public void CreateOrb() 93 { 94 GameObject orb = (GameObject)Instantiate(orbPrefab); 95 orb.transform.SetParent(canvasGame.transform, false); 96 orb.transform.localPosition = new Vector3(UnityEngine.Random.Range(-300.0f, 300.0f), UnityEngine.Random.Range(-140.0f, -500.0f)); 97 98 int kind = UnityEngine.Random.Range(0, templeLevel + 1); 99 switch (kind) 100 { 101 case 0: 102 orb.GetComponent<OrbManager>().SetKind(OrbManager.ORB_KIND.BLUE); 103 break; 104 case 1: 105 orb.GetComponent<OrbManager>().SetKind(OrbManager.ORB_KIND.GREEN); 106 break; 107 case 2: 108 orb.GetComponent<OrbManager>().SetKind(OrbManager.ORB_KIND.PURPLE); 109 break; 110 111 112 } 113 114 } 115 public void GetOrb(int getScore) 116 { 117 118 audioSource.PlayOneShot(getScoreSE); 119 120 if (score < nextScore) 121 { 122 score += getScore; 123 124 125 if (score > nextScore) 126 { 127 score = nextScore; 128 } 129 130 TempleLevelUp(); 131 RefreshScoreText(); 132 imageTemple.GetComponent<TempleManager>().SetTempleScale(score, nextScore); 133 134 if ((score == nextScore) && (templeLevel == MAX_LEVEL)) 135 { 136 ClearEffect(); 137 } 138 } 139 140 currentOrb--; 141 } 142 143 void RefreshScoreText() 144 { 145 textScore.GetComponent<Text>().text = "徳:" + score + "/" + nextScore; 146 } 147 148 void TempleLevelUp() 149 { 150 if(score >= nextScore) 151 { 152 if(templeLevel < MAX_LEVEL) 153 { 154 templeLevel++; 155 score = 0; 156 157 TempleLevelUpEffect(); 158 159 nextScore = nextScoreTable[templeLevel]; 160 imageTemple.GetComponent<TempleManager>().SetTemplePicture(templeLevel); 161 } 162 } 163 } 164 void TempleLevelUpEffect() 165 { 166 GameObject smoke = (GameObject)Instantiate(smokePrefab); 167 smoke.transform.SetParent(canvasGame.transform, false); 168 smoke.transform.SetSiblingIndex(2); 169 170 audioSource.PlayOneShot(levelUpSE); 171 172 Destroy(smoke, 0.5f); 173 } 174 void ClearEffect() 175 { 176 GameObject kusudama = (GameObject)Instantiate(kusudamaPrefab); 177 kusudama.transform.SetParent(canvasGame.transform, false); 178 179 audioSource.PlayOneShot(clearSE); 180 } 181 182} 183

試したこと

対応策1
AudioclipはGameManagerに紐づいているので

AudioClip getScoreSE = this.GetComponent<GameManager>().getScoreSE;
this.GetComponent<GameManager>().PlayOneShot(getScoreSE);

とコードを変更しましたが変化はありませんでした。

対応策2
Audioclipは最初から音楽生成機能を持つAudiosourceに紐づけられるものとして

AudioClip getScoreSE = this.GetComponent<AudioSource>().getScoreSE;
this.GetComponent<AudioSource>().PlayOneShot(getScoreSE);

としましたが変化はありませんでした。

対応策3
空のAudiosource2を作成し、SE分だけそちらに付け替えましたが、Audiosourceの方に判定がいき、効果ありませんでした。

対応策4
audioSource.PlayOneShot(getScoreSE);にボリュームの値を追加しましたが変化ありませんでした。

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

Unity 2019 4.1f

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

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

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

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

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

sakura_hana

2020/07/10 03:04

エラー文の中にエラーが発生している箇所が書かれているのでそこを確認してください。(「〜.cs:数字」となっていて数字は行数を指す) NullReferenceExceptionについては以下を確認してください。 https://docs.unity3d.com/ja/current/Manual/NullReferenceException.html teratail内を検索するだけでも同じ質問が沢山出て来るはずなのでそれを参考にnullの箇所を調べてください。
naki888

2020/07/13 00:22

承知いたしました。確認します。ご回答ありがとうございます。
naki888

2020/07/14 01:41

確認した結果、audioSource.PlayOneShot(getScoreSE); audioSource.PlayOneShot(levelUpSE); audioSource.PlayOneShot(getScoreSE); でエラーが発生しています。 これらはGameManagerスクリプトprivateでAudioClip型として定義しています。 GameManagerの子にAudioSource(BGM付き)をつけていてもNULLが出るということはもう一つAudioSourceを作らなければいけないということなのでしょうか。
naki888

2020/07/14 01:44

もう1度記載しますがBGMの方はなります。BGMと一緒に鳴らそうとしているSEがならないので、AudioSourceにBGMをアタッチして、SEを流そうとするのが間違っているのかなどをお教えいただきたいのです。
sakura_hana

2020/07/14 02:19

AudioSourceが付いているのが「GameManagerの子」なら、 audioSource = this.gameObject.GetComponent<AudioSource>(); では取得出来ない(nullになる)のでそれが原因だと思います。 (これだと「GameManagerと同じGameObjectに付いているAudioSource」を取得しようとします) BGMが元々セットされているClipをPlayOnAwakeで流しているなら、スクリプトとは無関係に動作するのでBGMは正常に流れるのは自然な動きです。
naki888

2020/07/14 02:52

承知いたしました。ありがとうございます。 オブジェクト2つとaudioSourceを2個使用してアタッチしたBGM用とインスペクターは空のSE用に分けたら解決しました。SE用のものは空のため3種類のSEを流すことができました。
guest

回答1

0

(質問への追記・修正の依頼より)

AudioSourceが付いているのが「GameManagerの子」なら
audioSource = this.gameObject.GetComponent<AudioSource>();
では取得出来ない(=nullになる)のでそれが原因です。
(このコードでは「GameManagerと同じGameObjectに付いているAudioSource」を取得しようとします)

投稿2020/07/14 05:48

sakura_hana

総合スコア11427

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問