前言
因为之前对安卓,iOS和unity3d都有过接触和基础,最近在项目中遇到了交互问题,搜了一下网上的文章发现还挺多的,应用的场景也很普遍,我们的项目是把写好的unity3D游戏项目嵌套在原生的安卓和iOS APP中,因此就需要就行一些简单的交互。简单的记录下收集到各位大神资料后整理的笔记。
一:基础
安卓加载u3d界面并进行简单的交互
-
1:将u3d的项目打包成安卓项目并在安卓界面中展示
- 切换unity环境为安卓export项目 build system:Gradle
- 项目主要目录:
- assets文件下面是unity的一些资源文件,包括场景和渲染的文件(复制到main目录下)。
- libs下面当然就是jar包(复制进自己AS项目中lib中)。
- jniLibs/armeabi-v7a/libmain.so,libmono.so,libunity.so复制进安卓工程中相应目录
- layout中显示u3d界面
ll_unity=(LinearLayout)findViewById(R.id.ll_unity); mUnityPlayer = new UnityPlayer(this); ll_unity.removeAllViews(); ll_unity.addView(mUnityPlayer); mUnityPlayer.requestFocus();
-
2:交互:安卓与u3d中的方法互相调用
- 安卓调用u3d:
UnityPlayer.UnitySendMessage("Manager", "ZoomIn", "");
第一个参数是Game Object对象,所以需要在游戏对象上绑定脚本,第二个参数是unity中定义的方法名,第三个参数是定义方法的参数(可空)SendMessage不能调用static方法
。
- u3d调用安卓中的方法
- 没有返回值得普通方法
AndroidJavaObject jo = new AndroidJavaObject("android.content.res.Configuration");
jo.Call("setToDefaults");
- 带有返回值的普通方法
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String", "some string");
int hash = jo.Call("hashCode");
- 没有返回值的静态方法
AndroidJavaObject jo = new AndroidJavaObject("android.os.Binder");
jo.CallStatic("flushPendingCommands");
- 带有返回值的静态方法
AndroidJavaObject jo = new AndroidJavaObject("java.lang.String");
string valueString = jo.CallStatic("valueOf", 42.0);
示例调用安卓getName方法传入参数string(c#代码)
AndroidJavaClass jc = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
AndroidJavaObject jo = jc.GetStatic ("currentActivity");
string name = jo.Call ("getName", "成功调用android方法");
label.text = name;
安卓端代码
public void setName(String name){
Toast.makeText(context, name, Toast.LENGTH_SHORT).show();
}
安卓调用u3d不通过SendMessage
方法
实现思路:接口回调
1:在安卓端定义接口
public interface AndroidUnity
{
public void sendMessage();
public void sendMessage(String title);
}
2:在需要用到unity方法处实例化接口
private AndroidUnity androidUnity;
//点击这个按钮调u3d方法不通过`SendMessage`方法
public void ZoomIn(View view){
// UnityPlayer.UnitySendMessage("Manager", "ZoomIn", "");
if(androidUnity !=null){
androidUnity.sendMessage();
}
}
//通过`SendMessage`方法
public void ZoomOut(View view){
Log.e(TAG,"ZOOMOUT");
UnityPlayer.UnitySendMessage("Cube", "ZoomOut", "");
}
至此安卓端已经搞定了,接下来就是在unity脚本中回调接口
3:unity脚本代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class anunity : MonoBehaviour {
public class CallBack : AndroidJavaProxy
{
public CallBack() :base("com.example.allen.myapplication.AndroidUnity")
{
}
public void sendMessage ()
{
//监听回调后执行某些操作
//doSomething();
}
public void sendMessage (string message)
{
//doSomething();
}
}
// Use this for initialization
void Start () {
//
}
void Awake()
{
//获取当前activity
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic("currentActivity");
activity.Call ("runOnUiThread", new AndroidJavaRunnable (() => {
activity.Call ("setAndroidUnity", new CallBack ());
}));
UnityEngine.Debug.LogError("Awake");
}
// Update is called once per frame
void Update () {
}
}
注意点:
1:我们写的类必须继承AndroidJavaProxy。AndroidJavaProxy 接口,用于实现任何java接口;通过invoke调用接口中的方法
2:public CallBack() :base("com.example.allen.myapplication.AndroidUnity")包名及接口名必须保持与安卓端一致。
3:在Unity中,所有调用Android UI相关的东西,都要通过activity.runOnUiThead,在UI线程中调用。