Unity里Shader的加载使用,AB包加载使用遇到一个坑

博客记录了AB加载相关的一个坑,即AB加载的shader都要加入ProjectSetting==>Graphics==>Always Included Shaders列表中,未涉及代码内容。
这里直接说坑吧:AB包中的shader没有加入到ProjectSetting==>Graphics==>Always Included Shaders列表中的,使用Assetbundle加载使用后会看不到效果,我也是这方面的菜鸟,实验了好久才得出结论。
心塞啊,不知道是不是Unity的问题,更改了shader内容居然没起作用?难道是要我启动重启大法,将电脑重启一次???(我之前有些试验过程貌似都做过,没起效果,但是关机后放了个假再来试试就好了,我怀疑是不是编辑器没有刷新,下次再有结果来补上说明),不吐槽了,添加一下shader的加载代码
编辑器模式:
	//加载非Resources下的shader(注意Resource和Resources的区别)
    protected override Shader DoLoadShaderAtPath(string path)
    {
        string shaderPath = string.Format("Assets/Resource/Shader/{0}.shader", path);
        Shader shader = null;
#if UNITY_EDITOR
        //Shader.Find("Custom/MaskGray2")
        shader = UnityEditor.AssetDatabase.LoadAssetAtPath<Shader>(shaderPath);
#endif
        return shader;
    }
	
	//这是Resources目录下的shader加载
    protected override Shader DoLoadShader(string path)
    {
//        string shaderPath = string.Format("Custom/{0}", path);
//#if UNITY_EDITOR
//        Shader shader = Shader.Find(shaderPath);
//#endif
//        return shader;

        string shaderPath = string.Format("Shader/{0}.shader", path);
#if UNITY_EDITOR
        Shader shader = Resources.Load<Shader>(shaderPath);
#endif
        return shader;
    }
AB加载模式:
	//这是Resources目录下的shader加载
    protected override Shader DoLoadShader(string path)
    {
        string bundleName = "shader.unity3d";
        Shader shader = null;
        LoadedAssetBundle lab = LoadAssetBundleSync(bundleName);
        if (lab != null)
        {
            string assetName = string.Format("Assets/Resources/Shader/{0}.shader", path).ToLower();
            shader = lab.m_AssetBundle.LoadAsset<Shader>(assetName);
        }

        return shader;
    }

	//这是非Resources目录下的shader加载
    protected override Shader DoLoadShaderAtPath(string path)
    {
        string bundleName = "shader.unity3d";
        Shader shader = null;
        LoadedAssetBundle lab = LoadAssetBundleSync(bundleName);
        if (lab != null)
        {
            string assetName = string.Format("Assets/Resource/Shader/{0}.shader", path).ToLower();
            shader = lab.m_AssetBundle.LoadAsset<Shader>(assetName);
        }
        return shader;
    }

这里主要不讲代码,主要记录坑:AB加载的shader都要加入ProjectSetting==>Graphics==>Always Included Shaders列表中。

<think>首先,用户的问题是:“我想查找在Unity使用AB加载Animation的方法 请问Unity使用AssetBundle加载Animation的方法”。这表明用户在询问如何在Unity使用AssetBundle(AB加载Animation(动画)。 我有几个引用需要参考: - 引用[1]: 解释Unity Animation组件的使用方法,括Play方法等。它提到Animation组件是Legacy系统,但仍有优势。 - 引用[2]: 展示了一个代码示例,使用AssetBundle加载动画片段(AnimationClip),并将其添加到GameObject的Animation组件中。 - 引用[3]: 讨论打AnimatorController并加载RuntimeAnimatorController。 - 引用[4]: 关于AssetBundle打的XML配置。 - 引用[5]: 展示使用WWW加载AssetBundle并从中加载资源。 用户的问题集中在加载Animation组件的内容,而不是Animator(Mecanim系统)。引用[2]直接相关,因为它展示了加载AnimationClip并添加到Animation组件。 关键点: - AssetBundle用于加载资源。 - 对于Legacy Animation System,使用Animation组件;对于Mecanim,使用Animator组件。 - 用户指定了“Animation”,所以应该聚焦在Legacy系统。 引用[2]的代码示例很适合: ```csharp // 加载AssetBundle AssetBundle ab1 = AssetBundle.LoadFromFile("path_to_ab"); // 加载动画片段 AnimationClip clip = ab1.LoadAsset<AnimationClip>("Move"); // 创建GameObject并添加Animation组件 GameObject obj = new GameObject("AnimObject"); obj.AddComponent<Animation>(); Animation anim = obj.GetComponent<Animation>(); // 添加动画片段并播放 anim.clip = clip; anim.AddClip(clip, "newclip"); anim.Play(); ``` 这涵盖了核心步骤:加载AssetBundle,加载AnimationClip,添加到Animation组件,并播放。 其他引用: - 引用[1]支持Animation组件的使用。 - 引用[3]是关于AnimatorController(Mecanim),不直接相关。 - 引用[4]和[5]涉及打加载AssetBundle,但没有具体动画加载细节;引用[5]展示了WWW.LoadFromCacheOrDownload,这是旧方法,现在推荐使用UnityWebRequestAssetBundle。 系统指令: - 所有行内数学表达式使用$...$(但这没有数学内容)。 - 独立公式使用$$...$$(不适用)。 - LaTeX语法正确(不适用)。 - 使用中文回答。 - 生成相关问题。 - 引用的段落末尾添加引用标识,如[^数字]。 回答结构: - 清晰,逐步解决问题。 - 基于用户问题,提供可靠方法。 步骤概述: 1. **解释上下文**:Unity中Animation vs. Animator。 2. **加载AssetBundle**:使用AssetBundle.LoadFromFile或其他方法。 3. **加载动画片段**:LoadAsset<AnimationClip>。 4. **添加到GameObject**:创建GameObject,添加Animation组件,设置clip或AddClip。 5. **播放动画**:使用Play方法。 6. **优化和提示**:如使用UnityWebRequestAssetBundle替代WWW。 相关问题生成: - 基于主题,如加载AssetBundle的其他方法、性能优化、使用Mecanim等。 最终回答结构: - 介绍:简要解释。 - 详细步骤:参考引用[2]的核心代码。 - 添加引用标识。 - 生成相关问题。 </think>### Unity使用AssetBundle加载Legacy Animation的方法 在Unity中,AssetBundle(AB)是一种高效管理资源的机制,常用于加载预打的动画资源如AnimationClip(动画片段)。Unity支持两种动画系统:Legacy Animation System(基于Animation组件)和Mecanim System(基于Animator组件)。根据您的查询,您想了解加载Legacy Animation的方法,以下我将基于引用[^2]提供的代码示例,逐步解释完整流程。整个过程分为四个步骤:准备AssetBundle、加载AssetBundle、添加动画到GameObject,以及控制动画播放。所有代码示例均使用C#,适用于Unity 2021.3+版本。 #### 步骤1: 准备AssetBundle(打动画片段) 在加载动画前,需要先将动画资源(如AnimationClip)打成AssetBundle。Unity Editor中可以使用AssetBundle标签系统: - 在Project窗口选择动画资源(例如AnimationClip文件)。 - 在Inspector窗口设置AssetBundle名称(如"move")。 - 使用脚本或内置工具打(如引用[^4]所示的XML配置工具)。 例如,引用[^4]中提到AssetBundle打配置支持`AnimationClip`类型: ```xml <SourceAssetUnionTypeFilter>t:Scene t:Prefab t:Shader t:Model t:Material t:Texture t:AudioClip t:AnimationClip ...</SourceAssetUnionTypeFilter> ``` 这确保了动画片段能被正确打[^4]。 #### 步骤2: 加载AssetBundle并获取动画片段 在运行时,使用`AssetBundle.LoadFromFile`或异步方法加载AssetBundle,然后从中加载`AnimationClip`。引用[^2]展示了一个同步加载的例子: ```csharp using UnityEngine; using System.Collections; // 用于异步操作支持 public class AnimationLoader : MonoBehaviour { void Start() { // 定义AssetBundle路径(确保路径正确,如StreamingAssets文件夹) string path = "AssetBundles/move.ab"; // 替换为实际AB路径 // 加载AssetBundle AssetBundle ab = AssetBundle.LoadFromFile(path); if (ab == null) { Debug.LogError("Failed to load AssetBundle."); return; } // 从AssetBundle加载AnimationClip("Move"是动画片段在AB的名称) AnimationClip clip = ab.LoadAsset<AnimationClip>("Move"); if (clip == null) { Debug.LogError("AnimationClip not found in AssetBundle."); ab.Unload(false); // 释放AB,参数false表示不卸载已加载资源 return; } // 创建GameObject并添加Animation组件 GameObject animObject = new GameObject("AnimationObject"); Animation animComponent = animObject.AddComponent<Animation>(); // 添加动画片段到Animation组件(设置默认clip或添加新clip) animComponent.clip = clip; // 设置默认动画clip animComponent.AddClip(clip, "NewClip"); // 可选:添加多个clip,命名为"NewClip"便于控制 // 播放动画(默认clip) animComponent.Play(); // 可选:设置循环模式 animComponent.wrapMode = WrapMode.Loop; // 卸载不需要的AB(避免内存泄漏) ab.Unload(false); } } ``` **关键点**: - **加载方法**:`AssetBundle.LoadFromFile`是同步加载,适用于本地路径。对于远程加载(如网络服务器),推荐使用`UnityWebRequestAssetBundle`(异步,避免卡顿),例如引用[^5]的`WWW.LoadFromCacheOrDownload`已过时,现代替代方案为: ```csharp IEnumerator LoadBundleAsync(string url) { using (UnityWebRequest webRequest = UnityWebRequestAssetBundle.GetAssetBundle(url)) { yield return webRequest.SendWebRequest(); if (webRequest.result != UnityWebRequest.Result.Success) { Debug.LogError("Load failed: " + webRequest.error); } else { AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(webRequest); AnimationClip clip = bundle.LoadAsset<AnimationClip>("Move"); // 后续步骤同上... } } } ``` 这确保高效加载网络资源[^5]。 - **错误处理**:检查`null`值防止崩溃。 - **资源管理**:加载使用`Unload(false)`释放AB,但保留已加载资源如`AnimationClip`[^2]。 #### 步骤3: 添加动画到GameObject并控制播放 - **Animation组件设置**:如引用[^2]所示,通过`AddComponent<Animation>()`添加组件,并使用`clip`或`AddClip`方法绑定动画。 - **播放控制**:调用`Play()`方法启动动画。其他控制方法括: - `animComponent.Play("NewClip")`:播放指定名称的clip(如之前添加的"NewClip")。 - `animComponent.Stop()`:停止动画。 - `animComponent.wrapMode`:设置循环模式(如`WrapMode.Loop`)。 这些方法与引用[^1]中提到的`Animation.Play()`重载一致,支持精确控制播放模式[^1]。 #### 性能优化与常见问题 - **轻量级优势**:Legacy Animation组件在简单场景中比Mecanim更轻量(内存占用低),适合动态加载(如引用[^1])。 - **事件绑定**:可通过`AnimationEvent`绑定回调(如动画结束事件),引用[^1]有详细说明。 - **跨平台注意**:确保AB针对目标平台打(如Android或iOS),避免兼容问题。 - **内存泄漏**:加载后卸载未使用资源(使用`Resources.UnloadUnusedAssets()`或`AssetBundle.Unload(true)`)。 如果您需要切换到Mecanim系统(如加载AnimatorController),可以参考引用[^3]使用`RuntimeAnimatorController`,但Legacy Animation更适合您的查询场景[^3]。 ### 相关问题 1. **如何异步加载AssetBundle避免游戏卡顿?** 2. **Legacy Animation vs. Mecanim:在Unity中如何选择?** 3. **AssetBundle打动画时如何优化文件大小?** 如果您有更多细节(如平台或具体动画类型),我可以提供更针对性的建议!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值