赞
踩
虚幻引擎需要类始终保持前缀
在Character刚被加载的时候首先调用
如果它被执行,那么它已经被完全加载,完全初始化,这是我们可以信赖的第一件事。
每一帧都会被调用,也传递了一个delta时间访问
UCameraComponent
USpringArmComponent
CreateDefaultSubobject<CLASSNAME>(“TABNAME”)
其中CLASSNAME是实例的类型,TABNAME是它在编辑器中显示的名字
数据视图很难读懂正在发生的事情
蓝图读起来比较快
弹簧臂 SetupAttachment(RootComponent)
RootComponent是层次结构中的第一个组件
相机 SetupAttachment(弹簧臂)
相机安装在弹簧臂上
因为我们想要角色和相机之间有一定的距离
UPROPERTY,UFUNCTION,UCLASS,USTRUCT,UENUM(Unreal Macros 虚幻宏)
标记C++类,用于像编辑这样的事情,蓝图访问,甚至对于网络行为。
定义你的代码应该在哪里运行,服务器还是在本地客户机上。
而且也是为了内存管理,将会用于追踪指针和一个对象的内存,
比如
UProperty(VisibleAnywhere) //它将在任何地方可见
void AMainCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
// 加两个输入事件控制相机
// 轴运算
PlayerInputComponent -> BindAxis("LookRight", this,&AMainCharacter::AddControllerYawInput);
PlayerInputComponent -> BindAxis("LookForward", this,&AMainCharacter::AddControllerPitchInput);
}
我们其实有两个选择,BindAction和BindAxis
在目前我们对绑定轴感兴趣,因为希望能够移动前进和倒退。
我们可以联想一下,输入设备是GamePad的情况,拇指杆滑动,会在-1到1的区间里变化。
在输入设备是键盘的情况下,它仅仅是按下Key和松开Key的问题(0,1 二值)。
BindAxis 参数 (名称,接收输入对象,想要触发的函数)
触发委托之后,会把名称传递给接收输入对象,传递一个需要被触发的函数
Character已经封装了一些函数,
我们只需要说出往哪个方向走
目前只需要前后左右四个方向,就可以用函数直接获取。
再传递一个value 是一个-1到1的值
AddMovementInput(GetActorForwardVector(),value);
打开编辑器的项目设置,输入,绑定
直接使用Pawn中提供的函数即可
APawn::AddControllerYawInput
在VS2019 IDE中 可以直接Ctrl+鼠标左键,跳转到对应函数,查看源码。
虚幻引擎的一个问题是,它有800万行的代码,检索代码是很慢的
此处包含pitch、yaw、roll等知识点
Yaw 指的是水平旋转,pitch 指的是垂直旋转,roll 未知
打开PlayerCharacter蓝图
左上角会有
CapsuleComponent
ArrowComponent
Mesh
SpringArmComp (前面写的C++基类里的)
CameraComp (前面写的C++基类里的)
CharacterMovement
从detail页签可以随意修改模型引用路径
可以在Transform里修改位置和朝向
在Animation 选择Anim Class 动画蓝图或者动画C++基类
动画的意义:看一下自己角色的状态(比如:移动速度有多快,哪个方向,是不是在做攻击之类的事情)并且融合各种姿势和动画,合成一个最终的姿势。
Idle Pos 闲置状态。
git里面 可以看到修改了哪些文件,改动了哪些行
.uproject 文件 其实就是很像Json格式的明文字符串。
下面是我打开了自己的一个项目的.uproject文件
{ "FileVersion": 3, "EngineAssociation": "{*******-****-****-****-*******}", "Category": "", "Description": "", "Modules": [ { "Name": "UE5Build", "Type": "Runtime", "LoadingPhase": "Default", "AdditionalDependencies": [ "Engine" ] } ], "Plugins": [ { "Name": "ModelingToolsEditorMode", "Enabled": true, "TargetAllowList": [ "Editor" ] } ] }
很多外部生成的内容,和我们自己绑定的输入。
/Config/
/Content/
/Source/
/.gitignore
/**.uproject
/README.md
.sln文件 会被.uproject编译的时候生成。
GIT分析语言组成:C# 66.6% C++ 28.5% C 4.9%
C#主要是UBT和UHT自动生成的配置文件,占用较大。
C++是UObject类逻辑的主要实现地方,比C大一些。
C是UObject类的声明,不负责实现,占用最小。
每个Player都有一个PlayerController
一旦他加入游戏,就会被分配到一个框架
而且他会持有这个PlayerController直到他离开游戏或者地图被加载。
这里PlayerController可能会控制一个Pawn,这个Pawn会死,也会重生,也会看到其他人死掉的Pawn。
AI也是使用相似的类,AIController从Controller中驱动。
在PlayerCharacter蓝图中,勾选Pawn页签中的Use Controller Rotation
把这个勾选去掉的话,移动鼠标旋转相机的同时,人物朝向不会再随着相机(实际上是关联的控制器)旋转了。
再打开PlayerCharacter蓝图中的SpringComp,勾选CameraSettings页签中的Use Pawn Control Rotation
把这个勾选去掉的话,移动鼠标旋转的同时,相机不会再随着关联的控制器旋转了。
这里的做法是为了可以让角色有机会看向相机,比如Dark Soul和Final Fantasy的运动机制。
CharacterMovement的参数是十分庞大的,我们现在想把旋转定位到运动上,用最上方的快速搜索栏,搜索orient,找到Orient Rotation To Movement(定向旋转)
这是一个小技巧,想要找CharaterMovement中是否存在这样的变量,就在蓝图中搜索吧,之后再去C++代码里编写修改这个值的地方。
编码规范,bool类型的变量前面要加b字母
GetCharacterMovement()->bOrientRotationToMovement = True;
这将使我们的Character旋转,我们目前正朝着什么方向移动。
而不是只能向正面直直的移动,我们有侧面的移动。
这时候Character的CPP报错了,因为我们在调用CharacterMovement类的函数,却没有对CharacterMovement的声明。
#include "GameFramework/CharacterMovementComponent.h"
目前的效果是按下D会原地旋转,按下W会直直的向前走。
对于前进的步伐,我们实际上想要的不是Pawn当前的方向,而是要向摄像机的方向移动。
UE5默认的镜头方式其实是射击类游戏喜欢用的视角。
现在我们要做的是类似黑魂、只狼、最终幻想之类的游戏。
我们现在可以得到Controller的旋转,
FRotator ControlRot = GetControlRotation();
AddMovementInput
函数期望的是一个矢量,而不是一个旋转器(Rotator),但是我们可以非常容易地来回转换,在向量和Rotator之间转换,
AddMovementInput(ControlRot.Vector(),value);
因为我们只对yaw感兴趣,yaw是水平旋转,我们不关心俯仰(pitch roll)的问题,
ControlRot.Pitch = 0.0f;
ControlRot.Roll = 0.0f;
左右旋转不正常
Find Symbol工具
搜索rightVector,查询所有带这个词的函数
搜到 UKismetMathLibrary.GetRightVector
很多时候我们知道一个函数在蓝图里叫什么,但是不知道它在C++里叫什么,一些BOOL值可以通过命名规范推算出来,
Kismet的意思是蓝图(BluePrint) 在UE3中的老人都是这么说的,当提到Kismet在引擎代码或者其他地方,它意味着蓝图数学库。
FVector RightVector = FRotationMatrix(ControlRot).GetScaledAxis(EAxis::Y);
EAxis::Y 就是枚举类型命名空间的常量Y的值
Play的右边下拉菜单,找到高级设置,Play in Editor页签的第一个Game Gets Mouse Control
Editor preference -> General -> Loading & Saving
Startup页签下有加载级别的设置,设置为last opened
USphereComponent 是碰撞组件,这是最基本的
UProjectileMovementComponent 投射物运动组件,给定一个速度,它就会直直的移动
UParticleSystemComponent 粒子系统组件,让我们有东西可以展示出来
EffectComp->SetupAttachment(SphereComp);
选择父类,魔法投射物C++类
需要传递创建实例的类型,transform参数(是一个结构体,在比例尺中保存一个位置和旋转),生成参数结构体。
GetWorld()->SpawnActor<AActor>(ProjectileClass, SpawnTM, SpawnParams);
FTransform SpawnTM = FTransform(GetControlRotation(), GetActorLocation());
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = FSpawnActorCollisionHandlingMethod::AlwaysSpawn;
生成碰撞的覆盖处理,当物体在世界上产生的时候,将会检查它的碰撞,可以移动一些位置,让出现的时候不要和任何东西重叠。
UPROPERTY(EditAnyWhere)
TSubClassOf<AActor> ProjectileClass;
EditAnyWhere:在编辑器中可编辑
VisibleAnyWhere:在编辑器中可看
打开PlayerCharacter蓝图就能看到了,直接在里面编辑。
FVector HandLocation = GetMesh()->GetSocketLocation("Muzzle_01"); // 骨骼名
// 通过新的位置产生Transform结构体
FTransform SpawnTM = FTransform(GetControlRotation(), HandLocation);
UE4的骨骼树中,灰色的名字是Socket插槽,白色的名字是普通的骨头。
重力设置为0
打开魔法投射物蓝图,选中MovementComp
打开细节面板 找到Projectile页签下的 Projectile Gravity Scale 改为0
打开魔法投射物蓝图,选中球体组件
打开细节面板 找到Collision页签
Visible :AI能否看到你
Camera: 相机能否穿过组件
碰撞条件会发生在两个物体相互之间最小的层级。
比如你认为可以碰撞对方,但是对方认为不能碰撞你,那么就不会碰撞上。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。