Merge pull request #29 from thomas-stockx/fix/android_unity_to_flutter

Fix/android unity to flutter
This commit is contained in:
Rex Raphael 2019-08-10 15:04:13 +02:00 committed by GitHub
commit e739f40c50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 24280 additions and 36 deletions

View File

@ -160,11 +160,11 @@ If you want to use Unity for integrating Augmented Reality in your Flutter app,
### Add UnityMessageManager Support
Copy [`UnityMessageManager.cs`](https://github.com/snowballdigital/flutter-unity-view-widget/blob/master/example/Unity/Assets/UnityMessageManager.cs) to your unity project.
Copy [`UnityMessageManager.cs`](https://github.com/snowballdigital/flutter-unity-view-widget/tree/master/scripts/UnityMessageManager.cs) to your unity project.
Copy this folder [`JsonDotNet`](https://github.com/snowballdigital/flutter-unity-view-widget/tree/master/example/Unity/Assets/JsonDotNet) to your unity project.
Copy this folder [`JsonDotNet`](https://github.com/snowballdigital/flutter-unity-view-widget/tree/master/scripts/JsonDotNet) to your unity project.
Copy [`link.xml`](https://github.com/snowballdigital/flutter-unity-view-widget/blob/master/example/Unity/Assets/link.xml) to your unity project.
Copy [`link.xml`](https://github.com/snowballdigital/flutter-unity-view-widget/tree/master/scripts/link.xml) to your unity project.
<br />

View File

@ -64,10 +64,6 @@ public class FlutterUnityView implements PlatformView, MethodChannel.MethodCallH
methodName = methodCall.argument("methodName");
message = methodCall.argument("message");
System.out.print(gameObject);
System.out.print(methodName);
System.out.print(message);
UnityUtils.postMessage(gameObject, methodName, message);
result.success(true);
break;
@ -130,8 +126,12 @@ public class FlutterUnityView implements PlatformView, MethodChannel.MethodCallH
}
@Override
public void onMessage(String message) {
getChannel().invokeMethod("onUnityMessage", message);
public void onMessage(final String message) {
activity.runOnUiThread(new Runnable() {
public void run() {
getChannel().invokeMethod("onUnityMessage", message);
}
});
}
private MethodChannel getChannel() {

View File

@ -7,41 +7,35 @@ import 'package:flutter/services.dart';
typedef void UnityWidgetCreatedCallback(UnityWidgetController controller);
class UnityWidgetController {
UnityWidget _widget;
int _id;
static MethodChannel _channel = const MethodChannel('unity_view');
final _UnityWidgetState _unityWidgetState;
final MethodChannel channel;
UnityWidgetController(int id, UnityWidget widget) {
_id = id;
_channel.setMethodCallHandler(_handleMethod);
_channel = new MethodChannel('unity_view_$id');
_channel.setMethodCallHandler(_handleMethod);
print('********************************************');
print('Controller setup complete');
print('********************************************');
UnityWidgetController._(
this.channel,
this._unityWidgetState,
) {
channel.setMethodCallHandler(_handleMethod);
}
init(int id) {
_id = id;
_channel = new MethodChannel('unity_view_$id');
_channel.setMethodCallHandler(_handleMethod);
print('********************************************');
print('Controller setup complete');
print('********************************************');
static UnityWidgetController init(int id, _UnityWidgetState unityWidgetState) {
final MethodChannel channel = MethodChannel('unity_view_$id');
return UnityWidgetController._(
channel, unityWidgetState,
);
}
Future<bool> isReady() async {
final bool isReady = await _channel.invokeMethod('isReady');
final bool isReady = await channel.invokeMethod('isReady');
return isReady;
}
Future<bool> createUnity() async {
final bool isReady = await _channel.invokeMethod('createUnity');
final bool isReady = await channel.invokeMethod('createUnity');
return isReady;
}
postMessage(String gameObject, methodName, message) {
_channel.invokeMethod('postMessage', <String, dynamic>{
channel.invokeMethod('postMessage', <String, dynamic>{
'gameObject': gameObject,
'methodName': methodName,
'message': message,
@ -50,22 +44,23 @@ class UnityWidgetController {
pause() async {
print('Pressed paused');
await _channel.invokeMethod('pause');
await channel.invokeMethod('pause');
}
resume() async {
await _channel.invokeMethod('resume');
await channel.invokeMethod('resume');
}
Future<void> _dispose() async {
await _channel.invokeMethod('dispose');
await channel.invokeMethod('dispose');
}
Future<dynamic> _handleMethod(MethodCall call) async {
switch (call.method) {
case "onUnityMessage":
dynamic handler = call.arguments["handler"];
if (_widget != null) _widget.onUnityMessage(this, handler);
if (_unityWidgetState.widget != null) {
_unityWidgetState.widget.onUnityMessage(this, call.arguments);
}
break;
default:
throw UnimplementedError("Unimplemented ${call.method} method");
@ -140,9 +135,12 @@ class _UnityWidgetState extends State<UnityWidget> {
}
void _onPlatformViewCreated(int id) {
_controller = UnityWidgetController(id, widget);
_controller = UnityWidgetController.init(id, this);
if (widget.onUnityViewCreated != null) {
widget.onUnityViewCreated(_controller);
}
print('********************************************');
print('Controller setup complete');
print('********************************************');
}
}

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8" ?>
<linker>
<assembly fullname="System">
<type fullname="System.ComponentModel.TypeConverter" preserve="all" />
<!-- <namespace fullname="System.ComponentModel" preserve="all" /> -->
</assembly>
</linker>

View File

@ -0,0 +1,175 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using UnityEngine;
public class MessageHandler
{
public int id;
public string seq;
public String name;
private JToken data;
public static MessageHandler Deserialize(string message)
{
JObject m = JObject.Parse(message);
MessageHandler handler = new MessageHandler(
m.GetValue("id").Value<int>(),
m.GetValue("seq").Value<string>(),
m.GetValue("name").Value<string>(),
m.GetValue("data")
);
return handler;
}
public T getData<T>()
{
return data.Value<T>();
}
public MessageHandler(int id, string seq, string name, JToken data)
{
this.id = id;
this.seq = seq;
this.name = name;
this.data = data;
}
public void send(object data)
{
JObject o = JObject.FromObject(new
{
id = id,
seq = "end",
name = name,
data = data
});
UnityMessageManager.Instance.SendMessageToFlutter(UnityMessageManager.MessagePrefix + o.ToString());
}
}
public class UnityMessage
{
public String name;
public JObject data;
public Action<object> callBack;
}
public class UnityMessageManager : MonoBehaviour
{
#if UNITY_IOS && !UNITY_EDITOR
[DllImport("__Internal")]
private static extern void onUnityMessage(string message);
#endif
public const string MessagePrefix = "@UnityMessage@";
private static int ID = 0;
private static int generateId()
{
ID = ID + 1;
return ID;
}
public static UnityMessageManager Instance { get; private set; }
public delegate void MessageDelegate(string message);
public event MessageDelegate OnMessage;
public delegate void MessageHandlerDelegate(MessageHandler handler);
public event MessageHandlerDelegate OnFlutterMessage;
private Dictionary<int, UnityMessage> waitCallbackMessageMap = new Dictionary<int, UnityMessage>();
static UnityMessageManager()
{
GameObject go = new GameObject("UnityMessageManager");
DontDestroyOnLoad(go);
Instance = go.AddComponent<UnityMessageManager>();
}
void Awake()
{
}
public void SendMessageToFlutter(string message)
{
if (Application.platform == RuntimePlatform.Android)
{
using (AndroidJavaClass jc = new AndroidJavaClass("com.rexraphael.flutterunitywidget.UnityUtils"))
{
jc.CallStatic("onUnityMessage", message);
}
}
else if (Application.platform == RuntimePlatform.IPhonePlayer)
{
#if UNITY_IOS && !UNITY_EDITOR
onUnityMessage(message);
#endif
}
}
public void SendMessageToFlutter(UnityMessage message)
{
int id = generateId();
if (message.callBack != null)
{
waitCallbackMessageMap.Add(id, message);
}
JObject o = JObject.FromObject(new
{
id = id,
seq = message.callBack != null ? "start" : "",
name = message.name,
data = message.data
});
UnityMessageManager.Instance.SendMessageToFlutter(MessagePrefix + o.ToString());
}
void onMessage(string message)
{
if (OnMessage != null)
{
OnMessage(message);
}
}
void onFlutterMessage(string message)
{
if (message.StartsWith(MessagePrefix))
{
message = message.Replace(MessagePrefix, "");
}
else
{
return;
}
MessageHandler handler = MessageHandler.Deserialize(message);
if ("end".Equals(handler.seq))
{
// handle callback message
UnityMessage m;
if (waitCallbackMessageMap.TryGetValue(handler.id, out m))
{
waitCallbackMessageMap.Remove(handler.id);
if (m.callBack != null)
{
m.callBack(handler.getData<object>()); // todo
}
}
return;
}
if (OnFlutterMessage != null)
{
OnFlutterMessage(handler);
}
}
}

32
scripts/link.xml Normal file
View File

@ -0,0 +1,32 @@
<linker>
<!-- The following assemblies contain namespaces that should be fully preserved
even when assembly stripping is used. Not excluding the assemblies below from
stripping can result in crashes or various exceptions. -->
<assembly fullname="System">
<type fullname="System.ComponentModel.TypeConverter" preserve="all"/>
<type fullname="System.ComponentModel.ArrayConverter" preserve="all"/>
<type fullname="System.ComponentModel.BaseNumberConverter" preserve="all"/>
<type fullname="System.ComponentModel.BooleanConverter" preserve="all"/>
<type fullname="System.ComponentModel.ByteConverter" preserve="all"/>
<type fullname="System.ComponentModel.CharConverter" preserve="all"/>
<type fullname="System.ComponentModel.CollectionConverter" preserve="all"/>
<type fullname="System.ComponentModel.ComponentConverter" preserve="all"/>
<type fullname="System.ComponentModel.CultureInfoConverter" preserve="all"/>
<type fullname="System.ComponentModel.DateTimeConverter" preserve="all"/>
<type fullname="System.ComponentModel.DecimalConverter" preserve="all"/>
<type fullname="System.ComponentModel.DoubleConverter" preserve="all"/>
<type fullname="System.ComponentModel.EnumConverter" preserve="all"/>
<type fullname="System.ComponentModel.ExpandableObjectConverter" preserve="all"/>
<type fullname="System.ComponentModel.Int16Converter" preserve="all"/>
<type fullname="System.ComponentModel.Int32Converter" preserve="all"/>
<type fullname="System.ComponentModel.Int64Converter" preserve="all"/>
<type fullname="System.ComponentModel.NullableConverter" preserve="all"/>
<type fullname="System.ComponentModel.SByteConverter" preserve="all"/>
<type fullname="System.ComponentModel.SingleConverter" preserve="all"/>
<type fullname="System.ComponentModel.StringConverter" preserve="all"/>
<type fullname="System.ComponentModel.TimeSpanConverter" preserve="all"/>
<type fullname="System.ComponentModel.UInt16Converter" preserve="all"/>
<type fullname="System.ComponentModel.UInt32Converter" preserve="all"/>
<type fullname="System.ComponentModel.UInt64Converter" preserve="all"/>
</assembly>
</linker>