yasirkula / UnityIonicIntegration

A guide to integrating Unity 3D content into an Ionic app and sending messages between them (for Android & iOS)(tested with Vuforia plugin)
104 stars 32 forks source link

Sending of String not working from Ionic to Unity and vice versa. #55

Closed darellbernabe closed 5 years ago

darellbernabe commented 5 years ago

I managed to make the plugin work and followed all the steps here but I'm having problems getting the strings from either side. Can anyone help? These are the only changes I made, see snippets below:

home.page.html (Ionic Side) image

home.page.ts image

IonicComms.cs (Unity Side) image

ButtonPressed.cs image

Gist is if I press buttons it should send message to the other side and vice versa. Ionic Side: openUnity() is running successful but I can't retrieve the string. Unity Side: SendMessageToIonic() is not working. FinishActivity() is the only one working.

If I'm missing some in my codes, let me know also.

yasirkula commented 5 years ago

IonicComms object is automatically created on Unity-side (unless you have one in your first scene). You can make IonicComms.fromIonic a public static string FromIonic { get; private set; } property and simply say returnObj = IonicComms.FromIonic;.

Also use IonicComms.SendMessageToIonic instead of ionic.SendMessageToIonic, however I'm not sure if this will resolve the Unity-to-Ionic messaging issue. Maybe assigning the uMessageReceivedFromUnity to an Ionic button is somehow preventing the function from getting called? Try removing that Ionic button and adding a console.log( "=========" + message + "=========" ); to see if the function is really not getting called.

darellbernabe commented 5 years ago

Thanks for tips! I was able to make SendMessageToIonic work this time. I am still having trouble retrieving string from Ionic to Unity. All I did is dropped the script in under Assets folder:

image

yasirkula commented 5 years ago

You can change the contents of IonicComms.cs like this:

using System.IO;
using UnityEngine;

public class IonicComms : MonoBehaviour
{
    private static IonicComms Instance = null;

#if !UNITY_EDITOR && UNITY_IOS
    [System.Runtime.InteropServices.DllImport( "__Internal" )]
    private static extern void uHideUnity();

    [System.Runtime.InteropServices.DllImport( "__Internal" )]
    private static extern void uNotifyUnityReady();

    [System.Runtime.InteropServices.DllImport( "__Internal" )]
    private static extern void uSendMessageToIonic( string message );

    [System.Runtime.InteropServices.DllImport( "__Internal" )]
    private static extern void uSendResultToIonic( string result );
#endif

    public static string MessageFromIonic { get; private set; }

    [RuntimeInitializeOnLoadMethod( RuntimeInitializeLoadType.AfterSceneLoad )]
    static void Init()
    {
        if( Instance == null )
        {
            Instance = new GameObject( "IonicComms" ).AddComponent<IonicComms>();
            DontDestroyOnLoad( Instance.gameObject );
        }
    }

    void Awake()
    {
        if( Instance == null )
        {
            Instance = this;

            gameObject.name = "IonicComms";
            DontDestroyOnLoad( gameObject );
        }
        else if( this != Instance )
            Destroy( this );
    }

    void Start()
    {
        if( Instance != this )
            return;

#if !UNITY_EDITOR && UNITY_ANDROID
        using( AndroidJavaClass activityClass = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ) )
        using( AndroidJavaObject activity = activityClass.GetStatic<AndroidJavaObject>( "currentActivity" ) )
        {
            string data = activity.Get<string>( "commStr" );
            OnMessageReceivedFromIonic( data );
        }
#elif !UNITY_EDITOR && UNITY_IOS
        uNotifyUnityReady();
#endif
    }

    private void OnMessageReceivedFromIonic( string message )
    {
        if( string.IsNullOrEmpty( message ) )
            message = null;

        // Process message here
        MessageFromIonic = message;
    }

    public static void SendMessageToIonic( string message )
    {
        if( message == null || message.Length == 0 )
            return;

#if !UNITY_EDITOR && UNITY_ANDROID
        using( AndroidJavaClass activityClass = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ) )
        using( AndroidJavaObject activity = activityClass.GetStatic<AndroidJavaObject>( "currentActivity" ) )
        {
            activity.Call( "sendMessageToIonic", message );
        }
#elif !UNITY_EDITOR && UNITY_IOS
        uSendMessageToIonic( message );
#endif
    }

    public static void FinishActivity( string returnMessage = null )
    {
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;
        return;
#endif

        if( returnMessage == null )
            returnMessage = "";

        if( Instance == null )
        {
            Application.Quit();
        }
        else
        {
#if UNITY_EDITOR
#elif UNITY_ANDROID
            using( AndroidJavaClass activityClass = new AndroidJavaClass( "com.unity3d.player.UnityPlayer" ) )
            using( AndroidJavaObject activity = activityClass.GetStatic<AndroidJavaObject>( "currentActivity" ) )
            {
                activity.Set<string>( "commStr", returnMessage );
                activity.Call( "closeApp" );
            }
#elif UNITY_IOS
            uSendResultToIonic( returnMessage );            
            uHideUnity();
#else
            Application.Quit();
#endif
        }
    }
}

Then, in your scripts, you can use IonicComms.MessageFromIonic to retrieve the message from Ionic to Unity.

P.S. Out of interest, how did you resolve the Unity-to-Ionic communication issue?

darellbernabe commented 5 years ago

Thanks man, I'll try that. I was having errors in one of the buttons, so i tried doing it all in one function/button that was already working. I reverted back the static (since I was creating a new IonicComms class, so dumb of me.) on the functions and used IonicComms.SendMessageToIonic first then FinishActivity. I did not exposed the uMessageReceivedFromUnity function to the ionic buttons also. Instead, I allocated the 'message' into a global variable and work my way out to send the string into the UI.

P.S. I am also curious if I can use other variable types to pass on to each other. A universal one, JSON perhaps?

yasirkula commented 5 years ago

You can send any string to Ionic or Unity, so JSON should be fine. But you'll have to handle the JSON serialization/deserialization in your scripts.

darellbernabe commented 5 years ago

Fixed this! Checked in IonicComms that the MessageFromIonic is being populated, but not instantaneously. I'm getting a blank message initially on my Start() function, tried to add the Update() to see how many frames or in what instance will it take to update the said value. Got it in at least a millisecond in the Update().