源代码:GitHub - sueleeyu/arunitylib: 导出lib的unity工程
1.unity编写脚本AndroidHandler.cs,挂载到AR Camera上,(AR Camera的name为MainCamera,对应MainActivity中CallUnityFun的receiveObj)
2. AndroidHandler.cs增加调用unit调用android的代码:
public void OnClickToJavaFunSum()
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.MainActivity");
AndroidJavaObject jo = jc.CallStatic
messageText.text = jo.Call<int>("Sum", 5, 3).ToString();
}
3. AndroidHandler.cs增加android to unity的回调:
public void Receive(string str)
{
receiveMessageText.text = str;
}
4.AndroidHandler.cs:
using UnityEngine;
using UnityEngine.UI;
namespace UnityEngine.XR.ARFoundation.Samples
{
public class AndroidHandler : MonoBehaviour
{
private AndroidJavaObject javaObject;//MainActivity对象
[SerializeField]
private Text messageText;//unity场景显示Text
[SerializeField]
private Text receiveMessageText;//unity场景显示Text
// Start is called before the first frame update
void Start()
{
//第二种
AndroidJavaClass android = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
javaObject = android.GetStatic
}
public void OnClickToJavaFunSum()
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.MainActivity");
AndroidJavaObject jo = jc.CallStatic
messageText.text = jo.Call<int>("Sum", 5, 3).ToString();
}
public void OnClickToJavaFunSum2()
{
messageText.text = javaObject.Call<int>("Sum", 5, 3).ToString();
}
public void OnClickCall1()//android调用unity的启动示例,unity调用android的CallUnityFun方法,通过UnityPlayer.UnitySendMessage向unity发送消息
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.MainActivity");//MainActivity继承UnityPlayerActivity
AndroidJavaObject jo = jc.CallStatic
jo.Call("CallUnityFun", "Test2");//调用android端方法CallUnityFun
}
public void OnClickCall2()
{
javaObject.Call("CallUnityFun", "Test1");//调用android端方法CallUnityFun
}
//接收来自android的参数
public void Receive(string str)
{
receiveMessageText.text = str;
}
}
}
5. unity增加调用android按钮事件:
Unity场景新建Button,新增挂载OnClick方法,选择AndroidHander-OnClickToJavaFunSum。
6. unity中增加android调用unity按钮事件:
Unity场景新建Button,新增挂载OnClick方法,选择AndroidHander- OnClickCall1。
7.unity中增加2个调用展示Text:
u call a,a call u
8.File-build setting –player setting修改导出设置:
9.File-build settings-Android,导出为android工程。
1.新建或打开android工程,包名:com.xxx.xxxxx同unity一样
(包名可以不同)
2.拷贝导出的Unity下的 unityLibrary 到 安卓工程根目录
3.打开setting.gradle,增加:
include ':unityLibrary'
4.打开gradle.properties,增加:
unityStreamingAssets=.unity3d
5.打开local.properties,增加你的NDK路径:
6.Project的build.gradle在repositories增加:
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
7.app的build.gradle增加ndk:
ndk {
abiFilters 'armeabi-v7a'
}
8.app的build.gradle增加dependencies:
implementation project(':unityLibrary')
9.app的androidmanifest.xml的application增加:
<application
android:extractNativeLibs="true"
10.运行:
1.unityLibrary增加MainActvity,继承UnityPlayerActivity,代码都在MainActivity中编写:
package com.unity3d.player;
import android.os.Bundle;
import android.view.KeyEvent;
public class MainActivity extends UnityPlayerActivity{
private static MainActivity instance;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
}
public static MainActivity GetInstance()
{
return instance;
}
@Override public boolean dispatchKeyEvent(KeyEvent event)
{
if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){
onBackPressed();
return true;
}
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return mUnityPlayer.injectEvent(event);
return super.dispatchKeyEvent(event);
}
//------
@Override
public void onBackPressed() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mUnityPlayer.quit();
}
});
super.onBackPressed();
}
//unity调用android的方法
public int Sum(int x, int y)
{
return x + y;
}
public void CallUnityFun(String str)
{
String receiveObj = "MainCamera";//unity中脚本挂载的Object的name
String receiveMethod = "Receive";//unity中Object挂载脚本的方法名
String params = str + " Android Call Unity.";//方法要穿的参数
//android调用unity,
UnityPlayer.UnitySendMessage(receiveObj, receiveMethod, params);
}
}
2.修改unityLibrary的manifest文件,UnityPlayerActivity改为MainActivity:
android:name="com.unity3d.player.MainActivity"
UnitySendMessage方法的使用:
UnitySendMessage在android端调用,在回调方法被触发时,通过UnitySendMessage方法把结果发给unity,让unity这边处理。UnitySendMessage(“string”,“string”, ***),这是方法,我们至少需要传入两个参数,第一个参数为unity中的cs代码挂载的gameobject的名称(本例AR Camera的name为MainCamera,对应MainActivity中CallUnityFun的UnitySendMessage的receiveObj=” MainCamer”)
,第二个参数为这个gameobject身上捆绑的脚本中的一个方法,而第三参数事实上是这个对应方法上的参数,有没有参数就看你了。
1.app的Strings.xml增加如下,否则会报错:
<string name="game_view_content_description">Game viewstring>
2.android代码MainActivity增加调用代码,如下:
package com.suelee.libtest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
public static final int REQUSET = 1;
private TextView tv01;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv01 = (TextView) findViewById(R.id.tv01);
findViewById(R.id.callJs).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
tv01.setText("调用");
Intent intent = new Intent(MainActivity.this,
com.unity3d.player.MainActivity.class);
//发送意图标示为REQUSET=1
startActivityForResult(intent, REQUSET);
//startActivity(new Intent(MainActivity.this, UnityPlayerActivity.class));
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {//请求参数、返回参数、返回的intent
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
//requestCode标示请求的标示 resultCode表示有数据
if (requestCode == MainActivity.REQUSET && resultCode == RESULT_OK) {
}
String str = "从unity返回";
runOnUiThread(new Runnable() {
@Override
public void run() {
tv01.setText(str);
}
});
Toast.makeText(
this,
"requestCode=" + requestCode + ":" + "resultCode=" + resultCode,
Toast.LENGTH_LONG).show();
}
}
3. activity_main:
xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.suelee.libtest.MainActivity">
<TextView
android:id="@+id/tv01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Android App页面"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/callJs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="调用unity AR"
android:textAllCaps="false"
tools:ignore="MissingConstraints" />
androidx.constraintlayout.widget.ConstraintLayout>
4.运行:
1. NDK was located by using ndk.dir property. This method is deprecated and will be removed in a future release. Please use android.ndkVersion or android.ndkPath in build.gradle to specify the NDK to use. https://developer.android.com/r/studio-ui/ndk-dir
解决:在模块的 build.gradle 文件中使用 android.ndkVersion 属性指定相应的版本,如以下代码示例所示,android下加:
android {
ndkVersion = "major.minor.build" // e.g., ndkVersion "21.3.6528147"
}
2. Caused by: java.lang.RuntimeException: Duplicate class androidx.annotation.AnimRes found in modules annotation-1.3.0 (androidx.annotation:annotation:1.3.0) and jetified-com.android.support.support-annotations-26.1.0 (com.android.support.support-annotations-26.1.0.jar)
解决:删掉unityLIbrary下lib下对应的jar文件
3.打包出现duplicate,删除unityLIbrary下libs下对应的jar文件和buil.gradle里的对应implementation
4.
解决:禁用intel显卡驱动
5.unity返回android的activity会退出:
Androidmenufest中增加android:process=":UnityActivity",android:launchMode="singleInstance"或android:launchMode="standard"
:
<activity android:name="com.unity3d.player.MainActivity" android:process=":UnityActivity" android:theme="@style/UnityThemeSelector" android:screenOrientation="fullSensor" android:launchMode="singleInstance" 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" />
intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
<meta-data android:name="android.notch_support" android:value="true" />
<meta-data android:name="android.notch_support" android:value="true" />
activity>
1.Unity api:Unity - Manual: Unity User Manual 2021.3 (LTS)
2.ARFoundation示例:
GitHub - Unity-Technologies/arfoundation-samples: Example content for Unity projects based on AR Foundation
3.源代码:GitHub - sueleeyu/arunitylib: 导出lib的unity工程