《魔女:终末旅途》的脚本语法速通
前言
教程目的
本教程系魔女:终末旅途游戏的脚本语法速通及知识速查,不对您进行任何知识完备性的保证,旨在以最快速度上手脚本以及Mod编写。
在开始之前:熟悉Google Sheet表格
在在线文档上,表格被划分为Data与Text两个表。
其中Text表由于只包含文本及其本地化信息,不在本文讨论范围内。
接下来我们重点关注Data表
观察以下卡牌表格范例:
| Id | Rarity | Expend | Tag | InitScript | DrawScript | UseScript | DropScript | Icon | Effects | Action |
|---|---|---|---|---|---|---|---|---|---|---|
| 唯一的标识 | 稀有度 | 消耗的费用 | 标签 | 卡牌初始化脚本(可以简单理解成,每时每刻都在执行,用于更新卡面信息) | 卡牌抽到后执行 | 卡牌使用后执行 | 卡牌进入弃牌堆后执行 | 图标资源的路径 | 特效(填入名称) | 动作(填入名称) |
| *1 | 1 | 1 | Vars["BaseScript"]="AttackCardItem";Vars["DesVal1"]=Self!=null?Self.DamageCalculate(5+int.Parse(Vars["CorAtk"])).ToString():(5+int.Parse(Vars["CorAtk"])).ToString(); | SetStatus("Target");Damage("5"); | Icon/buff/治愈光环 | slash | Attack |
命名规范:凡是列标题的后缀为Script,即为脚本,也即为我们本文将要讨论的内容。
特别地:物品的游戏内Id由两部分组成,表名+表内id。例如这张表的名字为card.csv,所列出卡牌的Id为*1,那么其游戏内Id为card_*1。对于Mod物品,Id规则为:Mod名+表名+Id名,例如TestMod_card_1
C#语法速通(基础篇)
变量与赋值
在脚本中,变量就像游戏中的背包格子,用于存储各种数据。使用=符号进行赋值操作:
// 基本格式:变量名 = 表达式;
DamageValue = 5; // 数字
CardName = "火球术"; // 文字(必须用双引号包裹)
IsActive = true; // 布尔值(true/false)
DrawCount = 1+2+3; // 表达式(等同于DrawCount = 6)
在脚本中,变量分为两种。内建变量与自定义变量。
其中自定义变量若是第一次出现,需要声明其类型进行定义。如int(整数), float(实数), string(字符串,即文本)。 如定义一个整数int DamageValue = 5;
内建变量则不能声明类型,直接调用即可。
游戏中常用内建变量:
Vars(字典),采用键值对的方法存储,其中键为查找索引,值为结果,访问方法为Vars["这里输入你要找的值"],其结果返回一个字符串(string),存着一切需要永久保存的变量。Self(StatusManager),是自定义类,一种包含了若干自定义类与基础类型的复合类型,用于指向效果执行者自己。Target(StatusManager),是自定义类,类型同Self,用于指向效果对象自己。(单选目标卡特供)
基础运算符
就像数学一样,运算符用于计算数值:
| 运算符 | 示例 | 说明 |
|---|---|---|
| + | 3 + 2 → 5 | 加法 |
| - | 5 - 1 → 4 | 减法 |
| * | 2 * 3 → 6 | 乘法 |
| / | 11 / 2 → 5, 11 / 2.0 → 5.5 | 除法(若两边为整数,则是整除) |
| % | 10 % 3 → 1 | 取余数(模运算) |
| ++ | x++ → x+1 | 自增1,等同于x=x+1 |
| > | 5 > 3 → true | 大于 |
| ! | !(5 > 3) → false | 逻辑非 |
| == | 1 == 1 -> true | 逻辑等于 |
| >= | 1 >= 1 -> true | 大于等于 |
运算符可以在表达式中使用,即在赋值的=后,或条件判断中
例子:
x = 1 + 1;(1 + 1为表达式)x = x + 1;(x + 1为表达式)if (a > 1)(a > 1为表达式)
条件判断(if)
就像游戏中的分支剧情,根据条件执行不同操作:
if (魔力值 > 10) {
释放大招();
}
else if (魔力值 > 5) {
释放普通技能();
}
else {
使用药剂();
}
特别地,分支还可以通过三目运算符实现,其格式为:
条件表达式 ? 真时表达式 : 假时表达式
例如将x的值设为a与b的较大值
x = a > b ? a : b
注意,不要使用嵌套三目!此时请用if语句代替。
方法调用
程序提供了一些现成功能,直接调用即可实现预设功能:
// 基础格式:方法名(参数);
Damage("15"); // 造成15点伤害
DrawCount("20"); // 抽20张牌
AddBuff("buff_burn", "-10", "3"); // 添加3层无限时间的燃烧状态(附:-10被规定为 BUFF的无限时长)
常见游戏方法:
Damage(数值):造成伤害ChangeHp(数值):数值 >0 时治疗目标, < 0 时造成真实伤害AddBuff(状态名, 持续时间, 层数):添加Buff- DrawCount(数量):抽卡
特别地,一些方法名会连接在变量后面,例如15.ToString(),返回值为"15"(字符串类型的15),这是因为作为int类型,拥有ToString()作为成员方法。
这时即可调用x.ToString()(即在任意结果为整型的表达式后加.,效果如上的方法调用,可以理解成变量.方法名是其完整方法名。)
实战解析
让我们一起解构初始示例中的复杂脚本:
// InitScript
// 第一部分:设置基础卡牌类型
Vars["BaseScript"] = "AttackCardItem";
// 第二部分:动态计算应该显示在卡面上的伤害值
Vars["DesVal1"] =
// 如果卡牌存在(非空检查)
Self != null ?
// 计算伤害:5 + CorAtk变量值
Self.DamageCalculate(5 + int.Parse(Vars["CorAtk"])).ToString() // 调用Self变量中的DamageCalculate方法计算伤害值,调用int.Parse方法转换类型,调用ToString方法转换类型
:
// 备用计算(战斗外时)
(5 + int.Parse(Vars["CorAtk"])).ToString();
// UseScript
SetStatus("Target");
Damage("5");
要点:
int.Parse():将文本转换为数字(如"3"→3)ToString():将数字转为文本(如8→"8")三元运算符:条件 ? 真时结果 : 假时结果- 通过键值对访问
Vars字典,如访问键为DesVal1的值,将其变更为表达式的值。 Vars["CorAtk"]所存值为攻击的值增幅,仅接受例如“卡牌的数字+1”等特殊加成。
脚本编写安全指南
结尾分号:每个完整代码结尾必须加;
Damage("5"); // 正确
Damage("5") // 错误(缺少分号)
如若初始示例中的脚本,因为代码语义未尽,赋值格式:变量名 = 表达式的表达式未在一行中写全,则无需添加;
括号匹配:确保{}和()成对出现
if (x > y {} // 错误,缺少 )
if (x > y) { // 错误, 缺少}
if (x > y) 单行语句; // 正确
if (x > y)
{
语句1;
语句2;
} // 正确
实用模板
其中【】需要自填,不保留括号,记得删注释。
攻击卡模板
// InitScript
Vars["BaseScript"]="AttackCardItem";// 注: AttackCardItem为单选目标卡, CommonCardItem为不选目标卡。
AddDescription("1", "Damage", "【基础伤害】")
// UseScript
SetStatus("Target");// 设定接下来的效果对象为所选目标
Damage("【基础伤害】", "【伤害类型】");// 伤害类型不填则默认为Normal 普通伤害。 其余可选True 真实伤害
防御卡模板
// InitScript
Vars["BaseScript"]="CommonCardItem";
AddDescription("1", "Defence", "【基础防御】")
// UseScript
SetStatus("Target");// 设定接下来的效果对象为所选目标
ChangeDefence("【基础防御】");
治疗卡模板
// InitScript
Vars["BaseScript"]="CommonCardItem";
AddDescription("1", "Hp", "【治疗量】")
// UseScript
SetStatus("Self");// 设定接下来的效果对象为自己
ChangeHp("【治疗量】");
状态卡模板
// InitScript
Vars["BaseScript"]="AttackCardItem";
AddDescription("1", "Buff", "【Buff层数】")
// UseScript
SetStatus("Target");// 设定接下来的效果对象为所选目标
AddBuff("【Id】", "【持续时间】", "【层数】");
下一步行动
尝试修改
在测试环境中尝试修改示例数值(在/StreamingAssets/Data/Card/card.csv中)
// 将原脚本的5改为8
Damage(5); → Damage(8);
检查修改
打开游戏,等待加载完成。查看初始卡组的卡牌是否已经被修改。(记得新开游戏)
尝试添加卡牌
在测试环境中尝试添加卡牌(在/StreamingAssets/Data/Card/card.csv中)
id为testcard,其余配置仿照修改后的card_*1, 并额外添加如下效果:
打出时,抽一张卡。
别忘了修改Text表与其描述!
然后在游戏中使用控制台!输入give card card_testcard,查看是否获取了卡牌!
尝试自己编写效果
结合上述两步以及卡牌模板,编辑出如下效果
对对方造成5点伤害。若对方生命值 > 50%,则抽一张卡
提示:Target.MaxHp 为目标最大生命值,Target.CurHp为对方当前生命值。
Target与Self类型一样,其可访问的属性也一样!
查阅手册
已经成功?查阅《API速查手册》,开始你的脚本编写之旅!

浙公网安备 33010602011771号