在开发安卓软件的时候,Unity和Android之间的交互是非常有必要的,使用Android调用Unity相对来说比较简单,然而用Unity调用Android却是非常麻烦的事,这对于一个Android小白的我来说却是无比头大的,在网上我们能找到各种各样的Unity调用Android的方法,不过大同小异,无非都是AndroidStudio导出.jar/.aar包,看起来都没有什么问题,然而,自己照搬过来却总是花样报错。本人也是被受AndroidStudio的折磨。(Unity2019以后与Android的交互,从此告别.aar和.jar)
优势:
1.不要需要导包,告别.aar和.jar
2.打包不需要大量设置,名字随便填
3.方法简单易懂
准备:Unity2019及以后版本的Unity
废话不多说,我们直接上方法
一,Unity与Android的交互
1.新建两个txt文件,将它们分别命名为MainActivity和Androidmanifest
2. 将下面的脚本代码复制到txt文本中去
MainActivity
package com.pub.dou;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.Toast;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
public class MainActivity extends UnityPlayerActivity {
public String MName="Dou";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
//让Unity调用的方法
public String CallAndroid()
{
String Msg="HELLO UNITY, This is android";
Toast.makeText(MainActivity.this, Msg, Toast.LENGTH_SHORT).show();
return Msg;
}
//让Unity调用的方法
public void ShowToast(Context context, String Msg)
{
Toast.makeText(context, Msg, Toast.LENGTH_SHORT).show();
}
public void ShowName()
{
//调用Unity上物体Canvas上的callunity方法,MName是参数
UnityPlayer.UnitySendMessage("Canvas", "callunity",MName);
}
//需要调用什么都在这个MainActivity类里面写就好了,一些需要引用的别忘了在前面添加
}
package的名字可以自己随便写一个自己喜欢的就行,只要在Androidmanifest中做出相应的修改进行,不过不建议修改,因为这不会对自己Build apk设置有任何影响的。
Androidmanifest
// 调用Unity
// 需要的权限,也可以Unity上UnityEngine.Android里面弄
3.修改上面两个文本的后缀名
至此,Android方面的工作暂时是完成了,接下来就是Unity了。
4.打开Unity,随便创建一个新的项目,并将平台设置成Android。
5.新建文件夹Plugins/Android,并将上面改好名字的两个文件放置在Android文件夹下。
6.创建Canvas,并在Canvas下创建三个按钮,分别改名字为CallAndroid、ShowToast和ShowName(改名字和调用Android没直接联系,主要是我的编码习惯,方便使用)。
7.新建一个C#脚本,并添加在Canvas上,代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Test : MonoBehaviour
{
private Button[] btns;
AndroidJavaObject jo;
AndroidJavaObject context;
public Text tex;
private string str;
private void Start()
{
Init();
btns = transform.GetComponentsInChildren
8.新建一个text,拖拽到脚本上,用于显示Android调用Unity。
9.打包,随便设置一下公司名和产品名,开始Build。
10.使用安卓设备安装刚刚打包好的apk,运行 。下面是我的运行结果(按钮从上至下):
二,调用Android相册并获取
1.在网上找到unity调用Android相册获取路径的代码。
2.将代码整合到MainActivity里面(先将后缀名改为txt,整合后再改回来,也可以直接使用Java的编译工具打开MainActivity.java,Androidmanifest.xml需要添加权限),代码如下:
MainActivity.java
package com.pub.dou;
import android.Manifest;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.widget.Toast;
import android.app.Activity;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;
public class MainActivity extends UnityPlayerActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取存储权限,不然的话无法获取图片
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 100);
}
}
// unity点击按钮触发这个方法
public void startPhoto() {
Log.d("unity","打开相册");
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, 123456); // 第二个参数是请求码
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 123456: // 请求码
Log.d("Unity", "相册返回");
UnityPlayer.UnitySendMessage("Main Camera", "CallUnity", GetPath(data));
break;
}
}
}
public String GetPath(Intent data) {
Uri uri = data.getData();
String imagePath;
// 第二个参数是想要获取的数据
Cursor cursor = getContentResolver()
.query(uri, new String[]{MediaStore.Images.ImageColumns.DATA},
null, null, null);
if (cursor == null) {
imagePath = uri.getPath();
} else {
cursor.moveToFirst();
// 获取数据所在的列下标
int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
imagePath = cursor.getString(index); // 获取指定列的数据
cursor.close();
}
return imagePath; // 返回图片地址
}
//让Unity调用的方法
public void CallAndroid(String Msg)
{
Toast.makeText(MainActivity.this, Msg, Toast.LENGTH_SHORT).show();
}
}
Androidmanifest.xml
// 和unity交互需要加这一句
// 获取权限
3.新建场景,创建Canvas并创建一个Test脚本挂在Main Camera上(别忘了将准备好的Android文件放置到Android目录下)。
4.Test脚本代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
public class Test : MonoBehaviour
{
// 直接拖过来button和按钮上的image
public Button btn;
public Image ImageView;
AndroidJavaObject jo;
private void Awake()
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
jo = jc.GetStatic("currentActivity");
btn.onClick.AddListener(CallAndroid);
}
///
/// CALL>>>ANDROID>>>打开相册
///
void CallAndroid()
{
jo.Call("startPhoto");
}
///
/// 给Android调用的
///
///
public void CallUnity(string str)
{
ShowImage(str);
jo.Call("CallAndroid", string.Format("图片Address>>>>" + str));
//string path = "file://" + str;
//StartCoroutine(LoadTexturePreview(path));
}
//使用www方式获取图片
IEnumerator LoadTexturePreview(string path)
{
UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(path);
yield return uwr.SendWebRequest();
Debug.Log("图片地址:" + path);
if (uwr.isNetworkError || uwr.isHttpError)
{
Debug.Log("错误" + uwr.error);
}
else
{
Texture2D texture = DownloadHandlerTexture.GetContent(uwr);
// 图片显示在按钮上
Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(.5f, .5f));
ImageView.sprite = sprite;
}
}
//使用文件流读取图片
private void ShowImage(string path)
{
FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read);
fileStream.Seek(0, SeekOrigin.Begin);
byte[] bye = new byte[fileStream.Length];
fileStream.Read(bye, 0, (int)bye.Length);
fileStream.Close();
fileStream.Dispose();
fileStream = null;
Texture2D texture = new Texture2D(100,50);
texture.LoadImage(bye);
Sprite sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
ImageView.sprite = sprite;
// Destroy(texture,4);
}
}
至于为什么没有使用WWW的方式获取图片,主要是这种方式不知道为啥速度特别慢,至少要3秒,而且模拟器上能用,真机上却会报错:HTTP1.1 404,知道原因的请告诉我。
5.在Canvas下添加一个button和一个Image,拖拽至脚本。
6.打包收工。运行结果如下:
代码思路大概是这样:Unity.Button>>>Android.打开相册>>>Android.获取选中图片>>>Android.处理>>>Android.图片路径>>>CallUnity>>>Unity.读取>>>Unity.贴图
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)