UnityEditor 확장 필드로 보존된 사용자 정의 클래스의 개인 필드에 대한 액세스 정보: 메모
거치다
단원 편집기 확장에서 여러 가지 편리한 기능을 만들려고 시도할 때, 구성 요소 필드에 사용자 정의 클래스가 있다면, 검사기에서 사용자 정의 클래스의 개인 구성원을 조작할 때의 주석
다음 스크립트 예시 샘플 클래스의 hoge 필드에 직접 접근하고 싶어도private 구성원이기 때문에 직접 조작할 수 없습니다
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Sample
{
/// <summary>
/// サンプルクラス.
/// </summary>
public class Sample : MonoBehaviour
{
/// <summary>
/// 何かしらのデータクラス.
/// </summary>
[System.Serializable]
public class HogeParam
{
[SerializeField] int id;
public int Id => id;
public HogeParam(
int argId)
{
id = argId;
}
}
[SerializeField] string characterName;
[SerializeField] HogeParam hoge;
#if UNITY_EDITOR
[CustomEditor(typeof(Sample))]
class SampleEditor : Editor
{
public override void OnInspectorGUI()
{
var component = target as Sample;
EditorGUILayout.LabelField("エディタ拡張だべ");
component.characterName = EditorGUILayout.TextField("キャラ名", component.characterName);
// privateなメンバなためアクセスできない,プロパティもゲッターのみなので値のセットはできない.
//component.hoge.Id = EditorGUILayout.IntField("ID", component.hoge.Id);
}
}
#endif
}
}
RTA 플레이어의 가장 빠른 해결 방법
가장 빠른 해결 방법은 HogeParam 클래스의 구성원 필드를public로 설정하거나public 속성을 사용하여 외부에서 접근하는 것이다
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace Sample
{
/// <summary>
/// サンプルクラス.
/// </summary>
public class Sample : MonoBehaviour
{
/// <summary>
/// 何かしらのデータクラス.
/// </summary>
[System.Serializable]
public class HogeParam
{
[SerializeField] int id;
public int Id
{
get { return id; }
set { id = value; }
}
public HogeParam(
int argId)
{
id = argId;
}
}
[SerializeField] string characterName;
[SerializeField] HogeParam hoge;
#if UNITY_EDITOR
[CustomEditor(typeof(Sample))]
class SampleEditor : Editor
{
public override void OnInspectorGUI()
{
var component = target as Sample;
EditorGUILayout.LabelField("エディタ拡張だべ");
component.characterName = EditorGUILayout.TextField("キャラ名", component.characterName);
component.hoge.Id = EditorGUILayout.IntField("ID", component.hoge.Id);
}
}
#endif
}
}
공공영역을 갖고 싶지 않은 사람들의 해결책
어떤 사람들은 장소를 공공장소로 바꾸는데, 너무 황당하다.속성에서 자유롭게 외부에서 조작할 수 없는 파라미터를 만들고 싶다!그러나 Inspector 확장을 보면 작업을 원하는 경우도 있으므로 C#의 반사를 이용하여 문제를 해결할 수 있습니다.
using UnityEngine;
#if UNITY_EDITOR
using System.Reflection;
using UnityEditor;
#endif
namespace Sample
{
/// <summary>
/// サンプルクラス.
/// </summary>
public class Sample : MonoBehaviour
{
/// <summary>
/// 何かしらのデータクラス.
/// </summary>
[System.Serializable]
public class HogeParam
{
[SerializeField] int id;
public HogeParam(
int argId)
{
id = argId;
}
}
[SerializeField] string characterName;
[SerializeField] HogeParam hoge;
#if UNITY_EDITOR
[CustomEditor(typeof(Sample))]
class Class1Editor : Editor
{
public override void OnInspectorGUI()
{
var component = target as Sample;
EditorGUILayout.LabelField("エディタ拡張だべ");
component.characterName = EditorGUILayout.TextField("キャラ名", component.characterName);
EditorGUILayout.LabelField("Hoge");
EditorGUI.indentLevel++;
// Reflectionを利用してパラメータを操作.
{
System.Type fieldType = component.hoge.GetType();
FieldInfo fieldInfo = fieldType.GetField("id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
int tempId = (int)fieldInfo.GetValue(component.hoge);
fieldInfo.SetValue(component.hoge, (int)EditorGUILayout.IntField("ID", tempId));
}
EditorGUI.indentLevel--;
}
}
#endif
}
}
검사기에서 사용자 정의 클래스 내부의 개인 구성원에 성공적으로 접근
후기
Reflection은 편리하지만 남용하면 원본의 가독성과 원래의 접근 제한이 의미가 없기 때문에 저는 개인적으로 게임 논리 정편에서 사용하고 남용하지 않는 것이 좋다고 생각합니다.
이 방면 과 프로젝트 방침 등 의 상의
나에게 있어서, 나는 편집기만 확장하는 것이 가능하다고 생각한다
Reference
이 문제에 관하여(UnityEditor 확장 필드로 보존된 사용자 정의 클래스의 개인 필드에 대한 액세스 정보: 메모), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/matsumotokaka11/items/ca5bc67de211d0f277e5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)