はじめに
UnityでFlutterっぽいコードを書いて、アプリを作れるパッケージがあるという記事を見て、気になったので試してみました。
C#は5年、Dartは1~2年くらい経験があるので、本記事で紹介するパッケージを使ってみて、どこまでFlutterっぽいのか? どういう違いがあるか?などを最後にまとめています。
※本記事で紹介しているパッケージのバージョンですが、GitHubでアーカイブ化された古いバージョンのリポジトリのため、使うのは非推奨です。最新のリポジトリは以下になります。(私の環境だと使用できなかったため古いバージョンを使用しています。ご注意ください)
https://github.com/UIWidgets/com.unity.uiwidgets
作成環境
- Unity エディタバージョン 2021.3.8.f1
目次
UIWidgetsの導入
UIWidgets
とは、UnityでFlutterっぽくアプリ開発ができるパッケージの名前です。
導入はリポジトリからコードをダウンロードし、パッケージを使用したいプロジェクトのPackages
フォルダ配下に入れるだけです。
本章では、パッケージを導入 ~ 起動の確認まで説明したいと思います。
※なお、冒頭で説明した通り、導入説明は古いバージョンのパッケージの説明になりますのでご注意ください
プロジェクト作成
まずUnityでプロジェクトを作成します。
テンプレートは2D
、プロジェクト名をUIWidgetsSample
としました。
パッケージのダウンロード
Gitを使用する場合
- ターミナルを開いて、
cd
コマンドで作成した「プロジェクトフォルダ/Packages」に移動してください - 以下のコマンドを実行してください
git clone https://github.com/UnityTech/UIWidgets.git com.unity.uiwidgets
Gitを使用しない場合
-
リポジトリの
Download ZIP
からコードをダウンロードしてください。
-
ダウンロードが終わったら解凍後、作成したプロジェクトフォルダの
Packages
フォルダにコピーか移動してください。
起動の確認
シーンの設定
- Unityで作成したプロジェクトを開く
-
UIWidgets
を使いたいシーンを開き、UI‐Canvas
を追加 - 追加した
Canvas
にUI‐Panel
を追加 - 追加した
Panel
のImage
コンポーネントを削除
スクリプトの記述
- スクリプトを作成し、名前を
UIWidgetsExample
に変更します - リポジトリのREADMEにあるサンプルコードをコピペします。
using System.Collections.Generic;
using Unity.UIWidgets.animation;
using Unity.UIWidgets.engine;
using Unity.UIWidgets.foundation;
using Unity.UIWidgets.material;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.ui;
using Unity.UIWidgets.widgets;
using UnityEngine;
using FontStyle = Unity.UIWidgets.ui.FontStyle;
namespace UIWidgetsSample {
public class UIWidgetsExample : UIWidgetsPanel {
protected override void OnEnable() {
// if you want to use your own font or font icons.
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "font family name");
// load custom font with weight & style. The font weight & style corresponds to fontWeight, fontStyle of
// a TextStyle object
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to your font"), "Roboto", FontWeight.w500,
// FontStyle.italic);
// add material icons, familyName must be "Material Icons"
// FontManager.instance.addFont(Resources.Load<Font>(path: "path to material icons"), "Material Icons");
base.OnEnable();
}
protected override Widget createWidget() {
return new WidgetsApp(
home: new ExampleApp(),
pageRouteBuilder: (RouteSettings settings, WidgetBuilder builder) =>
new PageRouteBuilder(
settings: settings,
pageBuilder: (BuildContext context, Animation<float> animation,
Animation<float> secondaryAnimation) => builder(context)
)
);
}
class ExampleApp : StatefulWidget {
public ExampleApp(Key key = null) : base(key) {
}
public override State createState() {
return new ExampleState();
}
}
class ExampleState : State<ExampleApp> {
int counter = 0;
public override Widget build(BuildContext context) {
return new Column(
children: new List<Widget> {
new Text("Counter: " + this.counter),
new GestureDetector(
onTap: () => {
this.setState(()
=> {
this.counter++;
});
},
child: new Container(
padding: EdgeInsets.symmetric(20, 20),
color: Colors.blue,
child: new Text("Click Me")
)
)
}
);
}
}
}
}
起動確認
ToDoアプリっぽくする
上記だと全然Flutterっぽさがないので、FlutterっぽくToDoアプリっぽいものを作ってみました。
以下の動作を実装しています。
- タップすると項目がDoneになる
- スワイプで削除する
サンプルコード(ToDoのデータモデル)
public class ToDoData
{
public int Id { get; private set; }
public string Title { get; private set; }
public ToDoData(int id, string title)
{
Id = id;
Title = title;
}
}
サンプルコード(ToDoリストのWidget)
class ExampleApp : StatefulWidget
{
public ExampleApp(Key key = null) : base(key)
{
}
public override State createState()
{
return new ExampleState();
}
}
class ExampleState : State<ExampleApp>
{
private List<ToDoData> _toDoDatas = new List<ToDoData>()
{
new ToDoData(1, "ToDo1"),
new ToDoData(2, "ToDo2"),
new ToDoData(3, "ToDo3"),
new ToDoData(4, "ToDo4"),
new ToDoData(5, "ToDo5"),
};
public override Widget build(BuildContext context)
{
return new Scaffold(
appBar: new PreferredSize(
preferredSize: Size.fromHeight(120f),
child: new AppBar()
),
body: ListView.builder(
itemBuilder: (BuildContext context, int index) => {
var toDoData = _toDoDatas[index];
return new Dismissible(
key: new ObjectKey(toDoData.Id.ToString()),
onDismissed: (direction) => {
if (direction == DismissDirection.endToStart)
{
_toDoDatas.RemoveAt(index);
}
},
background: new Container(color: Colors.red),
child: new Card(
child: new ListTile(
title: new Text(
$"{_toDoDatas[index].Id:D4}:{_toDoDatas[index].Title}",
style: new TextStyle(fontSize: 64)
),
onTap: () => {
setState(() => { _toDoDatas[index] = new ToDoData(toDoData.Id, "Done!"); });
}
)
)
);
},
itemCount: _toDoDatas.Count
)
);
}
}
さわってみた所感
UIを記述する部分はほぼFlutterと同じで、Flutter経験者ならC#未経験でも書けそうだなと思いました。
そもそもDart
とC#
の文法が結構似ているので、自分で書いていて、インスタンスの生成にnew
をつけるかつけないかと、List
の書き方が若干違うくらいの差異しか感じなかったです。
Flutter経験者でUnityを触ってみたい人や、Unity経験者でFlutterの雰囲気を知りたい人の導入としては良さそうに思えました。
(ただがっつり勉強していくなら、このパッケージを使うよりはそれぞれの入門書などで勉強した方が良いと思います。)
あと気になった点として、動かしたときにデザインが崩れることがありました。
具体的には、FloatingActionButton
が小さく表示され、大きさを変えるとテキストのサイズが変わり、UIのバランスが変わってしまいました。
Flutterで書くのとまったく同じ書き方なのがまずかったのか、Unityでのシーンの設定がまずかったのかはわかりません。
ただFlutterの場合はプロジェクトを作成してすぐにコードを書いて開発していけますが、UIWidgets
でFlutterっぽいアプリを作る場合は、シーンの設定などしなければいけないので、その点はFlutterの知識だけではカバーできないようです。