Search Unity

Local package and directory structure in Visual Studio solution

Discussion in 'Package Manager' started by Tom-Atom, Jul 10, 2019.

  1. Tom-Atom

    Tom-Atom

    Joined:
    Jun 29, 2014
    Posts:
    37
    Hi,

    I successfully created local package with some common code and added it into my project. I can also see it in Visual Studio 2017 solution of that project. Unfortunately, folder structure is not preserved.

    Original folder structure looks like this on disk:
    FolderStructure.png

    Structure of package in Visual Studio (inside solution of Unity project using package) looks like this:
    VSStructure.png

    Is there any way how to preserve structure of folders?
    Is it Unity problem (like generating .csproj file for package)? Or is it VS problem?


    OK... I played a bit with .csproj file befeore sending this question and it seems that .csproj can be generated better to preserve folders.
    Currently, this is how part of .csproj file looks:

    <ItemGroup>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\AbstractGeneratorRequest.cs" />
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\AbstractMapGenerator.cs" />
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\BspNode.cs" />
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\BspNodeFactory.cs" />
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\Interfaces\IBspNodeFactory.cs" />
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\Interfaces\IGeneratorRequest.cs" />
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\Interfaces\IGeneratorResult.cs" />
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\ScriptableObjects\AbstractGeneratorParameters.cs" />


    If it was generated with small change like this:

    <ItemGroup>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\AbstractGeneratorRequest.cs">
    <Link>Runtime\AbstractGeneratorRequest.cs</Link>
    </Compile>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\AbstractMapGenerator.cs" >
    <Link>Runtime\AbstractMapGenerator.cs</Link>
    </Compile>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\BspNode.cs" >
    <Link>Runtime\BspNode.cs</Link>
    </Compile>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\BspNodeFactory.cs" >
    <Link>Runtime\BspNodeFactory.cs</Link>
    </Compile>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\Interfaces\IBspNodeFactory.cs" >
    <Link>Runtime\Interfaces\IBspNodeFactory.cs</Link>
    </Compile>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\Interfaces\IGeneratorRequest.cs" >
    <Link>Runtime\Interfaces\IGeneratorRequest.cs</Link>
    </Compile>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\Interfaces\IGeneratorResult.cs" >
    <Link>Runtime\Interfaces\IGeneratorResult.cs</Link>
    </Compile>
    <Compile Include="D:\MyUnityApps\_Common_\BSPMapGenerator\Runtime\ScriptableObjects\AbstractGeneratorParameters.cs" >
    <Link>Runtime\ScriptableObjects\AbstractGeneratorParameters.cs</Link>
    </Compile>


    Then code structure in Visual Studio looks like this - with folders srtucture preserved:
    NiceVSStructure.png

    Unfortunately, it is not preseved between Unity launches - next time, you run Unity, it is overwritten with original version without Link tag...

    Any chance you could change how .csproj is generated?
     
    Last edited: Jul 10, 2019
  2. okcompute_unity

    okcompute_unity

    Unity Technologies

    Joined:
    Jan 16, 2017
    Posts:
    573
    Hi @Tom-Atom ,

    Let's me reach out the Microsoft's VSTU team and see what we can do.

    Regards,

    Pascal
     
  3. okcompute_unity

    okcompute_unity

    Unity Technologies

    Joined:
    Jan 16, 2017
    Posts:
    573
  4. Tom-Atom

    Tom-Atom

    Joined:
    Jun 29, 2014
    Posts:
    37
    Hi Pascal,

    thanks for answer! Yes, it helped. I created little script - anyone interested can get it below (must be placed in Editor folder, name it as you want). It adds Link element under Compile elements in .csproj file.

    Here are some important points:
    - it is called on every .csproj in project. I am using it only for my custom packages and name of all these begin with SBC, like SBC.BSPMapGenerator. ProcessFile method decides, which .csproj files need adjustemtns (those, that begin with "SBC."
    - value of added link attribute is part of original file path. To know, which part of path to cut out I am looking for part beginning either with \Editor\ or \Runtime\. These are folder names recommended by Unity (see https://docs.unity3d.com/Manual/cus-layout.html)

    Best Regards,
    Tomas

    Code (CSharp):
    1. #if ENABLE_VSTU
    2.  
    3. using System.IO;
    4. using System.Text;
    5. using System.Xml.Linq;
    6.  
    7. using UnityEditor;
    8.  
    9. using SyntaxTree.VisualStudio.Unity.Bridge;
    10. using System.Text.RegularExpressions;
    11. using System.Collections.Generic;
    12.  
    13. [InitializeOnLoad]
    14. public class ProjectFileHook {
    15.  
    16.     // necessary for XLinq to save the xml project file in utf8
    17.     class Utf8StringWriter : StringWriter {
    18.  
    19.         // -----------------------------------------------------------
    20.         public override Encoding Encoding {
    21.             get { return Encoding.UTF8; }
    22.         }
    23.     }
    24.  
    25.     // -----------------------------------------------------------
    26.     static ProjectFileHook() {
    27.  
    28.         ProjectFilesGenerator.ProjectFileGeneration += (string name, string content) => {
    29.  
    30.             // process only file beginning SBC - my custom packages
    31.             if (!ProcessFile(name)) {
    32.                 return content;
    33.             }
    34.  
    35.             // parse the document and make some changes
    36.             XDocument document = XDocument.Parse(content);
    37.             AdjustDocument(document);
    38.  
    39.             // save the changes using the Utf8StringWriter
    40.             Utf8StringWriter str = new Utf8StringWriter();
    41.             document.Save(str);
    42.  
    43.             return str.ToString();
    44.         };
    45.     }
    46.  
    47.     // -----------------------------------------------------------
    48.     static bool ProcessFile(string name) {
    49.  
    50.         Regex regex = new Regex(@"[\/\\]SBC\..*\.csproj$");
    51.         Match match = regex.Match(name);
    52.  
    53.         return match.Success;
    54.     }
    55.  
    56.     // -----------------------------------------------------------
    57.     static void AdjustDocument(XDocument document) {
    58.  
    59.         // get namespace of document
    60.         XNamespace ns = document.Root.Name.Namespace;
    61.  
    62.         // get all Compile elements
    63.         IEnumerable<XElement> compileElements = document.Root.Descendants(ns + "Compile");
    64.  
    65.         // regex to find which part of Include attribute of Compile element to use for Link element value
    66.         // check for Editor or Runtime (recommended folders: https://docs.unity3d.com/Manual/cus-layout.html)
    67.         Regex regex = new Regex(@"\\(Runtime|Editor)\\.*\.cs$");
    68.  
    69.         // add child Link element to each Compile element
    70.         foreach (XElement el in compileElements) {
    71.  
    72.             string fileName = el.Attribute("Include").Value;
    73.  
    74.             Match match = regex.Match(fileName);
    75.  
    76.             if (match.Success) {
    77.  
    78.                 // substr from 1 to exclude initial slash character
    79.                 XElement link = new XElement(ns + "Link") {
    80.                     Value = match.Value.Substring(1)
    81.                 };
    82.  
    83.                 el.Add(link);
    84.             }
    85.         }
    86.     }
    87. }
    88.  
    89. #endif
    90.  
     
    Last edited: Jul 12, 2019
    okcompute_unity likes this.