diff --git a/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.msb4u.sln b/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.msb4u.sln index c067a8d..d87a3cd 100644 --- a/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.msb4u.sln +++ b/Samples/IntegratedDependencies.Unity/Assets/Project.Unity.msb4u.sln @@ -2,197 +2,472 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28307.539 MinimumVisualStudioVersion = 10.0.40219.1 -# This file is generated by MSBuildForUnity, it will get updated when the assembly definitions change. -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.TextMeshPro", "C:\Projects\MSBuildForUnity\Development\Samples\IntegratedDependencies.Unity\MSBuild\Projects\Unity.TextMeshPro.msb4u.csproj", "{6055BE8E-BEFD-69E4-8B49-212B09B47B2F}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Component.WSA.msb4u", "WSASpecific\Component.WSA.msb4u.csproj", "{BB41A40A-FD6B-AD74-0865-83AB52977BDC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.PackageManagerUI.Editor", "C:\Projects\MSBuildForUnity\Development\Samples\IntegratedDependencies.Unity\MSBuild\Projects\Unity.PackageManagerUI.Editor.msb4u.csproj", "{15A615C7-33AA-2409-09FE-0B28B0D5143C}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.TextMeshPro.msb4u", "..\MSBuild\Projects\Unity.TextMeshPro.msb4u.csproj", "{6055BE8E-BEFD-69E4-8B49-212B09B47B2F}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.CollabProxy.Editor", "C:\Projects\MSBuildForUnity\Development\Samples\IntegratedDependencies.Unity\MSBuild\Projects\Unity.CollabProxy.Editor.msb4u.csproj", "{645165C8-1694-74BF-BBEB-8FB0BCFD26F5}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.PackageManagerUI.Editor.msb4u", "..\MSBuild\Projects\Unity.PackageManagerUI.Editor.msb4u.csproj", "{15A615C7-33AA-2409-09FE-0B28B0D5143C}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSBuildForUnity", "C:\Projects\MSBuildForUnity\Development\Samples\IntegratedDependencies.Unity\MSBuild\Projects\MSBuildForUnity.msb4u.csproj", "{0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.CollabProxy.Editor.msb4u", "..\MSBuild\Projects\Unity.CollabProxy.Editor.msb4u.csproj", "{645165C8-1694-74BF-BBEB-8FB0BCFD26F5}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Analytics.DataPrivacy", "C:\Projects\MSBuildForUnity\Development\Samples\IntegratedDependencies.Unity\MSBuild\Projects\Unity.Analytics.DataPrivacy.msb4u.csproj", "{0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MSBuildForUnity.msb4u", "..\MSBuild\Projects\MSBuildForUnity.msb4u.csproj", "{0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.TextMeshPro.Editor", "C:\Projects\MSBuildForUnity\Development\Samples\IntegratedDependencies.Unity\MSBuild\Projects\Unity.TextMeshPro.Editor.msb4u.csproj", "{6546D776-5B41-65B4-0850-B3667F981C26}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.Analytics.DataPrivacy.msb4u", "..\MSBuild\Projects\Unity.Analytics.DataPrivacy.msb4u.csproj", "{0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unity.TextMeshPro.Editor.msb4u", "..\MSBuild\Projects\Unity.TextMeshPro.Editor.msb4u.csproj", "{6546D776-5B41-65B4-0850-B3667F981C26}" ProjectSection(ProjectDependencies) = postProject {6055BE8E-BEFD-69E4-8B49-212B09B47B2F} = {6055BE8E-BEFD-69E4-8B49-212B09B47B2F} EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Assembly-CSharp", "C:\Projects\MSBuildForUnity\Development\Samples\IntegratedDependencies.Unity\Assets\Assembly-CSharp.msb4u.csproj", "{FE8A6F42-D26E-4974-ADA4-18610F218C67}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Assembly-CSharp.msb4u", "Assembly-CSharp.msb4u.csproj", "{4989D6C6-D8B3-4556-B4A9-06093DED68AD}" ProjectSection(ProjectDependencies) = postProject {6546D776-5B41-65B4-0850-B3667F981C26} = {6546D776-5B41-65B4-0850-B3667F981C26} {15A615C7-33AA-2409-09FE-0B28B0D5143C} = {15A615C7-33AA-2409-09FE-0B28B0D5143C} {645165C8-1694-74BF-BBEB-8FB0BCFD26F5} = {645165C8-1694-74BF-BBEB-8FB0BCFD26F5} + {BB41A40A-FD6B-AD74-0865-83AB52977BDC} = {BB41A40A-FD6B-AD74-0865-83AB52977BDC} {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD} = {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD} {6055BE8E-BEFD-69E4-8B49-212B09B47B2F} = {6055BE8E-BEFD-69E4-8B49-212B09B47B2F} {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E} = {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E} EndProjectSection EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dependencies", "C:\Projects\MSBuildForUnity\Development\Samples\IntegratedDependencies.Unity\Assets\Dependencies.msb4u.csproj", "{DFB08FA4-CBE1-497A-9F1D-9C856FF2428A}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dependencies.msb4u", "Dependencies.msb4u.csproj", "{0D77AB82-D4EB-4034-AC54-4CA04D06906C}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Imported Packages", "Imported Packages", "{1208A866-B74A-4F43-BC60-D7D1074D9230}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonLibrary", "..\External\CommonLibrary\CommonLibrary.csproj", "{D36DD91A-2347-4BE3-BDAD-E72898C014BA}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External Packages", "External Packages", "{364236E7-C3A1-466B-A98A-43F9BA96A7E7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommonLibrary.WSA", "..\External\CommonLibrary.WSA\CommonLibrary.WSA.csproj", "{06FDDF06-41BA-47F3-863F-E426A80C69A8}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Imported Packages", "Imported Packages", "{F0962E2E-3201-42A4-90A4-4BD07B8D0413}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External Packages", "External Packages", "{02CFE9B1-8003-483F-802B-F2ACC2E2C82B}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "External", "External", "{9D69A397-2F47-459D-B35F-C5D0C9D588B8}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Android = Debug|Android + Debug|Any CPU = Debug|Any CPU + Debug|iOS = Debug|iOS + Debug|WindowsStandalone32 = Debug|WindowsStandalone32 + Debug|WindowsStandalone64 = Debug|WindowsStandalone64 + Debug|WSA = Debug|WSA InEditor|Android = InEditor|Android - Player|Android = Player|Android + InEditor|Any CPU = InEditor|Any CPU InEditor|iOS = InEditor|iOS - Player|iOS = Player|iOS InEditor|WindowsStandalone32 = InEditor|WindowsStandalone32 - Player|WindowsStandalone32 = Player|WindowsStandalone32 InEditor|WindowsStandalone64 = InEditor|WindowsStandalone64 - Player|WindowsStandalone64 = Player|WindowsStandalone64 InEditor|WSA = InEditor|WSA + Player|Android = Player|Android + Player|Any CPU = Player|Any CPU + Player|iOS = Player|iOS + Player|WindowsStandalone32 = Player|WindowsStandalone32 + Player|WindowsStandalone64 = Player|WindowsStandalone64 Player|WSA = Player|WSA + Release|Android = Release|Android + Release|Any CPU = Release|Any CPU + Release|iOS = Release|iOS + Release|WindowsStandalone32 = Release|WindowsStandalone32 + Release|WindowsStandalone64 = Release|WindowsStandalone64 + Release|WSA = Release|WSA EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Debug|Android.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Debug|Any CPU.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Debug|iOS.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Debug|WindowsStandalone32.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Debug|WindowsStandalone64.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Debug|WSA.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|Android.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|Android.Build.0 = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|Any CPU.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|iOS.ActiveCfg = InEditor|iOS + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|iOS.Build.0 = InEditor|iOS + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|WSA.ActiveCfg = InEditor|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.InEditor|WSA.Build.0 = InEditor|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Player|Android.ActiveCfg = Player|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Player|Any CPU.ActiveCfg = Player|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Player|iOS.ActiveCfg = Player|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Player|WindowsStandalone32.ActiveCfg = Player|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Player|WindowsStandalone64.ActiveCfg = Player|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Player|WSA.ActiveCfg = Player|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Player|WSA.Build.0 = Player|WSA + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Release|Android.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Release|Any CPU.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Release|iOS.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Release|WindowsStandalone32.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Release|WindowsStandalone64.ActiveCfg = InEditor|Android + {BB41A40A-FD6B-AD74-0865-83AB52977BDC}.Release|WSA.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Debug|Android.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Debug|Any CPU.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Debug|iOS.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Debug|WindowsStandalone32.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Debug|WindowsStandalone64.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Debug|WSA.ActiveCfg = InEditor|Android {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|Android.ActiveCfg = InEditor|Android - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|iOS.ActiveCfg = InEditor|iOS - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WSA.ActiveCfg = InEditor|WSA - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|Android.ActiveCfg = Player|Android - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|iOS.ActiveCfg = Player|iOS - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WSA.ActiveCfg = Player|WSA - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|Android.ActiveCfg = InEditor|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|iOS.ActiveCfg = InEditor|iOS - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WSA.ActiveCfg = InEditor|WSA - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Android.ActiveCfg = Player|Android - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|iOS.ActiveCfg = Player|iOS - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 - {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WSA.ActiveCfg = Player|WSA - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|Android.ActiveCfg = InEditor|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|iOS.ActiveCfg = InEditor|iOS - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WSA.ActiveCfg = InEditor|WSA - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Android.ActiveCfg = Player|Android - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|iOS.ActiveCfg = Player|iOS - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WSA.ActiveCfg = Player|WSA - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|Android.ActiveCfg = InEditor|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|iOS.ActiveCfg = InEditor|iOS - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WSA.ActiveCfg = InEditor|WSA - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Android.ActiveCfg = Player|Android - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|iOS.ActiveCfg = Player|iOS - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WSA.ActiveCfg = Player|WSA - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|Android.ActiveCfg = InEditor|Android - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|iOS.ActiveCfg = InEditor|iOS - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WSA.ActiveCfg = InEditor|WSA - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|Android.ActiveCfg = Player|Android - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|iOS.ActiveCfg = Player|iOS - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WSA.ActiveCfg = Player|WSA - {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|Android.ActiveCfg = InEditor|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|iOS.ActiveCfg = InEditor|iOS - {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 - {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 - {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WSA.ActiveCfg = InEditor|WSA - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Android.ActiveCfg = Player|Android - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|iOS.ActiveCfg = Player|iOS - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 - {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WSA.ActiveCfg = Player|WSA - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|Android.ActiveCfg = InEditor|Android - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|iOS.ActiveCfg = InEditor|iOS - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|WSA.ActiveCfg = InEditor|WSA - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|Android.ActiveCfg = Player|Android - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|iOS.ActiveCfg = Player|iOS - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|WSA.ActiveCfg = Player|WSA {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|Android.Build.0 = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|Any CPU.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|iOS.ActiveCfg = InEditor|iOS {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|iOS.Build.0 = InEditor|iOS + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WSA.ActiveCfg = InEditor|WSA {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.InEditor|WSA.Build.0 = InEditor|WSA + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|Android.ActiveCfg = Player|Android {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|Android.Build.0 = Player|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|Any CPU.ActiveCfg = Player|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|iOS.ActiveCfg = Player|iOS {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|iOS.Build.0 = Player|iOS + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WindowsStandalone32.Build.0 = Player|WindowsStandalone32 + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WindowsStandalone64.Build.0 = Player|WindowsStandalone64 + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WSA.ActiveCfg = Player|WSA {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Player|WSA.Build.0 = Player|WSA + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Release|Android.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Release|Any CPU.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Release|iOS.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Release|WindowsStandalone32.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Release|WindowsStandalone64.ActiveCfg = InEditor|Android + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F}.Release|WSA.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Debug|Android.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Debug|Any CPU.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Debug|iOS.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Debug|WindowsStandalone32.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Debug|WindowsStandalone64.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Debug|WSA.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|Android.ActiveCfg = InEditor|Android {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|Android.Build.0 = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|Any CPU.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|iOS.ActiveCfg = InEditor|iOS {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|iOS.Build.0 = InEditor|iOS + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WSA.ActiveCfg = InEditor|WSA {15A615C7-33AA-2409-09FE-0B28B0D5143C}.InEditor|WSA.Build.0 = InEditor|WSA + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Android.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|Any CPU.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|iOS.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Player|WSA.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|Android.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|Any CPU.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|iOS.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|WindowsStandalone32.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|WindowsStandalone64.ActiveCfg = InEditor|Android + {15A615C7-33AA-2409-09FE-0B28B0D5143C}.Release|WSA.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Debug|Android.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Debug|Any CPU.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Debug|iOS.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Debug|WindowsStandalone32.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Debug|WindowsStandalone64.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Debug|WSA.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|Android.ActiveCfg = InEditor|Android {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|Android.Build.0 = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|Any CPU.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|iOS.ActiveCfg = InEditor|iOS {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|iOS.Build.0 = InEditor|iOS + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WSA.ActiveCfg = InEditor|WSA {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.InEditor|WSA.Build.0 = InEditor|WSA + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Android.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|Any CPU.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|iOS.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Player|WSA.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|Android.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|Any CPU.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|iOS.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|WindowsStandalone32.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|WindowsStandalone64.ActiveCfg = InEditor|Android + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5}.Release|WSA.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Debug|Android.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Debug|Any CPU.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Debug|iOS.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Debug|WindowsStandalone32.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Debug|WindowsStandalone64.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Debug|WSA.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|Android.ActiveCfg = InEditor|Android {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|Android.Build.0 = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|Any CPU.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|iOS.ActiveCfg = InEditor|iOS {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|iOS.Build.0 = InEditor|iOS + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WSA.ActiveCfg = InEditor|WSA {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.InEditor|WSA.Build.0 = InEditor|WSA + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Android.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|Any CPU.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|iOS.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Player|WSA.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|Android.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|Any CPU.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|iOS.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|WindowsStandalone32.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|WindowsStandalone64.ActiveCfg = InEditor|Android + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD}.Release|WSA.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Debug|Android.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Debug|Any CPU.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Debug|iOS.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Debug|WindowsStandalone32.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Debug|WindowsStandalone64.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Debug|WSA.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|Android.ActiveCfg = InEditor|Android {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|Android.Build.0 = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|Any CPU.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|iOS.ActiveCfg = InEditor|iOS {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|iOS.Build.0 = InEditor|iOS + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WSA.ActiveCfg = InEditor|WSA {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.InEditor|WSA.Build.0 = InEditor|WSA + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|Android.ActiveCfg = Player|Android {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|Android.Build.0 = Player|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|Any CPU.ActiveCfg = Player|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|iOS.ActiveCfg = Player|iOS {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|iOS.Build.0 = Player|iOS + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WindowsStandalone32.Build.0 = Player|WindowsStandalone32 + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WindowsStandalone64.Build.0 = Player|WindowsStandalone64 + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WSA.ActiveCfg = Player|WSA {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Player|WSA.Build.0 = Player|WSA + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Release|Android.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Release|Any CPU.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Release|iOS.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Release|WindowsStandalone32.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Release|WindowsStandalone64.ActiveCfg = InEditor|Android + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E}.Release|WSA.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Debug|Android.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Debug|Any CPU.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Debug|iOS.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Debug|WindowsStandalone32.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Debug|WindowsStandalone64.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Debug|WSA.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|Android.ActiveCfg = InEditor|Android {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|Android.Build.0 = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|Any CPU.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|iOS.ActiveCfg = InEditor|iOS {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|iOS.Build.0 = InEditor|iOS + {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 + {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 + {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WSA.ActiveCfg = InEditor|WSA {6546D776-5B41-65B4-0850-B3667F981C26}.InEditor|WSA.Build.0 = InEditor|WSA - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|Android.Build.0 = InEditor|Android - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|iOS.Build.0 = InEditor|iOS - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.InEditor|WSA.Build.0 = InEditor|WSA - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|Android.Build.0 = Player|Android - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|iOS.Build.0 = Player|iOS - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|WindowsStandalone32.Build.0 = Player|WindowsStandalone32 - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|WindowsStandalone64.Build.0 = Player|WindowsStandalone64 - {FE8A6F42-D26E-4974-ADA4-18610F218C67}.Player|WSA.Build.0 = Player|WSA + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Android.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|Any CPU.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|iOS.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone32.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WindowsStandalone64.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Player|WSA.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Release|Android.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Release|Any CPU.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Release|iOS.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Release|WindowsStandalone32.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Release|WindowsStandalone64.ActiveCfg = InEditor|Android + {6546D776-5B41-65B4-0850-B3667F981C26}.Release|WSA.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Debug|Android.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Debug|Any CPU.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Debug|iOS.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Debug|WindowsStandalone32.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Debug|WindowsStandalone64.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Debug|WSA.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|Android.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|Android.Build.0 = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|Any CPU.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|iOS.ActiveCfg = InEditor|iOS + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|iOS.Build.0 = InEditor|iOS + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|WindowsStandalone32.ActiveCfg = InEditor|WindowsStandalone32 + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|WindowsStandalone32.Build.0 = InEditor|WindowsStandalone32 + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|WindowsStandalone64.ActiveCfg = InEditor|WindowsStandalone64 + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|WindowsStandalone64.Build.0 = InEditor|WindowsStandalone64 + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|WSA.ActiveCfg = InEditor|WSA + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.InEditor|WSA.Build.0 = InEditor|WSA + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|Android.ActiveCfg = Player|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|Android.Build.0 = Player|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|Any CPU.ActiveCfg = Player|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|iOS.ActiveCfg = Player|iOS + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|iOS.Build.0 = Player|iOS + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|WindowsStandalone32.ActiveCfg = Player|WindowsStandalone32 + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|WindowsStandalone32.Build.0 = Player|WindowsStandalone32 + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|WindowsStandalone64.ActiveCfg = Player|WindowsStandalone64 + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|WindowsStandalone64.Build.0 = Player|WindowsStandalone64 + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|WSA.ActiveCfg = Player|WSA + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Player|WSA.Build.0 = Player|WSA + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Release|Android.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Release|Any CPU.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Release|iOS.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Release|WindowsStandalone32.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Release|WindowsStandalone64.ActiveCfg = InEditor|Android + {4989D6C6-D8B3-4556-B4A9-06093DED68AD}.Release|WSA.ActiveCfg = InEditor|Android + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Debug|Android.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Debug|iOS.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Debug|WindowsStandalone32.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Debug|WindowsStandalone64.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Debug|WSA.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.InEditor|Android.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.InEditor|Any CPU.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.InEditor|iOS.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.InEditor|WindowsStandalone32.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.InEditor|WindowsStandalone64.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.InEditor|WSA.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Player|Android.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Player|Any CPU.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Player|iOS.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Player|WindowsStandalone32.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Player|WindowsStandalone64.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Player|WSA.ActiveCfg = Debug|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Release|Android.ActiveCfg = Release|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Release|Any CPU.Build.0 = Release|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Release|iOS.ActiveCfg = Release|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Release|WindowsStandalone32.ActiveCfg = Release|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Release|WindowsStandalone64.ActiveCfg = Release|Any CPU + {0D77AB82-D4EB-4034-AC54-4CA04D06906C}.Release|WSA.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|Android.ActiveCfg = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|Android.Build.0 = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|iOS.ActiveCfg = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|iOS.Build.0 = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|WindowsStandalone32.ActiveCfg = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|WindowsStandalone32.Build.0 = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|WindowsStandalone64.ActiveCfg = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|WindowsStandalone64.Build.0 = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|WSA.ActiveCfg = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Debug|WSA.Build.0 = Debug|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|Android.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|Android.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|Any CPU.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|Any CPU.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|iOS.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|iOS.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|WindowsStandalone32.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|WindowsStandalone32.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|WindowsStandalone64.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|WindowsStandalone64.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|WSA.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.InEditor|WSA.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|Android.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|Android.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|Any CPU.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|Any CPU.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|iOS.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|iOS.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|WindowsStandalone32.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|WindowsStandalone32.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|WindowsStandalone64.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|WindowsStandalone64.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|WSA.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Player|WSA.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|Android.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|Android.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|Any CPU.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|iOS.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|iOS.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|WindowsStandalone32.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|WindowsStandalone32.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|WindowsStandalone64.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|WindowsStandalone64.Build.0 = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|WSA.ActiveCfg = Release|Any CPU + {D36DD91A-2347-4BE3-BDAD-E72898C014BA}.Release|WSA.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|Android.ActiveCfg = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|Android.Build.0 = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|iOS.ActiveCfg = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|iOS.Build.0 = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|WindowsStandalone32.ActiveCfg = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|WindowsStandalone32.Build.0 = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|WindowsStandalone64.ActiveCfg = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|WindowsStandalone64.Build.0 = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|WSA.ActiveCfg = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Debug|WSA.Build.0 = Debug|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|Android.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|Android.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|Any CPU.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|Any CPU.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|iOS.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|iOS.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|WindowsStandalone32.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|WindowsStandalone32.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|WindowsStandalone64.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|WindowsStandalone64.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|WSA.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.InEditor|WSA.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|Android.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|Android.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|Any CPU.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|Any CPU.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|iOS.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|iOS.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|WindowsStandalone32.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|WindowsStandalone32.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|WindowsStandalone64.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|WindowsStandalone64.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|WSA.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Player|WSA.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|Android.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|Android.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|Any CPU.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|iOS.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|iOS.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|WindowsStandalone32.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|WindowsStandalone32.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|WindowsStandalone64.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|WindowsStandalone64.Build.0 = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|WSA.ActiveCfg = Release|Any CPU + {06FDDF06-41BA-47F3-863F-E426A80C69A8}.Release|WSA.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {6055BE8E-BEFD-69E4-8B49-212B09B47B2F} = {1208A866-B74A-4F43-BC60-D7D1074D9230} - {15A615C7-33AA-2409-09FE-0B28B0D5143C} = {1208A866-B74A-4F43-BC60-D7D1074D9230} - {645165C8-1694-74BF-BBEB-8FB0BCFD26F5} = {1208A866-B74A-4F43-BC60-D7D1074D9230} - {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E} = {1208A866-B74A-4F43-BC60-D7D1074D9230} - {6546D776-5B41-65B4-0850-B3667F981C26} = {1208A866-B74A-4F43-BC60-D7D1074D9230} - {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD} = {364236E7-C3A1-466B-A98A-43F9BA96A7E7} + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F} = {F0962E2E-3201-42A4-90A4-4BD07B8D0413} + {15A615C7-33AA-2409-09FE-0B28B0D5143C} = {F0962E2E-3201-42A4-90A4-4BD07B8D0413} + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5} = {F0962E2E-3201-42A4-90A4-4BD07B8D0413} + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD} = {02CFE9B1-8003-483F-802B-F2ACC2E2C82B} + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E} = {F0962E2E-3201-42A4-90A4-4BD07B8D0413} + {6546D776-5B41-65B4-0850-B3667F981C26} = {F0962E2E-3201-42A4-90A4-4BD07B8D0413} + {D36DD91A-2347-4BE3-BDAD-E72898C014BA} = {9D69A397-2F47-459D-B35F-C5D0C9D588B8} + {06FDDF06-41BA-47F3-863F-E426A80C69A8} = {9D69A397-2F47-459D-B35F-C5D0C9D588B8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {89752EEF-6413-4D53-BA9D-DCA0707F134E} + SolutionGuid = {6E6CC69E-A194-4F01-9182-CE7B0F63F375} + EndGlobalSection + GlobalSection(SolutionNotes) = postSolution + {F0962E2E-3201-42A4-90A4-4BD07B8D0413} = msb4u.generated + {02CFE9B1-8003-483F-802B-F2ACC2E2C82B} = msb4u.generated + {BB41A40A-FD6B-AD74-0865-83AB52977BDC} = msb4u.generated + {6055BE8E-BEFD-69E4-8B49-212B09B47B2F} = msb4u.generated + {15A615C7-33AA-2409-09FE-0B28B0D5143C} = msb4u.generated + {645165C8-1694-74BF-BBEB-8FB0BCFD26F5} = msb4u.generated + {0DF1F49A-50F1-5354-5BF9-9E3DBB6674AD} = msb4u.generated + {0FDA7EBE-61AB-2164-383D-10E32EFB9C6E} = msb4u.generated + {6546D776-5B41-65B4-0850-B3667F981C26} = msb4u.generated + {4989D6C6-D8B3-4556-B4A9-06093DED68AD} = msb4u.generated + {0D77AB82-D4EB-4034-AC54-4CA04D06906C} = msb4u.generated EndGlobalSection EndGlobal diff --git a/Samples/IntegratedDependencies.Unity/MSBuild/settings.json b/Samples/IntegratedDependencies.Unity/MSBuild/settings.json index 978fcfd..80e8845 100644 --- a/Samples/IntegratedDependencies.Unity/MSBuild/settings.json +++ b/Samples/IntegratedDependencies.Unity/MSBuild/settings.json @@ -1 +1 @@ -{"autoGenerateEnabled":true} \ No newline at end of file +{"version":3,"autoGenerateEnabled":true,"dependenciesProjectGuid":"0d77ab82-d4eb-4034-ac54-4ca04d06906c","assemblyCSharpGuid":"4989d6c6-d8b3-4556-b4a9-06093ded68ad","assemblyCSharpEditorGuid":"0cd3f705-4fb4-4a60-8d09-89dc9f0b38a2","assemblyCSharpFirstPassGuid":"5c2fd87a-9877-4af1-ace8-1eed615617c0","assemblyCSharpFirstPassEditorGuid":"eea5290c-d0ca-4efa-b53c-69b3606c8bf2","builtInPackagesFolderGuid":"f78b56e6-cdfd-4bf5-9c51-6a8989cb7c6d","importedPackagesFolderGuid":"f0962e2e-3201-42a4-90a4-4bd07b8d0413","externalPackagesFolderGuid":"02cfe9b1-8003-483f-802b-f2acc2e2c82b","solutionGuid":"6e6cc69e-a194-4f01-9182-ce7b0f63f375"} \ No newline at end of file diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template index ccc1049..7b34605 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/DependenciesProjectTemplate.g.props.template @@ -12,6 +12,7 @@ + InEditor $(MSBuildForUnityGeneratedOutputDirectory)\..\Output\obj\Dependencies diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SolutionTemplate.sln.template b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SolutionTemplate.sln.template index ebf9c2f..02cae39 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SolutionTemplate.sln.template +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/MSBuildTemplates/SolutionTemplate.sln.template @@ -2,12 +2,18 @@ # Visual Studio 15 VisualStudioVersion = 15.0.28307.539 MinimumVisualStudioVersion = 10.0.40219.1 -# This file is generated by MSBuildForUnity, it will get updated when the assembly definitions change. #PROJECT_TEMPLATE_START Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "", "", "{}" +#PROJECT_SECTION_TEMPLATE_START ProjectSection(ProjectDependencies) = postProject #PROJECT_DEPENDENCY_TEMPLATE {} = {} EndProjectSection +#PROJECT_SECTION_TEMPLATE_END +#EXTRA_PROJECT_SECTION_TEMPLATE_START + ProjectSection() = +#EXTRA_SECTION_LINE_TEMPLATE + EndProjectSection +#EXTRA_PROJECT_SECTION_TEMPLATE_END EndProject #PROJECT_TEMPLATE_END #FOLDER_TEMPLATE_START @@ -19,16 +25,23 @@ Global #CONFIGURATION_PLATFORM_TEMPLATE | = | EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution -#CONFIGURATION_PLATFORM_MAPPING_TEMPLATE {}.|.ActiveCfg = | -#CONFIGURATION_PLATFORM_ENABLED_TEMPLATE {}.|.Build.0 = | +#CONFIGURATION_PLATFORM_PROPERTY_TEMPLATE {}.|. = | EndGlobalSection GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE +#SOLUTION_PROPERTIES_TEMPLATE = EndGlobalSection GlobalSection(NestedProjects) = preSolution #FOLDER_NESTED_PROJECTS_TEMPLATE {} = {} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {89752EEF-6413-4D53-BA9D-DCA0707F134E} +#EXTENSIBILITY_GLOBALS_TEMPLATE = + EndGlobalSection + GlobalSection(SolutionNotes) = postSolution +#SOLUTION_NOTES_TEMPLATE = + EndGlobalSection +#EXTRA_GLOBAL_SECTION_TEMPLATE_START + GlobalSection() = +#EXTRA_SECTION_LINE_TEMPLATE EndGlobalSection +#EXTRA_GLOBAL_SECTION_TEMPLATE_END EndGlobal diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/AssemblyDefinitionInfo.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/AssemblyDefinitionInfo.cs index ca43ffb..1b831a4 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/AssemblyDefinitionInfo.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/AssemblyDefinitionInfo.cs @@ -23,10 +23,11 @@ public class AssemblyDefinitionInfo /// Creates an instance of for the default projects (such as Assembly-CSharp) /// /// The Unity assembly reference. + /// The guid for this assembly reference. /// A new instance. - public static AssemblyDefinitionInfo GetDefaultAssemblyCSharpInfo(Assembly assembly) + public static AssemblyDefinitionInfo GetDefaultAssemblyCSharpInfo(Assembly assembly, Guid guid) { - AssemblyDefinitionInfo toReturn = new AssemblyDefinitionInfo() { IsDefaultAssembly = true, Guid = Guid.NewGuid(), Directory = new DirectoryInfo(Utilities.AssetPath) }; + AssemblyDefinitionInfo toReturn = new AssemblyDefinitionInfo() { IsDefaultAssembly = true, Guid = guid, Directory = new DirectoryInfo(Utilities.AssetPath) }; toReturn.assembly = assembly; toReturn.name = assembly.name; toReturn.references = assembly.assemblyReferences.Select(t => t.name).ToArray(); diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IProjectExporter.cs index c9afe75..619438d 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/IProjectExporter.cs @@ -36,7 +36,8 @@ public interface IProjectExporter /// Exports the MSBuild solution given the information. /// /// This contains parsed data about the current Unity project. - void ExportSolution(UnityProjectInfo unityProjectInfo); + /// Configuration for MSBuild tools. + void ExportSolution(UnityProjectInfo unityProjectInfo, MSBuildToolsConfig config); /// /// Generates the Directory.Build.props file that is expected to be used by both generated and non-generated projects alike. diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedProjectExporter.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedProjectExporter.cs index 5831a61..21cbe21 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedProjectExporter.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TemplatedProjectExporter.cs @@ -18,6 +18,12 @@ namespace Microsoft.Build.Unity.ProjectGeneration.Exporters public class TemplatedProjectExporter : IProjectExporter { private const string MSBuildFileSuffix = "msb4u"; + private static readonly Guid FolderProjectTypeGuid = Guid.Parse("2150E333-8FDC-42A3-9474-1A3956D46DE8"); + + private readonly Dictionary solutionProperties = new Dictionary() + { + { "HideSolutionNode", "FALSE" } + }; private readonly DirectoryInfo generatedOutputFolder; @@ -218,26 +224,350 @@ public void GenerateDirectoryPropsFile(UnityProjectInfo unityProjectInfo) } /// - public void ExportSolution(UnityProjectInfo unityProjectInfo) + public void ExportSolution(UnityProjectInfo unityProjectInfo, MSBuildToolsConfig config) { string solutionFilePath = GetSolutionFilePath(unityProjectInfo); + SolutionFileInfo solutionFileInfo = null; + + // Parse existing solution if (File.Exists(solutionFilePath)) { - File.Delete(solutionFilePath); + TextSolutionFileParser.TryParseExistingSolutionFile(solutionFilePath, out solutionFileInfo); } + ITemplatePart rootTemplatePart = solutionFileTemplate.Root; TemplateReplacementSet rootReplacementSet = rootTemplatePart.CreateReplacementSet(); - ITemplatePart projectTemplate = rootTemplatePart.Templates["PROJECT"]; - ITemplatePart folderTemplate = rootTemplatePart.Templates["FOLDER"]; + // Remove known folders & projects + if (solutionFileInfo != null) + { + solutionFileInfo.Projects.Remove(config.BuiltInPackagesFolderGuid); + solutionFileInfo.Projects.Remove(config.ImportedPackagesFolderGuid); + solutionFileInfo.Projects.Remove(config.ExternalPackagesFolderGuid); + } + + List> folderNestedItems = new List>(); + List orderedProjects = new List(); + + ProcessProjects(unityProjectInfo, config, solutionFileInfo, solutionFilePath, rootTemplatePart, rootReplacementSet, folderNestedItems, orderedProjects); + + HashSet generatedItems = new HashSet(); + + ProcessSolutionFolders(rootTemplatePart, rootReplacementSet, folderNestedItems, generatedItems, solutionFileInfo); + + // Process Solution file configurations + SortedDictionary> configPlatformMap = GetSolutionConfigurationPlatformMap(unityProjectInfo, solutionFileInfo); + ProcessSolutionConfigurationPlatform(rootTemplatePart, rootReplacementSet, configPlatformMap); + + // Process Configurations Mappings + ProcessConfigPlatformMappings(unityProjectInfo, config, rootTemplatePart, rootReplacementSet, orderedProjects, generatedItems, configPlatformMap, solutionFileInfo); + + // Write Solution Properties + ITemplatePart solutionPropertiesTemplate = rootTemplatePart.Templates["SOLUTION_PROPERTIES"]; + ProcessPropertiesSet(solutionPropertiesTemplate, rootReplacementSet, solutionProperties, solutionFileInfo?.Properties); + + // Write Extensibility Globals + Dictionary extensibilityGlobals = new Dictionary() { { "SolutionGuid", "{" + config.SolutionGuid.ToString().ToUpper() + "}" } }; + ITemplatePart extensibilityGlobalsTemplate = rootTemplatePart.Templates["EXTENSIBILITY_GLOBALS"]; + ProcessPropertiesSet(extensibilityGlobalsTemplate, rootReplacementSet, extensibilityGlobals, solutionFileInfo?.ExtensibilityGlobals); + + // Write Solution Notes + ITemplatePart solutuonNotesTemplate = rootTemplatePart.Templates["SOLUTION_NOTES"]; + Dictionary generatedDictionary = generatedItems.ToDictionary(t => "{" + t.ToString().ToUpper() + "}", t => "msb4u.generated"); + ProcessPropertiesSet(solutuonNotesTemplate, rootReplacementSet, generatedDictionary, solutionFileInfo?.SolutionNotes); + + // Write Extra Sections found in the read Solution + ProcessExtraSolutionSections(rootTemplatePart, rootReplacementSet, solutionFileInfo); + + // Export projects + foreach (CSProjectInfo project in unityProjectInfo.CSProjects.Values) + { + ExportProject(unityProjectInfo, project); + } + + GenerateTopLevelDependenciesProject(unityProjectInfo, config.DependenciesProjectGuid); + + // Delete before we write to minimize chance of just deleting in case above fails + if (File.Exists(solutionFilePath)) + { + File.Delete(solutionFilePath); + } + + solutionFileTemplate.Write(solutionFilePath, rootReplacementSet); + } + + private void ProcessExtraSolutionSections(ITemplatePart rootTemplatePart, TemplateReplacementSet rootReplacementSet, SolutionFileInfo solutionFileInfo) + { + if (solutionFileInfo != null) + { + ITemplatePart extraSectionTemplate = rootTemplatePart.Templates["EXTRA_GLOBAL_SECTION"]; + + foreach (SolutionFileSection section in solutionFileInfo.SolutionSections.Values) + { + ProcessExtraSection(extraSectionTemplate, rootReplacementSet, section.Name, section.Type == SolutionGlobalSectionType.PreSolution ? "preSolution" : "postSolution", section.Lines); + } + } + } + + private void ConfigurationTemplateReplace(ITemplatePart templatePart, TemplateReplacementSet replacementSet, Guid projectGuid, string slnConfiguration, string slnPlatform, string property, string projConfiguration, string projPlatform) + { + templatePart.Tokens["PROJECT_GUID"].AssignValue(replacementSet, projectGuid.ToString().ToUpper()); + templatePart.Tokens["SOLUTION_CONFIGURATION"].AssignValue(replacementSet, slnConfiguration); + templatePart.Tokens["SOLUTION_PLATFORM"].AssignValue(replacementSet, slnPlatform); + templatePart.Tokens["PROPERTY"].AssignValue(replacementSet, property); + templatePart.Tokens["PROJECT_CONFIGURATION"].AssignValue(replacementSet, projConfiguration); + templatePart.Tokens["PROJECT_PLATFORM"].AssignValue(replacementSet, projPlatform); + } + + private class ProjectConfigurationMapping + { + private readonly Dictionary> propertySet = new Dictionary>(); + + public SortedDictionary Mappings { get; } = new SortedDictionary(ConfigPlatformPair.Comparer.Instance); + + public HashSet GetPropertySet(ConfigPlatformPair configPair) + { + if (!propertySet.TryGetValue(configPair, out HashSet set)) + { + propertySet.Add(configPair, set = new HashSet()); + } + + return set; + } + + public void AddConfigurationMapping(ConfigPlatformPair configMapping, params string[] properties) + { + AddConfigurationMapping(configMapping, configMapping, properties); + } + + public void AddConfigurationMapping(ConfigPlatformPair solutionMapping, ConfigPlatformPair projectMapping, params string[] properties) + { + Mappings[solutionMapping] = projectMapping; + HashSet set = GetPropertySet(solutionMapping); + foreach (string property in properties) + { + set.Add(property); + } + } + } + + private void ProcessMappings(ITemplatePart configPlatformPropertyTemplate, TemplateReplacementSet rootReplacementSet, IEnumerable projectOrdering, Dictionary projectConfigMapping) + { + foreach (Guid projectGuid in projectOrdering) + { + ProjectConfigurationMapping mapping = projectConfigMapping[projectGuid]; + + foreach (KeyValuePair configSet in mapping.Mappings) + { + foreach (string property in mapping.GetPropertySet(configSet.Key)) + { + TemplateReplacementSet configMappingReplacementSet = configPlatformPropertyTemplate.CreateReplacementSet(rootReplacementSet); + ConfigurationTemplateReplace(configPlatformPropertyTemplate, configMappingReplacementSet, projectGuid, configSet.Key.Configuration, configSet.Key.Platform, property, configSet.Value.Configuration, configSet.Value.Platform); + } + } + } + } + + private void ProcessConfigPlatformMappings(UnityProjectInfo unityProjectInfo, MSBuildToolsConfig config, ITemplatePart rootTemplatePart, TemplateReplacementSet rootReplacementSet, List orderedProjects, HashSet generatedItems, SortedDictionary> configPlatformMap, SolutionFileInfo solutionFileInfo) + { + ITemplatePart configPlatformPropertyTemplate = rootTemplatePart.Templates["CONFIGURATION_PLATFORM_PROPERTY"]; + + List projectOrdering = new List(); + Dictionary projectConfigMapping = new Dictionary(); + + void ProcessDefaultMappings(ProjectConfigurationMapping mapping, Dictionary> enabledMappings) + { + // Process defaults + foreach (KeyValuePair> pair in configPlatformMap) + { + string projectConfig = pair.Key; + string defaultPlatform = null; + if (!enabledMappings.TryGetValue(projectConfig, out List enabledPlatforms) || enabledPlatforms.Count == 0) + { + KeyValuePair> enabledPair = enabledMappings.First(); + projectConfig = enabledPair.Key; + defaultPlatform = enabledPair.Value[0]; + } + + foreach (string platform in pair.Value) + { + ConfigPlatformPair slnConfigPair = new ConfigPlatformPair(pair.Key, platform); + if (!mapping.Mappings.ContainsKey(slnConfigPair)) + { + ConfigPlatformPair projectPair; + if (!(enabledPlatforms?.Contains(platform) ?? false)) + { + string platformToUse = (enabledPlatforms == null || enabledPlatforms.Count == 0) ? defaultPlatform : enabledPlatforms[0]; + projectPair = new ConfigPlatformPair(projectConfig, platformToUse); + } + else + { + projectPair = new ConfigPlatformPair(projectConfig, platform); + } + mapping.Mappings[slnConfigPair] = projectPair; + HashSet set = mapping.GetPropertySet(slnConfigPair); + set.Add("ActiveCfg"); + } + } + } + } + + // Iterate over every project + foreach (CSProjectInfo project in orderedProjects) + { + // Mark as generated item + generatedItems.Add(project.Guid); + + // Add it to the ordering List for output + projectOrdering.Add(project.Guid); + + // Create mapping container for the project + ProjectConfigurationMapping mapping = new ProjectConfigurationMapping(); + projectConfigMapping.Add(project.Guid, mapping); + + void ProcessProjectPlatforms(string configuration, IEnumerable platforms) + { + foreach (string platform in platforms) + { + mapping.AddConfigurationMapping(new ConfigPlatformPair(configuration, platform), "ActiveCfg", "Build.0"); + } + } + + List enabledInEditorPlatforms = project.InEditorPlatforms.Select(t => t.Value.Name).ToList(); + List enabledPlayerPlatforms = project.PlayerPlatforms.Select(t => t.Value.Name).ToList(); + + // Add InEditor and Player platform mappings that are enabled for build + ProcessProjectPlatforms("InEditor", enabledInEditorPlatforms); + ProcessProjectPlatforms("Player", enabledPlayerPlatforms); + + // Add all other known solution mappings, map to itself or allowed mappings + ProcessDefaultMappings(mapping, new Dictionary> { { "InEditor", enabledInEditorPlatforms }, { "Player", enabledPlayerPlatforms } }); + } + + // Process the Dependencies Project now + generatedItems.Add(config.DependenciesProjectGuid); + projectOrdering.Add(config.DependenciesProjectGuid); + + ProjectConfigurationMapping dependencyProjectMapping = new ProjectConfigurationMapping(); + projectConfigMapping.Add(config.DependenciesProjectGuid, dependencyProjectMapping); + + // Add default Release/Debug mappings + dependencyProjectMapping.AddConfigurationMapping(new ConfigPlatformPair("Debug", "Any CPU"), "ActiveCfg", "Build.0"); + dependencyProjectMapping.AddConfigurationMapping(new ConfigPlatformPair("Release", "Any CPU"), "ActiveCfg", "Build.0"); + + List anyCpuPlatform = new List { "Any CPU" }; + ProcessDefaultMappings(dependencyProjectMapping, new Dictionary> { { "Debug", anyCpuPlatform }, { "Release", anyCpuPlatform } }); + + // Process projects that we aren't generating, but were added to the solution file + if (solutionFileInfo != null) + { + foreach (KeyValuePair> pair in solutionFileInfo.ProjectConfigurationEntires) + { + if (solutionFileInfo.Projects.ContainsKey(pair.Key)) + { + projectOrdering.Add(pair.Key); + + ProjectConfigurationMapping mapping = new ProjectConfigurationMapping(); + projectConfigMapping.Add(pair.Key, mapping); + + foreach (ProjectConfigurationEntry item in pair.Value) + { + mapping.Mappings[item.SolutionConfig] = item.ProjectConfig; + mapping.GetPropertySet(item.SolutionConfig).Add(item.Property); + } + } + } + } + + ProcessMappings(configPlatformPropertyTemplate, rootReplacementSet, projectOrdering, projectConfigMapping); + } + + private void ProcessPropertiesSet(ITemplatePart solutionPropertiesTemplate, TemplateReplacementSet rootReplacementSet, Dictionary propertySet, Dictionary existingPropertySet) + { + void WriteSolutionProperty(string key, string value) + { + TemplateReplacementSet replacementSet = solutionPropertiesTemplate.CreateReplacementSet(rootReplacementSet); + solutionPropertiesTemplate.Tokens["PROPERTY_KEY"].AssignValue(replacementSet, key); + solutionPropertiesTemplate.Tokens["PROPERTY_VALUE"].AssignValue(replacementSet, value); + } + + foreach (KeyValuePair prop in propertySet) + { + WriteSolutionProperty(prop.Key, prop.Value); + } + + if (existingPropertySet != null) + { + foreach (KeyValuePair prop in existingPropertySet) + { + if (!propertySet.ContainsKey(prop.Key)) + { + WriteSolutionProperty(prop.Key, prop.Value); + } + } + } + } + + private SortedDictionary> GetSolutionConfigurationPlatformMap(UnityProjectInfo unityProjectInfo, SolutionFileInfo solutionFileInfo) + { + SortedDictionary> configPlatformMap = new SortedDictionary>(); + + void AddPairToMap(string configuration, string platform) + { + if (!configPlatformMap.TryGetValue(configuration, out SortedSet set)) + { + configPlatformMap[configuration] = set = new SortedSet(); + } + + set.Add(platform); + } + + foreach (CompilationPlatformInfo platform in unityProjectInfo.AvailablePlatforms) + { + AddPairToMap("InEditor", platform.Name); + AddPairToMap("Player", platform.Name); + } + + if (solutionFileInfo != null) + { + foreach (ConfigPlatformPair item in solutionFileInfo.ConfigPlatformPairs) + { + AddPairToMap(item.Configuration, item.Platform); + } + } + + return configPlatformMap; + } + + private void ProcessSolutionConfigurationPlatform(ITemplatePart rootTemplatePart, TemplateReplacementSet rootReplacementSet, SortedDictionary> configPlatformMap) + { ITemplatePart configPlatformTemplate = rootTemplatePart.Templates["CONFIGURATION_PLATFORM"]; - ITemplatePart configPlatformMappingTemplate = rootTemplatePart.Templates["CONFIGURATION_PLATFORM_MAPPING"]; - ITemplatePart configPlatformEnabledTemplate = rootTemplatePart.Templates["CONFIGURATION_PLATFORM_ENABLED"]; - ITemplatePart folderNestedProjectsTemplate = rootTemplatePart.Templates["FOLDER_NESTED_PROJECTS"]; + + ITemplateToken configPlatform_ConfigurationToken = configPlatformTemplate.Tokens["CONFIGURATION"]; + ITemplateToken configPlatform_PlatformToken = configPlatformTemplate.Tokens["PLATFORM"]; + + void WriteConfigPlatformMapping(string configValue, string platformValue) + { + TemplateReplacementSet replacementSet = configPlatformTemplate.CreateReplacementSet(rootReplacementSet); + configPlatform_ConfigurationToken.AssignValue(replacementSet, configValue); + configPlatform_PlatformToken.AssignValue(replacementSet, platformValue); + } + + foreach (KeyValuePair> setPair in configPlatformMap) + { + foreach (string platform in setPair.Value) + { + WriteConfigPlatformMapping(setPair.Key, platform); + } + } + } + + private void ProcessProjects(UnityProjectInfo unityProjectInfo, MSBuildToolsConfig config, SolutionFileInfo solutionFileInfo, string solutionFilePath, ITemplatePart rootTemplatePart, TemplateReplacementSet rootReplacementSet, List> folderNestedItems, List orderedProjects) + { + ITemplatePart projectTemplate = rootTemplatePart.Templates["PROJECT"]; CSProjectInfo[] unorderedProjects = unityProjectInfo.CSProjects.Select(t => t.Value).ToArray(); - List orderedProjects = new List(); while (orderedProjects.Count < unorderedProjects.Length) { @@ -265,92 +595,73 @@ public void ExportSolution(UnityProjectInfo unityProjectInfo) } } - List builtinPackages = new List(); - List importedPacakges = new List(); - List externalPackages = new List(); foreach (CSProjectInfo project in orderedProjects) { + IEnumerable> extraSections = null; + if (solutionFileInfo != null) + { + if (solutionFileInfo.Projects.TryGetValue(project.Guid, out Project existingProject)) + { + solutionFileInfo.Projects.Remove(project.Guid); + extraSections = existingProject.Sections.Values; + } + } + TemplateReplacementSet replacementSet = projectTemplate.CreateReplacementSet(rootReplacementSet); - ProcessProjectEntry(project.Name, GetProjectPath(project).FullName, project.Guid, project.ProjectDependencies, projectTemplate, replacementSet); + ProcessProjectEntry(project.Name + ".msb4u", Utilities.GetRelativePath(Path.GetDirectoryName(solutionFilePath), GetProjectPath(project).FullName), project.Guid, project.ProjectDependencies.Select(t => t.Dependency.Guid).ToList(), projectTemplate, replacementSet, extraSections); switch (project.AssemblyDefinitionInfo.AssetLocation) { case AssetLocation.BuiltInPackage: - builtinPackages.Add(project); + folderNestedItems.Add(new Tuple(project, config.BuiltInPackagesFolderGuid, "Built In Packages")); break; case AssetLocation.PackageLibraryCache: - importedPacakges.Add(project); + folderNestedItems.Add(new Tuple(project, config.ImportedPackagesFolderGuid, "Imported Packages")); break; case AssetLocation.External: - externalPackages.Add(project); + folderNestedItems.Add(new Tuple(project, config.ExternalPackagesFolderGuid, "External Packages")); break; default: break; } } // Add the "Dependencies" project - ProcessProjectEntry("Dependencies", GetProjectFilePath(Utilities.AssetPath, "Dependencies"), Guid.NewGuid(), null, projectTemplate, projectTemplate.CreateReplacementSet(rootReplacementSet)); - - PopulateFolder(folderTemplate, folderNestedProjectsTemplate, rootReplacementSet, "Built In Packages", builtinPackages); - PopulateFolder(folderTemplate, folderNestedProjectsTemplate, rootReplacementSet, "Imported Packages", importedPacakges); - PopulateFolder(folderTemplate, folderNestedProjectsTemplate, rootReplacementSet, "External Packages", externalPackages); - - ITemplateToken configPlatform_ConfigurationToken = configPlatformTemplate.Tokens["CONFIGURATION"]; - ITemplateToken configPlatform_PlatformToken = configPlatformTemplate.Tokens["PLATFORM"]; - foreach (CompilationPlatformInfo platform in unityProjectInfo.AvailablePlatforms) { - TemplateReplacementSet replacementSet = configPlatformTemplate.CreateReplacementSet(rootReplacementSet); - configPlatform_ConfigurationToken.AssignValue(replacementSet, "InEditor"); - configPlatform_PlatformToken.AssignValue(replacementSet, platform.Name); + string dependencyRelativePath = Utilities.GetRelativePath(Path.GetDirectoryName(solutionFilePath), GetProjectFilePath(Utilities.AssetPath, "Dependencies")); + IEnumerable> extraSections = null; - replacementSet = configPlatformTemplate.CreateReplacementSet(rootReplacementSet); - configPlatform_ConfigurationToken.AssignValue(replacementSet, "Player"); - configPlatform_PlatformToken.AssignValue(replacementSet, platform.Name); + if (solutionFileInfo != null) + { + if (solutionFileInfo.Projects.TryGetValue(config.DependenciesProjectGuid, out Project existingProject)) + { + solutionFileInfo.Projects.Remove(config.DependenciesProjectGuid); + extraSections = existingProject.Sections.Values; + } + } + ProcessProjectEntry("Dependencies.msb4u", dependencyRelativePath, config.DependenciesProjectGuid, null, projectTemplate, projectTemplate.CreateReplacementSet(rootReplacementSet), extraSections); } - List disabled = new List(); - - foreach (CSProjectInfo project in orderedProjects.Select(t => t)) + if (solutionFileInfo != null) { - void ConfigurationTemplateReplace(ITemplatePart templatePart, TemplateReplacementSet replacementSet, string guid, string configuration, string platform) + foreach (Guid guid in solutionFileInfo.MSB4UGeneratedItems) { - templatePart.Tokens["PROJECT_GUID"].AssignValue(replacementSet, guid.ToString().ToUpper()); - templatePart.Tokens["PROJECT_CONFIGURATION"].AssignValue(replacementSet, configuration); - templatePart.Tokens["PROJECT_PLATFORM"].AssignValue(replacementSet, platform); - templatePart.Tokens["SOLUTION_CONFIGURATION"].AssignValue(replacementSet, configuration); - templatePart.Tokens["SOLUTION_PLATFORM"].AssignValue(replacementSet, platform); + solutionFileInfo.Projects.Remove(guid); } - void ProcessMappings(Guid guid, string configuration, IReadOnlyDictionary platforms) + // Process existing projects + foreach (Project project in solutionFileInfo.Projects.Values) { - foreach (CompilationPlatformInfo platform in unityProjectInfo.AvailablePlatforms) + // Don't process folders or what we previously thought were generated projects + if (project.TypeGuid != FolderProjectTypeGuid) { - TemplateReplacementSet replacemetSet = configPlatformMappingTemplate.CreateReplacementSet(rootReplacementSet); - ConfigurationTemplateReplace(configPlatformMappingTemplate, replacemetSet, guid.ToString(), configuration, platform.Name); - - if (platforms.ContainsKey(platform.BuildTarget)) - { - replacemetSet = configPlatformEnabledTemplate.CreateReplacementSet(rootReplacementSet); - ConfigurationTemplateReplace(configPlatformEnabledTemplate, replacemetSet, guid.ToString(), configuration, platform.Name); - } + TemplateReplacementSet replacementSet = projectTemplate.CreateReplacementSet(rootReplacementSet); + ProcessProjectEntry(project.Name, project.RelativePath, project.Guid, project.Dependencies, projectTemplate, replacementSet, project.Sections.Values); } } - - ProcessMappings(project.Guid, "InEditor", project.InEditorPlatforms); - ProcessMappings(project.Guid, "Player", project.PlayerPlatforms); - } - - foreach (CSProjectInfo project in unityProjectInfo.CSProjects.Values) - { - ExportProject(unityProjectInfo, project); } - - GenerateTopLevelDependenciesProject(unityProjectInfo); - - solutionFileTemplate.Write(solutionFilePath, rootReplacementSet); } - private void GenerateTopLevelDependenciesProject(UnityProjectInfo unityProjectInfo) + private void GenerateTopLevelDependenciesProject(UnityProjectInfo unityProjectInfo, Guid dependenciesProjectGuid) { string projectPath = GetProjectFilePath(Utilities.AssetPath, "Dependencies"); string propsPath = GetProjectFilePath(generatedOutputFolder.FullName, "Dependencies").Replace(".csproj", ".g.props"); @@ -361,6 +672,8 @@ private void GenerateTopLevelDependenciesProject(UnityProjectInfo unityProjectIn TemplateReplacementSet replacementSet = propsFileTemplate.CreateReplacementSet(); + propsFileTemplate.Tokens["PROJECT_GUID"].AssignValue(replacementSet, dependenciesProjectGuid.ToString().ToUpper()); + // We use this to emulate the platform support for all Dictionary allPlatforms = unityProjectInfo.AvailablePlatforms.ToDictionary(t => t.BuildTarget, t => t); foreach (CSProjectInfo projectInfo in unityProjectInfo.CSProjects.Values) @@ -381,21 +694,63 @@ private void GenerateTopLevelDependenciesProject(UnityProjectInfo unityProjectIn } } - private void PopulateFolder(ITemplatePart folderTemplate, ITemplatePart folderNestedProjectsTemplate, TemplateReplacementSet parentReplacementSet, string folderName, List projects) + private void ProcessSolutionFolders(ITemplatePart rootTemplatePart, TemplateReplacementSet parentReplacementSet, List> folderNestedItems, HashSet generatedItems, SolutionFileInfo solutionFileInfo) { - if (projects.Count > 0) - { - string folderGuid = Guid.NewGuid().ToString().ToUpper(); + ITemplatePart folderTemplate = rootTemplatePart.Templates["FOLDER"]; + ITemplatePart folderNestedProjectsTemplate = rootTemplatePart.Templates["FOLDER_NESTED_PROJECTS"]; + void AddFolder(string name, string guid) + { TemplateReplacementSet replacementSet = folderTemplate.CreateReplacementSet(parentReplacementSet); - folderTemplate.Tokens["FOLDER_NAME"].AssignValue(replacementSet, folderName); - folderTemplate.Tokens["FOLDER_GUID"].AssignValue(replacementSet, folderGuid); + folderTemplate.Tokens["FOLDER_NAME"].AssignValue(replacementSet, name); + folderTemplate.Tokens["FOLDER_GUID"].AssignValue(replacementSet, guid); + } + + void AddNestedMapping(string parentGuid, string childGuid) + { + TemplateReplacementSet nestedReplacementSet = folderNestedProjectsTemplate.CreateReplacementSet(parentReplacementSet); + folderNestedProjectsTemplate.Tokens["FOLDER_GUID"].AssignValue(nestedReplacementSet, parentGuid); + folderNestedProjectsTemplate.Tokens["CHILD_GUID"].AssignValue(nestedReplacementSet, childGuid); + } + + HashSet addedFolders = new HashSet(); + + foreach (Tuple tuple in folderNestedItems) + { + string guidStr = tuple.Item2.ToString().ToUpper(); - foreach (CSProjectInfo project in projects) + generatedItems.Add(tuple.Item2); + + if (addedFolders.Add(guidStr)) + { + AddFolder(tuple.Item3, guidStr); + } + + Guid childGuid = tuple.Item1.Guid; + AddNestedMapping(guidStr, childGuid.ToString().ToUpper()); + if (solutionFileInfo != null) + { + solutionFileInfo.ChildToParentNestedMappings.Remove(childGuid); + } + } + + if (solutionFileInfo != null) + { + foreach (Project project in solutionFileInfo.Projects.Values) + { + if (project.TypeGuid == FolderProjectTypeGuid) + { + string guidString = project.Guid.ToString().ToUpper(); + if (addedFolders.Add(guidString)) + { + AddFolder(project.Name, guidString); + } + } + } + + foreach (KeyValuePair mapping in solutionFileInfo.ChildToParentNestedMappings) { - replacementSet = folderNestedProjectsTemplate.CreateReplacementSet(parentReplacementSet); - folderNestedProjectsTemplate.Tokens["FOLDER_GUID"].AssignValue(replacementSet, folderGuid); - folderNestedProjectsTemplate.Tokens["CHILD_GUID"].AssignValue(replacementSet, project.Guid.ToString().ToUpper()); + AddNestedMapping(mapping.Value.ToString().ToUpper(), mapping.Key.ToString().ToUpper()); } } } @@ -477,24 +832,51 @@ private List GetPlatformConditions(IReadOnlyDictionary> projectDependencies, ITemplatePart templatePart, TemplateReplacementSet replacementSet) + private void ProcessProjectEntry(string projectName, string projectRelativePath, Guid projectGuid, IReadOnlyCollection projectDependencies, ITemplatePart templatePart, TemplateReplacementSet projectReplacementSet, IEnumerable> extraSections = null) { - templatePart.Tokens["PROJECT_NAME"].AssignValue(replacementSet, projectName); - templatePart.Tokens["PROJECT_RELATIVE_PATH"].AssignValue(replacementSet, projectPath); - templatePart.Tokens["PROJECT_GUID"].AssignValue(replacementSet, projectGuid.ToString().ToUpper()); + templatePart.Tokens["PROJECT_NAME"].AssignValue(projectReplacementSet, projectName); + templatePart.Tokens["PROJECT_RELATIVE_PATH"].AssignValue(projectReplacementSet, projectRelativePath); + templatePart.Tokens["PROJECT_GUID"].AssignValue(projectReplacementSet, projectGuid.ToString().ToUpper()); - ITemplatePart dependencyTemplate = templatePart.Templates["PROJECT_DEPENDENCY"]; + ITemplatePart projectSectionTemplate = templatePart.Templates["PROJECT_SECTION"]; + ITemplatePart dependencyTemplate = projectSectionTemplate.Templates["PROJECT_DEPENDENCY"]; if (projectDependencies != null && projectDependencies.Count > 0) { - foreach (CSProjectDependency project in projectDependencies) + TemplateReplacementSet projectSectionReplacementSet = projectSectionTemplate.CreateReplacementSet(projectReplacementSet); + foreach (Guid dependencyGuid in projectDependencies) + { + TemplateReplacementSet set = dependencyTemplate.CreateReplacementSet(projectSectionReplacementSet); + dependencyTemplate.Tokens["DEPENDENCY_GUID"].AssignValue(set, dependencyGuid.ToString().ToUpper()); + } + } + + ITemplatePart extraProjectSectionTemplate = templatePart.Templates["EXTRA_PROJECT_SECTION"]; + + if (extraSections != null) + { + foreach (SolutionFileSection section in extraSections) { - TemplateReplacementSet set = dependencyTemplate.CreateReplacementSet(replacementSet); - dependencyTemplate.Tokens["DEPENDENCY_GUID"].AssignValue(set, project.Dependency.Guid.ToString().ToUpper()); + ProcessExtraSection(extraProjectSectionTemplate, projectReplacementSet, section.Name, section.Type == SolutionProjecSectionType.PreProject ? "preProject" : "postProject", section.Lines); } } } + private void ProcessExtraSection(ITemplatePart extraSectionTemplate, TemplateReplacementSet parentReplacementSet, string sectionName, string sectionType, IEnumerable sectionLines) + { + ITemplatePart extraSectionLineTemplate = extraSectionTemplate.Templates["EXTRA_SECTION_LINE"]; + + TemplateReplacementSet sectionReplacementSet = extraSectionTemplate.CreateReplacementSet(parentReplacementSet); + extraSectionTemplate.Tokens["SECTION_NAME"].AssignValue(sectionReplacementSet, sectionName); + extraSectionTemplate.Tokens["PRE_POST_SECTION"].AssignValue(sectionReplacementSet, sectionType); + + foreach (string line in sectionLines) + { + TemplateReplacementSet lineReplacementSet = extraSectionLineTemplate.CreateReplacementSet(sectionReplacementSet); + extraSectionLineTemplate.Tokens["SECTION_LINE"].AssignValue(lineReplacementSet, line); + } + } + public void ExportPlatformPropsFile(CompilationPlatformInfo platform, bool inEditorConfiguration) { string configuration = inEditorConfiguration ? "InEditor" : "Player"; diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TextSolutionFileParser.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TextSolutionFileParser.cs new file mode 100644 index 0000000..b1a2ae8 --- /dev/null +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TextSolutionFileParser.cs @@ -0,0 +1,395 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#if UNITY_EDITOR + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text.RegularExpressions; + +namespace Microsoft.Build.Unity.ProjectGeneration.Exporters +{ + internal enum SolutionProjecSectionType + { + PreProject, + PostProject + } + + internal enum SolutionGlobalSectionType + { + PreSolution, + PostSolution + } + + internal class SolutionFileInfo + { + public Dictionary Projects { get; set; } + + public Dictionary> SolutionSections { get; set; } + + public Dictionary ChildToParentNestedMappings { get; set; } + + public HashSet ConfigPlatformPairs { get; set; } + + public Dictionary Properties { get; set; } + + public Dictionary ExtensibilityGlobals { get; set; } + + public Dictionary SolutionNotes { get; set; } + + public Dictionary> ProjectConfigurationEntires { get; set; } + + public HashSet MSB4UGeneratedItems { get; set; } + } + + internal struct ConfigPlatformPair + { + public string Configuration { get; set; } + + public string Platform { get; set; } + + public ConfigPlatformPair(string configuration, string platform) + { + Configuration = configuration; + Platform = platform; + } + + public override bool Equals(object obj) + { + return obj is ConfigPlatformPair other + && Equals(Configuration, other.Configuration) + && Equals(Platform, other.Platform); + } + + public override int GetHashCode() + { + return (Configuration?.GetHashCode() ?? 0) + ^ (Platform?.GetHashCode() ?? 0); + } + + internal struct Comparer : IComparer + { + internal static Comparer Instance { get; } = new Comparer(); + + public int Compare(ConfigPlatformPair x, ConfigPlatformPair y) + { + int results = string.Compare(x.Configuration, y.Configuration); + + return results == 0 + ? string.Compare(x.Platform, y.Platform) + : results; + } + } + } + + internal struct ProjectConfigurationEntry + { + public ConfigPlatformPair SolutionConfig { get; set; } + + public ConfigPlatformPair ProjectConfig { get; set; } + + public string Property { get; set; } + } + + internal struct SolutionFileSection + { + public string Name { get; set; } + + public T Type { get; set; } + + public List Lines { get; set; } + } + + internal struct Project + { + public Guid TypeGuid { get; set; } + + public string Name { get; set; } + + public string RelativePath { get; set; } + + public Guid Guid { get; set; } + + public HashSet Dependencies { get; set; } + + public Dictionary> Sections { get; set; } + } + + internal static class TextSolutionFileParser + { + public static bool TryParseExistingSolutionFile(string path, out SolutionFileInfo solutionFileInfo) + { + try + { + solutionFileInfo = ParseExistingSolutionFile(path); + return true; + } + catch (Exception ex) + { + UnityEngine.Debug.LogError($"Failed to parse existing solution file."); + UnityEngine.Debug.LogException(ex); + + solutionFileInfo = default; + return false; + } + } + + private static SolutionFileInfo ParseExistingSolutionFile(string path) + { + Dictionary projects = new Dictionary(); + Dictionary> globalSections = new Dictionary>(); + HashSet configPlatPairs = new HashSet(); + Dictionary solutionProperties = new Dictionary(); + Dictionary extensibilityGlobals = new Dictionary(); + Dictionary solutionNotes = new Dictionary(); + Dictionary childToParentNestedMapping = new Dictionary(); + Dictionary> projectConfigurationEntries = new Dictionary>(); + + HashSet msb4uGeneratedItems = new HashSet(); + + using (StreamReader reader = new StreamReader(path)) + { + string line = string.Empty; + while (!reader.EndOfStream) + { + line = reader.ReadLine(); + if (line.StartsWith("Project")) + { + // Entered Projects section + break; + } + } + + // Read Projects + while (!reader.EndOfStream) + { + if (!line.StartsWith("Project")) + { + throw new InvalidDataException("Unexpected top level section."); + } + + Project project = ParseProjectDefinitionSection(reader, line); + projects.Add(project.Guid, project); + + line = reader.ReadLine() ?? string.Empty; + + if (line.StartsWith("Global") && line.Trim().Length == "Global".Length) + { + // Entered next part of the Global sections + break; + } + } + + // Parse Global Sections + while (!reader.EndOfStream) + { + line = reader.ReadLine().TrimStart(); + + if (line.StartsWith("EndGlobal")) + { + // Done with Global (and file) + break; + } + + // SAMPLE: GlobalSection(SolutionConfigurationPlatforms) = preSolution + string globalSectionHeaderRegex = @"GlobalSection\(([^\)]+)\)\s+=\s+(preSolution|postSolution)"; + Match match = Regex.Match(line, globalSectionHeaderRegex); + + if (!match.Success) + { + throw new InvalidDataException("Expecting Global sections."); + } + string sectionName = match.Groups[1].Captures[0].Value; + string prePostSolution = match.Groups[2].Captures[0].Value; + switch (sectionName) + { + case "SolutionConfigurationPlatforms": + ReadLinesUntil(reader, "EndGlobalSection", l => + { + string[] configPlatPair = l.Split('=')[0].Trim().Split('|'); + configPlatPairs.Add(new ConfigPlatformPair(configPlatPair[0], configPlatPair[1])); + }); + break; + case "ProjectConfigurationPlatforms": + ReadLinesUntil(reader, "EndGlobalSection", l => + { + // SAMPLE: {}.|.ActiveCfg = | + // SAMPLE: {}.|.Build.0 = | + string regex = @"{([^}]+)}\.([^\|]+)\|([^\.]+)\.([^\s]+)\s+=\s+([^\|]+)\|(.+)"; + Match configMatch = Regex.Match(l, regex); + Guid projectGuid = Guid.Parse(configMatch.Groups[1].Captures[0].Value); + if (!projectConfigurationEntries.TryGetValue(projectGuid, out List list)) + { + projectConfigurationEntries.Add(projectGuid, list = new List()); + } + + list.Add(new ProjectConfigurationEntry() + { + SolutionConfig = new ConfigPlatformPair(configMatch.Groups[2].Captures[0].Value, configMatch.Groups[3].Captures[0].Value), + ProjectConfig = new ConfigPlatformPair(configMatch.Groups[5].Captures[0].Value, configMatch.Groups[6].Captures[0].Value), + Property = configMatch.Groups[4].Captures[0].Value + }); + }); + break; + case "SolutionProperties": + ReadLinesUntil(reader, "EndGlobalSection", l => + { + string[] property = l.Split('='); + solutionProperties[property[0].Trim()] = property[1].Trim(); + }); + break; + case "NestedProjects": + ReadLinesUntil(reader, "EndGlobalSection", l => + { + string[] nestedMapping = l.Split('='); + nestedMapping[0] = nestedMapping[0].Trim(); + nestedMapping[1] = nestedMapping[1].Trim(); + + string childProject = nestedMapping[0].Substring(1, nestedMapping[0].Length - 2); + string parentProject = nestedMapping[1].Substring(1, nestedMapping[1].Length - 2); + + childToParentNestedMapping[Guid.Parse(childProject)] = Guid.Parse(parentProject); + }); + break; + case "ExtensibilityGlobals": + ReadLinesUntil(reader, "EndGlobalSection", l => + { + string[] property = l.Split('='); + extensibilityGlobals[property[0].Trim()] = property[1].Trim(); + }); + break; + case "SolutionNotes": + ReadLinesUntil(reader, "EndGlobalSection", l => + { + string[] property = l.Split('='); + string key = property[0].Trim(); + string value = property[1].Trim(); + + if (value == "msb4u.generated") + { + msb4uGeneratedItems.Add(Guid.Parse(key.Substring(1, key.Length - 2))); + } + else + { + solutionNotes[key] = value; + } + }); + break; + default: + globalSections.Add(sectionName, ReadSection(reader, sectionName, prePostSolution == "preSolution" ? SolutionGlobalSectionType.PreSolution : SolutionGlobalSectionType.PostSolution, "EndGlobalSection")); + break; + } + } + } + + return new SolutionFileInfo() + { + Projects = projects, + ChildToParentNestedMappings = childToParentNestedMapping, + ConfigPlatformPairs = configPlatPairs, + ProjectConfigurationEntires = projectConfigurationEntries, + Properties = solutionProperties, + ExtensibilityGlobals = extensibilityGlobals, + SolutionNotes = solutionNotes, + SolutionSections = globalSections, + MSB4UGeneratedItems = msb4uGeneratedItems + }; + } + + private static Project ParseProjectDefinitionSection(StreamReader reader, string line) + { + // Line is currently the "Project" line, so parse the project until EndProject + + //Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "", "", "{}" + string projectLineRegex = "Project\\(\"{" + "([^}]+)" + "}\"\\)\\s*=\\s*\"" + "([^\"]+)" + "\",\\s*\"" + "([^\"]+)" + "\",\\s*\"" + "([^\"]+)" + "\""; + Match match = Regex.Match(line, projectLineRegex); + + if (!match.Success) + { + throw new InvalidDataException("Failed to parse the project line."); + } + + string projectType = match.Groups[1].Captures[0].Value; + string projectName = match.Groups[2].Captures[0].Value; + string projectPath = match.Groups[3].Captures[0].Value; + string projectGuid = match.Groups[4].Captures[0].Value; + + Dictionary> generalProjectSections = new Dictionary>(); + HashSet dependencies = new HashSet(); + do + { + string projectSectionRegex = @"ProjectSection\(([^\)]+)\)\s*=\s*(preProject|postProject)"; + + line = reader.ReadLine().TrimStart(); + if (line.StartsWith("EndProject")) + { + // We reached end of project section, read next line and return + return new Project() + { + Dependencies = dependencies, + Guid = Guid.Parse(projectGuid), + TypeGuid = Guid.Parse(projectType), + Name = projectName, + RelativePath = projectPath, + Sections = generalProjectSections + }; + } + + match = Regex.Match(line, projectSectionRegex); + if (!match.Success) + { + throw new InvalidDataException("Invalid data in the Project, expecting a ProjectSection"); + } + + string projectSectionName = match.Groups[1].Captures[0].Value; + string prePostProject = match.Groups[2].Captures[0].Value; + + if (projectSectionName == "ProjectDependencies") + { + ReadLinesUntil(reader, "EndProjectSection", l => + { + string guid = l.Split('=')[0].Trim(); + dependencies.Add(Guid.Parse(guid.Substring(1, guid.Length - 2))); + }); + } + else + { + generalProjectSections.Add(projectSectionName, ReadSection(reader, projectSectionName, prePostProject == "preProject" ? SolutionProjecSectionType.PreProject : SolutionProjecSectionType.PostProject, "EndProjectSection")); + } + + } while (!reader.EndOfStream); + + throw new InvalidDataException("We should have already returned."); + } + + private static SolutionFileSection ReadSection(StreamReader reader, string sectionName, T sessionType, string endSectionTag) + { + List sectionLines = new List(); + + ReadLinesUntil(reader, endSectionTag, sectionLines.Add); + + return new SolutionFileSection() + { + Lines = sectionLines, + Name = sectionName, + Type = sessionType + }; + } + + private static void ReadLinesUntil(StreamReader reader, string endLine, Action processLineCallback) + { + do + { + string line = reader.ReadLine().Trim(); + if (line == endLine) + { + break; + } + + processLineCallback(line); + } while (!reader.EndOfStream); + } + } +} +#endif \ No newline at end of file diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TextSolutionFileParser.cs.meta b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TextSolutionFileParser.cs.meta new file mode 100644 index 0000000..d8173d0 --- /dev/null +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/Exporters/TextSolutionFileParser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f4c32de2ea7230142b09b7e535b33815 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs index c384397..ee344d1 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/MSBuildTools.cs @@ -17,11 +17,43 @@ namespace Microsoft.Build.Unity.ProjectGeneration { public class MSBuildToolsConfig { + private const int CurrentConfigVersion = 3; + private static string MSBuildSettingsFilePath { get; } = Path.Combine(Utilities.ProjectPath, "MSBuild", "settings.json"); + [SerializeField] + private int version = 0; + [SerializeField] private bool autoGenerateEnabled = false; + [SerializeField] + private string dependenciesProjectGuid = Guid.NewGuid().ToString(); + + [SerializeField] + private string assemblyCSharpGuid = Guid.NewGuid().ToString(); + + [SerializeField] + private string assemblyCSharpEditorGuid = Guid.NewGuid().ToString(); + + [SerializeField] + private string assemblyCSharpFirstPassGuid = Guid.NewGuid().ToString(); + + [SerializeField] + private string assemblyCSharpFirstPassEditorGuid = Guid.NewGuid().ToString(); + + [SerializeField] + private string builtInPackagesFolderGuid = Guid.NewGuid().ToString(); + + [SerializeField] + private string importedPackagesFolderGuid = Guid.NewGuid().ToString(); + + [SerializeField] + private string externalPackagesFolderGuid = Guid.NewGuid().ToString(); + + [SerializeField] + private string solutionGuid = Guid.NewGuid().ToString(); + public bool AutoGenerateEnabled { get => autoGenerateEnabled; @@ -32,6 +64,24 @@ public bool AutoGenerateEnabled } } + internal Guid DependenciesProjectGuid { get; private set; } + + internal Guid AssemblyCSharpGuid { get; private set; } + + internal Guid AssemblyCSharpEditorGuid { get; private set; } + + internal Guid AssemblyCSharpFirstPassGuid { get; private set; } + + internal Guid AssemblyCSharpFirstPassEditorGuid { get; private set; } + + internal Guid BuiltInPackagesFolderGuid { get; private set; } + + internal Guid ImportedPackagesFolderGuid { get; private set; } + + internal Guid ExternalPackagesFolderGuid { get; private set; } + + internal Guid SolutionGuid { get; private set; } + private void Save() { File.WriteAllText(MSBuildSettingsFilePath, EditorJsonUtility.ToJson(this)); @@ -46,8 +96,47 @@ public static MSBuildToolsConfig Load() EditorJsonUtility.FromJsonOverwrite(File.ReadAllText(MSBuildSettingsFilePath), toReturn); } + bool needToSave = false; + + toReturn.DependenciesProjectGuid = EnsureGuid(ref toReturn.dependenciesProjectGuid, ref needToSave); + + toReturn.AssemblyCSharpGuid = EnsureGuid(ref toReturn.assemblyCSharpGuid, ref needToSave); + toReturn.AssemblyCSharpEditorGuid = EnsureGuid(ref toReturn.assemblyCSharpEditorGuid, ref needToSave); + toReturn.AssemblyCSharpFirstPassGuid = EnsureGuid(ref toReturn.assemblyCSharpFirstPassGuid, ref needToSave); + toReturn.AssemblyCSharpFirstPassEditorGuid = EnsureGuid(ref toReturn.assemblyCSharpFirstPassEditorGuid, ref needToSave); + + toReturn.BuiltInPackagesFolderGuid = EnsureGuid(ref toReturn.builtInPackagesFolderGuid, ref needToSave); + toReturn.ImportedPackagesFolderGuid = EnsureGuid(ref toReturn.importedPackagesFolderGuid, ref needToSave); + toReturn.ExternalPackagesFolderGuid = EnsureGuid(ref toReturn.externalPackagesFolderGuid, ref needToSave); + + toReturn.SolutionGuid = EnsureGuid(ref toReturn.solutionGuid, ref needToSave); + + if (CurrentConfigVersion > toReturn.version) + { + toReturn.version = CurrentConfigVersion; + needToSave = true; + } + + if (needToSave) + { + toReturn.Save(); + } + return toReturn; } + + private static Guid EnsureGuid(ref string field, ref bool needToSave) + { + if (!Guid.TryParse(field, out Guid guid)) + { + guid = Guid.NewGuid(); + field = guid.ToString(); + + needToSave = true; + } + + return guid; + } } /// @@ -90,7 +179,7 @@ public void OnActiveBuildTargetChanged(BuildTarget previousTarget, BuildTarget n private static UnityProjectInfo unityProjectInfo; - public static UnityProjectInfo UnityProjectInfo => unityProjectInfo ?? (unityProjectInfo = new UnityProjectInfo(supportedBuildTargets)); + public static UnityProjectInfo UnityProjectInfo => unityProjectInfo ?? (unityProjectInfo = new UnityProjectInfo(supportedBuildTargets, Config)); private static IProjectExporter exporter = null; @@ -274,7 +363,7 @@ private static void RegenerateEverything(bool reparseUnityData) propsFileGenerationEnd = stopwatch.ElapsedMilliseconds; solutionExportStart = stopwatch.ElapsedMilliseconds; - RegenerateSolution(); + Exporter.ExportSolution(UnityProjectInfo, Config); solutionExportEnd = stopwatch.ElapsedMilliseconds; foreach (string otherFile in TemplateFiles.Instance.OtherFiles) @@ -295,11 +384,6 @@ private static void RegenerateEverything(bool reparseUnityData) } } - private static void RegenerateSolution() - { - Exporter.ExportSolution(UnityProjectInfo); - } - private static void GenerateBuildProjectsFile(string fileName, string solutionPath, IEnumerable compilationPlatforms) { string template = File.ReadAllText(TemplateFiles.Instance.BuildProjectsTemplatePath); diff --git a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs index af4ea3b..e97e3aa 100644 --- a/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs +++ b/Source/MSBuildTools.Unity/Packages/com.microsoft.msbuildforunity/Editor/ProjectGenerator/Scripts/UnityProjectInfo.cs @@ -61,10 +61,10 @@ public class UnityProjectInfo : IDisposable /// public IReadOnlyCollection WinMDs { get; private set; } - public UnityProjectInfo(HashSet supportedBuildTargets) + public UnityProjectInfo(HashSet supportedBuildTargets, MSBuildToolsConfig config) { AvailablePlatforms = new ReadOnlyCollection(CompilationPipeline.GetAssemblyDefinitionPlatforms() - .Where(t=> Utilities.IsPlatformInstalled(t.BuildTarget)) + .Where(t => Utilities.IsPlatformInstalled(t.BuildTarget)) .Where(t => supportedBuildTargets.Contains(t.BuildTarget)) .Select(CompilationPlatformInfo.GetCompilationPlatform) .OrderBy(t => t.Name).ToList()); @@ -79,7 +79,7 @@ public UnityProjectInfo(HashSet supportedBuildTargets) } RefreshPlugins(); - RefreshProjects(); + RefreshProjects(config); CurrentPlayerPlatform = AvailablePlatforms.First(t => t.BuildTarget == EditorUserBuildSettings.activeBuildTarget); } @@ -104,16 +104,14 @@ public void RefreshPlugins() } WinMDs = new ReadOnlyCollection(winmds); - - RefreshProjects(); } - public void RefreshProjects() + public void RefreshProjects(MSBuildToolsConfig config) { - CSProjects = new ReadOnlyDictionary(CreateUnityProjects()); + CSProjects = new ReadOnlyDictionary(CreateUnityProjects(config)); } - private Dictionary CreateUnityProjects() + private Dictionary CreateUnityProjects(MSBuildToolsConfig config) { // Not all of these will be converted to C# objects, only the ones found to be referenced Dictionary asmDefInfoMap = new Dictionary(); @@ -164,7 +162,26 @@ private Dictionary CreateUnityProjects() throw new InvalidOperationException($"Failed to retrieve AsmDef for script assembly: {pair.Key}"); } - assemblyDefinitionInfo = AssemblyDefinitionInfo.GetDefaultAssemblyCSharpInfo(pair.Value); + Guid guid; + switch (pair.Key) + { + case "Assembly-CSharp": + guid = config.AssemblyCSharpGuid; + break; + case "Assembly-CSharp-firstpass": + guid = config.AssemblyCSharpFirstPassGuid; + break; + case "Assembly-CSharp-Editor": + guid = config.AssemblyCSharpEditorGuid; + break; + case "Assembly-CSharp-Editor-firstpass": + guid = config.AssemblyCSharpFirstPassEditorGuid; + break; + default: + throw new InvalidOperationException($"Predefined assembly '{assemblyDefinitionInfo.Name}' was not recognized, this generally means it should be added to the switch statement in CSProjectInfo:GetProjectType."); + } + + assemblyDefinitionInfo = AssemblyDefinitionInfo.GetDefaultAssemblyCSharpInfo(pair.Value, guid); projectsToProcess.Enqueue(pair.Key); } else