目录

一、Android加载Unity

1.1 Unity打包Android项目

1.2 Android加载Unity生成项目

1.3 加载Unity内容

二、Unity和Android交互

2.1 Unity发消息给Java

2.2 Android发消息给Unity


开发环境:Unity2019.2.17f,AndroidStudio3.5.3,VS2019。

我要达到的功能是

1.在unity里面点击一个按钮,在Unity三维内容前面弹出一个窗口,显示Android内容。

2.在Android界面的一部分显示Unity的三维内容。

一、Android加载Unity

1.1 Unity打包Android项目

参考:Unity 工程 融合 AndroidStudio工程

Unity导出Android项目,AndroidStudio导入过程中提示了几个窗口

总之继续下去,打开项目。

下载SDK,能够正常导入了。

加入现在打包运行的话,看到的就是Unity程序了。

--------------------------------------------------------------------------

1.2 Android加载Unity生成项目

将刚刚导出的项目从application改成library,修改成类库。

根据错误提示把下面的bundle和applicationId注释掉

可以打包成aar文件了。

放入Android项目中的libs文件夹中

加入到项目中

Build后出现错误:Manifest merger failed with multiple errors, see logs

参考:https://blog.csdn.net/dengweijunkedafu/article/details/80541104

输入gradlew processDebugManifest --stacktrace,结果

总之把Unity导出项目里面的AndroidManifest.xml的里面的冲突的都删除了。

也就是前面教程中的

就像这样

可以Build了。

---------------------------------------------------------

1.3 加载Unity内容

接下来在Android界面中加载Unity的内容

private UnityPlayer mUnityPlayer;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Log.i("MainActivity","onCreate");        //initUnityPlayer();        Button btnInit=findViewById(R.id.btnInitUnity);        btnInit.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.i("MainActivity","btnInit onClick");                initUnityPlayer();            }        });    }    private void initUnityPlayer() {        try {            Log.i("MainActivity","initUnityPlayer");            LinearLayout layout = findViewById(R.id.unityview);            mUnityPlayer = new UnityPlayer(this);            layout.addView(mUnityPlayer.getView());            mUnityPlayer.requestFocus();        }catch (Exception ex){            Log.e("MainActivity","Exception:"+ex);        }    }

运行测试的结果,initUnityPlayer放到onCreate或者onStart里面会闪退,而且没有提示。

加工按钮后,提示E/Unity: Failed to load 'libmain.so'

搜索E/Unity: Failed to load 'libmain.so',在百度上找不到相关资料,感觉它对于纯英文的比较无力....

libmain.so是Unity生成项目里面的

google到 https://forum.unity.com/threads/integration-unity-as-a-library-in-native-android-app.685240/

这个好像是Version1,还有个Version2

相关的还有:https://forum.unity.com/threads/using-unity-as-a-library-in-native-ios-android-apps.685195/

https://forum.unity.com/threads/integration-unity-as-a-library-in-native-android-app-version-2.751712/,

感觉官方的教程不是aar加载而是作为一个Model加载进来的。

另外,有个官方Demo:https://github.com/Unity-Technologies/uaal-example

按照这个

把Unity生成项目的ndk拷贝过来

        ndk {            abiFilters 'armeabi-v7a'        }

结果,不崩溃了,但是还是出不来,那个要显示Unity的区域变成黑色了。

------------------------------------------------------------------------------------

经过研究、思考,理解UnityPlayer是什么,观察Unity打包项目的UnityPlayerActivity后,算是弄出来了。

把前面的initUnityPlayer放到onCreate中,同时把UnityPlayerActivity里面的其他Override方法都拷贝过来。

public class MainActivity extends AppCompatActivity {    private UnityPlayer mUnityPlayer;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Log.i("MainActivity","onCreate");        initUnityPlayer();    }    private void initUnityPlayer() {        try {            Log.i("MainActivity","initUnityPlayer");            LinearLayout layout = findViewById(R.id.unityview);            mUnityPlayer = new UnityPlayer(this);            layout.addView(mUnityPlayer.getView());            mUnityPlayer.requestFocus();        }catch (Exception ex){            Log.e("MainActivity","Exception:"+ex);        }    }    @Override protected void onNewIntent(Intent intent) {        // To support deep linking, we need to make sure that the client can get access to        // the last sent intent. The clients access this through a JNI api that allows them        // to get the intent set on launch. To update that after launch we have to manually        // replace the intent with the one caught here.        super.onNewIntent(intent);        setIntent(intent);        mUnityPlayer.newIntent(intent);    }    // Quit Unity    @Override protected void onDestroy ()    {        mUnityPlayer.destroy();        super.onDestroy();    }    // Pause Unity    @Override protected void onPause()    {        super.onPause();        mUnityPlayer.pause();    }    // Resume Unity    @Override protected void onResume()    {        super.onResume();        mUnityPlayer.resume();    }。。。。。

拷贝过来后,onNewIntent会让你加个super.onNewIntent。

运行后,在预定的区域(一个LinearLayout里面)显示了Unity的内容了

测试发现显示Unity内容是用mUnityPlayer.resume();,在requestFocus,马上resume的话,三维能够出来。按钮点击触发resume的话也能出来。

----------------------

直接继承UnityPlayerActivity其实就可以了

public class MainActivity extends UnityPlayerActivity {    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initUnityPlayer();    }    private void initUnityPlayer() {        try {            Log.i("MainActivity","initUnityPlayer");            LinearLayout layout = findViewById(R.id.unityview);            //mUnityPlayer = new UnityPlayer(this);            layout.addView(mUnityPlayer.getView());//UnityPlayerActivity里面已经new了            //mUnityPlayer.requestFocus();        }catch (Exception ex){            Log.e("MainActivity","Exception:"+ex);        }    }}

-------------------------------------------

不过有发现,1.默认的标题栏不见了; 2.手机旋转时会崩溃退出

第一个不是问题,第二个必须处理。

直接横屏再打开是可以的。

Unity导出项目,生成运行测试,旋转不会崩溃。

。。。。。

===============================================================

二、Unity和Android交互

参考:Unity与Android Studio交互,Unity 与 Android 互调用

2.1 Unity发消息给Java

    public void ClickF()    {        Debug.Log("ClickF");        Count++;        Result.text = Count + "";        AndroidJavaClass jc = new AndroidJavaClass("com.example.myapplication.MainActivity");        AndroidJavaObject overrideActivity = jc.GetStatic("instance");        int r=overrideActivity.Call("UnityClick", Count);        Result.text += "|" + r;    }

Java中有相应的类->对象->方法,com.example.myapplication.MainActivity->instance->UnityClick。

public class MainActivity extends UnityPlayerActivity {    public static MainActivity instance;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        instance = this;        //...    }    @Override    protected void onDestroy() {        super.onDestroy();        instance = null;    }    public int UnityClick(int c){        return c+1;    }}

2.2 Android发消息给Unity

// objectName: Unity 对象的名称// methodName: Unity 对象绑定的脚本方法名// message: 自定义消息UnityPlayer.UnitySendMessage(String objectName, String methodName, String message);
        Button btn=findViewById(R.id.btnInitUnity);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                UnityPlayer.UnitySendMessage("JavaInterface","ReceiveFromAndroid","abc");            }        });

同样的Unity中必须有相应的GameObject->Function

public class JavaInterfaceABC : MonoBehaviour{    public void ReceiveFromAndroid(string a)    {        Debug.Log("ReceiveFromAndroid:" + a);    }}

类名不重要,重要的GameObject的名称。

另外假如JavaInterface对象上有多个脚本有ReceiveFromAndroid方法,都会被调用一次的。

-----------

总的来说,和Unity(Webgl)与Html交互很像。

因此实际功能开发时打算也是做成单一入口,所有的交互都从一个接口进入、一个接口出去,用json字符串的方式传递对象数据。

更多相关文章

  1. PullToRefreshScrollView和Banner
  2. Android官方文档翻译 三 1.1Creating an Android(安卓)Project
  3. android加载大图片内存问题
  4. Android:瀑布流效果 的简单实现
  5. android图片异步加载解决步骤
  6. Android(安卓)原始下载图片 通过HTTp
  7. android studio 复制项目
  8. android:使用webview加载网页
  9. android itemtouchhelper-extension 仿微信删除

随机推荐

  1. Android应用开发提高系列(5)——Android动
  2. 详解 Android(安卓)的 Activity 组件
  3. 不用SDK manager 下载 Android(安卓)sdk
  4. Android(安卓)GPS架构分析
  5. android 登陆、注册、并个指定用户充值
  6. Android(安卓)LaunchMode and StartActiv
  7. android adb配置环境变量
  8. 上官网学android之二(Building your First
  9. Ted Mosby - 一个MVP框架的软件架构
  10. Android(安卓)ADB server didn't ACK * f