Unity3D - Animator Controller循环依赖
问题
假设有2个Animator Controller,分别命名为TestControllerLhs.controller以及TestControllerRhs.controller。在TestControllerLhs.controller中设置状态如下:

TestControllerLhs.controller
当拷贝了包含Transitions并且该Transitions的Dst State不存在的Animator State到另一个Animator Controller时,就会出现游离依赖数据。以TestControllerLhs.controller为例,查看该文件能够发现,Attack01包含了Transitions数据:

Attack01包含的Transition
该Transition的Dst State为Attack02。如果我们拷贝Attack01但没有拷贝Attack02到TestControllerRhs.controller,那么就出现了游离依赖数据:

TestControllerRhs.controller

游离依赖数据
出现依赖的原因是该Transition的Dst State,即Attack02,仍然位于TestControllerLhs.controller中,没有被拷贝过来。说该数据是游离的原因是在TestControllerRhs.controller中,我们完全看不见他,也无法删除它。
在这里注意到这个问题的原因是,美术在制作Animator Controller时经常会使用拷贝、黏贴的操作,很容易在无意间产生游离依赖数据,而最关键也最严重的问题是循环依赖,即A.controller依赖B.controller,并且B.controller依赖A.controller。如果这两个Controller都是AssetBundle的话,就会产生无限依赖加载。
解决方案
通过之前的游离依赖数据分析可知他们的共性为m_DstState项包含了所依赖的.controller文件的guid,因此我们通过读取.controller文件将这些游离依赖数据删除。
以下的代码包含了检测循环依赖,打印依赖的Animator Controller以及去除游离依赖数据的功能,开发版本为Unity 5.5.2f1:
/******************************************************************************
* DESCRIPTION: AnimatorController处理器
*
* Copyright (c) 2017, 谭伟俊 (TanWeijun)
* All rights reserved
*
* COMPANY:
* CREATED: 2017.09.20, 15:48, CST
*******************************************************************************/ using System.IO;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEditor.Animations;
using GameFramework; public class AnimatorControllerProcessor
{
[MenuItem("Assets/Artist Tools/Animator Controller/Correct Data")]
private static void CorrectData()
{
string block = null;
bool isDependOtherAnimatorController = false;
AnimatorController animatorController = Selection.activeObject as AnimatorController;
string filePathName = Path.GetFullPath(AssetDatabase.GetAssetPath(animatorController));
string tempFilePathName = Application.dataPath + "/" + System.DateTime.Now.Ticks.ToString() + ".controller";
using (StreamWriter writer = File.CreateText(tempFilePathName))
{
using (StreamReader reader = File.OpenText(filePathName))
{
string content;
while (null != (content = reader.ReadLine()))
{
if (content.StartsWith("--- !u"))
{
if (!string.IsNullOrEmpty(block))
writer.Write(block); block = content + System.Environment.NewLine;
isDependOtherAnimatorController = false;
}
else
{
if (isDependOtherAnimatorController)
continue; if (string.IsNullOrEmpty(block))
writer.WriteLine(content);
else
{
block += (content + System.Environment.NewLine); // 检测是否依赖其他的Animator Controller
if (content.Contains("m_DstState:") && content.Contains("guid"))
{
block = null;
isDependOtherAnimatorController = true;
}
}
}
} // 写入最后的数据
if (!string.IsNullOrEmpty(block))
writer.Write(block);
}
} FileUtil.ReplaceFile(tempFilePathName, filePathName);
AssetDatabase.Refresh();
} [MenuItem("Assets/Artist Tools/Animator Controller/Collect Animator Controller Dependencies")]
private static void CollectAnimatorControllerDependencies()
{
AnimatorController animatorController = Selection.activeObject as AnimatorController;
string[] dependencyArray = AssetDatabase.GetDependencies(AssetDatabase.GetAssetPath(animatorController)); Log.Debug("************************* Animator Controller Dependencies (" + animatorController.name + ") *************************");
foreach (string dependency in dependencyArray)
{
if (dependency.EndsWith(".controller"))
Log.Debug(dependency);
}
Log.Debug("************************************************* End *************************************************");
} [MenuItem("ArtistTools/Check Animator Controller Dependencies")]
private static void CheckAnimatorControllerDependencies()
{
List<string> dependencyCheckNameList = new List<string>();
string[] filePathNameArray = Directory.GetFiles(Application.dataPath + "/BundleResources/Animator", "*.controller", SearchOption.TopDirectoryOnly);
foreach (string filePathName in filePathNameArray)
{
string[] dependencyArray = AssetDatabase.GetDependencies(filePathName.Substring(filePathName.IndexOf("/Assets/") + ));
foreach (string dependency in dependencyArray)
{
if (dependency.EndsWith(".controller"))
{
string assetName = Path.GetFileNameWithoutExtension(filePathName);
string dependencyName = Path.GetFileNameWithoutExtension(dependency); // A依赖于B,如果"B_A"存在,表示B也依赖于A,则是循环依赖
string checkName = dependencyName + "_" + assetName;
if (dependencyCheckNameList.Contains(checkName))
Log.Debug(Path.GetFileName(filePathName) + " and " + Path.GetFileName(dependency) + " depend each other"); dependencyCheckNameList.Add(assetName + "_" + dependencyName);
}
}
}
} [MenuItem("Assets/Artist Tools/Animator Controller/Correct Data", true)]
[MenuItem("Assets/Artist Tools/Animator Controller/Collect Animator Controller Dependencies", true)]
private static bool ValidateCorrectData()
{
return Selection.activeObject is AnimatorController;
}
}
打印依赖的Animator Controller:

TestControllerLhs依赖TestControllerRhs

TestControllerRhs依赖TestControllerLhs
检测循环依赖:

循环依赖
使用工具清理游离依赖数据后:

除了自身不再依赖其他的Animator Controller
本文固定链接: http://www.cnblogs.com/twjcnblog/p/7663048.html
转载请注明: EnigmaJJ 2017年10月13日 于 cnblog 发表
Unity3D - Animator Controller循环依赖的更多相关文章
- Unity3D之Mecanim动画系统学习笔记(五):Animator Controller
简介 Animator Controller在Unity中是作为一种单独的配置文件存在的文件类型,其后缀为controller,Animator Controller包含了以下几种功能: 可以对多个动 ...
- Animator Controller 继承关系
准备知识 对于Animator Controller中蜘蛛网一样的几十条连线,后续如果靠人工维护,那成本将是很大. AnimatorOverrideController组件的文档:https://do ...
- Spring基础系列-Spring事务不生效的问题与循环依赖问题
原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9476550.html 一.提出问题 不知道你是否遇到过这样的情况,在ssm框架中开发we ...
- service层代码相互调用, 导致spring循环依赖,设计上的优化
管理员创建用户需要发送激活邮件, 而发送激活邮件的时候需要判断发件人是不是合法的用户, 因此设计到一个循环依赖的问题 //UserService @Service class UserService{ ...
- Spring Cloud杜绝循环依赖
前言 大家在开发中有没有遇到过因循环依赖导致项目启动失败?在排查循环依赖的过程中有没困难?如何避免写出循环依赖的代码? 我没写过循环依赖的代码,作为稳定性负责人,我排查过多次. 有些逻辑简单的代码,循 ...
- .netcore ioc 循环依赖问题及其相关思考之DispatchProxy
.netcore引入了ioc机制让开发人员逐步习惯从过去的各种new对象变成通过IOC框架来管理对象的生命周期.这样当我们需要某个对象的时候,我们一般在构造函数里申明该对象的接口,即可通过ioc容器创 ...
- SpringBoot项目意外出现 循环依赖和注入的对象意外是Null的问题 Requested bean is currently in creation: Is there an unresolvable circular reference? 或 nested exception is java.lang.NullPointerException
1.Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name ...
- kmdjs和循环依赖
循环依赖 循环依赖是非常必要的,有的程序写着写着就循环依赖了,可以提取出一个对象来共同依赖解决循环依赖,但是有时会破坏程序的逻辑自封闭和高内聚.所以没解决好循环依赖的模块化库.框架.编译器都不是一个好 ...
- spring3 循环依赖
循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比如CircleA引用CircleB,CircleB引用CircleC,CircleC引用CircleA,则它们最终反映为一个环.此处不 ...
随机推荐
- Java企业微信开发_09_身份验证之移动端网页授权(有完整项目源码)
注: 源码已上传github: https://github.com/shirayner/WeiXin_QiYe_Demo 一.本节要点 1.1 授权回调域(可信域名) 在开始使用网页授权之前,需要先 ...
- .net asp mvc 如何从后端返回数据对象
今天在做项目时,有一个需求:获取从控制器返回的数组对象,方法如下 public ActionResult GetAllFiles() { string dir = Server.MapPath(&qu ...
- 201521123107 《Java程序设计》第1周学习总结
第1周学习总结 1.本周学习总结 本周我们正式开始了对一门新的编程语言java的学习.本周的主要内容是初步了解了java的发展过程,java具有简约且简单 .平台无关性等优点.java的3个关键的工具 ...
- Beta版本冲刺计划及安排(附七天冲刺的博客链接)
Beta版本冲刺计划及安排(附七天冲刺的博客链接) 新增组员 本次换人加入我们团队的新成员是原"爸爸说的都队"的队长念其锋同学,经过我们小组严格的两轮面试,他从几个同样前来面试的同 ...
- 201521123069 《Java程序设计》 第8周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 1.2 选做:收集你认为有用的代码片段 (1)泛型允许指定集合中元素的类型,在编译时就可以进行类型检查,避免运 ...
- 201521123111《Java程序设计》第6周学习总结
1. 本章学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰,内容覆盖 ...
- Java程序设计第四周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 答:①String类是final类,不能定义String的子类. ② instanceof ...
- 201521123070 《JAVA程序设计》第1周学习总结
本周学习总结 1.认识了三大平台Java SE.Java EE.Java ME. 2.认识了解了JDK,JVM与JRE,且熟悉JDK的操作并下载安装. 3.学会用博客写作业了. 书面作业 Q1.为什么 ...
- webservice05#soap消息
1, SOAPMessage结构图 2, SOAP消息的创建 1>前面的一个简单WebService 服务 package com.yangw.soap.service; import jav ...
- JVM菜鸟进阶高手之路二(JVM的重要性,Xmn是跟请求量有关。)
转载请注明原创出处,谢谢! 今天看群聊jvm,通常会问ygc合适吗? 阿飞总结,可能需要2个维度,1.单位时间执行次数,2.执行时间 ps -p pid -o etime 查看下进程的运行时间, 17 ...