You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
150 lines
6.3 KiB
150 lines
6.3 KiB
using System;
|
|
using System.Linq;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.VFX;
|
|
|
|
namespace UnityEditor.VFX
|
|
{
|
|
class CustomSpawnerVariant : VariantProvider
|
|
{
|
|
public override IEnumerable<Variant> GetVariants()
|
|
{
|
|
var types = VFXLibrary.FindConcreteSubclasses(typeof(VFXSpawnerCallbacks))
|
|
.Where(x => x != typeof(LoopAndDelay)) //Explicitly exclude loop and delay from listing, preferably use VFXSpawnContext settings instead
|
|
.ToArray();
|
|
foreach (var type in types)
|
|
{
|
|
yield return new Variant(
|
|
ObjectNames.NicifyVariableName(type.Name),
|
|
$"Spawn/Custom",
|
|
typeof(VFXSpawnerCustomWrapper),
|
|
new[] {new KeyValuePair<string, object>("m_customType", new SerializableType(type))});
|
|
}
|
|
}
|
|
}
|
|
|
|
[VFXInfo(variantProvider = typeof(CustomSpawnerVariant))]
|
|
class VFXSpawnerCustomWrapper : VFXAbstractSpawner
|
|
{
|
|
[SerializeField, VFXSetting(VFXSettingAttribute.VisibleFlags.None)]
|
|
protected SerializableType m_customType;
|
|
|
|
[SerializeField, VFXSetting(VFXSettingAttribute.VisibleFlags.None)]
|
|
protected MonoScript m_customScript;
|
|
|
|
private void ResolveCustomCallbackInstance()
|
|
{
|
|
//m_customScript always prevails on m_customType, we cannot modify m_customType twice.
|
|
if (m_customScript != null && m_customScript.GetClass() != null)
|
|
m_customType = m_customScript.GetClass();
|
|
|
|
//m_customScript is null in three cases
|
|
// - Newly created VFXSpawnerCustomWrapper, m_customType changed by SetSettingValue.
|
|
// - VFXSpawnerCallbacks has been suppressed, in that case, m_customType.text can display a message and m_customType == null.
|
|
// - VFXSpawnerCallbacks has been restored, m_customType != null, rebuild the m_instance.
|
|
if (m_customScript == null && m_customType != null)
|
|
{
|
|
var instance = CreateInstance(m_customType);
|
|
m_customScript = MonoScript.FromScriptableObject(instance);
|
|
}
|
|
}
|
|
|
|
public override void Sanitize(int version)
|
|
{
|
|
if (m_customScript == null && !object.ReferenceEquals(m_customType, null))
|
|
{
|
|
//Handle previous name based serialization, these class move to UnityEngine.VFX
|
|
if (m_customType.text.StartsWith("UnityEditor.VFX.LoopAndDelay,"))
|
|
m_customType = typeof(LoopAndDelay);
|
|
else if (m_customType.text.StartsWith("UnityEditor.VFX.SetSpawnTime,"))
|
|
m_customType = typeof(SetSpawnTime);
|
|
else if (m_customType.text.StartsWith("UnityEditor.VFX.SpawnOverDistance,"))
|
|
m_customType = typeof(SpawnOverDistance);
|
|
else if (m_customType.text.StartsWith("IncrementStripIndexOnStart,"))
|
|
m_customType = typeof(IncrementStripIndexOnStart);
|
|
|
|
ResolveCustomCallbackInstance();
|
|
}
|
|
base.Sanitize(version);
|
|
}
|
|
|
|
protected internal override void Invalidate(VFXModel model, InvalidationCause cause)
|
|
{
|
|
base.Invalidate(model, cause);
|
|
ResolveCustomCallbackInstance();
|
|
}
|
|
|
|
public override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
ResolveCustomCallbackInstance();
|
|
}
|
|
|
|
public override void GetImportDependentAssets(HashSet<int> dependencies)
|
|
{
|
|
base.GetImportDependentAssets(dependencies);
|
|
if (customBehavior != null)
|
|
{
|
|
dependencies.Add(customBehavior.GetInstanceID());
|
|
}
|
|
}
|
|
|
|
protected override IEnumerable<VFXPropertyWithValue> inputProperties
|
|
{
|
|
get
|
|
{
|
|
if (m_customType == null)
|
|
return Enumerable.Empty<VFXPropertyWithValue>();
|
|
return PropertiesFromType(((Type)m_customType).GetRecursiveNestedType(GetInputPropertiesTypeName()));
|
|
}
|
|
}
|
|
|
|
internal sealed override void GenerateErrors(VFXErrorReporter report)
|
|
{
|
|
base.GenerateErrors(report);
|
|
|
|
//Type isn't reachable ... but we already stored a type, log an error.
|
|
if (m_customType == null)
|
|
{
|
|
if (!object.ReferenceEquals(m_customType, null) && !string.IsNullOrEmpty(m_customType.text))
|
|
report.RegisterError("CustomSpawnerIDNotFound", VFXErrorType.Error, "The serialized reference to a VFXSpawnerCallbacks script is missing : " + m_customType.text, this);
|
|
else
|
|
report.RegisterError("CustomSpawnerIDNull", VFXErrorType.Error, "The serialized reference to a VFXSpawnerCallbacks script is missing.", this);
|
|
}
|
|
else if ((Type)m_customType == typeof(LoopAndDelay))
|
|
{
|
|
report.RegisterError("CustomSpawnerLoopAndDelay", VFXErrorType.Warning, "The block Loop And Delay is now deprecated in favor of the spawn context settings in inspector.", this);
|
|
}
|
|
|
|
if (customBehavior == null && m_customType != null)
|
|
{
|
|
if (m_customScript != null && m_customScript.GetClass() != null)
|
|
report.RegisterError("CustomSpawnerIDNotVFXSpawnerCallbacks", VFXErrorType.Error, string.Format("{0} isn't a VFXSpawnerCallbacks", m_customScript.GetClass()), this);
|
|
else
|
|
report.RegisterError("CustomSpawnerIDInvalid", VFXErrorType.Error, "Invalid ScriptableObject : " + (Type)m_customType, this);
|
|
}
|
|
}
|
|
|
|
public override sealed string name
|
|
{
|
|
get
|
|
{
|
|
if (m_customType != null)
|
|
return ObjectNames.NicifyVariableName(((Type)m_customType).Name);
|
|
return "Missing VFXSpawnerCallbacks";
|
|
}
|
|
}
|
|
|
|
public override sealed MonoScript customBehavior
|
|
{
|
|
get
|
|
{
|
|
if (m_customScript != null && typeof(VFXSpawnerCallbacks).IsAssignableFrom(m_customScript.GetClass()))
|
|
return m_customScript;
|
|
return null;
|
|
}
|
|
}
|
|
public override sealed VFXTaskType spawnerType { get { return VFXTaskType.CustomCallbackSpawner; } }
|
|
}
|
|
}
|