Unity动画控制器为何依赖另一个动画控制器:动画状态机Ctrl C拷贝的bug

未解之谜

查看一个动画控制器的依赖,里面竟然有另一个动画控制器。

直接去被依赖项的meta文件拷贝guid,然后去依赖项的YAML里搜索,结果是:

这个guid多次出现在AnimatorStateTransition模块。

看不懂YAML,于是把依赖别人的控制器复制一个,把状态删一个,打印一次依赖。然后删成默认状态机,啥都不依赖了,只依赖那个动画控制器。

然后把控制器的层、参数、状态全删掉,再建一个全新控制器,对比它们的YAML。新建的控制器很干净:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!91 &9100000
AnimatorController:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: New Animator Controller
  serializedVersion: 5
  m_AnimatorParameters: []
  m_AnimatorLayers: []

被删空的控制器YAML则是:

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1101 &-8043723507950298118
AnimatorStateTransition:
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: 
  m_Conditions:
  - m_ConditionMode: 1
    m_ConditionEvent: running
    m_EventTreshold: 0
  m_DstStateMachine: {fileID: 0}
  m_DstState: {fileID: 5868839050235648224, guid: 06bf078c7d5187148b17f1e7918a9e99,
    type: 2}
  m_Solo: 0
  m_Mute: 0
  m_IsExit: 0
  serializedVersion: 3
  m_TransitionDuration: 0.25
  m_TransitionOffset: 0
  m_ExitTime: 0.9464286
  m_HasExitTime: 0
  m_HasFixedDuration: 1
  m_InterruptionSource: 0
  m_OrderedInterruption: 1
  m_CanTransitionToSelf: 1
--- !u!1101 &-7986762334218738143
AnimatorStateTransition:
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: 
  m_Conditions:
  - m_ConditionMode: 6
    m_ConditionEvent: bodyStatus
    m_EventTreshold: 1
  m_DstStateMachine: {fileID: 0}
  m_DstState: {fileID: -4066937683750499412, guid: 06bf078c7d5187148b17f1e7918a9e99,
    type: 2}
  m_Solo: 0
  m_Mute: 0
  m_IsExit: 0
  serializedVersion: 3
  m_TransitionDuration: 0.25
  m_TransitionOffset: 0
  m_ExitTime: 0.89892185
  m_HasExitTime: 0
  m_HasFixedDuration: 1
  m_InterruptionSource: 0
  m_OrderedInterruption: 1
  m_CanTransitionToSelf: 1
--- !u!1101 &-5474338561685204398
AnimatorStateTransition:
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: 
  m_Conditions:
  - m_ConditionMode: 1
    m_ConditionEvent: Jump
    m_EventTreshold: 0
  m_DstStateMachine: {fileID: 0}
  m_DstState: {fileID: -9165411807507458709, guid: 06bf078c7d5187148b17f1e7918a9e99,
    type: 2}
  m_Solo: 0
  m_Mute: 0
  m_IsExit: 0
  serializedVersion: 3
  m_TransitionDuration: 0.068148136
  m_TransitionOffset: 0
  m_ExitTime: 0.89687735
  m_HasExitTime: 0
  m_HasFixedDuration: 1
  m_InterruptionSource: 0
  m_OrderedInterruption: 1
  m_CanTransitionToSelf: 1
--- !u!1101 &-789983268425872304
AnimatorStateTransition:
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: 
  m_Conditions:
  - m_ConditionMode: 1
    m_ConditionEvent: TakeDrop
    m_EventTreshold: 0
  m_DstStateMachine: {fileID: 0}
  m_DstState: {fileID: 3227172602469648728, guid: 06bf078c7d5187148b17f1e7918a9e99,
    type: 2}
  m_Solo: 0
  m_Mute: 0
  m_IsExit: 0
  serializedVersion: 3
  m_TransitionDuration: 0.25
  m_TransitionOffset: 0
  m_ExitTime: 0.89892185
  m_HasExitTime: 0
  m_HasFixedDuration: 1
  m_InterruptionSource: 0
  m_OrderedInterruption: 1
  m_CanTransitionToSelf: 1
--- !u!1101 &-186031674231208760
AnimatorStateTransition:
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: 
  m_Conditions:
  - m_ConditionMode: 6
    m_ConditionEvent: bodyStatus
    m_EventTreshold: 0
  m_DstStateMachine: {fileID: 0}
  m_DstState: {fileID: -1130861594894586152, guid: 06bf078c7d5187148b17f1e7918a9e99,
    type: 2}
  m_Solo: 0
  m_Mute: 0
  m_IsExit: 0
  serializedVersion: 3
  m_TransitionDuration: 0.25
  m_TransitionOffset: 0
  m_ExitTime: 0.89892185
  m_HasExitTime: 0
  m_HasFixedDuration: 1
  m_InterruptionSource: 0
  m_OrderedInterruption: 1
  m_CanTransitionToSelf: 1
--- !u!91 &9100000
AnimatorController:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: NPC 1
  serializedVersion: 5
  m_AnimatorParameters: []
  m_AnimatorLayers:
  - serializedVersion: 5
    m_Name: Base Layer
    m_StateMachine: {fileID: 50358232126170600}
    m_Mask: {fileID: 0}
    m_Motions: []
    m_Behaviours: []
    m_BlendingMode: 0
    m_SyncedLayerIndex: -1
    m_DefaultWeight: 0
    m_IKPass: 0
    m_SyncedLayerAffectsTiming: 0
    m_Controller: {fileID: 9100000}
--- !u!1107 &50358232126170600
AnimatorStateMachine:
  serializedVersion: 6
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: Base Layer
  m_ChildStates: []
  m_ChildStateMachines: []
  m_AnyStateTransitions: []
  m_EntryTransitions: []
  m_StateMachineTransitions: {}
  m_StateMachineBehaviours: []
  m_AnyStatePosition: {x: 0, y: 30, z: 0}
  m_EntryPosition: {x: 120, y: 120, z: 0}
  m_ExitPosition: {x: 270, y: 50, z: 0}
  m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
  m_DefaultState: {fileID: 0}
--- !u!1101 &1116902853594775685
AnimatorStateTransition:
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: 
  m_Conditions:
  - m_ConditionMode: 3
    m_ConditionEvent: gunStatus
    m_EventTreshold: 0
  m_DstStateMachine: {fileID: 0}
  m_DstState: {fileID: -2272526421185388783, guid: 06bf078c7d5187148b17f1e7918a9e99,
    type: 2}
  m_Solo: 0
  m_Mute: 0
  m_IsExit: 0
  serializedVersion: 3
  m_TransitionDuration: 0.25
  m_TransitionOffset: 0
  m_ExitTime: 0.90909094
  m_HasExitTime: 0
  m_HasFixedDuration: 1
  m_InterruptionSource: 0
  m_OrderedInterruption: 1
  m_CanTransitionToSelf: 1

多了很多AnimatorStateTransition:模块。

我能想到的解释就是这个控制器的一些状态和转换当初是从被依赖的直接复制出来的,在序列化文件里它就是直接复制了这部分文本,但是这样无效,所以保存时序列化另外创建了转换对象,这部分文本也没有删。

这里m_ObjectHideFlags意思应该是这个对象已失效,隐藏,但是不删除。

我看了被依赖控制器YAML的一个转换对象,m_DstState字段根本没有guid,所以可能是拷贝状态时转换对象进了新控制器,添加了对原来目标状态的引用。

AnimatorStateTransition:
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: 
  m_Conditions:
  - m_ConditionMode: 6
    m_ConditionEvent: bodyStatus
    m_EventTreshold: 2
  m_DstStateMachine: {fileID: 0}
  m_DstState: {fileID: -5291231011926439337}
  m_Solo: 0
  m_Mute: 0
  m_IsExit: 0
  serializedVersion: 3
  m_TransitionDuration: 0.25
  m_TransitionOffset: 0
  m_ExitTime: 0.9493243
  m_HasExitTime: 0
  m_HasFixedDuration: 1
  m_InterruptionSource: 0
  m_OrderedInterruption: 1
  m_CanTransitionToSelf: 1
--- !u!114 &-9205196945450993477

继续实验:拷贝状态转换

然后我从一个状态机C拷了一个转换,到新建的状态机,什么也没拷上,然后打印一下新状态机的依赖,已经依赖上状态机C了。

如果徒手修改YAML文件

我删除了AnimatorStateTransition:k开头的一段,编辑器直接解析失败,状态机界面打不开,文件直接废掉。

继续实验:拷贝状态

又新建动画控制器,从控制器M拷贝状态过去,成功粘贴。打印依赖,依赖了状态机M。

被粘贴的控制器的YAML是这样的,控制器M的guid是05a5eccf713b1304b872c5c0c2e3ab0a,出现在AnimatorStateTransition模块,而不是AnimatorState模块。

%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1101 &-9221984846367630791
AnimatorStateTransition:
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: 
  m_Conditions:
  - m_ConditionMode: 2
    m_ConditionEvent: dead
    m_EventTreshold: 0
  m_DstStateMachine: {fileID: 0}
  m_DstState: {fileID: -3094905352768277915, guid: 05a5eccf713b1304b872c5c0c2e3ab0a,
    type: 2}
  m_Solo: 0
  m_Mute: 0
  m_IsExit: 0
  serializedVersion: 3
  m_TransitionDuration: 0.25
  m_TransitionOffset: 0
  m_ExitTime: 0.92788464
  m_HasExitTime: 0
  m_HasFixedDuration: 1
  m_InterruptionSource: 0
  m_OrderedInterruption: 1
  m_CanTransitionToSelf: 1
--- !u!1107 &-3121839260780123505
AnimatorStateMachine:
  serializedVersion: 6
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: Base Layer
  m_ChildStates:
  - serializedVersion: 1
    m_State: {fileID: 798723549730859907}
    m_Position: {x: 320, y: 30, z: 0}
  m_ChildStateMachines: []
  m_AnyStateTransitions: []
  m_EntryTransitions: []
  m_StateMachineTransitions: {}
  m_StateMachineBehaviours: []
  m_AnyStatePosition: {x: 50, y: 20, z: 0}
  m_EntryPosition: {x: 50, y: 120, z: 0}
  m_ExitPosition: {x: 800, y: 120, z: 0}
  m_ParentStateMachinePosition: {x: 800, y: 20, z: 0}
  m_DefaultState: {fileID: 798723549730859907}
--- !u!91 &9100000
AnimatorController:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: "\u54C8\u54C8\u54C8"
  serializedVersion: 5
  m_AnimatorParameters: []
  m_AnimatorLayers:
  - serializedVersion: 5
    m_Name: Base Layer
    m_StateMachine: {fileID: -3121839260780123505}
    m_Mask: {fileID: 0}
    m_Motions: []
    m_Behaviours: []
    m_BlendingMode: 0
    m_SyncedLayerIndex: -1
    m_DefaultWeight: 0
    m_IKPass: 0
    m_SyncedLayerAffectsTiming: 0
    m_Controller: {fileID: 9100000}
--- !u!1102 &798723549730859907
AnimatorState:
  serializedVersion: 6
  m_ObjectHideFlags: 1
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_Name: Dead
  m_Speed: 2
  m_CycleOffset: 0
  m_Transitions: []
  m_StateMachineBehaviours: []
  m_Position: {x: 50, y: 50, z: 0}
  m_IKOnFeet: 0
  m_WriteDefaultValues: 0
  m_Mirror: 0
  m_SpeedParameterActive: 0
  m_MirrorParameterActive: 0
  m_CycleOffsetParameterActive: 0
  m_TimeParameterActive: 0
  m_Motion: {fileID: 7400000, guid: 78833b2045374d9489cc36e6fa0e9bed, type: 2}
  m_Tag: 
  m_SpeedParameter: 
  m_MirrorParameter: 
  m_CycleOffsetParameter: 
  m_TimeParameter: 

如何拷贝状态机

右键有一个

粘贴后不会依赖源控制器,源控制器的guid也不会出现在YAML。

结论&教训

不要从已有的状态机框选Ctrl C拷贝状态和转换,否则目标控制器会引用源控制器。分AB包会出问题。

在状态机界面右键点拷贝。

Broken text PPtr in file(Assets/Art/Animators/XXX.controller). Local file identifier (-2698132134870541907) doesn't exist!

现在推测这个错误也是框选拷贝状态机导致的,在YAML里被添加了对动画文件的引用,但是这些模块停止随编辑器更新。

更多实验

我又框选Ctrl C几次,也不是一定会隐性依赖。一切以选择依赖结果为准,看见有2个控制器,说明已经被污染了。一旦污染这个控制器也就完蛋了,不管怎么删都无法去除依赖了,手动删YAML又会导致编辑器解析错误。

没有隐性依赖其他控制器,但是隐性依赖很多动画剪辑

还遇到了这个情况,依赖的动画剪辑明显多于实际用到的。

内容概要:本文围绕基于Transformer模型的电力负荷预测展开研究,提出了一种利用Transformer架构进行负荷预测的方法,并提供了完整的Python代码实现。文章详细阐述了Transformer在处理时间序列数据方面的独特优势,如强大的长期依赖捕捉能力和高效的并行化训练机制,相较于传统的RNN或LSTM模型在预测精度、收敛速度和稳定性方面表现更优。研究涵盖了从原始数据预处理、特征工程构建、模型结构设计到训练优化及预测结果评估的全流程,重点剖析了编码器-解码器结构、自注意力机制、位置编码等核心技术在负荷预测任务中的具体应用与实现细节,并通过真实电力负荷数据集验证了该方法在短期和中期负荷预测场景下的有效性和鲁棒性。; 适合人群:具备一定Python编程基础和机器学习、深度学习理论知识,从事电力系统分析、能源管理、智能电网、时序预测等相关领域的科研人员及工程技术人员,特别适合工作1-3年、希望深入掌握先进深度学习模型在能源领域实际应用的研发人员。; 使用场景及目标:①应用于电力系统短期或中期负荷预测任务,辅助电网调度、发电计划制定和能源市场交易,提升电力系统运行的智能化与精细化水平;②为研究者和开发者提供一个基于Transformer的时间序列预测完整实践范例,帮助深入理解其建模范式、关键组件的设计原理及超参数调优策略;③推动深度学习特别是注意力机制在电力负荷预测及其他能源时序数据分析中的创新应用与技术迭代。; 阅读建议:建议读者结合所提供的Python代码逐模块复现整个建模流程,重点关注输入序列的滑动窗口构造、位置编码的实现方式、多头注意力机制的计算过程以及损失函数的选择,同时鼓励在不同地区、不同季节的负荷数据集上进行迁移实验,以全面评估模型泛化能力,并尝试引入外部变量(如天气、节假日)进一步优化预测性能。
内容概要:本文围绕“计及电气热综合需求响应的区域综合能源系统优化调度”展开研究,提供了完整的Matlab代码实现方案,旨在通过模型复现帮助科研人员深入掌握综合能源系统的优化调度方法。研究聚焦于电力、燃气、热力等多种能源形式的协同优化,充分考虑用户侧的需求响应机制,构建了包含多种能源转换设备、储能装置及多类型负荷的区域综合能源系统模型。以系统运行经济性、能源利用效率和碳排放最小化为多重优化目标,建立了精细化的数学模型,并采用Matlab进行编程求解,实现了在不同场景下的优化调度仿真与性能对比分析,为提升系统综合效益、促进清洁能源消纳及实现低碳化运行提供了有效的技术路径与决策支持。; 适合人群:具备电力系统、能源系统、优化理论或运筹学等相关基础知识,从事综合能源系统、微电网、需求响应、低碳调度等方向研究的研究生、高校科研人员及能源领域的工程技术人员。; 使用场景及目标:① 学习和复现区域综合能源系统优化调度的经典建模思路与算法实现过程;② 掌握Matlab在多能流耦合系统建模、求解器调用与结果可视化方面的综合应用能力;③ 支持开展电气热综合需求响应相关的科研项目、论文撰写与工程实践;④ 为构建更复杂的多区域协同、不确定性优化或博弈调度模型提供可靠的代码基础与技术参考。; 阅读建议:此资源以Matlab代码为核心载体,结合详细的模型说明与结果分析,建议读者按照文档目录结构逐步研读,结合代码注释理解变量定义、约束构建与目标函数设定的逻辑,重点关注需求响应建模与多能耦合环节的实现方式,并可通过调整负荷参数、设备配置或优化目标等方式拓展模型,以适应自身的研究需求,同时可利用提供的网盘链接下载完整资源进行深入学习与验证。
内容概要:本文系统阐述了基于遗传算法优化长短记忆网络(GA-LSTM)的电力系统负荷预测方法,该模型通过遗传算法(GA)对LSTM的关键超参数进行全局寻优,有效克服了传统LSTM依赖经验调参的局限性,显著提升了预测的精度与鲁棒性。研究内容涵盖了完整的数据预处理流程、GA-LSTM混合模型的架构设计、遗传算法的优化机制以及详细的实验验证过程,并利用Matlab代码实现了整个算法流程。文中通过对比实验验证了GA-LSTM模型相较于单一LSTM及其他传统预测模型在预测准确性上的优越性能。; 适合人群:具备一定电力系统基础知识和Matlab编程能力,从事科研或工程应用的研发人员、研究生及高年级本科生。; 使用场景及目标:①应用于电力系统短期或中期负荷预测,为电网调度、发电计划制定提供科学依据,提高电网运行的经济性与安全性;②为新能源并网、电力市场运营、需求侧管理等业务提供精准的负荷数据支持;③学习并掌握智能优化算法(如遗传算法)与深度学习模型(如LSTM)融合的技术路径与实现方法,拓展在时序预测领域的研究与应用能力。; 阅读建议:读者应结合提供的Matlab代码进行实践操作,重点关注遗传算法优化LSTM超参数的具体实现过程、模型训练细节及性能评估指标的分析,建议在深刻理解模型原理的基础上,尝试调整算法参数或将其迁移应用于其他时间序列预测问题,以深化理解和掌握。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值