KV3文件简介及DOTA2自定义音效制作

最近在做COTA的音效,进一步深入了kv3文件,kv3比起kv2还是比较好写,而且代码相对会简洁很多,而且,KV3可以很方便地转成json(因为格式太像了),如果我们想用啥现成的工具来管理kv3文件的话,只需要自己写一个简单的kv3-json转换器就可以了。

言归正传,首先来说一下kv3文件。

就目前来讲,dota2自定义游戏中使用到kv3文件的部分包括了 vmdl, vpcf, vsndevts,也就是模型、特效和音效文件,此外还有custom_net_tables.txt使用的也是kv3文件,更多的部分(例如npc文件夹的那些东西)能不能用kv3,我还没有尝试过,欢迎去试试。

1. KV3的语法格式

kv3是V社开发的特殊数据格式,非常像json,增加的功能是允许二进制编码,版本控制和数据注释等等,此外还有额外的语法支持,比如多行注释和多行字符串等。

1.1 文件头

每个KV3文件都需要一个文件头,里面包含了标识编码和格式的guid,对于大多数人来讲,只需要记住创建文件的时候复制粘贴这一行到文件头就可以了。

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->

1.2 语法

语法很简单,一个文件就足以说明所有问题

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
    boolValue = false // 布尔值
    intValue = 128 // 整数
    doubleValue = 64.000000 // 浮点数
    stringValue = "hello world" // 字符串
    stringThatIsAResourceReference = resource:"particles/items3_fx/star_emblem.vpcf" // 这个是带有resource flag前缀的特殊用法
    multiLineStringValue = """
First line of a multi-line string literal.
Second line of a multi-line string literal.
"""
// 多行字符串
    arrayValue =
    [
        1,
        2,
    ]
// 数组,注意各个元素之间有逗号
    objectValue =
    {
        n = 5
        s = "foo"
    }
// Object,注意各个元素之间没有逗号
/*
这是一个多行注释
*/
}

1.3 多行字符串的特殊说明

在kv3中写多行字符串,需要用三个括号开始,之后立马开始一个新行,在多行字符串结束之后,需要开始一个新行,之后写三个括号。这两个新行都是必须的。在这六个括号之间的所有字符,都会被直接读取,而不解析(也就是说\n之类的并不会被解释为换行。)

2. kv3自定义音效

dota2的自定义音效的使用需要两种类型的文件,一个是位于soundevents中的vsndevts kv3文件,一个是位于sounds文件夹中的音频文件(mp3和wav格式的音乐文件都是支持的,其他类型的文件没有测试)。音频文件就不说了,只要放着就可以了,在完成vsndevts的编辑之后,音频文件将会被自动编译成vsnd文件。
这里先放一个示例文件,再来细说:

<!-- kv3 encoding:text:version{e21c7f3c-8a33-41c5-9977-a76d3a32aa0d} format:generic:version{7412167c-06e9-4698-aff2-e63eb59037e7} -->
{
    Rock.ui_startup =
    {
        type = "dota_update_ui_startup"
        vsnd_files =
        [
            "sounds/ui_startup_01.vsnd",
            "sounds/ui_startup_02.vsnd",
        ]
        volume = "1.000000"
        weights =
        [
            "1",
            "1",
        ]
    }
}

只要这么定义之后,我们就可以在lua或者js文件中来使用EmitSound的各类API来使用 "Rock.ui_startup"来播放我们放在sounds文件夹中的ui_startup_01.mp3或者ui_startup_02.mp3了。

解释一下几个参数:
1、 type 声音的事件类型,这个事件是很重要的,目前所有可能的值包括

    dota_src1_2d // 2D音频
    dota_src1_3d // 3D音频

    battle_end_countdown // 战斗结束的倒数计时
    dota_gamestart_horn // 游戏开始的号角

    dota_update_vo_clamped_panning
    dota_update_vo_spatial_stereo
    dota_update_vo_switch
    dota_update_vo_default
    dota_update_vo_clamped
    dota_update_vo_announcer // 几种类型的voice

    dota_update_ganked_music
    dota_update_music_3layer
    dota_update_battle_music
    dota_update_battle_end
    dota_update_hero_select
    dota_update_default
    
    dota_update_killed
    dota_update_smoke
    dota_update_smoke_end
    dota_update_smoke_end_hero
    dota_update_roshan
    dota_update_roshan_end
    dota_music_respawn
    dota_update_countdown
    dota_update_opvar_track

    dota_music_stinger_stoptracks

    dota_ui_start_multi
    dota_ui_limit_time
    dota_update_ui_startup
    dota_update_ui_main
    dota_stop_loop_ui
    dota_voip

    dota_limit_speakers_ui
    dota_limit_speakers_inv
    dota_limit_speakers_spectui

我们一般来说只需要用到dota_src1_2d或者dota_src1_3d类型的音频就可以了,要记住的一点就是,如果你突然不知道要怎么定义了,就到官方的vsndevts文件中去搜索同样类型的文件,仿照着抄就可以了。

2、声音的属性定义

// 属性名 范例值 说明
soundlevel "81.000000" 声音强度
distance_max "2500.000000" 最大范围,3d音效使用

spread_radius "6000.000000" 扩展范围

rand_delay_min "1.000000" 随机开始延迟的最小和最大值
rand_delay_max "5.000000"

volume 0-1 声音的音量
volume_fade_in "1.500000" 淡入时间
volume_fade_out "1.500000" 淡出时间
volume_falloff_min "10.000000" 减弱距离
volume_falloff_max "1000.000000"
volume_rand_min "-0.149902" 随机的音量偏移的最小和最大值
volume_rand_max "0.149902"

pitch 0-1 音调,属性和音量类似

pitch_rand_min "-0.010000"
pitch_rand_max "0.010000"

vsnd_files "sounds/vo/announcer/announcer_now_select.vsnd" // 定义音乐文件,不管你的音乐是啥扩展名,一概写成vsnd就可以
vsnd_files 
    [
        "sounds/vo/announcer/announcer_now_select1.vsnd",
        "sounds/vo/announcer/announcer_now_select2.vsnd"
    ]

weights
    [
        1,
        1
    ]
// 随机在多个音乐之间选择一个,用weights来定义不同的文件的出现概率

start_point "2.000000"
end_point "9.000000"
restart_time "41.599998"
stop_at_time "40.000000"
// 循环播放的音频的起始点、结束点、重新开始的时间
 
position "[5545.06, 4998.54, 1494]"
// 定义播放的位置

// 下面的这些属性不常用,有兴趣的可以继续往下看
limiter_on
    0 1
limiter_event_name "ui.spect_pickup_in"
limiter_max "1.000000"
limiter_match_entity "0.000000"
limiter_match_type 0 1
limiter_match_substring "0.000000"
limiter_match_entity "1.000000"

memory_type 0

volume_remap_x1 "0.250000"
volume_remap_x2 "0.500000"
volume_remap_x3 "0.750000"
volume_remap_x4 "1.000000"
volume_remap_y1 "0.250000"
volume_remap_y2 "0.500000"
volume_remap_y3 "0.750000"
volume_remap_y4 "1.000000"

remap_vol_x1 "0.800000"
remap_vol_y1 "0.250000"
remap_vol_x2 "0.900000"
remap_vol_y2 "0.500000"
remap_vol_x3 "1.000000"
remap_vol_y3 "1.000000"
remap_vol_x4 "1.000000"
remap_vol_y4 "1.000000"

volume_move_vol "0.010000"
volume_move_vel "300.000000"
volume_move_filter_vel "1.000000"



pitch_remap_x1 "0.250000"
pitch_remap_x2 "0.500000"
pitch_remap_x3 "0.750000"
pitch_remap_x4 "1.000000"
pitch_remap_y1 "0.250000"
pitch_remap_y2 "0.500000"
pitch_remap_y3 "0.750000"
pitch_remap_y4 "1.000000"

remap_intensity_x1 "0.000000"
remap_intensity_y1 "1.000000"
remap_intensity_x2 "0.200000"
remap_intensity_y2 "1.000000"
remap_intensity_x3 "0.670000"
remap_intensity_y3 "1.000000"
remap_intensity_x4 "1.000000"
remap_intensity_y4 "0.500000"


track "explore2"
random_delay_opvar "laning_01_random_delay_opvar"


use_event_data
laning_master



mixgroup "HeroPick"
mixgroup "Weapons"
mixgroup "Stingers"
mixgroup "Ping"
mixgroup "All"
mixgroup "Ultimates"
mixgroup "Physics"
mixgroup "Ambient"
mixgroup "Creeps"

stops_others 0 or 1

block_name "ui_generic_button_click"
block_time "0.250000"
block_time2 "0.750000"
block_duration "1.500000"

soundevent_01 "ui_menu_fadeout"
soundevent_02 "ui_select_md"

use_01 "1.000000"
use_02 "1.000000"
use_03 "1.000000"



stop_entry_name "random_wheel_spin"

opvar_field_name "dota_random_wheel_speed"
opvar_stack_name "dota_opvars"
opvar_operator_name "opvars"



event_type
    0 1 2 3 4
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容