0

I am developing a project which includes Android app and Unity app. The main app is Android which at some point opens the Unity app. I exported the Unity app as Android plugin and integrated it in the Android studio as AAR module. When I open Unity app from Android I have to send a variable (integer) and retrieve it in Unity. Depending on this integer then I activate different objects. My question is how to send this integer in Android and then retrieve it in Unity? I read and tried a lot, used "UnityPlayer.UnitySendMessage" in Android and "AndroidJavaObject" in Unity but I didn't manage to achieve what I want.

Package name of Android app is "android.unityembed" and of Unity is "com.borut.multiple".

Java code:

package android.unityembed;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.unity3d.player.UnityPlayer;
import com.borut.multiple.UnityPlayerActivity;

public class Start extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.start);

    Button button = (Button) findViewById(R.id.button);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Intent intent = new Intent(getApplicationContext(), UnityPlayerActivity.class);
            startActivity(intent);
        }
    });
}

public static int OnSceneLoadComplete(){
    return 1;
}

}

Unity code:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.VR;

public class NormalStart : MonoBehaviour {
public GameObject space1;
public GameObject space2;

// Use this for initialization
void Start () {
    StartCoroutine (LoadDeviceInit ("", false));

    // x is the variable you get from Java
    AndroidJavaClass jc = new AndroidJavaClass ("android.unityembed.Start");
    int x = jc.CallStatic<int> ("OnSceneLoadComplete");
}

// Update is called once per frame
void Update () {
}

public void active1() {
    space1.SetActive (true);
}

public void active2() {
    space2.SetActive (true);
}

IEnumerator LoadDeviceInit(string newDevice, bool enable)
{
    Debug.Log ("LoadDevice: " + newDevice + " enabled: " + enable);
    VRSettings.LoadDeviceByName(newDevice);
    yield return null;
    VRSettings.enabled = enable;
    yield return null;
    Camera.main.ResetAspect();

}

//Called from Java to receive message
public void JavaMessageReceiver(string message)
{
    Debug.Log("Received Message form Java: "+message);
}

}

EDIT: I solved the problem, updated code above does what I wanted.

I have another issue. My Unity app uses Google VR SDK and it's implemented also for Cardboard. When I build Unity app normally (I get .apk file) the Cardboard loads like it should (split screen). But when I export this app as a module in Android Studio, when I run UnityPlayerActivity the Cardboard view doesn't load, the scene is loaded like a normal Unity 3D scene.

Here are two screenshots of Android Studio Logcat: Logcat 1 Logcat 2

Here is also a screenshot of my Player Settings in Unity. Sometimes I want to load the Cardboard, sometimes not (depending on user's choice). Unity Player Settings

How can I solve this problem?

Borut Kolar
  • 23
  • 1
  • 7
  • You talked about `UnityPlayer.UnitySendMessage` but your code didn't use it. That's really all you need. – Programmer Apr 24 '18 at 17:14
  • In Java code I added this line above Intent: UnityPlayer.UnitySendMessage("FirstScreenCanvas", "active1", ""); And in the C# script Normal Start I added this function: "public void active1() { space1.SetActive(true); }" But when I run app GameObject "space1" didn't become active. – Borut Kolar Apr 27 '18 at 20:37
  • You have to edit your post. Add edit under it, then your new C# and Java code. Also, add a screenshot of Inspector tab of the Object your C# script is attached to. I need these to know what you're doing wrong – Programmer Apr 27 '18 at 21:00
  • I edited my post. – Borut Kolar Apr 28 '18 at 07:48
  • The Unity scene is not yet loaded before you called `UnitySendMessage`. You are supposed to call start unity's Activity before calling `UnitySendMessage`. I suggest you use a callback and a static boolean variable. When scene loads in the C# side, set a static boolean variable on the Java side to through. After that you can use that boolean variable to decide if to call `UnitySendMessage` or not. If the scene is not loaded, `UnitySendMessage` won't be anything. – Programmer Apr 28 '18 at 10:57
  • How should I implement this callback? How can I get C# variable in Android Studio? How can I check in Android Studio if Unity scene is loaded? – Borut Kolar Apr 28 '18 at 19:10
  • In your Unity/C# side, from the `Start` function, you can use [`AndroidJavaObject`](https://docs.unity3d.com/ScriptReference/AndroidJavaObject.CallStatic.html) to call a `static` function in your Java plugin. This `static` function will set the loading boolean variable to true. In fact, you don't even need a boolean variable. From that `static` function in your Java, you can make your `UnitySendMessage` call if you want. This will make sure that `UnitySendMessage` is used when scene is actually loaded. – Programmer Apr 28 '18 at 19:18
  • Is this way ok? I updated the code. – Borut Kolar Apr 30 '18 at 08:15
  • Very close but does it work? – Programmer Apr 30 '18 at 08:18
  • Your Java plugin did not extend `UnityPlayerActivity` so I don't think using `com.unity3d.player.UnityPlayer` to call get your plugin is appropriate here. Find your plugin class with its package name: `AndroidJavaClass jc = new AndroidJavaClass("android.unityembed.Start");` then call it `jc.CallStatic("send");`. Note that I assume that `android.unityembed.Start` is the package and class name of your plugin. You have to replace it with the actual one you have. – Programmer Apr 30 '18 at 08:28
  • It's ok now? The code is updated. – Borut Kolar Apr 30 '18 at 13:11
  • Not sure why you were calling the `Start` function from Java. This function is called by Unity when scene loads. From the `Start` function, we can call a Java function to tell Java that we are done loading then set some variable to true. After that we can use that variable to determine if we should send data to C# or not. See my Edit. Take a look at the `send` and `OnSceneLoadComplete` functions – Programmer Apr 30 '18 at 13:30
  • Thank you for editing. But when does function "public static void send(String message)" execute? I have to call it. – Borut Kolar Apr 30 '18 at 21:08
  • It''s not called yet. When do you want to call it and what do you want to send to it? – Programmer Apr 30 '18 at 21:16
  • Just fyi, when calling UnityPlayer.UnitySendMessage, you have to send it to the class you are trying to do something with. You used: UnityPlayer.UnitySendMessage("FirstScreenCanvas", "JavaMessageReceiver",message); but you should do: UnityPlayer.UnitySendMessage("NormalStart", "JavaMessageReceiver",message); And also I think (not all sure) your package names for both android and unity should be the same. – abotrix Apr 30 '18 at 22:44
  • @abotrix OP is already confused please don't make it worse by suggesting something that's not correct. *"you have to send it to the class you are trying to do something with."* **No**. The first parameter is the name of GameObject the script is attached to which is *FirstScreenCanvas* and **not** the name of the script. Every script attached to that GameObject that has a function called `JavaMessageReceiver` will receive that message when sent from Java – Programmer May 01 '18 at 07:08
  • Thank you for the info. I want to send the message (an integer) when I click on a button in Unity or even better, immediately after the scene in Unity is loaded. – Borut Kolar May 01 '18 at 11:21
  • @Programmer Sure...your correct....;)...excuse me... – abotrix May 02 '18 at 06:18
  • I figured it out! There is no need of "UnityPlayer.UnitySendMessage" at all. You just have to return what you want in the Java method you call it from Unity. I updated the code. – Borut Kolar May 02 '18 at 12:47
  • Thank you a lot for all of your help, I appreciate it! I have another issue, I updated the post. – Borut Kolar May 02 '18 at 13:24

0 Answers0