FlutterからUnityにCSVDataを送る 1.Flutter側
これはリスクのある方法です
Flutterをfrontとして、backendはServerpodで、
userが協働して作るDatabaseを構築中。
Flutterでデータを登録、検索、検索結果の表示もする。
じゃ、Unityはなんなんだというと、Databaseを三次元空間として表示する。
その三次元空間内を動き回ることもできる。
つまり、大きな図書館内を歩き回るように、Databaseの中を歩き回る。
それでともかく、FlutterからUnityにDataを送りたい。
Flutterのアプリ上で、これ、Unityで見たいぞ、となったら、
ボタン一つでDataを抱えてUnityに飛びたい。
そんなことできるか、と爺様に聞くと、できる、という。
ただし、推奨しない、という。
データ量に制限があるし、セキュリティ面の問題もあるという。
推奨されないのに、あえてやる理由
今、どういう状況か。
表示画面としてのUnityはfirebaseHostingで公開されている。
一方、ServerpodのProjectとして制作中のFlutterアプリは、
まだuploadできていない。
Serverpodが「近日Upgrade!」というから、それを待っている。
uploadしたら、ServerpodにはWebServerがついているので、
Unityもそこにdeployできる。
serverを介して、Dataのやりとりができる。
が、現状ではそれができない。
ともかく、Dataを受け取って、表示できるか、その実験のために
推奨されない方法を、あえてとろうというわけ。
手順
- 検索結果をListとして取得
- ListをCSVにconvert
- CSVをUriにencode
- encodeしたDataを含むUrlをつかって、url_launcherで飛ぶ
紆余曲折
いきなりUnityがうまく開いて、おおおっ! ってなったが、
よく見たら関数がうまく書けてなくて、肝心の検索結果が空だった。
なので、ふつうのUrlでふつうに飛んだだけ、なのですぐに開いた。
関数を書き直したら、当然のように飛べなかった。
Urlが長すぎますって書いてある。
やっぱそうだよねえ、と、妙に納得。
でも、今回もよく見たら、これはこれで関数のミスで、
絞り込まれずに百件ものDataがencodeされている。
うーん、将来serverで繋がったら百件送ることもあるだろうけど、
今はそんなに要らん。
で、また関数を書き直して、うまく十件に絞り込んだら、
おおおおっ! ちゃんとUnityが開いたではないか!
拒否られなかったとはいえ、結構長いUrlだ。
まあ、十件、実験、ちょうどいい。
十件って、正しい日本語ではじゅっけん、じゃなく、じっけんって発音するって知ってました?
もちろん、これは実験なのだから、50件はいけるか、とか、25件はどうか、とか
やってみてもよいのだけれど、今日はここまでにする。
記事としてはムダなコードも入ってるけど
これ以上もの考える力が残っていないので、全部貼り付けました(゚゚)(。。)ペコッ。
import 'package:acorn_client/acorn_client.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
import '../search/multiple_search_page.dart';
class FourDViewPage extends StatefulWidget {
final List<int>? principalIds;
const FourDViewPage({super.key, this.principalIds});
_FourDViewPageState createState() => _FourDViewPageState();
}
class _FourDViewPageState extends State<FourDViewPage> {
List<WithGlobe> withGlobes = [];
void initState() {
super.initState();
}
///前ページでの検索結果をもとに、Unityに送るべきListを取得する。
Future<void>fetchWithGlobe({List<int>? principalIds}) async {
try {
withGlobes = await client.withGlobe.getWithGlobe(keyNumbers: widget.principalIds);
print('fetch with $principalIds');
} catch (e) {
debugPrint('$e');
}
}
///取得したListをCsvに変換する。
String convertListGlobeToCsv(List<WithGlobe> withGlobes) {
if (withGlobes.isEmpty) return '';
List<String> rows = [];
rows.add('annee, affair, location, precise, x_coordinate, y_coordinate, z_coordinate, coefficient');
for (var withGlobe in withGlobes) {
List<dynamic> row = [
withGlobe.annee,
withGlobe.affair,
withGlobe.location,
withGlobe.precise,
withGlobe.x_coordinate,
withGlobe.y_coordinate,
withGlobe.z_coordinate,
withGlobe.coefficient,
];
rows.add(row.join(','));
}
return rows.join('\n');
}
///変換したCSVDataをUriにencodeし、さらにurlとしてparseして飛ぶ。
Future onLaunchUrl() async {
String csvGlobe = convertListGlobeToCsv(withGlobes);
print(withGlobes);
String encodedCsvGlobe = Uri.encodeComponent(csvGlobe);
print(encodedCsvGlobe);
final Uri url = Uri.parse('https://tempo-spaco.web.app?data=$encodedCsvGlobe');
if (await canLaunchUrl(url)) {
await launchUrl(url);
}
}
Widget build(BuildContext context) {
return Center(
child: Scaffold(
appBar: AppBar(
leading: IconButton(
icon:const Icon(Icons.arrow_back),
onPressed: () {
Navigator.push<String>(
context,
MaterialPageRoute(
builder: (context) => MultiSearchPage(),
),
);
},
),
title: const Text('4D VIEW'),
),
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: FloatingActionButton.extended(
onPressed: () async {
///Listを取得する。
await fetchWithGlobe(principalIds: widget.principalIds);
///飛ぶ。
onLaunchUrl();
},
label: const Text ('Jump for Unity')),
),
body: Container(
constraints: const BoxConstraints.expand( ),
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/images/4d.png'),
fit: BoxFit.cover,
),
),
),
),
);
}
}
flutter unity widgetがあるでしょう!?
知ってはいるけど・・・今回は却下。
Unityで遊んでみてください
Discussion