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

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

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

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

Unity

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

Q&A

解決済

1回答

16287閲覧

自作クラス(MonoBehavior)の呼び出しの扱いについて。

MOTOMUR

総合スコア195

C#

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

Unity

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

0グッド

0クリップ

投稿2020/06/01 11:05

下記のようなクラス(中にはメンバとそれへのget,setのみ)をインスタンス化するときに、エラーではなく注意ですが、
You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all
UnityEngine.MonoBehaviour:.ctor()
と表示されます。

これについては検索して、MonoBehavior継承してたら
GameObject.Find("オブジェクト").GetComponent<AllyMemberStatus>();
でもってこないとだめだということはわかりました。

AllyMemberStatus.cs

1public class AllyMemberStatus : MonoBehaviour 2{ 3 public string charactorName = " "; 4 public string CharactorID; 5 public int level = 1; 6 public JobType.JobKind jobType = JobType.JobKind.戦士; 7 public JobType.JobName jobName = JobType.JobName.戦士; 8 public WeaponEnum.AllWeapon equipWeapon; 9 10 11 public int earnedExperience = 0; 12 public int nextLvUpExperience = 0; 13 14 public int maxHP = 100; 15 public int nowHP = 100; 16 public int maxMP = 30; 17 public int nowMP = 30; 18 public int ATK = 20; 19 public int DEF = 10; 20 public int INT = 15; 21 public int MND = 10; 22 public int DEX = 10; 23 public int AGI = 10; 24 public int CRI = 5; 25 26 27 public bool isPoisonState = false; 28 public bool isNumbnessState = false; 29 public bool isSelected = false; 30 31 public void SetCharactorName(string CharactorName) 32 { 33 charactorName = CharactorName; 34 } 35 36 public string GetCharactorName() 37 { 38 return charactorName; 39 } 40//以下セットとゲットのみ

しかし、個人的な使いやすさとしては、これをこのままインスタンスのように使いたい。

MasterData.cs

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class MasterData : MonoBehaviour 6{ 7 public static AllyMemberStatus[] AllyMemberStatusArray; //冒険者パーティー。一覧。 8 public static AllyMemberStatus[] AllyMemberSelectedArray;//パーティ選出メンバー管理用。 9 public static bool InitialGame = true; 10 11 12 public static void InitialSetAllyMember() { 13 var AllyMemberStatusList = new List<AllyMemberStatus>(); 14 if (InitialGame) 15 { 16 Debug.Log("initial setされたよ"); 17 AllyStatus a1 = Resources.Load<AllyStatus>("AllyStatus/いち/1"); 18 AllyMemberStatus aa1 = a1.GetAllyMemberStatus(); 19 AllyStatus a2 = Resources.Load<AllyStatus>("AllyStatus/に/1"); 20 AllyMemberStatus aa2 = a2.GetAllyMemberStatus(); 21 AllyMemberStatusArray = new AllyMemberStatus[2] { aa1, aa2 }; 22 AllyMemberSelectedArray = new AllyMemberStatus[2] { aa1, aa2 }; 23 InitialGame = false; 24 Debug.Log(AllyMemberSelectedArray[0].GetCharactorName()); 25 Debug.Log(AllyMemberSelectedArray[1].GetCharactorName()); 26 } 27 } 28 29 30 31 void Start() 32 { 33 //InitialSetAllyMember(); 34 DontDestroyOnLoad(this); 35 } 36 37 38 39 void Update() 40 { 41 42 } 43} 44

このコードのAllyMemberStatus aa1 = a1.GetAllyMemberStatus();
の部分をGameObject.Find("オブジェクト").GetComponent<AllyMemberStatus>();にしないとずっと注意されるので直したいのですが、
インスタンスとして使えるAllyMemberStatusを作成したつもりだったので、使い勝手が悪い。
AllyMemberStatus内にインスタンスできるようにされにpublic void class AllyMemberStatusInnerなどを作って、今のAllyMemberStatusの中身をすべてInnerに入れれば

allyMemberStatus=GameObject.Find("オブジェクト").GetComponent<AllyMemberStatus>(); allyMemberStatus.AllyMemberStatusInner aa1 =a1.GetAllyMemberStatus();

と呼び出せるので、注意書きがなくなるのはわかるのですが、ほかのコードファイルにも影響している部分なので書き直しは面倒。。

こういう場合、ほかの賢い手法があるのかそれとも、あきらめて上のようにやればいいのかアドバイスが欲しいです。
よろしくお願いいたします。

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

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

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

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

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

fiveHundred

2020/06/01 12:00

そもそも、newとGameObject.Find("オブジェクト").GetComponent<AllyMemberStatus>();を同列として扱っていること自体、考え方としておかしいです。 newは新しいインスタンスを生成するものであり、Instantiate()やAddComponent<>();がそれに近いです。 一方で、GameObject.Find("オブジェクト").GetComponent<AllyMemberStatus>();は「オブジェクト」というゲームオブジェクトのAllyMemberStatusを取得する、という意味です。 あらかじめ用意しているものを参照するというものなので、新しく生成するnewとは全くの別物です。
guest

回答1

0

ベストアンサー

MonoBehaviourを継承しなければいいです。
public class AllyMemberStatus { }
こんな感じにしておけば普通にnew出来ます。

MonoBehaviourを継承しない場合、そのスクリプトをGameObjectに付与出来なくなります。
結果的にgameObjecttransformGetComponent(前に何も付けない用法)といった「暗黙的に自分のGameObjectを参照する変数やメソッド」が使えなくなります。

一方で別スクリプトから、特定のGameObjectへの参照を与えることは可能です。
(以下一例。「こういうことも出来る」というだけでこれが適しているかは別問題)

C#

1public class AllyMemberStatus { 2 public Text myText; 3 4 public void Test() { 5 myText.text = "aaa"; 6 } 7} 8 9//呼び出し側クラスにて 10AllyMemberStatus aa2 = new AllyMemberStatus(); 11Text myText = GetComponent<Text>(); 12aa2.myText = myText; 13aa2.Test();

投稿2020/06/02 01:34

編集2020/06/02 03:05
sakura_hana

総合スコア11427

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

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

MOTOMUR

2020/06/02 02:38

MonoBehaviorを外すとエラーになったのでUnityのスクリプトは全てMonoBehaviorを継承しなくてはいけないのかと勘違いしていました。とあるオブジェクトにアタッチしていたからエラーになってたけなんですね。。。 ちなみにMonoBehaviorを継承してなくてもどこかのGameObjectの例えばTextとかに代入するのは問題ないですよね?? (MonoBehaviorを継承していないだけですよね?Unity特有のMonoBehaviorとかScriptableObjectを継承していないクラスを作成したことがないたUnity上で動作するかわからないため確認です。)
sakura_hana

2020/06/02 03:06

語弊あったので回答を修正しました。 「Textとかに代入する」の意味が分かりません。(Textクラスの変数にはTextクラスを継承しているクラスでないと入りません) やりたいことは正確に表記してください。 当然ですが以下のようなことは可能です。(まず一度自分でやってみるといいと思います) AllyMemberStatus aa2 = new AllyMemberStatus(); Text myText = GetComponent<Text>(); myText.text = aa2.charactorName;
MOTOMUR

2020/06/02 12:30

「textとかに代入する」話を略しすぎました。 sakura_hanaさんの回答の意味です。汲み取っていただきありがとうございます。家に帰ってきて試してみましたが、問題なく動作しますね!ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問