Unity 和 Android Studio 的双向通信

具体功能:

在雷电模拟器运行程序,实现了点击Button,调用Android Studio中的点击方法,然后在Android Studio中再调用Unity的C#脚本中的修改Text文本内容的方法。

基础设置:

先查看是否下载好Android包

查看Edit-Preferences-External Tools是否如图无警告(这样环境才算配置好了)

好像还得有这个

具体案例:

效果:

Unity操作:

UI搭建:

脚本:

using UnityEngine;
using UnityEngine.UI;

public class UIManager : MonoBehaviour
{
    public Button btnButton;

    private UnityToAndroid unityToAndroid;

    void Start()
    {
        unityToAndroid = FindObjectOfType<UnityToAndroid>();

        btnButton.onClick.AddListener(() => unityToAndroid.OnBtn());
    }
}
using UnityEngine;
using UnityEngine.UI;

public class UnityToAndroid : MonoBehaviour
{
    public Text uiText;
    public Button textButton;
    private AndroidJavaObject unityActivity;

    void Start()
    {
        // 获取当前的 UnityPlayer Activity
        using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            unityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        }
    }

    // 该方法将由 Android 调用来更新 UI 文本
    public void UpdateUIText(string message)
    {
        if (uiText != null)
        {
            uiText.text = message+Random.Range(0,1000);
        }
    }
    // Unity 中的 OnText 函数
    public void OnText(string message)
    {
        Debug.Log("Unity OnText: " + message);
        // 调用 Android 中的 OnText 函数
        if (unityActivity != null)
        {
            unityActivity.Call("OnText", message);
        }
    }

    // Unity 中的 OnBtn 函数
    public void OnBtn()
    {
        Debug.Log("Unity OnBtn called");
        // 调用 Android 中的 OnBtn 函数
        if (unityActivity != null)
        {
            unityActivity.Call("OnBtn");
        }
    }
}

打包:

File-Build Settings(场景托进来后勾选Export Project再点击Export)

创建用来存放Android包的文件夹,并选择

打包后,复制Android包所在文件夹的路径(或者把这个文件夹用Android Studio打开)

Android Studio操作:

打开脚本:

全部代码:

导入命名空间
import android.util.Log;
import android.widget.Toast;
类中插入代码
    private static final String TAG = "UnityPlayerActivity";
    
    // Android 中的 OnText 函数
    public void OnText(final String message) {
        Log.d(TAG, "Android OnText: " + message);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(UnityPlayerActivity.this, "Received from Unity: " + message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    // Android 中的 OnBtn 函数
    public void OnBtn() {
        Log.d(TAG, "Android OnBtn called");
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                OnText("Button clicked in Unity called Android OnBtn");
                UnityPlayer.UnitySendMessage("YourGameObjectName", "UpdateUIText", "当前数字是:");
            }
        });
    }
完整内容如下:
package com.unity3d.player;

import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.os.Process;

import android.util.Log;
import android.widget.Toast;

public class UnityPlayerActivity extends Activity implements IUnityPlayerLifecycleEvents
{
    private static final String TAG = "UnityPlayerActivity";
    protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code

    // Override this in your custom UnityPlayerActivity to tweak the command line arguments passed to the Unity Android Player
    // The command line arguments are passed as a string, separated by spaces
    // UnityPlayerActivity calls this from 'onCreate'
    // Supported: -force-gles20, -force-gles30, -force-gles31, -force-gles31aep, -force-gles32, -force-gles, -force-vulkan
    // See https://docs.unity3d.com/Manual/CommandLineArguments.html
    // @param cmdLine the current command line arguments, may be null
    // @return the modified command line string or null
    protected String updateUnityCommandLineArguments(String cmdLine)
    {
        return cmdLine;
    }

    // Setup activity layout
    @Override protected void onCreate(Bundle savedInstanceState)
    {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);

        String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity"));
        getIntent().putExtra("unity", cmdLine);

        mUnityPlayer = new UnityPlayer(this, this);
        setContentView(mUnityPlayer);
        mUnityPlayer.requestFocus();
    }

    // When Unity player unloaded move task to background
    @Override public void onUnityPlayerUnloaded() {
        moveTaskToBack(true);
    }

    // Callback before Unity player process is killed
    @Override public void onUnityPlayerQuitted() {
    }
    
    // Android 中的 OnText 函数
    public void OnText(final String message) {
        Log.d(TAG, "Android OnText: " + message);
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(UnityPlayerActivity.this, "Received from Unity: " + message, Toast.LENGTH_SHORT).show();
            }
        });
    }

    // Android 中的 OnBtn 函数
    public void OnBtn() {
        Log.d(TAG, "Android OnBtn called");
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                OnText("Button clicked in Unity called Android OnBtn");
                UnityPlayer.UnitySendMessage("YourGameObjectName", "UpdateUIText", "当前数字是:");
            }
        });
    }

    @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.
        setIntent(intent);
        mUnityPlayer.newIntent(intent);
    }

    // Quit Unity
    @Override protected void onDestroy ()
    {
        mUnityPlayer.destroy();
        super.onDestroy();
    }

    // If the activity is in multi window mode or resizing the activity is allowed we will use
    // onStart/onStop (the visibility callbacks) to determine when to pause/resume.
    // Otherwise it will be done in onPause/onResume as Unity has done historically to preserve
    // existing behavior.
    @Override protected void onStop()
    {
        super.onStop();

        if (!MultiWindowSupport.getAllowResizableWindow(this))
            return;

        mUnityPlayer.pause();
    }

    @Override protected void onStart()
    {
        super.onStart();

        if (!MultiWindowSupport.getAllowResizableWindow(this))
            return;

        mUnityPlayer.resume();
    }

    // Pause Unity
    @Override protected void onPause()
    {
        super.onPause();

        MultiWindowSupport.saveMultiWindowMode(this);

        if (MultiWindowSupport.getAllowResizableWindow(this))
            return;

        mUnityPlayer.pause();
    }

    // Resume Unity
    @Override protected void onResume()
    {
        super.onResume();

        if (MultiWindowSupport.getAllowResizableWindow(this) && !MultiWindowSupport.isMultiWindowModeChangedToTrue(this))
            return;

        mUnityPlayer.resume();
    }

    // Low Memory Unity
    @Override public void onLowMemory()
    {
        super.onLowMemory();
        mUnityPlayer.lowMemory();
    }

    // Trim Memory Unity
    @Override public void onTrimMemory(int level)
    {
        super.onTrimMemory(level);
        if (level == TRIM_MEMORY_RUNNING_CRITICAL)
        {
            mUnityPlayer.lowMemory();
        }
    }

    // This ensures the layout will be correct.
    @Override public void onConfigurationChanged(Configuration newConfig)
    {
        super.onConfigurationChanged(newConfig);
        mUnityPlayer.configurationChanged(newConfig);
    }

    // Notify Unity of the focus change.
    @Override public void onWindowFocusChanged(boolean hasFocus)
    {
        super.onWindowFocusChanged(hasFocus);
        mUnityPlayer.windowFocusChanged(hasFocus);
    }

    // For some reason the multiple keyevent type is not supported by the ndk.
    // Force event injection by overriding dispatchKeyEvent().
    @Override public boolean dispatchKeyEvent(KeyEvent event)
    {
        if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
            return mUnityPlayer.injectEvent(event);
        return super.dispatchKeyEvent(event);
    }

    // Pass any events not handled by (unfocused) views straight to UnityPlayer
    @Override public boolean onKeyUp(int keyCode, KeyEvent event)     { return mUnityPlayer.onKeyUp(keyCode, event); }
    @Override public boolean onKeyDown(int keyCode, KeyEvent event)   { return mUnityPlayer.onKeyDown(keyCode, event); }
    @Override public boolean onTouchEvent(MotionEvent event)          { return mUnityPlayer.onTouchEvent(event); }
    @Override public boolean onGenericMotionEvent(MotionEvent event)  { return mUnityPlayer.onGenericMotionEvent(event); }
}

具体操作

Build

打开雷电模拟器再按下图操作

最后运行

如图开始运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值