成都青羊区建设局网站flash做网站轮播图
web/
2025/9/27 6:39:00/
文章来源:
成都青羊区建设局网站,flash做网站轮播图,如何进行网站域名解析,上海人才网积分查询动画系统包含#xff1a;
动画片段 Animation Clip#xff0c;记录物体变化的信息#xff0c;可以是角色的闪转腾挪#xff0c;也可以是一扇门的开闭动画状态机 Animator Controller#xff0c;根据设置切换动画片段动画组件 Animator#xff0c;Animation替身 Avatar
动画片段 Animation Clip记录物体变化的信息可以是角色的闪转腾挪也可以是一扇门的开闭动画状态机 Animator Controller根据设置切换动画片段动画组件 AnimatorAnimation替身 Avatar对人形动画进行复用
动画复用
把一个 .anim 的动画文件作为文本打开 里面有个path属性记录动画要操作的对象的路径如果根据path找不到对象这个动画就会失效 其他物体要使用这个动画就必须包含路径一致的对象否则Animation窗口里就会显示Missing 对于人形动画的fbx文件选中动画按Ctrl D就可以把动画复制出来同样作为文本打开 这里path为空而attribute记录Avatar中对应的骨骼节点和进行什么操作
Avatar 替身系统 在mixamo上下载一个动画文件 不同DCC软件制作的骨骼节点的名称可能不一样的不能直接使用该动画这时候需要借助Avatar建立骨骼和Unity肌肉系统的映射关系
假设AB两个模型的骨骼名称不同要把A模型的动画片段A复用到B模型上 步骤 1.创建AAvatarAAvatar中保存模型A骨骼和Unity肌肉结构的对应关系骨骼信息也被保存到Avatar文件中 2.创建BAvatarBAvatar中保存模型B骨骼和Unity肌肉结构的对应关系 3.通过AAvatar把动画片段A从描述A的骨骼变化翻译为描述unity肌肉拉伸 4.模型B使用动画片段A通过BAvatar把动画文件中对Unity肌肉结构的描述翻译为对B模型骨骼变化的描述
具体操作 在模型的Rig面板中选择人形动画点击Apply
Avatar DefinitionCreate From This Model 从这个模型本身创建Avatar把当前模型的骨骼与Unity肌肉结构建立对应关系Copy from OtherAvatar 从其他Avatar中复制骨骼层次结构、绑定信息等需要确保两者具有相似的骨骼层次结构和绑定信息模型不会创建新的Avatar只会导入动画Skin Weights蒙皮或者mesh上的节点可以被几个骨骼所影响Strip Bones勾选后Unity会自动删除所有不必要的骨骼并将相邻的骨骼合并为一个单独的骨骼。这样可以减少骨骼数量和顶点权重数量从而提高游戏性能Optimize Game Objects勾选后会删除模型上的骨骼从Avatar中读取骨骼信息 模型中会出现Avatar点击Inspector界面上的Configure Avatar进入配置界面 这里可以看到骨骼和Unity肌肉的映射关系这些Unity基本已经配置好了一般不需要修改 动画的Rig面板中选择Copy From Other Avatar并选择来源模型的Avatar点击Apply 在模型的Animator组件中选择各自的Avatar文件这时动画就可以复用了
Animator Apply Root Motion有的动画片段自带位移勾选后就会把位移应用到对象上如果通过脚本控制位移就不勾选Update ModeNormal 与Monobehaviour的Update同步Animate Physics 与FixedUpdate同步如果角色动画需要与物理系统交互选这个Unscaled Time 与Update同步忽略TimeScaleCulling ModeAlways Animate 不剔除始终运行动画Cull Update Transforms 不可见时会禁用重定向ikTransform变化Cull Completely 不可见时停止模拟再次出现时从停止的状态继续模拟
运行时最下面还会显示动画片段相关信息 在Animator中动画状态分为3种单独的动画片段多个片段组成的混合树另一个状态机 在Animator窗口右上角有个Auto Live Link选中后会在窗口内聚焦当前播放的动画状态
动画片段AnimationClip Tag给动画加标签在代码中就可以根据动画的标签执行不同的逻辑Motion这个动画状态管理的动画片段如果是混合树就显示管理的混合树Speed动画播放速度负值就是倒放脚本无法修改Speed数值Multiplier勾选右边的Parameter激活选择Parameters中的一个浮点型参数关联动画的速度就等于 Speed * MultiplierMotion Time范围0~1f修改后会使动画停在特定时间点0是开始1是结束Mirror镜像动画Cycle Offset播放时的偏移值0表示不偏移0.5表示从中间开始播放偏移不是切割动画还是会完整播放只是动画的起始点改变Foot IK使用IK矫正把脚步实际位置向IK Goal位置拉近一点需要设置IK Goal权重Write DefaultsAnimator触发OnEable时将遍历AnimatorController中的所有片段收集所有片段的属性值。如果某个片段中没有描述某些属性的变化是否为其写入默认值
正向动力学Forward Kinematics常见的动画一般是由骨骼根节点人形动画是屁股到末梢骨骼节点依次计算旋转位移缩放来决定每个骨骼的最终位置 反向动力学Inverse Kinematics末梢骨骼位置确定反向计算各个父节点骨骼的旋转位移缩放比如脚放在台阶上反向计算其各个父骨骼 使用Avatar把骨骼系统转为肌肉系统后双手双脚位置可能出现一些偏移Unity会保存转换前骨骼系统下手脚的正确位置并把这些位置放在IK Goal目标位置上也就是上图中双手双脚位置的红球手肘处的红球和膝盖处的红球是IK Hint辅助位置通过它防止肘部关节出现奇怪的扭曲Foot Ik参考的是IK Goal的初始位置 使用IK需要在Layer上激活IK Pass这样就可以在脚本中调用IK相关方法
public class AnimatorTest : MonoBehaviour
{[Range(0, 1)]public float weight;private Animator animator;//动画状态private AnimatorStateInfo stateInfo;//关联Multiplier参数private float animationMultiplier 1;//Multiplier映射的hash值private int multiplierHash;void Start(){animator GetComponentAnimator();multiplierHash Animator.StringToHash(Multiplier);animator.SetFloat(multiplierHash, animationMultiplier);//获取当前动画状态0表示base layerstateInfo animator.GetCurrentAnimatorStateInfo(0);//判断动画的Tag是否为Animif (stateInfo.IsTag(Anim)){//do something}}void Update(){if(Input.GetKeyDown(KeyCode.W)){animationMultiplier 0.1f;animator.SetFloat(multiplierHash, animationMultiplier);}}/// summary/// layer上开启IK Pass/// /summaryprivate void OnAnimatorIK(int layerIndex){//设置右脚IKGoal的位置animator.SetIKPosition(AvatarIKGoal.RightFoot, new Vector3(1,0,0));//权重越高右脚越靠近设置的位置animator.SetIKPositionWeight(AvatarIKGoal.RightFoot, weight);}
}调用时机 当Animator的Update Mode为Nomal或Unscaled TimeOnAnimatorMove和OnAnimatorIk方法与Update同步当Update Mode为Animate Physics时与FixedUpdate同步
状态转换Transition 两个状态之间可以添加多个转换这样会变成三个箭头选中右侧的某个转换就可以为其单独设置转换条件比如条件1和条件2都会触发 idle - walk 这个转换分别设置转换条件即可它们之间是 “或” 的关系
转换的优先级 1.如果有勾选了Solo只执行勾选的转换不考虑其他的 2.勾选的Solo的转换中哪个条件先满足就执行哪个转换 3.如果条件同时满足优先执行上面的转换 4.勾选Mute的转换不会执行 上方可以修改转换名称
Has Exit Time勾选表示条件满足也要播放到某个时间点才执行转换不勾选需要设置ConditionsExit Time比例值0表示从第一帧转换0.5表示从中间帧开始Fixed Duration勾选表示转换持续时间按秒计算否则按百分比计算Transition Duration转换持续时间Transition Offset0表示下一个动画状态从第一帧开始播放0.5表示下一个动画状态从中间一帧开始播放Transition Duration转换持续时间Interruption SourceNone 转换不能被打断Current State 可以被其他相同起始状态的转换打断设置Ordered Interruption需要优先级更高Next State 可以被其他相同目标状态的转换打断Current State Then Next State 有相同状态的转换都可以打断但起始状态一样的优先级更高Next State Then Current State 有相同状态的转换都可以打断但目标状态一样的优先级更高Ordered Interruption勾选表示转换按照优先级排序优先级更高的状态才能打断Conditions转换条件
状态机里只有四个状态从A到D。当中的所有转换由相应的触发器变量trigger来控制 与A相关的转换有三个
选中A到B的转换把Interruption Source设置为Current State且Ordered Interruption勾选 当激活触发器来启动A-B的转换时从A到B的转换就可以被某些同样从A出发的转换所打断了因为勾选Ordered Interruption转换只能被优先级更高的A到C的转换打断 Trigger类型的参数只要激活就会触发转换如果与Trigger相关的动画转换并没有被执行Trigger会一直处于激活状态直到转换被执行 Conditions可以设置多条它们之间是 “与” 的关系必须同时满足才能触发转换注意如果勾选Has Exit Time即使条件满足也得等动画播放到Exit Time才能触发转换
Root Motion动画
Root Motion动画自带根位移会把动画上的位移应用到对象上有效避免角色动画和实际位移不同步产生的滑步现象。动画文件会在每一帧里直接修改对象的坐标值和角度值绝对值而Root Motion则通过相对位移和转角来移动游戏对象
Animator勾选Apply Root Motion后Unity会让游戏对象会乘以缩放矩阵旋转矩阵平移矩阵
public class AnimatorTest : MonoBehaviour
{private Animator animator;void Start(){animator GetComponentAnimator();}/// summary/// 使用该方法用代码替代动画修改对象位移旋转/// /summaryprivate void OnAnimatorMove(){//animator.deltaPosition已经考虑了缩放值transform.position animator.deltaPosition;transform.rotation * animator.deltaRotation;}
}勾选Apply Root Motion并实现OnAnimatorMove动画由脚本控制
在Generic动画中的使用Root Motion只需要管理一根根骨骼Root node实际工作中美术一般会给模型单独制作一根根骨骼这个骨骼的作用就是记录模型的位移旋转 Unity会把Generic动画对这根骨骼的操作当作对游戏对象的操作Apply Root Motion会把根骨骼节点上的绝对坐标和绝对角度转换为游戏对象的相对位移和相对转角 Root Transform Rotation绕y轴旋转Root Transform PositionYy方向位移Root Transform PositionXZ水平方向位移这三个属性与Root Motion相关的动画 动画文件中的Root Q和Root T表示对游戏对象的旋转和位移勾选Root Transform Rotation下的Bake Into Pose就不会旋转游戏对象而是去旋转根骨骼节点当我们不希望动画带动游戏对象旋转时就需要勾选这个Bake Into Pose。后面的loop match是检查动画第一帧和最后一帧的吻合度红色表示不吻合绿色表示吻合红色就不要勾选Bake Into Pose Root Transform PositionY下的Bake Into Pose同理勾选后动画不会影响游戏对象y方向上的位移而是去修改根骨骼的位移
Root Transform Rotation绕y轴旋转Bake Into Pose勾选表示旋转只影响骨骼和蒙皮外观并不影响游戏对象的旋转能不能勾选参考loop matchBased Upon游戏对象开始时对准的方向Original 动画本来的朝向美术制作时设置的朝向一般选这个Root Node RotationGeneric 对准根骨骼节点方向一般不准确Body OrientationHumanoid 对准上半身前方一般不准确Offset对旋转做偏移Root Transform PositionYy方向位移Bake Into Pose勾选表示y方向位移只影响骨骼和蒙皮外观并不影响游戏对象的位置能不能勾选参考loop matchBased Upon垂直方向上把模型的哪个位置对齐到游戏对象的原点Original 美术在设置的原点一般选这个Root Node RotationGeneric将根骨骼作为原点Center of MassHumanoid 质心作为原点FeetHumanoid 脚作为原点动画复用可能导致Original不准此时可以选这项Offsety方向偏移量Root Transform PositionXZ水平方向位移Bake Into Pose勾选表示水平方向位移只影响骨骼和蒙皮外观并不影响游戏对象的位置能不能勾选参考loop matchBased Upon水平方向上把模型的哪个位置对齐到游戏对象的原点Original 美术在设置的原点一般选这个Root Node RotationGeneric将根骨骼作为原点Center of MassHumanoid 质心作为原点 在动画预览界面点击坐标轴图标就可以显示center of mass这个质心也被称为body transform它的位置接近hips骨骼 红色箭头为质心在水平面的投影我们可以把这个投影当作Root Motion的根骨骼节点这个点被称为root Transform代码中这样访问它的位置和方向
private Animator animator;
void Start()
{animator GetComponentAnimator();Vector3 bodyTransformPos animator.bodyPosition;Quaternion bodyTransformRotation animator.bodyRotation;Vector3 rootTransformPos animator.rootPosition;Quaternion rootTransformRotation animator.rootRotation;
}Humanoid动画中的Root Motion的原理Unity会计算处一个root transformRoot Motion会把动画文件中描述的root transform的坐标和角度值转换为相对位移和相对转角并以此来移动游戏对象
1D混合树 创建混合树双击进入点击 “” 添加三个Root Motion动画
Parameter关联一个浮点型参数三角形示意图横轴是Speed的值纵轴是片段的权重随着Speed的值增大第一个片段权重减小第二个片段权重增加Threshold参数Speed为多少时片段的权重为1时钟符号片段播放的速度人形符号是否要镜像动画仅限人形动画使用Automate Thresholds取消勾选 Automate Thresholds就可以修改Threshold的值Compute Thresholds根据片段的一些属性重新计算Threshold需要Root Motion动画Speed 速度的绝对值Velocity X/Y/Z 分别表示Root Motion在三个方向上的位移速度Angular SpeedRad旋转速度弧度每秒Angular SpeedDeg旋转速度角度每秒Adjust Time ScaleHomogeneous Speed 自动计算动画播放速度使多个动画的移动旋转速度相等idle动画不需要计算可排除Reset Time Scale 将所有片段的速度设为1
上图中Compute Thresholds选择Velocity Z即根据前进后退方向上的速度计算Threshold动画前进的速度大约是1.745667后退的速度大约是-1.426688。Adjust Time Scale选择Homogeneous Speed使得动画速度一致 Root Motion的速度不一定是匀速的这里的1.745667是平均速度 在Animation窗口中观察z方向移动的动画曲线曲线分成多段并不是线性的
注意Unity动画做混合时包含非线性插值计算无法保证参数Speed为1时动画速度也为1这时可以调整播放速度来控制移动速度把播放速度改成 1/1.745667这样前进速度就是1 动画中前进后退的速度是针对原本骨骼的使用Avatar复用动画后会根据骨骼的缩放值调整速度
public class PlayerMoveTest : MonoBehaviour
{private Animator _animator;private float _forwardSpeed 1.745667f;private float _backwardSpeed 1.426688f;private float _targetSpeed;private float _currentSpeed;void Start(){_animator GetComponentAnimator();//Root Motion会考虑物体的缩放值humanScale记录了Avatar对骨骼的缩放//我们不希望整个animator的播放速度都受到影响修改特定动画状态的Multiplier属性_animator.SetFloat(Multiplier, 1 / _animator.humanScale);Debug.Log(humanScale: _animator.humanScale);}void Update(){Move();}void Move(){_currentSpeed Mathf.Lerp(_currentSpeed, _targetSpeed, 0.5f);_animator.SetFloat(Speed, _currentSpeed);Debug.Log(velocity.z: _animator.velocity.z);}public void PlayerMove(InputAction.CallbackContext callbackContext){Vector2 movement callbackContext.ReadValueVector2();_targetSpeed movement.y 0 ? _forwardSpeed * movement.y : _backwardSpeed * movement.y;}
}这里使用了Input System
Root Motion与Rigidbody一起使用
引入Root Motion是为了避免实际位移和动画表现位移不同步Root Motion解决的是同步问题而不是位移要控制位移就需要通过脚本的OnAnimatorMove方法注意animator的update mode改为animate physics动画记得Bake into pose
public class PlayerMoveTest : MonoBehaviour
{private Animator _animator;private Rigidbody _rigidbody;private float _forwardSpeed 1.745667f;private float _backwardSpeed 1.426688f;private float _targetSpeed;private float _currentSpeed;void Start(){_animator GetComponentAnimator();_rigidbody GetComponentRigidbody();_animator.SetFloat(Multiplier, 1 / _animator.humanScale);}private void OnAnimatorMove(){Move();}void Move(){_currentSpeed Mathf.Lerp(_currentSpeed, _targetSpeed, 0.5f);_animator.SetFloat(Speed, _currentSpeed);//物理引擎中会修改rigidbody在y方向上的速度Vector3 vector3 new Vector3(_animator.velocity.x, _rigidbody.velocity.y, _animator.velocity.z);//用animator从Root Motion动画中提取值传递给受物理引擎影响的rigidbogy_rigidbody.velocity vector3;}public void PlayerMove(InputAction.CallbackContext callbackContext){Vector2 movement callbackContext.ReadValueVector2();_targetSpeed movement.y 0 ? _forwardSpeed * movement.y : _backwardSpeed * movement.y;}
}参考
Unity动画系统详解
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/82601.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!