1、Unity 中创建空物体 BundleLoader 并挂载脚本
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/ 目录下 )
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)
}
}