├── Editor.meta ├── Editor ├── NoteDrawer.cs ├── NoteDrawer.cs.meta ├── SI.NoteAttribute.Editor.asmdef └── SI.NoteAttribute.Editor.asmdef.meta ├── LICENSE ├── LICENSE.meta ├── README.md ├── README.md.meta ├── Runtime.meta ├── Runtime ├── NoteAttribute.cs ├── NoteAttribute.cs.meta ├── SI.NoteAttribute.Runtime.asmdef └── SI.NoteAttribute.Runtime.asmdef.meta ├── package.json ├── package.json.meta ├── preview.png └── preview.png.meta /Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c91682881ba12d946b5ed37daec953bf 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Editor/NoteDrawer.cs: -------------------------------------------------------------------------------- 1 | // https://github.com/ShadowIgnition/Unity-Note-Attribute 2 | using UnityEditor; 3 | using UnityEngine; 4 | 5 | namespace SI.Note 6 | { 7 | [CustomPropertyDrawer(typeof(NoteAttribute))] 8 | public class NoteDrawer : DecoratorDrawer 9 | { 10 | // 11 | /// Overrides OnGUI() to draw the note attribute in the Inspector. 12 | /// 13 | /// The position of the drawer in the Inspector. 14 | public override void OnGUI(Rect position) 15 | { 16 | CachePreviewHeight(Attribute.Description, position.width); 17 | 18 | if (m_Height != m_ScrollViewHeight) 19 | { 20 | Rect scrollArea = GetRect(position, true); 21 | Rect content = scrollArea; 22 | 23 | // Adjust xMax to account for vertical scrollbar 24 | content.xMax -= 14; 25 | 26 | using (var scrollScope = new GUI.ScrollViewScope(position, scrollPos, content)) 27 | { 28 | scrollPos = scrollScope.scrollPosition; 29 | GUI.Box(content, Attribute.Description, GetNoteStyle()); 30 | } 31 | } 32 | else 33 | { 34 | GUI.Box(GetRect(position, false), Attribute.Description, GetNoteStyle()); 35 | } 36 | } 37 | 38 | /// 39 | /// Gets the height of the drawer. 40 | /// 41 | /// The height of the drawer. 42 | public override float GetHeight() 43 | { 44 | return m_Height; 45 | } 46 | 47 | /// 48 | /// Gets the cached note style. 49 | /// 50 | /// The GUIStyle for the note. 51 | static GUIStyle GetNoteStyle() 52 | { 53 | if (Style == null) 54 | { 55 | GUIStyle style = GUI.skin.box; 56 | style.padding = new RectOffset(4, 16, 4, 4); 57 | style.normal.background = Texture2D.grayTexture; 58 | style.wordWrap = true; 59 | style.alignment = TextAnchor.UpperLeft; 60 | style.richText = true; 61 | Style = style; 62 | } 63 | return Style; 64 | } 65 | 66 | /// 67 | /// Caches the height of the note text area. 68 | /// 69 | /// The note string. 70 | /// The width of the text area. 71 | void CachePreviewHeight(string note, float width) 72 | { 73 | if (Attribute.LineHeight > 0) 74 | { 75 | // If a custom line height is specified, use it 76 | m_Height = GetPaddedLineHeight(Attribute.LineHeight); 77 | m_ScrollViewHeight = m_Height; 78 | } 79 | else 80 | { 81 | // Calculate the height of the text area 82 | m_Height = GUI.skin.textArea.CalcHeight(new GUIContent(note), width) + (GUI.skin.textArea.lineHeight / 2); 83 | 84 | // Store the unclamped height, so we can use for a scroll view later if needed 85 | m_ScrollViewHeight = m_Height; 86 | 87 | // Clamp the height within the specified range (Don't want to be able to make the editor preview too big) 88 | m_Height = Mathf.Clamp(m_Height, GetPaddedLineHeight(AUTO_MIN_HEIGHT), GetPaddedLineHeight(AUTO_MAX_HEIGHT)); 89 | } 90 | } 91 | 92 | /// 93 | /// Gets the rect for drawing the note area. 94 | /// 95 | /// The position of the drawer in the Inspector. 96 | /// Flag indicating if the drawer is part of a scroll view. 97 | /// The rect for drawing the note area. 98 | Rect GetRect(Rect position, bool isScrollView) 99 | { 100 | return new Rect(position.x, position.y, position.width, isScrollView ? m_ScrollViewHeight : m_Height); 101 | } 102 | 103 | /// 104 | /// Gets the padded line height based on the number of lines. 105 | /// 106 | /// The number of lines. 107 | /// The padded line height. 108 | float GetPaddedLineHeight(uint lineCount) 109 | { 110 | return (GUI.skin.textArea.lineHeight * lineCount) + (GUI.skin.textArea.lineHeight / 2); 111 | } 112 | 113 | /// 114 | /// Gets the associated with this drawer. 115 | /// 116 | NoteAttribute Attribute { get { return attribute as NoteAttribute; } } 117 | 118 | static GUIStyle Style; 119 | 120 | Vector2 scrollPos; // Current Scroll position 121 | float m_Height; // Height of the note text area 122 | float m_ScrollViewHeight; // Height of the note text area 123 | 124 | const uint AUTO_MAX_HEIGHT = 5; // Maximum number of lines for the text area 125 | const uint AUTO_MIN_HEIGHT = 2; // Minimum number of lines for the text area 126 | } 127 | } -------------------------------------------------------------------------------- /Editor/NoteDrawer.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98e6c31863c24724383bdaf9161c130f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Editor/SI.NoteAttribute.Editor.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SI.NoteAttribute.Editor", 3 | "rootNamespace": "", 4 | "references": [ 5 | "GUID:d281c34580c69d141a9e39cef15ed80d" 6 | ], 7 | "includePlatforms": [ 8 | "Editor" 9 | ], 10 | "excludePlatforms": [], 11 | "allowUnsafeCode": false, 12 | "overrideReferences": false, 13 | "precompiledReferences": [], 14 | "autoReferenced": true, 15 | "defineConstraints": [], 16 | "versionDefines": [], 17 | "noEngineReferences": false 18 | } -------------------------------------------------------------------------------- /Editor/SI.NoteAttribute.Editor.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6a5eb41c8e6408f47a4186ad1747d7be 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 ShadowIgnition 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSE.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 537454a68b537804e910d4b58441412f 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Note Attribute 2 | 3 | The `NoteAttribute` is a custom attribute used for creating Inspector notes in Unity, helpful in streamlining design processes. 4 | 5 | ![Note Attribute](preview.png) 6 | 7 | ## Usage 8 | To use the `NoteAttribute`, follow these steps: 9 | 10 | 1. Attach the `NoteAttribute` to a serialized field in a MonoBehaviour script or a ScriptableObject. 11 | 2. Provide the note description as a string parameter when creating an instance of the `NoteAttribute`. 12 | 3. Optionally, you can specify the line height for the note by providing a `uint` value as the second parameter. A value of 0 indicates auto-sizing. 13 | 14 | In this example, the `NoteAttribute` is attached to the `myField` serialized field in the `MyScript` MonoBehaviour. The provided note description will be displayed in the Unity Inspector for the `myField` field. 15 | 16 | ```csharp 17 | using SI.Note 18 | { 19 | public class MyScript : MonoBehaviour 20 | { 21 | [Note("This is a note for the field.")] 22 | public int myField; 23 | 24 | [Note(3, "This is a note with a custom line height.")] 25 | public int myField; 26 | } 27 | } 28 | ``` 29 | 30 | 4. Save your script and go back to the Unity Editor. Open the Inspector for the object that contains the script you just modified. 31 | 32 | 5. In the Inspector, you will now see a note above the associated field. 33 | 34 | ## How to add to your Unity Project via Package Manager 35 | 36 | To add this your package to your Unity project via the Package Manager, follow these steps: 37 | 38 | 1. Open your Unity project. 39 | 2. Open the Package Manager window by going to `Window > Package Manager`. 40 | 3. Click on the `+` button in the top left corner of the Package Manager window. 41 | 4. Select "Add package from git URL...". 42 | 5. In the text field that appears, enter the URL of your repository, adding `.git` to the end of the url. (Example: `https://github.com/ShadowIgnition/Unity-Note-Attribute.git`) 43 | 6. Click the `Add` button. 44 | 45 | The package will now be added to your project! 46 | 47 | 48 | ## Customization 49 | You can customize the appearance and behavior of the note drawer by modifying the following constants in the `NoteDrawer` class: 50 | 51 | - `AUTO_MAX_HEIGHT`: Maximum number of lines for the note text area (auto-sizing only). 52 | - `AUTO_MIN_HEIGHT`: Minimum number of lines for the note text area (auto-sizing only). 53 | 54 | You can also modify the `GetNoteStyle` method to change the visual style of the note box. 55 | 56 | ## Notes 57 | 58 | - The `NoteAttribute` is purely for preview purposes in the Unity Inspector and does not affect the runtime behavior of your game or application. 59 | 60 | - If you find the `NoteAttribute` helpful, please consider giving it a star on the GitHub repository. Your support is greatly appreciated! 61 | 62 | ## License 63 | 64 | The `NoteAttribute` is provided as-is under the terms of the MIT License. Feel free to modify and adapt it to suit your needs. 65 | -------------------------------------------------------------------------------- /README.md.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dc3763379639c004192accc4e3175855 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 009a7d9cfac97ee4b8de81b1658ddaa6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Runtime/NoteAttribute.cs: -------------------------------------------------------------------------------- 1 | // https://github.com/ShadowIgnition/Unity-Note-Attribute 2 | using UnityEngine; 3 | 4 | namespace SI.Note 5 | { 6 | /// 7 | /// Custom attribute class used for creating Inspector notes 8 | /// 9 | public class NoteAttribute : PropertyAttribute 10 | { 11 | /// 12 | /// The text contained in the note. 13 | /// 14 | public readonly string Description; 15 | 16 | /// 17 | /// The line height for the localized string translation. A value of 0 indicates auto-sizing. 18 | /// 19 | public readonly uint LineHeight = 0; 20 | 21 | /// 22 | /// Initializes a new instance of the class with the specified description and (auto-sizing) line height. 23 | /// 24 | /// The text description for the note. 25 | public NoteAttribute(string description) 26 | { 27 | Description = description; 28 | } 29 | 30 | /// 31 | /// Initializes a new instance of the class with the specified description and line height. 32 | /// 33 | /// The line height for the note, A value of 0 indicates auto-sizing. 34 | /// The text description for the note. 35 | public NoteAttribute(uint lineHeight, string description) 36 | { 37 | Description = description; 38 | LineHeight = lineHeight; 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /Runtime/NoteAttribute.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 32672e269ac4eee4c94a86e1ee87d581 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Runtime/SI.NoteAttribute.Runtime.asmdef: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SI.NoteAttribute" 3 | } 4 | -------------------------------------------------------------------------------- /Runtime/SI.NoteAttribute.Runtime.asmdef.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d281c34580c69d141a9e39cef15ed80d 3 | AssemblyDefinitionImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.shadowignition.unitynoteattribute", 3 | "displayName": "Unity Note Attribute", 4 | "description": "The NoteAttribute is a custom attribute used for creating Inspector notes in Unity, helpful in streamlining design processes.", 5 | "version": "1.0.0", 6 | "unity": "2021.1", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "git+https://github.com/ShadowIgnition/Unity-Note-Attribute.git" 11 | }, 12 | "author": { 13 | "name": "shadowignition", 14 | "email": "43722770+ShadowIgnition@users.noreply.github.com", 15 | "url": "https://github.com/shadowignition" 16 | }, 17 | "dependencies": {} 18 | } 19 | -------------------------------------------------------------------------------- /package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f731803efca31064aa99359e27c70902 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ShadowIgnition/Unity-Note-Attribute/3af26dc6fa93d451d2a878b9feafe2e992f9cb61/preview.png -------------------------------------------------------------------------------- /preview.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8dc7acf1e576560448de3017f346b01d 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 12 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | vTOnly: 0 27 | ignoreMasterTextureLimit: 0 28 | grayScaleToAlpha: 0 29 | generateCubemap: 6 30 | cubemapConvolution: 0 31 | seamlessCubemap: 0 32 | textureFormat: 1 33 | maxTextureSize: 2048 34 | textureSettings: 35 | serializedVersion: 2 36 | filterMode: 1 37 | aniso: 1 38 | mipBias: 0 39 | wrapU: 1 40 | wrapV: 1 41 | wrapW: 1 42 | nPOTScale: 0 43 | lightmap: 0 44 | compressionQuality: 50 45 | spriteMode: 1 46 | spriteExtrude: 1 47 | spriteMeshType: 1 48 | alignment: 0 49 | spritePivot: {x: 0.5, y: 0.5} 50 | spritePixelsToUnits: 100 51 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 52 | spriteGenerateFallbackPhysicsShape: 1 53 | alphaUsage: 1 54 | alphaIsTransparency: 1 55 | spriteTessellationDetail: -1 56 | textureType: 8 57 | textureShape: 1 58 | singleChannelComponent: 0 59 | flipbookRows: 1 60 | flipbookColumns: 1 61 | maxTextureSizeSet: 0 62 | compressionQualitySet: 0 63 | textureFormatSet: 0 64 | ignorePngGamma: 0 65 | applyGammaDecoding: 0 66 | cookieLightType: 0 67 | platformSettings: 68 | - serializedVersion: 3 69 | buildTarget: DefaultTexturePlatform 70 | maxTextureSize: 2048 71 | resizeAlgorithm: 0 72 | textureFormat: -1 73 | textureCompression: 1 74 | compressionQuality: 50 75 | crunchedCompression: 0 76 | allowsAlphaSplitting: 0 77 | overridden: 0 78 | androidETC2FallbackOverride: 0 79 | forceMaximumCompressionQuality_BC6H_BC7: 0 80 | - serializedVersion: 3 81 | buildTarget: Standalone 82 | maxTextureSize: 2048 83 | resizeAlgorithm: 0 84 | textureFormat: -1 85 | textureCompression: 1 86 | compressionQuality: 50 87 | crunchedCompression: 0 88 | allowsAlphaSplitting: 0 89 | overridden: 0 90 | androidETC2FallbackOverride: 0 91 | forceMaximumCompressionQuality_BC6H_BC7: 0 92 | - serializedVersion: 3 93 | buildTarget: Server 94 | maxTextureSize: 2048 95 | resizeAlgorithm: 0 96 | textureFormat: -1 97 | textureCompression: 1 98 | compressionQuality: 50 99 | crunchedCompression: 0 100 | allowsAlphaSplitting: 0 101 | overridden: 0 102 | androidETC2FallbackOverride: 0 103 | forceMaximumCompressionQuality_BC6H_BC7: 0 104 | spriteSheet: 105 | serializedVersion: 2 106 | sprites: [] 107 | outline: [] 108 | physicsShape: [] 109 | bones: [] 110 | spriteID: 5e97eb03825dee720800000000000000 111 | internalID: 0 112 | vertices: [] 113 | indices: 114 | edges: [] 115 | weights: [] 116 | secondaryTextures: [] 117 | nameFileIdTable: {} 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 0 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | --------------------------------------------------------------------------------