虛幻4 ue4 學習筆記pwan篇 1.4 pawn結合UPawnMovementComponent類 移動組件實現 移動球體添加物理碰撞


MyPawn.h部分

 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 MoveForward(float AxisValue);
29     void MoveRight(float AxisValue);
30 
31     class UMyPawnMovementComponent* OurMovementComponent;
32 
33     virtual UPawnMovementComponent* GetMovementComponent() const override;
34     /*
35         1.引入同一項目類請加入 class
36         2.如果補加入頭文件 只能引入同一項目引用 而不能確定繼承關系
37 
38     */
39     UParticleSystemComponent* OurParticleSystem;
40 private:
41     int32 coutFire = 0;//計數器 禁止外部對象和子對象訪問
42     float RunningTime = 0.0f;
43 
44 };

MyPawn.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 "MyPawnMovementComponent.h"
 11 #include "string"
 12 using namespace std;
 13 // Sets default values
 14 AMyPawn::AMyPawn()
 15 {
 16      // Set this pawn to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 17     PrimaryActorTick.bCanEverTick = true;
 18     AutoPossessPlayer = EAutoReceiveInput::Player0;//這行代碼不加 無法實現用戶操作 此時用戶視角就是當前pawn視角
 19 
 20     USphereComponent * SphereComponent = CreateDefaultSubobject<USphereComponent>("RootComponent");
 21     RootComponent = SphereComponent;//這里不一定非要用物體組件
 22     
 23 
 24     
 25 //    創建靜態網格物體
 26     UStaticMeshComponent * SphereVisual = CreateDefaultSubobject<UStaticMeshComponent>("VisualRepresentation");
 27     SphereVisual->SetupAttachment(RootComponent);
 28     SphereComponent->InitSphereRadius(40.f);// 實際物理 碰撞半徑
 29     SphereComponent->SetCollisionProfileName(TEXT("Pawn"));//碰撞設置 設置這個方法才可以實現物理碰撞 這里的名稱必須為Pawn
 30     //SetCollisionProfileName需要刪除之前虛幻4場景中的pawn物體然后再重新加入才能實現物理碰撞
 31     FName sComProName = SphereComponent->GetCollisionProfileName();// 得到 碰撞設置的名稱
 32     
 33     //打開素材庫
 34     static ConstructorHelpers::FObjectFinder<UStaticMesh> SphereVisualAssetWzh(TEXT("/Game/StarterContent/Shapes/Shape_Sphere.Shape_Sphere"));
 35     if (SphereVisualAssetWzh.Succeeded()) {
 36         SphereVisual->SetStaticMesh(SphereVisualAssetWzh.Object);
 37         SphereVisual->SetRelativeLocation(FVector(0.0f, 0.0f, -40.0f));//設置位置0,0,0為初始位置                                               
 38         SphereVisual->SetWorldScale3D(FVector(0.8f));//SetWorldScale3D 設置組件在世界空間中的變換倍數。 倍數以原來模型大小為基准
 39     }
 40 
 41     // 創建一個可啟用或停用的粒子系統
 42     OurParticleSystem = CreateDefaultSubobject<UParticleSystemComponent>(TEXT("MovementParticles"));
 43     OurParticleSystem->SetupAttachment(RootComponent);//直接將粒子系統添加到根組件上
 44     OurParticleSystem->bAutoActivate = false;//在場景中激活
 45 
 46     OurParticleSystem->SetRelativeLocation(FVector(-20.0f, 0.0f, 20.0f));
 47     OurParticleSystem->SetWorldScale3D(FVector(3.0f));//SetWorldScale3D 設置組件在世界空間中的變換倍數。 倍數以原來模型大小為基准
 48     static ConstructorHelpers::FObjectFinder<UParticleSystem> ParticleAsset(TEXT("/Game/StarterContent/Particles/P_Fire.P_Fire"));
 49     if (ParticleAsset.Succeeded())
 50     {
 51         OurParticleSystem->SetTemplate(ParticleAsset.Object);
 52     }
 53 
 54 
 55     //加入個攝像頭讓視角看起來舒服點 當然不加也是可以看到 
 56     UCameraComponent* Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("ActualCamera"));
 57     Camera->SetupAttachment(RootComponent);
 58     Camera->SetRelativeLocation(FVector(-250.f, 0.0f, 400));//設置位置0,0,0為初始位置    
 59     Camera->RelativeRotation = FRotator(-45.f, 0.f, 0.f);// y z x順序旋轉  一個旋轉信息的容器 所有旋轉值都以度數存儲。
 60 
 61     // 創建移動組件的一個實例,並告知其更新根組件。
 62     //<UMyPawnMovementComponent>為自定義移動組件類
 63     OurMovementComponent = CreateDefaultSubobject<UMyPawnMovementComponent>(TEXT("CustomMovementComponent"));//創建自定義移動組件類 如果沒有這行代碼無法實現物理碰撞無法使用自定義移動類移動球體
 64     OurMovementComponent->UpdatedComponent = RootComponent;//這行代碼不加也可以
 65 
 66 }
 67 
 68 // Called when the game starts or when spawned
 69 void AMyPawn::BeginPlay()
 70 {
 71     Super::BeginPlay();
 72 
 73     
 74 }
 75 
 76 // Called every frame
 77 void AMyPawn::Tick(float DeltaTime)//沒兩幀之間的時間間隔
 78 {
 79     Super::Tick(DeltaTime);    
 80 
 81 
 82 }
 83 
 84 // Called to bind functionality to input
 85 void AMyPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
 86 {
 87     Super::SetupPlayerInputComponent(PlayerInputComponent);
 88     PlayerInputComponent->BindAction("fire", IE_Released, this, &AMyPawn::fire);
 89     InputComponent->BindAxis("MoveRight", this, &AMyPawn::MoveRight);
 90     InputComponent->BindAxis("MoveForward", this, &AMyPawn::MoveForward);
 91 }
 92 
 93 UPawnMovementComponent*  AMyPawn::GetMovementComponent() const//得到移動組件
 94 {
 95     return OurMovementComponent;
 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::MoveForward(float AxisValue)//移動前進
114 {
115 
116 
117     if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
118     {
119         if (GEngine)
120         {
121             // TEXT只能接受字符串常量
122 
123             FVector xyz1 = GetActorForwardVector();
124             string str = to_string(xyz1.X) + " , " + to_string(xyz1.Y) + " , " + to_string(xyz1.Z) + " AxisValue = " + to_string(AxisValue);
125             FString fstr = FString(str.c_str());
126             //按下s鍵AxisValue為-1 w鍵AxisValue為1
127             GEngine->AddOnScreenDebugMessage(-1, 0.5, FColor::Yellow, fstr);
128         }
129 
130         //AddInputVector 設置每次移動的方向和距離 輸入值 0.0 - 1.0之前
131 
132         //GetActorForwardVector()得到當前視角永遠向前的值 通過計算sin和鼠標轉動的大小實現 就算視角變換也永遠向前 
133         //x大小就是當前sin大小 默認是1/2π 90度等於1 取值范圍-1 -- 1, y z永遠為0
134 
135         //AxisValue ue4里按鍵綁定的值 設置輸入的向量值移動的大小
136 
137         OurMovementComponent->AddInputVector(GetActorForwardVector() * AxisValue);//AxisValue ue4里按鍵綁定的值 設置輸入的向量值移動的大小  不按下時為0
138 
139         if (GEngine)
140         {
141             // TEXT只能接受字符串常量
142             FVector xyz2 = OurMovementComponent->GetInputVector();//注意這里不是 GetActorForwardVector()
143 
144             string str2 = to_string(xyz2.X) + " , " + to_string(xyz2.Y) + " , " + to_string(xyz2.Z) + " AxisValue = " + to_string(AxisValue) + " Speed = " + to_string(OurMovementComponent->GetMaxSpeed());
145             FString fstr2 = FString(str2.c_str());
146             GEngine->AddOnScreenDebugMessage(-1, 0.5, FColor::Red, fstr2);
147 
148         }
149 
150     }
151 }
152 
153 void AMyPawn::MoveRight(float AxisValue)//移動向右
154 {
155     if (OurMovementComponent && (OurMovementComponent->UpdatedComponent == RootComponent))
156     {
157         OurMovementComponent->AddInputVector(GetActorRightVector() * AxisValue);
158     }
159 }

 

MyPawnMovementComponent.h部分

 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/PawnMovementComponent.h"
 7 #include "MyPawnMovementComponent.generated.h"
 8 
 9 /**
10  * 
11  */
12 UCLASS()
13 class TEST4_API UMyPawnMovementComponent : public UPawnMovementComponent
14 {
15     GENERATED_BODY()
16     
17 public:
18     virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
19 
20     
21     
22 };

 

MyPawnMovementComponent.cpp部分

 1 // Fill out your copyright notice in the Description page of Project Settings.
 2 
 3 #include "MyPawnMovementComponent.h"
 4 void UMyPawnMovementComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction)
 5 {
 6     Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
 7 
 8     // 確保所有內容仍然有效,並允許移動。
 9     if (!PawnOwner || !UpdatedComponent || ShouldSkipUpdate(DeltaTime))
10     {
11         return;
12     }
13 
14     // 獲取(然后清除)在 ACollidingPawn::Tick 設置的移動矢量。
15     FVector DesiredMovementThisFrame = ConsumeInputVector().GetClampedToMaxSize(1.0f) * DeltaTime * 150.0f;
16     if (!DesiredMovementThisFrame.IsNearlyZero())
17     {
18         FHitResult Hit;
19         SafeMoveUpdatedComponent(DesiredMovementThisFrame, UpdatedComponent->GetComponentRotation(), true, Hit);
20 
21         // 如碰到物體,嘗試沿其滑動
22         if (Hit.IsValidBlockingHit())
23         {
24             SlideAlongSurface(DesiredMovementThisFrame, 1.f - Hit.Time, Hit.Normal, Hit);
25         }
26     }
27 };

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM