Cast蓝图函数

[复制链接]

该用户从未签到

3

主题

3

帖子

5

积分

新手上路

Rank: 1

积分
5
跳转到指定楼层
楼主
发表于 2017-8-8 22:09:38 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

想要查看内容赶紧注册登陆吧!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
类型转换Cast函数


由于在代码层面,Cast使用的是C++模板做的泛型编程,不太好解释,所以这里我只对Cast的蓝图函数进行介绍。上面给出的Cast蓝图的截图只是一个示例,实际使用中Cast函数会根据不同的输入输出类型来转换成不同的样子。

Cast这个单词本身有投射或者映射的意思,在C++里面实际上被用作类型转换。这个Cast的类型转换指的是指针类型的转换,也就是把一个东西转换成另一个相关的东西(而不是把浮点数转换成整型数那种转换)。

我们为什么要使用类型转换呢,在学习和使用Cast之前我们一定要先思考这个问题。
对于初学者来说,有个很厉害的概念叫蓝图通信,就是不同的蓝图之间交换数据。之前曾经看到有的新人发言说蓝图通信就是Cast函数,这个说法是不对的。但是蓝图通信确实在大多数情况下都用到了Cast函数,所以导致会有人认为Cast函数就是蓝图通信。

-----------------------------------------------------------------------------------------------

现在我来举个例子,当你继承Character类创建了一个叫做MyPlayer的角色蓝图,并且在这个叫MyPlayer的蓝图里添加了HP,MP,Name这三个属性。
现在我们就有了一个名叫MyPlayer的蓝图,它包含了Character类的全部属性和功能,同时还包含我们刚刚创建的HP,MP和Name这三个属性。

假设我们用某些方法(比如BeginOverlap事件)获得了这个蓝图

由触发的事件输出可以知道,比如BeginOverlap事件返回的是一个重叠的Actor,这个类型是Actor而不是Character,更不是我们创建的MyPlayer类,所以当我们需要从这个返回的物体中获取到我们的HP或者MP时,是无法找到这个节点的


所以这个时候,我们就需要将我们获得的Actor转换为MyPlayer类

这个动作相当于让编辑器知道了你要获取的是MyPlayer类,这样就能让编辑器检索到里面特有的属性,比如你创建的HP和MP。
此时再搜索HP或者MP,就能像搜索普通变量一样查找到你要的属性,接下来就能进行Set或者Get操作了


不知道这样是否能更容易理解Cast函数。

-----------------------------------------------------------------------------------------------

举完例子,让我们说一些深入一点的内容。
理解Cast的用法,我觉得有一点很重要,就是Cast的主要功能是为了还原
Cast类型转换只能转有继承关系的类,比如你创建的MyPlayer是继承自Character类,那么就可以将一个获取到的Character转化为MyPlayer。
从继承关系来讲,无论控制器(Controller),玩家角色(Character),可控制单位(Pawn),包括游戏模式(Game Mode)都是继承自AActor类,所以通常我们创建的类都可以被Cast到。

但是我们一定能注意到,Cast函数的输出除了有正常的空白输出引脚外,还有一个CastFailed引脚,就是当类型转换失败的时候执行的流程。我们可以灵活的使用这个功能。
比如我们的人物走进一个Volume范围内,触发Overlap事件来打开一扇门,这时只要是有物体进入了Volume内,就会触发这个Volume的Overlap事件,这时就会造成,即使我们开枪,让子弹进入了Volume范围,也会触发使门打开,当然这不是我们想要的。
这时我们就会使用到CastFailed的特性,在Overlap之后做一次Cast,如果能成功将Actor转换成我们的MyPlayer蓝图类,才能触发后续的开门流程,否则就什么都不执行。
这样一个操作就能做到灵活判断触发的物体的类型,并且根据"是我们要的类型"和"不是我们要的类型"这两种情况来执行不同的逻辑。

这里要说明一下何时会CastFailed:只有当我们得到的物体(输入Object)是我们的目标物体(输出Object)或者目标物体的子类时,才能成功Cast。
举个例子,当我们控制自己的角色进入触发范围,获取到的物体就是我们玩家类(比如之前创建的MyPlayer)本身,所以能Cast成我们的玩家类。当我们开枪,子弹进入触发范围时,我们获取到的是子弹这个物体,和我们玩家类没有关系,所以就会CastFailed,也就是不能Cast成我们的玩家类。

-----------------------------------------------------------------------------------------------

总结一下:
(1)Cast是将我们当前获取的类转换成它的子类,只有带有继承关系的类可以相互Cast,没有继承关系的类无法进行Cast。
(2)Cast通常是因为用基类(比如Actor)获取到了你的目标物体(比如你的自定义玩家角色),用Cast把它"还原"成目标物体使用的,就像上面举例,本身我得到的Actor就是我的MyPlayer类,才能转换成MyPlayer类。如果我的到的是其他东西,比如子弹物体,则会CastFailed。
(3)Cast还原目标类型是为了获取目标类型中特有的数据,比如我们需要HP和MP的值才把获取的Actor转换为MyPlayer,如果我们仅仅需要它的移动组件(Movement Component这个在Character类里就创建了),那么只Cast为Character也是可以的。
(4)只有你创建过的类或者现有类才可以被Cast到,也就是说你无法Cast到你工程里没有创建过的类。(不要跟着别人的教程或者工程,看见别人Cast成什么自己就跟着Cast成什么,名字一定要和自己工程里的类相同)。

-----------------------------------------------------------------------------------------------

很多时候,当我们需要新获取的物体去执行一个逻辑时,提前Cast一遍是一个好习惯,这样避免了让新获取的物体执行不属于自己的方法或者调用不属于自己的属性这样的危险。
在C++中,如果一个对象调用了不属于自己的函数或者属性,更甚至一开始就没有获取到对象时(对象指针指向nullptr),如果在这种情况下仍然假装一切正常的调用后续逻辑,会导致程序直接崩溃。

关于Cast暂时就介绍这么多,更深入的理解可以去看看官方的项目中对于Cast的使用。




分享到:  QQ好友和群QQ好友和群
收藏收藏
回复

使用道具 举报

快速回复高级模式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表