CSGO制图经验分享5 - 用VScript做出游戏菜单
cs:source吧
全部回复
仅看楼主
level 8
工口地瓜 楼主
大家都有玩过CTX的新地图coop_mission_storm吧?感觉那个地图已经可以单独做成dlc发售了。在那个地图中,CTX创造了很多大家之前闻所未闻的新功能,颠覆了我们对CSGO玩法的认识。有玩过的话,你应该会记得地图中有个由纯文本组成的“背包系统”,玩家通过W/A/S/D和鼠标选择并使用道具。
---------------------------------------
所以我在想,能不能用同样或者类似的方法,在不使用sourcemod插件的情况下,只靠地图和VScript模拟出游戏菜单功能呢?[滑稽]
---------------------------------------
抱着试一试的心理,我模拟了一个CSGO游戏中的菜单。这个菜单在多人模式中也是可以使用的,但是可能还需要再就某些方面进行修改,以防止BUG发生,比如多人同时使用的冲突问题等等。我以一个只有3个选项的菜单为例,如果你想制作选项更多的菜单,可以反编译CTX的地图并仿照CTX的做法。
---------------------------------------
视频效果

2018年04月13日 13点04分 1
level 8
工口地瓜 楼主
(第二步)
有关事件监听的功能的实现请直接参考这个范例,我不再赘述。But,这真的是一个非常有用的功能。现在,在范例的地图中直接创建一个logic_eventlistener实体,Class Info如下设置:
Name : logic_eventlistener5
Entity Scripts : eventlistener.nut
Script think function : Think
Event Name : player_say
Fetch Event Data : Yes
其他键值默认
Outputs如图设置:
2018年04月13日 13点04分 4
level 8
工口地瓜 楼主
(第三步)
然后,创建一个game_player_equip实体,命名为equiper,Flags勾选【Use Only】和【Only Strip Same Weapon Type】。
2018年04月13日 13点04分 6
level 8
工口地瓜 楼主
(第四步)
接着,创建一个logic_timer实体,命名为timer3,Refire Interval设置为4。Outputs如下图:
2018年04月13日 13点04分 9
level 8
工口地瓜 楼主
(第五步)
然后就可以编译这个地图了。用Notepad++或者你喜欢的工具打开eventlistener.nut,你可以把“超高跳”、“传送枪”等功能直接注释掉或者删掉,如果你不需要它们的话。你也可以在地图中删除对应的logic_eventlistener实体来取消这些功能。
然后如下图,在脚本的最下方插入截图中的代码。关于CSGO的游戏事件(Game Events)有疑问的话,可以在AlliedModders论坛的Wiki中查找到相关的解释。当然,这个例子里的player_say并不是CSGO的游戏事件,而是通用起源服务器的事件。
2018年04月13日 13点04分 10
level 8
工口地瓜 楼主
2018年04月13日 13点04分 13
level 8
工口地瓜 楼主
2018年04月13日 13点04分 14
level 5
[真棒]干货的东西必须支持,一直只会玩实体不会写脚本,虽然效果一样但是脚本实现感觉更加简洁便利全面一点,这东西正好是个几号的学习范本
2019年04月26日 01点04分 15
level 1
楼主,能否在vscript中创建事件监听器实体?我试了以下代码,info_game_event_proxy 能正常 GenerateGameEvent,但是监听器实体就
是监听不到事件,求帮助
代码:
// 创建一个事件监听器实体,监听player_use事件
if ( !("event_listener_player_use" in getroottable()) || ! (::event_listener_player_use.IsValid()) )
{
::event_listener_player_use <- Entities.CreateByClassname("logic_eventlistener");
::event_listener_player_use.__KeyValueFromString("EventName","player_use");
::event_listener_player_use.__KeyValueFromInt("FetchEventData", 1);
EntFireByHandle(::event_listener_player_use, "Enable", "", 0.0, null, null);
}
// 设置监听器监听到事件发生时触发的函数
::event_listener_player_use.ValidateScriptScope();
::event_listener_player_use.GetScriptScope().OnGameEvent_player_use <- function(event_data)
{
printl( event_data["userid"] + "has used something!" );
}
::event_listener_player_use.ConnectOutput("OnEventFired", "OnGameEvent_player_use");
// 设置 info_game_event_proxy 实体以帮助触发事件player_use
if ( !("gameevents_proxy" in getroottable()) || ! (::gameevents_proxy.IsValid()) )
{
::gameevents_proxy <- Entities.CreateByClassname("info_game_event_proxy");
::gameevents_proxy.__KeyValueFromString("targetname","gameevents_proxy");
::gameevents_proxy.__KeyValueFromString("event_name","player_use");
::gameevents_proxy.__KeyValueFromInt("range",0);
}
::gameevents_proxy.ValidateScriptScope();
// 当 gameevents_proxy 成功 GenerateGameEvent 时输出字符串
::gameevents_proxy.GetScriptScope().InputGenerateGameEvent <- function(){ printl("GenerateGameEvent!!!"); }
// 让每一位玩家都触发一次player_use事件
player <- null;
while( (player = Entities.FindByClassname(player,"*")) != null )
{
if ( player.GetClassname() == "player" && player.IsValid() )
{
EntFireByHandle(::gameevents_proxy, "GenerateGameEvent", "", 0.0, player, null);
}
}
2022年02月15日 18点02分 16
1