首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Android 与 Unity扯不清的关系

Android 与 Unity扯不清的关系

作者头像
包子388321
发布于 2020-06-16 10:23:24
发布于 2020-06-16 10:23:24
2.2K00
代码可运行
举报
文章被收录于专栏:包子的书架包子的书架
运行总次数:0
代码可运行
历史背景

近期在游戏SDK接入的技术支持中,不断有游戏反馈希望有现成的unity插件可以直接接入,为了减轻和方便游游戏方接入,对SDK进行unity的插件开发

用到的兵器

1、Android studio 官方下载地址

2、Unity 2017.4.2f2 官方下载地址

官网有时候无法访问,这边提供百度

unity2017中文安装包:链接:https://pan.baidu.com/s/1gW2tDhAiodKf0qRNUNCKWg 提取码:k8to

unity2017的Android支持的插件:链接:https://pan.baidu.com/s/1tTCAYlZnDUtXIizz_70Gpg 提取码:0mtp

Android方面的操作(这边提供的是aar的形式)

1、新建一个Android Library的module

创建插件module.png

2、编译下对应的module,名称和包名(包名就是unity的项目的包名)

填写包名.png

3、原有的要接入SDK,已经达成aar包,将SDK的aar包,导入到我们这个plugin的module的libs下,配置一下gradle

gradle的配置修改.png

4、个人这边将SDK的内容进行了封装到一个类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class SinglePaySDK {

  private static final String TAG = "SDK";

  private SingleOperateCenter mOpeCenter;

  public SinglePaySDK(Activity context, String appKey, String gameName, int orientation,
      SingleOperateCenter.SingleRechargeListener singleRechargeListener) {
    initSDK(context, appKey, gameName, orientation, singleRechargeListener);
  }

  private void initSDK(Activity activity, String appKey, String gameName, int orientation,
      SingleOperateCenter.SingleRechargeListener singleRechargeListener) {
    Log.i(TAG, "appKey = " + appKey + ", orientation = " + orientation);

    if (isInitReady()) {
      return;
    }

    mOpeCenter = SingleOperateCenter.getInstance();
    new OperateCenterConfig.Builder(activity)
        .setDebugEnabled(true)  //发布游戏时,要设为false
        .setOrientation(orientation) //设置SDK界面方向,应与游戏设置一直
        .setSupportExcess(true) //设置是否支持超出金额充值
        .setGameKey(appKey)  //换成实际游戏的game key
        .setGameName(gameName)  //换成实际游戏的名字,原则上与游戏名字匹配
        .build();

    mOpeCenter.init(activity, singleRechargeListener);
  }

  public void doPay(Activity activity, final String money, final String productName) {
    doPay(activity, money, productName, null);
  }

  public void doPay(final Activity activity, final String money, final String productName,
      final String extra) {
    Log.d(TAG, "execute method doPay... money = " + money + ", productName = " + productName);

    if (mOpeCenter == null) {
      Log.d(TAG, "SDK need init first");
      return;
    }
    //extra是透传的字段
    if (TextUtils.isEmpty(extra)) {
      mOpeCenter.recharge(activity, money, productName);
    } else {
      mOpeCenter.recharge(activity, money, productName, extra);
    }
  }

  public boolean isInitReady() {
    return mOpeCenter != null;
  }

  public void doCheck(Activity activity, Callbacks.OnCheckFinishedListener listener) {
    Log.d(TAG, "execute doCheck...");
    if (!isInitReady()) {
      Log.d(TAG, "SDK need init first");
      return;
    }

    mOpeCenter.doCheck(activity, listener);
  }

  private void doDownload(Activity activity,  Callbacks.OnDownloadListener listener) {
    Log.d(TAG, "execute doDownload...");
    if (!isInitReady()) {
      Log.d(TAG, "SDK need init first");
      return;
    }

    mOpeCenter.doDownload(activity, listener);
  }

  private void doInstall(Activity activity) {
    Log.d(TAG, "execute doInstall...");
    if (!isInitReady()) {
      Log.d(TAG, "SDK need init first");
      return;
    }

    mOpeCenter.doInstall(activity);
  }
}

5、在unity的安装目录下:D:\Program Files\Unity\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar,将该文件拷贝到plugin 的module下的libs目录, 刷新gradle

6、由于当前默认使用原有的UnityPlayerActivity,并没有继承该该类 继承UnityPlayerActivity的写法

AndroidManifest.xml文件需要配置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:screenOrientation="portrait" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false">
          <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
            <category android:name="android.intent.category.LEANBACK_LAUNCHER" />
          </intent-filter>
          <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
    </activity>
            ............其他的代码.......

7、打包成aar

打包成aar.png

8、由于我们SDK插件打包成aar的时候,会将libs的unity的classes的jar包一并打包进去,需要手动用压缩软件打开aar将里面的classes.jar的文件删掉

Unity方面的操作

1、新建Unity项目,创建Secne场景,添加了Canvas的画布,在画布下添加了,Button和Text

新建unity场景.png

2、在unity的project下的assert目录下新建plugins目,然后再plugins目录下,在新建Android目录,将项目的AndroidManifest.xml文件拷贝进去,然后再新家libs目录将aar包copy进去,这边有两个,一个是SDK的aar包,一个我们编写创建的aar包,要注意一个地方是plugin-release的AndroidManifest文件包名和主项目的AndroidManifest不能一样,在17版本编译会出现重复包名的错误

需要用到的插件信息.png

3、在Assert目录下创建Scripts目录(这个主要是这边用于存放C#的脚本文件,直接放Assert级的目录下也是可以的)

创建的脚本文件.png

4、上述的脚本文件,就需要选择一个主要脚本,将该脚本文件添加到component中,用于绑定到该场景,设置调用通过add component-->scripts, 然后选择所开发的脚本文件

添加脚本.png

5、编译这边有两个区分,一个是gradle编译,一个Internal编译,主要区别是在2017版本gradle编译,可以不进行包名设置,internal是需要设置。

image.png

Player settings.png

6、注意PlatForm中Android 是需自己安装的

unity2017的Android 平台支持的插件:链接:https://pan.baidu.com/s/1tTCAYlZnDUtXIizz_70Gpg 提取码:0mtp

7、生成apk

这边讲讲上面C#调用java的相关代码

先贴代码

--SinglePaySDKContext.cs文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace SinglePay{
    public sealed class SinglePaySDKContext : MonoBehaviour
    {

        private AndroidJavaObject currentActivity;

        private static readonly SinglePaySDKContext _SinglePaySDKContext = new SinglePaySDKContext();

        /*
         * 获取当前实例       
         */
        public static SinglePaySDKContext GetInstance()
        {
            return _SinglePaySDKContext;
        }


        /*
         * 获取当前Activity       
         */
        public AndroidJavaObject GetActivity()
        {
            if (null == currentActivity)
            {
                currentActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer")
                .GetStatic<AndroidJavaObject>("currentActivity");
            }

            return currentActivity;
        }

        /*
         * 运行在主UI线程       
         */
        public void RunOnUIThread(AndroidJavaRunnable runnable)
        {
            GetActivity().Call("runOnUiThread", runnable);
        }


        /*
         * 获取根节点的布局 
         */
        public AndroidJavaObject GetRootLayout()
        {
            AndroidJavaClass R = new AndroidJavaClass("android.R$id");
            return currentActivity.Call<AndroidJavaObject>("findViewById", R.GetStatic<int>("content"));

        }
    }
}

--SinglePaySDK.cs文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using SinglePay;

public class SinglePaySDK : MonoBehaviour {

    private Transform canvasForm;
    private Button initButton;
    private Button payButton;
    private Button checkButton;
    private Text ResultText;

    //表示横屏
    private const int SCREEN_ORIENTATION_LANDSCAPE = 0;
    //表示竖屏
    private const int SCREEN_ORIENTATION_PORTRAIT = 1;
    //表示反向横屏
    private const int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
    //表示反向竖屏
    private const int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;

    //获取全局的上下文件对象
    private SinglePaySDKContext singlePaySDKContext;

    //获取单机支付SDK的对象
    private AndroidJavaObject singlePaySDK;

    //是否开始计时
    private bool IsTiming;
    //倒计时
    private float CountDown; 

    // Use this for initialization
    void Start () {

        singlePaySDKContext = SinglePaySDKContext.GetInstance();

        canvasForm = GameObject.Find("Canvas").transform;
        //获取控件对象设置时间监听
        initButton = canvasForm.Find("InitButton").GetComponent<Button>();
        payButton = canvasForm.Find("PayButton").GetComponent<Button>();
        checkButton = canvasForm.Find("CheckButton").GetComponent<Button>();
        ResultText = canvasForm.Find("ResultText").GetComponent<Text>();
        initButton.onClick.AddListener(InitSDK);
        payButton.onClick.AddListener(doPay);
        checkButton.onClick.AddListener(doCheck);
        ResultText.text = "hello";

        //Input.backButtonLeavesApp = true;//设置返回键,是否退出程序。(系统默认为 false,所以不自己写方法是不会退出 App 的)
    }

    public void InitSDK()
    {

        //AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        //AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");

        //调用成员方法
        //传入appkey
        //SingleRechargeListenerProxy listenerProxy = new SingleRechargeListenerProxy(this);
        //jo.Call("init","70001", SCREEN_ORIENTATION_PORTRAIT, listenerProxy);

        //调用静态方法
        //ResultText.text = jo.CallStatic<string>("GetInformation");
    
        singlePaySDKContext.RunOnUIThread(new AndroidJavaRunnable(() =>
        {
            SingleRechargeListenerProxy listenerProxy = new SingleRechargeListenerProxy(this);
            singlePaySDK = new AndroidJavaObject("cn.m4399.plugin.SinglePaySDK", singlePaySDKContext.GetActivity(), "70001", "测试游戏",SCREEN_ORIENTATION_PORTRAIT, listenerProxy);
            ResultText.text = "init sdk";

        }));
    }

    public void doPay()
    {

        //AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        //AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");

        singlePaySDKContext.RunOnUIThread(new AndroidJavaRunnable(() =>
        {
            bool isInitReady = singlePaySDK.Call<bool>("isInitReady");

            //调用成员方法
            //传入金额和商品名称
            //对应java的方法 doPay(money, productName, extra) 注:extra是透传参数
            //jo.Call("doPay","10","砖石");
            if (isInitReady)
            {
                singlePaySDK.Call("doPay", singlePaySDKContext.GetActivity(), "10", "砖石", "测试数据");
                ResultText.text = "do pay";
            }
            else
            {
                ResultText.text = "sdk init is not finished";
            }

        })); 
       
    }

    /*
     * 充值回调   
     */
    internal class SingleRechargeListenerProxy : AndroidJavaProxy
    {

        private SinglePaySDK sdk;
        public SingleRechargeListenerProxy(SinglePaySDK singlepay) : base("cn.m4399.operate.SingleOperateCenter$SingleRechargeListener")
        {
            sdk = singlepay;
        }
        /**
         * 加载成功
         */
        void onRechargeFinished(bool success, string msg)
        {
            Debug.Log("success = "+ success +",msg = "+msg);
            sdk.ResultText.text = "success = " + success + ",msg = " + msg;
        }

        /**
         * 加载失败
         * @param message
         */
        bool notifyDeliverGoods(bool shouldDeliver, AndroidJavaObject o)
        {
            Debug.Log("shouldDeliver = "+ shouldDeliver +", o "+ o.Call<string>("getJe"));
            return shouldDeliver;
        }
    }


    public void doCheck()
    {
        singlePaySDKContext.RunOnUIThread(new AndroidJavaRunnable(() =>
        {
            bool isInitReady = singlePaySDK.Call<bool>("isInitReady");

            //调用成员方法
            //传入金额和商品名称
            //对应java的方法 doPay(money, productName, extra) 注:extra是透传参数
            //jo.Call("doPay","10","砖石");
            if (isInitReady)
            {
                OnCheckFinishedListenerProxy listenerProxy = new OnCheckFinishedListenerProxy(this);
                singlePaySDK.Call("doCheck", singlePaySDKContext.GetActivity(), listenerProxy);
                ResultText.text = "do check update";
            }
            else
            {
                ResultText.text = "sdk init is not finished";
            }

        }));
    }

    /*
    * 充值回调   
    */
    internal class OnCheckFinishedListenerProxy : AndroidJavaProxy
    {

        private SinglePaySDK sdk;
        public OnCheckFinishedListenerProxy(SinglePaySDK singlepay) : base("cn.m4399.operate.model.callback.Callbacks$OnCheckFinishedListener")
        {
            sdk = singlepay;
        }

        void onCheckResponse(AndroidJavaObject o)
        {
            //这个回调参数对象是java的 UpgradeInfo,查看demo文档
            int code = o.Call<int>("getResultCode");
            if(code == o.GetStatic<int>("APK_CHECK_NO_UPDATE"))
            {
                sdk.ResultText.text = "已经是最新版本";
            }
            else if(code == o.GetStatic<int>("APK_CHECK_NEED_UPDATE"))
            {
                sdk.ResultText.text = "新版本号:"+o.Call<string>("getVersionCode");
                sdk.doDownload();
            }
            else
            {
                sdk.ResultText.text = "检查更新失败";
            }
        }
    }

    public void doDownload()
    {
        singlePaySDKContext.RunOnUIThread(new AndroidJavaRunnable(() =>
        {

            OnDownloadListenerProxy listenerProxy = new OnDownloadListenerProxy(this);
             singlePaySDK.Call("doDownload", singlePaySDKContext.GetActivity(), listenerProxy);
             ResultText.text = "do download";
           
        }));
    }

    internal class OnDownloadListenerProxy : AndroidJavaProxy
    {

        private SinglePaySDK sdk;
        public OnDownloadListenerProxy(SinglePaySDK singlepay) : base("cn.m4399.operate.model.callback.Callbacks$OnDownloadListener")
        {
            sdk = singlepay;
        }

        void onDownloadStart()
        {
            sdk.ResultText.text = "开始下载...";
        }

        void onDownloadProgress(long progress, long max)
        {
            sdk.ResultText.text = "总大小:"+max+", 已下载:"+progress;
        }

        void onDownloadSuccess()
        {
            sdk.ResultText.text = "下载成功...";
            sdk.doInstall();
        }

        void onDownloadFail(int resultCode, string message)
        {
            sdk.ResultText.text = "下载失败,resultCode = " + resultCode + ", message:" + message;
        }
    }

    public void doInstall()
    {
        singlePaySDKContext.RunOnUIThread(new AndroidJavaRunnable(() =>
        {
            singlePaySDK.Call("doInstall", singlePaySDKContext.GetActivity());
            ResultText.text = "do install";

        }));
    }


    // Update is called once per frame (每一帧刷新)
    void Update () {
        if (Application.platform == RuntimePlatform.Android && Input.GetKeyDown(KeyCode.Escape)) // 返回键
        {
            if (CountDown == 0)                          //当倒计时时间等于0的时候
            {
                CountDown = Time.time;                   //把游戏开始时间,赋值给 CountDown
                IsTiming = true;                        //开始计时
                ToastUtils.showToast("再按一次退出"); //显示提示信息 —— 这里的提示方法,需要根据自己需求来完成(用你自己所需要的方法完成提示)
                ResultText.text = "再按一次退出";
            }
            else
            {
                Application.Quit();                      //退出游戏
            }
        }
        if (IsTiming) //如果 IsTiming 为 true 
        {
            if ((Time.time - CountDown) > 2.0)           //如果 两次点击时间间隔大于2秒
            {
                CountDown = 0;                           //倒计时时间归零
                IsTiming = false;                       //关闭倒计时
            }

        }
        if (Application.platform == RuntimePlatform.Android && Input.GetKeyDown(KeyCode.Home)) // Home键
        {
            //Code
        }
    }
}

--ToastUtils.cs文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace SinglePay
{
    public class ToastUtils
    {
        public static void showToast(string text)
        {
            SinglePaySDKContext.GetInstance().RunOnUIThread(new AndroidJavaRunnable(() =>
            {
                AndroidJavaClass Toast = new AndroidJavaClass("android.widget.Toast");
                Toast.CallStatic<AndroidJavaObject>("makeText", SinglePaySDKContext.GetInstance().GetActivity(), text, Toast.GetStatic<int>("LENGTH_SHORT")).Call("show");
            }));
        }
    }
}

上面主要的语法知识点:

1、AndroidJavaClass 这个就是相当于C#到AndroidJava的类的映射

---- 调用静态方法Android中类的静态方法 和获取对应的静态字段

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
AndroidJavaClass jc = new AndroidJavaClass("完整的路径类名");
静态方法调用:jc.CallStatic<返回类型>("java对应的方法名",object[] args); //args:参数,类型没有传默认就是void
静态字段获取:jc.GetStatic<返回类型>("字段名称")). //public类型的字段
例子
 AndroidJavaClass Toast = new AndroidJavaClass("android.widget.Toast"); Toast.CallStatic<AndroidJavaObject>("makeText", SinglePaySDKContext.GetInstance().GetActivity(), text, Toast.GetStatic<int>("LENGTH_SHORT")).Call("show");

2、AndroidJavaObject 这个就是相当于C#到AndroidJava的对象的映射

---- 调用Android中对的方法 和获取对应的字段

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
AndroidJavaObject  jo= new AndroidJavaObject ("完整的路径类名",object[] args); //args:构成方法的参数
方法调用:jo.Call<返回类型>("方法名", object[] args); //args:参数,//类型没有传默认就是void
成员变量调用:jo.Get<int>("字段名称"));
例子:
AndroidJavaObject  singlePaySDK = new AndroidJavaObject("cn.m4399.plugin.SinglePaySDK", singlePaySDKContext.GetActivity(), "70001", "测试游戏",SCREEN_ORIENTATION_PORTRAIT, listenerProxy);
singlePaySDK.Call("doPay", singlePaySDKContext.GetActivity(), "10", "砖石", "测试数据");

3、AndroidJavaProxy接口的语法调用

----unity对应java接口

java的接口代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public  interface SDKCallbackListener
{
    void OnSDKInited(String msg);
    void OnAuthSuccess(String token);
    void OnCreatedLive(String url);
    void OnDeletedLive(String id);
}

Unity中C#的代码:

Unity C#代码实现Android Java 代码必须要完全一致,但是允许在UnityC#代码中实现多次

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class SDKCallbackListener : AndroidJavaProxy
{
        // 这句话很重要!!!C#找到Jar中接口的引用
        public SDKCallbackListener() : base("包名.SDKCallbackListener") { }

        public void OnSDKInited(string msg)
        {
            ATrace.Log( "OnSDKInited:" + msg);
        }
        public void OnAuthSuccess(string token)
        {
            ATrace.Log("OnAuthSuccess:" + token);
        }
        public void OnCreatedLive(string url)
        {
            ATrace.Log("OnCreatedLive:" + url);
        }
        public void OnDeletedLive(string id)
        {
            ATrace.Log("OnDeletedLive:" + id);
        }
}

4、AndroidJavaRunnable其实就是对应java的 java.lang.Runnable.

直接看Unity Api

总结,Android和Unity的交互就是一方导出插件的形式给一方使用,本文写法是提供了Android导出aar给Unity使用,以上就本文的全部内容,如果有什么错误的地方,欢迎大家指出
参考文献:

https://docs.unity3d.com/ScriptReference

https://www.jianshu.com/p/ceaac83808f2

https://www.jianshu.com/p/b5e3cfcdf081

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Unity与Android Studio✨之间那些不清不楚的小秘密✨(Android Studio与unity交互)
前言:因为最近在学习Unity与安卓之间的交互,所以在网上搜寻了很多关于这方面的东西。因为自己在网上搜的时候,感觉大家的东西都有些零碎,该有的差不多都有了,但是都不够全面,所以自己写篇文章用来整理这些精华 Unity与Android Studio互相调用的知识给大家分享一下
呆呆敲代码的小Y
2021/08/12
4.2K0
ARFoundation☀️ 二、工程的基础配置
Windows--Packages,选择Advanced:Show preview packages
星河造梦坊官方
2024/08/15
1650
ARFoundation☀️ 二、工程的基础配置
Unity-SDK接入
游戏客户端和第三方包进行组合 第三方代码: JAVA代码 游戏U3D代码 eclipse AndroidStudio
祝你万事顺利
2019/06/20
2.7K0
Unity-SDK接入
u3d与安卓交互(Android studio)
AndroidStudio导出 .jar文件,在Unity里使用 开发环境:as2.3.2.0,u3d5.6.0
立羽
2023/08/24
3180
u3d与安卓交互(Android studio)
unity和android的项目交互
由于近期工作要求需要给实现unity5.6.5上打包android的项目,个人算是研究一天左右,才完成这个工作,将自己遇到的坑和一些学习操作的过程,总结一下与大家分享。
包子388321
2020/06/16
2.4K0
Unity3d和Android之间互相调用
摘抄博客 Unity3d Android SDK接入解析(一)Unity3d 与 Android之间的互相调用,一共四章,一定要看完
用户3112896
2019/09/26
3.8K0
Unity3d和Android之间互相调用
【Unity游戏开发】SDK接入与集成——小白入门篇
  通常一款游戏开发到后期,一般都会涉及到第三方SDK的接入与集成,对于不熟悉SDK接入的同学来说,接SDK每次都是云里雾里,而熟悉SDK接入的同学又觉得不断地重复做接入SDK工作这样没有成就感,太尼玛无聊了(Android渠道一弄就十几个,直接吐血)。其实通常情况下接入SDK都是很简单的一个过程,本系列博客就让马三和大家从小白开始,从零基础开始学习如何接入SDK以及一些常见的SDK的接入流程。本系列博客规划为以下几篇:
马三小伙儿
2018/09/12
5.8K2
【Unity游戏开发】SDK接入与集成——小白入门篇
【Unity】QQ登录SDK接入(Unity&Android)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
bering
2019/12/03
3K0
“别人用Unity写代码为啥这么快,这么强”,“因为用了工具类呀”
在开发中,我们会将调用次数比较多的函数单独提出来写到一个类中,比如字符串转16进制,给字符串加密这些都是比较常用的,就可以将这些常用的函数提取出来,放到工具类中,方便调用
恬静的小魔龙
2022/08/07
9620
Unity与Android交互之✨| 使用AndroidJavaProxy代理方式,让Android与Unity通讯
下面我们就先从Android Studio端开始一步一步做起,Android Studio下面统称AS
呆呆敲代码的小Y
2021/10/29
4K0
Unity与Android交互之✨| 使用AndroidJavaProxy代理方式,让Android与Unity通讯
Unity与Android Studio交互之 ✨ 获取手机权限(存储、录音、相机等)
Unity通过Android Studio 获取手机权限(存储、录音、相机等) 文章目录 Unity通过Android Studio 获取手机权限(存储、录音、相机等) 常用权限 一、动态获取权限流程 二、使用步骤 1.检测当前是否已获取权限 2.检测当前安卓版本 3.申请动态获取权限 总结 ---- 常用权限 <!--连接网络权限,用于执行云端语音能力 --> <uses-permission android:name="android.permission.INTERNET"/> <!--获取手机录音
呆呆敲代码的小Y
2021/08/12
2.4K1
unity3d+androidstudio:接微信官方分享sdk
1.得到的签名在微信后台一定要填对,不然返回-6 2.如果测试微信调不起来,清除微信缓存,即可,因为上次的错误信息保存了
立羽
2023/08/24
2880
unity3d+androidstudio:接微信官方分享sdk
Unity 和 Android 的工程集成
有时候,我们需要在 Unity 里调用一些 Android 的功能,这些功能在 Unity 中可能并没有提供接口,需要在 Android 平台上实现。此时,我们需要有一个方法来让 Android 代码和 Unity 代码互调用。这里记录一下操作方法,并提供一个工具来简化两个工程之间的集成流程。
zhiruili
2023/10/20
7640
Unity 和 Android 的工程集成
Unity3D研究院之打开照相机与本地相册进行裁剪显示
Unity与Android的交互 如果有不会的朋友请看MOMO之前的文章喔,Unity3D研究院之打开Activity与调用JAVA代码传递参数(十八)这里有关交互的方式就不详细说明,主要将如何在Unity中打开摄像机、在Unity中打开本地相册,选一个照片后如何进行裁剪,最后将图片转换成Texture显示在U3D的世界当中。
bering
2019/12/02
1.5K0
Unity与Android调用交互
AS 和 Unity 之间如何通信。AS 和 Unity 之间通信的方法介绍如下:
呆呆敲代码的小Y
2021/08/12
1.4K0
Unity3D与Android的交互通信(Unity3D)
&emsp; 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧。
恬静的小魔龙
2022/08/07
2.4K0
Unity3D与Android的交互通信(Unity3D)
unity+Android:剪切板
立羽
2023/08/24
4120
Unity项目中调用Android方法实现分享功能
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
bering
2019/12/03
2.1K0
unity3d+android:支付宝
给服务器发商品id与数量,服务器向支付宝后台请求下单信息,服务器再发给客户端调用android端
立羽
2023/08/24
4140
unity3d+android:支付宝
Android/Unity大乱斗-完整双方集成交互指南
源码地址:https://github.com/RXlung/Android-Unity---
芝麻粒儿
2021/08/03
1.4K0
Android/Unity大乱斗-完整双方集成交互指南
推荐阅读
相关推荐
Unity与Android Studio✨之间那些不清不楚的小秘密✨(Android Studio与unity交互)
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档