Unity 中的回调侦听器 - 如何从 Android 中的 UnityPlayerActivity 调用脚本文件方法

Posted

技术标签:

【中文标题】Unity 中的回调侦听器 - 如何从 Android 中的 UnityPlayerActivity 调用脚本文件方法【英文标题】:Callback Listener in Unity - How to call script file method from UnityPlayerActivity in Android 【发布时间】:2015-10-05 08:47:02 【问题描述】:

我有一个android库项目,并在Unity项目中导入了库项目。现在,我想在 Unity 项目中实现一个回调,它将根据 android 库项目给出的响应执行。我的意思是说,从 UnityPlayerActivity(Android 项目)调用脚本文件方法。

目前我正在使用以下代码行,但没有任何反应:

UnityPlayer.UnitySendMessage("Main Camera","showMessage",errorMessage);

Main Camera 是我的游戏对象。 showMessage 是脚本文件中的消息名称。 Message 是通过 Android Activity 显示在 Unity 中的消息。

请检查我下面的代码 Unity 脚本文件和 Android Activity。

Unity 脚本文件:

using UnityEngine;
using System.Collections;

public class scriptfile : MonoBehaviour 

    // Use this for initialization
    void Start () 


        AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); 
        AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); 
        jo.Call("shareText","236","236");
    

    void showMessage(string message)
        print ("hello");
        Debug.Log ("hello");
     

Android 文件 UnityPlayerActivity:

/**
 * Created by CH-E01073 on 28-09-2015.
 */
public class MainAct extends UnityPlayerActivity implements RegistrationListener,BOffersListener 
    Context context;
    SharedPreferences prefs ;
    String AppIds="";
    String PublisherIDs="";
     public void shareText(String AppId,String PublisherID) 
       context=MainAct.this;
        prefs = PreferenceManager
               .getDefaultSharedPreferences(context);
       Log.e("AppID", AppId);
       Log.e("PublisherID",PublisherID);

        AppIds=AppId;
        PublisherIDs=PublisherID;

         runOnUiThread(new Runnable() 
             @Override
             public void run() 
                 UnityPlayer.UnitySendMessage("Main Camera","showMessage","Start UI Thread");
                 if (prefs.getString(FreeBConstants.ID, null) == null
                         || prefs.getString(FreeBConstants.ID, null).equals("")
                         || !Build.VERSION.RELEASE.equals(prefs.getString(
                         FreeBConstants.VERSION, null))
                         || !FreeBCommonUtility.getDeviceId(context).equals(
                         (prefs.getString(FreeBConstants.DEVICE_ID, null)))) 
                BSDKLogger.enableLogging(true);
                SDKRegistration.initialize(MainAct.this, getApplicationContext(), AppIds,PublisherIDs);
                 else

                Offers Offers = new Offers(MainAct.this);
                 Offers.setOnFreeBOffersListener(MainAct.this);
                 Offers.setTitle(
                         "Pick Any Offer to unlock your premium features",
                         "#FFFFFF", "#FF6D00");
                 
         
         );



    

    @Override
    public void onOffersLoaded(String code,String freeBOffers) 
        CommonUtility.showToast(getApplicationContext(), code);
        UnityPlayer.UnitySendMessage("Main Camera","showMessage",freeBOffers);
    

    @Override
    public void onShowOffers() 

         UnityPlayer.UnitySendMessage("Main Camera","showMessage","Show Offers");
    

    @Override
    public void noOfferInstalled(String s, String s2) 
    

    @Override
    public void onLeaveApplication(String s, String s2) 
    

    @Override
    public void onDialogDismiss(String s) 
    

    @Override
    public void onOffersFailed(String code, String errorMessage) 

        FreeBCommonUtility.showToast(getApplicationContext(), errorMessage);
        UnityPlayer.UnitySendMessage("Main Camera","showMessage",errorMessage);
    

    @Override
    public void onOffersInstallSuccess(String code, String errorMessage) 
         FreeBCommonUtility.showToast(getApplicationContext(), errorMessage);
    

    @Override
    public void onOffersInstallFailure(String code, String errorMessage) 
         FreeBCommonUtility.showToast(getApplicationContext(), errorMessage);
    


    @Override
    public void onRegistrationFailed(String code, String errorMessage) 
        FreeBCommonUtility.showToast(getApplicationContext(), errorMessage);
        UnityPlayer.UnitySendMessage("Main Camera","showMessage",errorMessage);
    

    @Override
    public void onRegistrationSuccess(String code, String errorMessage) 
      // FreeBCommonUtility.showToast(getApplicationContext(), errorMessage);
        Log.e("SUCCESS", errorMessage);
        // TODO Auto-generated method stub
        UnityPlayer.UnitySendMessage("Main Camera","showMessage",errorMessage);

        Offers Offers = new Offers(MainAct.this);
        Offers.setOnFreeBOffersListener(MainAct.this);
       Offers.setTitle(
             "Pick Any Offer to unlock your premium features",
              "#FFFFFF", "#FF6D00");
    

谁能帮我解决这个问题?

【问题讨论】:

确保你的脚本附加了主摄像机(被调用的游戏对象)。见参考文献answers.unity3d.com/questions/366452/… 是的 vivek,它已经正确连接了。 我个人不太喜欢Unity消息系统,为什么不使用回调接口呢? 有没有办法实现android与unity之间通信的接口。确切地说,如果我们想在 unity 内或在 android 模块内进行通信,接口是个好主意。这里我们要在 Android Activity 和 Unity Script File 之间建立桥梁。 【参考方案1】:

另一种选择是使用 AndroidJavaProxy 实现接口回调。除了使用 UnitySendMessage,您可以简单地在 Java 代码中使用接口回调,然后使用 AndroidJavaProxy 在 C# 中实现此接口,并将其传递给 Java 方法以接收返回的消息。

创建您的 Java 界面:

package com.example.android;
public interface PluginCallback 
    public void onSuccess(String videoPath);
    public void onError(String errorMessage);

调用传入的监听器/回调函数返回消息

public void myPluginMethod(PluginCallback callback) 
    // Do something
    callback.onSuccess("onSuccess");
    // Do something horrible
    callback.onError("onError");

用C#实现接口

class AndroidPluginCallback : AndroidJavaProxy
    
        public AndroidPluginCallback() : base("com.example.android.PluginCallback")  

        public void onSuccess(string videoPath) 
            Debug.Log("ENTER callback onSuccess: " + videoPath);
        
        public void onError(string errorMessage)
        
            Debug.Log("ENTER callback onError: " + errorMessage);
        
    

将 C# 接口传递给 Java 方法

AndroidJavaObject pluginClass = new     AndroidJavaObject("com.example.android.MyPlugin");
pluginClass.Call("myPluginMethod", new AndroidPluginCallback());

【讨论】:

我的班级必须是AppCompatActivity。我收到一个错误AndroidJavaException: java.lang.IllegalStateException: Method addObserver must be called on the main thread。我尝试了runOnUiThread(new Runnable() @Override public void run() callback.onSuccess("Some message"); 之类的方法,但无法使其正常工作。有什么想法吗?【参考方案2】:

我相信您只能从主线程调用 UnitySendMessage() - 至少在上述一种情况下,您是从 Android UI 工作线程调用它。

作为一个快速的健全性测试,请尝试在您的 shareText() 函数顶部调用它。

【讨论】:

以上是关于Unity 中的回调侦听器 - 如何从 Android 中的 UnityPlayerActivity 调用脚本文件方法的主要内容,如果未能解决你的问题,请参考以下文章

使用具有多个模块的模块模式,一个模块中的事件监听器如何使用来自另一个模块的回调?

如何从 JavaScript 监听器创建 Dart Stream

如何在 Kotlin 中使用回调?

当 `this` 不可用时,从拖动回调中检索 DOM 目标

如何从根祖先访问 Flutter 中最新的脚手架?

目标 -C 回调不适用于不幸的后台崩溃