跳至正文
版本:最新版 - a1.148.0 ⚖️

基本 HUD(HTML)

如何使用 HTML + JavaScript + CSS 添加一个基本 HUD,以根据 CS:GO HUD 显示角色的生命值和弹药量。

提示

以下示例已弃用,你可以在我们的 Sandbox 官方仓库 中找到更新后的 HTML UI。

创建 UI

在包的 Client 文件夹内,新建一个名为 UI/ 的文件夹(可选),以便将 UI 文件与脚本(lua)文件区分开来:

UI/ 文件夹内创建以下文件:index.htmlstyle.cssindex.js

信息

在此 UI 中我们将使用 JQuery,请下载最新版本并将其放置在 UI/ 文件夹中。

Client/UI/index.html
<html>
<head>
<!-- 引入我们创建的所有文件(JS、JQuery 和 CSS) -->
<script src="jquery-3.5.1.min.js"></script>
<script src="index.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- 生命值容器(黑色背景) -->
<div id="health_container">
<img src="health.png">
<span id="health_current">100</span> <!-- 生命值数值 -->
</div>

<!-- 武器弹药容器(黑色背景) -->
<div id="weapon_ammo_container">
<span id="weapon_ammo_clip">30</span> <!-- 弹匣弹药数 -->
<span id="weapon_ammo_bag">/ 1000</span> <!-- 弹药袋弹药数 -->
</div>
</body>
</html>
信息

如果你注意到我们使用了一张图片 health.png,你可以从这里下载 https://i.imgur.com/0BmQJVZ.png 并同样将其放置在 UI/ 中。

现在让我们为其添加样式,为此请编辑你的 style.css 并添加以下 CSS 代码:

Client/UI/style.css
body {
font-family: Tahoma, sans-serif;
font-size: 14px;
margin: 0px;
padding: 0px;
margin-bottom: 20px;
}

#weapon_ammo_container {
display: none;
position: absolute;
right: 0px;
bottom: 0px;
width: 200px;
height: 50px;
background-image: linear-gradient(to right, #00000000, #00000080);
text-align: right;
line-height: 47px;
}

#weapon_ammo_bag {
color: #ededed;
font-weight: bold;
font-size: 16px;
margin-right: 30px;
position: relative;
top: -4px;
}

#weapon_ammo_clip {
color: white;
font-weight: bold;
font-size: 32px;
}

#health_container {
position: absolute;
bottom: 0px;
width: 200px;
height: 50px;
background-image: linear-gradient(to left, #00000000, #00000080);
}

#health_container img {
height: 23px;
margin: 13px;
}

#health_current {
color: white;
font-size: 32px;
font-weight: bold;
position: absolute;
margin-top: 4px;
}

最后,在你的包的 Index.lua 中生成 WebUI:

Client/Index.lua
-- 使用你刚刚创建的 HTML 文件生成 WebUI
main_hud = WebUI("Main HUD", "file://UI/index.html")

结果:

这还只是静态文本! 现在让我们让它动起来,显示实际的数值!

添加事件和回调以与你的包通信

在你的 index.js 中添加以下 JavaScript 代码:

Client/UI/index.js
// 注册 UpdateWeaponAmmo 自定义事件(来自 Lua)
Events.Subscribe("UpdateWeaponAmmo", function(enable, clip, bag) {
if (enable)
$("#weapon_ammo_container").show();
else
$("#weapon_ammo_container").hide();

// 使用 JQuery,用新的弹药值覆盖这些 SPAN 的 HTML 内容
$("#weapon_ammo_clip").html(clip);
$("#weapon_ammo_bag").html("/ " + bag);
});

// 注册 UpdateHealth 自定义事件(来自 Lua)
Events.Subscribe("UpdateHealth", function(health) {
// 使用 JQuery,用新的生命值覆盖 SPAN 的 HTML 内容
$("#health_current").html(health);

// 额外效果:当生命值低于 25 时将背景变为红色
if (health <= 25)
$("#health_container").css("background-image", "linear-gradient(to left, #0000, #d00c)");
else
$("#health_container").css("background-image", "linear-gradient(to left, #00000000, #00000080)");
});

既然我们的 UI 已经准备就绪,让我们完成 Lua 代码来处理整个逻辑!

Client/Index.lua
-- 使用你刚刚创建的 HTML 文件生成 WebUI
main_hud = WebUI("Main HUD", "file://UI/index.html")


-- 当 LocalPlayer 生成时,在其上设置一个事件,以便在控制新角色时触发,从而在本地存储本地控制的角色。该事件仅调用一次,请参阅 Package:Subscribe("Load") 以在重新加载包时加载它
Client.Subscribe("SpawnLocalPlayer", function(local_player)
local_player:Subscribe("Possess", function(player, character)
UpdateLocalCharacter(character)
end)
end)

-- 当包加载时,验证 LocalPlayer 是否已存在(例如重新加载包时),然后尝试获取并存储其控制的角色
Package.Subscribe("Load", function()
local local_player = Client.GetLocalPlayer()
if (local_player ~= nil) then
UpdateLocalCharacter(local_player:GetControlledCharacter())
end
end)

-- 在本地角色上设置所有所需事件的函数(以便在其受到伤害或死亡时更新 UI)
function UpdateLocalCharacter(character)
-- 验证 character 是否不为 nil(例如当 GetControllerCharacter() 未返回角色时)
if (character == nil) then return end

-- 使用当前角色的生命值更新 UI
UpdateHealth(character:GetHealth())

-- 在角色上设置一个事件,以便在其受到伤害后更新生命值 UI
character:Subscribe("TakeDamage", function(charac, damage, type, bone, from_direction, instigator, causer)
UpdateHealth(math.max(charac:GetHealth() - damage, 0))
end)

-- 在角色上设置一个事件,以便在其死亡后更新生命值 UI
character:Subscribe("Death", function(charac)
UpdateHealth(0)
end)

-- 尝试获取角色是否手持任何武器
local current_picked_item = character:GetPicked()

-- 如果手持武器,更新 UI
if (current_picked_item and current_picked_item:IsA(Weapon)) then
UpdateAmmo(true, current_picked_item:GetAmmoClip(), current_picked_item:GetAmmoBag())
end

-- 在角色上设置一个事件以更新其抓取的武器(在 UI 上显示弹药)
character:Subscribe("PickUp", function(charac, object)
if (object:IsA(Weapon)) then
UpdateAmmo(true, object:GetAmmoClip(), object:GetAmmoBag())
end
end)

-- 在角色上设置一个事件,以便在其丢弃武器时移除弹药 UI
character:Subscribe("Drop", function(charac, object)
UpdateAmmo(false)
end)

-- 在角色上设置一个事件,以便在其开火时更新 UI
character:Subscribe("Fire", function(charac, weapon)
UpdateAmmo(true, weapon:GetAmmoClip(), weapon:GetAmmoBag())
end)

-- 在角色上设置一个事件,以便在其换弹时更新 UI
character:Subscribe("Reload", function(charac, weapon, ammo_to_reload)
UpdateAmmo(true, weapon:GetAmmoClip(), weapon:GetAmmoBag())
end)
end

-- 更新弹药 UI 的函数
function UpdateAmmo(enable_ui, ammo, ammo_bag)
main_hud:CallEvent("UpdateWeaponAmmo", {enable_ui, ammo, ammo_bag})
end

-- 更新生命值 UI 的函数
function UpdateHealth(health)
main_hud:CallEvent("UpdateHealth", {health})
end
提示

就这些! 尽情在你的包中使用它吧!