// Amplify Shader Editor - Visual Shader Editing Tool // Copyright (c) Amplify Creations, Lda using UnityEngine; using UnityEditor; using System; namespace AmplifyShaderEditor { [Serializable] [NodeAttributes( "Int", "Constants And Properties", "Int property", null, KeyCode.Alpha0 )] public sealed class IntNode : PropertyNode { [SerializeField] private int m_defaultValue; [SerializeField] private int m_materialValue; [SerializeField] private bool m_setAsUINT = false; private const float LabelWidth = 8; private int m_cachedPropertyId = -1; private bool m_isEditingFields; private int m_previousValue; private string m_fieldText = "0"; public IntNode() : base() { } public IntNode( int uniqueId, float x, float y, float width, float height ) : base( uniqueId, x, y, width, height ) { } protected override void CommonInit( int uniqueId ) { base.CommonInit( uniqueId ); GlobalTypeWarningText = string.Format( GlobalTypeWarningText, "Int" ); AddOutputPort( WirePortDataType.INT, Constants.EmptyPortValue ); m_insideSize.Set( 50, 10 ); m_selectedLocation = PreviewLocation.BottomCenter; m_drawPrecisionUI = false; m_showHybridInstancedUI = true; m_availableAttribs.Add( new PropertyAttributes( "Enum", "[Enum]" ) ); m_previewShaderGUID = "0f64d695b6ffacc469f2dd31432a232a"; m_srpBatcherCompatible = true; } protected override void OnUniqueIDAssigned() { base.OnUniqueIDAssigned(); UIUtils.RegisterFloatIntNode( this ); } public override void Destroy() { base.Destroy(); UIUtils.UnregisterFloatIntNode( this ); } public override void OnDirtyProperty() { UIUtils.UpdateFloatIntDataNode( UniqueId, PropertyInspectorName ); } public override void RefreshExternalReferences() { base.RefreshExternalReferences(); OnPropertyNameChanged(); OnDirtyProperty(); } public override void SetPreviewInputs() { base.SetPreviewInputs(); if( m_cachedPropertyId == -1 ) m_cachedPropertyId = Shader.PropertyToID( "_InputInt" ); if( m_materialMode && m_currentParameterType != PropertyType.Constant ) PreviewMaterial.SetInt( m_cachedPropertyId, m_materialValue ); else PreviewMaterial.SetInt( m_cachedPropertyId, m_defaultValue ); } public override void CopyDefaultsToMaterial() { m_materialValue = m_defaultValue; DrawSetAsUINT(); } public override void DrawSubProperties() { m_defaultValue = EditorGUILayoutIntField( Constants.DefaultValueLabel, m_defaultValue ); DrawSetAsUINT(); } private void DrawSetAsUINT() { EditorGUI.BeginChangeCheck(); m_setAsUINT = EditorGUILayoutToggle( "Set as UINT", m_setAsUINT ); if( EditorGUI.EndChangeCheck() ) { WirePortDataType portType = m_setAsUINT ? WirePortDataType.UINT : WirePortDataType.INT; m_outputPorts[ 0 ].ChangeType( portType, false ); } } public override void DrawMaterialProperties() { if( m_materialMode ) EditorGUI.BeginChangeCheck(); m_materialValue = EditorGUILayoutIntField( Constants.MaterialValueLabel, m_materialValue ); if( m_materialMode && EditorGUI.EndChangeCheck() ) { m_requireMaterialUpdate = true; } } public override void OnNodeLayout( DrawInfo drawInfo ) { base.OnNodeLayout( drawInfo ); m_propertyDrawPos = m_remainingBox; m_propertyDrawPos.x = m_remainingBox.x - LabelWidth * drawInfo.InvertedZoom; m_propertyDrawPos.width = drawInfo.InvertedZoom * Constants.FLOAT_DRAW_WIDTH_FIELD_SIZE; m_propertyDrawPos.height = drawInfo.InvertedZoom * Constants.FLOAT_DRAW_HEIGHT_FIELD_SIZE; } public override void DrawGUIControls( DrawInfo drawInfo ) { base.DrawGUIControls( drawInfo ); if( drawInfo.CurrentEventType != EventType.MouseDown ) return; Rect hitBox = m_remainingBox; hitBox.xMin -= LabelWidth * drawInfo.InvertedZoom; bool insideBox = hitBox.Contains( drawInfo.MousePosition ); if( insideBox ) { GUI.FocusControl( null ); m_isEditingFields = true; } else if( m_isEditingFields && !insideBox ) { GUI.FocusControl( null ); m_isEditingFields = false; } } public override void Draw( DrawInfo drawInfo ) { base.Draw( drawInfo ); if( !m_isVisible ) return; if( m_isEditingFields && m_currentParameterType != PropertyType.Global ) { float labelWidth = EditorGUIUtility.labelWidth; EditorGUIUtility.labelWidth = LabelWidth * drawInfo.InvertedZoom; if( m_materialMode && m_currentParameterType != PropertyType.Constant ) { EditorGUI.BeginChangeCheck(); m_materialValue = EditorGUIIntField( m_propertyDrawPos, " ", m_materialValue, UIUtils.MainSkin.textField ); if( EditorGUI.EndChangeCheck() ) { PreviewIsDirty = true; m_requireMaterialUpdate = true; if( m_currentParameterType != PropertyType.Constant ) BeginDelayedDirtyProperty(); } } else { EditorGUI.BeginChangeCheck(); m_defaultValue = EditorGUIIntField( m_propertyDrawPos, " ", m_defaultValue, UIUtils.MainSkin.textField ); if( EditorGUI.EndChangeCheck() ) { PreviewIsDirty = true; BeginDelayedDirtyProperty(); } } EditorGUIUtility.labelWidth = labelWidth; } else if( drawInfo.CurrentEventType == EventType.Repaint ) { bool guiEnabled = GUI.enabled; GUI.enabled = m_currentParameterType != PropertyType.Global; Rect fakeField = m_propertyDrawPos; fakeField.xMin += LabelWidth * drawInfo.InvertedZoom; if( GUI.enabled ) { Rect fakeLabel = m_propertyDrawPos; fakeLabel.xMax = fakeField.xMin; EditorGUIUtility.AddCursorRect( fakeLabel, MouseCursor.SlideArrow ); EditorGUIUtility.AddCursorRect( fakeField, MouseCursor.Text ); } bool currMode = m_materialMode && m_currentParameterType != PropertyType.Constant; int value = currMode ? m_materialValue : m_defaultValue; if( m_previousValue != value ) { m_previousValue = value; m_fieldText = value.ToString(); } GUI.Label( fakeField, m_fieldText, UIUtils.MainSkin.textField ); GUI.enabled = guiEnabled; } } public override string GenerateShaderForOutput( int outputId, ref MasterNodeDataCollector dataCollector, bool ignoreLocalvar ) { base.GenerateShaderForOutput( outputId, ref dataCollector, ignoreLocalvar ); if( m_currentParameterType != PropertyType.Constant ) return PropertyData( dataCollector.PortCategory ); return m_defaultValue.ToString(); } public override string GetPropertyValue() { return PropertyAttributes + m_propertyName + "(\"" + m_propertyInspectorName + "\", Int) = " + m_defaultValue; } public override void UpdateMaterial( Material mat ) { base.UpdateMaterial( mat ); if( UIUtils.IsProperty( m_currentParameterType ) && !InsideShaderFunction ) { mat.SetInt( m_propertyName, m_materialValue ); } } public override void SetMaterialMode( Material mat, bool fetchMaterialValues ) { base.SetMaterialMode( mat, fetchMaterialValues ); if( fetchMaterialValues && m_materialMode && UIUtils.IsProperty( m_currentParameterType ) && mat.HasProperty( m_propertyName ) ) { m_materialValue = mat.GetInt( m_propertyName ); } } public override void ForceUpdateFromMaterial( Material material ) { if( UIUtils.IsProperty( m_currentParameterType ) && material.HasProperty( m_propertyName ) ) { m_materialValue = material.GetInt( m_propertyName ); PreviewIsDirty = true; } } public override void ReadFromString( ref string[] nodeParams ) { base.ReadFromString( ref nodeParams ); m_defaultValue = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); if( UIUtils.CurrentShaderVersion() > 14101 ) m_materialValue = Convert.ToInt32( GetCurrentParam( ref nodeParams ) ); if( UIUtils.CurrentShaderVersion() > 18500 ) m_setAsUINT = Convert.ToBoolean( GetCurrentParam( ref nodeParams ) ); } public override void WriteToString( ref string nodeInfo, ref string connectionsInfo ) { base.WriteToString( ref nodeInfo, ref connectionsInfo ); IOUtils.AddFieldValueToString( ref nodeInfo, m_defaultValue ); IOUtils.AddFieldValueToString( ref nodeInfo, m_materialValue ); IOUtils.AddFieldValueToString( ref nodeInfo, m_setAsUINT ); } public override string GetPropertyValStr() { return ( m_materialMode && m_currentParameterType != PropertyType.Constant ) ? m_materialValue.ToString( Mathf.Abs( m_materialValue ) > 1000 ? Constants.PropertyBigIntFormatLabel : Constants.PropertyIntFormatLabel ) : m_defaultValue.ToString( Mathf.Abs( m_defaultValue ) > 1000 ? Constants.PropertyBigIntFormatLabel : Constants.PropertyIntFormatLabel ); } public override void SetGlobalValue() { Shader.SetGlobalInt( m_propertyName, m_defaultValue ); } public override void FetchGlobalValue() { m_materialValue = Shader.GetGlobalInt( m_propertyName ); } public int Value { get { return m_defaultValue; } set { m_defaultValue = value; } } public void SetMaterialValueFromInline( int val ) { m_materialValue = val; m_requireMaterialUpdate = true; } } }