写在前面

  • 这次例子参考这篇实现博文(附带项目下载),博文前面介绍非常具体,可惜后面特写轨实现代码不是按照我想要的标准四大件(data、mixer、clip、track)来组织的,所以这里我略过介绍,只记录我在实现中遇到的问题。
  • 测试环境Unity2019.2.6:因为移动镜头用到了Cinemachine插件来实现,而该插件需要在Unity2018以上用Package安装(以前Cinemachine是放在Asset Store里的,现在已下架),Unity2017也不支持最新的Cinemachine,所以这里统一用Unity2019.2.6来测试。
  • 因为实现重点是“动作特写”,而不是研究Cinemachine,所以这里我没有去深入了解Cinemachine。

记录

  • 用Cinemachine插件Create Virtual Camera后,MainCamera想要移动位置都要靠这个Virtual Camera/vcam,而且vcam要改变位置(位置+角度)只能在场景中手动调,不能直接改坐标。
  • 【问题1】在测试“动作特写”时,注视target的vcam的中心很低(见下图),而参考做的就很合适(见下下图),怎么回事?

我做的测试:中心(黄线处)很低

参考:别人做的位置(黄线处)就很合适

  ——> targetGroup是不能移动的。但我的测试中放的target是人物脚下(见下方左图),而参考放的target是人物的腰(见下方右图),所以中心不一致。

                    

  • 【问题2】人物加完动作后,是原地做动作,不是朝着敌人跑过去,怎么朝敌人跑过去?——> 解决方案就是加入override轨,在override轨记录人物的位置。

    • override轨如果mute的话,编辑时会看不到效果
    • 空白的override轨要先点录制,随便加入一个关键帧,后面双击override轨才能编辑效果
    • 我想过用MatchOffsets来改动作,但这功能是为了两个动作顺滑过渡用的,而人物要跑向敌人,这之间位移之大,是不能用MatchOffsets来完成的。
  • 【问题3】人物有rising和idle两个动作融合不好,有位移 ——> 解决方法同上。
  • 参考博文用Animation Curve来实现时间变速,实现了自定义特写轨,但它不按标准四大件data、mixer、clip、track来组织,只写了一个脚本,而且还覆盖了Unity暴露出的参考轨Playable Track。我给特写轨起名为Time,按标准四大件重新组织了代码,依次如下:
    • data:TimeBehaviour.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables; [Serializable]
public class TimeBehaviour : PlayableBehaviour
{
public AnimationCurve curve; }
    • mixer:TimeMixerBehaviour.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables; public class TimeMixerBehaviour : PlayableBehaviour
{
private float curTime = 0;
private float maxTime = 0; public override void OnGraphStart(Playable playable)
{ } public override void OnGraphStop(Playable playable)
{
Time.timeScale = 1;
} public override void OnBehaviourPlay(Playable playable, FrameData info)
{ } public override void OnBehaviourPause(Playable playable, FrameData info)
{ } public override void PrepareFrame(Playable playable, FrameData info)
{ } public override void ProcessFrame(Playable playable, FrameData info, object playerData)
{
float scale = 1;
int inputCount = playable.GetInputCount();
for (int i = 0; i < inputCount; i++)
{
float inputWeight = playable.GetInputWeight(i);
if (!Mathf.Approximately(inputWeight, 0f))
{
curTime += info.deltaTime;
ScriptPlayable<TimeBehaviour> inputPlayable = (ScriptPlayable<TimeBehaviour>)playable.GetInput(i);
TimeBehaviour input = inputPlayable.GetBehaviour();
// maxTime 当前clip的时长
maxTime = (float)PlayableExtensions.GetDuration(playable.GetInput(i));
// curTime 当前clip的执行到哪个时刻
scale = input.curve.Evaluate(curTime / maxTime);
}
else
{
curTime = 0;
}
}
Time.timeScale = scale; } }
    • clip:TimeClip.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline; [System.Serializable]
public class TimeClip : PlayableAsset, ITimelineClipAsset
{
public TimeBehaviour template = new TimeBehaviour(); public ClipCaps clipCaps
{
get
{
return ClipCaps.Blending; //选择None,clip当然不会支持快捷键淡入淡出操作
}
} public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
{
var playable = ScriptPlayable<TimeBehaviour>.Create(graph, template);
return playable; } }
    • track:TimeTrack.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Playables;
using UnityEngine.Timeline;
using UnityEngine.UI; [TrackColor(0.898f, 0.701f, 0.207f)]
[TrackClipType(typeof(TimeClip))]
[System.Serializable]
public class TimeTrack : TrackAsset
{
public override Playable CreateTrackMixer(PlayableGraph graph, GameObject go, int inputCount)
{
return ScriptPlayable<TimeMixerBehaviour>.Create(graph, inputCount); } public override void GatherProperties(PlayableDirector director, IPropertyCollector driver)
{
base.GatherProperties(director, driver); }
}
  • 和博文的参考代码相比,我的代码修改重点:

    • 【重点1】如下图,博文这里的maxTime:因为不用mixer脚本,所以maxTime可以直接拿到当前clip的时长;

博文的maxTime

  我写的mixer脚本如下图,maxTime应该像这样取值才行。如果像博文那样写,得到的maxTime会是无穷尽。

我写的maxTime

    • 【重点2】如下图,博文这里的curTime会得到当前clip的进行时刻,意味着没有clip或切到下一个clip时,curTime会变为0;

博文的curTime

  我写的curTime如下图,应该像这样取值才会拿到当前clip的进行时刻。

【Unity】Timeline探索记(4)第二个例子——动作特写/子弹时间的更多相关文章

  1. 3、netty第二个例子,使用netty建立客户端,与服务端通讯

    第一个例子中,建立了http的服务器端,可以直接使用curl命令,或者浏览器直接访问. 在第二个例子中,建立一个netty的客户端来主动发送请求,模拟浏览器发送请求. 这里先启动服务端,再启动客户端, ...

  2. Akka探索第二个例子by fsharp

    本文重度借鉴了github上akkabootcamp教程. 先上代码 open Akka open Akka.Actor open System type Message = | ContinuePr ...

  3. Unity GeometryShader(从一个线框渲染的例子开始)

    GeometryShader这个概念,已经出现很久了,但由于性能不佳,所以使用的并不多.甚至移动平台根本就不支持.移动平台的硬件更新速度也是越来越快,GS的应用普及应该不会太远.就现阶段而言,GS来做 ...

  4. jqGrid移动滑块时冻结首列和第二列例子

    js代码如以下代码:在initAllGrid函数colModel1加入属性设置:frozen:true:然后在_initGrid('task_con_grid_div',colModel1)函数里面加 ...

  5. Unity TimeLine 资源结构

    ---恢复内容开始--- 先看一个TimeLine,如图 再来看看在Inspector中的PlayableDirector 其他参数字面意思很清楚了不再赘述,着重讲一下一个TimeLine绑定的资源. ...

  6. Unity TimeLine

    最近一直再看这方面的内容,看的比较多知识点比较分散,所以目的就是把这些知识点内容梳理一边,并作记录. PlayableDirector与TrackAsset,TrackAsset与PlayableAs ...

  7. Vuex2.0边学边记+两个小例子

    最近在研究Vuex2.0,搞了好几天终于有点头绪了. 首先vuex概念比较多,一定要搞懂里面的概念,可以参考官网Vuex2.0概念,我写此文的目的是希望能对前端爱好者提供个参考,加深对vuex2.0各 ...

  8. Dagger2 探索记1——四大基本组件(一)

    喝很多自主学习的人,我接触Dagger 2 框架的原因是刚进公司的时候导师给安排的学习任务,学习方式是组内培训. 听到这个消息的我,以为是部门的人轮流给我讲课. 后来导师跟我说,组内培训的意思是,我先 ...

  9. 日常小节----unity小坑记(射线检测固定层级)

    unity中射线检测需设定所需层级时,必须加上距离!!! //一条从主相机到屏幕点击点的射线 Ray ray = Camera.Main.ScreenPointToRay(Input.mousePos ...

  10. Unity 之 Redux 模式(第二篇)—— Rigidbody 改造,摄像机控制

    作者:软件猫 日期:2016年12月8日 转载请注明出处:http://www.cnblogs.com/softcat/p/6144041.html 上一篇文章中存在一个很严重的问题,首先我们先让 M ...

随机推荐

  1. 三本书带您快速深入掌握Spring Boot应用开发《Spring Boot从零开始学(视频教学版)》

    #好书推荐##好书奇遇季#三本书带您快速深入掌握Spring Boot应用开发<Spring Boot从零开始学(视频教学版)><Spring Boot应用开发实战><深 ...

  2. mi

    小米耳机页面 <style> * { margin: 0; padding: 0; } body { width: 1226px; background-color: #f5f5f5; m ...

  3. Windows10 Vmware安装Centos虚拟机

    准备工作 安装Vmware软件 下载地址:https://www.vmware.com/cn/products/workstation-pro.html 下载Centos7 镜像 下载地址:https ...

  4. Access to the path 'C:\Windows\TEMP\XXX.tmp' is denied.

    System.UnauthorizedAccessException: Access to the path 'C:\Windows\TEMP\ASPNETCORE_935a19f1-814f-4b3 ...

  5. 羊了怎么居家办公?免费不限速的远控软件RayLink一解燃眉之急!!

    近期疫情放开,各地症状不断的小阳人数量猛增(R君盼望大家早日转阴!!).不论是"羊"后居家,还是天选打工人被迫居家,远程控制公司电脑实现居家办公,成了大部分人的默契选择. 想远程控 ...

  6. JMM(Java内存模型)笔记

    JMM介绍1.什么是JMM?2.JMM的三大特性:1.原子性2.可见性3.有序性3.关于同步的规定:4.解释说明JMM中的八种操作:1.什么是JMM?​ JMM 是Java内存模型( Java Mem ...

  7. 【C++复习】第九章 模板与群体数据(1)

    1.例:求绝对值函数的模板 函数重载方便了函数的使用者,开发者还是要写两个函数 模板是用来生成函数的东西 编译器通过推导生成函数: 2.函数模板定义语法 从例题入手,别上来就扣语法 3.例9-1 函数 ...

  8. 平台总线模型(注册设备、注册驱动、编写probe函数)

    平台总线模型概念 注册platform设备 struct platform_device结构体 platform_device_register() platform_device_unregiste ...

  9. C语言学习--练习--合并两个字符串

    将两个字符串合并追加在一起, 类似于python的str1+str2 #include<stdio.h> #include<string.h> #include<stdl ...

  10. mac怎么设置开机自启动项,mac选择开机启动项

    转自 https://www.zhangshilong.cn/work/386853.html Login Items Mac OSX的当前用户成功登录后启动的程序,该类别的启动项配置文件存放在~/L ...