背景

最近研究dota2rpg时候发现一个问题:游戏流程如果使用官方的做法会比较死板。比如你必须选完队伍,然后再去选择英雄,然后再开始游戏。当然这个不是说它不好,但对于一款高度定制化的地图编辑器来说,这着实会束缚开发者的能力。很多优秀的rpg地图都可以定制整个游戏前的流程。

调查

首先,最重要的是搞清楚已有的dota游戏流程是如何的。

可以看到整个流程还是比较详细的,也容易看懂。其中比较重要的就是game_setup和hero_selection了。

一般来说要修改game_setup界面还是比较简单的。比如:

	<Panel>
		<!-- Ingame HUD -->
		<CustomUIElement type="GameSetup" layoutfile="file://{resources}/layout/custom_game/team_selection.xml" />
	</Panel>

同理我们也可以添加

<CustomUIElement type="HeroSelection" layoutfile="file://{resources}/layout/custom_game/pick_hero.xml" />

这样来达到自定义界面的效果。
当我尝试出来效果一般。首先按照这个思路我们还是必须严格按照流程来进行界面设置。也就是必须设置完了队伍再去选择英雄之类。那如果游戏的设定不希望是这个流程呢?其次感觉要覆盖掉原来的英雄选择界面比较麻烦。我摸索出来的思路就是一个覆盖而已,效果如下:

跳出盒子

有没有可能我在game_setup里面就直接做完了所有的事情呢。这样的话我们就不必完全按照预设的流程。

准备工作:

我们需要让game_setup不往hero_selection走。那么需要这么设置:

function COverthrowGameMode:OnGameRulesStateChange()
	local nNewState = GameRules:State_Get()

	-- Disable auto launch when entering custom game setup, it can be
	-- re-enabled at any point later while still in custom game setup
	if nNewState == DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP then
		GameRules:EnableCustomGameSetupAutoLaunch( false )
	end
end

这样就不会发生跳转了。

接下来的问题是:我们可以自己做一个英雄界面(或者其他准备界面),但怎么跳过默认的hero_selection?官网并没提供可以跳过某个步骤的接口。就是说按照dota2底层实现它是必须严格按照上面的顺序来做的。

经过摸索,其实道理很简单。为什么默认机制是会强行你进入hero_selection?那是因为你没有英雄。如果你能在hero_selection之前让底层认为你选定了英雄就一切搞定了。顺着这个思路寻找的话,我们可以有两种方案达到:

  1. 地图中拖一个 dota_custom_game_events 进去,设置里面的属性ForceSelectHero = "npc_dota_hero_wisp"。
  2. 强行设定某个英雄 GameRules:GetGameModeEntity():SetCustomGameForceHero(keys.HeroName);
  3. 设定自定义英雄 CreateHeroForPlayer(keys.HeroName, player)

最终效果
个人比较推荐后面两种,虽然第一种也可以达到效果。经过测试发现我们在hero_selection之前就选定好了英雄,达到欺骗底层的目的了。

可以注意到我们还是经历了所有的STATE,只是我们在页面上没有感知而已。

展开

按照上面的思路,我们甚至可以做到进入游戏后再选择英雄也是可以的。重点是我们跳过了hero_selection,鼓掌散花。。。

建议

首先,你必须喜欢玩moba类游戏,尤其是dota。当然不是要求你多么高的天体分,而是说你要对于大部分dota的机制都很清楚。这样理解整个dota2rpg的开发也是相当有帮助的。
其次,由于valve官网的文档很难用,整个dota2rpg的入门还是没有那么容易。所以最好的方案还是看源代码配合官方文档来用,当然amhc社区对于英文不是特别好的小伙伴来说也是不错的选择。
最后也是最重要的,就是要坚持,有了这一点什么事情都能做好了。

参考

Custom Game Setup

CustomHeroSelection