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 }