Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Question Strange interaction between "Regenerate Nodes" and references to UVS types

Discussion in 'Visual Scripting' started by AlexanderWorret, Oct 12, 2022.

  1. AlexanderWorret


    Aug 25, 2020

    I'm using UVS to setup the abilities of my turn-based RPG, mostly with custom UVS units. One thing that has bothered me was that it was not possible to see if a graph had any issues, for example because of changes to existing units, such as additional required inputs. Those are only visible in the graph editor and manually iterating all graphs in the project becomes rather time-consuming with increasing number.

    For this reason, I wrote some code that would validate the graphs and the units contained in them with the help of Odin Validator and that has worked great so far.
    However, I now ran across an issue that is somehow caused by that validation code, but not actually by the code executing. Even the code just sitting there somehow interferes with building the node list.

    Code (CSharp):
    1. public class AbilityData : ScriptableObject
    2. {
    3.     [ValidateInput(nameof(IsValidAbilityGraph), "Must be null or valid.")]
    4.     [SerializeField]
    5.     private ScriptGraphAsset AbilityGraph;
    7.     private ScriptGraphAsset PrepareAbilityGraph(ScriptGraphAsset unpreparedAsset)
    8.     {
    9.         var result = Instantiate(unpreparedAsset);
    10. ...
    11.         return result;
    12.     }
    14.     private bool IsValidAbilityGraph(ScriptGraphAsset graphAsset, ref string errorMessage)
    15.     {
    16.         if (graphAsset == null)
    17.             return true;
    19.         var preparedGraph = PrepareAbilityGraph(graphAsset);
    21.         var unitAnalysisWarnings = new List<string>();
    22.         var graphReference = GraphReference.New(preparedGraph, false);
    24.         foreach (var unit in preparedGraph.graph.units)
    25.         {
    26.             //NOTE: This breaks regenerating visual scripting nodes, comment out if you need to regenerate the node library
    27.             var analysis = unit.Analysis<UnitAnalysis>(graphReference);
    28.             unitAnalysisWarnings.AddRange(analysis.warnings.Where(w => w.level == WarningLevel.Error || w.level == WarningLevel.Severe).Select(w => w.message));
    29.         }
    31.         if (unitAnalysisWarnings.Any())
    32.         {
    33.             var builder = new StringBuilder();
    35.             for (int i = 0; i < unitAnalysisWarnings.Count; i++)
    36.                 builder.AppendLine(unitAnalysisWarnings[i]);
    38.             errorMessage = builder.ToString();
    39.             return false;
    40.         }
    42.         return true;
    43.     }
    44.     ...
    45. }
    Lines 24 and 25 cause all of my custom units (around 30 at this time) to be discarded when regenerating the node list from project properties. If I comment out those two lines and regenerate, they all show up again. As already mentioned, the code itself does not seem to be the issue, because if I comment out the ValidateInputAttribute (so that the code is not executed), the units still get discarded when building the list. For some reason just referencing some UVS types causes this issue. In a previous version I had a List<Warning>() instead of a List<string>() and simply referencing Warning, without any additional code or populating the list, resulted in no custom units showing up in the fuzzy finder as well.

    My working theory is that referencing UVS types causes my own assembly to be treated like the UVS assemblies, but that is just a guess.

    My current workaround is commenting out those lines whenever I need to regenerate the node list and then putting them back in afterwards. But obviously that is not ideal. While I'll admit that this is probably not the most common UVS usage, it still strikes me as odd. Can anyone explain to me why this is happening and if there is a better way to work around it?
    REDACT3D_ likes this.