This document is about: QUANTUM 1
SWITCH TO

アセットを簡単にベイキングできるUnity MonoBehaviourの作成

警告: 自分でカスタム作業が必要となります

最初の方法は、アセットを作成するか、既存のアセットを返しますが、これを手動で行う必要があります。これは、ユーザーが単一のMonoBehaviourに多くの値を設定することによって複数のアセットを作成する場合に最も適しています。

C#

using Photon.Deterministic;
using UnityEditor;
using UnityEngine;
using System.Reflection;

namespace Quantum
{
    /// <summary>
    /// A generic bakable class, which will be run at bake time
    /// </summary>
    public class QuantumBakable : MonoBehaviour
    {
        public bool baked = false;

    public T FindOrCreateAsset<T, U>( ref string Guid, string bakedAssetPath, bool createAsChild = false )
        where T : AssetBase
        where U : AssetObject, new()
    {
        T newAsset = null;
        if( Guid != null )
        {
            newAsset = UnityDB.FindAsset<T>( Guid );
        }
#if UNITY_EDITOR
        if( newAsset == null )
        {
            newAsset = ScriptableObject.CreateInstance<T>();
            var type = typeof( T );
            FieldInfo[] fieldInfos;
            fieldInfos = type.GetFields( BindingFlags.Public | BindingFlags.Instance );

            foreach( FieldInfo field in fieldInfos )
            {
                if( field.FieldType == typeof( U ) )
                {
                    object link = field.GetValue( newAsset );
                    field.SetValue( newAsset, new U() );
                    link = field.GetValue( newAsset );
                    var guidField = link.GetType().GetProperty( "Guid" );
                    guidField.SetValue( link, GUID.NewGUID() );
                }
            }

            if( createAsChild )
            {
                AssetDatabase.AddObjectToAsset( newAsset, bakedAssetPath );
            }
            else
            {
                AssetDatabase.CreateAsset( newAsset, bakedAssetPath );
            }
            Guid = newAsset.AssetObject.Guid;
        }
#endif
        return newAsset;
    }

    public virtual object OnBake( string folderPath, string sceneName, string assetName, UserMapData userMapData, string containerAsset = null )
        {
            baked = true;
            return null;
        }
    }
}

ただし、1:1のUnityコンポーネントとQuantumアセットの関係がある場合、次のようなものがより役立つかもしれません。

C#

using Photon.Deterministic;
using UnityEditor;
using UnityEngine;
using System.Reflection;

namespace Quantum
{
    /// <summary>
    /// A specialized baking class that will produce an asset with an initialized Settings type
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <typeparam name="U"></typeparam>
    public class QuantumAssetBaker<T,U> : QuantumBakable
    where T : AssetBase
    where U : AssetObject, new()
    {
        // TODO: Make the backing fields automatic in editor
        //[HideInInspector]
        public U Settings;


        private T m_bakedAssetCache;
        public T FindOrCreateAsset(ref string Guid, string assetPath, bool createAsChild = false) {
            T asset = FindOrCreateAsset<T, U>(ref Guid, assetPath, createAsChild);
            m_bakedAssetCache = asset;
            return asset;
        }

        public string DefaultBakePath(string folderPath, string sceneName, string assetName, string objectName ) {
            string bakedAssetPath = System.IO.Path.Combine(folderPath, sceneName + "_" + assetName + "_" + objectName + ".asset");
            return bakedAssetPath;
        }
    }
}

Example Usage:

C#

using UnityEngine;
using Quantum;
using Photon.Deterministic;
using UnityEditor;

public class NetworkTerminalUnity : QuantumAssetBaker<NetworkTerminalAsset, NetworkTerminal>
{
    public NetworkTerminalLink Terminal;

    public FP radius;

    public override object OnBake( string folderPath, string sceneName, string assetName, UserMapData userMapData, string parentAssetPath = null )
    {
        base.OnBake( folderPath, sceneName, assetName, userMapData );

        string terminalPath = System.IO.Path.Combine( folderPath, sceneName + "_" + assetName + "_" + name + "_Terminal.asset" );

        var position = transform.TransformPoint(Vector3.zero);
        var rotation = transform.rotation.eulerAngles.z;
        NetworkTerminalAsset newTerminalAsset = FindOrCreateAsset(ref Terminal.Guid, parentAssetPath, true);

        newTerminalAsset.name = sceneName + "_" + assetName + "_" + name + "_Terminal";
        newTerminalAsset.Settings.Name = assetName;
        newTerminalAsset.Settings.Radius = radius;
        newTerminalAsset.Settings.Position = new FPVector2( FP.FromFloat_UNSAFE( position.x ), FP.FromFloat_UNSAFE( position.y ) );

        EditorUtility.SetDirty( newTerminalAsset );

        return newTerminalAsset;
    }

    public void OnDrawGizmosSelected()
    {
        Gizmos.DrawWireSphere( transform.position, radius.AsFloat );
    }
}
Back to top