查看: 342|回复: 11

[编程指南] 【3. Coding our Pawn Movement Component's behavior | Unreal Engine】

[复制链接]

1

主题

273

帖子

7万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
73036
发表于 2016-6-27 00:54:10 | 显示全部楼层 |阅读模式



Previous Step
Next Step



   
Programming Tutorials Home


We can go back to Visual Studio now and program our customized Pawn Movement Component. All we really need to write is a TickComponent function (similar to an Actor's Tick function) to tell us how to move each frame. In CollidingPawnMovementComponent.h, we'll need to override TickComponent in the class definition:

public:    virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;  
We'll define this function in CollidingPawnMovementComponent.cpp:

void UCollidingPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction){    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);    // Make sure that everything is still valid, and that we are allowed to move.    if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))    {
return;    }    // Get (and then clear) the movement vector that we set in ACollidingPawn::Tick    FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f;    if (!DesiredMovementThisFrame.IsNearlyZero())    {
FHitResult Hit;
SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent-GetComponentRotation(), true, Hit);
// If we bumped into something, try to slide along it
if (Hit.IsValidBlockingHit())
{
     SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
}    }};
This code will move our Pawn smoothly around the world, sliding off of surfaces where appropriate. There is no gravity applied to our Pawn, and its maximum speed is hard-coded to 150 Unreal Units per second.


This TickComponent function makes use of a few of the powerful features offered by the UPawnMovementComponent class.

ConsumeInputVector reports and clears the value of a built-in variable that we will use to store our movement inputs.

SafeMoveUpdatedComponent uses Unreal Engine physics to move our Pawn Movement Component while respecting solid barriers.

SlideAlongSurface handles the calculations and physics involved with sliding smoothly along collision surfaces like walls and ramps when a move results in a collision, rather than simply stopping in place and "sticking" to the wall or ramp.

There are more features included in Pawn Movement Components that are worthy of examination, but they are not needed for the scope of this tutorial. Looking at other classes, such as Floating Pawn Movement, Spectator Pawn Movement, or Character Movement Component, could provide additional usage examples and ideas.



With our Pawn Movement Component's behavior defined, we can now write the code that will tie it all together in our customized Pawn class.


Work-In-Progress Code


CollidingPawn.h

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.#pragma once#include "GameFramework/Pawn.h"#include "CollidingPawn.generated.h"UCLASS()class HOWTO_COMPONENTS_API ACollidingPawn : public APawn{    GENERATED_BODY()public:    // Sets default values for this pawn's properties    ACollidingPawn();    // Called when the game starts or when spawned    virtual void BeginPlay() override;    // Called every frame    virtual void Tick( float DeltaSeconds ) override;    // Called to bind functionality to input    virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;    UParticleSystemComponent* OurParticleSystem;};
CollidingPawn.cpp

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.#include "HowTo_Components.h"#include "CollidingPawn.h"// Sets default valuesACollidingPawn::ACollidingPawn(){    // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.    PrimaryActorTick.bCanEverTick = true;    // Our root component will be a sphere that reacts to physics    USphereComponent* SphereComponent = CreateDefaultSubobjectUSphereComponent(TEXT("RootComponent"));    RootComponent = SphereComponent;    SphereComponent-InitSphereRadius(40.0f);    SphereComponent-SetCollisionProfileName(TEXT("Pawn"));    // Create and position a mesh component so we can see where our sphere is    UStaticMeshComponent* SphereVisual = CreateDefaultSubobjectUStaticMeshComponent(TEXT("VisualRepresentation"));    SphereVisual-AttachTo(RootComponent);    static ConstructorHelpers::FObjectFinderUStaticMesh SphereVisualAsset(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));    if (SphereVisualAsset.Succeeded())    {
SphereVisual-SetStaticMesh(SphereVisualAsset.Object);
SphereVisual-SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));
SphereVisual-SetWorldScale3D(FVector(0.8f));    }    // Create a particle system that we can activate or deactivate    OurParticleSystem = CreateDefaultSubobjectUParticleSystemComponent(TEXT("MovementParticles"));    OurParticleSystem-AttachTo(SphereVisual);    OurParticleSystem-bAutoActivate = false;    OurParticleSystem-SetRelativeLocation(FVector(-20.0f, 0.0f, 20.0f));    static ConstructorHelpers::FObjectFinderUParticleSystem ParticleAsset(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire"));    if (ParticleAsset.Succeeded())    {
OurParticleSystem-SetTemplate(ParticleAsset.Object);    }    // Use a spring arm to give the camera smooth, natural-feeling motion.    USpringArmComponent* SpringArm = CreateDefaultSubobjectUSpringArmComponent(TEXT("CameraAttachmentArm"));    SpringArm-AttachTo(RootComponent);    SpringArm-RelativeRotation = FRotator(-45.f, 0.f, 0.f);    SpringArm-TargetArmLength = 400.0f;    SpringArm-bEnableCameraLag = true;    SpringArm-CameraLagSpeed = 3.0f;    // Create a camera and attach to our spring arm    UCameraComponent* Camera = CreateDefaultSubobjectUCameraComponent(TEXT("ActualCamera"));    Camera-AttachTo(SpringArm, USpringArmComponent::SocketName);    // Take control of the default player    AutoPossessPlayer = EAutoReceiveInput::Player0;}// Called when the game starts or when spawnedvoid ACollidingPawn::BeginPlay(){    Super::BeginPlay();}// Called every framevoid ACollidingPawn::Tick( float DeltaTime ){    Super::Tick( DeltaTime );}// Called to bind functionality to inputvoid ACollidingPawn::SetupPlayerInputComponent(class UInputComponent* InputComponent){    Super::SetupPlayerInputComponent(InputComponent);}
CollidingPawnMovementComponent.h

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.#pragma once#include "GameFramework/PawnMovementComponent.h"#include "CollidingPawnMovementComponent.generated.h"/** *  */UCLASS()class HOWTO_COMPONENTS_API UCollidingPawnMovementComponent : public UPawnMovementComponent{    GENERATED_BODY()public:    virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;  };
CollidingPawnMovementComponent.cpp

// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.#include "HowTo_Components.h"#include "CollidingPawnMovementComponent.h"void UCollidingPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction){    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);    // Make sure that everything is still valid, and that we are allowed to move.    if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))    {
return;    }    // Get (and then clear) the movement vector that we set in ACollidingPawn::Tick    FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f;    if (!DesiredMovementThisFrame.IsNearlyZero())    {
FHitResult Hit;
SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent-GetComponentRotation(), true, Hit);
// If we bumped into something, try to slide along it
if (Hit.IsValidBlockingHit())
{
     SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
}    }};


   
Previous Step
Next Step



   
Programming Tutorials Home
回复

使用道具 举报

0

主题

836

帖子

2754

积分

vip会员

Rank: 1

积分
2754
发表于 2016-7-2 19:35:08 来自手机 | 显示全部楼层
不错的资源啊,可以研究研究
回复 支持 反对

使用道具 举报

0

主题

875

帖子

2859

积分

vip会员

Rank: 1

积分
2859
发表于 2016-7-3 23:50:21 | 显示全部楼层
谢谢支持。
回复 支持 反对

使用道具 举报

0

主题

896

帖子

2958

积分

vip会员

Rank: 1

积分
2958
发表于 2016-7-4 11:31:18 | 显示全部楼层
超cool。。。喜欢,下载来看看。。
回复 支持 反对

使用道具 举报

0

主题

904

帖子

2986

积分

vip会员

Rank: 1

积分
2986
发表于 2016-7-9 20:57:20 来自手机 | 显示全部楼层
谢谢版主分享,现在又看到它了,我就不能放弃,
回复 支持 反对

使用道具 举报

0

主题

916

帖子

2989

积分

vip会员

Rank: 1

积分
2989
发表于 2016-7-11 09:45:19 | 显示全部楼层
收下了~~感谢~
回复 支持 反对

使用道具 举报

0

主题

892

帖子

2936

积分

vip会员

Rank: 1

积分
2936
发表于 2016-7-15 15:17:38 | 显示全部楼层
秒了 秒了  秒了  这东西 秒了
回复 支持 反对

使用道具 举报

0

主题

934

帖子

3017

积分

vip会员

Rank: 1

积分
3017
发表于 2016-7-17 05:38:31 来自手机 | 显示全部楼层
这个支持了呀,不错,顶顶帖拿拿钱
回复 支持 反对

使用道具 举报

0

主题

874

帖子

2897

积分

vip会员

Rank: 1

积分
2897
发表于 2016-7-18 10:57:42 | 显示全部楼层
回复看看!!!!!!!!!楼主辛苦
回复 支持 反对

使用道具 举报

0

主题

878

帖子

2886

积分

vip会员

Rank: 1

积分
2886
发表于 2016-7-20 05:18:06 | 显示全部楼层
好资源,谢谢
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | enginedx注册

本版积分规则

 
 



邮件留言:


 
返回顶部