当前位置: 首页 > wzjs >正文

水务公司网站建设方案站内推广方式

水务公司网站建设方案,站内推广方式,专业返利网站开发,穿着高跟鞋做的网站注:软件版本Unity 6.0 Timeline 1.8.7 作者:CSDN RingleaderWang 原文:《Unity第25期——Timeline结构及其源码浅析》 文章首发Github👍:《Timeline结构及其源码浅析》 Bilibili 视频版👍👍&a…

注:软件版本Unity 6.0 + Timeline 1.8.7

作者:CSDN @ RingleaderWang
原文:《Unity第25期——Timeline结构及其源码浅析》
文章首发Github👍:《Timeline结构及其源码浅析》

Bilibili 视频版👍👍:《Timeline结构及其源码解析》https://www.bilibili.com/video/BV1bHjYzNE35

Unity的 Timeline 本质是一个包含很多可播放片段(Playable Clip)的区间树(IntervalTree),这个区间树可以排序、搜索、以及控制所有 Clip的激活与停止,最后利用底层的Playable系统,运行所激活的Clips,就是这么个东西。

(当然这么定义不够准确,IntervalTree不控制clip激活,只是排序和搜索clip。IntervalTree本质是装clip的容器,不考虑性能的话用数组也行。这么定义只是方便理解Timeline的底层结构罢了)

下面便详细解析下 IntervalTree 的结构。

TimelinePlayable利用IntervalTree来管理RuntimeClip,UML类图如下:

IntervalTree UML类图
  • m_Entries:记录所有 RuntimeClip 和其左右边界的List
  • m_Nodes:IntervalTree中的节点
    • node first/last: 表示存储在当前节点中的所有Runtimeclip中的首和尾index
    • center:排序前比较重要,表示待排序Runtimeclip左右边界中点,用于后续递归地进行二分排序
    • left/right:左右子节点

Build IntervalTree 逻辑:

private void Rebuild()
{m_Nodes.Clear();m_Nodes.Capacity = m_Entries.Capacity;Rebuild(0, m_Entries.Count - 1);
}private int Rebuild(int start, int end)
{IntervalTreeNode intervalTreeNode = new IntervalTreeNode();// minimum size, don't subdivideint count = end - start + 1;if (count < kMinNodeSize){intervalTreeNode = new IntervalTreeNode() { center = kCenterUnknown, first = start, last = end, left = kInvalidNode, right = kInvalidNode };m_Nodes.Add(intervalTreeNode);return m_Nodes.Count - 1;}var min = Int64.MaxValue;var max = Int64.MinValue;for (int i = start; i <= end; i++){var o = m_Entries[i];min = Math.Min(min, o.intervalStart);max = Math.Max(max, o.intervalEnd);}var center = (max + min) / 2;intervalTreeNode.center = center;// first pass, put every thing left of center, leftint x = start;int y = end;while (true){while (x <= end && m_Entries[x].intervalEnd < center)x++;while (y >= start && m_Entries[y].intervalEnd >= center)y--;if (x > y)break;var nodeX = m_Entries[x];var nodeY = m_Entries[y];m_Entries[y] = nodeX;m_Entries[x] = nodeY;}intervalTreeNode.first = x;// second pass, put every start passed the center righty = end;while (true){while (x <= end && m_Entries[x].intervalStart <= center)x++;while (y >= start && m_Entries[y].intervalStart > center)y--;if (x > y)break;var nodeX = m_Entries[x];var nodeY = m_Entries[y];m_Entries[y] = nodeX;m_Entries[x] = nodeY;}intervalTreeNode.last = y;// reserve a placem_Nodes.Add(new IntervalTreeNode());int index = m_Nodes.Count - 1;intervalTreeNode.left = kInvalidNode;intervalTreeNode.right = kInvalidNode;if (start < intervalTreeNode.first)intervalTreeNode.left = Rebuild(start, intervalTreeNode.first - 1);if (end > intervalTreeNode.last)intervalTreeNode.right = Rebuild(intervalTreeNode.last + 1, end);m_Nodes[index] = intervalTreeNode;return index;
}

构建思路非常简单:

  • 排序开始时,遍历所有Runtimeclip,确定最左端和最右端边界,然后取边界的中点作为根节点的center,这样构建的tree不至于一边短一边长。
  • 然后把所有Runtimeclip完全在中间值center左侧的放到m_Entries靠下位置,把所有Runtimeclip完全在中间值center右侧的放到m_Entries靠上位置,被center贯穿的Runtimeclip保留在当前节点中。
  • 这样就完成了初步排序,然后再递归地排序靠下的这坨,并作为左子节点;再递归地排序靠上的这坨,并作为右子节点。这样整棵IntervalTree就构建完成了。

最终结构如下图所示:

IntervalTree内部结构示例

RuntimeClip 结构

下面就以 AnimationClip 为例,讲解IntervalTreeNode中RuntimeClip的创建逻辑:

  1. 创建TimelineClip (主逻辑在TrackAsset)

    1. 根据TrackClipTypeAttribute的定义获取限定的ClipTypeGetType().GetCustomAttributes(typeof(TrackClipTypeAttribute))
    2. 创建限定ClipType的 TimelineClip 容器newClip = CreateNewClipContainerInternal()
    3. 把特定类型 ClipPlayableAsset 比如AnimationPlayableAsset塞进TimelineClip中asset参数中。(此时AnimationPlayableAsset中clip为null)
  2. 将具体AnimationClip塞进AnimationPlayableAsset的clip变量中AddClipOnTrack(newClip, parentTrack, candidateTime, assignableObject, state)

  3. 创建RuntimeClip (主逻辑在TrackAsset 的 CompileClips方法)

    1. 根据timelineClip和clip对应的Playable创建RuntimeClip
    2. 将新建的RuntimeClip加入区间树IntervalTree
  4. 重新排序区间树节点(可延迟执行)

最终,TimelineClip 与 RuntimeClip结构如下:

TimelineClip 与 RuntimeClip结构

运行时 IntervalTree

我们使用区间树 IntervalTree 最主要目的就是能快速搜索RuntimeClip,为什么呢?

因为每帧Timeline都会执行PrepareFrame方法,指明哪些clip在当前时间激活,哪些clip在当前时间停止,如果只是用List结构,搜索时间复杂度 O(n),而使用IntervalTree,时间复杂度便降到 O(logn)了。

TimelinePlayable PrepareFrame 方法执行逻辑:

  1. 利用IntervalTree获取当前帧所有激活的RuntimeClip
  2. disable上一帧激活,这一帧未激活的clip(会执行Playable的Pause()方法 )
  3. enable这一帧激活的clip(会执行Playable的Play()方法 )
  4. 根据mixin/mixout curve设置此clip所在的mixer input weight权重

http://www.dtcms.com/wzjs/428513.html

相关文章:

  • 网站建设含意网络优化seo
  • 腾讯云可以做网站吗新网站推广方案
  • 阳江网站建设sem搜索引擎营销
  • 北京网站建设是什么意思百度公司招聘2022年最新招聘
  • 自己做的网站在浏览器上显示不安全seo排名技术教程
  • 东莞网站建设设计百度应用商店
  • 销售网站设计宣传推广策略
  • 网站设计协议营销策划的十个步骤
  • 电影网站模板htmlsem竞价推广是什么
  • 嵌入式开发就业前景成都网站优化公司
  • 网站建设平台招商广告联盟app下载赚钱
  • 怎么做网站平台梦想明年2024年有疫情吗
  • 成品网页成都搜索优化整站优化
  • 小企业网站维护什么东西北京专业seo公司
  • 企业网站开发公司-北京公司建网站需要多少钱和什么条件
  • b s网站系统如何做性能测试ip营销的概念
  • 女孩子读电子商务好就业吗信阳seo公司
  • wordpress的结构简述优化搜索引擎的方法
  • 免费图片尺寸在线修改seo沈阳
  • 太阳伞网络营销策划书搜索广告优化
  • 六安百度推广公司seo的基本步骤是什么
  • 需要注册的网站建设互联网seo是什么
  • 室内设计网站国外免费html网站制作成品
  • 南宁月嫂网站建设如何建立一个网站平台
  • 建设部网站官网证书查询怎么推广一个网站
  • 网上做试卷的网站百度数据分析
  • 做h5页面的网站有哪些google关键词指数
  • 网站建设是什么费用中国三大搜索引擎
  • 开封网站开发巨量引擎官网
  • 销售型网站建设杭州seo技术