开发Unity增强现实vuforia应用程序并与本机Android应用程序集成

时间:2023-01-22 20:17:06

I have an e-commerence application with complex UI and argument reality features like model rendering and image recognition. Application required to support image recognition feature to low end devices as well which is not supported by ARCORE yet. So only option is Unity. Due to no experience in unity, want to develop application in android java (all UI components, add to cart and payment feature) and AR module in unity vuforia. Then integrate unity AR module code in android application and call it from java code. I have seen few tutorials in which java and unity code integrated but those are sample projects with little back forth communication.

我有一个e-commerence应用程序,具有复杂的UI和参数现实功能,如模型渲染和图像识别。支持图像识别功能所需的应用程序也适用于低端设备,但ARCORE尚不支持。所以唯一的选择是Unity。由于没有统一的经验,想在android java中开发应用程序(所有UI组件,添加到购物车和支付功能)和AR模块在统一vuforia。然后在android应用程序中集成统一AR模块代码并从java代码调用它。我已经看到很少有java和统一代码集成的教程,但那些是几乎没有反向沟通的示例项目。

So Is this a good approach to develop UI native and AR rendering in unity and then integrate it together? If yes then how much difficulty can be caused by this approach ?

那么这是一个很好的方法来统一开发UI原生和AR渲染,然后将它们集成在一起吗?如果是,那么这种方法会带来多大的困难?

4 个解决方案

#1


2  

I would create the mobile app in UI in unity itself. Unity has many modules for working in mobile AR that i highly recommend you look at. If you know java, then working in c# is not difficult at all They are practically the same. You can do all the UI elements using Vuforia, I do not see why that is an issue. In fact, Vuforia does allow you to use android studio with it, so maybe that route is the best for you.

我会在UI中以统一的方式创建移动应用程序。 Unity有许多用于移动AR的模块,我强烈建议你看看。如果你了解java,那么在c#中工作并不困难它们实际上是一样的。您可以使用Vuforia执行所有UI元素,我不明白为什么这是一个问题。事实上,Vuforia确实允许你使用android studio,所以也许这条路线最适合你。

#2


2  

Android to Unity communication is very simple. I'm using it from last 3 years and its working like a charm :)

Android到Unity的沟通非常简单。我使用它从过去3年,它的工作就像一个魅力:)

IMP: When developing a Unity Android application, it is possible to extend the standard UnityPlayerActivity class (the primary Java class for the Unity Player on Android, similar to AppController.mm on Unity iOS). An application can override any and all of the basic interaction between the Android OS and the Unity Android application.

IMP:在开发Unity Android应用程序时,可以扩展标准UnityPlayerActivity类(Android上Unity播放器的主要Java类,类似于Unity iOS上的AppController.mm)。应用程序可以覆盖Android OS和Unity Android应用程序之间的任何和所有基本交互。

  • You can write simple Wrapper in your C# unity code and Export the Android Studio source Code from Unity.
  • 您可以在C#unity代码中编写简单的Wrapper,并从Unity导出Android Studio源代码。
  • Unity C# scripts allow you to access features like OS calls and third-party code libraries that would otherwise not be available to Unity.
  • Unity C#脚本允许您访问操作系统调用和第三方代码库等功能,否则Unity将无法使用这些功能。

First Create Code inside Unity and call the android function from unity

首先在Unity中创建代码并从统一调用android函数

1. First Create Build in Unity Editor:

1.首先在Unity编辑器中创建构建:

You need to call a Native Android method from Unity or vice-versa : Eg:

您需要从Unity调用Native Android方法,反之亦然:例如:

 public void OpenActivity()
    {
        var androidJC = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        var jo = androidJC.GetStatic<AndroidJavaObject>("currentActivity");
        // Accessing the class to call a static method on it
        var jc = new AndroidJavaClass("com.xyz.abc.StartActivity");
        // Calling a Call method to which the current activity is passed
        jc.CallStatic("Call", jo);
    }

}

Replace it by your activity and package name

将其替换为您的活动和包名称

var jc = new AndroidJavaClass("com.xyz.abc.StartActivity");

In C# (Caller)

在C#(来电者)

jc.CallJavaFunc( "javaTestFunc", "UnityJavaJarTest" );

In Android (Callee)

在Android(Callee)中

public void javaTestFunc(String strFromUnity) { 
    /* ... Do something here with java native api ... */ 
} 

2. Then Export the code as development build and import the same in Android studio:

2.然后将代码导出为开发版本并在Android studio中导入相同的代码:

In Android Studio Extend/Modify the UnityPlayerActivity. The UnityPlayerActivity.java file

在Android Studio中扩展/修改UnityPlayerActivity。 UnityPlayerActivity.java文件

In Android (Caller)

在Android(来电者)

UnityPlayer.UnitySendMessage("AndroidManager", "SetJavaLog", strFromUnity + "HelloWorld"); 

In C# (Callee)

在C#(Callee)中

void SetJavaLog(string strJavaLog)
{
    strLog = strJavaLog;
    _text.text = strLog;
}

Then Create a new Android Manifest to set the new activity as the entry point of your application.

然后创建一个新的Android Manifest,将新活动设置为应用程序的入口点。

VERY VERY IMP: Though this method support string , still for relible output use pointer/IntPtr

非常非常IMP:虽然这个方法支持字符串,仍然用于可靠的输出使用指针/ IntPtr


Here is Complete Example Code:

这是完整的示例代码:

Java:

Java的:

public final class MyPlugin { //Make class static variable so that the callback function is sent to one instance of this class. public static MyPlugin testInstance;

public final class MyPlugin {//使类静态变量,以便将回调函数发送到此类的一个实例。 public static MyPlugin testInstance;

 public static MyPlugin instance()
 {
     if(testInstance == null)
     {
         testInstance = new MyPlugin();
     }
     return testInstance;
 }

string result = "";


public string UnitySendMessageExtension(string gameObject, string functionName, string funcParam)
{
    UnityPlayer.UnitySendMessage(gameObject, functionName, funcParam);
    string tempResult = result;
    return tempResult;
}

//Receives result from C# and saves it to result  variable
void receiveResult(string value)
{
    result = "";//Clear old data
    result = value; //Get new one
}}

C#:

C#:

class TestScript: MonoBehaviour
{
    //Sends the data from PlayerPrefs to the receiveResult function in Java
    void sendResultToJava(float value)
    {
        using(AndroidJavaClass javaPlugin = new AndroidJavaClass("com.company.product.MyPlugin"))
        {
             AndroidJavaObject pluginInstance = javaPlugin.CallStatic("instance");
             pluginInstance.Call("receiveResult",value.ToString());
        }
    }

    //Called from Java to get the saved PlayerPrefs
    void testFunction(string key)
    {
        float value = PlayerPrefs.GetFloat(key) //Get the saved value from key
        sendResultToJava(value); //Send the value to Java
    }}

Usage from Java:

Java的用法:

String str = UnitySendMessageExtension("ProfileLoad", "testFunction","highScore"); 

#3


1  

If you are experienced in Android, I wouldn't create everything in Unity, as UI canvas renderer does not exactly fit with complex UI like phone apps UI. I have done a project a bit opposite to yours where I used native functions like Gallery View and 360 Image Viewer in Android calling from Unity. Remember that when you run Unity in Android, it is actually an android app wrapping over Unity. So you are already using Android app and Unity.

如果您在Android方面经验丰富,我不会在Unity中创建所有内容,因为UI画布渲染器并不完全适合复杂的UI,如手机应用程序UI。我做了一个与你的项目有点相反的项目,我在Unity中使用了Gallery View和360 Image Viewer等原生函数。请记住,当您在Android中运行Unity时,它实际上是一个环绕Unity的Android应用程序。所以你已经在使用Android应用和Unity了。

If you do not know much about Android, you will spend too much time configuring stuff that is hard to maintain. So weigh it, if you do everything in Unity it will be easy to deploy your app in IOS as well.

如果您对Android不太了解,那么您将花费太多时间来配置难以维护的内容。所以权衡它,如果你在Unity中做所有事情,那么在IOS中部署你的应用程序也很容易。

This is the way I did it in Android https://docs.unity3d.com/Manual/AndroidUnityPlayerActivity.html

这是我在Android中的方式https://docs.unity3d.com/Manual/AndroidUnityPlayerActivity.html

#4


0  

If you are not familiar with Unity, you will take longer to build an application like that in unity. For Android, you can use OpenCV.

如果您不熟悉Unity,则需要更长时间才能构建一个统一的应用程序。对于Android,您可以使用OpenCV。

#1


2  

I would create the mobile app in UI in unity itself. Unity has many modules for working in mobile AR that i highly recommend you look at. If you know java, then working in c# is not difficult at all They are practically the same. You can do all the UI elements using Vuforia, I do not see why that is an issue. In fact, Vuforia does allow you to use android studio with it, so maybe that route is the best for you.

我会在UI中以统一的方式创建移动应用程序。 Unity有许多用于移动AR的模块,我强烈建议你看看。如果你了解java,那么在c#中工作并不困难它们实际上是一样的。您可以使用Vuforia执行所有UI元素,我不明白为什么这是一个问题。事实上,Vuforia确实允许你使用android studio,所以也许这条路线最适合你。

#2


2  

Android to Unity communication is very simple. I'm using it from last 3 years and its working like a charm :)

Android到Unity的沟通非常简单。我使用它从过去3年,它的工作就像一个魅力:)

IMP: When developing a Unity Android application, it is possible to extend the standard UnityPlayerActivity class (the primary Java class for the Unity Player on Android, similar to AppController.mm on Unity iOS). An application can override any and all of the basic interaction between the Android OS and the Unity Android application.

IMP:在开发Unity Android应用程序时,可以扩展标准UnityPlayerActivity类(Android上Unity播放器的主要Java类,类似于Unity iOS上的AppController.mm)。应用程序可以覆盖Android OS和Unity Android应用程序之间的任何和所有基本交互。

  • You can write simple Wrapper in your C# unity code and Export the Android Studio source Code from Unity.
  • 您可以在C#unity代码中编写简单的Wrapper,并从Unity导出Android Studio源代码。
  • Unity C# scripts allow you to access features like OS calls and third-party code libraries that would otherwise not be available to Unity.
  • Unity C#脚本允许您访问操作系统调用和第三方代码库等功能,否则Unity将无法使用这些功能。

First Create Code inside Unity and call the android function from unity

首先在Unity中创建代码并从统一调用android函数

1. First Create Build in Unity Editor:

1.首先在Unity编辑器中创建构建:

You need to call a Native Android method from Unity or vice-versa : Eg:

您需要从Unity调用Native Android方法,反之亦然:例如:

 public void OpenActivity()
    {
        var androidJC = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        var jo = androidJC.GetStatic<AndroidJavaObject>("currentActivity");
        // Accessing the class to call a static method on it
        var jc = new AndroidJavaClass("com.xyz.abc.StartActivity");
        // Calling a Call method to which the current activity is passed
        jc.CallStatic("Call", jo);
    }

}

Replace it by your activity and package name

将其替换为您的活动和包名称

var jc = new AndroidJavaClass("com.xyz.abc.StartActivity");

In C# (Caller)

在C#(来电者)

jc.CallJavaFunc( "javaTestFunc", "UnityJavaJarTest" );

In Android (Callee)

在Android(Callee)中

public void javaTestFunc(String strFromUnity) { 
    /* ... Do something here with java native api ... */ 
} 

2. Then Export the code as development build and import the same in Android studio:

2.然后将代码导出为开发版本并在Android studio中导入相同的代码:

In Android Studio Extend/Modify the UnityPlayerActivity. The UnityPlayerActivity.java file

在Android Studio中扩展/修改UnityPlayerActivity。 UnityPlayerActivity.java文件

In Android (Caller)

在Android(来电者)

UnityPlayer.UnitySendMessage("AndroidManager", "SetJavaLog", strFromUnity + "HelloWorld"); 

In C# (Callee)

在C#(Callee)中

void SetJavaLog(string strJavaLog)
{
    strLog = strJavaLog;
    _text.text = strLog;
}

Then Create a new Android Manifest to set the new activity as the entry point of your application.

然后创建一个新的Android Manifest,将新活动设置为应用程序的入口点。

VERY VERY IMP: Though this method support string , still for relible output use pointer/IntPtr

非常非常IMP:虽然这个方法支持字符串,仍然用于可靠的输出使用指针/ IntPtr


Here is Complete Example Code:

这是完整的示例代码:

Java:

Java的:

public final class MyPlugin { //Make class static variable so that the callback function is sent to one instance of this class. public static MyPlugin testInstance;

public final class MyPlugin {//使类静态变量,以便将回调函数发送到此类的一个实例。 public static MyPlugin testInstance;

 public static MyPlugin instance()
 {
     if(testInstance == null)
     {
         testInstance = new MyPlugin();
     }
     return testInstance;
 }

string result = "";


public string UnitySendMessageExtension(string gameObject, string functionName, string funcParam)
{
    UnityPlayer.UnitySendMessage(gameObject, functionName, funcParam);
    string tempResult = result;
    return tempResult;
}

//Receives result from C# and saves it to result  variable
void receiveResult(string value)
{
    result = "";//Clear old data
    result = value; //Get new one
}}

C#:

C#:

class TestScript: MonoBehaviour
{
    //Sends the data from PlayerPrefs to the receiveResult function in Java
    void sendResultToJava(float value)
    {
        using(AndroidJavaClass javaPlugin = new AndroidJavaClass("com.company.product.MyPlugin"))
        {
             AndroidJavaObject pluginInstance = javaPlugin.CallStatic("instance");
             pluginInstance.Call("receiveResult",value.ToString());
        }
    }

    //Called from Java to get the saved PlayerPrefs
    void testFunction(string key)
    {
        float value = PlayerPrefs.GetFloat(key) //Get the saved value from key
        sendResultToJava(value); //Send the value to Java
    }}

Usage from Java:

Java的用法:

String str = UnitySendMessageExtension("ProfileLoad", "testFunction","highScore"); 

#3


1  

If you are experienced in Android, I wouldn't create everything in Unity, as UI canvas renderer does not exactly fit with complex UI like phone apps UI. I have done a project a bit opposite to yours where I used native functions like Gallery View and 360 Image Viewer in Android calling from Unity. Remember that when you run Unity in Android, it is actually an android app wrapping over Unity. So you are already using Android app and Unity.

如果您在Android方面经验丰富,我不会在Unity中创建所有内容,因为UI画布渲染器并不完全适合复杂的UI,如手机应用程序UI。我做了一个与你的项目有点相反的项目,我在Unity中使用了Gallery View和360 Image Viewer等原生函数。请记住,当您在Android中运行Unity时,它实际上是一个环绕Unity的Android应用程序。所以你已经在使用Android应用和Unity了。

If you do not know much about Android, you will spend too much time configuring stuff that is hard to maintain. So weigh it, if you do everything in Unity it will be easy to deploy your app in IOS as well.

如果您对Android不太了解,那么您将花费太多时间来配置难以维护的内容。所以权衡它,如果你在Unity中做所有事情,那么在IOS中部署你的应用程序也很容易。

This is the way I did it in Android https://docs.unity3d.com/Manual/AndroidUnityPlayerActivity.html

这是我在Android中的方式https://docs.unity3d.com/Manual/AndroidUnityPlayerActivity.html

#4


0  

If you are not familiar with Unity, you will take longer to build an application like that in unity. For Android, you can use OpenCV.

如果您不熟悉Unity,则需要更长时间才能构建一个统一的应用程序。对于Android,您可以使用OpenCV。