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)
    }
}
相关推荐
天空之城--27 分钟前
Android Flutter行业动态与学习参考(2026年8月)
android·flutter
松树戈37 分钟前
godot项目【宝石捕手】04~添加音效、记分
游戏引擎·godot
quantdash_cc1 小时前
基于 QuantDash 5 分钟 K 线的网格交易策略参数网格搜索寻优实战
android·开发语言·pandas·量化·quantdash
杉氧2 小时前
原生交互:如何在 Flutter 中嵌入 Android/iOS 原生组件并解决手势冲突
android·flutter·dart
Android打工仔3 小时前
Continuation 的链式关系 —— 一个 suspend 函数如何把结果交还给调用者?
android·kotlin
hunterandroid3 小时前
[Android 从零到一] Kotlin Channel 与复杂并发场景:从生产者-消费者到结构化并发治理
android
FlightYe3 小时前
linux系统编程(八):阻塞与非阻塞IO对比
android·linux·运维·服务器·github·vim
恋猫de小郭4 小时前
Flutter iOS Deep Link 为什么会突然失效:一系列难以言喻的问题
android·前端·flutter
LONGZETECH4 小时前
无人机实训高成本痛点解法:虚拟仿真实现 70% 耗材损耗下降
大数据·算法·unity·架构·无人机
Kapaseker4 小时前
小白都看得懂的 Skill 教程 - 初识 Skill
android·kotlin·vibecoding