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

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

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

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

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

Q&A

解決済

1回答

1997閲覧

Unity:ScriptableObjectを使用し、データをスクリプトから取得したい

covakaiser

総合スコア3

C#

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

Null

Nullとは、プログラミング言語やデータベースにおけるデータ表現の一種です。コンテキストによって"空"もしくは"長さ0の文字列"、”未知・不明”を意味します。

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Unity

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

0グッド

0クリップ

投稿2021/12/22 20:29

編集2021/12/23 07:08

前提・実現したいこと

unityの勉強も兼ねて、格闘ゲームを製作しています。

5人の登場人物1人1人に別のステータスを設定(ジャンプ特化のキャラ、攻撃力特化のキャラのようなイメージ)したく、ScriptableObjectを使用しました。

具体的な実装方法として、
1:キャラクター選択した際、キャラクター1=number(1)のような感じで、変数numberが保存される。
2:変数numberの値によって、取得するScriptableObject(データ)が変わる
という方法です。

しかし、タイトルの通りすぐにNullのエラーが発生してしまいます。

そこで、ScriptableObjectからのデータの取得方法が間違っているのではと考えました。
正しい取得方法やもっと良い実装方法があれば教えていただきたいです。

以下、ソースコードです。明らかに質問と関係のない部分は省いています。
拙いコードですがご教授いただければ幸いです。

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

NullReferenceException: Object reference not set to an instance of an object PlayerController.Movement () (at Assets/Scripts/PlayerController.cs:42) PlayerManager.Update () (at Assets/Scripts/PlayerManager.cs:55)

該当のソースコード

###ScriptableObject

C#

1public class FighterModel 2{ 3 public float at; 4 public float df; 5 public float moveJump; 6 public float moveSpeed; 7 8 public FighterModel(int fighterID) 9 { 10 FighterEntity fighterEntity = Resources.Load<FighterEntity>("FighterEntity" + fighterID); 11 12 at = fighterEntity.Attack; 13 df = fighterEntity.Defence; 14 moveJump = fighterEntity.MoveJump; 15 moveSpeed = fighterEntity.MoveSpeed; 16 } 17} 18

###エラーが出たソースコード

C#

1public class PlayerManager : MonoBehaviour 2{ 3 //動きに関する処理 4 PlayerController pc; 5 6 //Playerのデータ 7 public FighterModel model; 8 GameManager gameManager; 9 10 private void Awake() 11 { 12 pc = GetComponent<PlayerController>(); 13 } 14 // Start is called before the first frame update 15 void Start() 16 { 17 SetUp(); 18 } 19 //キャラクターのステータス取得 20 void SetUp() 21 { 22 switch (PlayerPrefs.GetInt("Data")) 23 { 24 case 0: 25 model = new FighterModel(0); 26 Debug.Log(model.moveJump); 27 Debug.Log(model.moveSpeed); 28 break; 29 case 1: 30 model = new FighterModel(1); 31 break; 32 case 2: 33 model = new FighterModel(2); 34 break; 35 case 3: 36 model = new FighterModel(3); 37 break; 38 } 39 } 40 // Update is called once per frame 41 void Update() 42 { 43 pc.Movement(); //エラー箇所 44 } 45} 46

C#

1public class PlayerController : MonoBehaviour 2{ 3 //data 4 public FighterModel model; 5 PlayerManager playerManager; 6 7 CharacterController characterController; 8 Vector3 moveDirection; 9 10 private void Awake() 11 { 12 characterController = GetComponent<CharacterController>(); 13 capsuleCollider = GetComponent<CapsuleCollider>(); 14 playerManager = GetComponent<PlayerManager>(); 15 } 16 //jump,横移動 17 public void Movement() 18 { 19 float z = Input.GetAxis("Horizontal"); 20 21 if (characterController.isGrounded) 22 { 23 //横方向の移動 24 moveDirection = new Vector3(0, 0, -z * model.moveSpeed); //エラー箇所 25 animator.SetFloat("speed", Mathf.Abs(z)); 26 27 //jump 28 if (Input.GetKeyDown(KeyCode.Space)) 29 { 30 //animator.SetTrigger("jump"); 31 moveDirection.y = model.moveJump; 32 } 33 } 34 moveDirection.y -= 10 * Time.deltaTime; 35 36 characterController.Move(moveDirection * Time.deltaTime); 37 } 38} 39

###キャラクター選択時のスクリプト

C#

1public class CharaSelect : MonoBehaviour 2{ 3 public int N; 4 5 public void SelectImage(int number) 6 { 7 N = number; 8 switch(N) 9 { 10 case 0 : 11 PlayerPrefs.SetInt("Data",N); //どのキャラクターを選択したか別のスクリプトでもつかえるようにする 12 selectText.text = "1人目"; 13 Debug.Log(N); 14 break; 15 16 case 1: 17 PlayerPrefs.SetInt("Data", N); 18 selectText.text = "2人目"; 19 break; 20 case 2: 21 PlayerPrefs.SetInt("Data", N); 22 selectText.text = "3人目"; 23 break; 24 case 3: 25 PlayerPrefs.SetInt("Data", N); 26 selectText.text = "4人目"; 27 break; 28 } 29 } 30} 31

試したこと

Debug.Logを使用し、データを取得できているか確認したところ初めの数秒は取得できていることが確認できた。
Update()でSetUp()を呼び出してみたところ変わらず、Start()で呼び出した場合と同様の結果が得られた。

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

unityバージョンは2020.2.7f1 を使用しております。
Udemyの講座を受講していたところ、ScriptableObjectを拝見し、実際に使用してみようと思い、使用しました。

以下、unity入門の森では、Inspector上に直接ScriptableObjectを設定していました。できるだけ、スクリプト上で完結させたかったので、こちらの方法は使用しておりません。

###主に参考にしたサイト
unty入門の森
https://3dunity.org/game-create-lesson/clicker-game/adding-clicker-items/

Udemy
https://www.udemy.com/share/1028PK3@mPf48vwoXdYWN6jtWqNSxncdyjDi0rxtb7_4Nsq0tL2mXc4l3wJ9V8RuwI90Xy7qDw==/

【Unity】今更ScriptableObject入門
https://qiita.com/4_mio_11/items/a7d8967b853cef4385cd

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

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

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

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

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

guest

回答1

0

ベストアンサー

C#

1 model = new FighterModel(0);

上記はPlayerManagerで行われているため、PlayerManagerのmodelに格納されています。
にもかかわらず、

C#

1 moveDirection = new Vector3(0, 0, -z * model.moveSpeed); //エラー箇所

上記はPlayerControllerで行われているため、PlayerControllerのmodelを参照していることになり、正しくありません。
PlayerManagerのmodelとPlayerControllerのmodelは別の変数なので、PlayerManagerのmodelに代入しても、PlayerControllerのmodelには一切反映されません。

投稿2021/12/23 07:27

編集2021/12/23 07:30
fiveHundred

総合スコア9803

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

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

covakaiser

2021/12/23 09:37

言われるまで全く気付きませんでした、、、 moveDirection = new Vector3(0, 0, -z * playerManager.model.moveSpeed); とすることで無事解決しました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問