设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 22239|回复: 72
打印 上一主题 下一主题

[原创发布] [MV/MZ]ULDS无限图层插件使用详解 (2025-07-14更新+范例v4)

  [复制链接]

Lv4.逐梦者

梦石
0
星屑
6422
在线时间
800 小时
注册时间
2021-8-28
帖子
89
跳转到指定楼层
1
发表于 2022-4-24 23:24:39 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
本帖最后由 Rose_shadows 于 2025-7-17 15:04 编辑

taroxd大佬的ULDS无限图层插件具有非常强大的图层功能,允许开发者在地图上叠加无限的视差图层。但相信不少人在研究插件的时候都曾为插件帮助中不甚详尽的说明绞尽脑汁……
现在论坛上似乎还没有系统的ULDS教程,为了能让更多的新人小白感受到这个插件的魅力,我以我对ULDS浅薄的认识写了这样一篇教程。
与此同时,诚邀各路大神一起解决该教程中的问题,弥补该教程中的缺憾。

2025-07-14 ULDS简易范例更新至v4.00(蓝奏云):
https://wwll.lanzout.com/iriaC3110uub
修改了ULDS插件,新增截取源图像的一部分作为图片图像的功能,并添加了对应的范例,初步整理了范例项目和插件帮助内容,更新 ReadMe 文件

旧版本范例


注意!

从版本v4.00的范例开始,范例中包含的插件将是添加了新功能的修改版插件
若要获取原版插件,请访问:
https://blog.taroxd.com/mvmz-plugins/ULDS.html



该教程将依次讲述以下6个模块,后续也许还会更新:

1. 地图注释(基础)
2. 地图注释(高级)
3. 地图注释例子
※. 新功能:只显示指定图片的一小块图像 (2025-07-14更新)
4. 设置碰撞体积
5. 技巧
     •关于相对地图远景
     •关于动态帧图层
        ├ 方式1:搭配事件+变量实现
        └ 方式2:使用"frame"参数实现 (2025-07-14更新)
     •关于简易光源 (2022-12-09更新)
        ├ 简易圆形光源
        └ 简易手电筒
     •关于淡入淡出 (2023-07-27更新)
        ├ 立即淡入淡出
        ├ 与开关相联的淡入/淡出(仅能同时实现一种)
        └ 与开关相联的自由淡入淡出(两种皆可实现)
     •关于遮罩房间 (2023-08-04更新)
     •(或许以后还会更新...)

---------------------------------------------------------------------
=== ULDS插件使用说明 ===

ULDS插件通过配置地图注释来实现图层功能。

== 1. 地图注释(基础) ==
在地图注释中按以下格式书写:

<ulds> {
    参数1: 值1,
    参数2: 值2,
    ......
    参数n: 值n
} </ulds>

<ulds>和</ulds>之间要以 JSON 格式书写。请自行学习JSON格式如何书写。

其中,必须有的参数是:

"name": 图片名称。

"x": 图片的x坐标。x坐标越大,图片越靠右。
     若为 纯数字 ,则表示以 屏幕左上角 为原点的图片x坐标。图片横向位置始终与屏幕保持一致。
     若为 this.rx(n) ,则表示以 地图左上角 为原点的图片x坐标。
     n 可以是以下2种情况:
       - 若n为 数字,则表示以 地图左上角 为原点的图片x坐标,且x坐标为 n 。
         例如 this.rx(48) 指的是图片会贴在地图x坐标为 48 像素的位置。
       - 若n为 t ,则图片将会被从左向右滚动播放。
         如果是 -t ,则图片会被从右向左滚动播放。

"y": 图片的y坐标。y坐标越大,图片越靠下。
     若为 纯数字 ,则表示以 屏幕左上角 为原点的图片y坐标。图片纵向位置始终与屏幕保持一致。
     若为 this.ry(n) ,则表示以 地图左上角 为原点的图片y坐标。
     n 可以是以下2种情况:
       - 若n为 数字,则表示以 地图左上角 为原点的图片y坐标,且y坐标为 n 。
         例如 this.ry(48) 指的是图片会贴在地图y坐标为 48 像素的位置。
       - 若n为 t ,则图片将会被从上到下滚动播放。
         如果是 -t ,则图片会被从下向上滚动播放。

其他可供选择的基础参数有:

"z": 图片的z层级。默认是0.5(可在插件参数中设置)。小数点可精确至后两位。建议大于1,且为浮点数,这样设置可以最大程度地兼容其他涉及图层的插件(如灯光插件等)。
     指定图片可以覆盖在z层级小于该图片z层级的所有图片之上。
     例如,若指定A图片z层级为6,B图片z层级为10,则A图片会覆盖所有z层级低于6的贴图,但会被B图片覆盖。
     RMMV中各贴图的原生层级:0 -> 远景,3 -> 玩家/事件,4 -> 星标图块,7 -> 气泡,8 -> 动画,10 -> 目的地光标。

"path": 自定义图片所在的文件夹。文件夹必须在img文件夹里。默认是parallaxes(插件参数中可配置)

"loop": true/false
        是否循环播放图片。

还有一些参数,需要开发人员对Sprite类, Bitmap类属性具有初步的认识:
(不过本人已将常用参数全部列在下方了,即便不懂脚本的小伙伴们应该也可以看懂)

"smooth": true/false
          是否应用平滑缩放。

"blendMode": 图片的混合模式。默认是0(正常)。
             RMMV原生混合模式:0 -> 正常,1 -> 叠加,2 -> 正片叠底,
             3 -> 滤色

"opacity": 图片的不透明度。0-255间的一个数字。默认是255(完全不透明)。

"rotation": 图片的旋转角度(弧度)。数字 兀 在JS中是 Math.PI 。

"scale.x": 图片被横向缩放的倍数。默认是1(不放大)。可以是小数。
           如果是负数,图片就会被左右镜像翻转。

"scale.y": 图片被纵向缩放的倍数。默认是1(不放大)。可以是小数。
           如果是负数,图片就会被上下镜像翻转。

"visible": true/false
           图片是否可见。



== 2. 地图注释(高级) ==

上面模块讲的是地图注释的基本格式。这一模块将会讲到该插件的一些高级用法和提供的一些引用。


无限图层的设置在游玩时是即时动态更新的。
所以在地图注释中,可以调用$gameSwitches和$gameVariables等脚本的值来实时控制图片的状态。

例如:

· 参数"visible"可以这样写:
  "visible": "$gameSwitches.value(2)"
  - 这表示由开关#2来实时控制图片的显示与隐藏。

· 参数"rotation"可以这样写:
  "rotation": "$gameVariables.value(1)*Math.PI"
  - 这表示由变量#1来控制图片的旋转角度。变量#1最好是介于0到2的数字。

当然,以此类推,其他插件提供的脚本变量/开关也可以使用。


也许各位会觉得每次写$gameVariables, $gameSwitches什么的太麻烦了,还容易写错,
那么可以考虑使用插件作者提供的引用:s 和 v 来代替开关和变量。

仍以上面举过的两个例子为例:

· 参数"visible"可以这样写:
  "visible": "s.value(2)"
  - 这表示由开关#2来实时控制图片的显示与隐藏。

· 参数"rotation"可以这样写:
  "rotation": "v.value(1)*Math.PI"
  - 这表示由变量#1来控制图片的旋转角度。变量#1最好是介于0到2的数字。

除了 s, v 这两个引用之外,插件作者还提供了一个引用。
还记得前面提到的 this.rx(t) 吗?
其中的 t 也是一个引用。t 代表每帧都会自增(自己+1)的一个数字。初始值是0。

一个地图中可以添加多个注释。利用z层级来控制各图层的叠加情况,就可以非常灵活地制作视差地图了!



== 3. 例子 ==

<ulds> {
    "name": "BlueSky",
    "x": "this.rx(t)",
    "y": 50,
    "z": 10.5,
    "loop": true,
    "scale.x": -1,
    "visible": "s.value(3)"
} </ulds>
  - 在地图中使用位于img/parallaxes/中的BlueSky.png图片。
    该图片Z层级是10.5,在横向位置上以正常速度(1帧1像素)从左向右循环自滚动,在纵向位置上相对于屏幕的y坐标为50,图片被左右镜像反转,由开关#3控制显示和隐藏。

<ulds> {
    "name": "Night",
    "path": "pictures",
    "x": "this.rx(48)",
    "y": "this.ry(48)",
    "z": 20,
    "visible": "s.value(5)",
    "scale.x": "v.value(2)",
    "scale.y": "v.value(2)",
    "blendMode": 2,
    "rotation": "Math.PI"
} </ulds>
  - 在地图中使用位于img/pictures/中的Night.png图片。
    该图片Z层级是20,相对于地图的坐标为(48, 48),由开关#5控制显示和隐藏,
    横纵向缩放的倍数是变量#2的值,混合模式是正片叠底,以图片左上角为锚点,旋转180°。



== 新功能 == 2025-07-14更新

这一版插件在原版基础上添加了新的功能,允许开发人员截取一张图中的一部分用作图片的图像。这样就可以把许多小摆件整合到同一张图片上调取。

在注释中添加如下参数:

"frame": "{x: x坐标, y: y坐标, w: 宽度, h: 高度}"

x坐标、y坐标、宽度、高度的单位均为*像素*。
(x坐标, y坐标) 是开始截取图片的位置坐标,宽度和高度指的是要截取的图像的宽高。
例如:

<ulds> {
    "name": "Inside_C",
    "path": "tilesets",
    "x": "this.rx(100)",
    "y": "this.ry(50)",
    "z": 4,
    "frame": "{x: 240, y: 240, w: 48, h: 48}"
} </ulds>
- 在地图中使用位于 img/tilesets/ 中的 Inside_C.png 图像作为源图像。
  以源图像左上角为原点,从 (240, 240) 处截取宽高各为 48 的图像用作要显示的部分,并将图片放在相对于地图 (100, 50) 的位置处。该图片Z层级是4。

这样,地图上就会出现一盘炒饭。

如果小摆件的尺寸和摆放方式、源图像的大小恰好和图块组中B、C、D、E类型图块图片一模一样,那么 frame 参数的值也可以这样写:

"frame": "{tx: x坐标, ty: y坐标, tw: 宽度, th: 高度}"

此时:
x坐标 - 截取部分最左上角的图块是从左往右数第几块图块。
y坐标 - 截取部分最左上角的图块是从上往下数第几块图块。
宽度 - 截取部分的宽度相当于几块图块。省略时默认为 1。
高度 - 截取部分的高度相当于几块图块。省略时默认为 1。
例如:

<ulds> {
    "name": "Inside_C",
    "path": "tilesets",
    "x": "this.rx(100)",
    "y": "this.ry(50)",
    "z": 4,
    "frame": "{tx: 6, ty: 6}"
} </ulds>
- 效果同上一个注释。地图上会出现一盘炒饭。

<ulds> {
    "name": "Inside_C",
    "path": "tilesets",
    "x": "this.rx(100)",
    "y": "this.ry(50)",
    "z": 4,
    "frame": "{tx: 13, ty: 6, tw: 1, th: 2}"
} </ulds>
- 地图上会出现一尊士兵雕像。

注意,"frame"参数对"loop"参数为true的图片无效。



== 4. 设置碰撞体积 ==

ULDS插件本身不提供碰撞体积功能。

默认情况下,在地图的图块组 A组 中随意寻找 可通行图块 和 不可通行图块 各一种,
然后根据所使用的图层直接在RMMV地图编辑器中绘制相应可通行/不可通行区域即可。

似乎也可以使用与该插件同作者的RegionPassage.js,用区域来设置相应可通行/不可通行区域。

如果有更为细微的需求(例如半格或不规则碰撞体积),也可以找找别的插件。
例如QM+CollisionMap.js及其前置插件QMovement.js,允许你进行像素级移动,
并通过检查一张图片的颜色来设定通行设置。
图片白色和透明部分是可通行的地方,其他颜色不可通行。



== 5. 技巧 ==

可以先稍微熟悉一下以上四个模块的内容,再来看这一模块。


= 关于相对地图远景 =

设想情景:玩家正行走在一处山峰中。山峰会随着玩家的走动而移动。
表现形式:距离镜头近的山峰移动速度快。距离镜头远的山峰(背景)移动速度慢。
核心问题:解决不同山峰贴图的不同移动速度问题。
解决方法:在原来注释的基础上,只给各个贴图相应的注释参数"x"和"y"值乘一个PARAM即可:
         (比如如果贴图原先位于相对于地图的(0, 0)处,就做出如下改动:)
            "x": "this.rx(0)*PARAM",
            "y": "this.ry(0)*PARAM",
         其中,PARAM 是一个数字。
       - 对于 距离镜头近 的贴图:PARAM 最好是一个1以上的数字。
         数字越大,贴图随玩家移动的速度越快,所演绎的贴图与镜头的距离就越近。
         记得将z层级设为4以上。
       - 对于 距离镜头远 的贴图:PARAM 最好是一个0到1之间的小数。
         小数越小,贴图随玩家移动的速度越慢,所演绎的贴图与镜头的距离就越远。
         记得将z层级设为3以下。


= 关于动态帧图层 =

设想情景:玩家走到一处风景宜人的桃源乡暂且歇脚。湖泊中流水潺潺,好一幅生机勃勃之景。
表现形式:用多帧图层来表现动态的湖水。
核心问题:如何按照指定帧数依次显示湖水的各个图层。
解决方法:(1) 辅助事件&变量 [3张图片, 3条注释]
         假设图层相对于地图位于(144, 144),共有3帧(湖泊_1, 湖泊_2, 湖泊_3),
         则创建以以下格式书写的地图注释:
<ulds> {
    "name": "湖泊_1",
    "x": "this.rx(144)",
    "y": "this.ry(144)",
    "z": 1.5,
    "visible": "v.value(10) === 0"
} </ulds>
<ulds> {
    "name": "湖泊_2",
    "x": "this.rx(144)",
    "y": "this.ry(144)",
    "z": 1.5,
    "visible": "v.value(10) === 1"
} </ulds>
<ulds> {
    "name": "湖泊_3",
    "x": "this.rx(144)",
    "y": "this.ry(144)",
    "z": 1.5,
    "visible": "v.value(10) === 2"
} </ulds>
       在这个例子中,属性"visible"中的条件占用了变量#10。
       如果想替换为别的变量,直接将所有出现的"10"替换为所使用的变量ID即可。
       随后,在地图上创建一个并行处理的事件,内容如下:
           ◆等待:n 帧
           ◆变量操作:#0010 = 1
           ◆等待:n 帧
           ◆变量操作:#0010 = 2
           ◆等待:n 帧
           ◆变量操作:#0010 = 0
       n 是图层的帧间隔。

         (2) 使用"frame"参数 [1张*从左到右*摆放动画帧图片, 1条注释]
         假设图层相对于地图位于(144, 144),使用 Water_Animated.png 作为图像,
         图片中动画共有3帧,每帧间隔20帧 (1/3秒),
         图片动画帧*从左到右*摆放,且要*循环播放*,
         则创建以以下格式书写的地图注释:
<ulds>{
    "name": "Water_Animated",
    "x": "this.rx(144)",
    "y": "this.ry(144)",
    "z": 1,
    "frame": "{y: 0, w: 96, h: 96, x: (function(){var frameCount = 3; var frameInverval = 20; var size = 96; var isCharAnime = false; var result=0;var f=Math.floor(t/frameInverval);var realFrameCount=isCharAnime?(frameCount-1)*2:frameCount;var currentFrameUnderTurn=Math.floor(f%realFrameCount);if(isCharAnime){if(currentFrameUnderTurn<frameCount){result=currentFrameUnderTurn*size;}else{result=(realFrameCount-currentFrameUnderTurn)*size;}}else{result=currentFrameUnderTurn*size;}return result;})()}"
}</ulds>
         "frame"的用法详见 “== 新功能 ==” 部分。
         在这个例子中,w 和 h 分别为一帧动画的宽高,
         frameCount 指的是图片中包含几帧动画,frameInverval 是帧间隔。
         size 则应该等于 w,即一帧动画的宽度。

         isCharAnime 控制播放方式。
         当图片中的动画帧这样摆放:[1][2][3]
         如果将 isCharAnime 设为 false (如上例),那么播放方式为:
         > [1][2][3][1][2][3][1][2]...
         如果将 isCharAnime 设为 true,播放方式则为:
         > [1][2][3][2][1][2][3][2][1][2]...

         ※ 同样的例子,
         如果动画图片中的动画帧是*从上到下*摆放的,
         那么将 frame 参数中的 y 和 x 的位置交换,再将 size 改为 h 的值(一帧动画的高度)就可以了。
         即:
         "frame": "{x: 0, w: 96, h: 96, y: (function(){var frameCount = 3; var frameInverval = 20; var size = 96; var isCharAnime = false; var result=0;var f=Math.floor(t/frameInverval);var realFrameCount=isCharAnime?(frameCount-1)*2:frameCount;var currentFrameUnderTurn=Math.floor(f%realFrameCount);if(isCharAnime){if(currentFrameUnderTurn<frameCount){result=currentFrameUnderTurn*size;}else{result=(realFrameCount-currentFrameUnderTurn)*size;}}else{result=currentFrameUnderTurn*size;}return result;})()}"


= 关于简易光源 = 2022-12-09更新

设想情景:玩家/跟随者/事件在黑暗中行走,只有柔和的光源相伴左右,营造出一种静谧的氛围。

注意,这一例子主要是讲解将图片绑定在玩家/跟随者/事件上的方法和介绍图片锚点属性。
这一部分所制作的光源一个地图只能使用一张,局限性非常大,如果有需求的话还是要使用插件。
不过通过将图片绑定在玩家/跟随者/事件上与动态帧图层方法结合起来,可以制作类似角色行走图特效等的效果。

0.光源图片的配置

这一部分所要用到的光源图片并非一张简单的有色光源图片,而是背景为纯黑色,只有中心部分镂空作为光源的一张图片。
图片的尺寸下限以游戏分辨率为准。一格默认为48像素x48像素,如果分辨率为17格x13格(816像素x624像素),那么图片的大小至少应当是(17x2-1)格x(13x2-1)格,即1584像素x1200像素。
在这一情况下,考虑到图片文件的大小,可以适当缩小图片,使用时设置"scale.x"和"scale.y"属性调整缩放值即可。

在此提供两张用于816x624分辨率下游戏的光源图片。使用时需要将"scale.x"和"scale.y"属性均设为2。建议将"opacity"设为225。
light_816x624.zip (13.19 KB, 下载次数: 83)

1.简易圆形光源 (烛光)

表现形式:以玩家/跟随者/事件为中心,周身环绕着圆形的光源。
核心问题:如何将圆形光源图片绑定在玩家/跟随者/事件身上。
解决方法:假设圆形光源图片名为 light.png ,为了将图片绑定到*玩家*身上,
         则创建以以下格式书写的地图注释:
          <ulds> {
               "name": "light",
               "x": "this.rx(($gamePlayer._realX+1/2)*$gameMap.tileWidth())",
               "y": "this.ry(($gamePlayer._realY+1/2)*$gameMap.tileHeight())",
               "z": 5,
               "anchor.x": 0.5,
               "anchor.y": 0.5,
               "visible": "v.value(11) == 1"
          } </ulds>
       将变量#11的值设为1时图片就会显现出来。

       其中,"anchor.x"和"anchor.y"属性是指图片的锚点。锚点的位置将会影响图片的旋转和缩放效果。
       锚点在左上角时"anchor.x"和"anchor.y"分别为0, 0,在中央时分别为0.5, 0.5,在右下角时分别为1, 1,以此类推。

       ※如果想将光源图片绑定到*跟随者*上的话,就将"x""y"属性中的$gamePlayer替换成$gamePlayer.followers().visibleFollowers()[INDEX]。INDEX从零开始计数,第一个跟随者(地图上玩家身后的角色)索引是0。
       ※如果想将光源图片绑定到*事件*上的话,就将"x""y"属性中的$gamePlayer替换成$gameMap.event(EVENT_ID)。EVENT_ID是事件ID。

2.简易手电筒

表现形式:手电筒的光源将会永远朝向玩家/跟随者/事件的正前方。
核心问题:如何让手电筒光源图片的旋转角度与玩家的朝向相关联。
解决方法:假设手电筒光源图片名为flashlight.png,图片中手电筒光源朝下,为了将图片绑定到*玩家*身上,
         则创建以以下格式书写的地图注释:
          <ulds> {
               "name": "flashlight",
               "x": "this.rx(($gamePlayer._realX+1/2)*$gameMap.tileWidth())",
               "y": "this.ry(($gamePlayer._realY+1/2)*$gameMap.tileHeight())",
               "z": 5,
               "anchor.x": 0.5,
               "anchor.y": 0.5,
               "visible": "v.value(11) == 2",
               "rotation": "(function(){var obj = $gamePlayer;if(obj.direction()==2) return 0;if(obj.direction()==4) return 1/2*Math.PI;if(obj.direction()==8) return Math.PI;if(obj.direction()==6) return -1/2*Math.PI;})()"
          } </ulds>
       将变量#11的值设为2时图片就会显现出来。

对于将手电筒光源图片绑定到跟随者/事件上的方法,参见 1.简易圆形光源 (烛光) 部分。记得将"rotation"属性值中的$gamePlayer也替换掉。


= 关于淡入淡出 = 2023-07-27更新

1. 立即淡入淡出

设想情景:玩家甫一进入洋馆客房,房间墙壁和地毯上竟慢慢浮现出大块大块狰狞的暗褐色污渍。
表现形式:玩家进入地图时,血迹贴图渐渐由透明变为不透明(淡入)。
核心问题:如何使血迹贴图的不透明度随时间推移而增大。
解决方法:假设血液贴图的名称为 blood.png ,以图片左上角为锚点,贴图位于 (123, 456),需要在 1.5s 内显现,
         则创建以以下格式书写的地图注释:
          <ulds> {
               "name": "blood",
               "x": "this.rx(123)",
               "y": "this.ry(456)",
               "z": 3.5,
               "opacity": "(function(){var duration=1.5;var f=duration*60;var val=255/f;if(t<f){return t*val;}else{return 255;}})()"
          } </ulds>
       如果想自定义时长,可以将参数 opacity 中的变量 duration 的值从 1.5 改成别的数。

       ※ 如果要表现玩家一进入洋馆客房,墙壁上狰狞的暗褐色污渍渐渐淡去(淡出),则创建以以下格式书写的地图注释:
          <ulds> {
               "name": "blood",
               "x": "this.rx(123)",
               "y": "this.ry(456)",
               "z": 3.5,
               "opacity": "(function(){var duration=1.5;var f=duration*60;var val=255/f;if(t<f){return 255-t*val;}else{return 0;}})()"
          } </ulds>
       如果想自定义时长,可以将参数 opacity 中的变量 duration 的值从 1.5 改成别的数。

2. 与开关相联的淡入/淡出(仅能同时实现一种)

设想情景:玩家最终找到了真相,在幻象消失之际,怨魂渐渐现身。
表现形式:打开指定开关后,怨魂贴图渐渐由透明变为不透明(淡入)。
核心问题:如何在等到指定开关打开后,相关贴图的不透明度随时间推移而增大。
解决方法:假设怨魂贴图的名称为 phantom.png ,以图片左上角为锚点,贴图位于 (123, 456),需要在 1.5s 内消失,
         则创建以以下格式书写的地图注释:
         <ulds> {
               "name": "phantom",
               "x": "this.rx(123)",
               "y": "this.ry(456)",
               "z": 3.5,
               "opacity": "(function(){var duration=1.5;var sId_show=20;var sId_prevent=21;var vId=13;var f=duration*60;var val=255/f;if(s.value(sId_show)){if(!v.value(vId)){v.setValue(vId, t);};var rt=t-v.value(vId);if(!s.value(sId_prevent)&&(rt<f)){return rt*val;}else{return 225;};}else{return 0;};})()"
          } </ulds>
      !注意!这个注释占用了两个开关(#20, #21)和一个变量(#13)。
      开关#20打开时,贴图就会慢慢显现。变量#13存储开关#20打开时 t 的值,用以与之后的 t 进行比较。开关#21是为了防止每次进入地图时贴图都会显现一次。
      所以在执行淡入时,可以设置事件:
        ◆开关操作:#0020 = ON
        ◆等待:90帧
        ◆开关操作:#0021 = ON
        90帧 = 1.5s,即所设置的淡入时长。必须先打开用于显现图片的开关(#20),等待所设置的淡入时长后,再打开防止贴图重新显现的开关(#21)。
      如果想再次执行淡入,在进入地图之前将两个开关关掉,再在进入地图后将两个开关按如上设置打开即可。
      如果想自定义开关ID和变量ID,可以将参数 opacity 中的 sId_show 的值从 20 改成别的开关ID用以显示贴图,sId_prevent 用于防止贴图重新显现,vId 的值从 13 改为别的变量ID。
      如果想自定义时长,可以将参数 opacity 中的变量 duration 的值从 1.5 改成别的数,单位秒。在事件中,记得打开两个开关之间等待的时长要和这里的值换算成帧数的最终结果相同。

      ※ 如果要表现幻象渐渐消失,整个洋馆终于露出了它真实的样子(淡出),则创建以以下格式书写的地图注释:
          <ulds> {
               "name": "phantom",
               "x": "this.rx(123)",
               "y": "this.ry(456)",
               "z": 3.5,
               "opacity": "(function(){var duration=1.5;var sId_show=20;var sId_prevent=21;var vId=13;var f=duration*60;var val=255/f;if(s.value(sId_show)){if(!v.value(vId)){v.setValue(vId, t);};var rt=t-v.value(vId);if(!s.value(sId_prevent)&&(rt<f)){return 255-rt*val;}else{return 0;};}else{return 255;};})()"
          } </ulds>
      !注意!这个注释占用了两个开关(#20, #21)和一个变量(#13)。
      开关#20打开时,贴图就会慢慢消失。变量#13存储开关#20打开时 t 的值,用以与之后的 t 进行比较。开关#21是为了防止每次进入地图时贴图都会消失一次。
      所以在执行淡出时,可以设置事件:
        ◆开关操作:#0020 = ON
        ◆等待:90帧
        ◆开关操作:#0021 = ON
        90帧 = 1.5s,即所设置的淡出时长。必须先打开用于淡出图片的开关(#20),等待所设置的淡出时长后,再打开防止贴图重新消失的开关(#21)。
      如果想再次执行淡出,在进入地图之前将两个开关关掉,再在进入地图后将两个开关按如上设置打开即可。
      如果想自定义开关ID和变量ID,可以将参数 opacity 中的 sId_show 的值从 20 改成别的开关ID用以淡出贴图,sId_prevent 用于防止贴图重新消失,vId 的值从 13 改为别的变量ID。
      如果想自定义时长,可以将参数 opacity 中的变量 duration 的值从 1.5 改成别的数,单位秒。在事件中,记得打开两个开关之间等待的时长要和这里的值换算成帧数的最终结果相同。

3. 与开关相关联的自由淡入淡出(两种皆可实现)

设想情景:临近傍晚时分,街上的路灯一盏盏亮起;而至次日黎明,又会一盏盏暗去。
表现形式:打开用于淡入的开关后,路灯灯光贴图渐渐由透明变为不透明;打开用于淡出的开关后,路灯灯光贴图渐渐由不透明变为透明。
核心问题:如何将用于淡入的开关和用于淡出的开关同时绑定到灯光贴图上。
解决方法:假设路灯灯光贴图的名称为 streetlight.png,以图片左上角为锚点,贴图位于 (123, 456),淡入淡出时长为 1.5s,
则创建以以下格式书写的地图注释:
         <ulds> {
               "name": "streetlight",
               "x": "this.rx(123)",
               "y": "this.ry(456)",
               "z": 3.5,
               "opacity": "(function(){var duration=1.5;var init_opacity=0;var sId_show=4;var sId_hide=5;var sId_prevent=20;var vId_target=15;var vId_opacity=16;var f=duration*60;var val=255/f;if(!v.value(vId_opacity)){v.setValue(vId_opacity,0);}if(s.value(sId_show)){v.setValue(vId_target,255);}else if(s.value(sId_hide)){v.setValue(vId_target,0);}var result=v.value(vId_target)==255?Math.min(v.value(vId_target),v.value(vId_opacity)+val):Math.max(v.value(vId_target),v.value(vId_opacity)-val);if((s.value(sId_show)||s.value(sId_hide))&&s.value(sId_prevent)){result=v.value(vId_target);}v.setValue(vId_opacity,result);return result||init_opacity;})()"
          } </ulds>
      !注意!这个注释占用了三个开关(#4, #5, #20)和两个变量(#15, #16)。
      变量#15存储贴图的目标不透明度(0或255),变量#16存储贴图的当前不透明度,是动态变化的。这两个变量均只读。
      开关#4是淡入贴图的开关,开关#5是淡出贴图的开关,开关#20是为了防止每次进入地图时贴图都会消失一次的开关。
      在执行淡入时,可以设置事件:
        ◆开关操作:#0020 防止每次淡入淡出 = OFF
        ◆开关操作:#0005 开始淡出 = OFF
        ◆开关操作:#0004 开始淡入 = ON
        ◆等待:90帧
        ◆开关操作:#0020 防止每次淡入淡出 = ON
      在执行淡出时,可以设置事件:
        ◆开关操作:#0020 防止每次淡入淡出 = OFF
        ◆开关操作:#0004 开始淡入 = OFF
        ◆开关操作:#0005 开始淡出 = ON
        ◆等待:90帧
        ◆开关操作:#0020 防止每次淡入淡出 = ON
      90帧 = 1.5s,即所设置的淡入淡出时长。
      注意,如果淡入淡出前没有关掉防止每次淡入淡出的开关#20,那么就无法淡入淡出。
      在参数opacity的参数值中,sId_show 是淡入贴图的开关ID,sId_hide 是淡出贴图的开关ID,sId_prevent 是防止再次淡入淡出的开关ID,
      vId_target 是存储贴图的目标不透明度的变量ID,vId_opacity 是存储贴图的当前不透明度的变量ID,
      最开始的 duration 是淡入淡出时长,单位秒;init_opacity 是贴图的初始不透明度。


= 关于遮罩房间 = 2023-08-04更新

设想情景:玩家只能看到自己当前所在的房间,其他房间在玩家看来一片漆黑。
表现形式:只有踩在特定ID的区域内,相应的房间贴图才会显示。
核心问题:如何将特定ID的区域与房间贴图的显隐相关联。
解决方法:创建以以下格式书写的地图注释:
         <ulds> {
                "name": "streetlight",
               "x": "this.rx(123)",
               "y": "this.ry(456)",
               "z": 3.5,
               "opacity": "(function(){var regionId=200;if($gamePlayer.regionId()==regionId){return true;}else{return false};})()"
          } </ulds>
        !注意!这个注释占用了区域#200。
        当玩家踩在区域#200上时,房间贴图才会显现,否则会消失。
        若想自定义区域ID,请设置 regionId 的值。

      ※如果想在某个*跟随者*踩到特定ID的区域时显示房间贴图,就将"visible"属性中的$gamePlayer替换成$gamePlayer.followers().visibleFollowers()[INDEX]。INDEX从零开始计数,第一个跟随者(地图上玩家身后的角色)索引是0。
      ※如果想在某个*事件*踩到特定ID的区域时显示房间贴图,就将"visible"属性中的$gamePlayer替换成$gameMap.event(EVENT_ID)。EVENT_ID是事件ID。





如果想实现某种功能又不知从何下手的话可以回帖求助,我能帮得上忙的话,就会在主楼(这一层帖子)补充相关知识(技巧模块可能会持续更新)。大家的每一个问题、每一分解答都有助于完善该教程。

评分

参与人数 21星屑 +600 +20 收起 理由
背棺走的骷髅 + 1 精品文章
windy0322 + 1 精品文章
Ranita + 1 塞糖
worldxczero + 1 精品文章
门掩黄昏 + 1 精品文章
tangke001 + 1 精品文章
li19910808 + 1 精品文章
yxremaen + 1 精品文章
小王呀 + 1 塞糖
dunklen.f + 1 塞糖

查看全部评分

Lv4.逐梦者

梦石
0
星屑
11849
在线时间
2163 小时
注册时间
2013-6-10
帖子
1578
2
发表于 2022-4-24 23:51:52 | 只看该作者
真乃精品教程也!
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1666
在线时间
223 小时
注册时间
2020-4-26
帖子
44
3
发表于 2022-4-25 04:46:39 | 只看该作者
好耶!终于有教程了!
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
7566
在线时间
1409 小时
注册时间
2018-12-16
帖子
1983
4
发表于 2022-4-25 09:54:01 | 只看该作者
很多人不知道楼主有多棒!
我帮楼主讲解一下!
无限图层外挂已经出来好几年了...
之所以明明很好用 结果却没有人再用 原因就是 连作者都不知道要怎麽用 没有说明 作者自己也说 他自己根本不会用
所以就无解了!
只能让想要试试看的人 盲目的去试验...
就拿我自己来说...
试成功了 固然很高兴 结果下一个功能又失败了.... 后来干脆用别的外挂取代就好了....
但是心里想 如果无限图层有教程就好了
好多年过去了
现在竟然有善心楼主出现了!
真的是太棒了!!!!!!!!!!!!!!!!!!!!!!!!!!!!
赞赞赞赞赞赞赞!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

点评

真的...我一开始也以为作者只是懒得写说明...结果作者自己说的...他是不知道怎麽用...  发表于 2022-6-12 01:54
真的假的,作者自己都不会用?这也太神奇海螺了。  发表于 2022-6-11 15:42
诶嘿(*'▽'*)♪感谢捧场~  发表于 2022-4-25 10:01
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
3571
在线时间
749 小时
注册时间
2018-5-18
帖子
412
5
发表于 2022-4-25 10:49:18 | 只看该作者
感谢分享,请问一下,我看ULDS网站上写着【* @target MZ】是说只能MZ用吗?MV可以使用吗?
这个人很馋,什么都没有留下。。。
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
6422
在线时间
800 小时
注册时间
2021-8-28
帖子
89
6
 楼主| 发表于 2022-4-25 10:58:30 | 只看该作者
本帖最后由 Rose_shadows 于 2022-4-25 11:00 编辑
马铃薯条 发表于 2022-4-25 10:49
感谢分享,请问一下,我看ULDS网站上写着【* @target MZ】是说只能MZ用吗?MV可以使用吗? ...


MV MZ通用。这篇教程就是基于MV测试出来的。
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
336
在线时间
125 小时
注册时间
2021-9-5
帖子
59
7
发表于 2022-4-25 11:10:53 | 只看该作者
B站上有大佬讲过基础的,但是没有这个这么详细大佬太棒了
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
5524
在线时间
593 小时
注册时间
2020-2-20
帖子
224
8
发表于 2022-4-25 14:47:16 | 只看该作者
太棒了哟!
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
3050
在线时间
800 小时
注册时间
2020-1-24
帖子
257
9
发表于 2022-4-25 20:22:55 | 只看该作者
太棒了楼主
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
107
在线时间
12 小时
注册时间
2022-4-25
帖子
10
10
发表于 2022-4-26 01:10:19 | 只看该作者
谢谢大佬的教程!
我这里有个问题,做动态帧我只有两帧 ,star1和star2,写了没有动起来是咋回事,麻烦太太有空帮我看下,谢谢qwq!!!
<ulds> {
"name": "star1",
"x": "this.rx(1)",
"y": "this.ry(1)",
"z": "-2",
"visible": "v.value(10) === 0"
} </ulds>



事件我写的是:
*            ◆等待:1 帧
*            ◆变量操作:#0010 = 1
*            ◆等待:1 帧
*            ◆变量操作:#0010 = 0
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2025-7-18 22:40

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表