├── 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 | 
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 |
--------------------------------------------------------------------------------