WeAthFolD's Inverted Field
前两天在看Twitter的Effective Scala的时候,看到了一些关于类型协变性的讨论。
之前虽然断断续续的看过一些讲协变性的文章,不过感觉果然还是没搞清楚呢……
于是花了一个晚上和半个早上的时间整理了一篇学习笔记,也算是了解了怎么回事。
// Type system is indeed interesting :-)
Update 2016.11.3:在学完Kotlin以后添加了关于Type Projection的小节。
首先,变性(Variance)是什么?简单的来说,它是用来处理复合类型的类型转换的一些规则。
常见的复合类型有数组和泛型类。当我们在讨论类似这样的问题:
List<EntityPlayer>
是否能被转型成 List<Entity>
?Object[]
的引用是否能接受一个 String[]
类型的引用?的时候,我们就在讨论复合类型的变性。
通常来说,变性分类为以下三种(假设 ASub
是 A
的子类):
List<ASub>
是一个 List<A>
,反之不成立。List<A>
是一个 List<ASub>
,反之不成立。List<ASub>
不是一个 List<A>
,List<A>
也不是一个 List<ASub>
。这里的” A
是 B
“的意思是:一个 B
类型的引用可以接受一个 A
类型的引用。可以通俗的理解为A
是 B
的子类。简单的来说,协变保持了类型参数的继承关系;逆变则逆转了类型参数的继承关系。
最近在做的项目里很经常的用到动画系统。其中遇到了一个比较特别的需求:在一个动画播放的过程中,让一个对象去跟随外部的对象。由此引发了一些对Unity动画系统的一些有趣的思考。
我们在制作一个2D的动作游戏,其中需要实现玩家角色的摔投技。摔投技需要让玩家摔投的怪物跟随着一个特定的路径(大致是玩家手的移动轨迹)运动,最后被砸到玩家身后的地上。
首先,这个轨迹肯定需要可视化编辑,正好玩家的动作部分的播放也是用的Unity的Mechanim动画系统,所以就考虑把轨迹部分编入动画系统实现。
这个轨迹是相对于玩家而言的,因此我在玩家下新建一个指示跟踪位置的节点(称为跟踪节点),并且在玩家的动画里操作该节点的位置。接下来想要让怪物跟随这个指示节点。这可以通过写一个小的跟随脚本,在脚本里公开一个follow对象,并在follow对象不为空的时候重设当前节点的位置实现。
| Player (Animator 1)
|- Follow Node
| Monster (Animator 2)
- Component FollowObject
- GameObject follow
接下来,只需要在动画里动态的改变follow对象,让它先设置为玩家的跟踪节点,在无需跟踪时设置为空,我们想要的跟踪效果就实现了。
……
真的是这样么?
愉快的迁移了博客~