unity3d人物动作中怎么让主角停止正在做的动作

1935人阅读
一、Apply RootMotion的作用:Apply RootMotion:控制角色在场景中动画的运动。角色动画驱动角色运动,类似于在游戏中直接使用动画,提高了动画的使用效率。
Root Motion 可以控制角色在动画中的运动,位移是变化的,如果没有包含Root Motion或Root Motion为0 那么如何控制角色在场景中运动呢?
例如下面walk前进的动画片段(In Place &原地踏步,原地运动)没有发生位移变化的。
二、对以上的片段如果运用在游戏中,如何控制角色在场景中运动呢?
答案:是使用曲线+脚本 公共作用来驱动角色在场景中运动
2.1、确保此动画片段经过Avatar处理及肌肉定义后选择Clips下的walk动画片段
2.2、选择循环项、另外确保每个都是“绿色”状态这样动画有很好的循环匹配性。如果是红色最好再调式下
2.3、曲线属性,单击+ 号来来新增一条曲线,命名WalkSpeed
2.4、创建一个角色控制器命名RootController并双击打开
2.5、拖动walk到动画控制器中,可以自动产生一个动画状态。&多个动画状态可以形成一个动画状态机
黄色表示是一个默认的动画状态
2.6、在动画控制器中左下角Parameters 选择+ 号创建一个Float并命名为WalkSpeed。对这个名字必须和之前的动画曲线名字一样。因为这样动画参数可以直接获取动画片段中动画曲线的数值。若不是用相同名称,就无法使用动画曲线里面的数值。
2.7、把角色资源拖动到场景中,并把动画控制器赋值给角色资源的Control
2.8、运行起来看看效果:in place
2.9、添加脚本
using UnityE
using System.C
public class RootControl : MonoBehaviour {
void OnAnimatorMove()
Animator animator = GetComponent&Animator&();
if (animator)
Vector3 newPosition = transform.
newPosition.z += animator.GetFloat(&WalkSpeed&)*Time.deltaT
transform.position = newP
在附加到动画之前,Apply Root Motion使用的是动画默认的Root Motion当附件脚本后就改成了脚本
三、最终效果
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:347339次
积分:2900
积分:2900
排名:第9658名
原创:68篇
转载:56篇
评论:20条
(1)(2)(10)(3)(3)(1)(1)(3)(5)(9)(5)(2)(4)(8)(5)(5)(12)(11)(5)(6)(1)(6)(16)4352人阅读
Unity(30)
bool AnimationStillPlaying( string animationName )
return animation.IsPlaying(animationName) && animation[animationName].normalizedTime&1.0f;
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:338419次
积分:3759
积分:3759
排名:第6729名
原创:96篇
转载:20篇
评论:34条
(2)(1)(4)(2)(2)(2)(3)(2)(2)(1)(2)(2)(1)(3)(1)(2)(1)(1)(4)(5)(2)(1)(4)(2)(1)(3)(6)(8)(13)(15)(1)(11)(1)(1)(1)(4)后使用快捷导航没有帐号?
只需一步,快速开始
&加载中...
查看: 7020|回复: 69
unity3D 动作师相关问题及解决方案
TA的其他好贴
马上注册,加入CGJOY,让你轻松玩转CGJOY。
才可以下载或查看,没有帐号?
本帖最后由 拉撒路 于
16:29 编辑
15lnzkgwn93k.jpg (38.82 KB, 下载次数: 41)
19:11 上传
先给明天的十一期m.o.a动画合集打个广告 敬请期待!!!
同为moa的管理 看见石头 春哥他们搞新的动作合集心痒难耐
无奈没有大块的时间用来动手做东西 只好用零碎的时间来写流水账
用u3d大概快四年了 踩过无数坑 遇到过各种问题 在此整理以免后来人再掉坑
由于时间久远有些问题虽然遇到过并且也解决了 但是现在已经记不得了
希望大家能跟帖说下遇到过哪些问题 我会一一整理 后续发出
遇到我不知道的问题 cgjoy这么大肯定有别人能解决 我也会一并记录
ps:附件为图片打包下载 1券意思意思 打了水印 诸君勿怪pps:欢迎各位加我的QQ群 unity坑中的动画师 群号:
(396.21 KB, 下载次数: 68)
18:53 上传
(507.1 KB, 下载次数: 41)
18:53 上传
(566.41 KB, 下载次数: 55)
18:53 上传
(199.29 KB, 下载次数: 63)
19:13 上传
(463.62 KB, 下载次数: 32)
18:53 上传
(510.22 KB, 下载次数: 46)
18:53 上传
组图打开中,请稍候......
19:06 上传
点击文件名下载附件
售价: 1 张CG券 &[]
, , , , , , ,
赞! 谢谢分享
谢路爷分享
酷!~ 感谢!
如何勾引别人关注你?
写的详细到位 ,感谢大神
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
感谢。指点
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
顶起&&写的很详细 感谢楼主分享{:7_252:}
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
~~~~~~~~~~~~~~~~~~~~~~~敬请期待!!!
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
大赞,问下 万向轴问题是什么
最常见的就是旋转超过180度就会从反方向转过去
晚点我补上&
本楼回复(<span id="dp_count_)
如何勾引别人关注你?
Powered by扫一扫,访问微社区
后使用快捷导航没有帐号?
签到成功!您今天第{todayrank}个签到,签到排名竞争激烈,记得每天都来签到哦!已连续签到:{constant}天,累计签到:{days}天
当前位置: &
查看: 838|回复: 1
在Unity中实现流畅动作以及时间线
7排名<font color="#FF昨日变化1主题帖子积分
在线时间110 小时
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
才可以下载或查看,没有帐号?
本帖最后由 木木妖妖 于
07:13 编辑
Uniry社区里有一个争论很激烈的,那就是怎样在游戏中除去不流畅的动作,使其看起来很自然。这个是普遍存在的,直接取决于你使用引擎的时间。没有一个单独的方案且适用于所有情况,但却有一些例子看起来确实不是最佳方案。很多开发者在一方面或者另一个点上遇到过动作不流畅的问题,但是确实很难得到一些帮。在中,有惊人数目的误导信息让人忽略时间线。Unity论坛中有很多答案,虽然正确,但是很难理解,需要自己充分解决一些疑惑。这篇文章的主要目的是通过解释Unity的时间线从而更深一层的解决问题,以及说明哪里,为什么会导致生涩,呈现一个能解决问题的方案。在呈现出这个方案的过程中,提供一个资源包。
对不流畅的类型熟悉吗?
上面的图片展示了一个动作不流畅的简单例子。很明显,这动作不是我们想要的。
创建一个新项目
导入默认的第一人称角色控制器,并把它放到一个新场景里。放置一些物体并环绕一圈。移除头部装备,使用游戏手柄会让观察的效果更好。通常情况下,移动的同时看看四周,你会注意到某部分会有很明显的不流畅。
让我们看看这个例子,我使用到的技术,后面将会讨论到。第一个例子和第二个相比较,在流畅性上你会发现有很大的差异。
很棒也很流畅,看起来更好。
在解决这个问题之前,理解Unity的Update循环是很重要的。我们需要检查Update以及FixedUpdate函数后面的逻辑。下面是Uniy执行顺序的摘录,可以在这里看:/Manual/ExecutionOrder.html
尤其是你会想仔细检查Update顺序段,如果你以前没有这样做过,它与这篇文章的其余部分高度相关。
原链接:/Manual/ExecutionOrder.html
了解流程图。
这个图表概述了,方法在单一的框架中被调用的顺序。该部分重点是FixedUpdate和Update的方法,分别用绿色和红色高亮显示。
Unity实现的就是所谓的半固定时间间隔。这意味着游戏主循环使用变化的时间线也能以任意的帧速率运行,在Unity叫做deltaTime,它使用固定的时间线去管理一个内部循环。这样做有些好处,首先,当锁定核心游戏模拟到一个恒定的速度的时候,能够以硬件许可的速度运行视觉更新。当然也存在一些缺点的,包括很容易出现上面提及到的生涩问题。下面程序简单描述了unity的update循环的大概结构。
[AppleScript] 纯文本查看 复制代码float currentSimulationTime = 0;
float lastUpdateTime = 0;
while (!quit) // variable steps
while (currentSimulationTime
&Time.time) // fixed steps
FixedUpdate();
Physics.SimulationStep(currentState, Time.fixedDeltaTime);
currentSimulationTime +=Time.fixedDeltaT
Time.deltaTime= Time.time - lastUpdateT
lastUpdateTime = Time.
Update函数可能对于你来说很熟悉。刚在Unity中对输入进行处理了以后,在屏幕上渲染之前,它就在monobehaviors的每一帧里进行调用。如果VSync可以使用,当完成了一帧后,Unity将会立即开始下一个,从而获得最高帧率。
每次物理模拟完成以后,FixedUpdate就会在Monobehaviors中调用。Unity将这些回调当做固定时间的一部分,即使在实际时间中,遇到偶数时间间时,多个模拟步骤就不计算。这是因为游戏物理性,尤其是加速动作,甚至考虑到delta times都是最准确和稳定的。在Unity里最为熟知的就是固定的时间线即fixedDeltaTime。它有一个默认的值:0.02,意味着游戏每秒钟就有50个物理节奏以及FixedUpdate的回调。这样的话,人们可以这样认为,独立的FixedUpdate帧速率,每秒回调次数相同,即使渲染速率或高或低。有必要强调的就是FixedUpdate和物理循环是异步的,不会在单独的线程中调用。
在这点上,让我们看几个Update频率的例子。
上面所述的频率大概就是每秒钟有50个FixedUpdates和60帧。然而,自从帧率是多变的以后,它就不能很好的实现了,因此,一个更现实的时间表如下,虽然夸张。注意一些框架是紧密联系在一起的,他们之间没有物理的步骤,通常发生在低渲染复杂度的情况下。另一方面,其他updates之间有很长的停顿,每帧都有许多物理步骤,经常在资源加载的时候发生。这意味着,即使您尝试以固定的步骤数量匹配帧速率,它们也不能保证被对齐。
利用我们对Unity时间线的了解,我们就能理解下面所呈现的例子。在这个场景中,有一个球体和相机都围绕着一个支点。当相机的transform设在左边的FixedUpdate循环中,右边是Update,球体的transform设在Update循环中。当右边保持平滑,左边有明显的生涩。
相机在左边的FixedUpdate中移动,Update在右边。因为Update和FixedUpdate相比,回调的频率不一样,当相机保持这样子,球体经常动。球体相对于相机移动会不稳定,从而导致了不流畅。让事物慢下来,这样行为可以观察。
上面所提及的例子,都是5%的速度。
所以,我可以看出不流畅的根本原因就是在Update或者FixedUpdate移动一些物体。简单的解决办法就是把所有的transform变化从Update或者FixedUpdate中移走。
然而,这是让事情变得棘手的地方。Unity开发者普遍回答是把大部分的游戏和运动逻辑放在Update中,FixedUpdate中只有偶尔物理任务。虽然这有一些优点,包括简单的使用,涉及许多原因所以它还是存在问题的。也许最重要的是,你的游戏是依赖于帧速率。这bugs以及不一致的行为打开了大门。更重要的是,它阻止了不确定性,几乎所有实时策略类型,例如,依赖。当你需要给一个物体加上加速运动,例如角色控制器的重力,它介绍了其中遇到的问题。对于这些物体来说,应该使用FixedUpdate,但是当物体在Update中移动时会出现不流畅(通过标准资源包的第一人称角色控制器来观察这个确切的问题)
因此,一个普遍的,有时又必要的选择就是把所有的状态和游戏逻辑放在一个固定的时间间隔里,例如FixedUpdate,在Update中严格处理视觉效果和输入逻辑。然而,这并不是没有它自己的挑战的。首先,你可能希望你的物理步骤在游戏逻辑上能以不同的速度发生,但这取决于你的游戏。可以通过实现自己的固定时间间隔循环,并从FixedUpdate中独立,可以达到你希望的速率。这做起来很简单,可以给你很多控制,运行轻微的调整从而实现优化。接着,当在FixedUpdate中为只读时,可能会遗漏输入,由于多个帧之间可能在FixedUpdates中发生,只有最后一帧的输入在下面的FixedUpdate中存在。这尤其对于按钮按下以及按钮松开事件有影响,当他们仅仅在单帧的时候处于激活状态。这个问题的解决方案就是缓存输入的每一帧,直到他们都在下一个FixedUpdate中处理了。将此行为集成到您使用的任何输入控制器中,这看起来是一个相当流畅的处理方式,并在一个地方保存缓冲。
然而有一个更大的问题,那就是FixedUpdate回调的频率通常小于客户端帧率,所以移动的物体不会随着屏幕渲染而频繁的更新自己的位置。这使得游戏有些起伏,但还是保持一致。有很多不同的方法来解决这个问题,使用内插和推论来找到适合FixedUpdates之间的帧,使运动看起来更流畅。内插,将一个对象从一个游戏状态平稳地移动到下面一个状态,它的方便之处在于可应用于对象,还能很轻松的工作,但也引入了一个需要等待的延迟fixeddeltatime。然而这种延迟被很多的游戏普遍接受了,甚至剧烈射击等,允许这种延迟使其更流畅。推断,预测一个对象将在下一个固定的步骤用到,避免了延迟,但本质上是更难以无停顿地工作,附带了性能成本。
相机和球体在FixedUpdate中的移动是通过使用右边的内插。
以上是另一个演示插值的比较。在左侧,相机和球体领域的变换都在FixedUpdate中设置。右边是相同的,但是随着在FixedUpdate时间线之间移动变换的平滑插值。注意这两个对象在任何一种情况下都保持一致,而在右边,更频繁的更新变换减少了生涩。
所以,内插是怎样在Unity里完成的呢?我打包了一个资源包,包含了一个setup,和我曾经使用的很相似,你可以在这里获得它。
另外,你可以利用这些模型,创建上面所提及到的例子。
启动程序基于三个脚本,当你导入了这个包后,在“Assets/ Scripts / FixedInterpolation”文件夹下可以找到。这些脚本是完全作了注解的,但更紧凑的版本在下面提供了,并简要说明了一下。
1、InterpolationController-存储两个最近固定节奏的时间标记,并通过在更新过程中生成一个全局插值因子来比较它们。脚本必须附加到场景中的单个对象上。[AppleScript] 纯文本查看 复制代码using System.C
public class InterpolationController :MonoBehaviour
private float[] m_lastFixedUpdateT
private int m_newTimeI
private static float m_interpolationF
public static float InterpolationFactor {
get { return m_interpolationF }
public void Start() {
m_lastFixedUpdateTimes = new float[2];
m_newTimeIndex = 0;
public void FixedUpdate()
m_newTimeIndex = OldTimeIndex();
m_lastFixedUpdateTimes[m_newTimeIndex] = Time.fixedT
public void Update() {
float newerTime =m_lastFixedUpdateTimes[m_newTimeIndex];
float olderTime = m_lastFixedUpdateTimes[OldTimeIndex()];
if (newerTime != olderTime) {
m_interpolationFactor = (Time.time - newerTime) / (newerTime -olderTime);
m_interpolationFactor = 1;
private int OldTimeIndex() {
return (m_newTimeIndex == 0 ? 1 : 0);
2、InterpolatedTransform -存储经过两个最新固定时间间隔的transforms对象,使用全局插值因子插入对象之间。它也确保对象被放置在最后一个固定步骤之后,当前固定步骤执行之前,而不是把它内插到最后。这意味着任何移动Transform的脚本都是在正确的状态下工作的。如果你传送一个对象并要防止插值,移动对象之后调用ForgetPrevious Transforms方法。这个脚本应该连接到在FixedUpdate中移动的任何物体。[AppleScript] 纯文本查看 复制代码using UnityE
using System.C
[RequireComponent(typeof(InterpolatedTransformUpdater))]
public class InterpolatedTransform :MonoBehaviour
private TransformData[] m_lastT
private int m_newTransformI
void OnEnable() {
ForgetPreviousTransforms();
public void ForgetPreviousTransforms() {
m_lastTransforms = new TransformData[2];
TransformData t = new TransformData(
transform.localPosition,
transform.localRotation,
transform.localScale);
m_lastTransforms[0] =
m_lastTransforms[1] =
m_newTransformIndex = 0;
void FixedUpdate() {
TransformData newestTransform = m_lastTransforms[m_newTransformIndex];
transform.localPosition = newestTransform.
transform.localRotation = newestTransform.
transform.localScale = newestTransform.
public void LateFixedUpdate() {
m_newTransformIndex = OldTransformIndex();
m_lastTransforms[m_newTransformIndex] = new TransformData(
transform.localPosition,
transform.localRotation,
transform.localScale);
void Update() {
TransformData newestTransform = m_lastTransforms[m_newTransformIndex];
TransformData olderTransform = m_lastTransforms[OldTransformIndex()];
transform.localPosition = Vector3.Lerp(
olderTransform.position,
newestTransform.position,
InterpolationController.InterpolationFactor);
transform.localRotation = Quaternion.Slerp(
olderTransform.rotation,
newestTransform.rotation,
InterpolationController.InterpolationFactor);
transform.localScale = Vector3.Lerp(
olderTransform.scale,
newestTransform.scale,
InterpolationController.InterpolationFactor);
private int OldTransformIndex() {
return (m_newTransformIndex == 0 ? 1 : 0);
private struct TransformData {
public Vector3
public Vector3
public TransformData(Vector3 position, Quaternion rotation, Vector3scale) {
this.position =
this.rotation =
this.scale =
3.InterpolatedTransformUpdater-用于调用interpolatedtransform 里面的几个方法,包括FixedUpdates之前和之后的其他脚本。必须放在有绑定过InterpolatedTransform的物体。[AppleScript] 纯文本查看 复制代码using UnityE
using System.C
public class InterpolatedTransformUpdater :MonoBehaviour
private InterpolatedTransform m_interpolatedT
void Awake() {
m_interpolatedTransform = GetComponent&InterpolatedTransform&();
voidFixedUpdate() {
m_interpolatedTransform.LateFixedUpdate();
原文链接:/news//rrypp5tkubynjwxhxjzd42s3o034o8
每日推荐:
71996/5000排名<font color="#FF昨日变化3主题帖子积分
日久生情, 积分 1996, 距离下一级还需 3004 积分
日久生情, 积分 1996, 距离下一级还需 3004 积分
蛮牛币3807
在线时间500 小时
粗略的看了一下,没太看懂,留着慢慢看。谢谢分享。
每日推荐:
经过游戏蛮牛认证的蛮牛小翻译unity中怎么让主角停止正在做的动作呢?_unity吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:16,702贴子:
unity中怎么让主角停止正在做的动作呢?收藏
急急急 谢谢了
票牛教你如何买到热门、便宜、真实的演出门票!
作为一个资深的酱油党,我们需要做的不仅仅是路过,在路过的同时还要帮助楼主,在这个冷漠的时代,给予楼主温暖。
本吧好心人解答一下吧~~~
upup~hoho~ddddd
学雷锋,做好事儿,看完帖,留个名,坐等解答。
没有吧友解答么!?!?
记录Time.time让他不计算 看说明文档 搜索time
animation.stop("run")
设置按键,当按键时角色停止运动
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或

我要回帖

更多关于 unity editor停止工作 的文章

 

随机推荐