虚幻4 ue4 学习笔记pwan篇 1.3D 添加玩家方向控制 通过BindAxis控制前后左右

时间:2020-12-16 20:35:06
 1 // Fill out your copyright notice in the Description page of Project Settings.
2
3 #pragma once
4
5 #include "CoreMinimal.h"
6 #include "GameFramework/Pawn.h"
7 #include "MyPawn.generated.h"
8 UCLASS()
9 class TEST4_API AMyPawn : public APawn
10 {
11 GENERATED_BODY()
12
13 public:
14 // Sets default values for this pawn's properties
15 AMyPawn();
16
17 protected:
18 // Called when the game starts or when spawned
19 virtual void BeginPlay() override;
20
21 public:
22 // Called every frame
23 virtual void Tick(float DeltaTime) override;
24
25 // Called to bind functionality to input
26 virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
27 void fire();
28 void left(float AxisValue);//左右移动
29 void front(float AxisValue);//前后移动
30
31 UParticleSystemComponent* OurParticleSystem;
32 private:
33 int32 coutFire = 0;//计数器 禁止外部对象和子对象访问
34 float RunningTime = 0.0f;
35
36 };

cpp主体部分

  1 // Fill out your copyright notice in the Description page of Project Settings.
2
3 #include "MyPawn.h"
4 #include "Runtime/Engine/Classes/Components/BoxComponent.h"
5 #include "Runtime/Engine/Classes/Components/SphereComponent.h"// USphereComponent 引用
6 #include "Runtime/CoreUObject/Public/UObject/ConstructorHelpers.h" // ConstructorHelpers 引用
7 #include "Runtime/Engine/Classes/Particles/ParticleSystemComponent.h"//UParticleSystemComponent 引用
8 #include "Runtime/Engine/Classes/GameFramework/SpringArmComponent.h"//UStaticMeshComponent 引用
9 #include "Runtime/Engine/Classes/Camera/CameraComponent.h"//UCameraComponent 引用
10 #include "string"
11 using namespace std;
12 // Sets default values
13 AMyPawn::AMyPawn()
14 {
15 // Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
16 PrimaryActorTick.bCanEverTick = true;
17 AutoPossessPlayer = EAutoReceiveInput::Player0;//这行代码不加 无法实现用户操作 此时用户视角就是当前pawn视角
18
19 USphereComponent * SphereComponent = CreateDefaultSubobject<USphereComponent>("RootComponent");
20 RootComponent = SphereComponent;//这里不一定非要用物体组件
21
22
23
24 // 创建静态网格物体
25 UStaticMeshComponent * SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>("VisualRepresentation");
26 SphereVisual->SetupAttachment(RootComponent);
27
28 //打开素材库
29 static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAssetWzh(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
30 if (SphereVisualAssetWzh.Succeeded()) {
31 SphereVisual->SetStaticMesh(SphereVisualAssetWzh.Object);
32 SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));//设置位置0,0,0为初始位置
33 SphereVisual->SetWorldScale3D(FVector(0.8f));//SetWorldScale3D 设置组件在世界空间中的变换倍数。 倍数以原来模型大小为基准
34 }
35
36 // 创建一个可启用或停用的粒子系统
37 OurParticleSystem = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("MovementParticles"));
38 OurParticleSystem->SetupAttachment(RootComponent);//直接将粒子系统添加到根组件上
39 OurParticleSystem->bAutoActivate = false;//在场景中激活
40
41 OurParticleSystem->SetRelativeLocation(FVector(-20.0f, 0.0f, 20.0f));
42 OurParticleSystem->SetWorldScale3D(FVector(3.0f));//SetWorldScale3D 设置组件在世界空间中的变换倍数。 倍数以原来模型大小为基准
43 static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire"));
44 if (ParticleAsset.Succeeded())
45 {
46 OurParticleSystem->SetTemplate(ParticleAsset.Object);
47 }
48
49
50 //加入个摄像头让视角看起来舒服点 当然不加也是可以看到
51 UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("ActualCamera"));
52 Camera->SetupAttachment(RootComponent);
53 Camera->SetRelativeLocation(FVector(-250.f, 0.0f, 400));//设置位置0,0,0为初始位置
54 Camera->RelativeRotation = FRotator(-45.f, 0.f, 0.f);// y z x顺序旋转 一个旋转信息的容器 所有旋转值都以度数存储。
55 }
56
57 // Called when the game starts or when spawned
58 void AMyPawn::BeginPlay()
59 {
60 Super::BeginPlay();
61
62
63 }
64
65 // Called every frame
66 void AMyPawn::Tick(float DeltaTime)//没两帧之间的时间间隔
67 {
68 Super::Tick(DeltaTime);
69
70 /* string print = " DeltaTime = " + to_string(DeltaTime);
71 FString print2(print.c_str());
72
73 if (GEngine)
74 {
75 GEngine->AddOnScreenDebugMessage(-1, 1, FColor::Red, print2);
76 }
77
78 FVector NewLocation = GetActorLocation();//得到当前位置
79 float DeltaHeight = FMath::Sin(RunningTime);
80 NewLocation.Z += DeltaHeight;
81 RunningTime += DeltaTime;
82 RootComponent->SetRelativeLocation(NewLocation);//设置位置0,0,0为初始位置*/
83 //this->SetActorLocation(NewLocation);//官方使用的是这行代码来移动位置的 同上行代码
84
85
86 }
87
88 // Called to bind functionality to input
89 void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
90 {
91 Super::SetupPlayerInputComponent(PlayerInputComponent);
92 PlayerInputComponent->BindAction("fire", IE_Released, this, &AMyPawn::fire);
93 InputComponent->BindAxis("left", this, &AMyPawn::left);
94 InputComponent->BindAxis("front", this, &AMyPawn::front);
95 }
96
97
98 void AMyPawn::fire() {
99 coutFire = !coutFire;
100 if (GEngine)
101 {
102 GEngine->AddOnScreenDebugMessage(-1, 0.2, FColor::Red, TEXT("火焰!"));
103
104 int32 active32 = OurParticleSystem->bIsActive;
105 //OurParticleSystem->ToggleActive(); //官方使用的ToggleActive()切换粒子状态 我建议不要使用这个函数 因为
106 //在快速按下键盘按键 调用事件函数fire时 无法执行里面的ToggleActive函数 但是可以打印文字“火焰“ 但是慢慢按就没问题
107 //我发现主要是 ToggleActive内部操作 bIsActive的问题 如果快速按下 bIsActive 就不会重新赋值 而是一直为1估计是虚幻4官方的bug, 慢慢按 才为0 我自己重新 定义一个外部变量coutFire 计数代替bIsActive 就没问题了不用ToggleActive实现
108 OurParticleSystem->SetActive(coutFire);//通过计数器 切换状态
109 }
110
111 }
112
113 void AMyPawn::left(float AxisValue) {
114 FVector NewLocation = GetActorLocation();//得到当前位置
115 if (AxisValue == 1) {
116 if (GEngine)GEngine->AddOnScreenDebugMessage(-1, 0.2, FColor::Red, TEXT("向左!"));
117 NewLocation.Y -= 1.0;
118
119
120 }
121 else if (AxisValue == -1) {
122 if (GEngine)GEngine->AddOnScreenDebugMessage(-1, 0.2, FColor::Red, TEXT("向右!"));
123 NewLocation.Y += 1.0;
124 }
125
126 RootComponent->SetRelativeLocation(NewLocation);//设置位置0,0,0为初始位置*/
127 //this->SetActorLocation(NewLocation);//官方使用的是这行代码来移动位置的 同上行代码
128 }
129
130 void AMyPawn::front(float AxisValue) {
131 FVector NewLocation = GetActorLocation();//得到当前位置
132 if (AxisValue == 1) {
133 if (GEngine)GEngine->AddOnScreenDebugMessage(-1, 0.2, FColor::Red, TEXT("向前!"));
134 NewLocation.X += 1.0;
135
136 }
137 else if (AxisValue == -1) {
138 if (GEngine)GEngine->AddOnScreenDebugMessage(-1, 0.2, FColor::Red, TEXT("向后!"));
139 NewLocation.X -= 1.0;
140 }
141 RootComponent->SetRelativeLocation(NewLocation);//设置位置0,0,0为初始位置*/
142 //this->SetActorLocation(NewLocation);//官方使用的是这行代码来移动位置的 同上行代码
143 }