Fork me on GitHub

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 }

 

添加完毕

 

posted @ 2021-09-17 13:55  索智源  阅读(741)  评论(0编辑  收藏  举报