【Unity】TimeLineCinemachine系列教程——动态赋值,我要打十个!

【Unity】TimeLineCinemachine系列教程——动态赋值,我要
打⼗个!
【Unity】TimeLine&Cinemachine系列教程——动态赋值,我要打⼗个!
孙志刚事件
前⾔
TimeLine在上⼀篇介绍了TimeLine的各个功能特性,已经⽤TimeLine做了⼀个固定的特写镜头。但是要⽤好TimeLine还得去学会如何去掌控它,因此今天主要内容之⼀是⽤代码赋值修改TimeLine中轨道的参数(为了能更好的做出效果,⼏乎快做了⼀个格⽃游戏了,想做动作游戏想的热⾎沸腾~,最后想着还要出教程,还是停下来⽼⽼实实做功能)。
前前后后遇到了很多坑点,TimeLine有许多没法⼒所能及的地⽅,在这篇⽂章结尾会将主要的问题写出来,避免⼤家继续踩坑。
最终效果
Track赋值
创建了TimeLine的物体会有⼀个绑定列表
绑定列表对应我们做TimeLine各个控制轨道
我们是可以对轨道修改名字的,这个修改后的名字就是Bindings的key值。
脚本中可以获取到PlayableDirector类,通过SetGenericBinding函数赋值物体。
var mDirector = new PlayableDirector;
mDirector.SetGenericBinding("轨道名字","轨道绑定的物体");
这⼀步是⽐较简单的,完成这⼀步后,我们可以创建两个动画,在游戏中触发TimeLine后,动态给轨道赋值。⽐如给攻击动画轨道赋值玩家模型,给受击动画轨道赋值怪物模型。
/*有的读者可能会问,我们如果做攻击和被击效果的话可以直接把动作放在⾓⾊控制器⾥⾯,没必要⽤TimeLine实现。的确是这样,但是如果游戏中模型动作资源太多,⽐如战神这款游戏,每⼀个精英怪都会有⼀个动作特写,如果⼀开始全部放在动画控制器中,会造成动画⼗分混乱。⽽使⽤TimeLine,相当于我们动态给模型加载动画,当使⽤到这个动画的时候再加载它,这样就会让动画控制器⾮常的⼲净简洁,也节约了动画占⽤的内存*/
TimeLineClip赋值
接下来我们会动态给轨道内的Clip赋值,⽐如说Cinemachine的摄像机,和摄像机观察的物体、跟随的物体。
获取到Clip的代码我是做了⼀个字典来在playableAsset.outputs输出信息中储存了所有轨道信息。
foreach (var at in mDirector.playableAsset.outputs)
{
if (!bindingDict.ContainsKey(at.streamName))
{
BLK222bindingDict.Add(at.streamName, at);
}
}
var CinemachineTrack = bindingDict["Cinemachine"].sourceObject as Cinemachine.Timeline.CinemachineTrack;
foreach (var clip in CinemachineTrack.GetClips())
{
//TODO
}
}
⽽没有⽤GetGenericBinding函数是因为传⼊的值是Object类型,⽬前没到⼀个有效传⼊数据。
给Clip赋值有⼏个重要的地⽅,⼀是Clip的名字是TimeLineClip的displayName,TimeLineClip.asset是⽚段资源,⼆是赋值的时候得创建ExposedReference类型的结构体,不然直接赋值是没法⽣效的。
public void Init()
{
……
……8510w
foreach (var info in CinemachineTrack.GetClips())
{
if (info.displayName == "CinemachineShot")
{
var cameraInfo = info.asset as Cinemachine.Timeline.CinemachineShot;
var vcam1 = GameObject.Find("CM vcam1").GetComponent<CinemachineVirtualCameraBase>();
var setCam = new ExposedReference<CinemachineVirtualCameraBase>();
setCam.defaultValue = vcam1;
cameraInfo.VirtualCamera = setCam;
}
}
}
侧脑室Clip如果赋值完毕后,要修改Clip的参数,必须解析playableGraph,不然修改的⽬标并不是实际游戏中的物体。
var cameraInfo = info.asset as Cinemachine.Timeline.CinemachineShot;
var vcam2 = cameraInfo.VirtualCamera.Resolve(mDirector.playableGraph.GetResolver());
vcam2.LookAt = ansform.Find("Tran_Chest").transform;
vcam2.Follow = ansform;
}
这⾥有坑点:playableGraph是TimeLine运⾏时才会创建⽣存,否则为空。因此我们修改的这些值实际是 TimeLine已经播放的时候修改的。如果TimeLine在OnGraphStart函数中⽤了的值,我们这⾥修改后是⽆效的。
编写触发脚本
做这个之前有⼀个⼩插曲,本来我是想⽤TimeLine的⾃定义脚本轨道来搞定被抓取后怪物的位置修正的,结果发现不能⽤TimeLine来做,因为TimeLine的赋值修改会直接对所有⽤到这个TimeLine资源的物体⼀起赋值(这个bug⽬前没有到解决⽅法),所以⽤⾃定义脚本轨道上处理位置修正,就会保留当前的⽬标信息,下次抓另⼀个怪物的时候就会两个物体⼀起运动(神奇的bug)。
所以我直接把抓取的时候位置修正代码和触发TimeLine的代码⼀起了,代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Timeline;
using UnityEngine.Playables;
using Cinemachine.Timeline;
using Cinemachine;
public class KillControl : MonoBehaviour
{
public GameObject mKillInfo;
[HideInInspector]
public PlayableDirector mDirector;
Dictionary<string, PlayableBinding> bindingDict = new Dictionary<string, PlayableBinding>();
public CharaControl playerControl;
private CharaControl mControl;
public Vector3 offsetPos;
public Vector3 offsetRot;
public UnityAction OnFinishEvent;基因甲基化
public void Start()
{
mControl = GetComponent<CharaControl>();
mKillInfo = Instantiate(mKillInfo);
mDirector = mKillInfo.GetComponent<PlayableDirector>();
foreach (var at in mDirector.playableAsset.outputs)
{
if (!bindingDict.ContainsKey(at.streamName))
{
bindingDict.Add(at.streamName, at);
宫本海峡}
}

本文发布于:2024-09-22 03:37:36,感谢您对本站的认可!

本文链接:https://www.17tex.com/xueshu/436263.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:轨道   赋值   动画   物体   模型   修改   时候   动态
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议