UE4 從無到有純 C++ & Slate 開發沙盒游戲(十八) 添加玩家模型與相機


上一部分吧 GameMode 都綁定好了,現在把模型和相機放到 PlayerCharacter 上去

 

先做准備工作

如果我們寫C++文件想要看到實時的效果,需要在 Content 下加個 Blueprint 文件夾,其下再創建個 Temp 文件夾,這個Temp 中保存寫的一些藍圖,這些藍圖在項目完成以后是不需要的。

添加藍圖

 

 

由於我們是要一邊寫 PlayerCharacter 一邊看他的效果,所以我們要選擇創建一個繼承自 PlayerCharacter 的藍圖,命名為 PlayerCharacterBP

 

這樣便可以修改C++代碼的同時動態的看到其實時效果

D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\Player\SlAiPlayerCharacter.cpp

 1 #include "Player/SlAiPlayerCharacter.h"
 2 
 3 
 4 // Sets default values
 5 ASlAiPlayerCharacter::ASlAiPlayerCharacter()
 6 {
 7      // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 8     PrimaryActorTick.bCanEverTick = true;
 9 
10     /**
11      * 創建 Component(屬性)
12      * CreateDefaultSubobject<T>() 在構造函數中創建使用
13      * NewObject<T> 如果要在其他位置的代碼或者藍圖中創建,可以用 NewObject,用來創建 Uobject 類型
14      */
15 
16     /**
17     * 給默認 Mesh 添加骨骼模型
18     * 
19     * Uobject 資源加載
20     * ConstructorHelpers::FObjectFinder<T>只能在構造函數使用
21     * LoadObiect<T>可以在任何地方使用
22     * 
23     * 藍圖資源加載
24     * ConstructorHelpers::FClassFinder <T>只能在構造函數使用
25     * LoadClass<T>可以在任何地方加載
26     * 
27     * 全局加載資源函數
28     * StaticLoadObject、StaticLoadClass
29     * 應該是早期的LoadObiect<T>和LoadClass<T>的版本
30     */
31     static ConstructorHelpers::FObjectFinder<USkeletalMesh> StaticMeshThird(TEXT("SkeletalMesh'/Game/AssetsvilleTown/Meshes/Characters/SK_citizen_female_10.SK_citizen_female_10'"));
32     GetMesh()->SetSkeletalMesh(StaticMeshThird.Object);
33     GetMesh()->bOnlyOwnerSee = true;                              //如果該值為True,則該組件僅在視圖參與者是該組件的所有者時才可見。直接或間接。
34     GetMesh()->bReceivesDecals = false;                            //是否接收光線反射
35     GetMesh()->SetCollisionObjectType(ECC_Pawn);                //在骨架網格上設置碰撞對象類型
36     GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);                //我們的碰撞都會放到根組件的橢圓碰撞,這里設置無碰撞
37     GetMesh()->SetCollisionResponseToChannels(ECR_Ignore);                         //讓這個Mesh忽略所有的碰撞
38     GetMesh()->SetRelativeLocation(FVector(0.f, 0.f, -95.f));                         //設置位置
39     GetMesh()->SetRelativeRotation(FQuat::MakeFromEuler(FVector(0.f, 0.f, -90.f)));        //設置旋轉
40 }
41 
42 // Called when the game starts or when spawned
43 void ASlAiPlayerCharacter::BeginPlay()
44 {
45     Super::BeginPlay();
46 }
47 
48 // Called every frame
49 void ASlAiPlayerCharacter::Tick(float DeltaTime)
50 {
51     Super::Tick(DeltaTime);
52 }
53 
54 // Called to bind functionality to input
55 void ASlAiPlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
56 {
57     Super::SetupPlayerInputComponent(PlayerInputComponent);
58 }

 

可以看到第三人稱的模型已經放到了原點,擁有正的朝向和高度,碰撞屬性也都配置好了

 

下面是第一人稱的配置

d:\ue4 project\ue26.2\courseproject\slaicourse\Source\SlAiCourse\Public\Player\SlAiPlayerCharacter.h

 1 #include "CoreMinimal.h"
 2 #include "GameFramework/Character.h"
 3 #include "SlAiPlayerCharacter.generated.h"
 4 
 5 UCLASS()
 6 class SLAICOURSE_API ASlAiPlayerCharacter : public ACharacter
 7 {
 8     GENERATED_BODY()
 9 
10 public:
11     // Sets default values for this character's properties
12     ASlAiPlayerCharacter();
13 
14 protected:
15     // Called when the game starts or when spawned
16     virtual void BeginPlay() override;
17 
18 public:    
19     // Called every frame
20     virtual void Tick(float DeltaTime) override;
21 
22     // Called to bind functionality to input
23     virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
24 
25     //第一人稱的骨骼模型,VisibleDefaultsOnly 默認的,
26     UPROPERTY(VisibleDefaultsOnly, Category = "SlAi") 27         USkeletalMeshComponent* MeshFirst; 28 };

 

D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\Player\SlAiPlayerCharacter.cpp

 1 #include "Player/SlAiPlayerCharacter.h"
 2 
 3 
 4 // Sets default values
 5 ASlAiPlayerCharacter::ASlAiPlayerCharacter()
 6 {
 7      // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 8     PrimaryActorTick.bCanEverTick = true;
 9 
10     /**
11      * 創建 Component(屬性)
12      * CreateDefaultSubobject<T>() 在構造函數中創建使用
13      * NewObject<T> 如果要在其他位置的代碼或者藍圖中創建,可以用 NewObject,用來創建 Uobject 類型
14      * 
15      * 給默認 Mesh 添加骨骼模型
16      *
17      * Uobject 資源加載
18      * ConstructorHelpers::FObjectFinder<T>只能在構造函數使用
19      * LoadObiect<T>可以在任何地方使用
20      *
21      * 藍圖資源加載
22      * ConstructorHelpers::FClassFinder <T>只能在構造函數使用
23      * LoadClass<T>可以在任何地方加載
24      *
25      * 全局加載資源函數
26      * StaticLoadObject、StaticLoadClass
27      * 應該是早期的LoadObiect<T>和LoadClass<T>的版本
28      */
29 
30      //添加第一人稱骨骼模型
31     static ConstructorHelpers::FObjectFinder<USkeletalMesh> StaticMeshFirst(TEXT("SkeletalMesh'/Game/AssetsvilleTown/Meshes/Characters/SK_citizen_female_10.SK_citizen_female_10'")); 32     MeshFirst = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("MeshFirst"));          //實例化
33     MeshFirst->SetSkeletalMesh(StaticMeshFirst.Object);                                     //設置骨骼模型
34     MeshFirst->SetupAttachment((USceneComponent*)GetCapsuleComponent());                    //將Component添加到碰撞組件下
35     MeshFirst->bOnlyOwnerSee = true;                            //如果該值為True,則該組件僅在視圖參與者是該組件的所有者時才可見。直接或間接。 36     //MeshFirst->bCastDynamicShadow = false; //是否渲染模型影子(如果你用的是兩個手臂一樣的模型,那就 false 屏蔽掉),默認是顯示
37     MeshFirst->bReceivesDecals = false;                         //是否接收光線反射 38     //更新頻率衰落
39     MeshFirst->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::OnlyTickMontagesWhenNotRendered; 40     MeshFirst->PrimaryComponentTick.TickGroup = TG_PrePhysics; 41     //設置碰撞屬性
42     MeshFirst->SetCollisionObjectType(ECC_Pawn);                             //在骨架網格上設置碰撞對象類型
43     MeshFirst->SetCollisionEnabled(ECollisionEnabled::NoCollision);          //我們的碰撞都會放到根組件的橢圓碰撞,這里設置無碰撞
44     MeshFirst->SetCollisionResponseToAllChannels(ECR_Ignore);                //讓這個Mesh忽略所有的碰撞 45     //設置位移
46     MeshFirst->SetRelativeLocation(FVector(0.f, 0.f, -95.f));                        //設置位置
47     MeshFirst->SetRelativeRotation(FQuat::MakeFromEuler(FVector(0.f, 0.f, -90.f)));  //設置旋轉 48 
49     //添加第三人稱骨骼模型
50     static ConstructorHelpers::FObjectFinder<USkeletalMesh> StaticMeshThird(TEXT("SkeletalMesh'/Game/AssetsvilleTown/Meshes/Characters/SK_citizen_female_10.SK_citizen_female_10'"));
51     GetMesh()->SetSkeletalMesh(StaticMeshThird.Object);
52     GetMesh()->bOnlyOwnerSee = true;
53     GetMesh()->bReceivesDecals = false;
54     GetMesh()->SetCollisionObjectType(ECC_Pawn);
55     GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
56     GetMesh()->SetCollisionResponseToAllChannels(ECR_Ignore);
57     GetMesh()->SetRelativeLocation(FVector(0.f, 0.f, -95.f));
58     GetMesh()->SetRelativeRotation(FQuat::MakeFromEuler(FVector(0.f, 0.f, -90.f)));
59 }
60 
61 // Called when the game starts or when spawned
62 void ASlAiPlayerCharacter::BeginPlay()
63 {
64     Super::BeginPlay();
65 }
66 
67 // Called every frame
68 void ASlAiPlayerCharacter::Tick(float DeltaTime)
69 {
70     Super::Tick(DeltaTime);
71 }
72 
73 // Called to bind functionality to input
74 void ASlAiPlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
75 {
76     Super::SetupPlayerInputComponent(PlayerInputComponent);
77 }

 

添加攝像機

d:\ue4 project\ue26.2\courseproject\slaicourse\Source\SlAiCourse\Public\Player\SlAiPlayerCharacter.h

 1 #include "CoreMinimal.h"
 2 #include "GameFramework/Character.h"
 3 #include "SlAiPlayerCharacter.generated.h"
 4 
 5 UCLASS()
 6 class SLAICOURSE_API ASlAiPlayerCharacter : public ACharacter
 7 {
 8     GENERATED_BODY()
 9 
10 public:
11     // Sets default values for this character's properties
12     ASlAiPlayerCharacter();
13     
14     // Called every frame
15     virtual void Tick(float DeltaTime) override;
16 
17     // Called to bind functionality to input
18     virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
19 
20 public: 21     UPROPERTY(VisibleDefaultsOnly, Category = "SlAi") 22         class USpringArmComponent* CameraBoom;            //相當於一個攝像機的搖桿
23 
24     UPROPERTY(VisibleDefaultsOnly, Category = "SlAi") 25         class UCameraComponent* ThirdCamera;              //第三人稱攝像機組件
26     
27     UPROPERTY(VisibleDefaultsOnly, Category = "SlAi") 28         UCameraComponent* FirstCamera;                    //第一人稱攝像機組件
29 
30 protected:
31     // Called when the game starts or when spawned
32     virtual void BeginPlay() override;
33 
34 public:    
35     //第一人稱的骨骼模型,VisibleDefaultsOnly 默認的,
36     UPROPERTY(VisibleDefaultsOnly, Category = "SlAi")
37         USkeletalMeshComponent* MeshFirst;
38 };

 

 

D:\UE4 Project\UE26.2\CourseProject\SlAiCourse\Source\SlAiCourse\Private\Player\SlAiPlayerCharacter.cpp

  1 #include "Player/SlAiPlayerCharacter.h"
  2 #include "UObject/Object.h"
  3 #include "GameFramework/SpringArmComponent.h"
 4 #include "Camera/CameraComponent.h"
  5 
  6 
  7 // Sets default values
  8 ASlAiPlayerCharacter::ASlAiPlayerCharacter()
  9 {
 10      // Set this character to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
 11     PrimaryActorTick.bCanEverTick = true;
 12 
 13     /**
 14      * 創建 Component(屬性)
 15      * CreateDefaultSubobject<T>() 在構造函數中創建使用
 16      * NewObject<T> 如果要在其他位置的代碼或者藍圖中創建,可以用 NewObject,用來創建 Uobject 類型
 17      * 
 18      * 給默認 Mesh 添加骨骼模型
 19      *
 20      * Uobject 資源加載
 21      * ConstructorHelpers::FObjectFinder<T>只能在構造函數使用
 22      * LoadObiect<T>可以在任何地方使用
 23      *
 24      * 藍圖資源加載
 25      * ConstructorHelpers::FClassFinder <T>只能在構造函數使用
 26      * LoadClass<T>可以在任何地方加載
 27      *
 28      * 全局加載資源函數
 29      * StaticLoadObject、StaticLoadClass
 30      * 應該是早期的LoadObiect<T>和LoadClass<T>的版本
 31      */
 32 
 33      //添加第一人稱骨骼模型
 34     static ConstructorHelpers::FObjectFinder<USkeletalMesh> StaticMeshFirst(TEXT("SkeletalMesh'/Game/AssetsvilleTown/Meshes/Characters/SK_citizen_female_10.SK_citizen_female_10'"));
 35     MeshFirst = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("MeshFirst"));            //實例化
 36     MeshFirst->SetSkeletalMesh(StaticMeshFirst.Object);                                                        //設置骨骼模型
 37     MeshFirst->SetupAttachment((USceneComponent*)GetCapsuleComponent());                    //將Component添加到碰撞組件下
 38     MeshFirst->bOnlyOwnerSee = true;                                //如果該值為True,則該組件僅在視圖參與者是該組件的所有者時才可見。直接或間接。
 39     //MeshFirst->bCastDynamicShadow = false;                    //是否渲染模型影子(如果你用的是兩個手臂一樣的模型,那就 false 屏蔽掉),默認是顯示
 40     MeshFirst->bReceivesDecals = false;                            //是否接收光線反射
 41     //更新頻率衰落
 42     MeshFirst->MeshComponentUpdateFlag = EMeshComponentUpdateFlag::OnlyTickMontagesWhenNotRendered;
 43     MeshFirst->PrimaryComponentTick.TickGroup = TG_PrePhysics;
 44     //設置碰撞屬性
 45     MeshFirst->SetCollisionObjectType(ECC_Pawn);                                     //在骨架網格上設置碰撞對象類型
 46     MeshFirst->SetCollisionEnabled(ECollisionEnabled::NoCollision);             //我們的碰撞都會放到根組件的橢圓碰撞,這里設置無碰撞
 47     MeshFirst->SetCollisionResponseToAllChannels(ECR_Ignore);                //讓這個Mesh忽略所有的碰撞
 48     //設置位移
 49     MeshFirst->SetRelativeLocation(FVector(0.f, 0.f, -95.f));                        //設置位置
 50     MeshFirst->SetRelativeRotation(FQuat::MakeFromEuler(FVector(0.f, 0.f, -90.f)));        //設置旋轉
 51 
 52     //添加第三人稱骨骼模型
 53     static ConstructorHelpers::FObjectFinder<USkeletalMesh> StaticMeshThird(TEXT("SkeletalMesh'/Game/AssetsvilleTown/Meshes/Characters/SK_citizen_female_10.SK_citizen_female_10'"));
 54     GetMesh()->SetSkeletalMesh(StaticMeshThird.Object);
 55     GetMesh()->bOnlyOwnerSee = true;
 56     GetMesh()->bReceivesDecals = false;
 57     GetMesh()->SetCollisionObjectType(ECC_Pawn);
 58     GetMesh()->SetCollisionEnabled(ECollisionEnabled::NoCollision);
 59     GetMesh()->SetCollisionResponseToAllChannels(ECR_Ignore);
 60     GetMesh()->SetRelativeLocation(FVector(0.f, 0.f, -95.f));
 61     GetMesh()->SetRelativeRotation(FQuat::MakeFromEuler(FVector(0.f, 0.f, -90.f)));
 62 
 63     //攝像機手臂
 64     CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));  65     CameraBoom->SetupAttachment(RootComponent);  66     //設置距離
 67     CameraBoom->TargetArmLength = 300.f;  68     //設置偏移
 69     CameraBoom->TargetOffset = FVector(0.f, 0.f, 60.f);  70     //綁定 Controller 的旋轉
 71     CameraBoom->bUsePawnControlRotation = true;  72 
 73     //初始化第三人稱攝像機
 74     ThirdCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("ThirdCamera"));  75     ThirdCamera->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);  76     //設置 ThirdCamera 不跟隨控制器的旋轉
 77     ThirdCamera->bUsePawnControlRotation = false;  78 
 79     //初始化第一人稱攝像機
 80     FirstCamera = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstCamera"));  81     FirstCamera->SetupAttachment((USceneComponent*)GetCapsuleComponent());  82     //設置跟隨 Controller 的旋轉
 83     FirstCamera->bUsePawnControlRotation = true;  84 
 85     //位置偏移
 86     FirstCamera->AddLocalOffset(FVector(0.f, 0.f, 60.f));  87 }
 88 
 89 // Called when the game starts or when spawned
 90 void ASlAiPlayerCharacter::BeginPlay()
 91 {
 92     Super::BeginPlay();
 93 }
 94 
 95 // Called every frame
 96 void ASlAiPlayerCharacter::Tick(float DeltaTime)
 97 {
 98     Super::Tick(DeltaTime);
 99 }
100 
101 // Called to bind functionality to input
102 void ASlAiPlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
103 {
104     Super::SetupPlayerInputComponent(PlayerInputComponent);
105 }

 

添加完畢

 


免責聲明!

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



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