tuyoogame / YooAsset

unity3d resources management system
https://www.yooasset.com/
Apache License 2.0
2.34k stars 460 forks source link

ab包加载的资源和编辑器模式下载的资源效果不同 #240

Closed 9a6c closed 6 months ago

9a6c commented 6 months ago

这是什么原因呢

gmhevinci commented 6 months ago

https://www.yooasset.com/docs/FAQ 可以参考常见问题里的第二项

9a6c commented 6 months ago

我尝试收集着色器, android编辑器中显示紫色,打出的安卓包真机测试显示紫色, 还在尝试,关于1.确认是否收集过着色器变种,并且SVC文件参与打包。 如何确定它参与了打包呢, 我的办法是放在Resources目录中

gmhevinci commented 6 months ago

2.x版本记得勾选auto collect shader选项。打包完成会有一个unityshader.bundle的文件,你可以解开看下

9a6c commented 6 months ago

感谢您的回复!

关于打ab包界面, 后续版本是否考虑支持同时打多个包呢, 目前package1、package2出ab资源,需要一个一个打包

gmhevinci commented 6 months ago

感谢您的回复!

关于打ab包界面, 后续版本是否考虑支持同时打多个包呢, 目前package1、package2出ab资源,需要一个一个打包

主要是unity引擎不支持。

9a6c commented 6 months ago

unity2021.3.6f1 urp

您好, 我尝试使用1.5.7版本 ab包加载是正常的, 但是使用2.x最新版本,加载的ab资源是紫粉色的,下图是1.5.7版本的效果,紫粉色是场景中摆放的东西,ab资源加载的内容正常显示,切换到2.x版本,当前正常显示的内容是紫粉色,请问2.x版本和1.5.7版本有什么区别呢?

其它信息,代码是例子中的 ` private IEnumerator Start() { //获取appVersion Debug.Log("get version."); yield return GetAppVersion(); Debug.Log("get version end.");

    // 初始化资源系统
    YooAssets.Initialize();
    YooAssets.SetOperationSystemMaxTimeSlice(30);

    Debug.Log("开始初始化包...");
    yield return InitPackage("DefaultPackage", false, true);
    yield return InitPackage("RawPackage", true, false);

    Es.DataTables _dataTables = new Es.DataTables();
    _dataTables.Load(new Yoo.EsDataLoaderAssetBundle());

    //加载ummorpg的场景
    yield return LoadScene();

    //这里进行初始化出现了点问题,放在player加载后进行初始化
    //UnityMonoBehaviourEvent.Instance.Initalize();   //初始化
    //YooBuildLoad.Instance.Initalize();              //初始化
}

private IEnumerator GetAppVersion()
{
    yield return null;

    using (UnityWebRequest request = UnityWebRequest.Get(yoo_verson_url))
    {
        //request.timeout = 10;   //超时

if UNITY_2017_2_OR_NEWER

        yield return request.SendWebRequest();

else

            yield return request.Send();

endif

        bool flag = false;

if UNITY_2020_2_OR_NEWER

        flag = request.result == UnityWebRequest.Result.Success;

elif UNITY_2017_1_OR_NEWER

            flag = !(request.isNetworkError || request.isHttpError);

else

            flag = !request.isError;

endif

        if (flag)
        {
            Config config = JsonUtility.FromJson<Config>(request.downloadHandler.text);
            if (config != null && !string.IsNullOrWhiteSpace(config.version))
            {
                appVersion = config.version;

if UNITY_EDITOR

                Debug.Log($"获取到的版本为:{appVersion}");

endif

                //将appVersion保存到本地
                PlayerPrefs.SetString(yoo_version_key, appVersion);
                PlayerPrefs.Save();
            }
            else
            {
                if (PlayerPrefs.HasKey(yoo_version_key))
                {
                    appVersion = PlayerPrefs.GetString(yoo_version_key);
                }

                Debug.LogError("config error!!!");
            }
        }
        else
        {
            if (PlayerPrefs.HasKey(yoo_version_key))
            {
                appVersion = PlayerPrefs.GetString(yoo_version_key);
            }
        }

    }
}

private IEnumerator LoadScene()
{
    AsyncOperation asyncOperation = SceneManager.LoadSceneAsync(1, LoadSceneMode.Single);
    asyncOperation.allowSceneActivation = false;    // 这里限制了跳转
    // 这里就是循环输入进度
    while (asyncOperation.progress < 0.9f)
    {
        //Debug.Log(" progress = " + asyncOperation.progress);
    }

    asyncOperation.allowSceneActivation = true;    // 这里打开限制
    yield return null;

    if (asyncOperation.isDone)
    {
        Debug.Log("完成加载");
    }
}

/// <summary>
/// 
/// </summary>
/// <param name="packageName">包名</param>
/// <param name="download">下载?</param>
/// <param name="defaultPackage">默认包?</param>
/// <returns></returns>
IEnumerator InitPackage(string packageName, bool download, bool defaultPackage)
{
    //保存本次信息
    this.packageName = packageName;
    this.download = download;
    this.defaultPackage = defaultPackage;

    // 创建资源包裹类
    var package = YooAssets.TryGetPackage(packageName);
    if (package == null)
    {
        package = YooAssets.CreatePackage(packageName);
        if (this.defaultPackage)
        {
            Debug.Log($"设置默认包:{this.defaultPackage}");
            YooAssets.SetDefaultPackage(package);
        }
    }

    // 编辑器下的模拟模式
    InitializationOperation initializationOperation = null;
    if (playMode == EPlayMode.EditorSimulateMode)
    {
        var createParameters = new EditorSimulateModeParameters();
        createParameters.SimulateManifestFilePath = EditorSimulateModeHelper.SimulateBuild(packageName);
        initializationOperation = package.InitializeAsync(createParameters);
    }

    // 单机运行模式
    if (playMode == EPlayMode.OfflinePlayMode)
    {
        var createParameters = new OfflinePlayModeParameters();
        createParameters.DecryptionServices = new GameDecryptionServices();
        initializationOperation = package.InitializeAsync(createParameters);
    }

    // 联机运行模式
    if (playMode == EPlayMode.HostPlayMode)
    {
        string defaultHostServer = GetHostServerURL();
        string fallbackHostServer = GetHostServerURL();
        var createParameters = new HostPlayModeParameters();
        createParameters.DecryptionServices = new GameDecryptionServices();
        createParameters.BuildinQueryServices = new GameQueryServices();
        createParameters.DeliveryQueryServices = new DefaultDeliveryQueryServices();
        createParameters.RemoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
        initializationOperation = package.InitializeAsync(createParameters);
    }

    // WebGL运行模式
    if (playMode == EPlayMode.WebPlayMode)
    {
        string defaultHostServer = GetHostServerURL();
        string fallbackHostServer = GetHostServerURL();
        var createParameters = new WebPlayModeParameters();
        createParameters.DecryptionServices = new GameDecryptionServices();
        createParameters.BuildinQueryServices = new GameQueryServices();
        createParameters.RemoteServices = new RemoteServices(defaultHostServer, fallbackHostServer);
        initializationOperation = package.InitializeAsync(createParameters);
    }

    yield return initializationOperation;

    // 如果初始化失败弹出提示界面
    if (initializationOperation.Status != EOperationStatus.Succeed)
    {
        Debug.LogWarning($"{initializationOperation.Error}");
    }
    else
    {
        var version = initializationOperation.PackageVersion;
        Debug.Log($"Init resource package version : {version}");
        yield return UpdatePackageVersion();
    }
}
private IEnumerator UpdatePackageVersion()
{
    yield return new WaitForSecondsRealtime(0.5f);

    var package = YooAssets.GetPackage(packageName);
    var operation = package.UpdatePackageVersionAsync();
    yield return operation;

    if (operation.Status != EOperationStatus.Succeed)
    {
        Debug.LogWarning(operation.Error);
    }
    else
    {
        packageVersion = operation.PackageVersion;
        Debug.Log($"当前更新:{packageVersion}");
        yield return UpdateManifest();
    }
}

private IEnumerator UpdateManifest()
{
    yield return new WaitForSecondsRealtime(0.5f);

    var package = YooAssets.GetPackage(packageName);
    bool savePackageVersion = true;
    var operation = package.UpdatePackageManifestAsync(packageVersion, savePackageVersion);
    yield return operation;

    if (operation.Status != EOperationStatus.Succeed)
    {
        Debug.LogWarning(operation.Error);
        yield break;
    }
    else
    {
        if (download)
        {
            Debug.Log($"开始下载:{packageName} {packageVersion}");
            yield return CreateDownloader();
        }
    }
}

IEnumerator CreateDownloader()
{
    yield return new WaitForSecondsRealtime(0.5f);

    var package = YooAssets.GetPackage(packageName);
    int downloadingMaxNum = 10;
    int failedTryAgain = 3;
    downloader = package.CreateResourceDownloader(downloadingMaxNum, failedTryAgain);

    if (downloader.TotalDownloadCount == 0)
    {
        Debug.Log("Not found any download files !");
    }
    else
    {
        // 发现新更新文件后,挂起流程系统
        // 注意:开发者需要在下载前检测磁盘空间不足
        //int totalDownloadCount = downloader.TotalDownloadCount;
        //long totalDownloadBytes = downloader.TotalDownloadBytes;
        yield return BeginDownload();
    }
}
private IEnumerator BeginDownload()
{
    downloader.OnDownloadErrorCallback = (fileName, error) =>
    {
        Debug.LogError($"发生错误:{fileName} {error}");
    };

    downloader.OnDownloadProgressCallback = (totalDownloadCount, currentDownloadCount, totalDownloadBytes, currentDownloadBytes) =>
    {

if UNITY_EDITOR

        //Debug.Log($"下载进度回调:{totalDownloadCount} {currentDownloadCount} {totalDownloadBytes} {currentDownloadBytes}");

endif

    };

    downloader.BeginDownload();
    yield return downloader;

    // 检测下载结果
    if (downloader.Status != EOperationStatus.Succeed)
        yield break;

    //清理本地不使用的缓存文件
    var package = YooAssets.GetPackage(packageName);
    var operation = package.ClearUnusedCacheFilesAsync();
    operation.Completed += (obj) =>
    {
        Debug.Log("清理本地缓存文件");
    };
}
/// <summary>
/// 获取资源服务器地址
/// </summary>
private string GetHostServerURL()
{

if UNITY_EDITOR

    if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.Android)
        return $"{hostServerIP}/CDN/Android/{appVersion}";
    else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.iOS)
        return $"{hostServerIP}/CDN/IPhone/{appVersion}";
    else if (UnityEditor.EditorUserBuildSettings.activeBuildTarget == UnityEditor.BuildTarget.WebGL)
        return $"{hostServerIP}/CDN/WebGL/{appVersion}";
    else
        return $"{hostServerIP}/CDN/PC/{appVersion}";

else

    if (Application.platform == RuntimePlatform.Android)
        return $"{hostServerIP}/CDN/Android/{appVersion}";
    else if (Application.platform == RuntimePlatform.IPhonePlayer)
        return $"{hostServerIP}/CDN/IPhone/{appVersion}";
    else if (Application.platform == RuntimePlatform.WebGLPlayer)
        return $"{hostServerIP}/CDN/WebGL/{appVersion}";
    else
        return $"{hostServerIP}/CDN/PC/{appVersion}";

endif

}

/// <summary>
/// 远端资源地址查询服务类
/// </summary>
private class RemoteServices : IRemoteServices
{
    private readonly string _defaultHostServer;
    private readonly string _fallbackHostServer;

    public RemoteServices(string defaultHostServer, string fallbackHostServer)
    {
        _defaultHostServer = defaultHostServer;
        _fallbackHostServer = fallbackHostServer;
    }
    string IRemoteServices.GetRemoteMainURL(string fileName)
    {
        return $"{_defaultHostServer}/{fileName}";
    }
    string IRemoteServices.GetRemoteFallbackURL(string fileName)
    {
        return $"{_fallbackHostServer}/{fileName}";
    }
}

/// <summary>
/// 资源文件解密服务类
/// </summary>
private class GameDecryptionServices : IDecryptionServices
{
    public ulong LoadFromFileOffset(DecryptFileInfo fileInfo)
    {
        return 32;
    }

    public byte[] LoadFromMemory(DecryptFileInfo fileInfo)
    {
        throw new NotImplementedException();
    }

    public Stream LoadFromStream(DecryptFileInfo fileInfo)
    {
        BundleStream bundleStream = new BundleStream(fileInfo.FilePath, FileMode.Open, FileAccess.Read, FileShare.Read);
        return bundleStream;
    }

    public uint GetManagedReadBufferSize()
    {
        return 1024;
    }
}

/// <summary>
/// 默认的分发资源查询服务类
/// </summary>
private class DefaultDeliveryQueryServices : IDeliveryQueryServices
{
    public DeliveryFileInfo GetDeliveryFileInfo(string packageName, string fileName)
    {
        throw new NotImplementedException();
    }
    public bool QueryDeliveryFiles(string packageName, string fileName)
    {
        return false;
    }
}

}

///

/// 资源文件解密流 /// public class BundleStream : FileStream { public const byte KEY = 64;

public BundleStream(string path, FileMode mode, FileAccess access, FileShare share) : base(path, mode, access, share)
{
}
public BundleStream(string path, FileMode mode) : base(path, mode)
{
}

public override int Read(byte[] array, int offset, int count)
{
    var index = base.Read(array, offset, count);
    for (int i = 0; i < array.Length; i++)
    {
        array[i] ^= KEY;
    }
    return index;
}

}

[System.Serializable] public class Config { public string version; }`

9a6c commented 6 months ago

补充信息,感觉1.5.7版本资源分布相对均匀, 2.x版本资源主要分布在某几个包中

1.5.7版本出的ab资源包 image

2.x版本出的ab资源包 image

gmhevinci commented 6 months ago

上面的信息不足以排查问题原因,你可以进社区QQ群963240451,然后私聊我。