├── src ├── UnityUxmlGenerator.UnityPackage │ ├── ProjectSettings │ │ ├── boot.config │ │ ├── ProjectVersion.txt │ │ ├── ClusterInputManager.asset │ │ ├── PresetManager.asset │ │ ├── NetworkManager.asset │ │ ├── XRSettings.asset │ │ ├── VersionControlSettings.asset │ │ ├── TimeManager.asset │ │ ├── EditorBuildSettings.asset │ │ ├── VFXManager.asset │ │ ├── AudioManager.asset │ │ ├── TagManager.asset │ │ ├── UnityConnectSettings.asset │ │ ├── PackageManagerSettings.asset │ │ ├── MemorySettings.asset │ │ ├── EditorSettings.asset │ │ ├── DynamicsManager.asset │ │ ├── NavMeshAreas.asset │ │ ├── Physics2DSettings.asset │ │ ├── GraphicsSettings.asset │ │ ├── SceneTemplateSettings.json │ │ ├── QualitySettings.asset │ │ ├── InputManager.asset │ │ └── ProjectSettings.asset │ ├── Assets │ │ ├── Scenes.meta │ │ ├── Scenes │ │ │ ├── SampleScene.unity.meta │ │ │ └── SampleScene.unity │ │ ├── Plugins.meta │ │ └── Plugins │ │ │ ├── UnityUxmlGenerator │ │ │ ├── Runtime │ │ │ │ ├── UnityUxmlGenerator.dll │ │ │ │ └── UnityUxmlGenerator.dll.meta │ │ │ ├── package.json.meta │ │ │ ├── Runtime.meta │ │ │ └── package.json │ │ │ └── UnityUxmlGenerator.meta │ ├── .gitignore │ ├── Packages │ │ ├── manifest.json │ │ └── packages-lock.json │ └── .gitattributes └── UnityUxmlGenerator │ ├── Usings.cs │ ├── System.Runtime.CompilerServices │ └── IsExternalInit.cs │ ├── Extensions │ ├── PropertySyntaxExtensions.cs │ ├── StringExtensions.cs │ ├── BaseTypeDeclarationSyntaxExtensions.cs │ ├── SyntaxNodeExtensions.cs │ ├── TypeSyntaxExtensions.cs │ └── StringBuilderExtensions.cs │ ├── Diagnostics │ ├── DiagnosticExtensions.cs │ └── DiagnosticDescriptors.cs │ ├── Structs │ └── UxmlAttributeInfo.cs │ ├── Captures │ ├── UxmlFactoryCapture.cs │ ├── BaseCapture.cs │ └── UxmlTraitsCapture.cs │ ├── SyntaxReceivers │ ├── VisualElementReceiver.cs │ ├── BaseReceiver.cs │ ├── UxmlFactoryReceiver.cs │ └── UxmlTraitsReceiver.cs │ ├── UnityUxmlGenerator.csproj │ ├── UxmlGenerator.Factory.cs │ ├── UxmlGenerator.cs │ ├── UxmlGenerator.Attributes.cs │ ├── UxmlGenerator.Traits.cs │ └── UxmlGenerator.Widgets.cs ├── .idea └── .idea.UnityUxmlGenerator │ └── .idea │ ├── encodings.xml │ ├── vcs.xml │ ├── indexLayout.xml │ └── .gitignore ├── UnityUxmlGenerator.sln.DotSettings ├── .github └── FUNDING.yml ├── LICENSE ├── UnityUxmlGenerator.sln ├── .gitignore └── README.md /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/boot.config: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2021.3.22f1 2 | m_EditorVersionWithRevision: 2021.3.22f1 (b6c551784ba3) 3 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Usings.cs: -------------------------------------------------------------------------------- 1 | global using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; 2 | global using static UnityUxmlGenerator.Diagnostics.DiagnosticDescriptors; -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /.idea/.idea.UnityUxmlGenerator/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/.idea.UnityUxmlGenerator/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_DefaultPresets: {} 8 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 131a6b21c8605f84396be9f6751fb6e3 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Scenes/SampleScene.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2cda990e2423bbf4892e6590ba056729 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/NetworkManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!149 &1 4 | NetworkManager: 5 | m_ObjectHideFlags: 0 6 | m_DebugLevel: 0 7 | m_Sendrate: 15 8 | m_AssetToPrefab: {} 9 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Plugins.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 06bb5baac2ee92646b5177fa73cc4be0 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator/Runtime/UnityUxmlGenerator.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LibraStack/UnityUxmlGenerator/HEAD/src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator/Runtime/UnityUxmlGenerator.dll -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator/package.json.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 63e5d4e3919e04742b2e84384322e4fd 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /.idea/.idea.UnityUxmlGenerator/.idea/indexLayout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 533c13924400c324bbc7e322c226a51a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator/Runtime.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 50c63eac4e26da2449c6a692addd9b19 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/VersionControlSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!890905787 &1 4 | VersionControlSettings: 5 | m_ObjectHideFlags: 0 6 | m_Mode: Visible Meta Files 7 | m_CollabEditorSettings: 8 | inProgressEnabled: 1 9 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/System.Runtime.CompilerServices/IsExternalInit.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel; 2 | 3 | // ReSharper disable CheckNamespace 4 | // ReSharper disable UnusedType.Global 5 | 6 | namespace System.Runtime.CompilerServices; 7 | 8 | [EditorBrowsable(EditorBrowsableState.Never)] 9 | internal static class IsExternalInit 10 | { 11 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Extensions/PropertySyntaxExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | 3 | namespace UnityUxmlGenerator.Extensions; 4 | 5 | internal static class PropertySyntaxExtensions 6 | { 7 | public static string GetName(this PropertyDeclarationSyntax property) 8 | { 9 | return property.Identifier.Text; 10 | } 11 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Scenes/SampleScene.unity 10 | guid: 2cda990e2423bbf4892e6590ba056729 11 | m_configObjects: {} 12 | -------------------------------------------------------------------------------- /.idea/.idea.UnityUxmlGenerator/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Rider ignored files 5 | /.idea.UnityUxmlGenerator.iml 6 | /modules.xml 7 | /projectSettingsUpdater.xml 8 | /contentModel.xml 9 | # Editor-based HTTP Client requests 10 | /httpRequests/ 11 | # Datasource local storage ignored files 12 | /dataSources/ 13 | /dataSources.local.xml 14 | -------------------------------------------------------------------------------- /UnityUxmlGenerator.sln.DotSettings: -------------------------------------------------------------------------------- 1 | 2 | True -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Diagnostics/DiagnosticExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace UnityUxmlGenerator.Diagnostics; 4 | 5 | internal static class DiagnosticExtensions 6 | { 7 | public static Diagnostic CreateDiagnostic(this DiagnosticDescriptor descriptor, Location location, params object?[]? args) 8 | { 9 | return Diagnostic.Create(descriptor, location, args); 10 | } 11 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_StripUpdateShader: {fileID: 0} 10 | m_RenderPipeSettingsPath: 11 | m_FixedTimeStep: 0.016666668 12 | m_MaxDeltaTime: 0.05 13 | m_CompiledVersion: 0 14 | m_RuntimeVersion: 0 15 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Structs/UxmlAttributeInfo.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | 3 | namespace UnityUxmlGenerator.Structs; 4 | 5 | public ref struct UxmlAttributeInfo 6 | { 7 | public string PropertyName { get; init; } 8 | public string PrivateFieldName { get; init; } 9 | public string AttributeUxmlName { get; init; } 10 | 11 | public string TypeIdentifier { get; set; } 12 | public ExpressionSyntax DefaultValueAssignmentExpression { get; set; } 13 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Captures/UxmlFactoryCapture.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | 3 | namespace UnityUxmlGenerator.Captures; 4 | 5 | internal sealed class UxmlFactoryCapture : BaseCapture 6 | { 7 | public UxmlFactoryCapture(ClassDeclarationSyntax @class, AttributeSyntax attribute) : base(@class) 8 | { 9 | Attribute = attribute; 10 | } 11 | 12 | public override string ClassTag => "UxmlFactory"; 13 | 14 | public AttributeSyntax Attribute { get; } 15 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Volume: 1 8 | Rolloff Scale: 1 9 | Doppler Factor: 1 10 | Default Speaker Mode: 2 11 | m_SampleRate: 0 12 | m_DSPBufferSize: 1024 13 | m_VirtualVoiceCount: 512 14 | m_RealVoiceCount: 32 15 | m_SpatializerPlugin: 16 | m_AmbisonicDecoderPlugin: 17 | m_DisableAudio: 0 18 | m_VirtualizeEffects: 1 19 | m_RequestedDSPBufferSize: 0 20 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "com.chebanovdd.unityuxmlgenerator", 3 | "displayName": "Unity Uxml Generator", 4 | "author": { "name": "ChebanovDD", "url": "https://github.com/ChebanovDD" }, 5 | "version": "0.0.7", 6 | "unity": "2018.4", 7 | "description": "The Unity Uxml Generator allows you to generate 'UxmlFactory' and 'UxmlTraits' source code for a custom 'VisualElement'. Just mark elements with [UxmlElement] and [UxmlAttribute] attributes.", 8 | "keywords": [ "uxml", "source", "generator" ] 9 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/SyntaxReceivers/VisualElementReceiver.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace UnityUxmlGenerator.SyntaxReceivers; 4 | 5 | internal sealed class VisualElementReceiver : ISyntaxReceiver 6 | { 7 | public UxmlFactoryReceiver UxmlFactoryReceiver { get; } = new(); 8 | public UxmlTraitsReceiver UxmlTraitsReceiver { get; } = new(); 9 | 10 | public void OnVisitSyntaxNode(SyntaxNode syntaxNode) 11 | { 12 | UxmlFactoryReceiver.OnVisitSyntaxNode(syntaxNode); 13 | UxmlTraitsReceiver.OnVisitSyntaxNode(syntaxNode); 14 | } 15 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Captures/BaseCapture.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | using UnityUxmlGenerator.Extensions; 3 | 4 | namespace UnityUxmlGenerator.Captures; 5 | 6 | internal abstract class BaseCapture 7 | { 8 | protected BaseCapture(ClassDeclarationSyntax @class) 9 | { 10 | Class = @class; 11 | ClassName = @class.Identifier.Text; 12 | ClassNamespace = @class.GetParent()?.Name.ToString(); 13 | } 14 | 15 | public string ClassName { get; } 16 | public string? ClassNamespace { get; } 17 | public abstract string ClassTag { get; } 18 | 19 | public ClassDeclarationSyntax Class { get; } 20 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/SyntaxReceivers/BaseReceiver.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using UnityUxmlGenerator.Diagnostics; 3 | 4 | namespace UnityUxmlGenerator.SyntaxReceivers; 5 | 6 | internal abstract class BaseReceiver : ISyntaxReceiver 7 | { 8 | private readonly List _diagnostics = new(); 9 | 10 | public IEnumerable Diagnostics => _diagnostics; 11 | 12 | public abstract void OnVisitSyntaxNode(SyntaxNode syntaxNode); 13 | 14 | protected void RegisterDiagnostic(DiagnosticDescriptor diagnosticDescriptor, Location location, 15 | params object?[]? args) 16 | { 17 | _diagnostics.Add(diagnosticDescriptor.CreateDiagnostic(location, args)); 18 | } 19 | } -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: DimaChebanov 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: ["https://boosty.to/dimachebanov/about"] # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/UnityUxmlGenerator.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netstandard2.0 5 | enable 6 | 11 7 | false 8 | enable 9 | true 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | $(ProjectDir)..\UnityUxmlGenerator.UnityPackage\Assets\Plugins\UnityUxmlGenerator\Runtime\ 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Dima 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 | -------------------------------------------------------------------------------- /UnityUxmlGenerator.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{28B16CBC-CA44-4ECF-88C1-F2347348A635}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnityUxmlGenerator", "src\UnityUxmlGenerator\UnityUxmlGenerator.csproj", "{F8D3D995-5DBC-490A-AA0B-36710A6E5226}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(NestedProjects) = preSolution 13 | {F8D3D995-5DBC-490A-AA0B-36710A6E5226} = {28B16CBC-CA44-4ECF-88C1-F2347348A635} 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {F8D3D995-5DBC-490A-AA0B-36710A6E5226}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {F8D3D995-5DBC-490A-AA0B-36710A6E5226}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {F8D3D995-5DBC-490A-AA0B-36710A6E5226}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {F8D3D995-5DBC-490A-AA0B-36710A6E5226}.Release|Any CPU.Build.0 = Release|Any CPU 20 | EndGlobalSection 21 | EndGlobal 22 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_DashboardUrl: https://dashboard.unity3d.com 13 | m_TestInitMode: 0 14 | CrashReportingSettings: 15 | m_EventUrl: https://perf-events.cloud.unity3d.com 16 | m_Enabled: 0 17 | m_LogBufferSize: 10 18 | m_CaptureEditorExceptions: 1 19 | UnityPurchasingSettings: 20 | m_Enabled: 0 21 | m_TestMode: 0 22 | UnityAnalyticsSettings: 23 | m_Enabled: 0 24 | m_TestMode: 0 25 | m_InitializeOnStartup: 1 26 | m_PackageRequiringCoreStatsPresent: 0 27 | UnityAdsSettings: 28 | m_Enabled: 0 29 | m_InitializeOnStartup: 1 30 | m_TestMode: 0 31 | m_IosGameId: 32 | m_AndroidGameId: 33 | m_GameIds: {} 34 | m_GameId: 35 | PerformanceReportingSettings: 36 | m_Enabled: 0 37 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace UnityUxmlGenerator.Extensions; 4 | 5 | internal static class StringExtensions 6 | { 7 | public static string FirstCharToUpper(this string str) 8 | { 9 | return $"{char.ToUpper(str[0])}{str.Substring(1)}"; 10 | } 11 | 12 | public static string ToPrivateFieldName(this string propertyName) 13 | { 14 | return string.Concat("_", char.ToLower(propertyName[0]), propertyName.Substring(1)); 15 | } 16 | 17 | public static string ToDashCase(this string propertyName) 18 | { 19 | var stringBuilder = new StringBuilder(); 20 | 21 | stringBuilder.Append(char.ToLower(propertyName[0])); 22 | 23 | for (var i = 1; i < propertyName.Length; i++) 24 | { 25 | if (char.IsUpper(propertyName[i])) 26 | { 27 | stringBuilder.Append("-"); 28 | stringBuilder.Append(char.ToLower(propertyName[i])); 29 | } 30 | else 31 | { 32 | stringBuilder.Append(propertyName[i]); 33 | } 34 | } 35 | 36 | return stringBuilder.ToString(); 37 | } 38 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Extensions/BaseTypeDeclarationSyntaxExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | 5 | namespace UnityUxmlGenerator.Extensions; 6 | 7 | internal static class BaseTypeDeclarationSyntaxExtensions 8 | { 9 | public static bool InheritsFromAnyType(this BaseTypeDeclarationSyntax? @class) 10 | { 11 | return @class?.BaseList is not null && @class.BaseList.Types.Count != 0; 12 | } 13 | 14 | public static bool InheritsFromFullyQualifiedName(this BaseTypeDeclarationSyntax @class, 15 | GeneratorExecutionContext context, string name) 16 | { 17 | INamedTypeSymbol? symbol = context.Compilation.GetSemanticModel(@class.SyntaxTree).GetDeclaredSymbol(@class); 18 | 19 | if (symbol?.ToString() == name) 20 | { 21 | return true; 22 | } 23 | 24 | symbol = symbol?.BaseType; 25 | 26 | while (symbol != null) 27 | { 28 | if (symbol.ToString() == name) 29 | { 30 | return true; 31 | } 32 | 33 | symbol = symbol.BaseType; 34 | } 35 | 36 | return false; 37 | } 38 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/UxmlGenerator.Factory.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.Text; 4 | using UnityUxmlGenerator.Captures; 5 | 6 | namespace UnityUxmlGenerator; 7 | 8 | internal sealed partial class UxmlGenerator 9 | { 10 | private const string FactoryBaseTypeIdentifier = "global::UnityEngine.UIElements.UxmlFactory<{0}, UxmlTraits>"; 11 | 12 | private static SourceText GenerateUxmlFactory(UxmlFactoryCapture capture) 13 | { 14 | return CompilationUnitWidget( 15 | namespaceIdentifier: capture.ClassNamespace, 16 | member: ClassWidget( 17 | identifier: capture.ClassName, 18 | modifier: SyntaxKind.PartialKeyword, 19 | member: ClassWidget( 20 | identifier: "UxmlFactory", 21 | modifiers: new[] { SyntaxKind.PublicKeyword, SyntaxKind.NewKeyword }, 22 | baseType: SimpleBaseType(IdentifierName(string.Format(FactoryBaseTypeIdentifier, capture.ClassName))), 23 | addGeneratedCodeAttributes: true 24 | )), 25 | normalizeWhitespace: true) 26 | .GetText(Encoding.UTF8); 27 | } 28 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/PackageManagerSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &1 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 61 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: 14 | m_EditorClassIdentifier: 15 | m_EnablePreReleasePackages: 0 16 | m_EnablePackageDependencies: 0 17 | m_AdvancedSettingsExpanded: 1 18 | m_ScopedRegistriesSettingsExpanded: 1 19 | m_SeeAllPackageVersions: 0 20 | oneTimeWarningShown: 0 21 | m_Registries: 22 | - m_Id: main 23 | m_Name: 24 | m_Url: https://packages.unity.com 25 | m_Scopes: [] 26 | m_IsDefault: 1 27 | m_Capabilities: 7 28 | m_UserSelectedRegistryName: 29 | m_UserAddingNewScopedRegistry: 0 30 | m_RegistryInfoDraft: 31 | m_ErrorMessage: 32 | m_Original: 33 | m_Id: 34 | m_Name: 35 | m_Url: 36 | m_Scopes: [] 37 | m_IsDefault: 0 38 | m_Capabilities: 0 39 | m_Modified: 0 40 | m_Name: 41 | m_Url: 42 | m_Scopes: 43 | - 44 | m_SelectedScopeIndex: 0 45 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/SyntaxReceivers/UxmlFactoryReceiver.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp.Syntax; 3 | using UnityUxmlGenerator.Captures; 4 | using UnityUxmlGenerator.Extensions; 5 | 6 | namespace UnityUxmlGenerator.SyntaxReceivers; 7 | 8 | internal sealed class UxmlFactoryReceiver : BaseReceiver 9 | { 10 | private const string AttributeName = "UxmlElement"; 11 | 12 | private readonly List _captures = new(); 13 | 14 | public IEnumerable Captures => _captures; 15 | 16 | public override void OnVisitSyntaxNode(SyntaxNode syntaxNode) 17 | { 18 | if (syntaxNode.IsAttributeWithName(AttributeName, out var attribute) == false) 19 | { 20 | return; 21 | } 22 | 23 | var member = attribute!.GetParent(); 24 | if (member is not ClassDeclarationSyntax @class) 25 | { 26 | return; 27 | } 28 | 29 | if (@class.InheritsFromAnyType()) 30 | { 31 | _captures.Add(new UxmlFactoryCapture(@class, attribute!)); 32 | } 33 | else 34 | { 35 | RegisterDiagnostic(ClassHasNoBaseClassError, @class.GetLocation(), @class.Identifier.Text); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Captures/UxmlTraitsCapture.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp.Syntax; 2 | 3 | namespace UnityUxmlGenerator.Captures; 4 | 5 | internal sealed class UxmlTraitsCapture : BaseCapture 6 | { 7 | public UxmlTraitsCapture(ClassDeclarationSyntax @class, TypeSyntax baseClassType) : base(@class) 8 | { 9 | BaseClassType = baseClassType; 10 | Properties = new List<(PropertyDeclarationSyntax, AttributeSyntax)>(); 11 | } 12 | 13 | public override string ClassTag => "UxmlTraits"; 14 | 15 | public TypeSyntax BaseClassType { get; } 16 | public List<(PropertyDeclarationSyntax Property, AttributeSyntax Attribute)> Properties { get; } 17 | 18 | public string GetBaseClassName(out IEnumerable? genericTypeArguments) 19 | { 20 | if (BaseClassType is GenericNameSyntax genericNameSyntax) 21 | { 22 | genericTypeArguments = genericNameSyntax.TypeArgumentList.Arguments; 23 | return genericNameSyntax.Identifier.Text; 24 | } 25 | 26 | genericTypeArguments = default; 27 | 28 | if (BaseClassType is IdentifierNameSyntax identifierNameSyntax) 29 | { 30 | return identifierNameSyntax.Identifier.Text; 31 | } 32 | 33 | return BaseClassType.GetText().ToString().Trim(); 34 | } 35 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/MemorySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!387306366 &1 4 | MemorySettings: 5 | m_ObjectHideFlags: 0 6 | m_EditorMemorySettings: 7 | m_MainAllocatorBlockSize: -1 8 | m_ThreadAllocatorBlockSize: -1 9 | m_MainGfxBlockSize: -1 10 | m_ThreadGfxBlockSize: -1 11 | m_CacheBlockSize: -1 12 | m_TypetreeBlockSize: -1 13 | m_ProfilerBlockSize: -1 14 | m_ProfilerEditorBlockSize: -1 15 | m_BucketAllocatorGranularity: -1 16 | m_BucketAllocatorBucketsCount: -1 17 | m_BucketAllocatorBlockSize: -1 18 | m_BucketAllocatorBlockCount: -1 19 | m_ProfilerBucketAllocatorGranularity: -1 20 | m_ProfilerBucketAllocatorBucketsCount: -1 21 | m_ProfilerBucketAllocatorBlockSize: -1 22 | m_ProfilerBucketAllocatorBlockCount: -1 23 | m_TempAllocatorSizeMain: -1 24 | m_JobTempAllocatorBlockSize: -1 25 | m_BackgroundJobTempAllocatorBlockSize: -1 26 | m_JobTempAllocatorReducedBlockSize: -1 27 | m_TempAllocatorSizeGIBakingWorker: -1 28 | m_TempAllocatorSizeNavMeshWorker: -1 29 | m_TempAllocatorSizeAudioWorker: -1 30 | m_TempAllocatorSizeCloudWorker: -1 31 | m_TempAllocatorSizeGfx: -1 32 | m_TempAllocatorSizeJobWorker: -1 33 | m_TempAllocatorSizeBackgroundWorker: -1 34 | m_TempAllocatorSizePreloadManager: -1 35 | m_PlatformMemorySettings: {} 36 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/.gitignore: -------------------------------------------------------------------------------- 1 | # This .gitignore file should be placed at the root of your Unity project directory 2 | # 3 | # Get latest from https://github.com/github/gitignore/blob/master/Unity.gitignore 4 | # 5 | /[Ll]ibrary/ 6 | /[Tt]emp/ 7 | /[Oo]bj/ 8 | /[Bb]uild/ 9 | /[Bb]uilds/ 10 | /[Ll]ogs/ 11 | /[Mm]emoryCaptures/ 12 | /[Uu]serSettings/ 13 | 14 | # Asset meta data should only be ignored when the corresponding asset is also ignored 15 | !/[Aa]ssets/**/*.meta 16 | !/[Aa]ssets/**/*.tss 17 | !/[Pp]ackages/*.json 18 | 19 | # Uncomment this line if you wish to ignore the asset store tools plugin 20 | [Aa]ssets/AssetStoreTools* 21 | 22 | # Autogenerated Jetbrains Rider plugin 23 | .idea/ 24 | [Aa]ssets/Plugins/Editor/JetBrains* 25 | 26 | # Visual Studio cache directory 27 | .vs/ 28 | 29 | # Gradle cache directory 30 | .gradle/ 31 | 32 | # Autogenerated VS/MD/Consulo solution and project files 33 | ExportedObj/ 34 | .consulo/ 35 | *.csproj 36 | *.unityproj 37 | *.sln 38 | *.suo 39 | *.tmp 40 | *.user 41 | *.userprefs 42 | *.pidb 43 | *.booproj 44 | *.svd 45 | *.pdb 46 | *.mdb 47 | *.opendb 48 | *.VC.db 49 | 50 | # Unity3D generated files 51 | *.dwlt 52 | 53 | # Unity3D generated meta files 54 | *.pidb.meta 55 | *.pdb.meta 56 | *.mdb.meta 57 | 58 | # Unity3D generated file on crash reports 59 | sysinfo.txt 60 | 61 | # Builds 62 | *.apk 63 | *.unitypackage 64 | 65 | # Crashlytics generated file 66 | crashlytics-build.properties 67 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 11 7 | m_SerializationMode: 2 8 | m_LineEndingsForNewScripts: 0 9 | m_DefaultBehaviorMode: 1 10 | m_PrefabRegularEnvironment: {fileID: 0} 11 | m_PrefabUIEnvironment: {fileID: 0} 12 | m_SpritePackerMode: 4 13 | m_SpritePackerPaddingPower: 1 14 | m_EtcTextureCompressorBehavior: 1 15 | m_EtcTextureFastCompressor: 1 16 | m_EtcTextureNormalCompressor: 2 17 | m_EtcTextureBestCompressor: 4 18 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;asmref;rsp 19 | m_ProjectGenerationRootNamespace: 20 | m_EnableTextureStreamingInEditMode: 1 21 | m_EnableTextureStreamingInPlayMode: 1 22 | m_AsyncShaderCompilation: 1 23 | m_CachingShaderPreprocessor: 1 24 | m_PrefabModeAllowAutoSave: 1 25 | m_EnterPlayModeOptionsEnabled: 0 26 | m_EnterPlayModeOptions: 3 27 | m_GameObjectNamingDigits: 1 28 | m_GameObjectNamingScheme: 0 29 | m_AssetNamingUsesSpace: 1 30 | m_UseLegacyProbeSampleCount: 0 31 | m_SerializeInlineMappingsOnOneLine: 1 32 | m_DisableCookiesInLightmapper: 1 33 | m_AssetPipelineMode: 1 34 | m_CacheServerMode: 0 35 | m_CacheServerEndpoint: 36 | m_CacheServerNamespacePrefix: default 37 | m_CacheServerEnableDownload: 1 38 | m_CacheServerEnableUpload: 1 39 | m_CacheServerEnableAuth: 0 40 | m_CacheServerEnableTls: 0 41 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 13 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_DefaultMaxDepenetrationVelocity: 10 11 | m_SleepThreshold: 0.005 12 | m_DefaultContactOffset: 0.01 13 | m_DefaultSolverIterations: 6 14 | m_DefaultSolverVelocityIterations: 1 15 | m_QueriesHitBackfaces: 0 16 | m_QueriesHitTriggers: 1 17 | m_EnableAdaptiveForce: 0 18 | m_ClothInterCollisionDistance: 0.1 19 | m_ClothInterCollisionStiffness: 0.2 20 | m_ContactsGeneration: 1 21 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 22 | m_AutoSimulation: 1 23 | m_AutoSyncTransforms: 0 24 | m_ReuseCollisionCallbacks: 1 25 | m_ClothInterCollisionSettingsToggle: 0 26 | m_ClothGravity: {x: 0, y: -9.81, z: 0} 27 | m_ContactPairsMode: 0 28 | m_BroadphaseType: 0 29 | m_WorldBounds: 30 | m_Center: {x: 0, y: 0, z: 0} 31 | m_Extent: {x: 250, y: 250, z: 250} 32 | m_WorldSubdivisions: 8 33 | m_FrictionType: 0 34 | m_EnableEnhancedDeterminism: 0 35 | m_EnableUnifiedHeightmaps: 1 36 | m_SolverType: 0 37 | m_DefaultMaxAngularSpeed: 50 38 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | maxJobWorkers: 0 89 | preserveTilesOutsideBounds: 0 90 | debug: 91 | m_Flags: 0 92 | m_SettingNames: 93 | - Humanoid 94 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/SyntaxReceivers/UxmlTraitsReceiver.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp.Syntax; 3 | using UnityUxmlGenerator.Captures; 4 | using UnityUxmlGenerator.Extensions; 5 | 6 | namespace UnityUxmlGenerator.SyntaxReceivers; 7 | 8 | internal sealed class UxmlTraitsReceiver : BaseReceiver 9 | { 10 | private const string AttributeName = "UxmlAttribute"; 11 | 12 | private readonly Dictionary _captures = new(); 13 | 14 | public IReadOnlyDictionary Captures => _captures; 15 | 16 | public override void OnVisitSyntaxNode(SyntaxNode syntaxNode) 17 | { 18 | if (syntaxNode.IsAttributeWithName(AttributeName, out var attribute) == false) 19 | { 20 | return; 21 | } 22 | 23 | var member = attribute!.GetParent(); 24 | if (member is not PropertyDeclarationSyntax property) 25 | { 26 | return; 27 | } 28 | 29 | var @class = property.GetParent(); 30 | if (@class.InheritsFromAnyType() == false) 31 | { 32 | if (@class is null) 33 | { 34 | RegisterDiagnostic(ClassHasNoBaseClassError, property.GetLocation()); 35 | } 36 | else 37 | { 38 | RegisterDiagnostic(ClassHasNoBaseClassError, @class.GetLocation(), @class.Identifier.Text); 39 | } 40 | 41 | return; 42 | } 43 | 44 | if (_captures.TryGetValue(@class!.Identifier.Text, out var uxmlTraits) == false) 45 | { 46 | uxmlTraits = new UxmlTraitsCapture(@class, @class.BaseList!.Types.First().Type); 47 | _captures.Add(uxmlTraits.ClassName, uxmlTraits); 48 | } 49 | 50 | uxmlTraits.Properties.Add((property, attribute)); 51 | } 52 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Diagnostics/DiagnosticDescriptors.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | 3 | namespace UnityUxmlGenerator.Diagnostics; 4 | 5 | internal static class DiagnosticDescriptors 6 | { 7 | public static readonly DiagnosticDescriptor ClassHasNoBaseClassError = new( 8 | id: "UXMLG001", 9 | title: "Class has no base class", 10 | messageFormat: "Class '{0}' must be declared as a partial and be inherited from 'VisualElement' or one of its derived classes.", 11 | category: typeof(UxmlGenerator).FullName, 12 | defaultSeverity: DiagnosticSeverity.Error, 13 | isEnabledByDefault: true); 14 | 15 | public static readonly DiagnosticDescriptor ClassDoesNotInheritFromVisualElementError = new( 16 | id: "UXMLG002", 17 | title: "Class does not inherit from VisualElement", 18 | messageFormat: "Class '{0}' must be declared as a partial and be inherited from 'VisualElement' or one of its derived classes.", 19 | category: typeof(UxmlGenerator).FullName, 20 | defaultSeverity: DiagnosticSeverity.Error, 21 | isEnabledByDefault: true); 22 | 23 | public static readonly DiagnosticDescriptor PropertyTypeIsNotSupportedError = new( 24 | id: "UXMLG004", 25 | title: "Property type is not supported", 26 | messageFormat: "Property type '{0}' can not be used as an attribute.", 27 | category: typeof(UxmlGenerator).FullName, 28 | defaultSeverity: DiagnosticSeverity.Error, 29 | isEnabledByDefault: true); 30 | 31 | public static readonly DiagnosticDescriptor IncorrectEnumDefaultValueTypeError = new( 32 | id: "UXMLG005", 33 | title: "Type cannot be the default value for an enum", 34 | messageFormat: "Type '{0}' cannot be the default value for an enum.", 35 | category: typeof(UxmlGenerator).FullName, 36 | defaultSeverity: DiagnosticSeverity.Error, 37 | isEnabledByDefault: true); 38 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.collab-proxy": "2.0.4", 4 | "com.unity.feature.2d": "1.0.0", 5 | "com.unity.ide.rider": "3.0.21", 6 | "com.unity.ide.visualstudio": "2.0.18", 7 | "com.unity.ide.vscode": "1.2.5", 8 | "com.unity.test-framework": "1.1.33", 9 | "com.unity.textmeshpro": "3.0.6", 10 | "com.unity.timeline": "1.6.5", 11 | "com.unity.ugui": "1.0.0", 12 | "com.unity.visualscripting": "1.8.0", 13 | "com.unity.modules.ai": "1.0.0", 14 | "com.unity.modules.androidjni": "1.0.0", 15 | "com.unity.modules.animation": "1.0.0", 16 | "com.unity.modules.assetbundle": "1.0.0", 17 | "com.unity.modules.audio": "1.0.0", 18 | "com.unity.modules.cloth": "1.0.0", 19 | "com.unity.modules.director": "1.0.0", 20 | "com.unity.modules.imageconversion": "1.0.0", 21 | "com.unity.modules.imgui": "1.0.0", 22 | "com.unity.modules.jsonserialize": "1.0.0", 23 | "com.unity.modules.particlesystem": "1.0.0", 24 | "com.unity.modules.physics": "1.0.0", 25 | "com.unity.modules.physics2d": "1.0.0", 26 | "com.unity.modules.screencapture": "1.0.0", 27 | "com.unity.modules.terrain": "1.0.0", 28 | "com.unity.modules.terrainphysics": "1.0.0", 29 | "com.unity.modules.tilemap": "1.0.0", 30 | "com.unity.modules.ui": "1.0.0", 31 | "com.unity.modules.uielements": "1.0.0", 32 | "com.unity.modules.umbra": "1.0.0", 33 | "com.unity.modules.unityanalytics": "1.0.0", 34 | "com.unity.modules.unitywebrequest": "1.0.0", 35 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 36 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 37 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 38 | "com.unity.modules.unitywebrequestwww": "1.0.0", 39 | "com.unity.modules.vehicles": "1.0.0", 40 | "com.unity.modules.video": "1.0.0", 41 | "com.unity.modules.vr": "1.0.0", 42 | "com.unity.modules.wind": "1.0.0", 43 | "com.unity.modules.xr": "1.0.0" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator/Runtime/UnityUxmlGenerator.dll.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4bb5926bb4f2dc445b0b292be33eb471 3 | labels: 4 | - RoslynAnalyzer 5 | PluginImporter: 6 | externalObjects: {} 7 | serializedVersion: 2 8 | iconMap: {} 9 | executionOrder: {} 10 | defineConstraints: [] 11 | isPreloaded: 0 12 | isOverridable: 0 13 | isExplicitlyReferenced: 0 14 | validateReferences: 1 15 | platformData: 16 | - first: 17 | : Any 18 | second: 19 | enabled: 0 20 | settings: 21 | Exclude Android: 1 22 | Exclude Editor: 1 23 | Exclude Linux64: 1 24 | Exclude OSXUniversal: 1 25 | Exclude Win: 1 26 | Exclude Win64: 1 27 | Exclude iOS: 1 28 | - first: 29 | Android: Android 30 | second: 31 | enabled: 0 32 | settings: 33 | CPU: ARMv7 34 | - first: 35 | Any: 36 | second: 37 | enabled: 0 38 | settings: {} 39 | - first: 40 | Editor: Editor 41 | second: 42 | enabled: 0 43 | settings: 44 | CPU: AnyCPU 45 | DefaultValueInitialized: true 46 | OS: AnyOS 47 | - first: 48 | Standalone: Linux64 49 | second: 50 | enabled: 0 51 | settings: 52 | CPU: None 53 | - first: 54 | Standalone: OSXUniversal 55 | second: 56 | enabled: 0 57 | settings: 58 | CPU: None 59 | - first: 60 | Standalone: Win 61 | second: 62 | enabled: 0 63 | settings: 64 | CPU: None 65 | - first: 66 | Standalone: Win64 67 | second: 68 | enabled: 0 69 | settings: 70 | CPU: None 71 | - first: 72 | Windows Store Apps: WindowsStoreApps 73 | second: 74 | enabled: 0 75 | settings: 76 | CPU: AnyCPU 77 | - first: 78 | iPhone: iOS 79 | second: 80 | enabled: 0 81 | settings: 82 | AddToEmbeddedBinaries: false 83 | CPU: AnyCPU 84 | CompileFlags: 85 | FrameworkDependencies: 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Extensions/SyntaxNodeExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp.Syntax; 3 | 4 | namespace UnityUxmlGenerator.Extensions; 5 | 6 | internal static class SyntaxNodeExtensions 7 | { 8 | public static bool IsAttributeWithName(this SyntaxNode syntaxNode, string attributeName, 9 | out AttributeSyntax? attribute) 10 | { 11 | if (syntaxNode is not AttributeSyntax attributeSyntax) 12 | { 13 | attribute = default; 14 | return false; 15 | } 16 | 17 | attribute = attributeSyntax; 18 | 19 | switch (attributeSyntax.Name) 20 | { 21 | case IdentifierNameSyntax identifierNameSyntax 22 | when identifierNameSyntax.Identifier.Text.Contains(attributeName): 23 | case QualifiedNameSyntax qualifiedNameSyntax 24 | when qualifiedNameSyntax.Right.Identifier.Text.Contains(attributeName): 25 | return true; 26 | } 27 | 28 | return false; 29 | } 30 | 31 | public static T? GetParent(this SyntaxNode syntaxNode) 32 | { 33 | var parent = syntaxNode.Parent; 34 | 35 | while (parent != null) 36 | { 37 | if (parent is T result) 38 | { 39 | return result; 40 | } 41 | 42 | parent = parent.Parent; 43 | } 44 | 45 | return default; 46 | } 47 | 48 | public static ITypeSymbol? GetTypeSymbol(this SyntaxNode syntaxNode, GeneratorExecutionContext context) 49 | { 50 | return context.Compilation.GetSemanticModel(syntaxNode.SyntaxTree).GetTypeInfo(syntaxNode).Type; 51 | } 52 | 53 | public static string? GetTypeNamespace(this SyntaxNode syntaxNode, GeneratorExecutionContext context) 54 | { 55 | var containingNamespace = GetTypeSymbol(syntaxNode, context)?.ContainingNamespace; 56 | 57 | if (containingNamespace is null || containingNamespace.IsGlobalNamespace) 58 | { 59 | return null; 60 | } 61 | 62 | return containingNamespace.ToString(); 63 | } 64 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Extensions/TypeSyntaxExtensions.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis.CSharp; 2 | using Microsoft.CodeAnalysis.CSharp.Syntax; 3 | 4 | namespace UnityUxmlGenerator.Extensions; 5 | 6 | internal static class TypeSyntaxExtensions 7 | { 8 | public static bool IsBoolType(this TypeSyntax typeSyntax) 9 | { 10 | if (typeSyntax is PredefinedTypeSyntax predefinedTypeSyntax) 11 | { 12 | return IsBoolType(predefinedTypeSyntax); 13 | } 14 | 15 | return IsBoolKind(typeSyntax.RawKind); 16 | } 17 | 18 | public static bool IsBoolType(this PredefinedTypeSyntax typeSyntax) 19 | { 20 | return IsBoolKind(typeSyntax.Keyword.RawKind); 21 | } 22 | 23 | public static bool IsStringType(this TypeSyntax typeSyntax) 24 | { 25 | if (typeSyntax is PredefinedTypeSyntax predefinedTypeSyntax) 26 | { 27 | return IsStringType(predefinedTypeSyntax); 28 | } 29 | 30 | return IsStringKind(typeSyntax.RawKind); 31 | } 32 | 33 | public static bool IsStringType(this PredefinedTypeSyntax typeSyntax) 34 | { 35 | return IsStringKind(typeSyntax.Keyword.RawKind); 36 | } 37 | 38 | public static bool IsNumericType(this TypeSyntax typeSyntax) 39 | { 40 | if (typeSyntax is PredefinedTypeSyntax predefinedTypeSyntax) 41 | { 42 | return IsNumericType(predefinedTypeSyntax); 43 | } 44 | 45 | return IsNumericKind(typeSyntax.RawKind); 46 | } 47 | 48 | public static bool IsNumericType(this PredefinedTypeSyntax typeSyntax) 49 | { 50 | return IsNumericKind(typeSyntax.Keyword.RawKind); 51 | } 52 | 53 | private static bool IsBoolKind(int rawKind) 54 | { 55 | return rawKind == (int) SyntaxKind.BoolKeyword; 56 | } 57 | 58 | private static bool IsStringKind(int rawKind) 59 | { 60 | return rawKind == (int) SyntaxKind.StringKeyword; 61 | } 62 | 63 | private static bool IsNumericKind(int rawKind) 64 | { 65 | return rawKind == (int) SyntaxKind.IntKeyword || 66 | rawKind == (int) SyntaxKind.LongKeyword || 67 | rawKind == (int) SyntaxKind.FloatKeyword || 68 | rawKind == (int) SyntaxKind.DoubleKeyword; 69 | } 70 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_SimulationMode: 0 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 1 46 | m_AutoSyncTransforms: 0 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/.gitattributes: -------------------------------------------------------------------------------- 1 | # Packages 2 | *.tgz filter=lfs diff=lfs merge=lfs -text 3 | # 3D models 4 | *.3dm filter=lfs diff=lfs merge=lfs -text 5 | *.3ds filter=lfs diff=lfs merge=lfs -text 6 | *.blend filter=lfs diff=lfs merge=lfs -text 7 | *.c4d filter=lfs diff=lfs merge=lfs -text 8 | *.collada filter=lfs diff=lfs merge=lfs -text 9 | *.dae filter=lfs diff=lfs merge=lfs -text 10 | *.dxf filter=lfs diff=lfs merge=lfs -text 11 | *.fbx filter=lfs diff=lfs merge=lfs -text 12 | *.jas filter=lfs diff=lfs merge=lfs -text 13 | *.lws filter=lfs diff=lfs merge=lfs -text 14 | *.lxo filter=lfs diff=lfs merge=lfs -text 15 | *.ma filter=lfs diff=lfs merge=lfs -text 16 | *.max filter=lfs diff=lfs merge=lfs -text 17 | *.mb filter=lfs diff=lfs merge=lfs -text 18 | *.obj filter=lfs diff=lfs merge=lfs -text 19 | *.ply filter=lfs diff=lfs merge=lfs -text 20 | *.skp filter=lfs diff=lfs merge=lfs -text 21 | *.stl filter=lfs diff=lfs merge=lfs -text 22 | *.ztl filter=lfs diff=lfs merge=lfs -text 23 | # Audio 24 | *.aif filter=lfs diff=lfs merge=lfs -text 25 | *.aiff filter=lfs diff=lfs merge=lfs -text 26 | *.it filter=lfs diff=lfs merge=lfs -text 27 | *.mod filter=lfs diff=lfs merge=lfs -text 28 | *.mp3 filter=lfs diff=lfs merge=lfs -text 29 | *.ogg filter=lfs diff=lfs merge=lfs -text 30 | *.s3m filter=lfs diff=lfs merge=lfs -text 31 | *.wav filter=lfs diff=lfs merge=lfs -text 32 | *.xm filter=lfs diff=lfs merge=lfs -text 33 | # Fonts 34 | *.otf filter=lfs diff=lfs merge=lfs -text 35 | *.ttf filter=lfs diff=lfs merge=lfs -text 36 | # Images 37 | *.bmp filter=lfs diff=lfs merge=lfs -text 38 | *.exr filter=lfs diff=lfs merge=lfs -text 39 | *.gif filter=lfs diff=lfs merge=lfs -text 40 | *.hdr filter=lfs diff=lfs merge=lfs -text 41 | *.iff filter=lfs diff=lfs merge=lfs -text 42 | *.jpeg filter=lfs diff=lfs merge=lfs -text 43 | *.jpg filter=lfs diff=lfs merge=lfs -text 44 | *.pict filter=lfs diff=lfs merge=lfs -text 45 | *.png filter=lfs diff=lfs merge=lfs -text 46 | *.psd filter=lfs diff=lfs merge=lfs -text 47 | *.tga filter=lfs diff=lfs merge=lfs -text 48 | *.tif filter=lfs diff=lfs merge=lfs -text 49 | *.tiff filter=lfs diff=lfs merge=lfs -text 50 | # Collapse Unity-generated files on GitHub 51 | *.asset linguist-generated 52 | *.mat linguist-generated 53 | *.meta linguist-generated 54 | *.prefab linguist-generated 55 | *.unity linguist-generated 56 | *.aar filter=lfs diff=lfs merge=lfs -text -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 13 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_VideoShadersIncludeMode: 2 32 | m_AlwaysIncludedShaders: 33 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 38 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 39 | - {fileID: 10783, guid: 0000000000000000f000000000000000, type: 0} 40 | m_PreloadedShaders: [] 41 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, type: 0} 42 | m_CustomRenderPipeline: {fileID: 0} 43 | m_TransparencySortMode: 0 44 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 45 | m_DefaultRenderingPath: 1 46 | m_DefaultMobileRenderingPath: 1 47 | m_TierSettings: [] 48 | m_LightmapStripping: 0 49 | m_FogStripping: 0 50 | m_InstancingStripping: 0 51 | m_LightmapKeepPlain: 1 52 | m_LightmapKeepDirCombined: 1 53 | m_LightmapKeepDynamicPlain: 1 54 | m_LightmapKeepDynamicDirCombined: 1 55 | m_LightmapKeepShadowMask: 1 56 | m_LightmapKeepSubtractive: 1 57 | m_FogKeepLinear: 1 58 | m_FogKeepExp: 1 59 | m_FogKeepExp2: 1 60 | m_AlbedoSwatchInfos: [] 61 | m_LightsUseLinearIntensity: 0 62 | m_LightsUseColorTemperature: 0 63 | m_DefaultRenderingLayerMask: 1 64 | m_LogWhenShaderIsCompiled: 0 65 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/Extensions/StringBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | 5 | namespace UnityUxmlGenerator.Extensions; 6 | 7 | public static class StringBuilderExtensions 8 | { 9 | public static void AppendGenericString(this StringBuilder stringBuilder, GeneratorExecutionContext context, 10 | IEnumerable genericTypeArguments) 11 | { 12 | var isFirstArgument = true; 13 | 14 | stringBuilder.Append('<'); 15 | 16 | foreach (var genericClassTypeSyntax in genericTypeArguments) 17 | { 18 | if (isFirstArgument == false) 19 | { 20 | stringBuilder.Append(", "); 21 | } 22 | 23 | isFirstArgument = false; 24 | 25 | switch (genericClassTypeSyntax) 26 | { 27 | case PredefinedTypeSyntax predefinedTypeSyntax: 28 | AppendPredefinedTypeSyntax(stringBuilder, predefinedTypeSyntax); 29 | break; 30 | 31 | case IdentifierNameSyntax identifierNameSyntax: 32 | AppendIdentifierNameSyntax(stringBuilder, context, identifierNameSyntax); 33 | break; 34 | 35 | case GenericNameSyntax genericTypeSyntax: 36 | AppendGenericTypeSyntax(stringBuilder, context, genericTypeSyntax); 37 | break; 38 | } 39 | } 40 | 41 | stringBuilder.Append('>'); 42 | } 43 | 44 | private static void AppendPredefinedTypeSyntax(StringBuilder stringBuilder, 45 | PredefinedTypeSyntax predefinedTypeSyntax) 46 | { 47 | stringBuilder.Append(predefinedTypeSyntax.Keyword.Text); 48 | } 49 | 50 | private static void AppendIdentifierNameSyntax(StringBuilder stringBuilder, GeneratorExecutionContext context, 51 | IdentifierNameSyntax identifierNameSyntax) 52 | { 53 | var genericClassName = identifierNameSyntax.Identifier.Text; 54 | var genericClassNamespace = identifierNameSyntax.GetTypeNamespace(context); 55 | 56 | stringBuilder.Append("global::"); 57 | stringBuilder.Append(genericClassNamespace); 58 | stringBuilder.Append('.'); 59 | stringBuilder.Append(genericClassName); 60 | } 61 | 62 | private static void AppendGenericTypeSyntax(StringBuilder stringBuilder, GeneratorExecutionContext context, 63 | GenericNameSyntax genericTypeSyntax) 64 | { 65 | var genericClassName = genericTypeSyntax.Identifier.Text; 66 | var genericClassNamespace = genericTypeSyntax.GetTypeNamespace(context); 67 | 68 | if (string.IsNullOrWhiteSpace(genericClassNamespace) == false) 69 | { 70 | stringBuilder.Append("global::"); 71 | stringBuilder.Append(genericClassNamespace); 72 | stringBuilder.Append('.'); 73 | } 74 | 75 | stringBuilder.Append(genericClassName); 76 | 77 | AppendGenericString(stringBuilder, context, genericTypeSyntax.TypeArgumentList.Arguments); 78 | } 79 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/UxmlGenerator.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | using Microsoft.CodeAnalysis.Text; 5 | using UnityUxmlGenerator.Captures; 6 | using UnityUxmlGenerator.Diagnostics; 7 | using UnityUxmlGenerator.Extensions; 8 | using UnityUxmlGenerator.SyntaxReceivers; 9 | 10 | namespace UnityUxmlGenerator; 11 | 12 | [Generator] 13 | internal sealed partial class UxmlGenerator : ISourceGenerator 14 | { 15 | private const string VisualElementFullName = "UnityEngine.UIElements.VisualElement"; 16 | 17 | private static readonly AssemblyName AssemblyName = typeof(UxmlGenerator).Assembly.GetName(); 18 | 19 | public void Initialize(GeneratorInitializationContext context) 20 | { 21 | context.RegisterForSyntaxNotifications(() => new VisualElementReceiver()); 22 | } 23 | 24 | public void Execute(GeneratorExecutionContext context) 25 | { 26 | context.AddSource($"{nameof(UxmlElementClassName)}.g.cs", GenerateUxmlElementAttribute()); 27 | context.AddSource($"{nameof(UxmlAttributeClassName)}.g.cs", GenerateUxmlAttributeAttribute()); 28 | 29 | if (context.SyntaxReceiver is not VisualElementReceiver receiver || 30 | context.CancellationToken.IsCancellationRequested) 31 | { 32 | return; 33 | } 34 | 35 | foreach (var uxmlElement in receiver.UxmlFactoryReceiver.Captures) 36 | { 37 | context.CancellationToken.ThrowIfCancellationRequested(); 38 | 39 | if (IsValidClass(context, uxmlElement.Class) && 40 | IsValidAttribute(context, uxmlElement.Attribute)) 41 | { 42 | AddSource(context, uxmlElement, GenerateUxmlFactory(uxmlElement)); 43 | } 44 | } 45 | 46 | foreach (var capture in receiver.UxmlTraitsReceiver.Captures) 47 | { 48 | context.CancellationToken.ThrowIfCancellationRequested(); 49 | 50 | var uxmlTraits = capture.Value; 51 | 52 | if (IsValidClass(context, uxmlTraits.Class)) 53 | { 54 | AddSource(context, capture.Value, GenerateUxmlTraits(context, capture.Value)); 55 | } 56 | } 57 | 58 | ReportDiagnostics(context, receiver.UxmlTraitsReceiver.Diagnostics); 59 | ReportDiagnostics(context, receiver.UxmlFactoryReceiver.Diagnostics); 60 | } 61 | 62 | private static bool IsValidClass(GeneratorExecutionContext context, BaseTypeDeclarationSyntax @class) 63 | { 64 | if (@class.InheritsFromFullyQualifiedName(context, VisualElementFullName)) 65 | { 66 | return true; 67 | } 68 | 69 | ReportClassDoesNotInheritFromVisualElementError(context, @class); 70 | return false; 71 | } 72 | 73 | private static bool IsValidAttribute(GeneratorExecutionContext context, AttributeSyntax attribute) 74 | { 75 | return attribute.GetTypeNamespace(context) == AssemblyName.Name; 76 | } 77 | 78 | private static void AddSource(GeneratorExecutionContext context, BaseCapture capture, SourceText sourceText) 79 | { 80 | context.AddSource($"{capture.ClassName}.{capture.ClassTag}.g.cs", sourceText); 81 | } 82 | 83 | private static void ReportDiagnostics(GeneratorExecutionContext context, IEnumerable diagnostics) 84 | { 85 | foreach (var diagnostic in diagnostics) 86 | { 87 | context.ReportDiagnostic(diagnostic); 88 | } 89 | } 90 | 91 | private static void ReportClassDoesNotInheritFromVisualElementError(GeneratorExecutionContext context, 92 | BaseTypeDeclarationSyntax @class) 93 | { 94 | context.ReportDiagnostic( 95 | ClassDoesNotInheritFromVisualElementError.CreateDiagnostic(@class.GetLocation(), @class.Identifier.Text)); 96 | } 97 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/UxmlGenerator.Attributes.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | using Microsoft.CodeAnalysis.Text; 5 | 6 | namespace UnityUxmlGenerator; 7 | 8 | internal sealed partial class UxmlGenerator 9 | { 10 | private const string AttributeBaseType = "global::System.Attribute"; 11 | 12 | private const string AttributeClassTarget = "Class"; 13 | private const string AttributePropertyTarget = "Property"; 14 | 15 | private const string UxmlElementClassName = "UxmlElementAttribute"; 16 | private const string UxmlAttributeClassName = "UxmlAttributeAttribute"; 17 | 18 | private static SourceText GenerateUxmlElementAttribute() 19 | { 20 | return GenerateAttributeClass(UxmlElementClassName, AttributeClassTarget); 21 | } 22 | 23 | private static SourceText GenerateUxmlAttributeAttribute() 24 | { 25 | return GenerateAttributeClass(UxmlAttributeClassName, AttributePropertyTarget, GetUxmlAttributeMembers()); 26 | } 27 | 28 | private static SourceText GenerateAttributeClass(string attributeClassIdentifier, string attributeTarget, 29 | IEnumerable? members = null) 30 | { 31 | return CompilationUnitWidget( 32 | namespaceIdentifier: AssemblyName.Name, 33 | member: ClassWidget( 34 | identifier: attributeClassIdentifier, 35 | modifiers: new[] { SyntaxKind.InternalKeyword, SyntaxKind.SealedKeyword }, 36 | baseType: SimpleBaseType(IdentifierName(AttributeBaseType)), 37 | attribute: AttributeWidget( 38 | identifier: "global::System.AttributeUsage", 39 | arguments: new[] 40 | { 41 | AttributeArgument(MemberAccessWidget( 42 | identifier: "global::System.AttributeTargets", 43 | memberName: attributeTarget)), 44 | AttributeArgument(AssignmentWidget( 45 | left: IdentifierName("AllowMultiple"), 46 | right: LiteralExpression(SyntaxKind.FalseLiteralExpression))), 47 | AttributeArgument(AssignmentWidget( 48 | left: IdentifierName("Inherited"), 49 | right: LiteralExpression(SyntaxKind.FalseLiteralExpression))) 50 | }), 51 | members: members, 52 | addGeneratedCodeAttributes: true), 53 | normalizeWhitespace: true) 54 | .GetText(Encoding.UTF8); 55 | } 56 | 57 | private static IEnumerable GetUxmlAttributeMembers() 58 | { 59 | return new MemberDeclarationSyntax[] 60 | { 61 | ConstructorWidget( 62 | identifier: UxmlAttributeClassName, 63 | modifier: SyntaxKind.PublicKeyword, 64 | parameter: ParameterWidget( 65 | identifier: "defaultValue", 66 | type: NullableType(PredefinedType(Token(SyntaxKind.ObjectKeyword))), 67 | defaultValueKeyword: SyntaxKind.DefaultKeyword), 68 | bodyStatement: AssignmentStatementWidget( 69 | left: IdentifierName("DefaultValue"), 70 | right: IdentifierName("defaultValue")), 71 | addGeneratedCodeAttributes: true 72 | ), 73 | PropertyWidget( 74 | identifier: "DefaultValue", 75 | type: NullableType(PredefinedType(Token(SyntaxKind.ObjectKeyword))), 76 | modifier: SyntaxKind.PublicKeyword, 77 | accessor: SyntaxKind.GetAccessorDeclaration, 78 | addGeneratedCodeAttributes: true 79 | ) 80 | }; 81 | } 82 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/SceneTemplateSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "templatePinStates": [], 3 | "dependencyTypeInfos": [ 4 | { 5 | "userAdded": false, 6 | "type": "UnityEngine.AnimationClip", 7 | "ignore": false, 8 | "defaultInstantiationMode": 0, 9 | "supportsModification": true 10 | }, 11 | { 12 | "userAdded": false, 13 | "type": "UnityEditor.Animations.AnimatorController", 14 | "ignore": false, 15 | "defaultInstantiationMode": 0, 16 | "supportsModification": true 17 | }, 18 | { 19 | "userAdded": false, 20 | "type": "UnityEngine.AnimatorOverrideController", 21 | "ignore": false, 22 | "defaultInstantiationMode": 0, 23 | "supportsModification": true 24 | }, 25 | { 26 | "userAdded": false, 27 | "type": "UnityEditor.Audio.AudioMixerController", 28 | "ignore": false, 29 | "defaultInstantiationMode": 0, 30 | "supportsModification": true 31 | }, 32 | { 33 | "userAdded": false, 34 | "type": "UnityEngine.ComputeShader", 35 | "ignore": true, 36 | "defaultInstantiationMode": 1, 37 | "supportsModification": true 38 | }, 39 | { 40 | "userAdded": false, 41 | "type": "UnityEngine.Cubemap", 42 | "ignore": false, 43 | "defaultInstantiationMode": 0, 44 | "supportsModification": true 45 | }, 46 | { 47 | "userAdded": false, 48 | "type": "UnityEngine.GameObject", 49 | "ignore": false, 50 | "defaultInstantiationMode": 0, 51 | "supportsModification": true 52 | }, 53 | { 54 | "userAdded": false, 55 | "type": "UnityEditor.LightingDataAsset", 56 | "ignore": false, 57 | "defaultInstantiationMode": 0, 58 | "supportsModification": false 59 | }, 60 | { 61 | "userAdded": false, 62 | "type": "UnityEngine.LightingSettings", 63 | "ignore": false, 64 | "defaultInstantiationMode": 0, 65 | "supportsModification": true 66 | }, 67 | { 68 | "userAdded": false, 69 | "type": "UnityEngine.Material", 70 | "ignore": false, 71 | "defaultInstantiationMode": 0, 72 | "supportsModification": true 73 | }, 74 | { 75 | "userAdded": false, 76 | "type": "UnityEditor.MonoScript", 77 | "ignore": true, 78 | "defaultInstantiationMode": 1, 79 | "supportsModification": true 80 | }, 81 | { 82 | "userAdded": false, 83 | "type": "UnityEngine.PhysicMaterial", 84 | "ignore": false, 85 | "defaultInstantiationMode": 0, 86 | "supportsModification": true 87 | }, 88 | { 89 | "userAdded": false, 90 | "type": "UnityEngine.PhysicsMaterial2D", 91 | "ignore": false, 92 | "defaultInstantiationMode": 0, 93 | "supportsModification": true 94 | }, 95 | { 96 | "userAdded": false, 97 | "type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile", 98 | "ignore": false, 99 | "defaultInstantiationMode": 0, 100 | "supportsModification": true 101 | }, 102 | { 103 | "userAdded": false, 104 | "type": "UnityEngine.Rendering.PostProcessing.PostProcessResources", 105 | "ignore": false, 106 | "defaultInstantiationMode": 0, 107 | "supportsModification": true 108 | }, 109 | { 110 | "userAdded": false, 111 | "type": "UnityEngine.Rendering.VolumeProfile", 112 | "ignore": false, 113 | "defaultInstantiationMode": 0, 114 | "supportsModification": true 115 | }, 116 | { 117 | "userAdded": false, 118 | "type": "UnityEditor.SceneAsset", 119 | "ignore": false, 120 | "defaultInstantiationMode": 0, 121 | "supportsModification": false 122 | }, 123 | { 124 | "userAdded": false, 125 | "type": "UnityEngine.Shader", 126 | "ignore": true, 127 | "defaultInstantiationMode": 1, 128 | "supportsModification": true 129 | }, 130 | { 131 | "userAdded": false, 132 | "type": "UnityEngine.ShaderVariantCollection", 133 | "ignore": true, 134 | "defaultInstantiationMode": 1, 135 | "supportsModification": true 136 | }, 137 | { 138 | "userAdded": false, 139 | "type": "UnityEngine.Texture", 140 | "ignore": false, 141 | "defaultInstantiationMode": 0, 142 | "supportsModification": true 143 | }, 144 | { 145 | "userAdded": false, 146 | "type": "UnityEngine.Texture2D", 147 | "ignore": false, 148 | "defaultInstantiationMode": 0, 149 | "supportsModification": true 150 | }, 151 | { 152 | "userAdded": false, 153 | "type": "UnityEngine.Timeline.TimelineAsset", 154 | "ignore": false, 155 | "defaultInstantiationMode": 0, 156 | "supportsModification": true 157 | } 158 | ], 159 | "defaultDependencyTypeInfo": { 160 | "userAdded": false, 161 | "type": "", 162 | "ignore": false, 163 | "defaultInstantiationMode": 1, 164 | "supportsModification": true 165 | }, 166 | "newSceneOverride": 0 167 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Assets/Scenes/SampleScene.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 3 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 0} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 0} 41 | m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 12 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 0 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 0 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 500 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 2 83 | m_PVRDenoiserTypeDirect: 0 84 | m_PVRDenoiserTypeIndirect: 0 85 | m_PVRDenoiserTypeAO: 0 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 0 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_LightingSettings: {fileID: 0} 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | maxJobWorkers: 0 122 | preserveTilesOutsideBounds: 0 123 | debug: 124 | m_Flags: 0 125 | m_NavMeshData: {fileID: 0} 126 | --- !u!1 &519420028 127 | GameObject: 128 | m_ObjectHideFlags: 0 129 | m_CorrespondingSourceObject: {fileID: 0} 130 | m_PrefabInstance: {fileID: 0} 131 | m_PrefabAsset: {fileID: 0} 132 | serializedVersion: 6 133 | m_Component: 134 | - component: {fileID: 519420032} 135 | - component: {fileID: 519420031} 136 | - component: {fileID: 519420029} 137 | m_Layer: 0 138 | m_Name: MainCamera 139 | m_TagString: MainCamera 140 | m_Icon: {fileID: 0} 141 | m_NavMeshLayer: 0 142 | m_StaticEditorFlags: 0 143 | m_IsActive: 1 144 | --- !u!81 &519420029 145 | AudioListener: 146 | m_ObjectHideFlags: 0 147 | m_CorrespondingSourceObject: {fileID: 0} 148 | m_PrefabInstance: {fileID: 0} 149 | m_PrefabAsset: {fileID: 0} 150 | m_GameObject: {fileID: 519420028} 151 | m_Enabled: 1 152 | --- !u!20 &519420031 153 | Camera: 154 | m_ObjectHideFlags: 0 155 | m_CorrespondingSourceObject: {fileID: 0} 156 | m_PrefabInstance: {fileID: 0} 157 | m_PrefabAsset: {fileID: 0} 158 | m_GameObject: {fileID: 519420028} 159 | m_Enabled: 1 160 | serializedVersion: 2 161 | m_ClearFlags: 2 162 | m_BackGroundColor: {r: 0.21960786, g: 0.21960786, b: 0.21960786, a: 0} 163 | m_projectionMatrixMode: 1 164 | m_GateFitMode: 2 165 | m_FOVAxisMode: 0 166 | m_SensorSize: {x: 36, y: 24} 167 | m_LensShift: {x: 0, y: 0} 168 | m_FocalLength: 50 169 | m_NormalizedViewPortRect: 170 | serializedVersion: 2 171 | x: 0 172 | y: 0 173 | width: 1 174 | height: 1 175 | near clip plane: 0.3 176 | far clip plane: 1000 177 | field of view: 60 178 | orthographic: 1 179 | orthographic size: 5 180 | m_Depth: -1 181 | m_CullingMask: 182 | serializedVersion: 2 183 | m_Bits: 4294967295 184 | m_RenderingPath: -1 185 | m_TargetTexture: {fileID: 0} 186 | m_TargetDisplay: 0 187 | m_TargetEye: 0 188 | m_HDR: 1 189 | m_AllowMSAA: 0 190 | m_AllowDynamicResolution: 0 191 | m_ForceIntoRT: 0 192 | m_OcclusionCulling: 0 193 | m_StereoConvergence: 10 194 | m_StereoSeparation: 0.022 195 | --- !u!4 &519420032 196 | Transform: 197 | m_ObjectHideFlags: 0 198 | m_CorrespondingSourceObject: {fileID: 0} 199 | m_PrefabInstance: {fileID: 0} 200 | m_PrefabAsset: {fileID: 0} 201 | m_GameObject: {fileID: 519420028} 202 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 203 | m_LocalPosition: {x: 0, y: 0, z: -10} 204 | m_LocalScale: {x: 1, y: 1, z: 1} 205 | m_ConstrainProportionsScale: 0 206 | m_Children: [] 207 | m_Father: {fileID: 0} 208 | m_RootOrder: 0 209 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 210 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.rsuser 8 | *.suo 9 | *.user 10 | *.userosscache 11 | *.sln.docstates 12 | 13 | # User-specific files (MonoDevelop/Xamarin Studio) 14 | *.userprefs 15 | 16 | # Mono auto generated files 17 | mono_crash.* 18 | 19 | # Build results 20 | [Dd]ebug/ 21 | [Dd]ebugPublic/ 22 | [Rr]elease/ 23 | [Rr]eleases/ 24 | x64/ 25 | x86/ 26 | [Aa][Rr][Mm]/ 27 | [Aa][Rr][Mm]64/ 28 | bld/ 29 | [Bb]in/ 30 | [Oo]bj/ 31 | [Ll]og/ 32 | [Ll]ogs/ 33 | 34 | # Visual Studio 2015/2017 cache/options directory 35 | .vs/ 36 | # Uncomment if you have tasks that create the project's static files in wwwroot 37 | #wwwroot/ 38 | 39 | # Visual Studio 2017 auto generated files 40 | Generated\ Files/ 41 | 42 | # MSTest test Results 43 | [Tt]est[Rr]esult*/ 44 | [Bb]uild[Ll]og.* 45 | 46 | # NUnit 47 | *.VisualState.xml 48 | TestResult.xml 49 | nunit-*.xml 50 | 51 | # Build Results of an ATL Project 52 | [Dd]ebugPS/ 53 | [Rr]eleasePS/ 54 | dlldata.c 55 | 56 | # Benchmark Results 57 | BenchmarkDotNet.Artifacts/ 58 | 59 | # .NET Core 60 | project.lock.json 61 | project.fragment.lock.json 62 | artifacts/ 63 | 64 | # StyleCop 65 | StyleCopReport.xml 66 | 67 | # Files built by Visual Studio 68 | *_i.c 69 | *_p.c 70 | *_h.h 71 | *.ilk 72 | *.meta 73 | *.obj 74 | *.iobj 75 | *.pch 76 | *.pdb 77 | *.ipdb 78 | *.pgc 79 | *.pgd 80 | *.rsp 81 | *.sbr 82 | *.tlb 83 | *.tli 84 | *.tlh 85 | *.tmp 86 | *.tmp_proj 87 | *_wpftmp.csproj 88 | *.log 89 | *.vspscc 90 | *.vssscc 91 | .builds 92 | *.pidb 93 | *.svclog 94 | *.scc 95 | 96 | # Chutzpah Test files 97 | _Chutzpah* 98 | 99 | # Visual C++ cache files 100 | ipch/ 101 | *.aps 102 | *.ncb 103 | *.opendb 104 | *.opensdf 105 | *.sdf 106 | *.cachefile 107 | *.VC.db 108 | *.VC.VC.opendb 109 | 110 | # Visual Studio profiler 111 | *.psess 112 | *.vsp 113 | *.vspx 114 | *.sap 115 | 116 | # Visual Studio Trace Files 117 | *.e2e 118 | 119 | # TFS 2012 Local Workspace 120 | $tf/ 121 | 122 | # Guidance Automation Toolkit 123 | *.gpState 124 | 125 | # ReSharper is a .NET coding add-in 126 | _ReSharper*/ 127 | *.[Rr]e[Ss]harper 128 | *.DotSettings.user 129 | 130 | # TeamCity is a build add-in 131 | _TeamCity* 132 | 133 | # DotCover is a Code Coverage Tool 134 | *.dotCover 135 | 136 | # AxoCover is a Code Coverage Tool 137 | .axoCover/* 138 | !.axoCover/settings.json 139 | 140 | # Visual Studio code coverage results 141 | *.coverage 142 | *.coveragexml 143 | 144 | # NCrunch 145 | _NCrunch_* 146 | .*crunch*.local.xml 147 | nCrunchTemp_* 148 | 149 | # MightyMoose 150 | *.mm.* 151 | AutoTest.Net/ 152 | 153 | # Web workbench (sass) 154 | .sass-cache/ 155 | 156 | # Installshield output folder 157 | [Ee]xpress/ 158 | 159 | # DocProject is a documentation generator add-in 160 | DocProject/buildhelp/ 161 | DocProject/Help/*.HxT 162 | DocProject/Help/*.HxC 163 | DocProject/Help/*.hhc 164 | DocProject/Help/*.hhk 165 | DocProject/Help/*.hhp 166 | DocProject/Help/Html2 167 | DocProject/Help/html 168 | 169 | # Click-Once directory 170 | publish/ 171 | 172 | # Publish Web Output 173 | *.[Pp]ublish.xml 174 | *.azurePubxml 175 | # Note: Comment the next line if you want to checkin your web deploy settings, 176 | # but database connection strings (with potential passwords) will be unencrypted 177 | *.pubxml 178 | *.publishproj 179 | 180 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 181 | # checkin your Azure Web App publish settings, but sensitive information contained 182 | # in these scripts will be unencrypted 183 | PublishScripts/ 184 | 185 | # NuGet Packages 186 | *.nupkg 187 | # NuGet Symbol Packages 188 | *.snupkg 189 | # The packages folder can be ignored because of Package Restore 190 | **/[Pp]ackages/* 191 | # except build/, which is used as an MSBuild target. 192 | !**/[Pp]ackages/build/ 193 | # Uncomment if necessary however generally it will be regenerated when needed 194 | #!**/[Pp]ackages/repositories.config 195 | # NuGet v3's project.json files produces more ignorable files 196 | *.nuget.props 197 | *.nuget.targets 198 | 199 | # Microsoft Azure Build Output 200 | csx/ 201 | *.build.csdef 202 | 203 | # Microsoft Azure Emulator 204 | ecf/ 205 | rcf/ 206 | 207 | # Windows Store app package directories and files 208 | AppPackages/ 209 | BundleArtifacts/ 210 | Package.StoreAssociation.xml 211 | _pkginfo.txt 212 | *.appx 213 | *.appxbundle 214 | *.appxupload 215 | 216 | # Visual Studio cache files 217 | # files ending in .cache can be ignored 218 | *.[Cc]ache 219 | # but keep track of directories ending in .cache 220 | !?*.[Cc]ache/ 221 | 222 | # Others 223 | ClientBin/ 224 | ~$* 225 | *~ 226 | *.dbmdl 227 | *.dbproj.schemaview 228 | *.jfm 229 | *.pfx 230 | *.publishsettings 231 | orleans.codegen.cs 232 | 233 | # Including strong name files can present a security risk 234 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 235 | #*.snk 236 | 237 | # Since there are multiple workflows, uncomment next line to ignore bower_components 238 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 239 | #bower_components/ 240 | 241 | # RIA/Silverlight projects 242 | Generated_Code/ 243 | 244 | # Backup & report files from converting an old project file 245 | # to a newer Visual Studio version. Backup files are not needed, 246 | # because we have git ;-) 247 | _UpgradeReport_Files/ 248 | Backup*/ 249 | UpgradeLog*.XML 250 | UpgradeLog*.htm 251 | ServiceFabricBackup/ 252 | *.rptproj.bak 253 | 254 | # SQL Server files 255 | *.mdf 256 | *.ldf 257 | *.ndf 258 | 259 | # Business Intelligence projects 260 | *.rdl.data 261 | *.bim.layout 262 | *.bim_*.settings 263 | *.rptproj.rsuser 264 | *- [Bb]ackup.rdl 265 | *- [Bb]ackup ([0-9]).rdl 266 | *- [Bb]ackup ([0-9][0-9]).rdl 267 | 268 | # Microsoft Fakes 269 | FakesAssemblies/ 270 | 271 | # GhostDoc plugin setting file 272 | *.GhostDoc.xml 273 | 274 | # Node.js Tools for Visual Studio 275 | .ntvs_analysis.dat 276 | node_modules/ 277 | 278 | # Visual Studio 6 build log 279 | *.plg 280 | 281 | # Visual Studio 6 workspace options file 282 | *.opt 283 | 284 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 285 | *.vbw 286 | 287 | # Visual Studio LightSwitch build output 288 | **/*.HTMLClient/GeneratedArtifacts 289 | **/*.DesktopClient/GeneratedArtifacts 290 | **/*.DesktopClient/ModelManifest.xml 291 | **/*.Server/GeneratedArtifacts 292 | **/*.Server/ModelManifest.xml 293 | _Pvt_Extensions 294 | 295 | # Paket dependency manager 296 | .paket/paket.exe 297 | paket-files/ 298 | 299 | # FAKE - F# Make 300 | .fake/ 301 | 302 | # CodeRush personal settings 303 | .cr/personal 304 | 305 | # Python Tools for Visual Studio (PTVS) 306 | __pycache__/ 307 | *.pyc 308 | 309 | # Cake - Uncomment if you are using it 310 | # tools/** 311 | # !tools/packages.config 312 | 313 | # Tabs Studio 314 | *.tss 315 | 316 | # Telerik's JustMock configuration file 317 | *.jmconfig 318 | 319 | # BizTalk build output 320 | *.btp.cs 321 | *.btm.cs 322 | *.odx.cs 323 | *.xsd.cs 324 | 325 | # OpenCover UI analysis results 326 | OpenCover/ 327 | 328 | # Azure Stream Analytics local run output 329 | ASALocalRun/ 330 | 331 | # MSBuild Binary and Structured Log 332 | *.binlog 333 | 334 | # NVidia Nsight GPU debugger configuration file 335 | *.nvuser 336 | 337 | # MFractors (Xamarin productivity tool) working folder 338 | .mfractor/ 339 | 340 | # Local History for Visual Studio 341 | .localhistory/ 342 | 343 | # BeatPulse healthcheck temp database 344 | healthchecksdb 345 | 346 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 347 | MigrationBackup/ 348 | 349 | # Ionide (cross platform F# VS Code tools) working folder 350 | .ionide/ 351 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | skinWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | streamingMipmapsActive: 0 33 | streamingMipmapsAddAllCameras: 1 34 | streamingMipmapsMemoryBudget: 512 35 | streamingMipmapsRenderersPerFrame: 512 36 | streamingMipmapsMaxLevelReduction: 2 37 | streamingMipmapsMaxFileIORequests: 1024 38 | particleRaycastBudget: 4 39 | asyncUploadTimeSlice: 2 40 | asyncUploadBufferSize: 16 41 | asyncUploadPersistentBuffer: 1 42 | resolutionScalingFixedDPIFactor: 1 43 | customRenderPipeline: {fileID: 0} 44 | excludedTargetPlatforms: [] 45 | - serializedVersion: 2 46 | name: Low 47 | pixelLightCount: 0 48 | shadows: 0 49 | shadowResolution: 0 50 | shadowProjection: 1 51 | shadowCascades: 1 52 | shadowDistance: 20 53 | shadowNearPlaneOffset: 3 54 | shadowCascade2Split: 0.33333334 55 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 56 | shadowmaskMode: 0 57 | skinWeights: 2 58 | textureQuality: 0 59 | anisotropicTextures: 0 60 | antiAliasing: 0 61 | softParticles: 0 62 | softVegetation: 0 63 | realtimeReflectionProbes: 0 64 | billboardsFaceCameraPosition: 0 65 | vSyncCount: 0 66 | lodBias: 0.4 67 | maximumLODLevel: 0 68 | streamingMipmapsActive: 0 69 | streamingMipmapsAddAllCameras: 1 70 | streamingMipmapsMemoryBudget: 512 71 | streamingMipmapsRenderersPerFrame: 512 72 | streamingMipmapsMaxLevelReduction: 2 73 | streamingMipmapsMaxFileIORequests: 1024 74 | particleRaycastBudget: 16 75 | asyncUploadTimeSlice: 2 76 | asyncUploadBufferSize: 16 77 | asyncUploadPersistentBuffer: 1 78 | resolutionScalingFixedDPIFactor: 1 79 | customRenderPipeline: {fileID: 0} 80 | excludedTargetPlatforms: [] 81 | - serializedVersion: 2 82 | name: Medium 83 | pixelLightCount: 1 84 | shadows: 1 85 | shadowResolution: 0 86 | shadowProjection: 1 87 | shadowCascades: 1 88 | shadowDistance: 20 89 | shadowNearPlaneOffset: 3 90 | shadowCascade2Split: 0.33333334 91 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 92 | shadowmaskMode: 0 93 | skinWeights: 2 94 | textureQuality: 0 95 | anisotropicTextures: 1 96 | antiAliasing: 0 97 | softParticles: 0 98 | softVegetation: 0 99 | realtimeReflectionProbes: 0 100 | billboardsFaceCameraPosition: 0 101 | vSyncCount: 1 102 | lodBias: 0.7 103 | maximumLODLevel: 0 104 | streamingMipmapsActive: 0 105 | streamingMipmapsAddAllCameras: 1 106 | streamingMipmapsMemoryBudget: 512 107 | streamingMipmapsRenderersPerFrame: 512 108 | streamingMipmapsMaxLevelReduction: 2 109 | streamingMipmapsMaxFileIORequests: 1024 110 | particleRaycastBudget: 64 111 | asyncUploadTimeSlice: 2 112 | asyncUploadBufferSize: 16 113 | asyncUploadPersistentBuffer: 1 114 | resolutionScalingFixedDPIFactor: 1 115 | customRenderPipeline: {fileID: 0} 116 | excludedTargetPlatforms: [] 117 | - serializedVersion: 2 118 | name: High 119 | pixelLightCount: 2 120 | shadows: 2 121 | shadowResolution: 1 122 | shadowProjection: 1 123 | shadowCascades: 2 124 | shadowDistance: 40 125 | shadowNearPlaneOffset: 3 126 | shadowCascade2Split: 0.33333334 127 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 128 | shadowmaskMode: 1 129 | skinWeights: 2 130 | textureQuality: 0 131 | anisotropicTextures: 1 132 | antiAliasing: 0 133 | softParticles: 0 134 | softVegetation: 1 135 | realtimeReflectionProbes: 1 136 | billboardsFaceCameraPosition: 1 137 | vSyncCount: 1 138 | lodBias: 1 139 | maximumLODLevel: 0 140 | streamingMipmapsActive: 0 141 | streamingMipmapsAddAllCameras: 1 142 | streamingMipmapsMemoryBudget: 512 143 | streamingMipmapsRenderersPerFrame: 512 144 | streamingMipmapsMaxLevelReduction: 2 145 | streamingMipmapsMaxFileIORequests: 1024 146 | particleRaycastBudget: 256 147 | asyncUploadTimeSlice: 2 148 | asyncUploadBufferSize: 16 149 | asyncUploadPersistentBuffer: 1 150 | resolutionScalingFixedDPIFactor: 1 151 | customRenderPipeline: {fileID: 0} 152 | excludedTargetPlatforms: [] 153 | - serializedVersion: 2 154 | name: Very High 155 | pixelLightCount: 3 156 | shadows: 2 157 | shadowResolution: 2 158 | shadowProjection: 1 159 | shadowCascades: 2 160 | shadowDistance: 70 161 | shadowNearPlaneOffset: 3 162 | shadowCascade2Split: 0.33333334 163 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 164 | shadowmaskMode: 1 165 | skinWeights: 4 166 | textureQuality: 0 167 | anisotropicTextures: 2 168 | antiAliasing: 2 169 | softParticles: 1 170 | softVegetation: 1 171 | realtimeReflectionProbes: 1 172 | billboardsFaceCameraPosition: 1 173 | vSyncCount: 1 174 | lodBias: 1.5 175 | maximumLODLevel: 0 176 | streamingMipmapsActive: 0 177 | streamingMipmapsAddAllCameras: 1 178 | streamingMipmapsMemoryBudget: 512 179 | streamingMipmapsRenderersPerFrame: 512 180 | streamingMipmapsMaxLevelReduction: 2 181 | streamingMipmapsMaxFileIORequests: 1024 182 | particleRaycastBudget: 1024 183 | asyncUploadTimeSlice: 2 184 | asyncUploadBufferSize: 16 185 | asyncUploadPersistentBuffer: 1 186 | resolutionScalingFixedDPIFactor: 1 187 | customRenderPipeline: {fileID: 0} 188 | excludedTargetPlatforms: [] 189 | - serializedVersion: 2 190 | name: Ultra 191 | pixelLightCount: 4 192 | shadows: 2 193 | shadowResolution: 2 194 | shadowProjection: 1 195 | shadowCascades: 4 196 | shadowDistance: 150 197 | shadowNearPlaneOffset: 3 198 | shadowCascade2Split: 0.33333334 199 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 200 | shadowmaskMode: 1 201 | skinWeights: 255 202 | textureQuality: 0 203 | anisotropicTextures: 2 204 | antiAliasing: 2 205 | softParticles: 1 206 | softVegetation: 1 207 | realtimeReflectionProbes: 1 208 | billboardsFaceCameraPosition: 1 209 | vSyncCount: 1 210 | lodBias: 2 211 | maximumLODLevel: 0 212 | streamingMipmapsActive: 0 213 | streamingMipmapsAddAllCameras: 1 214 | streamingMipmapsMemoryBudget: 512 215 | streamingMipmapsRenderersPerFrame: 512 216 | streamingMipmapsMaxLevelReduction: 2 217 | streamingMipmapsMaxFileIORequests: 1024 218 | particleRaycastBudget: 4096 219 | asyncUploadTimeSlice: 2 220 | asyncUploadBufferSize: 16 221 | asyncUploadPersistentBuffer: 1 222 | resolutionScalingFixedDPIFactor: 1 223 | customRenderPipeline: {fileID: 0} 224 | excludedTargetPlatforms: [] 225 | m_PerPlatformDefaultQuality: 226 | Android: 2 227 | Lumin: 5 228 | GameCoreScarlett: 5 229 | GameCoreXboxOne: 5 230 | Nintendo Switch: 5 231 | PS4: 5 232 | PS5: 5 233 | Stadia: 5 234 | Standalone: 5 235 | WebGL: 3 236 | Windows Store Apps: 5 237 | XboxOne: 5 238 | iPhone: 2 239 | tvOS: 2 240 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityUxmlGenerator 2 | 3 | This package is part of [UnityMvvmToolkit](https://github.com/LibraStack/UnityMvvmToolkit). 4 | 5 | ![unityuxmlgenerator-github-cover](https://github.com/LibraStack/UnityUxmlGenerator/assets/28132516/c8c1ee74-ee9f-4343-a859-b2eb05bd152f) 6 | 7 | ## :open_book: Table of Contents 8 | 9 | - [About](#pencil-about) 10 | - [Folder Structure](#cactus-folder-structure) 11 | - [Installation](#gear-installation) 12 | - [How To Use](#joystick-how-to-use) 13 | - [UxmlElement](#uxmlelement) 14 | - [UxmlAttribute](#uxmlattribute) 15 | - [Contributing](#bookmark_tabs-contributing) 16 | - [Discussions](#discussions) 17 | - [Report a bug](#report-a-bug) 18 | - [Request a feature](#request-a-feature) 19 | - [Show your support](#show-your-support) 20 | - [License](#balance_scale-license) 21 | 22 | ## :pencil: About 23 | 24 | The **UnityUxmlGenerator** allows you to generate `UxmlFactory` and `UxmlTraits` using `[UxmlElement]` and `[UxmlAttribute]` attributes. 25 | 26 | ```csharp 27 | [UxmlElement] 28 | public partial class CustomVisualElement : VisualElement 29 | { 30 | [UxmlAttribute] 31 | private string CustomAttribute { get; set; } 32 | } 33 | ``` 34 | 35 | ## :cactus: Folder Structure 36 | 37 | . 38 | ├── src 39 | │ ├── UnityUxmlGenerator 40 | │ └── UnityUxmlGenerator.UnityPackage 41 | │ ... 42 | │ └── UnityUxmlGenerator.dll # Auto-generated 43 | │ 44 | ├── UnityUxmlGenerator.sln 45 | 46 | ## :gear: Installation 47 | 48 | You can install **UnityUxmlGenerator** in one of the following ways: 49 | 50 |
1. Install via Package Manager 51 |
52 | 53 | The package is available on the [OpenUPM](https://openupm.com/packages/com.chebanovdd.unityuxmlgenerator/). 54 | 55 | - Open `Edit/Project Settings/Package Manager` 56 | - Add a new `Scoped Registry` (or edit the existing OpenUPM entry) 57 | 58 | ``` 59 | Name package.openupm.com 60 | URL https://package.openupm.com 61 | Scope(s) com.chebanovdd.unityuxmlgenerator 62 | ``` 63 | - Open `Window/Package Manager` 64 | - Select `My Registries` 65 | - Install `UnityUxmlGenerator` package 66 | 67 |
68 | 69 |
2. Install via Git URL 70 |
71 | 72 | You can add `https://github.com/LibraStack/UnityUxmlGenerator.git?path=src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator` to the Package Manager. 73 | 74 | If you want to set a target version, UnityUxmlGenerator uses the `v*.*.*` release tag, so you can specify a version like `#v0.0.1`. For example `https://github.com/LibraStack/UnityUxmlGenerator.git?path=src/UnityUxmlGenerator.UnityPackage/Assets/Plugins/UnityUxmlGenerator#v0.0.1`. 75 | 76 |
77 | 78 | ## :joystick: How To Use 79 | 80 | ### UxmlElement 81 | 82 | To create a custom control, just add the `[UxmlElement]` attribute to the custom control class definition. The custom control class must be declared as a partial class and be inherited from `VisualElement` or one of its derived classes. By default, the custom control appears in the Library tab in UI Builder. 83 | 84 | You can use the `[UxmlAttribute]` attribute to declare that a property is associated with a `UXML` attribute. 85 | 86 | The following example creates a custom control with multiple attributes: 87 | 88 | ```csharp 89 | [UxmlElement] 90 | public partial class CustomVisualElement : VisualElement 91 | { 92 | [UxmlAttribute] 93 | private string CustomAttribute { get; set; } 94 | 95 | [UxmlAttribute("DefaultValue")] 96 | private string CustomAttributeWithDefaultValue { get; set; } 97 | } 98 | ``` 99 | 100 |
Generated code 101 |
102 | 103 | `CustomVisualElement.UxmlFactory.g.cs` 104 | 105 | ```csharp 106 | partial class CustomVisualElement 107 | { 108 | [global::System.CodeDom.Compiler.GeneratedCode("UnityUxmlGenerator", "1.0.0.0")] 109 | [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 110 | public new class UxmlFactory : global::UnityEngine.UIElements.UxmlFactory 111 | { 112 | } 113 | } 114 | ``` 115 | 116 | `CustomVisualElement.UxmlTraits.g.cs` 117 | 118 | ```csharp 119 | partial class CustomVisualElement 120 | { 121 | [global::System.CodeDom.Compiler.GeneratedCode("UnityUxmlGenerator", "1.0.0.0")] 122 | [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 123 | public new class UxmlTraits : global::UnityEngine.UIElements.VisualElement.UxmlTraits 124 | { 125 | [global::System.CodeDom.Compiler.GeneratedCode("UnityUxmlGenerator", "1.0.0.0")] 126 | private readonly global::UnityEngine.UIElements.UxmlStringAttributeDescription _customAttribute = new() 127 | { 128 | name = "custom-attribute", 129 | defaultValue = default 130 | }; 131 | 132 | [global::System.CodeDom.Compiler.GeneratedCode("UnityUxmlGenerator", "1.0.0.0")] 133 | private readonly global::UnityEngine.UIElements.UxmlStringAttributeDescription _customAttributeWithDefaultValue = new() 134 | { 135 | name = "custom-attribute-with-default-value", 136 | defaultValue = "DefaultValue" 137 | }; 138 | 139 | [global::System.CodeDom.Compiler.GeneratedCode("UnityUxmlGenerator", "1.0.0.0")] 140 | [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 141 | public override void Init(global::UnityEngine.UIElements.VisualElement visualElement, 142 | global::UnityEngine.UIElements.IUxmlAttributes bag, 143 | global::UnityEngine.UIElements.CreationContext context) 144 | { 145 | base.Init(visualElement, bag, context); 146 | var control = (CustomVisualElement)visualElement; 147 | control.CustomAttribute = _customAttribute.GetValueFromBag(bag, context); 148 | control.CustomAttributeWithDefaultValue = _customAttributeWithDefaultValue.GetValueFromBag(bag, context); 149 | } 150 | } 151 | } 152 | ``` 153 | 154 |
155 | 156 | The following UXML document uses the custom control: 157 | 158 | ```xml 159 | 160 | 161 | 162 | ``` 163 | 164 | ### UxmlAttribute 165 | 166 | By default, the property name splits into lowercase words connected by hyphens. The original uppercase characters in the name are used to denote where the name should be split. For example, if the property name is `CustomAttribute`, the corresponding attribute name would be `custom-attribute`. 167 | 168 | The following example creates a custom control with custom attributes: 169 | 170 | ```csharp 171 | [UxmlElement] 172 | public partial class CustomVisualElement : VisualElement 173 | { 174 | [UxmlAttribute] 175 | private bool MyBoolValue { get; set; } 176 | 177 | [UxmlAttribute] 178 | private int MyIntValue { get; set; } 179 | 180 | [UxmlAttribute] 181 | private long MyLongValue { get; set; } 182 | 183 | [UxmlAttribute] 184 | private float MyFloatValue { get; set; } 185 | 186 | [UxmlAttribute] 187 | private double MyDoubleValue { get; set; } 188 | 189 | [UxmlAttribute] 190 | private string MyStringValue { get; set; } 191 | 192 | [UxmlAttribute] 193 | private MyEnum MyEnumValue { get; set; } 194 | 195 | [UxmlAttribute] 196 | private Color MyColorValue { get; set; } 197 | } 198 | ``` 199 | 200 | Use the `[UxmlAttribute]` constructor to provide a default value for an attribute. Note that the provided value type and the property type must match. The only exception is for the `Color` type, where you must pass the name of the desired color. 201 | 202 | ```csharp 203 | [UxmlElement] 204 | public partial class CustomVisualElement : VisualElement 205 | { 206 | [UxmlAttribute(69)] 207 | private int MyIntValue { get; set; } 208 | 209 | [UxmlAttribute(6.9f)] 210 | private float MyFloatValue { get; set; } 211 | 212 | [UxmlAttribute("Hello World")] 213 | private string MyStringValue { get; set; } 214 | 215 | [UxmlAttribute(MyEnum.One)] 216 | private MyEnum MyEnumValue { get; set; } 217 | 218 | [UxmlAttribute(nameof(Color.red))] 219 | private Color MyColorValue { get; set; } 220 | } 221 | ``` 222 | 223 | ## :bookmark_tabs: Contributing 224 | 225 | You may contribute in several ways like creating new features, fixing bugs or improving documentation and examples. 226 | 227 | ### Discussions 228 | 229 | Use [discussions](https://github.com/LibraStack/UnityUxmlGenerator/discussions) to have conversations and post answers without opening issues. 230 | 231 | Discussions is a place to: 232 | * Share ideas 233 | * Ask questions 234 | * Engage with other community members 235 | 236 | ### Report a bug 237 | 238 | If you find a bug in the source code, please [create bug report](https://github.com/LibraStack/UnityUxmlGenerator/issues/new?assignees=ChebanovDD&labels=bug&template=bug_report.md&title=). 239 | 240 | > Please browse [existing issues](https://github.com/LibraStack/UnityUxmlGenerator/issues) to see whether a bug has previously been reported. 241 | 242 | ### Request a feature 243 | 244 | If you have an idea, or you're missing a capability that would make development easier, please [submit feature request](https://github.com/LibraStack/UnityUxmlGenerator/issues/new?assignees=ChebanovDD&labels=enhancement&template=feature_request.md&title=). 245 | 246 | > If a similar feature request already exists, don't forget to leave a "+1" or add additional information, such as your thoughts and vision about the feature. 247 | 248 | ### Show your support 249 | 250 | Give a :star: if this project helped you! 251 | 252 | Buy Me A Coffee 253 | 254 | ## :balance_scale: License 255 | 256 | Usage is provided under the [MIT License](LICENSE). 257 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | - serializedVersion: 3 297 | m_Name: Enable Debug Button 1 298 | descriptiveName: 299 | descriptiveNegativeName: 300 | negativeButton: 301 | positiveButton: left ctrl 302 | altNegativeButton: 303 | altPositiveButton: joystick button 8 304 | gravity: 0 305 | dead: 0 306 | sensitivity: 0 307 | snap: 0 308 | invert: 0 309 | type: 0 310 | axis: 0 311 | joyNum: 0 312 | - serializedVersion: 3 313 | m_Name: Enable Debug Button 2 314 | descriptiveName: 315 | descriptiveNegativeName: 316 | negativeButton: 317 | positiveButton: backspace 318 | altNegativeButton: 319 | altPositiveButton: joystick button 9 320 | gravity: 0 321 | dead: 0 322 | sensitivity: 0 323 | snap: 0 324 | invert: 0 325 | type: 0 326 | axis: 0 327 | joyNum: 0 328 | - serializedVersion: 3 329 | m_Name: Debug Reset 330 | descriptiveName: 331 | descriptiveNegativeName: 332 | negativeButton: 333 | positiveButton: left alt 334 | altNegativeButton: 335 | altPositiveButton: joystick button 1 336 | gravity: 0 337 | dead: 0 338 | sensitivity: 0 339 | snap: 0 340 | invert: 0 341 | type: 0 342 | axis: 0 343 | joyNum: 0 344 | - serializedVersion: 3 345 | m_Name: Debug Next 346 | descriptiveName: 347 | descriptiveNegativeName: 348 | negativeButton: 349 | positiveButton: page down 350 | altNegativeButton: 351 | altPositiveButton: joystick button 5 352 | gravity: 0 353 | dead: 0 354 | sensitivity: 0 355 | snap: 0 356 | invert: 0 357 | type: 0 358 | axis: 0 359 | joyNum: 0 360 | - serializedVersion: 3 361 | m_Name: Debug Previous 362 | descriptiveName: 363 | descriptiveNegativeName: 364 | negativeButton: 365 | positiveButton: page up 366 | altNegativeButton: 367 | altPositiveButton: joystick button 4 368 | gravity: 0 369 | dead: 0 370 | sensitivity: 0 371 | snap: 0 372 | invert: 0 373 | type: 0 374 | axis: 0 375 | joyNum: 0 376 | - serializedVersion: 3 377 | m_Name: Debug Validate 378 | descriptiveName: 379 | descriptiveNegativeName: 380 | negativeButton: 381 | positiveButton: return 382 | altNegativeButton: 383 | altPositiveButton: joystick button 0 384 | gravity: 0 385 | dead: 0 386 | sensitivity: 0 387 | snap: 0 388 | invert: 0 389 | type: 0 390 | axis: 0 391 | joyNum: 0 392 | - serializedVersion: 3 393 | m_Name: Debug Persistent 394 | descriptiveName: 395 | descriptiveNegativeName: 396 | negativeButton: 397 | positiveButton: right shift 398 | altNegativeButton: 399 | altPositiveButton: joystick button 2 400 | gravity: 0 401 | dead: 0 402 | sensitivity: 0 403 | snap: 0 404 | invert: 0 405 | type: 0 406 | axis: 0 407 | joyNum: 0 408 | - serializedVersion: 3 409 | m_Name: Debug Multiplier 410 | descriptiveName: 411 | descriptiveNegativeName: 412 | negativeButton: 413 | positiveButton: left shift 414 | altNegativeButton: 415 | altPositiveButton: joystick button 3 416 | gravity: 0 417 | dead: 0 418 | sensitivity: 0 419 | snap: 0 420 | invert: 0 421 | type: 0 422 | axis: 0 423 | joyNum: 0 424 | - serializedVersion: 3 425 | m_Name: Debug Horizontal 426 | descriptiveName: 427 | descriptiveNegativeName: 428 | negativeButton: left 429 | positiveButton: right 430 | altNegativeButton: 431 | altPositiveButton: 432 | gravity: 1000 433 | dead: 0.001 434 | sensitivity: 1000 435 | snap: 0 436 | invert: 0 437 | type: 0 438 | axis: 0 439 | joyNum: 0 440 | - serializedVersion: 3 441 | m_Name: Debug Vertical 442 | descriptiveName: 443 | descriptiveNegativeName: 444 | negativeButton: down 445 | positiveButton: up 446 | altNegativeButton: 447 | altPositiveButton: 448 | gravity: 1000 449 | dead: 0.001 450 | sensitivity: 1000 451 | snap: 0 452 | invert: 0 453 | type: 0 454 | axis: 0 455 | joyNum: 0 456 | - serializedVersion: 3 457 | m_Name: Debug Vertical 458 | descriptiveName: 459 | descriptiveNegativeName: 460 | negativeButton: down 461 | positiveButton: up 462 | altNegativeButton: 463 | altPositiveButton: 464 | gravity: 1000 465 | dead: 0.001 466 | sensitivity: 1000 467 | snap: 0 468 | invert: 0 469 | type: 2 470 | axis: 6 471 | joyNum: 0 472 | - serializedVersion: 3 473 | m_Name: Debug Horizontal 474 | descriptiveName: 475 | descriptiveNegativeName: 476 | negativeButton: left 477 | positiveButton: right 478 | altNegativeButton: 479 | altPositiveButton: 480 | gravity: 1000 481 | dead: 0.001 482 | sensitivity: 1000 483 | snap: 0 484 | invert: 0 485 | type: 2 486 | axis: 5 487 | joyNum: 0 488 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/Packages/packages-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.animation": { 4 | "version": "7.0.10", 5 | "depth": 1, 6 | "source": "registry", 7 | "dependencies": { 8 | "com.unity.2d.common": "6.0.6", 9 | "com.unity.2d.sprite": "1.0.0", 10 | "com.unity.modules.animation": "1.0.0", 11 | "com.unity.modules.uielements": "1.0.0" 12 | }, 13 | "url": "https://packages.unity.com" 14 | }, 15 | "com.unity.2d.common": { 16 | "version": "6.0.6", 17 | "depth": 2, 18 | "source": "registry", 19 | "dependencies": { 20 | "com.unity.2d.sprite": "1.0.0", 21 | "com.unity.mathematics": "1.1.0", 22 | "com.unity.modules.uielements": "1.0.0", 23 | "com.unity.burst": "1.5.1" 24 | }, 25 | "url": "https://packages.unity.com" 26 | }, 27 | "com.unity.2d.path": { 28 | "version": "5.0.2", 29 | "depth": 2, 30 | "source": "registry", 31 | "dependencies": {}, 32 | "url": "https://packages.unity.com" 33 | }, 34 | "com.unity.2d.pixel-perfect": { 35 | "version": "5.0.3", 36 | "depth": 1, 37 | "source": "registry", 38 | "dependencies": {}, 39 | "url": "https://packages.unity.com" 40 | }, 41 | "com.unity.2d.psdimporter": { 42 | "version": "6.0.7", 43 | "depth": 1, 44 | "source": "registry", 45 | "dependencies": { 46 | "com.unity.2d.animation": "7.0.9", 47 | "com.unity.2d.common": "6.0.6", 48 | "com.unity.2d.sprite": "1.0.0" 49 | }, 50 | "url": "https://packages.unity.com" 51 | }, 52 | "com.unity.2d.sprite": { 53 | "version": "1.0.0", 54 | "depth": 1, 55 | "source": "builtin", 56 | "dependencies": {} 57 | }, 58 | "com.unity.2d.spriteshape": { 59 | "version": "7.0.7", 60 | "depth": 1, 61 | "source": "registry", 62 | "dependencies": { 63 | "com.unity.mathematics": "1.1.0", 64 | "com.unity.2d.common": "6.0.6", 65 | "com.unity.2d.path": "5.0.2", 66 | "com.unity.modules.physics2d": "1.0.0" 67 | }, 68 | "url": "https://packages.unity.com" 69 | }, 70 | "com.unity.2d.tilemap": { 71 | "version": "1.0.0", 72 | "depth": 1, 73 | "source": "builtin", 74 | "dependencies": {} 75 | }, 76 | "com.unity.2d.tilemap.extras": { 77 | "version": "2.2.5", 78 | "depth": 1, 79 | "source": "registry", 80 | "dependencies": { 81 | "com.unity.modules.tilemap": "1.0.0", 82 | "com.unity.2d.tilemap": "1.0.0", 83 | "com.unity.ugui": "1.0.0", 84 | "com.unity.modules.jsonserialize": "1.0.0" 85 | }, 86 | "url": "https://packages.unity.com" 87 | }, 88 | "com.unity.burst": { 89 | "version": "1.6.6", 90 | "depth": 3, 91 | "source": "registry", 92 | "dependencies": { 93 | "com.unity.mathematics": "1.2.1" 94 | }, 95 | "url": "https://packages.unity.com" 96 | }, 97 | "com.unity.collab-proxy": { 98 | "version": "2.0.4", 99 | "depth": 0, 100 | "source": "registry", 101 | "dependencies": {}, 102 | "url": "https://packages.unity.com" 103 | }, 104 | "com.unity.ext.nunit": { 105 | "version": "1.0.6", 106 | "depth": 1, 107 | "source": "registry", 108 | "dependencies": {}, 109 | "url": "https://packages.unity.com" 110 | }, 111 | "com.unity.feature.2d": { 112 | "version": "1.0.0", 113 | "depth": 0, 114 | "source": "builtin", 115 | "dependencies": { 116 | "com.unity.2d.animation": "7.0.10", 117 | "com.unity.2d.pixel-perfect": "5.0.3", 118 | "com.unity.2d.psdimporter": "6.0.7", 119 | "com.unity.2d.sprite": "1.0.0", 120 | "com.unity.2d.spriteshape": "7.0.7", 121 | "com.unity.2d.tilemap": "1.0.0", 122 | "com.unity.2d.tilemap.extras": "2.2.5" 123 | } 124 | }, 125 | "com.unity.ide.rider": { 126 | "version": "3.0.21", 127 | "depth": 0, 128 | "source": "registry", 129 | "dependencies": { 130 | "com.unity.ext.nunit": "1.0.6" 131 | }, 132 | "url": "https://packages.unity.com" 133 | }, 134 | "com.unity.ide.visualstudio": { 135 | "version": "2.0.18", 136 | "depth": 0, 137 | "source": "registry", 138 | "dependencies": { 139 | "com.unity.test-framework": "1.1.9" 140 | }, 141 | "url": "https://packages.unity.com" 142 | }, 143 | "com.unity.ide.vscode": { 144 | "version": "1.2.5", 145 | "depth": 0, 146 | "source": "registry", 147 | "dependencies": {}, 148 | "url": "https://packages.unity.com" 149 | }, 150 | "com.unity.mathematics": { 151 | "version": "1.2.6", 152 | "depth": 2, 153 | "source": "registry", 154 | "dependencies": {}, 155 | "url": "https://packages.unity.com" 156 | }, 157 | "com.unity.test-framework": { 158 | "version": "1.1.33", 159 | "depth": 0, 160 | "source": "registry", 161 | "dependencies": { 162 | "com.unity.ext.nunit": "1.0.6", 163 | "com.unity.modules.imgui": "1.0.0", 164 | "com.unity.modules.jsonserialize": "1.0.0" 165 | }, 166 | "url": "https://packages.unity.com" 167 | }, 168 | "com.unity.textmeshpro": { 169 | "version": "3.0.6", 170 | "depth": 0, 171 | "source": "registry", 172 | "dependencies": { 173 | "com.unity.ugui": "1.0.0" 174 | }, 175 | "url": "https://packages.unity.com" 176 | }, 177 | "com.unity.timeline": { 178 | "version": "1.6.5", 179 | "depth": 0, 180 | "source": "registry", 181 | "dependencies": { 182 | "com.unity.modules.director": "1.0.0", 183 | "com.unity.modules.animation": "1.0.0", 184 | "com.unity.modules.audio": "1.0.0", 185 | "com.unity.modules.particlesystem": "1.0.0" 186 | }, 187 | "url": "https://packages.unity.com" 188 | }, 189 | "com.unity.ugui": { 190 | "version": "1.0.0", 191 | "depth": 0, 192 | "source": "builtin", 193 | "dependencies": { 194 | "com.unity.modules.ui": "1.0.0", 195 | "com.unity.modules.imgui": "1.0.0" 196 | } 197 | }, 198 | "com.unity.visualscripting": { 199 | "version": "1.8.0", 200 | "depth": 0, 201 | "source": "registry", 202 | "dependencies": { 203 | "com.unity.ugui": "1.0.0", 204 | "com.unity.modules.jsonserialize": "1.0.0" 205 | }, 206 | "url": "https://packages.unity.com" 207 | }, 208 | "com.unity.modules.ai": { 209 | "version": "1.0.0", 210 | "depth": 0, 211 | "source": "builtin", 212 | "dependencies": {} 213 | }, 214 | "com.unity.modules.androidjni": { 215 | "version": "1.0.0", 216 | "depth": 0, 217 | "source": "builtin", 218 | "dependencies": {} 219 | }, 220 | "com.unity.modules.animation": { 221 | "version": "1.0.0", 222 | "depth": 0, 223 | "source": "builtin", 224 | "dependencies": {} 225 | }, 226 | "com.unity.modules.assetbundle": { 227 | "version": "1.0.0", 228 | "depth": 0, 229 | "source": "builtin", 230 | "dependencies": {} 231 | }, 232 | "com.unity.modules.audio": { 233 | "version": "1.0.0", 234 | "depth": 0, 235 | "source": "builtin", 236 | "dependencies": {} 237 | }, 238 | "com.unity.modules.cloth": { 239 | "version": "1.0.0", 240 | "depth": 0, 241 | "source": "builtin", 242 | "dependencies": { 243 | "com.unity.modules.physics": "1.0.0" 244 | } 245 | }, 246 | "com.unity.modules.director": { 247 | "version": "1.0.0", 248 | "depth": 0, 249 | "source": "builtin", 250 | "dependencies": { 251 | "com.unity.modules.audio": "1.0.0", 252 | "com.unity.modules.animation": "1.0.0" 253 | } 254 | }, 255 | "com.unity.modules.imageconversion": { 256 | "version": "1.0.0", 257 | "depth": 0, 258 | "source": "builtin", 259 | "dependencies": {} 260 | }, 261 | "com.unity.modules.imgui": { 262 | "version": "1.0.0", 263 | "depth": 0, 264 | "source": "builtin", 265 | "dependencies": {} 266 | }, 267 | "com.unity.modules.jsonserialize": { 268 | "version": "1.0.0", 269 | "depth": 0, 270 | "source": "builtin", 271 | "dependencies": {} 272 | }, 273 | "com.unity.modules.particlesystem": { 274 | "version": "1.0.0", 275 | "depth": 0, 276 | "source": "builtin", 277 | "dependencies": {} 278 | }, 279 | "com.unity.modules.physics": { 280 | "version": "1.0.0", 281 | "depth": 0, 282 | "source": "builtin", 283 | "dependencies": {} 284 | }, 285 | "com.unity.modules.physics2d": { 286 | "version": "1.0.0", 287 | "depth": 0, 288 | "source": "builtin", 289 | "dependencies": {} 290 | }, 291 | "com.unity.modules.screencapture": { 292 | "version": "1.0.0", 293 | "depth": 0, 294 | "source": "builtin", 295 | "dependencies": { 296 | "com.unity.modules.imageconversion": "1.0.0" 297 | } 298 | }, 299 | "com.unity.modules.subsystems": { 300 | "version": "1.0.0", 301 | "depth": 1, 302 | "source": "builtin", 303 | "dependencies": { 304 | "com.unity.modules.jsonserialize": "1.0.0" 305 | } 306 | }, 307 | "com.unity.modules.terrain": { 308 | "version": "1.0.0", 309 | "depth": 0, 310 | "source": "builtin", 311 | "dependencies": {} 312 | }, 313 | "com.unity.modules.terrainphysics": { 314 | "version": "1.0.0", 315 | "depth": 0, 316 | "source": "builtin", 317 | "dependencies": { 318 | "com.unity.modules.physics": "1.0.0", 319 | "com.unity.modules.terrain": "1.0.0" 320 | } 321 | }, 322 | "com.unity.modules.tilemap": { 323 | "version": "1.0.0", 324 | "depth": 0, 325 | "source": "builtin", 326 | "dependencies": { 327 | "com.unity.modules.physics2d": "1.0.0" 328 | } 329 | }, 330 | "com.unity.modules.ui": { 331 | "version": "1.0.0", 332 | "depth": 0, 333 | "source": "builtin", 334 | "dependencies": {} 335 | }, 336 | "com.unity.modules.uielements": { 337 | "version": "1.0.0", 338 | "depth": 0, 339 | "source": "builtin", 340 | "dependencies": { 341 | "com.unity.modules.ui": "1.0.0", 342 | "com.unity.modules.imgui": "1.0.0", 343 | "com.unity.modules.jsonserialize": "1.0.0", 344 | "com.unity.modules.uielementsnative": "1.0.0" 345 | } 346 | }, 347 | "com.unity.modules.uielementsnative": { 348 | "version": "1.0.0", 349 | "depth": 1, 350 | "source": "builtin", 351 | "dependencies": { 352 | "com.unity.modules.ui": "1.0.0", 353 | "com.unity.modules.imgui": "1.0.0", 354 | "com.unity.modules.jsonserialize": "1.0.0" 355 | } 356 | }, 357 | "com.unity.modules.umbra": { 358 | "version": "1.0.0", 359 | "depth": 0, 360 | "source": "builtin", 361 | "dependencies": {} 362 | }, 363 | "com.unity.modules.unityanalytics": { 364 | "version": "1.0.0", 365 | "depth": 0, 366 | "source": "builtin", 367 | "dependencies": { 368 | "com.unity.modules.unitywebrequest": "1.0.0", 369 | "com.unity.modules.jsonserialize": "1.0.0" 370 | } 371 | }, 372 | "com.unity.modules.unitywebrequest": { 373 | "version": "1.0.0", 374 | "depth": 0, 375 | "source": "builtin", 376 | "dependencies": {} 377 | }, 378 | "com.unity.modules.unitywebrequestassetbundle": { 379 | "version": "1.0.0", 380 | "depth": 0, 381 | "source": "builtin", 382 | "dependencies": { 383 | "com.unity.modules.assetbundle": "1.0.0", 384 | "com.unity.modules.unitywebrequest": "1.0.0" 385 | } 386 | }, 387 | "com.unity.modules.unitywebrequestaudio": { 388 | "version": "1.0.0", 389 | "depth": 0, 390 | "source": "builtin", 391 | "dependencies": { 392 | "com.unity.modules.unitywebrequest": "1.0.0", 393 | "com.unity.modules.audio": "1.0.0" 394 | } 395 | }, 396 | "com.unity.modules.unitywebrequesttexture": { 397 | "version": "1.0.0", 398 | "depth": 0, 399 | "source": "builtin", 400 | "dependencies": { 401 | "com.unity.modules.unitywebrequest": "1.0.0", 402 | "com.unity.modules.imageconversion": "1.0.0" 403 | } 404 | }, 405 | "com.unity.modules.unitywebrequestwww": { 406 | "version": "1.0.0", 407 | "depth": 0, 408 | "source": "builtin", 409 | "dependencies": { 410 | "com.unity.modules.unitywebrequest": "1.0.0", 411 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 412 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 413 | "com.unity.modules.audio": "1.0.0", 414 | "com.unity.modules.assetbundle": "1.0.0", 415 | "com.unity.modules.imageconversion": "1.0.0" 416 | } 417 | }, 418 | "com.unity.modules.vehicles": { 419 | "version": "1.0.0", 420 | "depth": 0, 421 | "source": "builtin", 422 | "dependencies": { 423 | "com.unity.modules.physics": "1.0.0" 424 | } 425 | }, 426 | "com.unity.modules.video": { 427 | "version": "1.0.0", 428 | "depth": 0, 429 | "source": "builtin", 430 | "dependencies": { 431 | "com.unity.modules.audio": "1.0.0", 432 | "com.unity.modules.ui": "1.0.0", 433 | "com.unity.modules.unitywebrequest": "1.0.0" 434 | } 435 | }, 436 | "com.unity.modules.vr": { 437 | "version": "1.0.0", 438 | "depth": 0, 439 | "source": "builtin", 440 | "dependencies": { 441 | "com.unity.modules.jsonserialize": "1.0.0", 442 | "com.unity.modules.physics": "1.0.0", 443 | "com.unity.modules.xr": "1.0.0" 444 | } 445 | }, 446 | "com.unity.modules.wind": { 447 | "version": "1.0.0", 448 | "depth": 0, 449 | "source": "builtin", 450 | "dependencies": {} 451 | }, 452 | "com.unity.modules.xr": { 453 | "version": "1.0.0", 454 | "depth": 0, 455 | "source": "builtin", 456 | "dependencies": { 457 | "com.unity.modules.physics": "1.0.0", 458 | "com.unity.modules.jsonserialize": "1.0.0", 459 | "com.unity.modules.subsystems": "1.0.0" 460 | } 461 | } 462 | } 463 | } 464 | -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/UxmlGenerator.Traits.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Microsoft.CodeAnalysis; 3 | using Microsoft.CodeAnalysis.CSharp; 4 | using Microsoft.CodeAnalysis.CSharp.Syntax; 5 | using Microsoft.CodeAnalysis.Text; 6 | using UnityUxmlGenerator.Captures; 7 | using UnityUxmlGenerator.Diagnostics; 8 | using UnityUxmlGenerator.Extensions; 9 | using UnityUxmlGenerator.Structs; 10 | 11 | namespace UnityUxmlGenerator; 12 | 13 | internal sealed partial class UxmlGenerator 14 | { 15 | private const string UnityColorTypeFullName = "global::UnityEngine.Color"; 16 | private const string UnityUiElementsFullName = "global::UnityEngine.UIElements.{0}"; 17 | private const string UxmlColorAttributeDescription = "UxmlColorAttributeDescription"; 18 | 19 | private static SourceText GenerateUxmlTraits(GeneratorExecutionContext context, UxmlTraitsCapture capture) 20 | { 21 | return CompilationUnitWidget( 22 | namespaceIdentifier: capture.ClassNamespace, 23 | member: ClassWidget( 24 | identifier: capture.ClassName, 25 | modifier: SyntaxKind.PartialKeyword, 26 | members: new MemberDeclarationSyntax[] 27 | { 28 | ClassWidget( 29 | identifier: "UxmlTraits", 30 | modifiers: new[] { SyntaxKind.PublicKeyword, SyntaxKind.NewKeyword }, 31 | baseType: SimpleBaseType(IdentifierName($"{GetBaseClassName(context, capture)}.UxmlTraits")), 32 | members: GetTraitsClassMembers(context, capture), 33 | addGeneratedCodeAttributes: true), 34 | MethodWidget( 35 | identifier: "OnUxmlTraitsInitialized", 36 | type: PredefinedType(Token(SyntaxKind.VoidKeyword)), 37 | modifier: SyntaxKind.PartialKeyword, 38 | parameter: ParameterWidget( 39 | identifier: "uxmlAttributes", 40 | type: IdentifierName(string.Format(UnityUiElementsFullName, "IUxmlAttributes"))), 41 | addGeneratedCodeAttributes: true) 42 | }), 43 | normalizeWhitespace: true) 44 | .GetText(Encoding.UTF8); 45 | } 46 | 47 | private static IEnumerable GetTraitsClassMembers(GeneratorExecutionContext context, 48 | UxmlTraitsCapture capture) 49 | { 50 | var initMethodBody = new List 51 | { 52 | MethodCallWidget( 53 | expression: BaseExpression(), 54 | identifier: "Init", 55 | arguments: new[] 56 | { 57 | Argument(IdentifierName("visualElement")), 58 | Argument(IdentifierName("bag")), 59 | Argument(IdentifierName("context")) 60 | }), 61 | LocalVariableWidget( 62 | identifier: "control", 63 | initializer: CastExpressionWidget( 64 | identifier: "visualElement", 65 | typeToCast: IdentifierName(capture.ClassName))) 66 | }; 67 | 68 | var traitsClassMembers = new List(); 69 | 70 | foreach (var (property, attribute) in capture.Properties) 71 | { 72 | context.CancellationToken.ThrowIfCancellationRequested(); 73 | 74 | if (IsValidAttribute(context, attribute) == false || 75 | TryGetUxmlAttributeInfo(context, property, attribute, out var uxmlAttributeInfo) == false) 76 | { 77 | continue; 78 | } 79 | 80 | var propertyName = uxmlAttributeInfo.PropertyName; 81 | var fieldName = uxmlAttributeInfo.PrivateFieldName; 82 | 83 | initMethodBody.Add(GetAttributeValueAssignmentStatement(propertyName, fieldName)); 84 | traitsClassMembers.Add(GetAttributeFieldDeclaration(uxmlAttributeInfo)); 85 | } 86 | 87 | initMethodBody.Add(MethodCallWidget( 88 | expression: IdentifierName("control"), 89 | identifier: "OnUxmlTraitsInitialized", 90 | argument: Argument(IdentifierName("bag"))) 91 | ); 92 | 93 | var initMethod = MethodWidget( 94 | identifier: "Init", 95 | type: PredefinedType(Token(SyntaxKind.VoidKeyword)), 96 | modifiers: new[] { SyntaxKind.PublicKeyword, SyntaxKind.OverrideKeyword }, 97 | parameters: new[] 98 | { 99 | ParameterWidget( 100 | identifier: "visualElement", 101 | type: IdentifierName(string.Format(UnityUiElementsFullName, "VisualElement"))), 102 | ParameterWidget( 103 | identifier: "bag", 104 | type: IdentifierName(string.Format(UnityUiElementsFullName, "IUxmlAttributes"))), 105 | ParameterWidget( 106 | identifier: "context", 107 | type: IdentifierName(string.Format(UnityUiElementsFullName, "CreationContext"))), 108 | }, 109 | bodyStatements: initMethodBody, 110 | addGeneratedCodeAttributes: true 111 | ); 112 | 113 | traitsClassMembers.Add(initMethod); 114 | 115 | return traitsClassMembers; 116 | } 117 | 118 | private static FieldDeclarationSyntax GetAttributeFieldDeclaration(UxmlAttributeInfo attributeInfo) 119 | { 120 | return FieldWidget( 121 | identifier: attributeInfo.PrivateFieldName, 122 | type: IdentifierName(string.Format(UnityUiElementsFullName, attributeInfo.TypeIdentifier)), 123 | modifiers: new[] { SyntaxKind.PrivateKeyword, SyntaxKind.ReadOnlyKeyword }, 124 | initializers: new[] 125 | { 126 | AssignmentWidget( 127 | left: IdentifierName("name"), 128 | right: LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(attributeInfo.AttributeUxmlName))), 129 | AssignmentWidget( 130 | left: IdentifierName("defaultValue"), 131 | right: attributeInfo.DefaultValueAssignmentExpression) 132 | }, 133 | addGeneratedCodeAttributes: true 134 | ); 135 | } 136 | 137 | private static StatementSyntax GetAttributeValueAssignmentStatement(string propertyName, string fieldName) 138 | { 139 | return AssignmentStatementWidget( 140 | left: MemberAccessWidget(identifier: "control", memberName: propertyName), 141 | right: MethodInvocationWidget( 142 | memberIdentifier: fieldName, 143 | methodName: "GetValueFromBag", 144 | arguments: new[] 145 | { 146 | Argument(IdentifierName("bag")), 147 | Argument(IdentifierName("context")) 148 | })); 149 | } 150 | 151 | private static string GetBaseClassName(GeneratorExecutionContext context, UxmlTraitsCapture capture) 152 | { 153 | var baseClassName = capture.GetBaseClassName(out var genericTypeArguments); 154 | var baseClassNamespace = capture.BaseClassType.GetTypeNamespace(context); 155 | 156 | if (genericTypeArguments is null) 157 | { 158 | return $"global::{baseClassNamespace}.{baseClassName}"; 159 | } 160 | 161 | var stringBuilder = new StringBuilder(); 162 | 163 | stringBuilder.Append("global::"); 164 | stringBuilder.Append(baseClassNamespace); 165 | stringBuilder.Append('.'); 166 | stringBuilder.Append(baseClassName); 167 | stringBuilder.AppendGenericString(context, genericTypeArguments); 168 | 169 | return stringBuilder.ToString(); 170 | } 171 | 172 | private static bool TryGetUxmlAttributeInfo(GeneratorExecutionContext context, PropertyDeclarationSyntax property, 173 | AttributeSyntax attribute, out UxmlAttributeInfo attributeInfo) 174 | { 175 | var propertyName = property.GetName(); 176 | var uxmlAttributeDefaultValue = GetAttributeArgumentValue(attribute); 177 | 178 | attributeInfo = new UxmlAttributeInfo 179 | { 180 | PropertyName = propertyName, 181 | PrivateFieldName = propertyName.ToPrivateFieldName(), 182 | AttributeUxmlName = propertyName.ToDashCase() 183 | }; 184 | 185 | if (property.Type is PredefinedTypeSyntax predefinedType) 186 | { 187 | ConfigureAttributeInfoAsPredefinedType(predefinedType, uxmlAttributeDefaultValue, ref attributeInfo); 188 | return true; 189 | } 190 | 191 | SyntaxToken? propertyTypeIdentifier = property.Type switch 192 | { 193 | IdentifierNameSyntax identifierName => identifierName.Identifier, 194 | QualifiedNameSyntax qualifiedNameSyntax => qualifiedNameSyntax.Right.Identifier, 195 | _ => null 196 | }; 197 | 198 | if (propertyTypeIdentifier is null) 199 | { 200 | return false; 201 | } 202 | 203 | var typeSymbol = property.Type.GetTypeSymbol(context); 204 | var typeNamespace = typeSymbol?.ContainingNamespace.ToString(); 205 | 206 | var typeName = propertyTypeIdentifier.Value.Text; 207 | var typeFullName = $"global::{typeNamespace}.{typeName}"; 208 | 209 | if (typeFullName == UnityColorTypeFullName) 210 | { 211 | attributeInfo.TypeIdentifier = UxmlColorAttributeDescription; 212 | attributeInfo.DefaultValueAssignmentExpression = uxmlAttributeDefaultValue is null 213 | ? LiteralExpression(SyntaxKind.DefaultLiteralExpression, Token(SyntaxKind.DefaultKeyword)) 214 | : IdentifierName($"global::UnityEngine.{uxmlAttributeDefaultValue}"); 215 | return true; 216 | } 217 | 218 | if (typeSymbol?.TypeKind is not TypeKind.Enum) 219 | { 220 | ReportDiagnostic(PropertyTypeIsNotSupportedError, context, property.GetLocation(), typeSymbol?.Name); 221 | return false; 222 | } 223 | 224 | attributeInfo.TypeIdentifier = $"UxmlEnumAttributeDescription<{typeFullName}>"; 225 | 226 | if (uxmlAttributeDefaultValue is null) 227 | { 228 | attributeInfo.DefaultValueAssignmentExpression = LiteralExpression(SyntaxKind.DefaultLiteralExpression, 229 | Token(SyntaxKind.DefaultKeyword)); 230 | return true; 231 | } 232 | 233 | var attributeArgumentTypeSymbol = attribute.ArgumentList!.Arguments.First().Expression.GetTypeSymbol(context); 234 | if (attributeArgumentTypeSymbol?.TypeKind is TypeKind.Enum) 235 | { 236 | attributeInfo.DefaultValueAssignmentExpression = 237 | IdentifierName($"{typeFullName}.{uxmlAttributeDefaultValue}"); 238 | return true; 239 | } 240 | 241 | ReportDiagnostic(IncorrectEnumDefaultValueTypeError, context, attribute.GetLocation(), 242 | attributeArgumentTypeSymbol?.Name); 243 | return false; 244 | } 245 | 246 | private static void ConfigureAttributeInfoAsPredefinedType(PredefinedTypeSyntax predefinedPropertyType, 247 | string? uxmlAttributeDefaultValue, ref UxmlAttributeInfo attributeInfo) 248 | { 249 | attributeInfo.TypeIdentifier = $"Uxml{predefinedPropertyType.Keyword.Text.FirstCharToUpper()}AttributeDescription"; 250 | 251 | if (uxmlAttributeDefaultValue is null) 252 | { 253 | attributeInfo.DefaultValueAssignmentExpression = 254 | LiteralExpression(SyntaxKind.DefaultLiteralExpression, Token(SyntaxKind.DefaultKeyword)); 255 | return; 256 | } 257 | 258 | if (predefinedPropertyType.IsBoolType()) 259 | { 260 | attributeInfo.DefaultValueAssignmentExpression = IdentifierName(uxmlAttributeDefaultValue); 261 | return; 262 | } 263 | 264 | if (predefinedPropertyType.IsStringType()) 265 | { 266 | attributeInfo.DefaultValueAssignmentExpression = LiteralExpression(SyntaxKind.StringLiteralExpression, 267 | Literal(uxmlAttributeDefaultValue)); 268 | return; 269 | } 270 | 271 | if (predefinedPropertyType.IsNumericType()) 272 | { 273 | attributeInfo.DefaultValueAssignmentExpression = LiteralExpression(SyntaxKind.NumericLiteralExpression, 274 | Literal(uxmlAttributeDefaultValue, uxmlAttributeDefaultValue)); 275 | } 276 | } 277 | 278 | private static string? GetAttributeArgumentValue(AttributeSyntax attribute) 279 | { 280 | if (attribute.ArgumentList is null || attribute.ArgumentList.Arguments.Any() == false) 281 | { 282 | return null; 283 | } 284 | 285 | return attribute.ArgumentList.Arguments.First().Expression switch 286 | { 287 | IdentifierNameSyntax identifierName => identifierName.Identifier.Text, 288 | PrefixUnaryExpressionSyntax unary => GetUnaryExpressionValue(unary), 289 | LiteralExpressionSyntax literal => GetLiteralExpressionValue(literal), 290 | InvocationExpressionSyntax invocation => GetInvocationExpressionValue(invocation), 291 | MemberAccessExpressionSyntax member => GetMemberAccessExpressionValue(member), 292 | _ => null 293 | }; 294 | } 295 | 296 | private static string GetUnaryExpressionValue(PrefixUnaryExpressionSyntax unary) 297 | { 298 | var value = unary.Operand.GetText().ToString(); 299 | 300 | return unary.IsKind(SyntaxKind.UnaryMinusExpression) ? $"-{value}" : value; 301 | } 302 | 303 | private static string? GetLiteralExpressionValue(LiteralExpressionSyntax literal) 304 | { 305 | if (literal.Token.IsKind(SyntaxKind.DefaultKeyword)) 306 | { 307 | return null; 308 | } 309 | 310 | return literal.Token.IsKind(SyntaxKind.StringLiteralToken) ? literal.Token.ValueText : literal.Token.Text; 311 | } 312 | 313 | private static string GetMemberAccessExpressionValue(MemberAccessExpressionSyntax member) 314 | { 315 | return member.Name.Identifier.Text; 316 | } 317 | 318 | private static string? GetInvocationExpressionValue(InvocationExpressionSyntax invocation) 319 | { 320 | return invocation.ArgumentList.Arguments.FirstOrDefault()?.Expression.GetText().ToString(); 321 | } 322 | 323 | private static void ReportDiagnostic(DiagnosticDescriptor diagnosticDescriptor, GeneratorExecutionContext context, 324 | Location location, params object?[]? args) 325 | { 326 | context.ReportDiagnostic(diagnosticDescriptor.CreateDiagnostic(location, args)); 327 | } 328 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator/UxmlGenerator.Widgets.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.CodeAnalysis; 2 | using Microsoft.CodeAnalysis.CSharp; 3 | using Microsoft.CodeAnalysis.CSharp.Syntax; 4 | 5 | namespace UnityUxmlGenerator; 6 | 7 | internal sealed partial class UxmlGenerator 8 | { 9 | private static CompilationUnitSyntax CompilationUnitWidget( 10 | string? namespaceIdentifier = null, 11 | MemberDeclarationSyntax? member = null, 12 | IEnumerable? members = null, 13 | bool addGeneratedCodeLeadingTrivia = true, 14 | bool normalizeWhitespace = true) 15 | { 16 | var compilationUnit = CompilationUnit(); 17 | 18 | if (string.IsNullOrWhiteSpace(namespaceIdentifier) == false) 19 | { 20 | compilationUnit = compilationUnit 21 | .AddMembers(NamespaceWidget(identifier: namespaceIdentifier!, member: member, members: members)); 22 | } 23 | else 24 | { 25 | if (member is not null) 26 | { 27 | compilationUnit = compilationUnit.WithMembers(compilationUnit.Members.Add(member)); 28 | } 29 | 30 | if (members is not null) 31 | { 32 | compilationUnit = compilationUnit.WithMembers(List(members)); 33 | } 34 | } 35 | 36 | if (addGeneratedCodeLeadingTrivia) 37 | { 38 | compilationUnit = AddGeneratedCodeLeadingTrivia(compilationUnit); 39 | } 40 | 41 | return normalizeWhitespace 42 | ? compilationUnit.NormalizeWhitespace() 43 | : compilationUnit; 44 | } 45 | 46 | private static NamespaceDeclarationSyntax NamespaceWidget( 47 | string identifier, 48 | MemberDeclarationSyntax? member = null, 49 | IEnumerable? members = null) 50 | { 51 | var namespaceDeclaration = NamespaceDeclaration(IdentifierName(identifier)); 52 | 53 | if (member is not null) 54 | { 55 | namespaceDeclaration = namespaceDeclaration.WithMembers(namespaceDeclaration.Members.Add(member)); 56 | } 57 | 58 | if (members is not null) 59 | { 60 | namespaceDeclaration = namespaceDeclaration.WithMembers(List(members)); 61 | } 62 | 63 | return namespaceDeclaration; 64 | } 65 | 66 | private static ClassDeclarationSyntax ClassWidget( 67 | string identifier, 68 | SyntaxKind? modifier = null, 69 | IEnumerable? modifiers = null, 70 | BaseTypeSyntax? baseType = null, 71 | IEnumerable? baseTypes = null, 72 | MemberDeclarationSyntax? member = null, 73 | IEnumerable? members = null, 74 | AttributeSyntax? attribute = null, 75 | IEnumerable? attributes = null, 76 | bool addGeneratedCodeAttributes = false) 77 | { 78 | var classDeclaration = ClassDeclaration(identifier); 79 | 80 | if (baseType is not null) 81 | { 82 | classDeclaration = classDeclaration.WithBaseList(BaseList(SingletonSeparatedList(baseType))); 83 | } 84 | 85 | if (baseTypes is not null) 86 | { 87 | classDeclaration = classDeclaration.WithBaseList(BaseList(SeparatedList(baseTypes))); 88 | } 89 | 90 | if (member is not null) 91 | { 92 | classDeclaration = classDeclaration.WithMembers(classDeclaration.Members.Add(member)); 93 | } 94 | 95 | if (members is not null) 96 | { 97 | classDeclaration = classDeclaration.WithMembers(List(members)); 98 | } 99 | 100 | return BaseWidgetDecoration( 101 | widget: classDeclaration, 102 | modifier: modifier, 103 | modifiers: modifiers, 104 | attribute: attribute, 105 | attributes: attributes, 106 | addGeneratedCodeAttributes: addGeneratedCodeAttributes); 107 | } 108 | 109 | private static ConstructorDeclarationSyntax ConstructorWidget( 110 | string identifier, 111 | SyntaxKind? modifier = null, 112 | IEnumerable? modifiers = null, 113 | ParameterSyntax? parameter = null, 114 | IEnumerable? parameters = null, 115 | StatementSyntax? bodyStatement = null, 116 | IEnumerable? bodyStatements = null, 117 | AttributeSyntax? attribute = null, 118 | IEnumerable? attributes = null, 119 | bool addGeneratedCodeAttributes = false) 120 | { 121 | var constructorDeclaration = ConstructorDeclaration(Identifier(identifier)); 122 | 123 | if (parameter is not null) 124 | { 125 | constructorDeclaration = constructorDeclaration.WithParameterList(constructorDeclaration.ParameterList 126 | .WithParameters(constructorDeclaration.ParameterList.Parameters.Add(parameter))); 127 | } 128 | 129 | if (parameters is not null) 130 | { 131 | constructorDeclaration = constructorDeclaration.WithParameterList(constructorDeclaration.ParameterList 132 | .WithParameters(constructorDeclaration.ParameterList.Parameters.AddRange(parameters))); 133 | } 134 | 135 | if (bodyStatement is not null) 136 | { 137 | constructorDeclaration = constructorDeclaration.WithBody(Block(SingletonList(bodyStatement))); 138 | } 139 | 140 | if (bodyStatements is not null) 141 | { 142 | constructorDeclaration = constructorDeclaration.WithBody(Block(bodyStatements)); 143 | } 144 | 145 | return BaseWidgetDecoration( 146 | widget: constructorDeclaration, 147 | modifier: modifier, 148 | modifiers: modifiers, 149 | attribute: attribute, 150 | attributes: attributes, 151 | addGeneratedCodeAttributes: addGeneratedCodeAttributes); 152 | } 153 | 154 | private static FieldDeclarationSyntax FieldWidget( 155 | string identifier, 156 | TypeSyntax type, 157 | SyntaxKind? modifier = null, 158 | IEnumerable? modifiers = null, 159 | ExpressionSyntax? initializer = null, 160 | IEnumerable? initializers = null, 161 | AttributeSyntax? attribute = null, 162 | IEnumerable? attributes = null, 163 | bool addGeneratedCodeAttributes = false) 164 | { 165 | var variableDeclaration = VariableDeclarator(Identifier(identifier)); 166 | 167 | // TODO: Change to BaseObjectCreationExpressionSyntax. 168 | if (initializer is not null) 169 | { 170 | variableDeclaration = variableDeclaration.WithInitializer(EqualsValueClause(ImplicitObjectCreationExpression() 171 | .WithInitializer(InitializerExpression(SyntaxKind.ObjectInitializerExpression, SingletonSeparatedList(initializer))))); 172 | } 173 | 174 | if (initializers is not null) 175 | { 176 | variableDeclaration = variableDeclaration.WithInitializer(EqualsValueClause(ImplicitObjectCreationExpression() 177 | .WithInitializer(InitializerExpression(SyntaxKind.ObjectInitializerExpression, SeparatedList(initializers))))); 178 | } 179 | 180 | var fieldDeclaration = FieldDeclaration(VariableDeclaration(type) 181 | .WithVariables(SingletonSeparatedList(variableDeclaration))); 182 | 183 | return BaseWidgetDecoration( 184 | widget: fieldDeclaration, 185 | modifier: modifier, 186 | modifiers: modifiers, 187 | attribute: attribute, 188 | attributes: attributes, 189 | addGeneratedCodeAttributes: addGeneratedCodeAttributes); 190 | } 191 | 192 | private static PropertyDeclarationSyntax PropertyWidget( 193 | string identifier, 194 | TypeSyntax type, 195 | SyntaxKind? modifier = null, 196 | IEnumerable? modifiers = null, 197 | SyntaxKind? accessor = null, 198 | IEnumerable? accessors = null, 199 | ExpressionSyntax? initializer = null, 200 | AttributeSyntax? attribute = null, 201 | IEnumerable? attributes = null, 202 | bool addGeneratedCodeAttributes = false) 203 | { 204 | var propertyDeclaration = PropertyDeclaration(type, Identifier(identifier)); 205 | 206 | if (accessor is not null) 207 | { 208 | var accessorList = propertyDeclaration.AccessorList ?? AccessorList(); 209 | 210 | propertyDeclaration = propertyDeclaration.WithAccessorList(accessorList 211 | .WithAccessors(accessorList.Accessors.Add(AccessorWidget(accessor.Value)))); 212 | } 213 | 214 | if (accessors is not null) 215 | { 216 | var accessorList = propertyDeclaration.AccessorList ?? AccessorList(); 217 | 218 | propertyDeclaration = propertyDeclaration.WithAccessorList(accessorList 219 | .WithAccessors(accessorList.Accessors.AddRange(accessors.Select(AccessorWidget)))); 220 | } 221 | 222 | if (initializer is not null) 223 | { 224 | propertyDeclaration = propertyDeclaration 225 | .WithInitializer(EqualsValueClause(initializer)) 226 | .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); 227 | } 228 | 229 | return BaseWidgetDecoration( 230 | widget: propertyDeclaration, 231 | modifier: modifier, 232 | modifiers: modifiers, 233 | attribute: attribute, 234 | attributes: attributes, 235 | addGeneratedCodeAttributes: addGeneratedCodeAttributes); 236 | } 237 | 238 | private static MethodDeclarationSyntax MethodWidget( 239 | string identifier, 240 | TypeSyntax type, 241 | SyntaxKind? modifier = null, 242 | IEnumerable? modifiers = null, 243 | ParameterSyntax? parameter = null, 244 | IEnumerable? parameters = null, 245 | StatementSyntax? bodyStatement = null, 246 | IEnumerable? bodyStatements = null, 247 | AttributeSyntax? attribute = null, 248 | IEnumerable? attributes = null, 249 | bool addGeneratedCodeAttributes = false) 250 | { 251 | var methodDeclaration = MethodDeclaration(type, Identifier(identifier)); 252 | 253 | if (parameter is not null) 254 | { 255 | methodDeclaration = methodDeclaration.WithParameterList(methodDeclaration.ParameterList 256 | .WithParameters(methodDeclaration.ParameterList.Parameters.Add(parameter))); 257 | } 258 | 259 | if (parameters is not null) 260 | { 261 | methodDeclaration = methodDeclaration.WithParameterList(methodDeclaration.ParameterList 262 | .WithParameters(methodDeclaration.ParameterList.Parameters.AddRange(parameters))); 263 | } 264 | 265 | if (bodyStatement is not null) 266 | { 267 | methodDeclaration = methodDeclaration.WithBody(Block(SingletonList(bodyStatement))); 268 | } 269 | 270 | if (bodyStatements is not null) 271 | { 272 | methodDeclaration = methodDeclaration.WithBody(Block(bodyStatements)); 273 | } 274 | 275 | if (bodyStatement is null && bodyStatements is null) 276 | { 277 | methodDeclaration = methodDeclaration.WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); 278 | } 279 | 280 | return BaseWidgetDecoration( 281 | widget: methodDeclaration, 282 | modifier: modifier, 283 | modifiers: modifiers, 284 | attribute: attribute, 285 | attributes: attributes, 286 | addGeneratedCodeAttributes: addGeneratedCodeAttributes); 287 | } 288 | 289 | private static ParameterSyntax ParameterWidget( 290 | string identifier, 291 | TypeSyntax type, 292 | SyntaxKind defaultValueKeyword = SyntaxKind.None) 293 | { 294 | var parameterSyntax = Parameter(Identifier(identifier)) 295 | .WithType(type); 296 | 297 | return defaultValueKeyword switch 298 | { 299 | SyntaxKind.NullKeyword => parameterSyntax.WithDefault(EqualsValueClause( 300 | LiteralExpression(SyntaxKind.NullLiteralExpression, Token(SyntaxKind.NullKeyword)))), 301 | SyntaxKind.TrueKeyword => parameterSyntax.WithDefault(EqualsValueClause( 302 | LiteralExpression(SyntaxKind.TrueLiteralExpression, Token(SyntaxKind.TrueKeyword)))), 303 | SyntaxKind.FalseKeyword => parameterSyntax.WithDefault(EqualsValueClause( 304 | LiteralExpression(SyntaxKind.FalseLiteralExpression, Token(SyntaxKind.FalseKeyword)))), 305 | SyntaxKind.DefaultKeyword => parameterSyntax.WithDefault(EqualsValueClause( 306 | LiteralExpression(SyntaxKind.DefaultLiteralExpression, Token(SyntaxKind.DefaultKeyword)))), 307 | _ => parameterSyntax 308 | }; 309 | } 310 | 311 | private static StatementSyntax MethodCallWidget( 312 | ExpressionSyntax expression, 313 | string identifier, 314 | ArgumentSyntax? argument = null, 315 | IEnumerable? arguments = null) 316 | { 317 | var invocationExpression = InvocationExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, 318 | expression, IdentifierName(identifier))); 319 | 320 | if (argument is not null) 321 | { 322 | invocationExpression = invocationExpression.WithArgumentList(invocationExpression.ArgumentList 323 | .WithArguments(invocationExpression.ArgumentList.Arguments.Add(argument))); 324 | } 325 | 326 | if (arguments is not null) 327 | { 328 | invocationExpression = invocationExpression.WithArgumentList(invocationExpression.ArgumentList 329 | .WithArguments(invocationExpression.ArgumentList.Arguments.AddRange(arguments))); 330 | } 331 | 332 | return ExpressionStatement(invocationExpression); 333 | } 334 | 335 | private static StatementSyntax LocalVariableWidget( 336 | string identifier, 337 | EqualsValueClauseSyntax? initializer) 338 | { 339 | return 340 | LocalDeclarationStatement( 341 | VariableDeclaration(IdentifierName(Identifier(TriviaList(), SyntaxKind.VarKeyword, "var", "var", TriviaList()))) 342 | .WithVariables(SingletonSeparatedList(VariableDeclarator(Identifier(identifier)) 343 | .WithInitializer(initializer)))); 344 | } 345 | 346 | private static EqualsValueClauseSyntax CastExpressionWidget( 347 | string identifier, 348 | TypeSyntax typeToCast) 349 | { 350 | return EqualsValueClause(CastExpression(typeToCast, IdentifierName(identifier))); 351 | } 352 | 353 | private static StatementSyntax AssignmentStatementWidget( 354 | ExpressionSyntax left, 355 | ExpressionSyntax right, 356 | SyntaxKind expression = SyntaxKind.SimpleAssignmentExpression) 357 | { 358 | return ExpressionStatement(AssignmentWidget(left, right, expression)); 359 | } 360 | 361 | private static ExpressionSyntax AssignmentWidget( 362 | ExpressionSyntax left, 363 | ExpressionSyntax right, 364 | SyntaxKind expression = SyntaxKind.SimpleAssignmentExpression) 365 | { 366 | return AssignmentExpression(expression, left, right); 367 | } 368 | 369 | private static ExpressionSyntax MemberAccessWidget( 370 | string identifier, 371 | string memberName) 372 | { 373 | return MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(identifier), 374 | IdentifierName(memberName)); 375 | } 376 | 377 | private static ExpressionSyntax MethodInvocationWidget( 378 | string memberIdentifier, 379 | string methodName, 380 | ArgumentSyntax? argument = null, 381 | IEnumerable? arguments = null) 382 | { 383 | var invocationSyntax = 384 | InvocationExpression(MemberAccessWidget(identifier: memberIdentifier, memberName: methodName)); 385 | 386 | if (argument is not null) 387 | { 388 | invocationSyntax = invocationSyntax.WithArgumentList(invocationSyntax.ArgumentList 389 | .WithArguments(invocationSyntax.ArgumentList.Arguments.Add(argument))); 390 | } 391 | 392 | if (arguments is not null) 393 | { 394 | invocationSyntax = invocationSyntax.WithArgumentList(invocationSyntax.ArgumentList 395 | .WithArguments(invocationSyntax.ArgumentList.Arguments.AddRange(arguments))); 396 | } 397 | 398 | return invocationSyntax; 399 | } 400 | 401 | private static AccessorDeclarationSyntax AccessorWidget(SyntaxKind kind) 402 | { 403 | return AccessorDeclaration(kind).WithSemicolonToken(Token(SyntaxKind.SemicolonToken)); 404 | } 405 | 406 | private static AttributeSyntax AttributeWidget( 407 | string identifier, 408 | AttributeArgumentSyntax? argument = null, 409 | IEnumerable? arguments = null 410 | ) 411 | { 412 | var attributeSyntax = Attribute(IdentifierName(identifier)); 413 | 414 | if (argument is not null) 415 | { 416 | var argumentList = attributeSyntax.ArgumentList ?? AttributeArgumentList(); 417 | 418 | attributeSyntax = attributeSyntax.WithArgumentList(argumentList 419 | .WithArguments(argumentList.Arguments.Add(argument))); 420 | } 421 | 422 | if (arguments is not null) 423 | { 424 | var argumentList = attributeSyntax.ArgumentList ?? AttributeArgumentList(); 425 | 426 | attributeSyntax = attributeSyntax.WithArgumentList(argumentList 427 | .WithArguments(argumentList.Arguments.AddRange(arguments))); 428 | } 429 | 430 | return attributeSyntax; 431 | } 432 | 433 | private static TWidget BaseWidgetDecoration( 434 | TWidget widget, 435 | SyntaxKind? modifier = null, 436 | IEnumerable? modifiers = null, 437 | AttributeSyntax? attribute = null, 438 | IEnumerable? attributes = null, 439 | bool addGeneratedCodeAttributes = true) where TWidget : MemberDeclarationSyntax 440 | { 441 | if (modifier is not null) 442 | { 443 | widget = (TWidget) widget.WithModifiers(widget.Modifiers.Add(Token(modifier.Value))); 444 | } 445 | 446 | if (modifiers is not null) 447 | { 448 | widget = (TWidget) widget.WithModifiers(TokenList(modifiers.Select(Token))); 449 | } 450 | 451 | if (addGeneratedCodeAttributes) 452 | { 453 | var attributesList = GetGeneratedCodeAttributes(widget); 454 | 455 | if (attribute is not null) 456 | { 457 | attributesList.Add(attribute); 458 | } 459 | 460 | if (attributes is not null) 461 | { 462 | attributesList.AddRange(attributes); 463 | } 464 | 465 | return (TWidget) widget.WithAttributeLists(widget.AttributeLists.AddRange( 466 | attributesList.Select(attributeSyntax => AttributeList(SingletonSeparatedList(attributeSyntax))))); 467 | } 468 | 469 | if (attribute is not null) 470 | { 471 | widget = (TWidget) widget.WithAttributeLists(widget.AttributeLists.Add( 472 | AttributeList(SingletonSeparatedList(attribute)))); 473 | } 474 | 475 | if (attributes is not null) 476 | { 477 | widget = (TWidget) widget.WithAttributeLists(widget.AttributeLists.AddRange( 478 | attributes.Select(attributeSyntax => AttributeList(SingletonSeparatedList(attributeSyntax))))); 479 | } 480 | 481 | return widget; 482 | } 483 | 484 | private static TSyntax AddGeneratedCodeLeadingTrivia(TSyntax node) where TSyntax : SyntaxNode 485 | { 486 | // Prepare the leading trivia for the generated compilation unit. 487 | // This will produce code as follows: 488 | // 489 | // 490 | // #pragma warning disable 491 | // #nullable enable 492 | var syntaxTriviaList = TriviaList( 493 | Comment("// "), 494 | Trivia(PragmaWarningDirectiveTrivia(Token(SyntaxKind.DisableKeyword), true)), 495 | Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true))); 496 | 497 | return node.WithLeadingTrivia(syntaxTriviaList); 498 | } 499 | 500 | private static List GetGeneratedCodeAttributes(TMember member) where TMember : MemberDeclarationSyntax 501 | { 502 | var attributes = new List 503 | { 504 | AttributeWidget( 505 | identifier: "global::System.CodeDom.Compiler.GeneratedCode", 506 | arguments: new[] 507 | { 508 | AttributeArgument( 509 | LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(AssemblyName.Name))), 510 | AttributeArgument( 511 | LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(AssemblyName.Version.ToString()))) 512 | }) 513 | }; 514 | 515 | // [ExcludeFromCodeCoverage] is not supported on interfaces and fields. 516 | if (member.Kind() is not SyntaxKind.InterfaceDeclaration and not SyntaxKind.FieldDeclaration) 517 | { 518 | attributes.Add(AttributeWidget( 519 | identifier: "global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage")); 520 | } 521 | 522 | return attributes; 523 | } 524 | } -------------------------------------------------------------------------------- /src/UnityUxmlGenerator.UnityPackage/ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 24 7 | productGUID: d95e5302d19f19e4aac90a6d0c4c3999 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | AndroidEnableSustainedPerformanceMode: 0 11 | defaultScreenOrientation: 4 12 | targetDevice: 2 13 | useOnDemandResources: 0 14 | accelerometerFrequency: 60 15 | companyName: DefaultCompany 16 | productName: UnityUxmlGenerator.UnityPackage 17 | defaultCursor: {fileID: 0} 18 | cursorHotspot: {x: 0, y: 0} 19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 20 | m_ShowUnitySplashScreen: 1 21 | m_ShowUnitySplashLogo: 1 22 | m_SplashScreenOverlayOpacity: 1 23 | m_SplashScreenAnimation: 1 24 | m_SplashScreenLogoStyle: 1 25 | m_SplashScreenDrawMode: 0 26 | m_SplashScreenBackgroundAnimationZoom: 1 27 | m_SplashScreenLogoAnimationZoom: 1 28 | m_SplashScreenBackgroundLandscapeAspect: 1 29 | m_SplashScreenBackgroundPortraitAspect: 1 30 | m_SplashScreenBackgroundLandscapeUvs: 31 | serializedVersion: 2 32 | x: 0 33 | y: 0 34 | width: 1 35 | height: 1 36 | m_SplashScreenBackgroundPortraitUvs: 37 | serializedVersion: 2 38 | x: 0 39 | y: 0 40 | width: 1 41 | height: 1 42 | m_SplashScreenLogos: [] 43 | m_VirtualRealitySplashScreen: {fileID: 0} 44 | m_HolographicTrackingLossScreen: {fileID: 0} 45 | defaultScreenWidth: 1920 46 | defaultScreenHeight: 1080 47 | defaultScreenWidthWeb: 960 48 | defaultScreenHeightWeb: 600 49 | m_StereoRenderingPath: 0 50 | m_ActiveColorSpace: 0 51 | m_MTRendering: 1 52 | mipStripping: 0 53 | numberOfMipsStripped: 0 54 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 55 | iosShowActivityIndicatorOnLoading: -1 56 | androidShowActivityIndicatorOnLoading: -1 57 | iosUseCustomAppBackgroundBehavior: 0 58 | iosAllowHTTPDownload: 1 59 | allowedAutorotateToPortrait: 1 60 | allowedAutorotateToPortraitUpsideDown: 1 61 | allowedAutorotateToLandscapeRight: 1 62 | allowedAutorotateToLandscapeLeft: 1 63 | useOSAutorotation: 1 64 | use32BitDisplayBuffer: 1 65 | preserveFramebufferAlpha: 0 66 | disableDepthAndStencilBuffers: 0 67 | androidStartInFullscreen: 1 68 | androidRenderOutsideSafeArea: 1 69 | androidUseSwappy: 1 70 | androidBlitType: 0 71 | androidResizableWindow: 0 72 | androidDefaultWindowWidth: 1920 73 | androidDefaultWindowHeight: 1080 74 | androidMinimumWindowWidth: 400 75 | androidMinimumWindowHeight: 300 76 | androidFullscreenMode: 1 77 | defaultIsNativeResolution: 1 78 | macRetinaSupport: 1 79 | runInBackground: 0 80 | captureSingleScreen: 0 81 | muteOtherAudioSources: 0 82 | Prepare IOS For Recording: 0 83 | Force IOS Speakers When Recording: 0 84 | deferSystemGesturesMode: 0 85 | hideHomeButton: 0 86 | submitAnalytics: 1 87 | usePlayerLog: 1 88 | bakeCollisionMeshes: 0 89 | forceSingleInstance: 0 90 | useFlipModelSwapchain: 1 91 | resizableWindow: 0 92 | useMacAppStoreValidation: 0 93 | macAppStoreCategory: public.app-category.games 94 | gpuSkinning: 0 95 | xboxPIXTextureCapture: 0 96 | xboxEnableAvatar: 0 97 | xboxEnableKinect: 0 98 | xboxEnableKinectAutoTracking: 0 99 | xboxEnableFitness: 0 100 | visibleInBackground: 1 101 | allowFullscreenSwitch: 1 102 | fullscreenMode: 1 103 | xboxSpeechDB: 0 104 | xboxEnableHeadOrientation: 0 105 | xboxEnableGuest: 0 106 | xboxEnablePIXSampling: 0 107 | metalFramebufferOnly: 0 108 | xboxOneResolution: 0 109 | xboxOneSResolution: 0 110 | xboxOneXResolution: 3 111 | xboxOneMonoLoggingLevel: 0 112 | xboxOneLoggingLevel: 1 113 | xboxOneDisableEsram: 0 114 | xboxOneEnableTypeOptimization: 0 115 | xboxOnePresentImmediateThreshold: 0 116 | switchQueueCommandMemory: 1048576 117 | switchQueueControlMemory: 16384 118 | switchQueueComputeMemory: 262144 119 | switchNVNShaderPoolsGranularity: 33554432 120 | switchNVNDefaultPoolsGranularity: 16777216 121 | switchNVNOtherPoolsGranularity: 16777216 122 | switchNVNMaxPublicTextureIDCount: 0 123 | switchNVNMaxPublicSamplerIDCount: 0 124 | stadiaPresentMode: 0 125 | stadiaTargetFramerate: 0 126 | vulkanNumSwapchainBuffers: 3 127 | vulkanEnableSetSRGBWrite: 0 128 | vulkanEnablePreTransform: 0 129 | vulkanEnableLateAcquireNextImage: 0 130 | vulkanEnableCommandBufferRecycling: 1 131 | m_SupportedAspectRatios: 132 | 4:3: 1 133 | 5:4: 1 134 | 16:10: 1 135 | 16:9: 1 136 | Others: 1 137 | bundleVersion: 1.0 138 | preloadedAssets: [] 139 | metroInputSource: 0 140 | wsaTransparentSwapchain: 0 141 | m_HolographicPauseOnTrackingLoss: 1 142 | xboxOneDisableKinectGpuReservation: 1 143 | xboxOneEnable7thCore: 1 144 | vrSettings: 145 | enable360StereoCapture: 0 146 | isWsaHolographicRemotingEnabled: 0 147 | enableFrameTimingStats: 0 148 | enableOpenGLProfilerGPURecorders: 1 149 | useHDRDisplay: 0 150 | D3DHDRBitDepth: 0 151 | m_ColorGamuts: 00000000 152 | targetPixelDensity: 30 153 | resolutionScalingMode: 0 154 | resetResolutionOnWindowResize: 0 155 | androidSupportedAspectRatio: 1 156 | androidMaxAspectRatio: 2.1 157 | applicationIdentifier: 158 | Standalone: com.DefaultCompany.2DProject 159 | buildNumber: 160 | Standalone: 0 161 | iPhone: 0 162 | tvOS: 0 163 | overrideDefaultApplicationIdentifier: 1 164 | AndroidBundleVersionCode: 1 165 | AndroidMinSdkVersion: 22 166 | AndroidTargetSdkVersion: 0 167 | AndroidPreferredInstallLocation: 1 168 | aotOptions: 169 | stripEngineCode: 1 170 | iPhoneStrippingLevel: 0 171 | iPhoneScriptCallOptimization: 0 172 | ForceInternetPermission: 0 173 | ForceSDCardPermission: 0 174 | CreateWallpaper: 0 175 | APKExpansionFiles: 0 176 | keepLoadedShadersAlive: 0 177 | StripUnusedMeshComponents: 0 178 | VertexChannelCompressionMask: 4054 179 | iPhoneSdkVersion: 988 180 | iOSTargetOSVersionString: 12.0 181 | tvOSSdkVersion: 0 182 | tvOSRequireExtendedGameController: 0 183 | tvOSTargetOSVersionString: 12.0 184 | uIPrerenderedIcon: 0 185 | uIRequiresPersistentWiFi: 0 186 | uIRequiresFullScreen: 1 187 | uIStatusBarHidden: 1 188 | uIExitOnSuspend: 0 189 | uIStatusBarStyle: 0 190 | appleTVSplashScreen: {fileID: 0} 191 | appleTVSplashScreen2x: {fileID: 0} 192 | tvOSSmallIconLayers: [] 193 | tvOSSmallIconLayers2x: [] 194 | tvOSLargeIconLayers: [] 195 | tvOSLargeIconLayers2x: [] 196 | tvOSTopShelfImageLayers: [] 197 | tvOSTopShelfImageLayers2x: [] 198 | tvOSTopShelfImageWideLayers: [] 199 | tvOSTopShelfImageWideLayers2x: [] 200 | iOSLaunchScreenType: 0 201 | iOSLaunchScreenPortrait: {fileID: 0} 202 | iOSLaunchScreenLandscape: {fileID: 0} 203 | iOSLaunchScreenBackgroundColor: 204 | serializedVersion: 2 205 | rgba: 0 206 | iOSLaunchScreenFillPct: 100 207 | iOSLaunchScreenSize: 100 208 | iOSLaunchScreenCustomXibPath: 209 | iOSLaunchScreeniPadType: 0 210 | iOSLaunchScreeniPadImage: {fileID: 0} 211 | iOSLaunchScreeniPadBackgroundColor: 212 | serializedVersion: 2 213 | rgba: 0 214 | iOSLaunchScreeniPadFillPct: 100 215 | iOSLaunchScreeniPadSize: 100 216 | iOSLaunchScreeniPadCustomXibPath: 217 | iOSLaunchScreenCustomStoryboardPath: 218 | iOSLaunchScreeniPadCustomStoryboardPath: 219 | iOSDeviceRequirements: [] 220 | iOSURLSchemes: [] 221 | macOSURLSchemes: [] 222 | iOSBackgroundModes: 0 223 | iOSMetalForceHardShadows: 0 224 | metalEditorSupport: 1 225 | metalAPIValidation: 1 226 | iOSRenderExtraFrameOnPause: 0 227 | iosCopyPluginsCodeInsteadOfSymlink: 0 228 | appleDeveloperTeamID: 229 | iOSManualSigningProvisioningProfileID: 230 | tvOSManualSigningProvisioningProfileID: 231 | iOSManualSigningProvisioningProfileType: 0 232 | tvOSManualSigningProvisioningProfileType: 0 233 | appleEnableAutomaticSigning: 0 234 | iOSRequireARKit: 0 235 | iOSAutomaticallyDetectAndAddCapabilities: 1 236 | appleEnableProMotion: 0 237 | shaderPrecisionModel: 0 238 | clonedFromGUID: 10ad67313f4034357812315f3c407484 239 | templatePackageId: com.unity.template.2d@6.1.2 240 | templateDefaultScene: Assets/Scenes/SampleScene.unity 241 | useCustomMainManifest: 0 242 | useCustomLauncherManifest: 0 243 | useCustomMainGradleTemplate: 0 244 | useCustomLauncherGradleManifest: 0 245 | useCustomBaseGradleTemplate: 0 246 | useCustomGradlePropertiesTemplate: 0 247 | useCustomProguardFile: 0 248 | AndroidTargetArchitectures: 1 249 | AndroidTargetDevices: 0 250 | AndroidSplashScreenScale: 0 251 | androidSplashScreen: {fileID: 0} 252 | AndroidKeystoreName: 253 | AndroidKeyaliasName: 254 | AndroidBuildApkPerCpuArchitecture: 0 255 | AndroidTVCompatibility: 0 256 | AndroidIsGame: 1 257 | AndroidEnableTango: 0 258 | androidEnableBanner: 1 259 | androidUseLowAccuracyLocation: 0 260 | androidUseCustomKeystore: 0 261 | m_AndroidBanners: 262 | - width: 320 263 | height: 180 264 | banner: {fileID: 0} 265 | androidGamepadSupportLevel: 0 266 | chromeosInputEmulation: 1 267 | AndroidMinifyWithR8: 0 268 | AndroidMinifyRelease: 0 269 | AndroidMinifyDebug: 0 270 | AndroidValidateAppBundleSize: 1 271 | AndroidAppBundleSizeToValidate: 150 272 | m_BuildTargetIcons: [] 273 | m_BuildTargetPlatformIcons: 274 | - m_BuildTarget: Android 275 | m_Icons: 276 | - m_Textures: [] 277 | m_Width: 432 278 | m_Height: 432 279 | m_Kind: 2 280 | m_SubKind: 281 | - m_Textures: [] 282 | m_Width: 324 283 | m_Height: 324 284 | m_Kind: 2 285 | m_SubKind: 286 | - m_Textures: [] 287 | m_Width: 216 288 | m_Height: 216 289 | m_Kind: 2 290 | m_SubKind: 291 | - m_Textures: [] 292 | m_Width: 162 293 | m_Height: 162 294 | m_Kind: 2 295 | m_SubKind: 296 | - m_Textures: [] 297 | m_Width: 108 298 | m_Height: 108 299 | m_Kind: 2 300 | m_SubKind: 301 | - m_Textures: [] 302 | m_Width: 81 303 | m_Height: 81 304 | m_Kind: 2 305 | m_SubKind: 306 | - m_Textures: [] 307 | m_Width: 192 308 | m_Height: 192 309 | m_Kind: 1 310 | m_SubKind: 311 | - m_Textures: [] 312 | m_Width: 144 313 | m_Height: 144 314 | m_Kind: 1 315 | m_SubKind: 316 | - m_Textures: [] 317 | m_Width: 96 318 | m_Height: 96 319 | m_Kind: 1 320 | m_SubKind: 321 | - m_Textures: [] 322 | m_Width: 72 323 | m_Height: 72 324 | m_Kind: 1 325 | m_SubKind: 326 | - m_Textures: [] 327 | m_Width: 48 328 | m_Height: 48 329 | m_Kind: 1 330 | m_SubKind: 331 | - m_Textures: [] 332 | m_Width: 36 333 | m_Height: 36 334 | m_Kind: 1 335 | m_SubKind: 336 | - m_Textures: [] 337 | m_Width: 192 338 | m_Height: 192 339 | m_Kind: 0 340 | m_SubKind: 341 | - m_Textures: [] 342 | m_Width: 144 343 | m_Height: 144 344 | m_Kind: 0 345 | m_SubKind: 346 | - m_Textures: [] 347 | m_Width: 96 348 | m_Height: 96 349 | m_Kind: 0 350 | m_SubKind: 351 | - m_Textures: [] 352 | m_Width: 72 353 | m_Height: 72 354 | m_Kind: 0 355 | m_SubKind: 356 | - m_Textures: [] 357 | m_Width: 48 358 | m_Height: 48 359 | m_Kind: 0 360 | m_SubKind: 361 | - m_Textures: [] 362 | m_Width: 36 363 | m_Height: 36 364 | m_Kind: 0 365 | m_SubKind: 366 | - m_BuildTarget: iPhone 367 | m_Icons: 368 | - m_Textures: [] 369 | m_Width: 180 370 | m_Height: 180 371 | m_Kind: 0 372 | m_SubKind: iPhone 373 | - m_Textures: [] 374 | m_Width: 120 375 | m_Height: 120 376 | m_Kind: 0 377 | m_SubKind: iPhone 378 | - m_Textures: [] 379 | m_Width: 167 380 | m_Height: 167 381 | m_Kind: 0 382 | m_SubKind: iPad 383 | - m_Textures: [] 384 | m_Width: 152 385 | m_Height: 152 386 | m_Kind: 0 387 | m_SubKind: iPad 388 | - m_Textures: [] 389 | m_Width: 76 390 | m_Height: 76 391 | m_Kind: 0 392 | m_SubKind: iPad 393 | - m_Textures: [] 394 | m_Width: 120 395 | m_Height: 120 396 | m_Kind: 3 397 | m_SubKind: iPhone 398 | - m_Textures: [] 399 | m_Width: 80 400 | m_Height: 80 401 | m_Kind: 3 402 | m_SubKind: iPhone 403 | - m_Textures: [] 404 | m_Width: 80 405 | m_Height: 80 406 | m_Kind: 3 407 | m_SubKind: iPad 408 | - m_Textures: [] 409 | m_Width: 40 410 | m_Height: 40 411 | m_Kind: 3 412 | m_SubKind: iPad 413 | - m_Textures: [] 414 | m_Width: 87 415 | m_Height: 87 416 | m_Kind: 1 417 | m_SubKind: iPhone 418 | - m_Textures: [] 419 | m_Width: 58 420 | m_Height: 58 421 | m_Kind: 1 422 | m_SubKind: iPhone 423 | - m_Textures: [] 424 | m_Width: 29 425 | m_Height: 29 426 | m_Kind: 1 427 | m_SubKind: iPhone 428 | - m_Textures: [] 429 | m_Width: 58 430 | m_Height: 58 431 | m_Kind: 1 432 | m_SubKind: iPad 433 | - m_Textures: [] 434 | m_Width: 29 435 | m_Height: 29 436 | m_Kind: 1 437 | m_SubKind: iPad 438 | - m_Textures: [] 439 | m_Width: 60 440 | m_Height: 60 441 | m_Kind: 2 442 | m_SubKind: iPhone 443 | - m_Textures: [] 444 | m_Width: 40 445 | m_Height: 40 446 | m_Kind: 2 447 | m_SubKind: iPhone 448 | - m_Textures: [] 449 | m_Width: 40 450 | m_Height: 40 451 | m_Kind: 2 452 | m_SubKind: iPad 453 | - m_Textures: [] 454 | m_Width: 20 455 | m_Height: 20 456 | m_Kind: 2 457 | m_SubKind: iPad 458 | - m_Textures: [] 459 | m_Width: 1024 460 | m_Height: 1024 461 | m_Kind: 4 462 | m_SubKind: App Store 463 | m_BuildTargetBatching: [] 464 | m_BuildTargetShaderSettings: [] 465 | m_BuildTargetGraphicsJobs: 466 | - m_BuildTarget: MacStandaloneSupport 467 | m_GraphicsJobs: 0 468 | - m_BuildTarget: Switch 469 | m_GraphicsJobs: 0 470 | - m_BuildTarget: MetroSupport 471 | m_GraphicsJobs: 0 472 | - m_BuildTarget: AppleTVSupport 473 | m_GraphicsJobs: 0 474 | - m_BuildTarget: BJMSupport 475 | m_GraphicsJobs: 0 476 | - m_BuildTarget: LinuxStandaloneSupport 477 | m_GraphicsJobs: 0 478 | - m_BuildTarget: PS4Player 479 | m_GraphicsJobs: 0 480 | - m_BuildTarget: iOSSupport 481 | m_GraphicsJobs: 0 482 | - m_BuildTarget: WindowsStandaloneSupport 483 | m_GraphicsJobs: 0 484 | - m_BuildTarget: XboxOnePlayer 485 | m_GraphicsJobs: 0 486 | - m_BuildTarget: LuminSupport 487 | m_GraphicsJobs: 0 488 | - m_BuildTarget: AndroidPlayer 489 | m_GraphicsJobs: 0 490 | - m_BuildTarget: WebGLSupport 491 | m_GraphicsJobs: 0 492 | m_BuildTargetGraphicsJobMode: [] 493 | m_BuildTargetGraphicsAPIs: 494 | - m_BuildTarget: AndroidPlayer 495 | m_APIs: 150000000b000000 496 | m_Automatic: 1 497 | - m_BuildTarget: iOSSupport 498 | m_APIs: 10000000 499 | m_Automatic: 1 500 | m_BuildTargetVRSettings: [] 501 | m_DefaultShaderChunkSizeInMB: 16 502 | m_DefaultShaderChunkCount: 0 503 | openGLRequireES31: 0 504 | openGLRequireES31AEP: 0 505 | openGLRequireES32: 0 506 | m_TemplateCustomTags: {} 507 | mobileMTRendering: 508 | Android: 1 509 | iPhone: 1 510 | tvOS: 1 511 | m_BuildTargetGroupLightmapEncodingQuality: [] 512 | m_BuildTargetGroupLightmapSettings: [] 513 | m_BuildTargetNormalMapEncoding: [] 514 | m_BuildTargetDefaultTextureCompressionFormat: 515 | - m_BuildTarget: Android 516 | m_Format: 3 517 | playModeTestRunnerEnabled: 0 518 | runPlayModeTestAsEditModeTest: 0 519 | actionOnDotNetUnhandledException: 1 520 | enableInternalProfiler: 0 521 | logObjCUncaughtExceptions: 1 522 | enableCrashReportAPI: 0 523 | cameraUsageDescription: 524 | locationUsageDescription: 525 | microphoneUsageDescription: 526 | bluetoothUsageDescription: 527 | switchNMETAOverride: 528 | switchNetLibKey: 529 | switchSocketMemoryPoolSize: 6144 530 | switchSocketAllocatorPoolSize: 128 531 | switchSocketConcurrencyLimit: 14 532 | switchScreenResolutionBehavior: 2 533 | switchUseCPUProfiler: 0 534 | switchUseGOLDLinker: 0 535 | switchLTOSetting: 0 536 | switchApplicationID: 0x01004b9000490000 537 | switchNSODependencies: 538 | switchTitleNames_0: 539 | switchTitleNames_1: 540 | switchTitleNames_2: 541 | switchTitleNames_3: 542 | switchTitleNames_4: 543 | switchTitleNames_5: 544 | switchTitleNames_6: 545 | switchTitleNames_7: 546 | switchTitleNames_8: 547 | switchTitleNames_9: 548 | switchTitleNames_10: 549 | switchTitleNames_11: 550 | switchTitleNames_12: 551 | switchTitleNames_13: 552 | switchTitleNames_14: 553 | switchTitleNames_15: 554 | switchPublisherNames_0: 555 | switchPublisherNames_1: 556 | switchPublisherNames_2: 557 | switchPublisherNames_3: 558 | switchPublisherNames_4: 559 | switchPublisherNames_5: 560 | switchPublisherNames_6: 561 | switchPublisherNames_7: 562 | switchPublisherNames_8: 563 | switchPublisherNames_9: 564 | switchPublisherNames_10: 565 | switchPublisherNames_11: 566 | switchPublisherNames_12: 567 | switchPublisherNames_13: 568 | switchPublisherNames_14: 569 | switchPublisherNames_15: 570 | switchIcons_0: {fileID: 0} 571 | switchIcons_1: {fileID: 0} 572 | switchIcons_2: {fileID: 0} 573 | switchIcons_3: {fileID: 0} 574 | switchIcons_4: {fileID: 0} 575 | switchIcons_5: {fileID: 0} 576 | switchIcons_6: {fileID: 0} 577 | switchIcons_7: {fileID: 0} 578 | switchIcons_8: {fileID: 0} 579 | switchIcons_9: {fileID: 0} 580 | switchIcons_10: {fileID: 0} 581 | switchIcons_11: {fileID: 0} 582 | switchIcons_12: {fileID: 0} 583 | switchIcons_13: {fileID: 0} 584 | switchIcons_14: {fileID: 0} 585 | switchIcons_15: {fileID: 0} 586 | switchSmallIcons_0: {fileID: 0} 587 | switchSmallIcons_1: {fileID: 0} 588 | switchSmallIcons_2: {fileID: 0} 589 | switchSmallIcons_3: {fileID: 0} 590 | switchSmallIcons_4: {fileID: 0} 591 | switchSmallIcons_5: {fileID: 0} 592 | switchSmallIcons_6: {fileID: 0} 593 | switchSmallIcons_7: {fileID: 0} 594 | switchSmallIcons_8: {fileID: 0} 595 | switchSmallIcons_9: {fileID: 0} 596 | switchSmallIcons_10: {fileID: 0} 597 | switchSmallIcons_11: {fileID: 0} 598 | switchSmallIcons_12: {fileID: 0} 599 | switchSmallIcons_13: {fileID: 0} 600 | switchSmallIcons_14: {fileID: 0} 601 | switchSmallIcons_15: {fileID: 0} 602 | switchManualHTML: 603 | switchAccessibleURLs: 604 | switchLegalInformation: 605 | switchMainThreadStackSize: 1048576 606 | switchPresenceGroupId: 607 | switchLogoHandling: 0 608 | switchReleaseVersion: 0 609 | switchDisplayVersion: 1.0.0 610 | switchStartupUserAccount: 0 611 | switchSupportedLanguagesMask: 0 612 | switchLogoType: 0 613 | switchApplicationErrorCodeCategory: 614 | switchUserAccountSaveDataSize: 0 615 | switchUserAccountSaveDataJournalSize: 0 616 | switchApplicationAttribute: 0 617 | switchCardSpecSize: -1 618 | switchCardSpecClock: -1 619 | switchRatingsMask: 0 620 | switchRatingsInt_0: 0 621 | switchRatingsInt_1: 0 622 | switchRatingsInt_2: 0 623 | switchRatingsInt_3: 0 624 | switchRatingsInt_4: 0 625 | switchRatingsInt_5: 0 626 | switchRatingsInt_6: 0 627 | switchRatingsInt_7: 0 628 | switchRatingsInt_8: 0 629 | switchRatingsInt_9: 0 630 | switchRatingsInt_10: 0 631 | switchRatingsInt_11: 0 632 | switchRatingsInt_12: 0 633 | switchLocalCommunicationIds_0: 634 | switchLocalCommunicationIds_1: 635 | switchLocalCommunicationIds_2: 636 | switchLocalCommunicationIds_3: 637 | switchLocalCommunicationIds_4: 638 | switchLocalCommunicationIds_5: 639 | switchLocalCommunicationIds_6: 640 | switchLocalCommunicationIds_7: 641 | switchParentalControl: 0 642 | switchAllowsScreenshot: 1 643 | switchAllowsVideoCapturing: 1 644 | switchAllowsRuntimeAddOnContentInstall: 0 645 | switchDataLossConfirmation: 0 646 | switchUserAccountLockEnabled: 0 647 | switchSystemResourceMemory: 16777216 648 | switchSupportedNpadStyles: 22 649 | switchNativeFsCacheSize: 32 650 | switchIsHoldTypeHorizontal: 0 651 | switchSupportedNpadCount: 8 652 | switchEnableTouchScreen: 1 653 | switchSocketConfigEnabled: 0 654 | switchTcpInitialSendBufferSize: 32 655 | switchTcpInitialReceiveBufferSize: 64 656 | switchTcpAutoSendBufferSizeMax: 256 657 | switchTcpAutoReceiveBufferSizeMax: 256 658 | switchUdpSendBufferSize: 9 659 | switchUdpReceiveBufferSize: 42 660 | switchSocketBufferEfficiency: 4 661 | switchSocketInitializeEnabled: 1 662 | switchNetworkInterfaceManagerInitializeEnabled: 1 663 | switchPlayerConnectionEnabled: 1 664 | switchUseNewStyleFilepaths: 0 665 | switchUseLegacyFmodPriorities: 1 666 | switchUseMicroSleepForYield: 1 667 | switchEnableRamDiskSupport: 0 668 | switchMicroSleepForYieldTime: 25 669 | switchRamDiskSpaceSize: 12 670 | ps4NPAgeRating: 12 671 | ps4NPTitleSecret: 672 | ps4NPTrophyPackPath: 673 | ps4ParentalLevel: 11 674 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 675 | ps4Category: 0 676 | ps4MasterVersion: 01.00 677 | ps4AppVersion: 01.00 678 | ps4AppType: 0 679 | ps4ParamSfxPath: 680 | ps4VideoOutPixelFormat: 0 681 | ps4VideoOutInitialWidth: 1920 682 | ps4VideoOutBaseModeInitialWidth: 1920 683 | ps4VideoOutReprojectionRate: 60 684 | ps4PronunciationXMLPath: 685 | ps4PronunciationSIGPath: 686 | ps4BackgroundImagePath: 687 | ps4StartupImagePath: 688 | ps4StartupImagesFolder: 689 | ps4IconImagesFolder: 690 | ps4SaveDataImagePath: 691 | ps4SdkOverride: 692 | ps4BGMPath: 693 | ps4ShareFilePath: 694 | ps4ShareOverlayImagePath: 695 | ps4PrivacyGuardImagePath: 696 | ps4ExtraSceSysFile: 697 | ps4NPtitleDatPath: 698 | ps4RemotePlayKeyAssignment: -1 699 | ps4RemotePlayKeyMappingDir: 700 | ps4PlayTogetherPlayerCount: 0 701 | ps4EnterButtonAssignment: 2 702 | ps4ApplicationParam1: 0 703 | ps4ApplicationParam2: 0 704 | ps4ApplicationParam3: 0 705 | ps4ApplicationParam4: 0 706 | ps4DownloadDataSize: 0 707 | ps4GarlicHeapSize: 2048 708 | ps4ProGarlicHeapSize: 2560 709 | playerPrefsMaxSize: 32768 710 | ps4Passcode: bi9UOuSpM2Tlh01vOzwvSikHFswuzleh 711 | ps4pnSessions: 1 712 | ps4pnPresence: 1 713 | ps4pnFriends: 1 714 | ps4pnGameCustomData: 1 715 | playerPrefsSupport: 0 716 | enableApplicationExit: 0 717 | resetTempFolder: 1 718 | restrictedAudioUsageRights: 0 719 | ps4UseResolutionFallback: 0 720 | ps4ReprojectionSupport: 0 721 | ps4UseAudio3dBackend: 0 722 | ps4UseLowGarlicFragmentationMode: 1 723 | ps4SocialScreenEnabled: 0 724 | ps4ScriptOptimizationLevel: 2 725 | ps4Audio3dVirtualSpeakerCount: 14 726 | ps4attribCpuUsage: 0 727 | ps4PatchPkgPath: 728 | ps4PatchLatestPkgPath: 729 | ps4PatchChangeinfoPath: 730 | ps4PatchDayOne: 0 731 | ps4attribUserManagement: 0 732 | ps4attribMoveSupport: 0 733 | ps4attrib3DSupport: 0 734 | ps4attribShareSupport: 0 735 | ps4attribExclusiveVR: 0 736 | ps4disableAutoHideSplash: 0 737 | ps4videoRecordingFeaturesUsed: 0 738 | ps4contentSearchFeaturesUsed: 0 739 | ps4CompatibilityPS5: 0 740 | ps4AllowPS5Detection: 0 741 | ps4GPU800MHz: 1 742 | ps4attribEyeToEyeDistanceSettingVR: 0 743 | ps4IncludedModules: [] 744 | ps4attribVROutputEnabled: 0 745 | monoEnv: 746 | splashScreenBackgroundSourceLandscape: {fileID: 0} 747 | splashScreenBackgroundSourcePortrait: {fileID: 0} 748 | blurSplashScreenBackground: 1 749 | spritePackerPolicy: 750 | webGLMemorySize: 32 751 | webGLExceptionSupport: 1 752 | webGLNameFilesAsHashes: 0 753 | webGLDataCaching: 1 754 | webGLDebugSymbols: 0 755 | webGLEmscriptenArgs: 756 | webGLModulesDirectory: 757 | webGLTemplate: APPLICATION:Default 758 | webGLAnalyzeBuildSize: 0 759 | webGLUseEmbeddedResources: 0 760 | webGLCompressionFormat: 0 761 | webGLWasmArithmeticExceptions: 0 762 | webGLLinkerTarget: 1 763 | webGLThreadsSupport: 0 764 | webGLDecompressionFallback: 0 765 | webGLPowerPreference: 2 766 | scriptingDefineSymbols: {} 767 | additionalCompilerArguments: {} 768 | platformArchitecture: {} 769 | scriptingBackend: {} 770 | il2cppCompilerConfiguration: {} 771 | managedStrippingLevel: 772 | EmbeddedLinux: 1 773 | GameCoreScarlett: 1 774 | GameCoreXboxOne: 1 775 | Lumin: 1 776 | Nintendo Switch: 1 777 | PS4: 1 778 | PS5: 1 779 | Stadia: 1 780 | WebGL: 1 781 | Windows Store Apps: 1 782 | XboxOne: 1 783 | iPhone: 1 784 | tvOS: 1 785 | incrementalIl2cppBuild: {} 786 | suppressCommonWarnings: 1 787 | allowUnsafeCode: 0 788 | useDeterministicCompilation: 1 789 | enableRoslynAnalyzers: 1 790 | selectedPlatform: 0 791 | additionalIl2CppArgs: 792 | scriptingRuntimeVersion: 1 793 | gcIncremental: 1 794 | assemblyVersionValidation: 1 795 | gcWBarrierValidation: 0 796 | apiCompatibilityLevelPerPlatform: {} 797 | m_RenderingPath: 1 798 | m_MobileRenderingPath: 1 799 | metroPackageName: 2D_BuiltInRenderer 800 | metroPackageVersion: 801 | metroCertificatePath: 802 | metroCertificatePassword: 803 | metroCertificateSubject: 804 | metroCertificateIssuer: 805 | metroCertificateNotAfter: 0000000000000000 806 | metroApplicationDescription: 2D_BuiltInRenderer 807 | wsaImages: {} 808 | metroTileShortName: 809 | metroTileShowName: 0 810 | metroMediumTileShowName: 0 811 | metroLargeTileShowName: 0 812 | metroWideTileShowName: 0 813 | metroSupportStreamingInstall: 0 814 | metroLastRequiredScene: 0 815 | metroDefaultTileSize: 1 816 | metroTileForegroundText: 2 817 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 818 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} 819 | metroSplashScreenUseBackgroundColor: 0 820 | platformCapabilities: {} 821 | metroTargetDeviceFamilies: {} 822 | metroFTAName: 823 | metroFTAFileTypes: [] 824 | metroProtocolName: 825 | vcxProjDefaultLanguage: 826 | XboxOneProductId: 827 | XboxOneUpdateKey: 828 | XboxOneSandboxId: 829 | XboxOneContentId: 830 | XboxOneTitleId: 831 | XboxOneSCId: 832 | XboxOneGameOsOverridePath: 833 | XboxOnePackagingOverridePath: 834 | XboxOneAppManifestOverridePath: 835 | XboxOneVersion: 1.0.0.0 836 | XboxOnePackageEncryption: 0 837 | XboxOnePackageUpdateGranularity: 2 838 | XboxOneDescription: 839 | XboxOneLanguage: 840 | - enus 841 | XboxOneCapability: [] 842 | XboxOneGameRating: {} 843 | XboxOneIsContentPackage: 0 844 | XboxOneEnhancedXboxCompatibilityMode: 0 845 | XboxOneEnableGPUVariability: 1 846 | XboxOneSockets: {} 847 | XboxOneSplashScreen: {fileID: 0} 848 | XboxOneAllowedProductIds: [] 849 | XboxOnePersistentLocalStorageSize: 0 850 | XboxOneXTitleMemory: 8 851 | XboxOneOverrideIdentityName: 852 | XboxOneOverrideIdentityPublisher: 853 | vrEditorSettings: {} 854 | cloudServicesEnabled: {} 855 | luminIcon: 856 | m_Name: 857 | m_ModelFolderPath: 858 | m_PortalFolderPath: 859 | luminCert: 860 | m_CertPath: 861 | m_SignPackage: 1 862 | luminIsChannelApp: 0 863 | luminVersion: 864 | m_VersionCode: 1 865 | m_VersionName: 866 | apiCompatibilityLevel: 6 867 | activeInputHandler: 0 868 | windowsGamepadBackendHint: 0 869 | cloudProjectId: 870 | framebufferDepthMemorylessMode: 0 871 | qualitySettingsNames: [] 872 | projectName: 873 | organizationId: 874 | cloudEnabled: 0 875 | legacyClampBlendShapeWeights: 0 876 | playerDataPath: 877 | forceSRGBBlit: 1 878 | virtualTexturingSupportEnabled: 0 879 | --------------------------------------------------------------------------------