스크립트 대상은 파일 종류이다

6288 단어 UnityScriptableObject

세계는 기묘했다


며칠 전에 Scriptable Object를 사용할 때 이상한 현상이 발생했습니다.
나는 이런 각본을 썼다.
SO.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SO : ScriptableObject
{
}

[CreateAssetMenu(fileName = "SOInherit", menuName = "CreateSO")]
public class SOInherit : SO
{
    public string val;
}

ScriptableObject의 기본 클래스와 상속된 클래스는 파일에 기록됩니다.
이것은 항목 보기에서 마우스 오른쪽 단추를 눌러 만든 것입니다.

그리고 정상적으로 작동하는지 확인한 후 Unity 편집기를 다시 시작합니다.
그리고

이러한 Assert가 표시되고 Scriptable Object로서의 동작도 없습니다!
나 아무것도 안 했는데 고장났어...

해결 방법


제목이지만 ScriptableObject는 하나의 파일에 클래스만 씁니다.

원인


왜 한 파일에 여러 종류를 쓸 수 없습니까?
파일이 분할된 ScriptableObject 파일의 내용을 살펴보겠습니다.
SOInherit.asset
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 0}
  m_Enabled: 1
  m_EditorHideFlags: 0
  m_Script: {fileID: 11500000, guid: d740773b00796084096feb7e6b5b3618, type: 3}
  m_Name: SOInherit
  m_EditorClassIdentifier: 
  val: "\u5024\u3092\u3053\u3053\u306B\u5165\u308C\u308B\u3002"
주의해야 할 것은 m_Script의 guid입니다.
다음은 SOInherit입니다.cs의 메타 파일을 보겠습니다.
SOInherit.cs.meta
fileFormatVersion: 2
guid: d740773b00796084096feb7e6b5b3618
MonoImporter:
  externalObjects: {}
  serializedVersion: 2
  defaultReferences: []
  executionOrder: 0
  icon: {instanceID: 0}
  userData: 
  assetBundleName: 
  assetBundleVariant: 
guid의 값을 보세요, SOInherit.asset의 m_스크립트에 저장된guid와 일치합니다.
Unity는guid라는 유일한 id를 각자의 자원에 분배하고 이 id를 이용하여 자원의 참조를 실현한다.
ScriptableObject는 스크립트 파일의guid를 보존하여 자신이 이 종류의 실례임을 나타냅니다.
그런데 이때 만약에 한 파일에 여러 종류가 있다면 어떻게 될까요?guid는 모든 자원, 즉 파일에 따라 분배되기 때문에 ScriptableObject가 스크립트 파일의guid를 유지해도 어떤 종류의 실례인지 알 수 없습니다.
ScriptableObject를 만들 때부터 다시 시작할 때까지 정상적으로 작동하지만 Script 속성을 보면 None이기 때문에 참조가 제대로 작동하지 않습니다.

총결산


하고 싶은 말 제목이 다야.MonoBehaviour는 1 클래스 1 파일로 유명하지만 Scriptable Object는 잘 알려지지 않았고 다시 시작하기 전에 고장을 눈치채지 못해 번거롭습니다.조심하세요.

보충하여 기록하다


한 파일에 여러 클래스가 설명되어 있어도 파일 이름과 같은 스크립트 대상 클래스가 존재하면 이 클래스의 실례적인 자원 파일도 순조롭게 읽을 수 있을 것 같습니다.
Unity가 ScriptableObject를 가져올 때, 먼저 guid에서 어떤 스크립트 파일에 클래스가 기술되었는지 조사하여 이 스크립트 파일과 같은 클래스의 실례로 가져옵니다.
따라서 스크립트 파일에 클래스만 기술되어 있어도 파일 이름과 클래스 이름이 다른 상황에서는 Scriptable Object를 잘 읽을 수 없습니다.
어쨌든 한 파일에 여러 종류를 기술하거나 파일 이름과 클래스를 분리해서는 안 된다. 이렇게 하는 것은 매우 위험하다.

좋은 웹페이지 즐겨찾기