初识untiy3d与安卓交互

前言

因为之前对安卓,iOS和unity3d都有过接触和基础,最近在项目中遇到了交互问题,搜了一下网上的文章发现还挺多的,应用的场景也很普遍,我们的项目是把写好的unity3D游戏项目嵌套在原生的安卓和iOS APP中,因此就需要就行一些简单的交互。简单的记录下收集到各位大神资料后整理的笔记。

一:基础

安卓加载u3d界面并进行简单的交互

  • 1:将u3d的项目打包成安卓项目并在安卓界面中展示

    • 切换unity环境为安卓export项目 build system:Gradle
初识untiy3d与安卓交互_第1张图片
50B7FD3F-0C2D-4880-84E0-9CE29079B5CF.png
  • 项目主要目录:
    • 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();
    
    
初识untiy3d与安卓交互_第2张图片
复制后的文件目录.png
  • 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线程中调用。

通过这种方法我们就不用只依赖于通过SendMessage方法来交互。

你可能感兴趣的:(初识untiy3d与安卓交互)