Skip to content

快速入门

创建你的第一个魔兽世界插件。

准备工作

  1. Lua 基础知识
    • 跟随本文操作不需要编程知识,但了解 Lua 语言也许能帮助你明白插件的工作原理。
    • 本站有简易的 Lua 速查表,里面也有详细教程的链接。
  2. 文本编辑器
  3. 魔兽世界客户端
    • 本文基于正式服(更新于 11.0.2 版本),其他版本的客户端理论上同样适用,但有略微差别。

Hello World

运行脚本

要在魔兽世界中运行 Lua 脚本,只需要在聊天框输入 /run/script 加上 Lua 代码即可。例如:

/run print("Hello World")

你会看到聊天框输出了 Hello World

接下来我们要创建一个插件,让此过程在游戏登录时自动执行。

创建插件

魔兽世界的插件一般包含一个 TOC 文件,以及若干 Lua 文件和 XML 文件组成。

  • TOC 文件:包含插件的基本信息,以及文件的加载顺序。
  • Lua 文件:包含插件的主要逻辑。
  • XML 文件:可以包含插件的界面布局,大部分功能其实也能通过 Lua 实现。

在你的魔兽世界目录下找到 AddOns 目录,并创建一个新的文件夹,例如:/World of Warcraft/Interface/AddOns/HelloWorld,然后添加两个文件:

toc
## Interface: 110002
## Version: 1.0.0
## Title: Hello World
## Notes: 第一个插件
## Author: 你的名字

HelloWorld.lua
lua
print("Hello World")
代码解释

HelloWorld.toc 文件中包含两部分:

  • 第一部分是插件的基本信息(以 ## 开头的行),包含适用的游戏客户端版本、插件的版本号、名称、描述、作者等,可以在游戏内的插件管理界面看到这些信息。
  • 第二部分是插件的文件加载列表,客户端加载插件时,这些文件将按这里的顺序依次加载。
  • 关于 TOC 文件的语法和更多信息,详见 TOC 文件

HelloWorld.lua 文件中则仅包含一行,执行时会在聊天框输出 Hello World

提示

  1. TOC 文件的文件名必须和插件文件夹的名字相同,在上面的例子中为 HelloWorld
  2. TOC 文件第一行中的 110002 代表插件适配的游戏版本号。如果和游戏版本不一致,插件会被标记为过期,但实际能否运行则取决于具体的代码。

启动游戏,在插件列表界面中,就可以看到刚才新建的 Hello World 插件了。登录游戏时(或者使用 /reload 重载界面时),你会看到聊天框中输出了 Hello World

斜杠命令

信息

关于本节的更多信息,详见 创建斜杠命令

很多插件会为你的游戏客户端添加快捷的斜杠命令(就像常用的 /wa 等)。我们也修改 HelloWorld.lua,将登录游戏时输出的提示改为输入斜杠命令时运行。

lua
SlashCmdList["HELLOWORLD"] = function()
  print("Hello World")
end
SLASH_HELLOWORLD1 = "/helloworld"
SLASH_HELLOWORLD2 = "/hello"
代码解释

首先要为你的斜杠命令取一个全局的名称,一般为全大写字母。在本例中是 HELLOWORLD

接下来有两个步骤:

  • 在全局的 SlashCmdList 表中定义命令的行为。
    • 键为刚才选择的命令名称,值为命令的回调函数。
  • 创建全局变量,定义命令的文字(即聊天框中输入的内容)。
    • 全局变量名称以 SLASH_ 开头,后面跟上刚才选择的命令名称。
    • 同一个命令可以设置多个触发文字(就像 /wa/weakauras),只需要创建对应的多个全局变量,变量名后面跟上数字。

运行游戏(或重载界面)让插件生效。在聊天框中输入 /helloworld/hello,你会看到聊天框中输出了 Hello World

响应事件

信息

关于本节的更多信息,详见 事件处理

游戏中发生的几乎任何事情都是一个“事件”,插件往往会对一些事件做出响应。接下来修改 HelloWorld.lua,让插件能检测玩家开始和停止移动。

lua
local f = CreateFrame("Frame")
f:RegisterEvent("PLAYER_STARTED_MOVING")
f:RegisterEvent("PLAYER_STOPPED_MOVING")
f:SetScript("OnEvent", function(self, event, ...)
    if event == "PLAYER_STARTED_MOVING" then
      print("玩家开始移动了!")
    elseif event == "PLAYER_STOPPED_MOVING" then
      print("玩家停止移动了!")
    end
end)
代码解释

第 1 行创建了一个框架,存储于变量 f 中。魔兽世界的所有事件处理都需要依附于框架。

第 2 ~ 3 行,为框架 f 注册了两个事件:PLAYER_STARTED_MOVINGPLAYER_STOPPED_MOVING,分别表示玩家开始和停止移动。当这两个事件触发时,框架就会调用他的 OnEvent 脚本。

第 4 行之后,设置了框架 fOnEvent 脚本,根据触发事件的不同,在聊天框中输出不同的信息。

运行游戏(或重载界面)让插件生效。操控你的角色走两步,你会看到聊天框中输出的信息。

存储数据

信息

关于本节的更多信息,详见 存储数据

要让插件能长久存储数据(例如用户设置、插件状态等),需要在 TOC 文件中添加 SavedVariables 声明。这次我们还会给插件新建一个 Lua 文件,实现其他功能。

toc
## Interface: 110002
## Version: 1.0.0
## Title: Hello World
## Notes: 第一个插件
## Author: 你的名字
## SavedVariables: HelloWorldData

HelloWorld.lua
Counter.lua
lua
local f = CreateFrame("Frame")
f:RegisterEvent("ADDON_LOADED")
f:SetScript("OnEvent", function(self, event, addonName)
  if addonName == "HelloWorld" then
    HelloWorldData = HelloWorldData or {}
    HelloWorldData.sessions = (HelloWorldData.sessions or 0) + 1
    print("Hello World 插件已被加载 "..HelloWorldData.sessions.." 次!")
  end
end)
代码解释

在 TOC 文件中,我们新增了两行:

  • ## SavedVariables:声明了插件保存数据的名称,该名称对应的全局变量会在游戏退出时保存,并在下次启动时加载。
  • 最后一行表示插件在加载 HelloWorld.lua 后,加载第二个文件 Counter.lua

Counter.lua 文件中,我们像之前一样创建了一个框架,并为其注册了 ADDON_LOADED 事件。该事件会在任意插件加载完毕时触发,并将插件名称(文件夹的名字)作为第一个参数传入。

当一个插件加载完毕时,它的 SavedVariables 对应的全局变量就已经加载完毕了。在这次的事件处理函数中,我们用这个全局变量实现了一个每次 +1 的计数器。每当 HelloWorld 插件加载时,这个计数器就会增加 1,并存储于全局变量中。当退出游戏时,这个全局变量的值也会保存在游戏路径下的 WTF 文件夹中,以便下次启动时加载。

运行游戏(或重载界面)让插件生效,聊天框中会输出信息。每次重新登录游戏或重载界面,该计数器都会 +1。