Interaction and further packaging of Android Studio project and Unity project

If the callback event in unity needs to be exposed to the AS project listener, you can create a Plugins folder under your own project, add the Android folder under the subfolder, the java class or jar created under this Android folder, The aar package will be packaged together when the unity project outputs the AS package.

For example, when there is a method for loading a scene in the unity project, it will continuously return to the loading progress when loading, and call back the loading completion event after the loading is completed. If you want to expose this method of loading scenes to the AS project for invocation, the AS project cannot directly put the loading and completed monitoring into the loading method in a method.

Because AS calls the Unity method, it can only be called in the following way

/*
gameObj----unity挂载调用类的gameobject物体的name
function----unity中触发的类
param----unity中触发的类的参数
*/
UnityPlayer.UnitySendMessage("gameObj","function","param")

With this mechanism, if the method needs to pass in the monitoring event so that the callback monitoring cannot be implemented directly, but if you understand a little AS basics, you can further encapsulate the corresponding monitoring event in the AS project and integrate it into one method. Form, let’s talk about the specific approach below.

First, in the Unity project, the java class created under Plugins/Android is used to mark the callback methods that need to be monitored. According to the above example, you need to monitor the loading progress and loading completion events when loading the scene. Then you can create a CallbackActivity.java, the code inside is as follows:

package com.XXX.XXXX;
import android.os.Bundle;
import android.widget.FrameLayout;

import com.unity3d.player.UnityPlayerActivity;

public abstract class CallbackActivity extends UnityPlayerActivity
{
    public static CallbackActivity instance = null;

    abstract protected void loadSceneComplete();//加载完成的监听事件
    abstract protected void loadSceneProcess(String percent);//加载中的监听事件


    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        instance = this;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        instance = null;
    }
}

These two listening callbacks are triggered continuously when Unity triggers the method of loading the scene. Below is the code for unity

    /// <summary>
    /// 加载场景
    /// </summary>
    /// <param name="content"></param>
    public void LoadScene(string content)
    {
        #if UNITY_ANDROID
        AndroidJavaClass jc = new AndroidJavaClass("com.XXX.XX.CallbackActivity");
        AndroidJavaObject activity = jc.GetStatic<AndroidJavaObject>("instance");
        #endif
        rbxManager.LoadScene(sceneID,Progress.Create<float>(percent =>
        {
        #if UNITY_ANDROID
            activity.Call("loadSceneProcess", precent.ToString());
        #endif
        }), ()=> {
        #if UNITY_ANDROID
            activity.Call("loadSceneComplete","");
        #endif

        });

    }

The normal logic is that when the UnityPlayer.UnitySendMessage("gameObj","LoadScene","content") method is called in the AS project to load the scene, it is necessary to override the loadSceneComplete and loadSceneProcess methods in the CallbackActivity class inherited above. monitor. The code is as follows:

public class UnityCallbackActivity extends CallbackActivity {    
@Override
    protected void loadSceneComplete() {
        //监听
    }
@Override
    protected void loadSceneProcess(String percent) {
        //监听
    }
}

Up to this step is the default approach, through UnityPlayer.UnitySendMessage to trigger the loading, and then listen to the event in the replication method.

If the exported Unity project is used by itself, of course, it’s okay, but if the project is provided to AS development engineers who don’t understand 3D development, it’s a bit confusing to understand. I personally think that it needs to be further encapsulated in the method, and the method call and monitoring are both Put it in the same function.

The first is the rewrite of the commission. Java is not the same as C#. There is no built-in delegate type like Action, but delegates are implemented through interfaces.

Take the example of loading the scene above. Corresponding to the two callback methods of loadSceneComplete and loadSceneProcess, it is necessary to redefine two java classes corresponding to the interface

package com.realibox.ar.callback;

public interface LoadSceneCallback{
    public void loadSceneAction(float percent);
}
package com.xxx.xxxx.callback;

public interface LoadSceneComleteCallback{
    public  void loadSceneCompleteAction();
}

Then further modify the UnityCallbackActivity.java above, the code is as follows

public class UnityCallbackActivity extends CallbackActivity {    
    /*
    *when scene loading complete, this function will callback
     */
    private LoadSceneComleteCallback loadSceneComleteCallback;
    @Override
    protected void loadSceneComplete() {
        if (loadSceneComleteCallback!=null)
        loadSceneComleteCallback.loadSceneCompleteAction();
    }

    /*
    * when scene is loading, this function will stay callback
     */
    private LoadSceneCallback loadSceneCallback;
    @Override
    protected void loadSceneProcess(String percent) {
        if (loadSceneCallback!=null) {
                loadSceneCallback.loadSceneAction(p);
        }
    }
}

The logic implemented above is that when Unity calls back these two events, the methods of the classes that inherit these two interfaces will also be triggered.

In this case, in the AS project, the method of calling the scene can be further encapsulated, the code is as follows:

    void Init(){
                LoadProject(sceneId, 
                    percent -> {
                        Log.e(TAG, "percent-"+percent);
                    }, 
                    () -> {
                        Log.e(TAG, "loadsenecomplete");
                    });
    }

    /*
     *
     * scene_id
     * LoadSceneCallback:return percent of load scene
     * LoadComleteCallback:callback when finish load scene
     */
    protected void LoadProject(String sceneid, String doMain,LoadSceneCallback loadSceneCallback,LoadSceneComleteCallback loadSceneComleteCallback) {
        UnityPlayer.UnitySendMessage("gameobj", "LoadScene", sceneid);
        this.loadSceneCallback = loadSceneCallback;
        this.loadSceneComleteCallback = loadSceneComleteCallback;

    }   

In this way, when calling the method of loading the scene, you can pass the loading and completion callbacks as parameters into the method.

Guess you like

Origin blog.csdn.net/ssssssilver/article/details/108466721