技术标签: UE4 UE4 Possess UE4 Jump UE4 Crouch UE4 Movement
原创内容,转载请注明出处。
创建一个基于Character的蓝图,可以看到左侧可以覆盖一些方法,针对这些方法在代码层面做一个介绍。
如下图,写这篇文章的目的其实希望大家知道引擎原生提供的一些方法,能够更快的写逻辑。
防止各位同仁自造轮子。
本文只介绍Character的事件,Actor的事件在上篇文章中讲过了。UE4 Actor事件接口详解
是否可跳跃,跳跃之前的条件判断
检查角色是否可以在当前状态下跳跃。跳跃之前的一些你的逻辑判断。
描述:是否可以跳跃?
源码:其实由上面的源码可以看出,由BlueprintCallable所修饰的CanJump虚方法其实调用的就是由
BlueprintNativeEvent所修饰的CanJumpInternal(), CanJumpInternal()这个方法蓝图可以重载实现,
当蓝图中重载了之后C++ 的CanJumpInternal()将不再会调用。
C++默认的CanJumpInternal_Implementation()(默认这个方法的实现体会有些条件判断,
比如不是蹲着的时候返回true,蹲着的时候是不允许跳跃的;判断跳跃是否超过了最大跳跃限制次数,比如二段跳);
如果是你的C++想重载的话,请重载CanJump()逻辑,而不是CanJumpInternal()。
返回值:bool:是否可以在当前状态跳转
当触发一次跳跃,执行逻辑依次为
1>CanJump? 我可以跳吗?
2>CanJump? 我可以跳吗?
3>OnJump 跳起来了
4>OnLanded 我落地了
如果蓝图中直接实现了CanJump, return true的话,Character上面的JumpMaxCount(最大限制跳跃次数)将失去效果,需要自己增加这部分的逻辑。如果你发现你的二段跳功能失效了,怀疑是不是这里的问题,或者搜索JumpMaxCount也能找到原因。
事件在角色刚开始跳跃时触发,当你触发跳跃的一瞬间,就会调用这个函数
在C++中调用
在蓝图中重写OnJump
事件在角色刚开始跳跃落地时触发,当你接触Floor的一瞬间,就会调用这个函数。 参数是当时落地的坐标的一些参数,比如有具体的位置,落地时候地表的物理材质等信息。
在C++中你想重载写一些逻辑的话,重载virtual void Landed(const FHitResult& Hit);
在蓝图中你想重载写一些逻辑的话,直接实现OnLanded(const FHitResult& Hit)即可。
发射角色,和Jump有点像,这个是会给一个力。应用到就像CF里面生化模式跳到某个传送门一下跳老高的那种效果。我觉得就是为FPS游戏设计的该功能
我在场景中放了一个传送门,很丑,用了个火的粒子。
当角色与这个TriigerBox发生Overlap时候,会将角色弹射起来,给角色一个向上的力。就像CF里面那种效果。下面是在关卡蓝图里面的实现。
回到蓝图中的OnLaunched方法介绍上
UFUNCTION(BlueprintImplementableEvent)
void OnLaunched(FVector LaunchVelocity, bool bXYOverride, bool bZOverride)
其实这个方法触发的时候,就是角色被调用了LaunchCharacter,之后会调用CharacterMovement->Launch(FinalVel),
然后调用让蓝图知道一下这个角色被发射了。
触发现象是当你的walk切换到fall,比如从高处掉下的时候会调用。
我认为可以做一些从步行->跌倒的功能。
官方解释不包括跳跃或其他可能导致运动模式中发生相同过渡的事物。
下面是Character.h中的相关代码
/**
* Event fired when the Character is walking off a surface and is about to fall because CharacterMovement->CurrentFloor became unwalkable.
* If CharacterMovement->MovementMode does not change during this event then the character will automatically start falling afterwards.
* @note Z velocity is zero during walking movement, and will be here as well. Another velocity can be computed here if desired and will be used when starting to fall.
*
* @param PreviousFloorImpactNormal Normal of the previous walkable floor.
* @param PreviousFloorContactNormal Normal of the contact with the previous walkable floor.
* @param PreviousLocation Previous character location before movement off the ledge.
* @param TimeTick Time delta of movement update resulting in moving off the ledge.
*/
UFUNCTION(BlueprintNativeEvent, Category=Character)
void OnWalkingOffLedge(const FVector& PreviousFloorImpactNormal, const FVector& PreviousFloorContactNormal, const FVector& PreviousLocation, float TimeDelta);
virtual void OnWalkingOffLedge_Implementation(const FVector& PreviousFloorImpactNormal, const FVector& PreviousFloorContactNormal, const FVector& PreviousLocation, float TimeDelta);
想要角色开始蹲下, 需要满足下面条件
1>需要将UCharacterMovementComponent里面的NavAgentProps参数中bCanCrouch设置为true
2>需要调用Crouch进入蹲下状态,相反的是调用UnCrouch退出蹲下状态
角色蹲下后走到边坡不能进入自由落体,怎么解决?
1>将UCharacterMovementComponent对象的bCanWalkOffLedgesWhenCrouching设置为true
下面是CharacterMovementComponent.h中关于蹲下的相关参数声明(请看具体的注释理解)
//蹲下时候的最大移动速度,也就是说蹲下后走的慢了。没错符合物理真实,这很UE4。
UPROPERTY(Category="Character Movement: Walking", EditAnywhere, BlueprintReadWrite, meta=(ClampMin="0", UIMin="0"))
float MaxWalkSpeedCrouched;
//蹲下时候角色的Capsule的高度
UPROPERTY(Category="Character Movement (General Settings)", EditAnywhere, BlueprintReadOnly, meta=(ClampMin="0", UIMin="0"))
float CrouchedHalfHeight;
//这个比较有意思,默认为false。如果false的话走到边坡你会发现没法掉下去。当为true的时候就能掉下去了。
//并且也会触发On Walking Off Ledge
UPROPERTY(Category="Character Movement: Walking", EditAnywhere, BlueprintReadWrite)
uint8 bCanWalkOffLedgesWhenCrouching:1;
下面是Character.h中关于蹲下的相关函数声明
//调用该方法让 蹲下
UFUNCTION(BlueprintCallable, Category=Character, meta=(HidePin="bClientSimulation"))
virtual void Crouch(bool bClientSimulation = false);
//调用该方法让角色 停止蹲下
UFUNCTION(BlueprintCallable, Category=Character, meta=(HidePin="bClientSimulation"))
virtual void UnCrouch(bool bClientSimulation = false);
//可以蹲下吗?
UFUNCTION(BlueprintCallable, Category=Character)
virtual bool CanCrouch() const;
//当角起身的时候调用 调用了UnCrouch之后
virtual void OnEndCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust);
//蓝图版本的OnEndCrouch
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName="OnEndCrouch", ScriptName="OnEndCrouch"))
void K2_OnEndCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust);
//角色蹲下的时候调用, 调用了Crouch之后
virtual void OnStartCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust);
//蓝图版本的OnStartCrouch
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName="OnStartCrouch", ScriptName="OnStartCrouch"))
void K2_OnStartCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust);
这个比较好理解,Character上CharacterMovement中的变量
UPROPERTY(Category=“Character Movement: MovementMode”, BlueprintReadOnly)
TEnumAsByte MovementMode;
也就是说当这个枚举发生变化的时候会有个通知
下面是C++的代码部分
//MovementMode改变
//参数:PrevMovementMode 更改之前是啥模式
//参数:PreviousCustomMode 更改之前的自定义模式是啥。注意是自定义模式。比如绝地求生的climbing攀爬模式
virtual void OnMovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode = 0);
//MovementMode改变的时候广播这个多播代理
UPROPERTY(BlueprintAssignable, Category=Character)
FMovementModeChangedSignature MovementModeChangedDelegate;
//蓝图中用的,就是在上面的OnMovementModeChanged中调用的。
//参数:PrevMovementMode 更改之前是啥模式
//参数:NewMovementMode 新的模式
//参数:PrevCustomMode 更改之前的自定义模式是啥。注意是自定义模式
//参数:NewCustomMode 更改之后的自定义模式是啥模式。比如绝地求生的climbing攀爬模式
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName="OnMovementModeChanged", ScriptName="OnMovementModeChanged"))
void K2_OnMovementModeChanged(EMovementMode PrevMovementMode, EMovementMode NewMovementMode, uint8 PrevCustomMode, uint8 NewCustomMode);
Controller和Pawn其实是一个相互持有的关系,比如有想切换操控的角色的功能,可以用这个实现。
那么应该怎么去实现切换角色的功能呢?
1>调用Controller->Possess(传一个Pawn的对象即可完成切换角色的功能)
2>不建议调用角色身上的PossessedBy, 可能会遇到一些问题,因为Controller的部分逻辑没有被执行到。
3>往往切换角色功能会伴随着要spawn一个新的character逻辑,然后再将这个新spawn出来的character进行Controller->Possess(新spawn的character),再将老的character进行Destroy();
Character继承自Pawn,下面Pawn.h的代码
//当Controller调用Possess的时候呢,会调用到这个方法
virtual void PossessedBy(AController* NewController);
//在ReceivePossessed中调用的,目的是为了通知蓝图
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName= "Possessed"))
void ReceivePossessed(AController* NewController);
/** Event called when the Pawn is no longer possessed by a Controller. */
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName= "Unpossessed"))
void ReceiveUnpossessed(AController* OldController);
//当Controller调用UnPossess的时候调用Pawn的UnPossessed
virtual void UnPossessed();
下面是Controller.h的代码, 可以看到下面俩方法都已经是final,不允许在进行重写了。
/**
* Handles attaching this controller to the specified pawn.
* Only runs on the network authority (where HasAuthority() returns true).
* @param InPawn The Pawn to be possessed.
* @see HasAuthority()
*/
UFUNCTION(BlueprintCallable, BlueprintAuthorityOnly, Category=Pawn, meta=(Keywords="set controller"))
virtual void Possess(APawn* InPawn) final; // DEPRECATED(4.22, "Posssess is marked virtual final as you should now be overriding OnPossess instead")
/** Called to unpossess our pawn for any reason that is not the pawn being destroyed (destruction handled by PawnDestroyed()). */
UFUNCTION(BlueprintCallable, Category=Pawn, meta=(Keywords="set controller"))
virtual void UnPossess() final; // DEPRECATED(4.22, "Posssess is marked virtual final as you should now be overriding OnUnPossess instead")
和上面的Possessed相反
比如此时我有个需求,不想控制这个角色了,怎么办?
1 >关闭角色的Input, DisableInput(Controller和Character身上都有,调用一次)
2>来个狠的,直接调用Unpossessed.
这个函数是当MovementMode设置成Custom的时候,这个方法会调用。下面是堆栈信息。这个是通过UCharacterMovementComponent::PhysCustom()过来的
相对应的UCharacterMovementComponent中还有PhysWalking/PhysNavWalking/PhysFlying/PhysSwimming/还有PhysCustom等几个方法。这个里面可以重载了实现自定义模式下的逻辑。
下面是Character.h中对这个方法的定义
/**
* Event for implementing custom character movement mode. Called by CharacterMovement if MovementMode is set to Custom.
* @note C++ code should override UCharacterMovementComponent::PhysCustom() instead.
* @see UCharacterMovementComponent::PhysCustom()
*/
UFUNCTION(BlueprintImplementableEvent, meta=(DisplayName="UpdateCustomMovement", ScriptName="UpdateCustomMovement"))
void K2_UpdateCustomMovement(float DeltaTime);
下面是一个关于K2_UpdateCustomMovement调用的一个堆栈信息
谢谢!创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 (๑◕ܫ←๑)
文章浏览阅读1.1k次。一、选择题1. 串行接口是指( )。A. 接口与系统总线之间串行传送,接口与I/0设备之间串行传送B. 接口与系统总线之间串行传送,接口与1/0设备之间并行传送C. 接口与系统总线之间并行传送,接口与I/0设备之间串行传送D. 接口与系统总线之间并行传送,接口与I/0设备之间并行传送【答案】C2. 最容易造成很多小碎片的可变分区分配算法是( )。A. 首次适应算法B. 最佳适应算法..._874 计算机科学专业基础综合题型
文章浏览阅读9.7k次,点赞5次,收藏15次。连接xshell失败,报错如下图,怎么解决呢。1、通过ps -e|grep ssh命令判断是否安装ssh服务2、如果只有客户端安装了,服务器没有安装,则需要安装ssh服务器,命令:apt-get install openssh-server3、安装成功之后,启动ssh服务,命令:/etc/init.d/ssh start4、通过ps -e|grep ssh命令再次判断是否正确启动..._could not connect to '192.168.17.128' (port 22): connection failed.
文章浏览阅读209次。00000000_杰理 空白芯片 烧入key文件
文章浏览阅读475次。2023年初,“ChatGPT”一词在社交媒体上引起了热议,人们纷纷探讨它的本质和对社会的影响。就连央视新闻也对此进行了报道。作为新传专业的前沿人士,我们当然不能忽视这一热点。本文将全面解析ChatGPT,打开“技术黑箱”,探讨它对新闻与传播领域的影响。_引发对chatgpt兴趣的表述
文章浏览阅读259次。用Python数据分析方法进行汉字声调频率统计分析木合塔尔·沙地克;布合力齐姑丽·瓦斯力【期刊名称】《电脑知识与技术》【年(卷),期】2017(013)035【摘要】该文首先用Python程序,自动获取基本汉字字符集中的所有汉字,然后用汉字拼音转换工具pypinyin把所有汉字转换成拼音,最后根据所有汉字的拼音声调,统计并可视化拼音声调的占比.【总页数】2页(13-14)【关键词】数据分析;数据可..._汉字声调频率统计
文章浏览阅读64次。最近在做一个android系统移植的项目,所使用的开发板com1是调试串口,就是说会有uboot和kernel的调试信息打印在com1上(ttySAC0)。因为后期要使用ttySAC0作为上层应用通信串口,所以要把所有的调试信息都给去掉。参考网上的几篇文章,自己做了如下修改,终于把调试信息重定向到ttySAC1上了,在这做下记录。参考文章有:http://blog.csdn.net/longt..._嵌入式rootfs 输出重定向到/dev/console
文章浏览阅读1.2k次,点赞4次,收藏12次。1,先去iconfont登录,然后选择图标加入购物车 2,点击又上角车车添加进入项目我的项目中就会出现选择的图标 3,点击下载至本地,然后解压文件夹,然后切换到uniapp打开终端运行注:要保证自己电脑有安装node(没有安装node可以去官网下载Node.js 中文网)npm i -g iconfont-tools(mac用户失败的话在前面加个sudo,password就是自己的开机密码吧)4,终端切换到上面解压的文件夹里面,运行iconfont-tools 这些可以默认也可以自己命名(我是自己命名的_uniapp symbol图标
文章浏览阅读1.2w次,点赞25次,收藏192次。char*和char[]都是指针,指向第一个字符所在的地址,但char*是常量的指针,char[]是指针的常量_c++ char*
文章浏览阅读930次。代码编辑器或者文本编辑器,对于程序员来说,就像剑与战士一样,谁都想拥有一把可以随心驾驭且锋利无比的宝剑,而每一位程序员,同样会去追求最适合自己的强大、灵活的编辑器,相信你和我一样,都不会例外。我用过的编辑器不少,真不少~ 但却没有哪款让我特别心仪的,直到我遇到了 Sublime Text 2 !如果说“神器”是我能给予一款软件最高的评价,那么我很乐意为它封上这么一个称号。它小巧绿色且速度非
文章浏览阅读4.1k次。一、选择法这是每一个数出来跟后面所有的进行比较。2.冒泡排序法,是两个相邻的进行对比。_对十个数进行大小排序java
文章浏览阅读2.9k次。物联网开发笔记——使用网络调试助手连接阿里云物联网平台(基于MQTT协议)其实作者本意是使用4G模块来实现与阿里云物联网平台的连接过程,但是由于自己用的4G模块自身的限制,使得阿里云连接总是无法建立,已经联系客服返厂检修了,于是我在此使用网络调试助手来演示如何与阿里云物联网平台建立连接。一.准备工作1.MQTT协议说明文档(3.1.1版本)2.网络调试助手(可使用域名与服务器建立连接)PS:与阿里云建立连解释,最好使用域名来完成连接过程,而不是使用IP号。这里我跟阿里云的售后工程师咨询过,表示对应_网络调试助手连接阿里云连不上
文章浏览阅读544次,点赞5次,收藏6次。运算符与表达式任何高级程序设计语言中,表达式都是最基本的组成部分,可以说C++中的大部分语句都是由表达式构成的。_无c语言基础c++期末速成