Thursday, June 27, 2024

Godot'da Avalonia ile UI Oluşturma

Bugün ilginç bir proje ile karşılaştım. Projenin adı Estragonia. GitHub reposuna Releases · MrJul/Estragonia (github.com) buradan ulaşabilirsiniz. Projenin başlığında ise Avalonia in Godot yazmakta yani Godot uygulamasında Avalonia kütüphanesini UI oluşturma imkanı sunma amacı taşıyan bir köprü.

Kulağa hiç fena gelmediği için denemeye karar verdim. Repository'de yer alan README kısmında yer alan yönergelere göre projeyi oluşturmaya çalışalım.

İlk olarak Godot Engine'in .NET sürümünü indirelim. Godot üzerinde bir tane proje oluşturalım. Renderer kısmında Forward+ veya Mobile kullanmalıyız. Anladığım kadarıyla Compatibility şu an desteklenmiyor. Forward+'ı seçtim. Proje adını örnek olması amacıyla GodotWithAvalonia olarak belirledim.

2D Scene oluşturdum ve bu sahneye de Control node ekledim. Node'un ismini de UserInterface yapalım. Daha sonrasında UserInterface node'u seçin ve Inspector kısmında yer alan Focus bölümünde Mode değerini None yerine All yapın. Bu sayede keyboard input'ları işleyebileceğiz.

Gerekli ayarları yaptıktan sonra bu control node'una C# script ekleyelim. Script dosya ismi yine UserInterface.cs olsun. Daha sonrasında Godot solution'u VS Code ile açtım. Avalonia kurulumuna başlayabiliriz.

JLeb.Estragonia NuGet paketini projeye ekleyelim:
dotnet add package JLeb.Estragonia --version 1.1.1
Bu komutu kullanarak paketi yükleyebiliriz. .csproj uzantılı dosyayı kontrol ettiğimde paketin yüklendiğini anlıyorum:
<Project Sdk="Godot.NET.Sdk/4.2.2">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
    <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'ios' ">net8.0</TargetFramework>
    <EnableDynamicLoading>true</EnableDynamicLoading>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="JLeb.Estragonia" Version="1.1.1" />
  </ItemGroup>
</Project>
Ayrıca Avalonia Nuget theme paketini yüklememiz gerekiyor. Projenin geliştiricisi bunun sebebini, diğer türlü Avalonia'dan görüntü alamayız olarak belirtmiş.
dotnet add package Avalonia.Themes.Fluent --version 11.0.11
Gerekli paketleri yükledikten sonra UserInterface.cs script'ine dönelim ve sınıfın miras aldığı sınıfı JLeb.Estragonia.AvaloniaControl olarak değiştirelim. _Ready ve _Process metotları aşağıdaki gibi olsun:
using Godot;
using System;

public partial class UserInterface : JLeb.Estragonia.AvaloniaControl
{
    public override void _Ready()
    {
		
    }

    public override void _Process(double delta)
    {
        
    }
    // Called when the node enters the scene tree for the first time.

}
Avalonia projesinde olduğu gibi Estragonia'da Avalonia.Application'dan türetilmiş bir sınıfa ihtiyaç duyuyor. O sebeple App adında bir sınıf oluşturalım. Bunu XAML veya C# olarak oluşturmak size kalmış. Ben XAML üzerinden ilerleyeceğim:
App.axaml:
<Application
	xmlns="https://github.com/avaloniaui"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
	x:Class="GodotWithAvalonia.App">

	<Application.Styles>
		<FluentTheme />
	</Application.Styles>

<Application>
App.axaml.cs:
using Avalonia;
using Avalonia.Markup.Xaml;

namespace GodotWithAvalonia;

public class App : Application {

	public override void Initialize()
		=> AvaloniaXamlLoader.Load(this);
}
Avalonia'ı başlatmak için AppBuilder.Configure<App>.UseGodot().SetupWithoutStarting() kullanmamız gerek. Bunu tüm AvaloniaControl nesnelerinde tek tek kullanmamız gerekiyor _Ready metodunda ama bunun yerine Godot'da singleton anlamına gelen autoload ile tek bir yerden başlatabiliriz.Öncelikle AvaloniaLoader adında bir sınıf(AvaloniaLoader.cs) oluşturalım:
using Avalonia;
using Godot;
using JLeb.Estragonia;

namespace GodotWithAvalonia;

public partial class AvaloniaLoader : Node {
	public override void _Ready()
		=> AppBuilder
			.Configure<App>()
			.UseGodot()
			.SetupWithoutStarting();
}
Daha sonrasında ise project.godot dosyasına Autoload'u aşağıda gibi ekliyorum:
...

[application]

config/name="GodotWithAvalonia"
run/main_scene="res://main_scene.tscn"
config/features=PackedStringArray("4.2", "C#", "Forward Plus")
config/icon="res://icon.svg"

[autoload]

AvaloniaLoader="res://UI/AvaloniaLoader.cs"

[dotnet]

project/assembly_name="GodotWithAvalonia"
Test amaçlı bir TestView adında bir Avalonia View (Avalonia UserControl) oluşturalım:
TestView.axaml:
<UserControl xmlns="https://github.com/avaloniaui"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="GodotWithAvalonia.TestView">
	<TextBlock Text="Merhaba Godot!" />
</UserControl>
TestView.axaml.cs:
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;

namespace GodotWithAvalonia;

public partial class TestView : UserControl
{
    public TestView()
    {
        InitializeComponent();
    }
}
Daha sonrasında oluşturduğumuz UserControl'u _Ready metotunda çağıralım:
using Godot;
using GodotWithAvalonia;
using System;

public partial class UserInterface : JLeb.Estragonia.AvaloniaControl
{
    public override void _Ready()
    {
		Control = new TestView();

        base._Ready();
    }

    public override void _Process(double delta)
    {
        base._Process(delta);
    }
}
Şimdi projeyi çalıştıralım:
Avalonia in Godot

Kaynakça:

No comments:

Post a Comment