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

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

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

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

Unity

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

Q&A

解決済

3回答

2658閲覧

unityでアイテムを集めるとスコアが増えるようにしたいのに増えない

709

総合スコア28

C#

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

Unity

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

0グッド

0クリップ

投稿2019/04/02 11:20

編集2019/04/06 06:50

###何がしたいか
プレイヤーがアイテムを集めると変数「sc_count」を1ずつ増やしcanvas内のtextに「sc_count」を表示させたい
###問題
最初にプレイヤーがアイテムに触れたときは変数が増えるがそれ以降は増えなくなる。

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5public class item : MonoBehaviour 6{ 7 public GameObject target ; 8 public Text scoreLabel; 9 int sc_count; 10 void Start (){ 11 sc_count =0; 12 scoreLabel.text = sc_count.ToString(); 13 } 14 15 16 void OnTriggerEnter (Collider hit) 17 { 18 if (hit.CompareTag ("Player")) 19 { 20 21 Destroy(gameObject); 22//新しくランダムでアイテムを配置する 23 Instantiate (target,new Vector3(UnityEngine.Random.Range(-9.0f,9.0f),0.5f,UnityEngine.Random.Range(-9.0f,9.0f)),Quaternion.identity); 24 sc_count++; 25 scoreLabel.text = sc_count.ToString(); 26 27 28 29 } 30 } 31 32 33} 34

追記

画像
イメージ説明
イメージ説明
Creator.cs

C#

1//変更前 2var script = Instantiate<item>(ItemPrefab, pos, Quaternion.identity); 3//変更後 4var script = Instantiate<item>(ItemPrefab, new Vector3(UnityEngine.Random.Range(-9.0f,9.0f),0.5f,UnityEngine.Random.Range(-9.0f,9.0f)), Quaternion.identity);

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

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

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

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

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

guest

回答3

0

ベストアンサー

[追記] 追記していただいた画像について

どちらも合ってます。Creator.csのコードも問題ありません。

[追記] スコアが9ずつ増えていきます

これは、今分かりません。下記コードで試してみて9つ増えるのであれば言ってください。

[追記] コードを一部修正します。

コード見ました。itemCreatorをstaticにしてましたがstaticは理解するまで使わない方が良いです。といっても慣れた頃には使わない方が良いコードが書けると理解すると思います。今はDataManagerぐらいにしておくのがおすすめです。DataManagerは変えず、下記のような形でどうでしょうか?

itemCreator.cs

C#

1using UnityEngine; 2using System.Collections; 3using System.Collections.Generic; 4 5public class itemCreator : MonoBehaviour 6{ 7 //フォルダに入れたitemをアタッチ 8 public GameObject target; 9 10 void Start() 11 { 12 DataManager.Instance.OnAddScore += OnAddScore; 13 } 14 15 public void Create() 16 { 17 var pos = GetRandomPos(); 18 Instantiate(target, pos, Quaternion.identity); 19 } 20 21 //スコアが加算された時に呼ばれる 22 public void OnAddScore(int score) 23 { 24 //スコアが加算されたので生成 25 Create(); 26 } 27 28 Vector3 GetRandomPos() 29 { 30 return new Vector3( 31 UnityEngine.Random.Range(-9.0f, 9.0f), 32 0.5f, 33 UnityEngine.Random.Range(-9.0f, 9.0f) 34 ); 35 } 36}

item.cs

C#

1 2using UnityEngine; 3 4public class item : MonoBehaviour 5{ 6 void OnTriggerEnter(Collider hit) 7 { 8 if (hit.CompareTag("Player")) 9 { 10 DataManager.Instance.AddScore(100); 11 Destroy(gameObject); 12 } 13 } 14}

過去回答

回答させていいただきます。int sc_countstatic int sc_countに変更し、Startsc_count =0;を削除するとカウントされるはずです。

ただ、あまり良い方法とは言えません。
スコアを管理するスクリプトを用意して、そちらに通知するのが良いと思います。
僕なら下記のようにします。

・DataManager スコアを管理するスクリプト
・ScoreTxt DataManagerのスコアが加算されたら表示するスクリプト
・ItemCreator itemの生成、itemに対して一括処理したい内容(消した時の獲得スコアなど)を記述するスクリプト
・Item 現在のitemスクリプトのスコア関連を無くしたスクリプト

[追記]書いてみました

書いてみたので共有します。参考になりますと幸いです。

DataManager データの管理を担当
DontDestroyOnLoadを付与したシングルトンです。

C#

1using System; 2using UnityEngine; 3 4public class DataManager : MonoBehaviour 5{ 6 //シングルトン化 DataManager.Instanceで何処からでもアクセスできます。 7 public static DataManager Instance 8 { 9 get{ 10 if (_instance == null) 11 { 12 _instance = LoadInstance(); 13 } 14 return _instance; 15 } 16 } 17 static DataManager _instance; 18 19 /// <summary> 20 /// スコアが追加されたのを通知 21 /// </summary> 22 public event Action<int> OnAddScore = delegate {}; 23 24 /// <summary> 25 /// 現在のスコア 26 /// </summary> 27 /// <value>The score.</value> 28 public int Score{ get; private set; } 29 30 void Awake() 31 { 32 if(_instance != null 33 && _instance != this) 34 { 35 Destroy(gameObject); 36 } 37 } 38 39 public void AddScore(int addScore) 40 { 41 //スコアを加算 42 Score += addScore; 43 //通知 44 OnAddScore(Score); 45 } 46 47 /// <summary> 48 /// インスタンスの設定 49 /// </summary> 50 public static DataManager LoadInstance() 51 { 52 var instance = FindObjectOfType<DataManager>(); 53 54 if(instance == null) 55 { 56 var go = new GameObject("DataManager", new []{typeof(DataManager) }); 57 instance = go.GetComponent<DataManager>(); 58 } 59 60 DontDestroyOnLoad(instance.gameObject); 61 return instance; 62 } 63}

ItemCreator アイテムの生成とアイテムに一括処理したい内容を記述

C#

1using UnityEngine; 2 3public class ItemCreator : MonoBehaviour 4{ 5 /// <summary> 6 /// アイテムのPrefabをHierarchyから設置 7 /// </summary> 8 [SerializeField] item ItemPrefab; 9 10 void Awake() 11 { 12 //すでにHierarchyに設置されているitemがあれば初期化します。 13 //FindObjectsOfTypeは重い処理なのであまり使わない方が良いです。 14 foreach (var item in FindObjectsOfType<item>()) 15 { 16 SetUpItem(item); 17 } 18 } 19 20 /// <summary> 21 /// アイテムの生成 22 /// </summary> 23 /// <param name="pos">Position.</param> 24 public void Create(Vector3 pos) 25 { 26 var script = Instantiate<item>(ItemPrefab, pos, Quaternion.identity); 27 //アイテムの初期化 28 SetUpItem(script); 29 } 30 31 /// <summary> 32 /// アイテムの初期化 33 /// </summary> 34 /// <param name="item">Item.</param> 35 void SetUpItem(item item) 36 { 37 //アイテムの初期化 38 item.Initialized(1); 39 item.OnDestroyItem += OnDestroyItem; 40 } 41 42 /// <summary> 43 /// itemが破棄されたタイミングで呼ばれるイベント 44 /// </summary> 45 /// <param name="item">Item.</param> 46 void OnDestroyItem(item item) 47 { 48 //itemが破棄されたのでDataManagerにスコア通知 49 DataManager.Instance.AddScore(item.AddScore); 50 } 51}

ScoreTxt スコアの表示を担当

C#

1using UnityEngine; 2using UnityEngine.UI; 3 4public class ScoreTxt : MonoBehaviour 5{ 6 /// <summary> 7 /// テキストを設定 8 /// </summary> 9 [SerializeField] Text TxtRender; 10 11 void Start() 12 { 13 //初期スコアを設定 14 OnAddScore(DataManager.Instance.Score); 15 16 // スコア追加イベントを受け取る 17 DataManager.Instance.OnAddScore += OnAddScore; 18 } 19 20 /// <summary> 21 /// スコアがカウントされると呼ばれる 22 /// </summary> 23 /// <param name="score">Score.</param> 24 void OnAddScore(int score) 25 { 26 TxtRender.text = score.ToString(); 27 } 28}

item 少々改変しました

C#

1using System; 2using UnityEngine; 3 4public class item : MonoBehaviour 5{ 6 /// <summary> 7 /// itemが削除される際に呼ばれるイベント 8 /// </summary> 9 public event Action<item> OnDestroyItem = delegate {}; 10 11 /// <summary> 12 /// 追加するスコア 13 /// </summary> 14 /// <value>The add score.</value> 15 public int AddScore{ get; private set; } 16 17 public void Initialized(int addScore) 18 { 19 AddScore = addScore; 20 } 21 22 void OnTriggerEnter(Collider hit) 23 { 24 if (hit.CompareTag("Player")) 25 { 26 OnDestroyItem(this); 27 Destroy(gameObject); 28 } 29 } 30 31 void OnDestroy() 32 { 33 //イベントがバインドされている場合、GCに回収されない場合があるので破棄する 34 OnDestroyItem = null; 35 } 36}

投稿2019/04/02 12:04

編集2019/04/06 11:14
IShix

総合スコア1724

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

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

709

2019/04/02 12:32

回答ありがとうございます。 明日試してみます。
709

2019/04/03 11:50 編集

治りました 試してみたのですがこのようなエラーが出ました。 ~~~ You are trying to replace or create a Prefab from the instance 'item' that references a missing script. This is not allowed. Please change the script or remove it from the GameObject. UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr) ~~~
IShix

2019/04/03 17:17

削除したオブジェクトをInstantiateしようとしてエラーになってます。 アタッチしたItem Prefabですが、Hierarchyに設置したItem Prefabを設定していませんか? フォルダに置いたItem Prefabを設定するようにしてください。
709

2019/04/04 11:50

なぜかitemが増えません原因わかりますでしょうか? お手数おかけして申し訳ありません。
IShix

2019/04/04 16:05

なぜ増えないのかの判断できません。 情報もらえませんか?
709

2019/04/06 06:34

エラー NullReferenceException: Object reference not set to an instance of an object ScoreTxt.OnAddScore (System.Int32 score) (at Assets/script/ScoreTxt.cs:26) ScoreTxt.Start () (at Assets/script/ScoreTxt.cs:14)
709

2019/04/06 06:35

警告 DontDestroyOnLoad only work for root GameObjects or components on root GameObjects. UnityEngine.Object:DontDestroyOnLoad(Object) DataManager:LoadInstance() (at Assets/script/DataManager.cs:60) DataManager:get_Instance() (at Assets/script/DataManager.cs:12) ScoreTxt:Start() (at Assets/script/ScoreTxt.cs:14)
709

2019/04/06 06:41

scriptの場所の写真追加します
709

2019/04/06 06:51

情報の追記をしました
709

2019/04/06 07:10

エラーなどは消えました しかしもう一つ問題があったのをわすれていましたなぜかスコアが9ずつ増えていきます
IShix

2019/04/06 10:43

今、回答修正するので少々お待ちください。
IShix

2019/04/06 11:15

追記しました。
709

2019/04/06 11:30

ありがとうございました 無事解決しました
IShix

2019/04/06 11:35

解決できてよかったです。
guest

0

もう分らなかったので初心者なりに頑張りました
itemCreator.cs

C#

1using UnityEngine; 2using System.Collections; 3using System.Collections.Generic; 4public class itemCreator : MonoBehaviour 5{ 6 public static itemCreator Instance 7 { 8 get{ 9 if (_instance == null) 10 { 11 _instance = LoadInstance(); 12 } 13 return _instance; 14 } 15 } 16 static itemCreator _instance; 17 18 public GameObject target ; 19 20 21 public void Create() 22 { 23 24 var pos = new Vector3(UnityEngine.Random.Range(-9.0f,9.0f),0.5f,UnityEngine.Random.Range(-9.0f,9.0f)); 25 26 Instantiate(target, pos, Quaternion.identity); 27 28 29 } 30 public static itemCreator LoadInstance() 31 { 32 var instance = FindObjectOfType<itemCreator>(); 33 34 if(instance == null) 35 { 36 var go = new GameObject("itemCreator", new []{typeof(itemCreator) }); 37 instance = go.GetComponent<itemCreator>(); 38 } 39 40 DontDestroyOnLoad(instance.gameObject); 41 return instance; 42 } 43 44}

item.cs

C#

1using System; 2using UnityEngine; 3 4public class item : MonoBehaviour 5{ 6 /// <summary> 7 /// itemが削除される際に呼ばれるイベント 8 /// </summary> 9 public event Action<item> OnDestroyItem = delegate {}; 10 11 /// <summary> 12 /// 追加するスコア 13 /// </summary> 14 /// <value>The add score.</value> 15 public int AddScore{ get; private set; } 16 17 public void Initialized(int addScore) 18 { 19 AddScore = addScore; 20 } 21 22 void OnTriggerEnter(Collider hit) 23 { 24 if (hit.CompareTag("Player")) 25 { 26 OnDestroyItem(this); 27 Destroy(gameObject); 28 29 itemCreator.Instance.Create(); 30 DataManager.Instance.AddScore(100); 31 } 32 } 33 34 35}

この書き方やっぱあまり良くないですか?

投稿2019/04/06 09:12

編集2019/04/06 09:15
709

総合スコア28

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

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

0

この場合、itemごとにsc_countがカウントされます。
例えば、アイテムAとアイテムBが存在する場合に、アイテムAを取った場合、アイテムAのsc_countは増えますが、その後即座にアイテムAが消えるため、意味ないです(当然、アイテムBのsc_countは増えません)。

アイテムではなく、1つだけ存在する独立したゲームオブジェクトで、スコアを管理してください。

投稿2019/04/02 12:10

fiveHundred

総合スコア9805

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問