android unity混合开发
unity配置
创建一个3D mobile项目,在File-Build Settings中勾选Export Project,会出现Export按钮,点击即可导出unity工程作为Android工程的module
Android配置
在settings.gradle中添加:
include ':unityLibrary' |
在Project的build.gradle的repositories下添加:
flatDir { |
在使用到unity的module依赖中添加:
implementation project(':unityLibrary') |
最后在gradle.properties中添加:
unityStreamingAssets=.unity3d, google-services-desktop.json, google-services.json, GoogleService-Info.plist |
unity在Android中的使用
unity作为activity
直接创建一个activity继承于UnityPlayerActivity,此时在activity中不需要setContentView,UnityPlayerActivity中会创建一个UnityPlayer并调用setContentView(mUnityPlayer);。UnityPlayer本质是一个FrameLayout,可以使用addView来在其中添加其他View
unity作为fragment
在onCreateView中初始化unityPlayer
|
另外在fragment的onResume、onPause、onDestroy等生命周期中需要相应的调用UnityPlayer的对应生命周期的方法。
unity与Android的交互
Android调用unity中的方法
使用UnityPlayer.UnitySendMessage(String gameObjectName, String methodName, String param);(不推荐)
UnityPlayer.UnitySendMessage有三个参数,且都为string类型,第一个参数为需要调用的gameObject名称,第二个参数为需要调用的方法名称,第三个参数为需要调用的方法中的参数。
因为只有一个参数来进行参数传递,因此使用这种方法不能调用unity中参数大于一个的方法,并且也获取不到方法的返回值。当unity中的方法没有参数时,UnityPlayer.UnitySendMessage中的第三个参数需要为空字符串,不能为null!
此方法的好处在于当unity没有加载完成时调用此方法,unity将在加载完成后完成unity方法的调用。
使用接口:在Android中创建一个接口并在unity中实现(推荐)
例:在Android工程中创建一个名为IUnityController的接口:
public interface IUnityController {
void openDoor(float angle, float time, int doorId);
}unity中的实现:
private class UnityController : AndroidJavaProxy
{
public UnityController() : base("包名.IUnityController")
{
}
public void openDoor(float angle, float time, int doorId)
{
_doorAnim.DoorRotate(angle, time, doorId);
}
}在Android的activity或fragment中添加接口的设置方法,例如在fragment中添加:
private IUnityController listener;
public void setListener(IUnityController listener) {
this.listener = listener;
}unity中对应的设置方法:
private void Awake()
{
var activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").
GetStatic<AndroidJavaObject>("currentActivity");
using var fragment = _activity.Get<AndroidJavaObject>("mUnityFragment");
fragment.Call("setListener", new UnityController());
}这样在unity加载完成时就会给fragment中的listener赋值,可以直接使用
listener.openDoor()方法来调用unity中的方法。
unity中调用Android方法:
var activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer"). |
unity调用android方法默认不是在主线程中调用的,如果调用涉及到UI操作或其他必须在主线程中进行的操作时,需要在Android代码中添加runOnUiThread或者是在unity代码中添加:
currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() => |
出现的问题
apk打包安装后出现两个图标
解决方案:在unityLibrary的AndroidManifest中删除
<category android:name="android.intent.category.LAUNCHER" />

