android集成unity后动态导入 assetsBundle

1、Unity 中创建空物体 BundleLoader 并挂载脚本

csharp 复制代码
using System.Collections;
using System.Diagnostics;
using System.IO;
using UnityEngine;
using static System.Net.Mime.MediaTypeNames;

public class LoadSphereBundle : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(LoadSphere());


        // 测试 Android 或 Editor
        //#if UNITY_EDITOR
        //            string path = UnityEngine.Application.dataPath + "/AssetBundles/Android/spherebundle";
        //#else
        //        string path = UnityEngine.Application.persistentDataPath + "/spherebundle"; // Android 可读路径
        //#endif
        //        LoadSphereByPathBridge(path);
    }

    public IEnumerator LoadSphere()
    {
        // 正确的路径构建方式
        #if UNITY_EDITOR
                    // 编辑器模式下的路径
                    string path = UnityEngine.Application.dataPath + "/AssetBundles/Android/spherebundle";
        #else
            // 运行时模式下的路径(打包后)
            string path = UnityEngine.Application.streamingAssetsPath + "/spherebundle";
        #endif

        UnityEngine.Debug.Log("尝试从路径加载: " + path);

        // 加载 AssetBundle
        AssetBundle bundle = AssetBundle.LoadFromFile(path);
        if (bundle == null)
        {
            UnityEngine.Debug.LogError("Failed to load spherebundle from: " + path);
            UnityEngine.Debug.Log("请确认文件是否存在且路径正确");
            yield break;
        }

        // 加载 prefab
        GameObject spherePrefab = bundle.LoadAsset<GameObject>("sphere");
        if (spherePrefab != null)
        {
            Instantiate(spherePrefab, Vector3.zero, Quaternion.identity);
            UnityEngine.Debug.Log("成功加载并实例化 sphere prefab!");
        }
        else
        {
            UnityEngine.Debug.LogError("Failed to load prefab 'sphere' from bundle!");

            // 调试:列出bundle中所有资源
            UnityEngine.Debug.Log("Bundle中包含的资源:");
            foreach (string name in bundle.GetAllAssetNames())
            {
                UnityEngine.Debug.Log("- " + name);
            }
        }

        bundle.Unload(false);
    }




    // UnitySendMessage 调用入口
    public void LoadSphereByPathBridge(string path)
    {
        UnityEngine.Debug.Log("LoadSphereByPathBridge,收到 UnitySendMessage 调用, 路径 = " + path);
        StartCoroutine(LoadSphereByPath(path));
    }


    public IEnumerator LoadSphereByPath(string path)
    {
       
        UnityEngine.Debug.Log("尝试从路径加载: " + path);

        // 加载 AssetBundle
        AssetBundle bundle = AssetBundle.LoadFromFile(path);
        if (bundle == null)
        {
            UnityEngine.Debug.LogError("Failed to load spherebundle from: " + path);
            UnityEngine.Debug.Log("请确认文件是否存在且路径正确");
            yield break;
        }

        // 加载 prefab
        GameObject spherePrefab = bundle.LoadAsset<GameObject>("sphere");
        if (spherePrefab != null)
        {
            Instantiate(spherePrefab, Vector3.zero, Quaternion.identity);
            UnityEngine.Debug.Log("成功加载并实例化 sphere prefab!");
        }
        else
        {
            UnityEngine.Debug.LogError("Failed to load prefab 'sphere' from bundle!");

            // 调试:列出bundle中所有资源
            UnityEngine.Debug.Log("Bundle中包含的资源:");
            foreach (string name in bundle.GetAllAssetNames())
            {
                UnityEngine.Debug.Log("- " + name);
            }
        }

        bundle.Unload(false);
    }
}

2、android 中 使用 UnitySendMessage 调用 LoadSphereByPathBridge方法 加载 ab

(注意 assetsBundle 全部文件拷贝到 /storage/emulated/0/Android/data/com.example.dockwithtuanjie/files/ 目录下 )

csharp 复制代码
package com.example.dockwithtuanjie

// 在 app/src/main/java/你的包名/ 下创建 UnityFragment.kt   【step 1. 添加此文件】

import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.unity3d.player.UnityPlayer


class UnityFragment : Fragment() {

    // 移除 static,使用 lateinit 延迟初始化
    lateinit var mUnityPlayer: UnityPlayer

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 初始化 UnityPlayer,使用 requireActivity() 作为 context
        mUnityPlayer = UnityPlayer(requireActivity())
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        val view = mUnityPlayer.view
        // 防止视图已有父布局的重要检查
        if (view.parent != null) {
            (view.parent as ViewGroup).removeView(view)
        }
        // 设置窗口焦点监听
        view.viewTreeObserver.addOnWindowFocusChangeListener { hasFocus ->
            mUnityPlayer.windowFocusChanged(hasFocus)
        }
        return view
    }

    override fun onResume() {
        super.onResume()
        mUnityPlayer.resume()
    }

    override fun onPause() {
        super.onPause()
        mUnityPlayer.pause()
    }

    override fun onDestroy() {
        super.onDestroy()
        mUnityPlayer.quit()
    }


    fun send(msg: String?) {
        Log.d("UnityFragment", "我是unityFragment, 收到调用--->>> : $msg")
        UnityPlayer.UnitySendMessage("AutoCubeRotator", "OnMsg", msg)

        val a = 0.5;
        UnityPlayer.UnitySendMessage("AutoCubeRotator", "OnMsgToTransform", a.toString() )



        //-------------------------------->>>>> 动态加载测试
        val bundlePath = context?.getExternalFilesDir(null)?.absolutePath + "/spherebundle"
        Log.d("UnityFragment", "我是unityFragment, 尝试加载bundle路径--->>> : $bundlePath")
        UnityPlayer.UnitySendMessage("BundleLoader", "LoadSphereByPathBridge", bundlePath)
    }
}
相关推荐
HLC++12 小时前
Linux的进程间通信
android·linux·服务器
爱笑鱼15 小时前
Binder(二):AIDL 生成的 Proxy、Stub 和 Parcel 到底在做什么?
android
爱笑鱼16 小时前
Binder(一):一次方法调用,究竟怎样跨进程执行?
android
壮哥_icon17 小时前
【Android 系统开发】使用 BAT 脚本高效自动化管理 /system/priv-app/ 系统应用(安装与卸载)
android·运维·自动化
用户693717500138418 小时前
Claude Code终端日志Token占用实测:一个过滤器砍掉60%-90%
android·前端·后端
蝉蜕日记18 小时前
AccumuPDF高级版 v2.57 | 视图文转换PDF,合并分割压缩
android·智能手机·pdf·生活·软件需求
吐了啊取名字太难18 小时前
美颜系统AI修图本地跑并支持Mac、win、安卓、iOS不卡顿
android·人工智能·windows·数码相机·mac·ai编程
旧物有情19 小时前
游戏开发常用架构 #MVP,MVC
游戏·unity·架构·mvc
阿pin20 小时前
Android随笔-Retrofit
android·retrofit
想取一个与众不同的名字好难20 小时前
安卓自定义颜色选择器
android