unity PlayableDirector SetReferenceValue

(1)

bing    PlayableDirector  SetReferenceValue

(2)

Unity--如何将Timeline用于网络游戏的剧情系统中

https://blog.csdn.net/qq826364410/article/details/80501824

网络游戏中的角色都是动态生成的,所以如果要结合Timeline编辑剧情,就需要将动态生成的角色放入到“剧本”中。以下提供一个解决方案。

外部触发只需要提供timelineSn用于索引timeline,timelineDataSn用于索引剧情中的数据

TimelineData类用于timeline中的数据保存,通过Scriptable 序列化数据。数据主要分为演员数据和相机数据。

演员数据

 
  1. public struct ActorData

  2. {

  3. public string actorModelSn;//演员模型

  4. public string acotrName;//演员名字,剧情中演员的唯一标识

  5. public Vector3 actorPos;//由于演员出生位置、转角

  6. public Vector3 actorRotation;

  7. }

摄像机数据

 
  1. public struct VCamData

  2. {

  3. public string vCamPrefabSn;//索引保存非场景数据的prefab

  4. public string lookAtPart;//lookAtPart可以瞄准指定演员的指定部位

  5. public string followActorOrPostion;//跟随演员名字或出生位置

  6. }

 

 

  1. CreateAsset.cs 扩展Editor生成数据空壳。
  2. TimelineController类负责具体的timeline剧情细节,外部通过它来管理timeline剧情,而无需管具体细节。其最主要的职责之将 剧情数据与剧情相结合,而AssemblyTimeline方法主要执行这项工作。调用的Unity给出的接口有PlayableAsset 的outputs数据,这里获取剧情的binding数据,然后通过binding的sourceObj获取Track的类型,然后根据Track类型分别处理。

binding列表

 

  1. 对于AnimationTrack:通过SetGenericBinding来设置动作的执行演员(要求有Animator)
  2. 对于CinemachineTrack:通过GetClips获取镜头列表,然后通过Director的 SetReferenceValue将场景中的虚拟相机传入Timeline 中
  3. 对于自定义的PlayableBehaviour,也是通过类似的方法来传数据。但是另外有一点需要注意的是通过GetClips获取的是PlayableAsset对象,我认为他是一个对PlayableBehaviour对象的代理,如何对接两者的具体写法可以参照我自写的ConversationPlayable类。
  4. ScenarioObjController类用于管理剧情中的演员。
  5. ScenarioMod类模式类来管理剧情数据,以及执行主要逻辑。
  6. 剧情的演员列表存在ScenarioMod中的一个Dictionary中,Key是Name,Value是演员的ScenarioObjController

代码工程地址:

https://pan.baidu.com/s/1eSs3jAq

 

主场景在TimelineAction下的scene,按”K”键开始剧情。

(3)

Unity--Timeline自定义PlayableTrack

https://blog.csdn.net/qq826364410/article/details/80511057

今天尝试使用Unity timeline来做段动画, 发现BasicPlayableBehaviour已弃用, 而新的PlayableBehaviour不能直接往Playable Track拖。


翻了下文档使用PlayableAsset来新建PlayableBehaviour,然后使用ExposedReference,具体实现如下:

C# PlayableTest代码实现,功能就是当timeline开始播放时,设置Text为true,并把m_DialogStr字符串赋值给Text:

    using UnityEngine.Playables;
    using UnityEngine.UI;
     
    // A behaviour that is attached to a playable
    public class PlayableTest : PlayableBehaviour
    {
        public Text m_DialogContainer;
        public string m_DialogStr;
     
        // Called when the state of the playable is set to Play
        public override void OnBehaviourPlay(Playable playable, FrameData info)
        {
            if (m_DialogContainer != null)
            {
                m_DialogContainer.gameObject.SetActive(true);
                m_DialogContainer.text = m_DialogStr;
            }
        }
     
        // Called when the state of the playable is set to Paused
        public override void OnBehaviourPause(Playable playable, FrameData info)
        {
            if (m_DialogContainer != null)
            {
                m_DialogContainer.gameObject.SetActive(false);
            }
        }
    }

C# PlayableAssetTest 代码实现,真正拖入Timeline的PlayableTrack中的脚本,在Scene中创建一个UI的Text组件,并把Text组件拖到PlayableAssetTest 上的Text上,在m_DialogStr随便填写一段字符串,运行Unity即可看到效果:

注:Timeline的PlayOnAwake,一定要勾选,否则不会自动执行。当然也可以在代码中调用Timeline的Play()方法。

    using UnityEngine;
    using UnityEngine.Playables;
    using UnityEngine.UI;
     
    [System.Serializable]
    public class PlayableAssetTest : PlayableAsset
    {
        public ExposedReference<Text> m_DialogContainer;
        public string m_DialogStr;
     
        // Factory method that generates a playable based on this asset
        public override Playable CreatePlayable(PlayableGraph graph, GameObject go)
        {
            var playable = ScriptPlayable<PlayableTest>.Create(graph);
            playable.GetBehaviour().m_DialogContainer = m_DialogContainer.Resolve(graph.GetResolver());
            playable.GetBehaviour().m_DialogStr = m_DialogStr;
            return playable;
        }
    }

下面给出代码控制Timeline执行,把这个脚本挂在Scene中的随便一个GameObject上,不勾选PlayOnAwake,并把之前创建好的Text组件赋值给脚本的Text,把Timeline赋值给脚本的PlayableDirector,OK,现在运行Unity,只有当按下k键时,Timeline才会运行:

    using UnityEngine;
    using UnityEngine.Playables;
    using UnityEngine.Timeline;
    using UnityEngine.UI;
     
    public class DialogDirector : MonoBehaviour
    {
        public PlayableDirector director;
        public Text text;
        void Update()
        {
            if (Input.GetKeyDown(KeyCode.K))
            {
                foreach (PlayableBinding bind in director.playableAsset.outputs)
                {
                    if (bind.sourceObject.GetType() == typeof(PlayableTrack))
                    {
                        PlayableTrack playableTrack = (PlayableTrack)bind.sourceObject;
                        foreach (var clip in playableTrack.GetClips())
                        {
                            object clipAsset = clip.asset;
                            if (clipAsset is PlayableAssetTest)
                            {
                                PlayableAssetTest test = clipAsset as PlayableAssetTest;
                                director.SetReferenceValue(test.m_DialogContainer.exposedName, text);
                            }
                        }
                    }
                }
                director.Play();
            }
        }
    }

 

————————————————
版权声明:本文为CSDN博主「Mr_传奇」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq826364410/article/details/80511057

(4)

tsubaki/Rebind.cs

https://gist.github.com/tsubaki/30416864f4438fe1603ca34d32238c26

(5)

Set PlayableDirector bindings from script

https://forum.unity.com/threads/set-playabledirector-bindings-from-script.487337/

(6)

[专栏作家]探索TimelinePlayableAPI,让Timeline为所欲为

https://www.sohu.com/a/231583446_667928

之前快速地学习了一下Timeline,这里我们做快速的回顾,Timeline主要分为TimelineInstance和TimelineAsset,可以用Timeline PlayableDirector控制播放哪一个TimelineAsset

今天我们再来看看Timeline中的Track,并且动手实现一个老年迪斯科场景。

一图流

Track

Timeline可以添加很多Track来对不同的对象做控制。

  • Track 在Clip上控制动画,可以在有Animator组件但是没有AnimatorController的情况下直接播放动画。
  • Audio Track 在Clip上控制音频播放。
  • Activtion Track 在Clip上控制物体是否在场景中Active,GameObject.SetActive()的作用
  • Control Track 在Clip上可以控制和时间相关的元素,可以控制粒子系统,克隆物体,控制另一个timeline等。厉害的是我们放在Control Track上的例子特效,可以随意地拖动Timeline来预览效果,对特效兄弟来说是应该很强大很爽的地方。
  • Playable Track 控制继承自BasicPlayableBehaviour的clip (在2017.4.0f1版本里原先的BasicPlayableBehaviour因为性能原因已经被弃用,建议采用PlayableAsset和PlayableBehaviour)

如何有了这篇文章

虽然上面提供的几个track已经有很强大的功能了,但是实际操作中我们会发现这些远远不够,官方的Mannul上也没有更多的介绍,有效的资料是少之又少。那么官方演示的demo里的对话系统是怎么通过Timeline实现的呢?

于是我开始寻找,在Youtube上找到了Unite Europe2017上的演讲视频,Extending Timeline with your own playables(https://www.youtube.com/watch?v=uBPRfcox5hE&t=2331s)。

研究了一番,里面的例子就是LightControl将自己的理解分享给大家。让大家都能在Timeline里为所欲为。

深度理解Timeline

Timeline是建立在Playables API(https://docs.unity3d.com/Manual/Playables.html)上的PlayableGraph系统,在这套系统中Timeline相当于是一个函数的作用,我们从Assset传入InputData,Timeline处理后输出OutputData到对应的Component。

这套系统中有4个关键部分,Data,Clip,Mixer,Track

我希望我的这张图可以帮助大家快速对应和理解这4个部分。

Timeline也一个Templete,可以方便快速地被复用。

  • The Data 用来存放数据,需要被序列化。继承自PlayableBehaviour

  • The Clip 也就是asset,继承自PlayableAsset。因为是asset,所以不能直接与场景中的物体关联,需要关联场景中的物体时要用ExposedReference来声明, 并且通过Resolve方法赋值。

  • The Mixer Mixer控制当前Track中所有的clip的行为,根据每个clip不同的输入权重,计算需要的结果。 Mixer在Timeline中算是最重要的部分了。

d40c665ee82a4e2fa19b77e7b5d30201.jpeguploading.4e448015.gif转存失败重新上传取消

  • The Track 把Mixer计算的结果输出,可以指定输出到绑定的物体上。继承自TrackAsset。有好几个特性可以绑定,
    • TrackColor : 定义在编辑器中Track的标识颜色
    • BindingObejctType : 当前Track上的Mixer输出后的数据要传递的对象类型
    • TrackClipType : 当前Track上的Clip的类型

实践

通过上面的探究,我们要做老年disco效果,那就来定制一个自己的track,专门用来控制Light,我们叫LightControl

  • 创建一个新的场景添加两个角色,一红一蓝
  • 新建一个ParticleSytem,烘托一下Disco的气氛
  • 创建一个新的Timeline,DiscoTimeline
  • 在DiscoTimeline上新建2个AnimationTrack,一个控制蓝角色的动画,一个控制红角色的动画
  • 在DiscoTimeline新建一个ControlTrack,控制刚才创建的ParticleSystem
  • 在场景中新建一个SpotLight和一个PointLight
  • 在DiscoTimeline中新建一个TrackGroup,命名为PlayableLight
  • 在DiscoTimeline中新建我们的LightControl Track,将SpotLight与这个Track绑定,命名为SpotLight
  • 在DiscoTimeline中新建我们的LightControl Track,将PointLight与这个Track绑定,命名为PointLight
  • 将我们自定义的Clip添加2段到SpotLightTrack上,在一个Clip上的LookAtTarget上绑定蓝角色,另一个Clip上的LookAtTarget绑定到红角色
  • 将我们自定义的Clip添加2段到PointLightTrack上,设置变换的灯光颜色和强度。 最后的Timeline就是这样

Play and Enjoy It

结尾

关于Playable API比较有趣的是,Playable使用C#结构体而非C++对象来保存对象。使用结构体的目的是避免分配GC所需的内存。这样用起来可能稍微有点复杂,但由于该API承载了未来的很多功能,所以必须注重性能问题。

掌握了Timeline的系统设计理念后,我们基本上就能掌握Timeline,实现自己想要的效果了,希望大家能打开脑洞,用Timeline创造出更多好玩的东西来。

另外视频中提到的PreviewMode我还没有非常明白,就先不写出来了,如果有兄弟知道的话,希望你能不吝赐教。

 

 

 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值