수색…


비고

AssetBundles가있는 ScriptableObjects

스크립트에 ScriptableObject에 대한 참조가 포함되어있는 경우 프리 세트를 AssetBundle에 추가 할 때주의하십시오. ScriptableObjects는 본질적으로 애셋이기 때문에 Unity는 애셋 번들에 애트리뷰트를 추가하기 전에 애트리뷰트의 복제물을 생성하므로 런타임 중에 바람직하지 않은 동작이 발생할 수 있습니다.

AssetBundle에서 GameObject를 로딩 할 때 ScriptableObject 애셋을로드 된 스크립트에 재 주입하여 번들 스크립트를 대체 할 수 있습니다. Dependency Injection 참조.

소개

ScriptableObjects는 MonoBehaviours처럼 장면이나 게임 객체에 바인딩되지 않은 직렬화 된 객체입니다. 이를 한 가지 방법으로 말하자면 프로젝트 내부의 에셋 파일에 바인딩 된 데이터 및 메서드입니다. 이러한 ScriptableObject 에셋은 공용 메서드에 액세스 할 수있는 MonoBehaviours 또는 다른 ScriptableObject에 전달할 수 있습니다.

일련 화 된 자산으로서의 특성으로 인해 우수한 관리자 클래스 및 데이터 소스를 만듭니다.

ScriptableObject 애셋 만들기

다음은 간단한 ScriptableObject 구현입니다.

using UnityEngine;

[CreateAssetMenu(menuName = "StackOverflow/Examples/MyScriptableObject")]
public class MyScriptableObject : ScriptableObject
{
    [SerializeField]
    int mySerializedNumber;

    int helloWorldCount = 0;

    public void HelloWorld()
    {
        helloWorldCount++;
        Debug.LogFormat("Hello! My number is {0}.", mySerializedNumber);
        Debug.LogFormat("I have been called {0} times.", helloWorldCount);
    }
}

CreateAssetMenu 속성을 클래스에 추가하면 Unity가 Assets / Create 하위 메뉴에이를 나열합니다. 이 경우 Assets / Create / StackOverflow / Examples 아래에 있습니다.

생성 된 ScriptpectObject 인스턴스는 Inspector를 통해 다른 스크립트 및 ScriptableObject에 전달 될 수 있습니다.

using UnityEngine;

public class SampleScript : MonoBehaviour {

    [SerializeField]
    MyScriptableObject myScriptableObject;

    void OnEnable()
    {
        myScriptableObject.HelloWorld();
    }
}

코드를 통해 ScriptableObject 인스턴스 생성

ScriptableObject.CreateInstance<T>() 통해 새 ScriptableObject 인스턴스를 만듭니다.

T obj = ScriptableObject.CreateInstance<T>();

여기서 T ScriptableObject 확장합니다.

즉, 생성자를 호출하여 ScriptableObject를 만들지 마십시오. new ScriptableObject() .

런타임시 코드를 사용하여 ScriptableObject를 만드는 것은 데이터 직렬화를 주로 사용하기 때문에 거의 호출되지 않습니다. 이 시점에서 표준 클래스를 사용할 수도 있습니다. 편집기 확장을 스크립팅 할 때 더욱 일반적입니다.

ScriptableObjects는 PlayMode에서도 편집기에서 직렬화됩니다.

ScriptableObject 인스턴스에서 직렬화 된 필드에 액세스 할 때는 특히주의해야합니다.

필드가 public 으로 표시되거나 SerializeField를 통해 SerializeField 되면 해당 값을 변경할 수 없습니다. MonoBehaviours처럼 재생 모드를 끝낼 때 재설정되지 않습니다. 이것은 때때로 유용 할 수 있지만 엉망이 될 수도 있습니다.

이 때문에 직렬화 된 필드를 읽기 전용으로 만들고 공개 필드를 모두 피하는 것이 가장 좋습니다.

public class MyScriptableObject : ScriptableObject
{
    [SerializeField]
    int mySerializedValue;

    public int MySerializedValue
    {
        get { return mySerializedValue; }
    }
}

재생 세션간에 재설정되는 Publicable 값을 ScriptableObject에 저장하려면 다음 패턴을 사용하는 것이 좋습니다.

public class MyScriptableObject : ScriptableObject
{
    // Private fields are not serialized and will reset to default on reset
    private int mySerializedValue;

    public int MySerializedValue
    {
        get { return mySerializedValue; }
        set { mySerializedValue = value; }
    }
}

런타임 중에 기존 ScriptableObjects 찾기

런타임 중에 활성 ScriptableObjects를 찾으려면 Resources.FindObjectsOfTypeAll() 사용할 수 있습니다.

T[] instances = Resources.FindObjectsOfTypeAll<T>();

여기서 T 는 검색하려는 ScriptableObject 인스턴스의 유형입니다. 활성화 는 이전에 어떤 형태로든 메모리에로드되었음을 의미합니다.

이 메서드는 매우 느리므로 반환 값을 캐시하고 자주 호출하지 않도록하십시오. 스크립트에서 직접 ScriptableObjects를 참조하는 것이 좋습니다.

팁 : 빠른 조회를 위해 고유 한 인스턴스 콜렉션을 유지 보수 할 수 있습니다. OnEnable() 에서 OnEnable() 공유 컬렉션에 등록하십시오.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow