public override void Initialize() { base.Initialize(); _eventNamePopup = this.GetProgramPopup(UdonNodeExtensions.ProgramPopupType.Events, _eventNamePopup); }
// 0 = Value, 1 = name, 2 = public, 3 = synced, 4 = syncType public UdonParameterProperty(UdonGraph graphView, UdonNodeDefinition definition, UdonNodeData nodeData) { this.graph = graphView; this.definition = definition; this.nodeData = nodeData; // Make sure the incoming nodeData has the right number of nodeValues (super old graphs didn't have sync info) if (this.nodeData.nodeValues.Length != 5) { this.nodeData.nodeValues = GetDefaultNodeValues(); for (int i = 0; i < nodeData.nodeValues.Length; i++) { this.nodeData.nodeValues[i] = nodeData.nodeValues[i]; } } // Public Toggle isPublic = new Toggle { text = "public", value = (bool)GetValue(ValueIndices.isPublic) }; #if UNITY_2019_3_OR_NEWER isPublic.RegisterValueChangedCallback( #else isPublic.OnValueChanged( #endif e => { SetNewValue(e.newValue, ValueIndices.isPublic); }); Add(isPublic); // Is Synced Field isSynced = new Toggle { text = "synced", value = (bool)GetValue(ValueIndices.isSynced), }; #if UNITY_2019_3_OR_NEWER isSynced.RegisterValueChangedCallback( #else isSynced.OnValueChanged( #endif e => { SetNewValue(e.newValue, ValueIndices.isSynced); syncField.visible = e.newValue; }); Add(isSynced); // Sync Field, add to isSynced List <string> choices = new List <string>() { "none", "linear", "smooth" }; syncField = new EditorUI.PopupField <string>(choices, 0) { visible = isSynced.value }; #if UNITY_2019_3_OR_NEWER syncField.RegisterValueChangedCallback( #else syncField.OnValueChanged( #endif e => { SetNewValue(e.newValue, ValueIndices.syncType); }); isSynced.Add(syncField); // Container to show/edit Default Value var friendlyName = UdonGraphExtensions.FriendlyTypeName(definition.type).FriendlyNameify(); defaultValueContainer = new VisualElement(); defaultValueContainer.Add( new Label("default value") { name = "default-value-label" }); // Generate Default Value Field var value = TryGetValueObject(out object result); _inputField = UdonFieldFactory.CreateField( definition.type, result, newValue => SetNewValue(newValue, ValueIndices.value) ); if (_inputField != null) { defaultValueContainer.Add(_inputField); Add(defaultValueContainer); } }
public static EditorUI.PopupField <string> GetProgramPopup(this UdonNode node, ProgramPopupType popupType, EditorUI.PopupField <string> _eventNamePopup) { string PLACEHOLDER = "----"; string MISSING = "MISSING! Was"; List <string> _options = new List <string>() { PLACEHOLDER }; var data = node.data; bool unavailable = true; if (data.nodeUIDs.Length < 1 || string.IsNullOrEmpty(data.nodeUIDs[0])) { switch (popupType) { case ProgramPopupType.Events: _options = GetCustomEventsFromAsset(node.Graph.graphProgramAsset.SerializedProgramAsset); break; case ProgramPopupType.Variables: node.Graph.RefreshVariables(false); _options = new List <string>(node.Graph.GetVariableNames).Where(x => !x.StartsWithCached(VariableChangedEvent.OLD_VALUE_PREFIX)).ToList(); break; } unavailable = _options.Count == 0; _options.Insert(0, PLACEHOLDER); } else if (data.InputNodeAtIndex(0)?.fullName == "Get_Variable") { // So much work to get the underlying node referenced by a variable. Would be nice to have a method for this. var parts = data.nodeUIDs[0].Split('|'); if (parts.Length < 1) { return(null); } string targetId = parts[0]; var variableGetterNode = node.Graph.graphData.FindNode(targetId); if (variableGetterNode == null || variableGetterNode.nodeValues.Length < 1) { return(null); } string variableId = variableGetterNode.nodeValues[0].Deserialize() as string; if (string.IsNullOrWhiteSpace(variableId)) { return(null); } string variableName = node.Graph.GetVariableName(variableId); if (string.IsNullOrWhiteSpace(variableName)) { return(null); } if (node.Graph.udonBehaviour != null && node.Graph.udonBehaviour.publicVariables.TryGetVariableValue(variableName, out UdonBehaviour ub)) { if (ub != null) { switch (popupType) { case ProgramPopupType.Events: _options = GetCustomEventsFromAsset(ub.programSource.SerializedProgramAsset); break; case ProgramPopupType.Variables: _options = ub.programSource?.SerializedProgramAsset?.RetrieveProgram()?.SymbolTable .GetSymbols().Where(s => !s.StartsWithCached(UdonGraphCompiler.INTERNAL_VARIABLE_PREFIX) && !s.StartsWithCached(VariableChangedEvent.OLD_VALUE_PREFIX)).ToList(); break; } _options.Insert(0, PLACEHOLDER); unavailable = false; } } } int currentIndex = 0; int targetNodeValueIndex = node.data.fullName.Contains("SendCustomNetworkEvent") ? 2 : 1; string targetVarName = data.nodeValues[targetNodeValueIndex].Deserialize() as string; if (targetVarName != null && targetVarName.StartsWithCached(MISSING)) { targetVarName = null; } // If we have a target variable name: if (!string.IsNullOrWhiteSpace(targetVarName)) { if (_options.Contains(targetVarName)) { currentIndex = _options.IndexOf(targetVarName); } else { _options[0] = unavailable ? targetVarName : $"{MISSING} {targetVarName}"; } } if (_eventNamePopup == null) { _eventNamePopup = new EditorUI.PopupField <string>(_options, currentIndex); _eventNamePopup.name = popupType == ProgramPopupType.Events ? "EventNamePopup" : "VariablePopup"; var eventNamePort = node.inputContainer.Q(null, popupType == ProgramPopupType.Events ? "eventName" : "symbolName"); eventNamePort?.Add(_eventNamePopup); if (unavailable) { _eventNamePopup.SetEnabled(false); } } else { // Remaking it - remove the old one, at the new one at its previous location int index = node.inputContainer.IndexOf(_eventNamePopup); _eventNamePopup.RemoveFromHierarchy(); _eventNamePopup = new EditorUI.PopupField <string>(_options, currentIndex); node.inputContainer.Insert(index, _eventNamePopup); } #if UNITY_2019_3_OR_NEWER _eventNamePopup.RegisterValueChangedCallback( #else _eventNamePopup.OnValueChanged( #endif (e) => { node.SetNewValue(e.newValue.CompareTo(PLACEHOLDER) == 0 ? "" : e.newValue.ToString(), targetNodeValueIndex); // Todo: update text field directly and save instead of calling Reload node.Reload(); }); return(_eventNamePopup); }
public override void Initialize() { base.Initialize(); _programVariablePopup = this.GetProgramPopup(UdonNodeExtensions.ProgramPopupType.Variables, _programVariablePopup); }
// 0 = Value, 1 = name, 2 = public, 3 = synced, 4 = syncType public UdonParameterProperty(UdonGraph graphView, UdonNodeDefinition definition, UdonNodeData nodeData) { this.graph = graphView; this.definition = definition; this.nodeData = nodeData; string friendlyName = UdonGraphExtensions.FriendlyTypeName(definition.type).FriendlyNameify(); // Public Toggle isPublic = new Toggle { text = "public", value = (bool)GetValue(ValueIndices.isPublic) }; #if UNITY_2019_3_OR_NEWER isPublic.RegisterValueChangedCallback( #else isPublic.OnValueChanged( #endif e => { SetNewValue(e.newValue, ValueIndices.isPublic); }); Add(isPublic); if (UdonNetworkTypes.CanSync(definition.type)) { // Is Synced Field isSynced = new Toggle { text = "synced", value = (bool)GetValue(ValueIndices.isSynced), name = "syncToggle", }; #if UNITY_2019_3_OR_NEWER isSynced.RegisterValueChangedCallback( #else isSynced.OnValueChanged( #endif e => { SetNewValue(e.newValue, ValueIndices.isSynced); syncField.visible = e.newValue; }); // Sync Field, add to isSynced List <string> choices = new List <string>() { "none" }; if (UdonNetworkTypes.CanSyncLinear(definition.type)) { choices.Add("linear"); } if (UdonNetworkTypes.CanSyncSmooth(definition.type)) { choices.Add("smooth"); } syncField = new EditorUI.PopupField <string>(choices, 0) { visible = isSynced.value, }; syncField.Insert(0, new Label("smooth:")); #if UNITY_2019_3_OR_NEWER syncField.RegisterValueChangedCallback( #else syncField.OnValueChanged( #endif e => { SetNewValue(e.newValue, ValueIndices.syncType); }); // Only show sync smoothing dropdown if there are choices to be made if (choices.Count > 1) { isSynced.Add(syncField); } Add(isSynced); } else { // Cannot Sync SetNewValue(false, ValueIndices.isSynced); Add(new Label($"{friendlyName} cannot be synced.")); } // Container to show/edit Default Value defaultValueContainer = new VisualElement(); defaultValueContainer.Add( new Label("default value") { name = "default-value-label" }); // Generate Default Value Field var value = TryGetValueObject(out object result); _inputField = UdonFieldFactory.CreateField( definition.type, result, newValue => SetNewValue(newValue, ValueIndices.value) ); if (_inputField != null) { defaultValueContainer.Add(_inputField); Add(defaultValueContainer); } }