public static bool OnOpenVFX(int instanceID, int line) { var obj = EditorUtility.InstanceIDToObject(instanceID); if (obj is VFXGraph || obj is VFXModel || obj is VFXUI) { // for visual effect graph editor ScriptableObject select them when double clicking on them. //Since .vfx importer is a copyasset, the default is to open it with an external editor. Selection.activeInstanceID = instanceID; return(true); } else if (obj is VisualEffectAsset) { VFXViewWindow.GetWindow <VFXViewWindow>().LoadAsset(obj as VisualEffectAsset, null); return(true); } else if (obj is Shader || obj is ComputeShader) { string path = AssetDatabase.GetAssetPath(instanceID); if (path.EndsWith(".vfx")) { var resource = VisualEffectResource.GetResourceAtPath(path); if (resource != null) { int index = resource.GetShaderIndex(obj); resource.ShowGeneratedShaderFile(index, line); return(true); } } } return(false); }
public IEnumerator Sanitize_Shape_To_TShape_And_Check_VFXParameter_State() { var kSourceAsset = "Assets/AllTests/Editor/Tests/VFXSanitizeTShape.vfx_"; var graph = VFXTestCommon.CopyTemporaryGraph(kSourceAsset); yield return(null); Assert.AreEqual(8, graph.children.OfType <VFXParameter>().Count()); Assert.AreEqual(11, graph.children.OfType <VFXParameter>().SelectMany(o => o.nodes).Count()); Assert.AreEqual(0, graph.children.OfType <VFXParameter>().SelectMany(o => o.nodes).Where(o => o.position == Vector2.zero).Count()); Assert.AreEqual(0, graph.children.OfType <VFXParameter>().SelectMany(o => o.nodes).Where(o => !o.linkedSlots.Any()).Count()); yield return(null); var window = VFXViewWindow.GetWindow <VFXViewWindow>(); var resource = graph.GetResource(); window.LoadAsset(resource.asset, null); yield return(null); Assert.AreEqual(8, graph.children.OfType <VFXParameter>().Count()); Assert.AreEqual(11, graph.children.OfType <VFXParameter>().SelectMany(o => o.nodes).Count()); Assert.AreEqual(0, graph.children.OfType <VFXParameter>().SelectMany(o => o.nodes).Where(o => o.position == Vector2.zero).Count(), "Fail after window.LoadAsset"); foreach (var param in graph.children.OfType <VFXParameter>()) { var nodes = param.nodes.Where(o => !o.linkedSlots.Any()); if (nodes.Any()) { Assert.Fail(param.exposedName + " as an orphan node"); } } Assert.AreEqual(0, graph.children.OfType <VFXParameter>().SelectMany(o => o.nodes).Where(o => !o.linkedSlots.Any()).Count()); //Orphan link }
protected void OnEnable() { VFXViewWindow current = VFXViewWindow.GetWindow(target as VFXParameter); if (current != null) { controller = current.graphView.controller; if (controller != null) { controller.useCount++; } } }
public void ConvertToSubgraph() { //Create a new vfx based on the usual template var templateString = System.IO.File.ReadAllText(VisualEffectGraphPackageInfo.assetPackagePath + "/Editor/Templates/SimpleParticleSystem.vfx"); System.IO.File.WriteAllText(testSubgraphAssetName, templateString); VFXViewWindow window = VFXViewWindow.GetWindow <VFXViewWindow>(); window.LoadAsset(AssetDatabase.LoadAssetAtPath <VisualEffectAsset>(testAssetName), null); VFXConvertSubgraph.ConvertToSubgraphContext(window.graphView, window.graphView.Query <VFXContextUI>().ToList().Where(t => !(t.controller.model is VFXBasicSpawner)).Select(t => t.controller).Cast <Controller>(), Rect.zero, testSubgraphSubAssetName); window.graphView.controller = null; }
public void Subgraph_Event_Link_To_Spawn() { VFXViewWindow window = VFXViewWindow.GetWindow <VFXViewWindow>(); window.LoadAsset(AssetDatabase.LoadAssetAtPath <VisualEffectAsset>(testAssetName), null); //Create Spawner in subgraph { var spawner = ScriptableObject.CreateInstance <VFXBasicSpawner>(); m_ViewController.graph.AddChild(spawner); m_ViewController.LightApplyChanges(); var controller = window.graphView.Query <VFXContextUI>().ToList().Select(t => t.controller).Cast <Controller>(); Assert.AreEqual(1, controller.Count()); VFXConvertSubgraph.ConvertToSubgraphContext(window.graphView, controller, Rect.zero, testSubgraphSubAssetName); } var subGraphController = m_ViewController.allChildren.OfType <VFXContextController>().FirstOrDefault(o => o.model is VFXSubgraphContext); Assert.IsNotNull(subGraphController); //Create Event Context & Link the two input flow var subGraphContext = subGraphController.model; var eventContext = ScriptableObject.CreateInstance <VFXBasicEvent>(); Assert.IsTrue(VFXContext.CanLink(eventContext, subGraphContext, 0, 0)); Assert.IsTrue(VFXContext.CanLink(eventContext, subGraphContext, 0, 1)); eventContext.LinkTo(subGraphContext, 0, 0); eventContext.LinkTo(subGraphContext, 0, 1); var flow = eventContext.outputFlowSlot.First().link; Assert.AreEqual(2, flow.Count()); Assert.IsTrue(flow.All(o => o.context == subGraphContext)); Assert.IsTrue(flow.Any(o => o.slotIndex == 0)); Assert.IsTrue(flow.Any(o => o.slotIndex == 1)); window.graphView.controller = null; }
protected override void AssetField(VisualEffectResource resource) { using (new GUILayout.HorizontalScope()) { EditorGUILayout.PropertyField(m_VisualEffectAsset, Contents.assetPath); bool saveEnabled = GUI.enabled; if (m_VisualEffectAsset.objectReferenceValue == null && !m_VisualEffectAsset.hasMultipleDifferentValues) { GUI.enabled = saveEnabled; if (GUILayout.Button(Contents.createAsset, EditorStyles.miniButton, Styles.MiniButtonWidth)) { string filePath = EditorUtility.SaveFilePanelInProject("", "New Graph", "vfx", "Create new VisualEffect Graph"); if (!string.IsNullOrEmpty(filePath)) { VisualEffectAssetEditorUtility.CreateTemplateAsset(filePath); var asset = AssetDatabase.LoadAssetAtPath <VisualEffectAsset>(filePath); m_VisualEffectAsset.objectReferenceValue = asset; serializedObject.ApplyModifiedProperties(); VFXViewWindow window = EditorWindow.GetWindow <VFXViewWindow>(); window.LoadAsset(asset, targets.Length > 1 ? null : target as VisualEffect); } } } else { GUI.enabled = saveEnabled && !m_VisualEffectAsset.hasMultipleDifferentValues && m_VisualEffectAsset.objectReferenceValue != null && resource != null; // Enabled state will be kept for all content until the end of the inspectorGUI. if (GUILayout.Button(Contents.openEditor, EditorStyles.miniButton, Styles.MiniButtonWidth)) { var asset = m_VisualEffectAsset.objectReferenceValue as VisualEffectAsset; VFXViewWindow window = VFXViewWindow.GetWindow(asset, true); window.LoadAsset(asset, targets.Length > 1 ? null : target as VisualEffect); } } GUI.enabled = saveEnabled; } }
protected override void GenerateErrors(VFXInvalidateErrorReporter manager) { VFXSetting capacitySetting = GetSetting("capacity"); if ((uint)capacitySetting.value > 1000000) { manager.RegisterError("CapacityOver1M", VFXErrorType.PerfWarning, "Systems with large capacities can be slow to simulate"); } var data = GetData() as VFXDataParticle; if (data != null && CanBeCompiled()) { if (data.boundsMode == BoundsSettingMode.Recorded) { if (VFXViewWindow.GetWindow(GetGraph(), false, false)?.graphView?.attachedComponent == null || !BoardPreferenceHelper.IsVisible(BoardPreferenceHelper.Board.componentBoard, false)) { manager.RegisterError("NeedsRecording", VFXErrorType.Warning, "In order to record the bounds, the current graph needs to be attached to a scene instance via the Target Game Object panel"); } var boundsSlot = inputSlots.FirstOrDefault(s => s.name == "bounds"); if (boundsSlot != null && boundsSlot.HasLink(true)) { manager.RegisterError("OverriddenRecording", VFXErrorType.Warning, "This system bounds will not be recorded because they are set from operators."); } } if (data.boundsMode == BoundsSettingMode.Automatic) { manager.RegisterError("CullingFlagAlwaysSimulate", VFXErrorType.Warning, "Setting the system Bounds Mode to Automatic will switch the culling flags of the Visual Effect asset" + " to 'Always recompute bounds and simulate'."); } } }
static void OnPostprocessAllAssets(string[] importedAssets, string[] deletedAssets, string[] movedAssets, string[] movedFromAssetPaths) { List <string> assetToReimport = null; #if VFX_HAS_TIMELINE UnityEditor.VFX.Migration.ActivationToControlTrack.SanitizePlayable(importedAssets); #endif foreach (var assetPath in importedAssets) { bool isVFX = VisualEffectAssetModicationProcessor.HasVFXExtension(assetPath); if (isVFX) { VisualEffectResource resource = VisualEffectResource.GetResourceAtPath(assetPath); if (resource == null) { continue; } VFXGraph graph = resource.GetOrCreateGraph(); //resource.graph should be already != null at this stage but GetOrCreateGraph is also assigning the visualEffectResource. It's required for UpdateSubAssets if (graph != null) { bool wasGraphSanitized = graph.sanitized; try { graph.SanitizeForImport(); if (!wasGraphSanitized && graph.sanitized) { assetToReimport ??= new List <string>(); assetToReimport.Add(assetPath); } } catch (Exception exception) { Debug.LogErrorFormat("Exception during sanitization of {0} : {1}", assetPath, exception); } var window = VFXViewWindow.GetWindow(graph, false, false); if (window != null) { window.UpdateTitle(assetPath); } } else { Debug.LogErrorFormat("VisualEffectGraphResource without graph : {0}", assetPath); } } } //Relaunch previously skipped OnCompileResource if (assetToReimport != null) { foreach (var assetPath in assetToReimport) { try { AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate); } catch (Exception exception) { Debug.LogErrorFormat("Exception during reimport of {0} : {1}", assetPath, exception); } } } }