GodotSharp.SourceGenerators icon indicating copy to clipboard operation
GodotSharp.SourceGenerators copied to clipboard

[OnInstantiate] does not search all project scene files

Open valkyrienyanko opened this issue 1 year ago • 6 comments

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 a res://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] in UIOptions.cs. This is because there is no UIOptions.tscn file in this path as its located under res://Scenes not res://Scripts.

Error: Cannot open file 'res://Template/Scripts/UI/Options/UIOptions.tscn'.

Actual Scene Path: res://Scenes/Prefabs/UI/options.tscn Actual Script Path: res://Template/Scripts/UI/Options/UIOptions.cs

valkyrienyanko avatar Sep 22 '24 16:09 valkyrienyanko

I've made the decision to refactor my project to make it so all scripts are right next to their respective scene files.

valkyrienyanko avatar Sep 22 '24 17:09 valkyrienyanko

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...)

Cat-Lips avatar Sep 23 '24 01:09 Cat-Lips

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
         }
}

Example of how I use AdditionalFiles

valkyrienyanko avatar Sep 23 '24 01:09 valkyrienyanko

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)

Cat-Lips avatar Sep 24 '24 01:09 Cat-Lips

Anyway, I'll see what I can do to fix this for you.

Cat-Lips avatar Sep 24 '24 01:09 Cat-Lips

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

Cat-Lips avatar Sep 24 '24 02:09 Cat-Lips

Hi Valk. You happy for me to close this issue?

Cat-Lips avatar Nov 24 '24 06:11 Cat-Lips

I've gotten use to putting my scripts next to scene files.

valkyrienyanko avatar Nov 24 '24 16:11 valkyrienyanko

Thanks bud

Cat-Lips avatar Nov 24 '24 23:11 Cat-Lips