Open valkyrienyanko opened 1 month ago
I've made the decision to refactor my project to make it so all scripts are right next to their respective scene files.
Yes, true. I have an alternate path for tscn parsing on SceneTree, but not for any other attribute. It would suck having to specify an alternative for all these attribute-based generators, so unfortunately this paradigm does tend to lend itself to grouping scene files with source code.
If it helps, I nest my tscn/tres files under my cs files in Visual Studio: https://github.com/Cat-Lips/F00F (see .filenesting.json)
(Of course, also open to any ideas about how to better support separation of scenes and source if that's what is preferred...)
You could tell users to include the following in their main Godot .csproj
file.
<ItemGroup>
<AdditionalFiles Include="**\*.tscn" />
</ItemGroup>
And then you could loop through each .tscn
file in your source generator and parse it.
[Generator]
public class SourceGen: ISourceGenerator
{
public void Execute(GeneratorExecutionContext context)
{
// Get all additional text files
IEnumerable<AdditionalText> tscnFiles = context.AdditionalFiles
.Where(file => Path.GetExtension(file.Path)
.Equals(".tscn", StringComparison.OrdinalIgnoreCase));
// Do something with tscnFiles here
}
}
Ok, great. By providing the additional files to a source generator, it can find the matching tscn. But in your case, I've just realised that the names are different (options.tscn/UIOptions.cs), so even if they were in the same folder or using an additional files lookup, we'd probably still need to use an attribute property...
If the name and path is the same, it's easy to replace the extension to get the scene file, eg:
public static T GetScene<T>() where T : GodotObject
=> LoadScene<T>().Instantiate<T>();
public static PackedScene LoadScene<T>() where T : GodotObject
=> GD.Load<PackedScene>(GetScriptPath<T>().Replace(".cs", ".tscn"));
public static string GetScriptPath<T>() where T : GodotObject
=> typeof(T).GetCustomAttribute<ScriptPathAttribute>(false).Path;
(https://github.com/Cat-Lips/F00F.Core/blob/main/addons/F00F.Core/Utilities/Utils.cs)
Anyway, I'll see what I can do to fix this for you.
But in your case, I've just realised that the names are different (options.tscn/UIOptions.cs), so even if they were in the same folder or using an additional files lookup, we'd probably still need to use an attribute property...
Or... could parse tscn files to get cs path and create a static lookup
My project is setup so scripts are separate from scene files
I have always organized my project by having a
res://Scenes
folder for all.tscn
files and ares://Scripts
folder for all.cs
files. I'm not sure how I feel about keeping the.tscn
files next to the.cs
files. I might just refactor my entire projects file structure just to use this attribute.The Issue
I get the following error when I try to use
[OnInstantiate]
inUIOptions.cs
. This is because there is noUIOptions.tscn
file in this path as its located underres://Scenes
notres://Scripts
.Actual Scene Path:
res://Scenes/Prefabs/UI/options.tscn
Actual Script Path:res://Template/Scripts/UI/Options/UIOptions.cs