|
参考:
1、引擎安装
关于论坛讨论,可以遇到问题后到论坛查找一下:
打开laucher创建一个新的空白项目。选择一下的设置:

注意这里的项目名称,他说好像会影响在VS中的一些标识符。会根据名字创建相应的.cpp和.h。和他一样就得了。
创建项目的时候,会同时创建VS文件,里面有所有的Cpp代码。我们就在里面写代码。
右上角鼠标浮上去就会有相关的引擎版本信息。
同时VS现在会加载出来。
配合鼠标键盘来操作场景视角。
2、视口
配合移动缩放选择组件
和下面的实现连贯和不连贯的移动。

我们还可以按End键,让物体贴到它下面的面上。
3、编辑器概述

最左上角的时标签栏,用于多个项目打开的时候。然后是菜单栏,右边帽子是一个官方给的介绍的工具,还有一个介绍项目相关信息的。

左边时modes栏,里面都是可以访问的各种资源,可以直接拽到场景中。
上边是工具栏。重要的是play按钮。他的下拉框:

可以有不同的运行模式。
然后右下角view option选择:
可以看到
对于世界大纲:

我们可以在物体对应或者寻找物体的时候双击。
我们可以F聚焦某一个物体,然后按住alt键来从周围各个视角来看该物体。
detail 面板:会显示选中物体的各种属性信息。

可以在这里面修改位置等信息,然后回车就生效了。
4、关卡蓝图

然后点击左上角标签,拖拽就能让他独立处于一个浮动窗口。


一般给他拽到上边去。

通过搜索创建第一个node。这个就相当于游戏开始了。

创建一个print函数节点,然后编译并save

这时候我们运行游戏就可以:

同时,我们点击下拉框:

可以进行更多的设置。颜色和持续的时间。
还有一个节点:event tick这个是每一帧都触发的事件。

然后运行的结果:

这个每一帧都会输出一个。

这个是帧数的显示。
5、创建蓝图

在content右键就可以创建自己的蓝图,

这里会让你选择父类。创建后双击打开。
如果创建一个Actor的,那么就会有一个球,代表这里有一个actor,但是这个球只是给我们看的,实际运行起来并不存在。

然后添加一个static mesh

然后选择我们的mesh,右边会有detail panel:

其中有一个设置:

stati mesh一般会有这三个选择,这三个和光照有关系,如果写的是static,表示告诉引擎物体不会移动,那么引擎就会帮我们做bake shadow,这种阴影就是不会动的,不会实时更新的。
stationary是用于光源的,表示光源不会移动,但是可以调整亮度等信息。
然后我们在static mesh设置rock模型,编译保存之后,我们可以吧我们的蓝图直接拽到场景中,

另外:


这里默认有三个节点。

然后:

这样每一帧都能够让x移动1。另外编译之前,我们需要改一下设置,改成movable:

然后回到编辑器。play就可以看出效果。
6、C++和虚幻4





下面是虚幻中的继承关系:


pawn有额外的特性,比如可以用控制器控制(控制器是一个特殊的Actor类,可以接受用户输入),就意味着可以鼠标等控制移动。
character有专属的运动组件,组件有合适的函数,人的各种动作,跳,跑,等等。
而对于这些东西的实现非常复杂:



继承关系中出现的

一个自定义类型的变量作为另外一个类的成员

虚幻中


7、虚幻引擎类的创建

右键点击就可以创建,同样我们还是可以选择父类:

这里的右上角有一个show all ,然后这里我们选择父类为character。

创建好之后,会在VS中打开:

这里类名多了一个A是因为继承于Actor,会自动加上这个A字母。
然后这里的三个函数也都是对于父类的override。
我们可以利用VS的转到定义,一级级的往上找到父类。最后找到UObject,以后有U字母在前边的表示继承于object,如果继承了Actor,那就会变成A。

关于cpp文件中这三个函数给的实现,都是Super::什么,意思就是调用父类的同名函数。
关于构造函数

这个真表示tick函数起作用,false表示不起作用,可以节省一些资源。
8、反射和垃圾回收

c++本身没有,虚幻有反射系统,负责采集数据,负责合并c++数据和虚幻编辑器系统并显示在蓝图中,负责垃圾回收,

关于垃圾回收:大致就是虚幻引擎会记录对象的引用数,一旦所有引用消失之后,便会进行对象的资源回收。
要想实现这一点,我们需要用到宏。
这里有一个UHT,unreal header tool,他是在编译的时候去识别这些宏的,

当他识别到之后,会为这些宏生成相应的code,这样反射系统就可以发挥作用。
UCLASS放在所有类的顶部,代表反射系统的类。修饰之后该类就会有垃圾回收机制。

同时类里面的变量和函数前面也必须加上相应的宏,才能参与反射系统。

这个头文件包含了所有的

上边说的那些宏他们可以在后面加个括号传进去参数。
9、UObject

选中show all之后创建一个继承object的类。

这里的几个头文件,第一个一般object类都会包含它,它包含了object需要使用的大量后台代码。第二个和第一个是差不多的。第三个就是反射系统的,有了它才有垃圾回收,也能够把变量和函数反射至虚幻编辑器中。

这里的三个宏都是为了反射系统进行服务的。
通常来说,我们创建好cpp类之后,我们喜欢创建一个基于该Cpp类的蓝图。

这一点右键就可以实现,但是这里是不行的,

然后我们只需要回到cpp代码加上一个参数就好了:

然后保存,右键build


现在就好了。这是因为我们的反射系统在起作用。
现在就把刚刚的cpp和这里的蓝图联系在一起了。创建的东西就是之前cpp代码的蓝图版本。
他是object,不是actor,我们之前说class继承关系的时候,说过object不能直接拽到level中,

现在给cpp中加上一些自定义的变量和函数,同时写上构造函数,注意类名需要加上U~
想要在虚幻里面看到这些变量函数,需要加上宏:

但是加了之后只是反射系统弄过去了,但并不能访问,需要访问的话得对宏加上参数,

另外还需要加上public,才能真的访问的到。

同时cpp文件中写上俩函数的定义。执行build

现在回到蓝图之后,我们就可以read and write myfloat。

10、在蓝图中运用UObject

这里我们在两个宏里面加上更多的参数。

这时候就是对于我们的变量进行一个分类。这样可以更好的区分变量和函数。

我们还可以设置为ReadOnly。这样让蓝图那里九只能读。
我们可以对我们的函数写一些实现:


第一个参数表示该日志的类别是临时的,warning表示警告,会输出颜色为黄色。编译之后我们到MyActor:

我们只需要在这里添加一个MyObject_BP类型的变量。detail面板可以修改类型:

这里搜索,不带BP的是c++类,而带BP的是蓝图。注意右边还会出来四个选择,我们通常选第一个。
然后把变量拽到视口中,然后选择get就可以得到MyObject类的对象了。

然后一拽就能够访问它的函数了。然后连接到BeginPlay上:

这样游戏一旦开始就会调用这个函数了。

然后把日志窗口调出来。

这时候直接运行会出错。

原因就是我们创建的myobject_BP对象只是一个指针,指向该类型的指针,同时你看一下默认值是none,也就相当于这是一个空指针,那么这肯定不能访问相应的函数的。
所以我们需要创建处相应的对象,那么怎么创建呢?在C++中需要相应的new和构造函数,这里可以用一个节点:

这里第一个class是我们需要构造对象的那个类,然后outer这里是在Actor类中写的,就写MyActor就好了,最后的返回值其实就是new的结果,也就是指向构造的对象的指针。

然后我们用该指针去set我们的变量,set之后就可以调用函数了。

我们就可以看到我们设置的log了。
所以捋一捋:我们在c++ class 的地方创建一个c++类,然后用VS打开把代码完善,并设置好反射系统,然后回到UE,我们可以创建出这个c++类对应的蓝图类,然后这个类如果是Object的,不能直接拽到level中,那么我们可以在其他蓝图类中创建该类的对象,来使用该类编写好的函数。然后其他的蓝图类可以拽到level中直接创建一个实例。
11、Actors和Actor组件

这里首先创建一个BluePrints文件夹,把我们的蓝图都放进去,便于查找。

我们现在又俩蓝图,对于My Actor来说我们是直接右键创建的蓝图类,也就是说他并不想MyObject那样有一个对应的C++类。
我们现在想要创建一个带有对应c++类的蓝图Actor。我们要创建一个新的actor,它可以四处浮动,所以我们合理命名为Floater。

这里生成的代码和我们之前的MainCharacter是类似的,但是比character少了一个

这一点我们之前介绍虚幻中这些类的时候说过,character是继承于pawn,而pawn则是来自Actor的,也就是Actor更加基础一些。character功能更多一些,包括鼠标键盘输入等等。
然后我们就可以直接创建想要的蓝图类了,之前我们的Object还需要设置一下Blueprintable,这里并不用了,因为它继承了父类的这一点。(在Actor中)

然后创建相应的蓝图,打开后:

我们看一下这里的组件,组件是UObject的特殊类型,专门被用作Actor中的子对象,每一个Actor都有一个DefaultSceneRoot组件,这个组件不可见,不支持可视化,也不能赋给他网格,这个就是那个白色的球,但是它现在显示一个白色的球,只是告诉我们有东西,实际游戏的时候就没了。

我们把蓝图类拽到场景中,然后创建相应的实例,是可以看到那个球的,但是游戏一旦运行起来就没了。只是给我们一个reference。告诉我们这里有一个Actor。
这个是Scene 组件,他是Actor组件的一种,是一个basic组件,它支持的detail panel有transform等等。
primitive组件更加的具体。他是源于场景组件的,有几何和碰撞等信息。

这里的cube这些组件就是primitive组件,我们创建之后可以有static mesh。

我们创建cube之后,cube是root的child,会随着场景的transform等变化。

然后我们可以把scene root组件给舍弃,用我们创建的cube取而代之。

只需要拽着cube到root上边就好了。刚刚我们按End键对齐是按照球的中心和面对齐的,但是现在改了root之后,再对齐就是以立方体的底部进行对齐了。这样体现了场景组件和primitive组件的不同。
当我们现在把cube组件删除,之前的默认的scene组件就又回来了。
我们可以在该位置创建static mesh来使用,也可以在cpp code中创建。
组件是特殊的Object,所以这里我们不要忘记U前缀:

但是上边我们只是创建了一个指针,并没有实际的组件,我们还需要在构造函数中:

这个函数就是用来创建对象的,可以创建任意类型的对象,模板参数告诉它类型即可,然后参数是一个TEXT。

这时候我们就创建出来了。
12、位置矢量

这里我们先创建一个新的文件夹,然后导入这个模型,导入的同时UE会帮我们创建一个材质。
这里的

这个mesh导入之后会同时导入四个材质球。

我们按住ctrl 或者 shift都可以实现多选,当我们想要移动的时候,按住shift进行一个移动,会使得相机和物体一起移动。
剩余的就是说了一下关于位置表示。
13、FVector 上
我们可以在detail panel中设置位置变换,同样我们在代码中也可以实现:

这样我们就可以实现,让物体在游戏运行的时候把位置重置到原点。
然后点开了FVector看了一波,这个FVector的第一个字母f是因为和计算有关系,f表示float,计算多是float。
14、FVector 中
这里我们尝试把设置的位置作为类的一个成员,然后成员在面板中是可以编辑的。

这里我们多加了一个宏的关键字。他的作用就是:EditInstanceOnly表示该属性可通过属性窗口来编辑,但仅能对实例而非原型进行编辑。
面板中剩余的东西就是这个对象的组件的属性,因为组件其实说白了就是组成该对象的成分,所以组件的属性就是该对象的属性。包括mesh 等等的全都是。

上边的InstanceOnly怎么体现的呢?其实我们在蓝图中是找不到这个值的,蓝图中如果有了,那就相当于对类本身的值进行修改了,而不是对每一个实例去编辑。
这里还有一个位置的设置,就是当我们把一个instance拽到视口中的时候,它放在哪里,这个位置我们可以给显示出来。

这里又用到了一个新的关键字,VisibleInstanceOnly : 表示该属性仅在实例的属性窗口中可见,但对原型则不行,并且无法被编辑。其实对于实例可见对于原型不可见这一点还有一个理解方式:就是每一个实例的该值是可以不一样的,原型你也没法显示。
然后这个位置我们只需要在游戏刚开始的时候获取赋值一下就行了,

我们只需要运行之后按shift + f1就可以把鼠标弄出来,然后用鼠标点击世界大纲中的这些instance,我们就可以看到他们被拽进去的位置。
接下来弄一个bool类型的变量,bool类型的需要在变量名前面加一个b,这个是虚幻的代码习惯,加上就得了。

这里新的关键词,EditDefaultsOnly,表示该属性可通过属性窗口来编辑,但仅能对原型编辑。

这时候虚幻把我们的bool类型b字母就给自动去掉了。
15、FVector 下

16、碰撞

这里的模型本身没有带简单碰撞,我们可以自己去为他添加:

点击后:

我们根据这个组件,是可以对碰撞的盒子进行一个编辑的,包括平移缩放旋转等。

也可以进行remove。还可以尝试其他各种各样的包围盒。

回到蓝图中,这里有一个物理模拟的开关,然后下面的Mass是质量,后面还有是否开启重力,如果关闭物理模拟,开启重力是没用的。
damping那俩是线速度阻尼和角速度阻尼。就是减慢平移速度和转动速度的。

场景中的这种图标没了按一下G就回来了,回来之后再按就消失了。
17、碰撞(续篇)

在蓝图中我们创建一个节点,创建之前,我们要在左边点一下选中这个:
才能搜索到该节点。因为他们需要static mesh,这样选中之后生成的节点会自动帮我们带出来一个static mesh。这个static mesh我们也可以选中上边的,然后拽进去也会出现。

我们把力的值设置好之后,我们编译会出现警告,我们一定要弄清楚原因,这里就是静态网格节点有限制,不可以在蓝图中使用。我们需要在cpp中消除这一点限制。

加上上边这个就好了,其实这就是cpp中限制了蓝图操作,而蓝图中硬操作出现的结果。

然后我们如果把椅子的物理模拟也加上,就会出现互相碰撞,椅子被撞翻了的情况:

然后我们可以查看这些物体的

这时候我们运行,然后shift+f1把鼠标显示出来,按一下键盘上的~键,就可以出现一个cmd:

然后我们输入show collision然后直接回车,就可以看到物体的碰撞检测的盒子了:

另外这里如果我们关闭重力:

就直接像太空人一样飘起来了,如上图的桌子。
18、扫除

这里的shape,各种的网格形状,如果我们把他们拽到视口中,那么实则是创建了一个带静态网格的Actor。

然后把立方体给缩放成一个墙,关闭物理模拟和力量的节点(需要在实例的面板和默认设置面板都给关了)。

然后勾选一下自动Float的,这时候我们去运行游戏,我们的盒子并不会和墙相撞,而是直接float穿过墙。直接穿透过去。
原因就是我们关闭了物理模拟。

然后回到我们的c++代码中,这里的第二个参数是是否sweep,而这个sweep就和我们的碰撞检测相关。
如果我们把刚刚的物理模拟关掉,然后把这里的sweep改成true,这样再运行就会发现盒子不能穿过墙了,

也就是sweep为true,会组织碰撞发生。

第三个参数是一个结构体,他里面有一个成员,首先这个结构体是一个hit result表示hit命中结果,然后这个成员的意思是:该命中结果是否是阻挡碰撞的结果。


这里还有一个成员,表示hit的location,这里他的类型是FVector的优化版本,我们可以把他当作FVector使用。

然后我们吧hitLocation给输出一下:

刚开始没有hit信息,也就是保持默认初始化的状态,全都是0,然后第一次碰撞发生之后就更新hitlocation。

对于每一个物体还有一个collision模块,

其中的设置还可以自定义,让我们有很大的自由度。

这里有一个Object Type,这个选项能够决定该对象和其他对象碰撞时的表现。同时她下面的勾选,是对于其他类物体的回应,可以忽略可以重叠,阻挡。

我们的floater,他的object 类型是world dynamic,然后我们修改一下墙的

变成自定义的,然后我们设置和world dynamic碰撞为overlap也就是重叠。这样我们运行之后就算sweep为true,但是这里设置的类型是overlap,他也会进行一个穿透了。当然在floater那里修改该physicsBody类型的选择也是一样可行的。
19、局部与世界偏移
把之前的每一帧平移给关掉,然后再beginplay的地方加上:

这里我们给我们的物体发生一些旋转,

然后通过上边的这个地方,我们就可以对物体身上的平移组件显示的轴进行一个切换,切换世界或者local轴。而我们旋转之后,世界轴和局部轴不再统一,这时候我们可以发现我们刚刚的offset是顺着局部轴进行的。因为他就叫 localoffset。
我们想要顺着世界的轴平移,那就可以换个函数。

我们出了平移还有旋转:

这里的三个参数表示的pitch yaw roll。
我们现在的形状不容易看出旋转效果,可以给他处理一下:

我们只需要添加一个新的static mesh组件,然后给他放上去我们的轴mesh。

现在就能明显看出旋转之后的效果了。可以看出pitch是抬头低头,yaw是左右扭头。roll是身体左右摇摆。
我们也可以把这个rotation操作放在每一帧中,也可以设置worldrotation。
20、力矩和扭矩
之前我们说过一个AddForce,也就是给物体加一个恒定方向和大小的力,那个带来的结果就是物体会发生平移,而这里有一个类似的力,就是让物体发生旋转的,扭矩。torque。

加上这两行,这里视频中出现了一些问题,他的VS不认识StaticMesh对应的类型,也就是缺了一个头文件,然后缺的什么头文件呢?

可以直接搜索这个名字,然后发现有这么一个头文件:

加上就好了,我这里并不需要这个头文件就可以跑起来,可能是版本问题吧~
运行之前需要开启物理模拟才会有效果。
另外一个小经验,就是在测试力这类东西的时候,因为大小可能需要随时调节,所以我们最好加个UPROPERTY,这样可以设置成面板那里直接手动调节了。不需要每次修改code,然后compile了。
类似的我们也在面板上设置一个torque的,


21、随机数值
这里主要是介绍关于虚幻里面的数学函数,有一个FMath,F开头是一个结构,然后他里面有很多的静态函数,我们可以::来直接调用,至于每一个函数的左右,我们可以通过函数名字和一些转到定义的手段来确定,并且可以多做做实验。
我们可以FMath::FRand来生成一个随机值,来作为initialLocation。

这里你会发现随机值永远是正数,我们想要负数可能还需要两个相减,但是我们还有一个RandRange,这个就可以自己指定范围了。
22、正弦函数
我们利用正弦函数来对物体的浮动方式进行一个控制。

正弦需要随着时间来进行一个计算,我们这里获取时间的方式就是利用每一帧的deltaTime,然后利用一个变量对这些deltaTime进行不断累加。

正弦函数返回值是-1到1的,如果我们想要实现上下的漂浮,那么我们只需要让我们的xy不变,然后z和sin函数一致进行周期性变化就好了。

这样球就可以实现浮动的效果了。我们可以修改正弦函数的系数,外面的系数可以影响上下浮动的最大幅度,里面加一个系数可以修改浮动的周期。当然也可以尝试最后面加一个上下平移。

我们这里可以把三角函数的三个参数给变成成员,然后暴露到蓝图中,这样可以直接在面板中进行一个修改。

这里我们在分类的时候分类一个子类,Wave Parameters,只需要在中间加一个 | 符号就可以实现。

另外注意,我们每次重现编译代码,都会让面板上的这些参数重置为构造函数中写的值。
改一下名字:A是Amplitude,表示波幅,B叫TimeStretch,表示波左右伸展。

当然它的作用不只是浮动,我们可以这么对xy使用,这样就可以画圆了。

我们回顾一下原来的式子,其实这个东西并不是表示的在初始z位置上-1到1的浮动,他是拿的上一次的z去和三角函数做加法,第一次z = 0,然后加了0.1,第二次z = 0.1,z加了0.2,这样第二次相加之后就等于0.3了,这也是为啥我们A=1的时候还能有那么大的幅度。
如果我们是只对最开始的时候的z值加上三角函数,A 等于1 的时候上下浮动基本上是看不出来的。但我们看具体的z值是可以看出确实在上下浮动的。

另外这里如果在UPROPERTY里面加上一个BlueprintReadOnly,我们再进行编译会报错,这个错误我们只需要把他们放在public下面就好了。

这里其实还有一个,就是加在sin()括号内部的值,这个影响并不大,知道就好了:

23、删除类
我们现在知道了如何为类添加组件,添加静态网格组件,
删除蓝图的话,直接按delete

然后所有的instance都会消失,但是对于cpp class直接delete是不行的,而且右键也不能删除。
具体方式:


把这俩文件删除就行了。但是还没完,还得删除一些文件,

这个给删除了。

然后右键项目文件,generate那一项。然后重新打开项目,会提示dll确实,点yes重新生成就好了。刚刚删除的Binaries会重新生成,这样我们的cpp类就删除干净了。
flaoter.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Floater.generated.h"
UCLASS()
class FIRSTPROJECT_API AFloater : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AFloater();
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "ActorMeshComponents")
UStaticMeshComponent* StaticMesh;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category = "Floater Variable")//实例信息可编辑
FVector InitialLocation;
UPROPERTY(VisibleInstanceOnly, BlueprintReadWrite, Category = "Floater Variable")//实例信息可见
FVector PlacedLocation;
UPROPERTY(VisibleDefaultsOnly, BlueprintReadOnly, Category = "Floater Variable")//原型可见
FVector WorldOrigin;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Floater Variable")//原型,实例均可编辑
FVector InitialDirection;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Floater Variable")//原型,实例均可编辑
bool bShouldFloat;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = "Floater Variable")//原型可编辑(默认设置下就是所说的原型)
bool bInitializeFloaterLocation;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category = "Floater Variable")
FVector InitialForce;
UPROPERTY(EditInstanceOnly, BlueprintReadWrite, Category = "Floater Variable")
FVector InitialTorque;
private:
float RuningTime;
public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Floater Variable | Wave Parameters")
float A;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Floater Variable | Wave Parameters")
float B;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Floater Variable | Wave Parameters")
float C;
float BaseZLocation;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
floater.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "Floater.h"
// Sets default values
AFloater::AFloater()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT(&#34;CustomStaticMesh&#34;));
InitialLocation = FVector(0.0f);
PlacedLocation = FVector(0.0f);
WorldOrigin = FVector(0.0f);
InitialDirection = FVector(0.0f);
bInitializeFloaterLocation = false;
bShouldFloat = false;
InitialForce = FVector(2000000.0f, 0.0f, 0.0f);
InitialTorque = FVector(2000000.0f, 0.0f, 0.0f);
RuningTime = 0.f;
A = 1.f;
B = 1.f;
C = 0.f;
}
// Called when the game starts or when spawned
void AFloater::BeginPlay()
{
Super::BeginPlay();
InitialLocation = FVector(FMath::FRandRange(-1000.f, 1000.f), FMath::FRandRange(-1000.f, 1000.f), FMath::FRandRange(-1000.f, 1000.f));
PlacedLocation = GetActorLocation();
if (bInitializeFloaterLocation) {
SetActorLocation(InitialLocation);
}
BaseZLocation = PlacedLocation.Z;
//StaticMesh->AddForce(InitialForce);
//StaticMesh->AddTorque(InitialTorque);
//FHitResult FHitResult;
//FVector LocationOffset = FVector(200.0f, 0.0f, 0.0f);
//AddActorWorldOffset(LocationOffset, true, &FHitResult);
//FRotator Rotation = FRotator(0.0f, 0.0f, 50.0f);
//AddActorLocalRotation(Rotation);
}
// Called every frame
void AFloater::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (bShouldFloat)
{
RuningTime += DeltaTime;
FVector NewLocation = GetActorLocation();
NewLocation.Z = BaseZLocation + A * FMath::Sin(B * RuningTime) + C;
SetActorLocation(NewLocation);
//FHitResult FHitResult;
//AddActorLocalOffset(InitialDirection, true, &FHitResult);
//FVector HitLocation = FHitResult.Location;
//UE_LOG(LogTemp, Warning, TEXT(&#34;Hit Location : X = %f, Y = %f, Z = %f&#34;), HitLocation.X, HitLocation.Y, HitLocation.Z);
}
//FRotator Rotation = FRotator(0.0f, 0.0f, 1.0f);
//AddActorWorldRotation(Rotation);
} |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|