UE4无尽跑酷游戏制作杂记之二
2015-12-24 14:44
621 查看
UE4无尽跑酷游戏制作杂记之二
在做游戏的过程中,我先后犯了两个很愚蠢的错误,这个在我观看官方的无尽的奔跑者之后我意识到了这个错误。首先在我原来的设计当中,我使用了一个单例类,或者说一个管理者类(继承自UObject)来管理整个的路途,叫做RoadManager,然后他持有游戏中所有的道路,我们每个道路都是在RoadManger中的道路队列下,每一帧我们窥探队列的首元素,然后判断它与玩家的距离是不是大于了两千,是的话就销毁它并且生成一个新的。这部分我们的代码如下:
代码如下,其余的实现我们在蓝图中继承覆盖。
void URoadManager:: tickTimeRoadCreate (){ AMyRoad * tempOut ; if ( roadQueue .Peek ( tempOut)){ float distance = ( Owner-> GetActorLocation () - tempOut ->GetActorLocation ()). Size(); if ( distance > 2000){ roadQueue .Dequeue ( tempOut); tempOut ->Destroy (); tempOut = randomRoad(); //这里我们条用生成的函数,并且销毁我们之前生成的道路。 setRoadLocation (tempOut ); }
蓝色字体部分是我们对于游戏逻辑的判断是如上所说的,生成部分的代码如下:
AMyRoad * URoadManager :: randomRoad(){ float probability = FMath ::FRandRange ( 0, 1); if ( probability < 0.8){ return currentWorld -> SpawnActor< AMyRoad >(roadOne ); } else if (probability < 0.9){ return currentWorld -> SpawnActor< AMyRoad >(roadTwo ); } else { return currentWorld -> SpawnActor< AMyRoad >(roadThree ); } }
然而这样做无疑是低效的,我需要每一帧都监听我们主角与队列中道路的位置,一但我把主角删除,无疑我的程序一下就会出现很多的BUG
其实正确而高效的做法是我在RoadManager中将我们的生成新路径的代码写好,然后在每一段路线的尽头我都设置一个触发器,走到尽头后出发,通知roadManager调用。
(这里说个题外话,我发现4.92中原来调用OnComponentBeginOverlap的方式没有了,我似乎只会在蓝图中调用)
第二个错误是我没有用好GameMode模块,而是自己写了个管理器,我的管理器的很多操作应该在GameMode中进行的。
GameMode
*“AGameMode”类定义所玩的游戏,并执行游戏规则。“AGameMode”中的一些默认功能包括:
任何设定游戏规则的新函数或变量都应添加在“AGameMode”类的子类中。从玩家以什么库存道具开始,或有多少条命,到时间限制,以及结束游戏所需的分数都属于 GameMode。可以为游戏应包括的每个游戏类型创建“AGameMode”类的子类。一个游戏可以有任何数量的游戏类型,因此有任何数量的“AGameMode”类的子类;然而,在任何特定时间只可以使用一种游戏类型。每次通过“UGameEngine::LoadMap()”函数初始化一个游戏等级时都会实例化一个 GameMode Actor。该 Actor 定义的游戏类型将被用于该等级所持续的时间。
*
比赛状态
GameMode 包含监测比赛状态或整体游戏流程的状态机。要查询当前状态,你可以使用 GetMatchState,或诸如 HasMatchStarted、IsMatchInProgress 和 HasMatchEnded 的包装器。以下是可能的比赛状态:
EnteringMap 是初始状态。Actors 尚未开始计数,并且世界尚未完全初始化。当一切都完全加载后会过渡到下个状态。
WaitingToStart是下个状态,进入时调用 HandleMatchIsWaitingToStart。Actors开始计数,但尚未生成玩家。如果 ReadyToStartMatch 返回true,或如果有人调用 StartMatch,则过渡到下个状态。
InProgress 是下个状态,进入时调用 HandleMatchHasStarted,进而调用所有 Actors的 BeginPlay。普通游戏正在进行中。如果 ReadyToEndMatch 返回true,或如果有人调用 EndMatch,则过渡到下个状态。
WaitingPostMatch 是下个状态,进入时调用 HandleMatchHasEnded。Actors仍在计数,但不接受新玩家。当地图转换开始时过渡到下个状态。
LeavingMap是最后的状态,进入时调用HandleLeavingMap。在转至新地图时比赛停留在该状态。
Aborted 是故障状态,从 AbortMatch 开始。当存在不可恢复的错误时设置成该状态。
默认情况下,比赛状态几乎总为 InProgress。但个别游戏可以覆盖该行为,以构建有更复杂规则的多人游戏。
设置GameMode
有几种方法来设置某一等级的GameMode,以下按照从最低优先级到最高优先级的顺序:
在“DefaultGame.ini”文件中的“/Script/Engine.WorldSettings/”部分设置“GlobalDefaultGameMode”项`将为项目中的所有地图设置默认游戏模式。
[/Script/Engine.WorldSettings]GlobalDefaultGameMode="/Script/MyGame.MyGameGameMode"GlobalDefaultServerGameMode="/Script/MyGame.MyGameGameMode"
然后在GameMode中我可以使用
static ConstructorHelpers:: FClassFinder <APawn > PlayerPawnBPClass ( TEXT( "/Game/ThirdPersonCPP/Blueprints/ThirdPersonCharacter" )); if ( PlayerPawnBPClass .Class != NULL ) { DefaultPawnClass = PlayerPawnBPClass. Class ; } PlayerControllerClass = ABatteryCollectorPlayerController ::StaticClass ();
如下代码去初始化我们的游戏。
在GameMode 中我们同样有BeginPlay Tick等事件
World -> GetAuthGameMode()这个函数可以得打我们的游戏模式进而进行操纵。
相关文章推荐
- UICollectionView详解
- requirejs 到底有什么好处?
- ios ASIFormDataRequest上传图片到php服务器
- UIViewController
- 【android学习】关于textview.setEllipsize(TextUtils.TruncateAt.valueOf("END"));失效
- 类似UC天气下拉和微信下拉眼睛头部弹入淡出UI交互效果(开源项目)。
- UILTview
- UITextField和lUIButton结合
- UITextField
- 转载:设置UIImage的渲染模式:UIImage.renderingMode
- UIButton
- UE4无尽跑酷游戏制作杂记之一
- ueditor使用小结
- 动态调整UITableViewCell的高度
- mysql_escape_string — 转义一个字符串用于 mysql_query
- iOS开发系列之三 - UITextField 使用方法小结
- UIdynamic的简单使用
- Android如何通过gradientui类库实现渐变切换icon效果
- UICollectionViewLayout
- UITextField