先说开始的准备工作,我使用的工具版本是 Unity 6000.0.23f1 和 Android Studio Iguana | 2023.2.1。开发流程是先通过 Unity 导出 Android 工程,再用 Android Studio 打开进行后续开发。当 Unity 中的资源或代码有改动时,会重新打包并替换 Android 工程中的相关文件以保持同步。

实现效果如下

第一步在unity中的准备:

先在unity中进行准备工作,创建脚本,挂载,获取一下自身的按钮组件再托上去一个Image,

(临时测试脚本一切从简),

逻辑是点击按钮触发SelectImageFromGallery()函数,调用起安卓相册,然后选择图片把图片地址传回Unity中.:

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Networking;
using System.Collections;

public class ImageSelector : MonoBehaviour
{
    public Image background; // 连接到背景图片的 Image 组件
   
    void Start()
    {
        // 通过按钮触发选择图片的方法
        Button btn = GetComponent<Button>();
        btn.onClick.AddListener(SelectImageFromGallery);
    }


    // 选择图片的方法
    public void SelectImageFromGallery()
    {
        // 检查是否在Android平台
#if UNITY_ANDROID
        using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity"); // 获取当前活动
            
            // 创建 Intent 对象
            AndroidJavaObject intent = new AndroidJavaObject("android.content.Intent"); // 创建 Intent 实例
            intent.Call<AndroidJavaObject>("setAction", "android.intent.action.GET_CONTENT"); // 设置动作
            intent.Call<AndroidJavaObject>("setType", "image/*"); // 设置内容类型
            
            // 启动选择图片的 Activity
            currentActivity.Call("startActivityForResult", intent, 0);
        }
#else
        Debug.Log("非 Android 平台");
#endif
    }
    
    // 这个方法将在 Java 中调用
    public void OnImageSelected(string path)
    {
        Debug.Log("unity中的   OnImageSelected!!!     " + path);
        StartCoroutine(LoadImage(path)); // 加载并显示图片
    }

    private IEnumerator LoadImage(string path)
    {
        using (UnityWebRequest www = UnityWebRequestTexture.GetTexture(path))
        {
            yield return www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError("加载图片时出错: " + www.error);
            }
            else
            {
                // 创建纹理并设置为背景图像
                Texture2D texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
                background.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
            }
        }
    }
    
}

第二步在Android中进行开发:

由于安卓开发这块比较本人比较菜鸡,就直接在UnityPlayerGameActivity.java中进行开发了,添加的代码为

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 0) { // 检查请求代码
            if (resultCode == RESULT_OK && data != null) {
                Uri imageUri = data.getData(); // 获取图片的 Uri

                // 检查 URI 是否有效
                Log.d("URI Debug", "Received URI: " + imageUri.toString());

                // 从 URI 获取输入流
                InputStream imageStream = getInputStreamFromURI(imageUri);
                if (imageStream != null) {
                    // 保存输入流到文件
                    String imagePath = saveInputStreamToFile(imageStream);
                    if (imagePath != null) {
                        // 调用 Unity 的方法,传递文件路径
                        UnityPlayer.UnitySendMessage("Image", "OnImageSelected", "jar:file://"+imagePath);
                    } else {
                        Log.e("ImageLoader", "无法保存图像文件.");
                    }
                } else {
                    Log.e("ImageLoader", "无法获取输入流.");
                }
            }
        }
    }

    private InputStream getInputStreamFromURI(Uri uri) {
        try {
            return getContentResolver().openInputStream(uri);
        } catch (FileNotFoundException e) {
            Log.e("ImageLoader", "文件未找到: " + e.getMessage());
            return null;
        } catch (Exception e) {
            Log.e("ImageLoader", "获取输入流时出错: " + e.getMessage());
            return null;
        }
    }
    private String saveInputStreamToFile(InputStream inputStream) {
        try {
            File tempFile = new File(getCacheDir(), "temp_image.jpg"); // 创建临时文件
            FileOutputStream out = new FileOutputStream(tempFile);

            byte[] buffer = new byte[1024];
            int read;
            while ((read = inputStream.read(buffer)) != -1) {
                out.write(buffer, 0, read);
            }
            out.close();
            inputStream.close();

            return tempFile.getAbsolutePath(); // 返回文件路径
        } catch (IOException e) {
            Log.e("ImageLoader", "保存输入流到文件时出错: " + e.getMessage());
            return null;
        }
    }

在上面的Java代码中, 

Uri imageUri = data.getData(); // 获取图片的 Uri ,

打印url为: Received URI: content://com.android.providers.media.documents/document/image%3A2799

此处返回的url无法直接传回unity使用,我查询多种转换方式均无效,以下我发起的提问:

Android安卓下获取到的图片路径怎么才能转换为unity可用的路_移动开发-CSDN问答

所以我采取了另外一种方式,

直接在安卓中将此图片进行拷贝到一个unity可直接加载的路径,最后返回到unity中的路径为:

file:///data/user/0/你的包名/cache/temp_image.jpg

此路径即可通过UnityWebRequest类直接加载.

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐