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

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

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

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

Unity3D

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

Q&A

解決済

2回答

773閲覧

EditorGUILayoutを他クラスから呼び出すとクラッシュする

lkiuxc

総合スコア29

C#

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

Unity3D

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

0グッド

0クリップ

投稿2020/07/19 19:56

using UnityEngine; using UnityEngine.UI; using UnityEditor.Experimental.GraphView; using System.IO; using System.Reflection; using System.Linq; using System; using Boo.Lang; #if UNITY_EDITOR using UnityEditor; #endif public class ShootInfomationCreate : EditorWindow { const int _MinWidth = 480; const int _MinHeight = 300; const string _SavePath = "Assets/Resources"; // or Script/ScriptableObject //const string _InfomationLoadPath = "Assets/Resources/Infomations/Infomation.asset"; int _ShootPatturn; static System.Collections.Generic.List<Infomation> _InfomationClasses; static string[] _InfomationNames; [MenuItem("Window/WeaponCreate")] static void CreateWindow() { var window = GetWindow<ShootInfomationCreate>(); window.minSize = new Vector2(_MinWidth, _MinHeight); //現在のInfomation継承クラスを全取得 _InfomationClasses = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.BaseType == typeof(Infomation)).ToList().ConvertAll(new Converter<Type, Infomation>(TypeToInfomation)); _InfomationClasses.ForEach(x => { x = (Infomation)ScriptableObject.CreateInstance(x.GetType().Name); }); _InfomationNames = _InfomationClasses.Select(x => x.GetType().Name).ToArray(); } static Infomation TypeToInfomation(Type type) { return (Infomation)Activator.CreateInstance(type); } private void OnGUI() { using (var scope = new GUILayout.VerticalScope()) { _ShootPatturn = EditorGUILayout.Popup(_ShootPatturn, _InfomationNames); //ここでエラー発生、他クラスにてOnGUIのイベントを呼び出そうとしている _InfomationClasses[_ShootPatturn].Input(scope); if (GUILayout.Button("生成")) { string path = _SavePath + "/" + _ShootPatturn.ToString() + "/" + _InfomationClasses[_ShootPatturn].Name + ".asset"; var m = ObjectCreate<Infomation>(path); EditorUtility.SetDirty(m); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } } T ObjectCreate<T>(string path) where T : ScriptableObject { if (!File.Exists(path)) { var i = ScriptableObject.CreateInstance<T>(); AssetDatabase.CreateAsset(i, path); return i; } else { return AssetDatabase.LoadAssetAtPath<T>(path); } } } public enum ShootPatturn { Gerobi, Diffusion, Colmn, }
using System; using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; [Serializable] public class ColmnShootInfomation : Infomation { const float _BeginShotPointLimit = -10f; const float _EndShotPointLimit = 10f; [SerializeField] float _ReloadTime; [SerializeField] bool _IsCharge; [SerializeField] float _ChargeTime; [SerializeField] float _BeginBulletPosition; [SerializeField] float _EndBulletPosition; [SerializeField] float _BulletDistance; public void Initialize(float reload, bool isCharge, float chargeT,float begin,float end,float distance) { _ReloadTime = reload; _IsCharge = isCharge; _ChargeTime = chargeT; _BeginBulletPosition = begin; _EndBulletPosition = end; _BulletDistance = distance; } public override void Initialize(Infomation inf) { var i = (ColmnShootInfomation)inf; _ReloadTime = i._ReloadTime; _IsCharge = i._IsCharge; _ChargeTime = i._ChargeTime; _BeginBulletPosition = i._BeginBulletPosition; _EndBulletPosition = i._EndBulletPosition; _BulletDistance = i._BulletDistance; } //ここで呼び出している public override void Input(GUI.Scope scope) { using (scope) { base.Name = EditorGUILayout.TextField("武装名", base.Name); _ReloadTime = EditorGUILayout.FloatField("リロードにかかる時間", _ReloadTime); _IsCharge = EditorGUILayout.Toggle("チャージがあるか", _IsCharge); if(_IsCharge)_ChargeTime = EditorGUILayout.FloatField("チャージ時間", _ChargeTime); _BeginBulletPosition = EditorGUILayout.Slider("開始位置",_BeginBulletPosition, _BeginShotPointLimit,0); _EndBulletPosition = EditorGUILayout.Slider("終了位置", _EndBulletPosition,0,_EndShotPointLimit); _BulletDistance = EditorGUILayout.Slider("弾の隙間", _BulletDistance, 0, Mathf.Abs(_EndBulletPosition - _BeginBulletPosition)); } } コード

タイトルの通り、他クラスのEditorGUILayoutをOnGUIより呼び出して動かすとクラッシュします。

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

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

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

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

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

guest

回答2

0

自己解決

using UnityEngine; using UnityEngine.UI; using UnityEditor.Experimental.GraphView; using System.IO; using System.Reflection; using System.Linq; using System; using Boo.Lang; #if UNITY_EDITOR using UnityEditor; #endif public class ShootInfomationCreate : EditorWindow { const int _MinWidth = 480; const int _MinHeight = 300; const string _SavePath = "Assets/Resources"; // or Script/ScriptableObject //const string _InfomationLoadPath = "Assets/Resources/Infomations/Infomation.asset"; int _ShootPatturn; static System.Collections.Generic.List<ShootInfomationBase> _InfomationClasses; static string[] _InfomationNames; [MenuItem("Window/WeaponCreate")] static void CreateWindow() { var window = GetWindow<ShootInfomationCreate>(); window.minSize = new Vector2(_MinWidth, _MinHeight); //現在のInfomation継承クラスを全取得 _InfomationClasses = Assembly.GetExecutingAssembly().GetTypes().Where(x => x.BaseType == typeof(ShootInfomationBase)).ToList().ConvertAll(new Converter<Type, ShootInfomationBase>(TypeToInfomation)); _InfomationClasses.ForEach(x => { //こちらで作ったインスタンスによって、PropertyがNullになっていた。そのため今回のエラーが発生した。 x = (ShootInfomationBase)ScriptableObject.CreateInstance(x.GetType().Name); //こちらでNullを解消 x.Initialize(); }); _InfomationNames = _InfomationClasses.Select(x => x.GetType().Name).ToArray(); } static ShootInfomationBase TypeToInfomation(Type type) { return (ShootInfomationBase)Activator.CreateInstance(type); } private void OnGUI() { _ShootPatturn = EditorGUILayout.Popup(_ShootPatturn, _InfomationNames); _InfomationClasses[_ShootPatturn].Input(default); if (GUILayout.Button("生成")) { string path = _SavePath + "/" + _InfomationClasses[_ShootPatturn].GetType().ToString() + "/" + _InfomationClasses[_ShootPatturn].Name + ".asset"; MaskDebug.Log(path); var m = ObjectCreate<ShootInfomationBase>(path); EditorUtility.SetDirty(m); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } T ObjectCreate<T>(string path) where T : ScriptableObject { if (!File.Exists(path)) { var i = ScriptableObject.CreateInstance<T>(); AssetDatabase.CreateAsset(i, path); return i; } else { return AssetDatabase.LoadAssetAtPath<T>(path); } } } public enum ShootPatturn { Gerobi, Diffusion, Colmn, }
using System; using System.Collections; using System.Collections.Generic; using UnityEditor; using UnityEngine; [Serializable] public class ColmnShootInfomation : ShootInfomationBase { const float _BeginShotPointLimit = -10f; const float _EndShotPointLimit = 10f; [SerializeField] float _ReloadTime; [SerializeField] bool _IsCharge; [SerializeField] float _ChargeTime; [SerializeField] float _BeginBulletPosition; [SerializeField] float _EndBulletPosition; [SerializeField] float _BulletDistance; public void Initialize(float reload, bool isCharge, float chargeT, float begin, float end, float distance) { _ReloadTime = reload; _IsCharge = isCharge; _ChargeTime = chargeT; _BeginBulletPosition = begin; _EndBulletPosition = end; _BulletDistance = distance; } public override void Initialize(ShootInfomationBase inf) { var i = (ColmnShootInfomation)inf; _ReloadTime = i._ReloadTime; _IsCharge = i._IsCharge; _ChargeTime = i._ChargeTime; _BeginBulletPosition = i._BeginBulletPosition; _EndBulletPosition = i._EndBulletPosition; _BulletDistance = i._BulletDistance; } public override void Input(GUI.Scope scope) {     //こちらのbase.NameがNullだったため永久に参照をしてクラッシュしていた base.Name = EditorGUILayout.TextField("武装名", base.Name); _ReloadTime = EditorGUILayout.FloatField("リロードにかかる時間", _ReloadTime); _IsCharge = EditorGUILayout.Toggle("チャージがあるか", _IsCharge); if (_IsCharge) _ChargeTime = EditorGUILayout.FloatField("チャージ時間", _ChargeTime); _BeginBulletPosition = EditorGUILayout.Slider("開始位置", _BeginBulletPosition, _BeginShotPointLimit, 0); _EndBulletPosition = EditorGUILayout.Slider("終了位置", _EndBulletPosition, 0, _EndShotPointLimit); _BulletDistance = EditorGUILayout.Slider("弾の隙間", _BulletDistance, 0, Mathf.Abs(_EndBulletPosition - _BeginBulletPosition)); } }

CreateInstanceにて作ったScriptableObject内のプロパティがNullになっていました。そのため永久に参照してしまうためエディタがクラッシュしてしまいました。
Nullを解消することで解決しました。

投稿2020/07/20 03:59

lkiuxc

総合スコア29

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

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

0

ColmnShootInformation.Inputメソッドにスコープオブジェクトを引数として渡している意図が理解できないのですが、何のためなんでしょうか。

usingステートメントは、スコープから抜ける場合にDispose(いわゆる破棄処理)が実行されます。
今回の場合、ColmnShootInformation.Inputメソッドの呼び出し元とメソッドの中で二重にusingスコープしているので、二度破棄処理が行われる事になります。
(それ以前に、おそらく他のIMGUIの処理で暗黙的にスコープオブジェクトが参照されると思うので、ColmnShootInformatino.Inputメソッドから戻った時点で破棄されたスコープオブジェクトを参照する事になるので、それで問題が起きているだと思いますが)

投稿2020/07/19 22:35

katsuko

総合スコア3538

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

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

lkiuxc

2020/07/20 03:44

回答ありがとうございます。 これを引数にしているのはスコープが必要かな・・・・?と思ってのことでした。 今現時点で必要ないとわかっているので消しています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問