看了一下终于发现了跳跃的关键代码

bool UCharacterMovementComponent::DoJump(bool bReplayingMoves)
{
if ( CharacterOwner && CharacterOwner->CanJump() )
{
// Don't jump if we can't move up/down.
if (!bConstrainToPlane || FMath::Abs(PlaneConstraintNormal.Z) != .f)
{
Velocity.Z = JumpZVelocity;
SetMovementMode(MOVE_Falling);
return true;
}
} return false;
}

这里跳跃就和JumpZVelocity联系在一起了,同时运动状态改成了Falling(我认为这里设置Falling是不对的,因为在空中有上升还有下落两个状态),不过MovementComponent有判断停止下落的函数,可以在状态机里直接用。

当然判断是否可以跳跃就是另一回事了,你也可以自己写一个跳跃函数。

首先是CharactorMovementComponent中的DoJump(),里面检测一下能不能跳跃,(即是否允许角色Z方向的移动,因为要兼容别的类型的游戏。
),之后在ACharacter中DoJump()中与CanJump()进行与运算,CanJump返回CanJumpInternal(),CanJumpInternal()是个事件,所以我们需要

去看CanJumpInternal_Implementation(),果然CanJumpInternal_Implementation是个虚函数,所以修改跳跃逻辑就修改这个函数就好了。

看一下CanJumpInternal_Implementation的逻辑

bool ACharacter::CanJumpInternal_Implementation() const
{
const bool bCanHoldToJumpHigher = (GetJumpMaxHoldTime() > 0.0f) && IsJumpProvidingForce(); return !bIsCrouched && CharacterMovement && (CharacterMovement->IsMovingOnGround() || bCanHoldToJumpHigher) && CharacterMovement->IsJumpAllowed() && !CharacterMovement->bWantsToCrouch;
}

!bIsCrouched角色的运行模式不能为蹲

CharacterMovement->IsMovingOnGround() 确定角色是否还处于走路状态

bCanHoldToJumpHigher的是判断当按下跳跃键的时候,是否还能到达最高点

CharacterMovement->IsJumpAllowed() 角色运动组件是否可以跳

!CharacterMovement->bWantsToCrouch不能正在做下蹲动作

另外补充一下相关代码

float UCharacterMovementComponent::GetMaxJumpHeight() const
{
const float Gravity = GetGravityZ();
if (FMath::Abs(Gravity) > KINDA_SMALL_NUMBER)
{
return FMath::Square(JumpZVelocity) / (-.f * Gravity);
}
else
{
return .f;
}
}

一个重力下落公式

void UCharacterMovementComponent::JumpOff(AActor* MovementBaseActor)
{
if ( !bPerformingJumpOff )
{
bPerformingJumpOff = true;
if ( CharacterOwner )
{
const float MaxSpeed = GetMaxSpeed() * 0.85f;
Velocity += MaxSpeed * GetBestDirectionOffActor(MovementBaseActor);
if ( Velocity.Size2D() > MaxSpeed )
{
Velocity = MaxSpeed * Velocity.GetSafeNormal();
}
Velocity.Z = JumpOffJumpZFactor * JumpZVelocity;
SetMovementMode(MOVE_Falling);
}
bPerformingJumpOff = false;
}
}

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

如何实现:

首先在你的角色类的头文件中加入

virtual bool CanJumpInternal_Implementation() const override;

覆盖CanJumpInternal事件。

之后在Cpp文件中加入

bool AThirdPersonCharacter::CanJumpInternal_Implementation() const
{
const bool bCanHoldToJumpHigher = (GetJumpMaxHoldTime() > 0.0f) && IsJumpProvidingForce(); //return !bIsCrouched && CharacterMovement && (CharacterMovement->IsMovingOnGround() || bCanHoldToJumpHigher) && CharacterMovement->IsJumpAllowed() && !CharacterMovement->bWantsToCrouch;
  
return !bIsCrouched && CharacterMovement && CharacterMovement->IsJumpAllowed() && !CharacterMovement->bWantsToCrouch;
}

我把(CharacterMovement->IsMovingOnGround() || bCanHoldToJumpHigher)删掉了,这里就替换上你的二段跳逻辑即可

在头文件中加入2个用于判断二段跳的变量

//最大跳跃次数
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Jump")
int32 MaxJumpNum = ; //当前跳跃次数
int32 JumpNum=2;

当然把JumNum在构造函数中赋值才是正确选择

覆盖事件

    //virtual void OnMovementModeChanged(EMovementMode PrevMovementMode, uint8 PreviousCustomMode = 0) override;

    virtual void Landed(const FHitResult& Hit) override;

2个都可以用,第一个功能更加强大

然后在Cpp文件里:

void AThirdPersonCharacter::Jump()
{
if (JumpNum>)
{
bPressedJump = true;
JumpKeyHoldTime = 0.0f;
JumpNum = JumpNum - ;
}
} void AThirdPersonCharacter::Landed(const FHitResult& Hit)
{
Super::Landed(Hit);
JumpNum = MaxJumpNum;
}

当然之前的按键事件绑定也需要修改一下

void AThirdPersonCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
// Set up gameplay key bindings
check(InputComponent);
  //把这个Jump改为你自己刚才定义的Jump
InputComponent->BindAction("Jump", IE_Pressed, this, &AThirdPersonCharacter::Jump);
InputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping); InputComponent->BindAxis("MoveForward", this, &AThirdPersonCharacter::MoveForward);
InputComponent->BindAxis("MoveRight", this, &AThirdPersonCharacter::MoveRight); // We have 2 versions of the rotation bindings to handle different kinds of devices differently
// "turn" handles devices that provide an absolute delta, such as a mouse.
// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
InputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
InputComponent->BindAxis("TurnRate", this, &AThirdPersonCharacter::TurnAtRate);
InputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
InputComponent->BindAxis("LookUpRate", this, &AThirdPersonCharacter::LookUpAtRate); // handle touch devices
InputComponent->BindTouch(IE_Pressed, this, &AThirdPersonCharacter::TouchStarted);
InputComponent->BindTouch(IE_Released, this, &AThirdPersonCharacter::TouchStopped);
}

看Ue4角色代码——跳跃与实现二段跳的更多相关文章

  1. unity3D角色代码控制问题

    ///////////////2015/07/06//////// ///////////////by xbw////////////// //////////////环境 unity4.6.1// ...

  2. 从零开始一起学习SLAM | 理解图优化,一步步带你看懂g2o代码

    首发于公众号:计算机视觉life 旗下知识星球「从零开始学习SLAM」 这可能是最清晰讲解g2o代码框架的文章 理解图优化,一步步带你看懂g2o框架 小白:师兄师兄,最近我在看SLAM的优化算法,有种 ...

  3. 看图写代码---看图写代码 阅读<<Audio/Video Connectivity Solutions for Virtex-II Pro and Virtex-4 FPGAs >>

    看图写代码 阅读<<Audio/Video Connectivity Solutions for Virtex-II Pro and Virtex-4 FPGAs >> 1.S ...

  4. 【前端模板之路】一、重构的兄弟说:我才不想看你的代码!把HTML给我交出来!

    写在前面 随着前端领域的发展和社会化分工的需要,继前端攻城湿之后,又一重要岗位横空出世——重构攻城湿!所谓的重构攻城湿,他们的一大特点之一,就是精通CSS配置文件的编写...前端攻城湿跟重构攻城湿是一 ...

  5. (转)【前端模板之路】一、重构的兄弟说:我才不想看你的代码!把HTML给我交出来!

    原文地址:http://www.cnblogs.com/chyingp/archive/2013/06/30/front-end-tmplate-start.html 写在前面 随着前端领域的发展和社 ...

  6. 我的Android进阶之旅------>真正在公司看几天代码的感触

    仅以此文来回顾这一周我的工作情况,以及由此而触发的感想. ============================================================= 来到新公司5天了, ...

  7. php实现把数组排成最小的数(核心是排序)(看别人的代码其实也没那么难)(把php代码也看一下)(implode("",$numbers);)(usort)

    php实现把数组排成最小的数(核心是排序)(看别人的代码其实也没那么难)(把php代码也看一下)(implode("",$numbers);)(usort) 一.总结 核心是排序 ...

  8. 由阿里巴巴一道笔试题看Java静态代码块、静态函数、动态代码块、构造函数等的执行顺序

    一.阿里巴巴笔试题: public class Test { public static int k = 0; public static Test t1 = new Test("t1&qu ...

  9. 怎么看 EOS 的代码最爽?

    进入 EOS 的世界之前,愉快地看系统代码是第一步,试了 Visual Studio / Source Insight / Understand / Sublime 等多款 IDE / 编辑器后,强烈 ...

随机推荐

  1. ASP.NET SignalR 与 LayIM2.0 配合轻松实现Web聊天室(八) 之 用 Redis 实现用户在线离线状态消息处理

    前言 上篇的预告好像是“聊天室的小细节,你都注意到了吗?”.今天也是为那篇做铺垫吧.之前的版本有好多问题,比如:当前登录用户是否合法问题,userid参数如果随便传后台没有验证.还有一个致命的问题,用 ...

  2. Bootstrap学习(一)

    Bootstrap就是对jQuery的一次再开发,所以jQuery脚本引用必须在bootstrap脚本之前. 链接:http://www.cnblogs.com/vvjiang/p/5189804.h ...

  3. 警告 - no rule to process file 'WRP_CollectionView/README.md' of type net.daringfireball.markdown for architecture i386

    warning: no rule to process file '/Users/mac/Downloads/Demo/Self/WRP_CollectionView/WRP_CollectionVi ...

  4. NYOJ之三个数从小到大排序

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAsoAAAGvCAIAAADNJWRjAAAgAElEQVR4nO3dPXLqSrs24DMJcgbi1A

  5. 关于java中的异常问题 1

    1.首先参考一下关于java异常处理方面的知识 查看博客http://lavasoft.blog.51cto.com/62575/18920/ 这里介绍的很好,下面从中学习到一些东西,摘抄如下: 1. ...

  6. Java -- 访问控制

    原文:http://www.cnblogs.com/diyingyun/archive/2011/12/21/2295947.html 可见/访问性 在同一类中 同一包中 不同包中  同一包子类中  ...

  7. Android -- getQuantityString无效

    原文:http://www.xuebuyuan.com/1510993.html 原因:中文没有复数语法.

  8. 使用Delphi对象(声明、实例化、构造、释放)

    一.声明和实例化 在使用一个对象之前,用class关键字声明一个对象.可以在一个程序或单元的type部分声明一个对象类型: type TFooObject = class; 除了声明一个对象类型,通常 ...

  9. python生成RSS(PyRSS2Gen)

    既然能够用python解析rss,那么也顺带研究下生成rss. 其实很简单,只是生成一个比较特殊点的xml文档而已. 这里我使用了PyRss2Gen,用法很简单,看代码就知道了,如下: import ...

  10. java 存储对象

    一.存储区域: 1)寄存器.这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器根据需求进行分配.你不能直接控制,也不能在程序中感觉到寄存器存在的任何 ...