RominaV
RominaV

Reputation: 3415

Prepare Unity without showing UnityPlayer

I'm integrating Unity as a subview in a native Android app.

I'd need to prepare Unity when the app starts, but without showing it, because I need to change between scenes when the user taps a button, without showing the Unity screen presentation.

The flow is:

User chooses a scene in Activity A -> Display scene in PlayGameActivity with UnityPlayer.UnitySendMessage, without Unity splash/loading screen

In iOS I did it like this:

class AppDelegate: UIResponder, UIApplicationDelegate {

var currentUnityController: UnityAppController!

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    self.currentUnityController = UnityAppController()

    self.currentUnityController.application(application, didFinishLaunchingWithOptions: launchOptions)

    return true
}

But I don't find something similar in Android.

This is how I'm showing the UnityPlayer in a subview:

public class PlayGameActivity extends UnityPlayerActivity {
    private static final String TAG = "PlayGameActivity";

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

        // Create the UnityPlayer
        mUnityPlayer = new UnityPlayer(this);
        int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);
        boolean trueColor8888 = false;
        mUnityPlayer.init(glesMode, trueColor8888);

        // Add the Unity view
        RelativeLayout layout = (RelativeLayout) findViewById(R.id.container_unity_play_game_activity);
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) layout.getLayoutParams();
        layout.addView(mUnityPlayer.getView(), 0, lp);

        String unityScene = "some_scene";
        Log.d(TAG, "calling scene " + unityScene);
        UnityPlayer.UnitySendMessage("AController", "AMethodToChangeScene", unityScene);
    }
}

I tried changing scene in an Activity with the player and the buttons below, and it works, because I wait for the player to be ready. Unity does receive the message of changing scene and does so after loading itself.

So is there a way to init Unity without showing it like in iOS? Or a way to know when the UnityPlayer is ready/isn't showing the splash screen?

Upvotes: 0

Views: 1497

Answers (1)

Matt Brown
Matt Brown

Reputation: 288

I tested an approach that I think may work for you.

First I made a two View variables so that the views can be manipulated throughout the class.

public class PlayGameActivity extends UnityPlayerActivity {
    private static final String TAG = "PlayGameActivity";
    private View playerView;
    private RelativeLayout layout;
    RelativeLayout.LayoutParams lp

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

        // Create the UnityPlayer
        mUnityPlayer = new UnityPlayer(this);
        int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);
        boolean trueColor8888 = false;
        mUnityPlayer.init(glesMode, trueColor8888);
        //MODIFIED VERSION OF YOUR CODE
        playerView = mUnityPlayer.getView();

        // Add the Unity view SLIGHTY MODIFIED
        layout = (RelativeLayout) findViewById(R.id.container_unity_play_game_activity);
        lp = (RelativeLayout.LayoutParams) layout.getLayoutParams();
        String unityScene = "some_scene";
        Log.d(TAG, "calling scene " + unityScene);
        UnityPlayer.UnitySendMessage("AController", "AMethodToChangeScene", unityScene);
    }
}

Then in my test, I had two buttons with listeners set up. The first button let me send a message to Unity,

Button theButton = (Button)findViewById(R.id.button);
        theButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                mUnityPlayer.UnitySendMessage("CallThis", "MessageFromAndroid", "HI!");
            }
        });

Then the second button did the following,

Button good = (Button)findViewById(R.id.button2);
        good.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            layout.addView(playerView);
            mUnityPlayer.requestFocus();
        }
    });

So the basic idea is don't add mUnityPlayer using layout.addView() to the view until you are ready. You could have your program call UnitySendMessage, and then from within Unity make a call into Android that runs the second line from the button I made. That is, just replace that button I used with a function that Unity can call. You're probably familiar with it already but I'll link to the Android Scripting API anyway.

EDIT: I ran another test and it is not necessary to put mUnityPlayer.requestFocus() in the method that adds the UnityPlayer to your view.

Upvotes: 2

Related Questions