进入游戏
打开UE4,新建一个场景,现在开始实现场景的跳转
打开Res → PolygonAdventure → Maps
文件夹下新建一个Level,Demonstration_Large
然后将他拖到Map中,选择 copy 一份
然后将名字改为GameMap
如果没有场景文件,去淘宝买一套,淘宝搜UE4场景资源。很多的角色、场景、特效等东西。
进行场景跳转的功能我们要来到 SlAiMenuWidget.cpp 这里,在 MenuItemOnClicked() 方法下的 EnterGame 以及 EnterRecord下进行场景跳转。
D:UE4 ProjectUE26.2CourseProjectSlAiCourseSourceSlAiCoursePrivateUIWidgetSSlAiMenuWidget.cpp
1 #include "SlateOptMacros.h"
2 #include "Common/SlAiHelper.h"
3 #include "Data/SlAiDataHandle.h"
4 #include "Widgets/Layout/SBox.h" //一版会把SlateWidget的根组件设成SBox
5 #include "Widgets/Images/SImage.h"
6 #include "Widgets/Text/STextBlock.h"
7 #include "Widgets/SBoxPanel.h"
8 #include "UI/Style/SlAiStyle.h"
9 #include "UI/Style/SlAiMenuWidgetStyle.h"
10 #include "UI/Widget/SSlAiMenuWidget.h"
11 #include "UI/Widget/SSlAiGameOptionWidget.h"
12 #include "UI/Widget/SSlAiMenuItemWidget.h"
13 #include "UI/Widget/SSlAiNewGameWidget.h"
14 #include "UI/Widget/SSlAiChooseRecordWidget.h"
15 #include "Kismet/GameplayStatics.h"
16 #include "GamePlay/SlAiMenuController.h"
17
18
19 /**
20 * 每一个结构体对应一个菜单*/
21 struct MenuGroup
22 {
23 //菜单标题
24 FText MenuName;
25 //菜单高度
26 float MenuHeight;
27 //下属组件
28 TArray<TSharedPtr<SCompoundWidget>> ChildWidget;
29
30 //构造函数
31 MenuGroup(const FText Name, const float Height, TArray<TSharedPtr<SCompoundWidget>>* Children)
32 {
33 MenuName = Name;
34 MenuHeight = Height;
35 for (TArray<TSharedPtr<SCompoundWidget>>::TIterator It(*Children); It; It++)
36 {
37 ChildWidget.Add(*It);
38 }
39 }
40 };
41
42
43 BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
44 void SSlAiMenuWidget::Construct(const FArguments& InArgs)
45 {
46 //获取MenuStyle
47 MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle");
48
49 //转换为中文
50 //SlAiDataHandle::Get()->ChangeLocalizationCulture(ECultureTeam::ZH);
51
52 //播放背景音乐
53 FSlateApplication::Get().PlaySound(MenuStyle->MenuBackgroudMusic);
54
55 ChildSlot
56 [
57 /**
58 *没有Slot,没有Slot要么不能插入子组件,要么只能插入一个子组件,SizeBox 只能插入一个子组件
59 */
60 SAssignNew(RootSizeBox, SBox)
61 [
62 SNew(SOverlay)
63
64 +SOverlay::Slot() //主菜单背景
65 .HAlign(HAlign_Fill)
66 .VAlign(VAlign_Fill)
67 .Padding(FMargin(0.f, 50.f, 0.f, 0.f)) //FMargin 间隔(左 上 右 下)
68 [
69 SNew(SImage)
70 .Image(&MenuStyle->MenuBackgroundBrush)
71 ]
72
73 +SOverlay::Slot() //菜单左侧图片
74 .HAlign(HAlign_Left)
75 .VAlign(VAlign_Center)
76 .Padding(FMargin(0.f, 25.f, 0.f, 0.f))
77 [
78 SNew(SImage).Image(&MenuStyle->LeftIconBrush)
79 ]
80
81 +SOverlay::Slot() //菜单右侧图片
82 .HAlign(HAlign_Right)
83 .VAlign(VAlign_Center)
84 .Padding(FMargin(0.f, 25.f, 0.f, 0.f))
85 [
86 SNew(SImage).Image(&MenuStyle->RightIconBrush)
87 ]
88
89 +SOverlay::Slot() //菜单标题图片
90 .HAlign(HAlign_Center)
91 .VAlign(VAlign_Top)
92 [
93 SNew(SBox)
94 .WidthOverride(400.f)
95 .HeightOverride(100.f)
96 [
97 SNew(SBorder)
98 .BorderImage(&MenuStyle->TitleBorderBrush)
99 .HAlign(HAlign_Center)
100 .VAlign(VAlign_Center)
101 [
102 SAssignNew(TitleText, STextBlock)
103 .Font(SlAiStyle::Get().GetFontStyle("MenuItemFort"))
104 .Text(NSLOCTEXT("SlAiMenu", "Menu", "Menu"))
105 .Font(MenuStyle->Font_60)
106 ]
107 ]
108 ]
109
110 +SOverlay::Slot() //菜单按钮组件
111 .HAlign(HAlign_Center)
112 .VAlign(VAlign_Top)
113 .Padding(FMargin(0.f, 130.f, 0.f, 0.f))
114 [
115 //菜单组件创建到这里
116 SAssignNew(ContentBox, SVerticalBox)
117 ]
118 ]
119 ];
120 InitializedMenuList();
121 InitializedAnimation();
122 }
123
124 void SSlAiMenuWidget::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
125 {
126 switch (AnimState)
127 {
128 case EMenuAnim::Stop:
129 break;
130 case EMenuAnim::Close: //如果菜单为关闭状态
131 if (MenuAnimation.IsPlaying())
132 {
133 //MenuCurve.GetLerp() 动态修改Menu的大小,从1到0
134 ResetWidgetSize(MenuCurve.GetLerp() * 600.f, -1.f);
135 //Menu的大小在缩小了40%的时候不显示组件
136 if (MenuCurve.GetLerp() < 0.6f && IsMenuShow) ChooseWidget(EMenuType::None);
137 }
138 else
139 {
140 //动画播放完毕,GetLerp到0后,设置状态为打开
141 AnimState = EMenuAnim::Open;
142 //开始播放打开的动画, Play 0到1
143 MenuAnimation.Play(this->AsShared());
144 }
145 break;
146 case EMenuAnim::Open:
147 //如果正在播放
148 if (MenuAnimation.IsPlaying())
149 {
150 //实时修改Menu的大小
151 ResetWidgetSize(MenuCurve.GetLerp() * 600.f, CurrentHeight);
152 //打开60%后显示组件, 并且没有显示组件, 调用ChooseWidget(),WidgetType != EMenuType::None 时 IsMenuShow 将会变为True
153 if (MenuCurve.GetLerp() > 0.6f && !IsMenuShow) ChooseWidget(CurrentMenu);
154 }
155 if (MenuAnimation.IsAtEnd())
156 {
157 //修改动画状态为停止
158 AnimState = EMenuAnim::Stop;
159 //解锁按钮
160 ControlLocked = false;
161 }
162 break;
163 }
164 }
165
166 END_SLATE_FUNCTION_BUILD_OPTIMIZATION
167
168 //按钮点击事件,实现界面跳转
169 void SSlAiMenuWidget::MenuItemOnClicked(EMenuItem::Type ItemType)
170 {
171 //如果锁住了,直接return
172 if (ControlLocked) return;
173 //设置锁住按钮,避免播放动画过程中操作其他按钮造成bug
174 ControlLocked = true;
175
176 switch (ItemType)
177 {
178 case EMenuItem::StartGame:
179 PlayClose(EMenuType::StartGame);
180 break;
181 case EMenuItem::GameOption:
182 PlayClose(EMenuType::GameOption);
183 break;
184 case EMenuItem::QuitGame:
185 //退出游戏,播放声音并且延时调用退出函数
186 SlAiHelper::PlayerSoundAndCall(UGameplayStatics::GetPlayerController(GWorld, 0)->GetWorld(), MenuStyle->ExitGameSound, this, &SSlAiMenuWidget::QuitGame);
187 break;
188 case EMenuItem::NewGame:
189 PlayClose(EMenuType::NewGame);
190 break;
191 case EMenuItem::LoadRecord:
192 PlayClose(EMenuType::ChooseRecord);
193 break;
194 case EMenuItem::StartGameGoBack:
195 PlayClose(EMenuType::MainMenu);
196 break;
197 case EMenuItem::GameOptionGoBack:
198 PlayClose(EMenuType::MainMenu);
199 break;
200 case EMenuItem::NewGameGoBack:
201 PlayClose(EMenuType::StartGame);
202 break;
203 case EMenuItem::ChooseRecordGoBack:
204 PlayClose(EMenuType::StartGame);
205 break;
206 case EMenuItem::EnterGame:
207 if (NewGameWidget->AllowEnterGame())
208 {
209 //进入游戏,播放声音并且延时调用进入游戏函数
210 SlAiHelper::PlayerSoundAndCall(UGameplayStatics::GetPlayerController(GWorld, 0)->GetWorld(), MenuStyle->StartGameSound, this, &SSlAiMenuWidget::EnterGame);
211 }
212 else
213 {
214 //解锁按钮
215 ControlLocked = false;
216 }
217 break;
218 case EMenuItem::EnterRecord:
219 ChooseRecordWidget->UpDateRecordName();
220 //进入游戏,播放声音并且延时调用退出函数
221 SlAiHelper::PlayerSoundAndCall(UGameplayStatics::GetPlayerController(GWorld, 0)->GetWorld(), MenuStyle->StartGameSound, this, &SSlAiMenuWidget::EnterGame);
222 break;
223 }
224 }
225
226 void SSlAiMenuWidget::ChangeCulture(ECultureTeam Culture)
227 {
228 SlAiDataHandle::Get()->ChangeLocalizationCulture(Culture);
229 }
230
231 void SSlAiMenuWidget::ChangeVolume(const float MusicVolume, const float SoundVolume)
232 {
233 SlAiDataHandle::Get()->ResetMenuVolume(MusicVolume, SoundVolume);
234 }
235
236 /*
237 * 游戏运行后会调用到 InitializedMenuList() 实例化所有的界面组件
238 */
239 void SSlAiMenuWidget::InitializedMenuList()
240 {
241 //实例化主界面
242 TArray<TSharedPtr<SCompoundWidget>> MainMenuList;
243 MainMenuList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "StartGame", "StartGame")).ItemType(EMenuItem::StartGame).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
244 MainMenuList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "GameOption", "GameOption")).ItemType(EMenuItem::GameOption).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
245 MainMenuList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "QuitGame", "QuitGame")).ItemType(EMenuItem::QuitGame).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
246
247 MenuMap.Add(EMenuType::MainMenu, MakeShareable(new MenuGroup(NSLOCTEXT("SlAiMenu", "Menu", "Menu"), 510.f, &MainMenuList)));
248
249 //开始游戏界面
250 TArray<TSharedPtr<SCompoundWidget>> StartGameList;
251 StartGameList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "NewGame", "NewGame")).ItemType(EMenuItem::NewGame).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
252 StartGameList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "LoadRecord", "LoadRecord")).ItemType(EMenuItem::LoadRecord).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
253 StartGameList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "GoBack", "GoBack")).ItemType(EMenuItem::StartGameGoBack).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
254
255 MenuMap.Add(EMenuType::StartGame, MakeShareable(new MenuGroup(NSLOCTEXT("SlAiMenu", "StartGame", "StartGame"), 510.f, &StartGameList)));
256
257 //游戏设置界面
258 TArray<TSharedPtr<SCompoundWidget>> GameOptionList;
259 //实例化游戏设置Widget(语言和声音)
260 SAssignNew(GameOptionWidget, SSlAiGameOptionWidget).ChangeCulture(this, &SSlAiMenuWidget::ChangeCulture).ChangeVolume(this, &SSlAiMenuWidget::ChangeVolume);
261 GameOptionList.Add(GameOptionWidget);
262 GameOptionList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "GoBack", "GoBack")).ItemType(EMenuItem::GameOptionGoBack).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
263
264 MenuMap.Add(EMenuType::GameOption, MakeShareable(new MenuGroup(NSLOCTEXT("SlAiMenu", "GameOption", "GameOption"), 610.f, &GameOptionList)));
265
266 //新游戏界面
267 TArray<TSharedPtr<SCompoundWidget>> NewGameList;
268 SAssignNew(NewGameWidget, SSlAiNewGameWidget);
269 NewGameList.Add(NewGameWidget);
270 NewGameList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "EnterGame", "EnterGame")).ItemType(EMenuItem::EnterGame).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
271 NewGameList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "GoBack", "GoBack")).ItemType(EMenuItem::NewGameGoBack).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
272
273 MenuMap.Add(EMenuType::NewGame, MakeShareable(new MenuGroup(NSLOCTEXT("SlAiMenu", "NewGame", "NewGame"), 510.f, &NewGameList)));
274
275 //选择存档界面
276 TArray<TSharedPtr<SCompoundWidget>> ChooseRecordList;
277 SAssignNew(ChooseRecordWidget, SSlAiChooseRecordWidget);
278 ChooseRecordList.Add(ChooseRecordWidget);
279 ChooseRecordList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "EnterRecord", "EnterRecord")).ItemType(EMenuItem::EnterRecord).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
280 ChooseRecordList.Add(SNew(SSlAiMenuItemWidget).ItemText(NSLOCTEXT("SlAiMenu", "GoBack", "GoBack")).ItemType(EMenuItem::ChooseRecordGoBack).OnClicked(this, &SSlAiMenuWidget::MenuItemOnClicked));
281
282 MenuMap.Add(EMenuType::ChooseRecord, MakeShareable(new MenuGroup(NSLOCTEXT("SlAiMenu", "LoadRecord", "LoadRecord"), 510.f, &ChooseRecordList)));
283 }
284
285 void SSlAiMenuWidget::ChooseWidget(EMenuType::Type WidgetType)
286 {
287 //是否已经显示菜单,显示菜单为True
288 IsMenuShow = WidgetType != EMenuType::None;
289
290 //移除所有组件
291 ContentBox->ClearChildren();
292
293 if (WidgetType == EMenuType::None) return;
294
295 //添加菜单的下属组件
296 for (TArray<TSharedPtr<SCompoundWidget>>::TIterator It((*MenuMap.Find(WidgetType))->ChildWidget); It; It++)
297 {
298 ContentBox->AddSlot().AutoHeight()[(*It)->AsShared()];
299 }
300
301 //更改标题
302 TitleText->SetText((*MenuMap.Find(WidgetType))->MenuName);
303 }
304
305 //如果不修改高度,NewHeight传入-1
306 void SSlAiMenuWidget::ResetWidgetSize(float NewWidget, float NewHeight)
307 {
308 RootSizeBox->SetWidthOverride(NewWidget);
309 if (NewHeight < 0)
310 {
311 return;
312 }
313 RootSizeBox->SetHeightOverride(NewHeight);
314 }
315
316 /**
317 * FCurveSequence 动画播放器
318 * FCurveHandle 是曲线控制器
319 * 我们会通过动画控制器 FCurveSequence 的一些方法 (如 Play Stop 等……) 让曲线 FCurveHandle 0到1、1到0实时的变化
320 * 我们可以实时的获取曲线 FCurveHandle 的值,获取曲线的值动态的修改界面的大小
321 */
322 void SSlAiMenuWidget::InitializedAnimation()
323 {
324 //开始延时
325 const float StartDelay = 0.3f;
326
327 //持续时间
328 const float AnimDuration = 0.6f;
329
330 //将动画播放器实例化
331 MenuAnimation = FCurveSequence();
332
333 //曲线控制器注册进动画播放器,参数:开始延时、持续时间、播放类型
334 MenuCurve = MenuAnimation.AddCurve(StartDelay, AnimDuration, ECurveEaseFunction::QuadInOut);
335
336 //初始设置Menu大小
337 ResetWidgetSize(600.f, 510.f);
338
339 //初始显示主界面
340 ChooseWidget(EMenuType::MainMenu);
341
342 //是否允许点击按钮
343 ControlLocked = false;
344
345 //设置动画状态为停止
346 AnimState = EMenuAnim::Stop;
347
348 //设置动画播放器跳到结尾 1
349 MenuAnimation.JumpToEnd();
350 }
351
352 void SSlAiMenuWidget::PlayClose(EMenuType::Type NewMenu)
353 {
354 //设置新的界面
355 CurrentMenu = NewMenu;
356 //设置新高度
357 CurrentHeight = (*MenuMap.Find(CurrentMenu))->MenuHeight;
358 //设置播放状态是Close, 代表关闭Menu
359 AnimState = EMenuAnim::Close;
360 //播放反向动画,从1播放到0,动画播放器初始化时 MenuAnimation.JumpToEnd(); 设置到了1
361 MenuAnimation.PlayReverse(this->AsShared());
362 //播放切换菜单音乐
363 FSlateApplication::Get().PlaySound(MenuStyle->MenuItemChangeSound);
364 }
365
366 void SSlAiMenuWidget::QuitGame()
367 {
368 //Cast 是一个类型转换的方法,控制台输入 quit
369 Cast<ASlAiMenuController>(UGameplayStatics::GetPlayerController(GWorld, 0))->ConsoleCommand("quit");
370 }
371
372 void SSlAiMenuWidget::EnterGame()
373 {
374 //跳转到Level
375 UGameplayStatics::OpenLevel(UGameplayStatics::GetPlayerController(GWorld, 0)->GetWorld(), FName("GameMap"));
376 }
然后运行,打开UE4,进入场景编辑放入一个 PlayerStart 组件,这样进入游戏关卡后,出生点便是 PlayerStart 的位置,但进入场景后是无法移动的。
到此MenuMap的功能全部实现完了
GameInstance
接下来开始写GameMap里的内容,先给GameMap添加 GamePlay 框架
关闭VS和UE后,重新打开UE4.左上角点击 Edit → Project Settings → Map&Modes
将默认打开Map改成 GameMap
然后再 D:/UE4 Project/UE26.2/CourseProject/SlAiCourse/Source/SlAiCourse/Public/GamePlay 文件夹下
新建一个 Game Mode Base 类
GamePlay文件夹下再新建一个 GameInstance,用来一会儿测试跨场景传递变量
D:/UE4 Project/UE26.2/CourseProject/SlAiCourse/Source/SlAiCourse/Public/UI/HUD 文件夹下
新建一个HUD
然后前往 GameMap 下的 WorldSettings 设置下 GameMode → GameMpde Override 设置为 SlAiGameMode 点击 Save All 保存
来到左上角点击 Edit → Project Settings → Map&Modes
将GameInstance设置为 SlAiGameInstance
GameInstance 的主要作用有4种,这里主要说明游戏的的初始化加载
这里将会写一个 GameInstance 方法,和之前的 SlAiDataHandle 方法,写一个同样的功能,跨场景时将一个 Level 的数据带到第二个 Level
GameInstance 中声明一个 GameName
d:ue4 projectue26.2courseprojectslaicourseSourceSlAiCoursePublicGamePlaySlAiGameInstance.h
1 #include "CoreMinimal.h"
2 #include "Engine/GameInstance.h"
3 #include "SlAiGameInstance.generated.h"
4
5 /**
6 *
7 */
8 UCLASS()
9 class SLAICOURSE_API USlAiGameInstance : public UGameInstance
10 {
11 GENERATED_BODY()
12
13 public:
14
15 //Init() ,UGameInstance父类的方法,其初始化比较靠前,可以放一些优先初始化的东西
16 //virtual void Init() override;
17
18 UPROPERTY(VisibleAnywhere, Category = "SlAi")
19 FString GameName;
20 };
SlAiMenuGameMode 中将 GameName 赋值
D:UE4 ProjectUE26.2CourseProjectSlAiCourseSourceSlAiCoursePublicGamePlaySlAiMenuGameMode.h
1 #include "CoreMinimal.h"
2 #include "GameFramework/GameModeBase.h"
3 #include "SlAiMenuGameMode.generated.h"
4
5 /**
6 *
7 */
8 UCLASS()
9 class SLAICOURSE_API ASlAiMenuGameMode : public AGameModeBase
10 {
11 GENERATED_BODY()
12
13 public:
14 ASlAiMenuGameMode();
15
16 protected:
17 virtual void BeginPlay() override;
18 };
D:UE4 ProjectUE26.2CourseProjectSlAiCourseSourceSlAiCoursePrivateGamePlaySlAiMenuGameMode.cpp
1 #include "GamePlay/SlAiMenuGameMode.h"
2 #include "UI/HUD/SlAiMenuHUD.h"
3 #include "GamePlay/SlAimenuController.h"
4
5 #include "GamePlay/SlAiGameInstance.h"
6 #include "Kismet/GameplayStatics.h"
7
8
9 ASlAiMenuGameMode::ASlAiMenuGameMode()
10 {
11 PlayerControllerClass = ASlAiMenuController::StaticClass(); //PlayerControllerClass 是这个GameMode类下边的属性,StaticClass是UE4通过反射自己创建的一个函数,
12 HUDClass = ASlAiMenuHUD::StaticClass();
13 }
14
15 void ASlAiMenuGameMode::BeginPlay()
16 {
17 //通过GameInstance 修改SlAiGameInstance 下的 GameName 的值
18 Cast<USlAiGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()))->GameName = FString("SlAiCourse");
19 }
在 SlAiGameMode 中使用 GameInstance 和 SlAiDataHandle 同时调用在 Menu 中的数据,查看下结果
d:ue4 projectue26.2courseprojectslaicourseSourceSlAiCoursePublicGamePlaySlAiGameMode.h
1 #include "CoreMinimal.h"
2 #include "GameFramework/GameModeBase.h"
3 #include "SlAiGameMode.generated.h"
4
5 /**
6 *
7 */
8 UCLASS()
9 class SLAICOURSE_API ASlAiGameMode : public AGameModeBase
10 {
11 GENERATED_BODY()
12
13 public:
14 ASlAiGameMode();
15
16 protected:
17 virtual void BeginPlay() override;
18
19 };
D:UE4 ProjectUE26.2CourseProjectSlAiCourseSourceSlAiCoursePrivateGamePlaySlAiGameMode.cpp
1 #include "GamePlay/SlAiGameMode.h"
2 #include "Common/SlAiHelper.h"
3 #include "Data/SlAiDataHandle.h"
4 #include "GamePlay/SlAiGameInstance.h"
5 #include "Kismet/GameplayStatics.h"
6
7 ASlAiGameMode::ASlAiGameMode()
8 {
9
10 }
11
12 void ASlAiGameMode::BeginPlay()
13 {
14 SlAiHelper::Debug(FString("DataHandle : ") + SlAiDataHandle::Get()->RecordName, 30.f);
15 //Cast<USlAiGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()))->GameName = FString("SlAiCourse");
16 SlAiHelper::Debug(FString("GameInstance : ") + Cast<USlAiGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()))->GameName, 30.f);
17 }
运行项目后新建一个存档New,进入游戏后左上角会显示如下截图的内容,说明使用 SlAiDataHandle 和SlAiGameInstance都可以让一个Level的变量在另一个场景使用(全局)
下面的的项目将会使用 SlAiDataHandle这种方式
接下来继续创建一些C++的文件,所有的玩家相关类都放在这个下边
保存玩家数据
动作蓝图的基类
基于SlAiPlayerAnim 的第三人称动作蓝图
基于SlAiPlayerAnim 的第一人称动作蓝图
一共6个C++文件创建完毕
这时候在场景下会发现,WorldSettings 下的 GameMode→SelectedGameMode 都没有指定需要前往C++类里进行指定
D:UE4 ProjectUE26.2CourseProjectSlAiCourseSourceSlAiCoursePublicGamePlaySlAiGameMode.h
1 #include "CoreMinimal.h"
2 #include "GameFramework/GameModeBase.h"
3 #include "SlAiGameMode.generated.h"
4
5 /**
6 *
7 */
8 UCLASS()
9 class SLAICOURSE_API ASlAiGameMode : public AGameModeBase
10 {
11 GENERATED_BODY()
12
13 public:
14 ASlAiGameMode();
15
16 //重写帧函数
17 virtual void Tick(float DeltaSeconds) override;
18
19 protected:
20 virtual void BeginPlay() override;
21 };
d:ue4 projectue26.2courseprojectslaicourseSourceSlAiCoursePrivateGamePlaySlAiGameMode.cpp
1 #include "GamePlay/SlAiGameMode.h"
2 #include "Player/SlAiPlayerController.h"
3 #include "Player/SlAiPlayerCharacter.h"
4 #include "Player/SlAiPlayerState.h"
5 #include "UI/HUD/SlAiGameHUD.h"
6 #include "Common/SlAiHelper.h"
7 #include "Data/SlAiDataHandle.h"
8 #include "GamePlay/SlAiGameInstance.h"
9 #include "Kismet/GameplayStatics.h"
10
11
12 ASlAiGameMode::ASlAiGameMode()
13 {
14 //允许开启Tick函数
15 PrimaryActorTick.bCanEverTick = true;
16
17 //添加组件
18 HUDClass = ASlAiGameHUD::StaticClass();
19 PlayerControllerClass = ASlAiPlayerController::StaticClass();
20 PlayerStateClass = ASlAiPlayerState::StaticClass();
21 DefaultPawnClass = ASlAiPlayerCharacter::StaticClass();
22 }
23
24 void ASlAiGameMode::Tick(float DeltaSeconds)
25 {
26
27 }
28
29 void ASlAiGameMode::BeginPlay()
30 {
31 SlAiHelper::Debug(FString("DataHandle : ") + SlAiDataHandle::Get()->RecordName, 30.f);
32 SlAiHelper::Debug(FString("GameInstance : ") + Cast<USlAiGameInstance>(UGameplayStatics::GetGameInstance(GetWorld()))->GameName, 30.f);
33 }
绑定好了
下一部分写添加玩家模型与相机
=========================================================================================================================================================
原文链接: https://www.cnblogs.com/CooCoChoco/p/15293332.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/213756
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!