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 UParticleSystemComponent* OurParticleSystem; 29 private: 30 int32 coutFire = 0;//计数器 禁止外部对象和子对象访问 31 float RunningTime = 0.0f; 32 33 };
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 94 } 95 96 97 void AMyPawn::fire() { 98 coutFire = !coutFire; 99 if (GEngine) 100 { 101 GEngine->AddOnScreenDebugMessage(-1, 0.2, FColor::Red, TEXT("火焰!")); 102 103 int32 active32 = OurParticleSystem->bIsActive; 104 //OurParticleSystem->ToggleActive(); //官方使用的ToggleActive()切换粒子状态 我建议不要使用这个函数 因为 105 //在快速按下键盘按键 调用事件函数fire时 无法执行里面的ToggleActive函数 但是可以打印文字“火焰“ 但是慢慢按就没问题 106 //我发现主要是 ToggleActive内部操作 bIsActive的问题 如果快速按下 bIsActive 就不会重新赋值 而是一直为1估计是虚幻4官方的bug, 慢慢按 才为0 我自己重新 定义一个外部变量coutFire 计数代替bIsActive 就没问题了不用ToggleActive实现 107 OurParticleSystem->SetActive(coutFire);//通过计数器 切换状态 108 } 109 110 }