zoukankan      html  css  js  c++  java
  • 【Unity】Timeline探索记(4)第二个例子——动作特写/子弹时间

    写在前面

    • 这次例子参考这篇实现博文(附带项目下载),博文前面介绍非常具体,可惜后面特写轨实现代码不是按照我想要的标准四大件(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的进行时刻。

  • 相关阅读:
    eclipse export runnable jar(导出可执行jar包) runnable jar可以执行的
    mave常用指令
    771. Jewels and Stones珠宝数组和石头数组中的字母对应
    624. Maximum Distance in Arrays二重数组中的最大差值距离
    724. Find Pivot Index 找到中轴下标
    605. Can Place Flowers零一间隔种花
    581. Shortest Unsorted Continuous Subarray连续数组中的递增异常情况
    747. Largest Number At Least Twice of Others比所有数字都大两倍的最大数
    643. Maximum Average Subarray I 最大子数组的平均值
    414. Third Maximum Number数组中第三大的数字
  • 原文地址:https://www.cnblogs.com/caiger-blog/p/13754738.html
Copyright © 2011-2022 走看看