cs:source吧 关注:1,537贴子:16,062
  • 8回复贴,共1

CSGO制图经验分享5 - 用VScript做出游戏菜单

只看楼主收藏回复

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


IP属地:福建1楼2018-04-13 21:10回复
    (第二步)
    有关事件监听的功能的实现请直接参考这个范例,我不再赘述。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如图设置:


    IP属地:福建4楼2018-04-13 21:22
    回复
      (第三步)
      然后,创建一个game_player_equip实体,命名为equiper,Flags勾选【Use Only】和【Only Strip Same Weapon Type】。


      IP属地:福建6楼2018-04-13 21:24
      回复
        (第四步)
        接着,创建一个logic_timer实体,命名为timer3,Refire Interval设置为4。Outputs如下图:


        IP属地:福建9楼2018-04-13 21:27
        回复
          (第五步)
          然后就可以编译这个地图了。用Notepad++或者你喜欢的工具打开eventlistener.nut,你可以把“超高跳”、“传送枪”等功能直接注释掉或者删掉,如果你不需要它们的话。你也可以在地图中删除对应的logic_eventlistener实体来取消这些功能。
          然后如下图,在脚本的最下方插入截图中的代码。关于CSGO的游戏事件(Game Events)有疑问的话,可以在AlliedModders论坛的Wiki中查找到相关的解释。当然,这个例子里的player_say并不是CSGO的游戏事件,而是通用起源服务器的事件。




          IP属地:福建10楼2018-04-13 21:28
          回复


            IP属地:福建13楼2018-04-13 21:32
            回复


              IP属地:福建14楼2018-04-13 21:33
              回复
                干货的东西必须支持,一直只会玩实体不会写脚本,虽然效果一样但是脚本实现感觉更加简洁便利全面一点,这东西正好是个几号的学习范本


                IP属地:美国15楼2019-04-26 09:50
                回复
                  楼主,能否在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);
                  }
                  }


                  IP属地:广东16楼2022-02-16 02:47
                  回复