meta data for this page
📚 差别
这里会显示出您选择的修订版和当前版本之间的差别。
| 两侧同时换到之前的修订记录前一修订版后一修订版 | 前一修订版 | ||
| scripting:world:player [2023/08/16 11:18] – bibiboxs | scripting:world:player [2025/08/29 15:50] (当前版本) – bibiboxs | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| < | < | ||
| # World/ | # World/ | ||
| + | |||
| + | 玩家对象是一个**抽象的概念**,它**并不是**一个可以看见的世界实例。 | ||
| + | |||
| + | **任何加入到当前服务器的玩家(包括本地玩家)均被认定为`Player`。** | ||
| + | |||
| + | |||
| ## Event | ## Event | ||
| 行 6: | 行 12: | ||
| ### OnPlayerJoin( player ) | ### OnPlayerJoin( player ) | ||
| - | > 当新玩家加入到房间时调用。 | + | > 当新玩家**加入主机**时调用,此事件通常较少使用。 |
| + | > | ||
| + | > 注意:此时玩家只是连接成功,并非加载完成,完整加载使用`OnPlayerComplete`。 | ||
| - | ### OnPlayerPart | + | ### OnPlayerComplete( player ) |
| - | > 当玩家离开房间时调用。 | + | > 当玩家**完全加载**时调用。 |
| > | > | ||
| - | > Reason:离开原因(int) | + | > 通常情况下,应该使用此事件作为玩家的**入口事件**。 |
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerPart ( player, reason ) | ||
| + | |||
| + | > 当玩家**离开主机**时调用。 | ||
| + | > | ||
| + | > 注意:如果玩家是主机,且直接关闭游戏进程时,此方法可能**不会按照预期**工作。 | ||
| + | |||
| + | - **Reason:**离开原因(int)(0=断开连接;1=被服务器踢出;2=被服务器封禁) | ||
| 行 21: | 行 39: | ||
| > 当玩家发送消息时调用。 | > 当玩家发送消息时调用。 | ||
| + | > | ||
| + | > 此事件有**返回值机制**,如果返回为`false`则不使用内置的聊天输出(不会输出任何消息),默认返回`true`。 | ||
| + | > | ||
| + | > 如果有**自定义聊天样式**需求,可以通过`return 0`然后使用`Message(" | ||
| + | > | ||
| + | > 注意:默认聊天消息经过了`Native.FormatRichText()`格式化,这将使文本支持`[URL\@AT\Emoji]`等高亮显示,如果有自定义输出需求并希望支持这些功能,可以在手动发送Message前使用API格式化一次。** | ||
| + | |||
| + | [note] | ||
| + | 游戏聊天框默认支持`UBB|HTML`格式的消息,如果不希望玩家随意使用,可以通过`Misc.IsUBBText()`或其他方式检测文本,并决定哪些内容允许被发送。 | ||
| + | [/note] | ||
| + | |||
| + | ```javascript | ||
| + | function OnPlayerChat( player, text ) | ||
| + | { | ||
| + | // | ||
| + | // | ||
| + | Message(" | ||
| + | return 0; //return 0 == ignore engine default chat message | ||
| + | } | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerNetworkCMD( player, cmd, arg0, arg1, arg2 ) | ||
| + | |||
| + | > 当接收到来自玩家客户端发送的**CMD消息**时调用,这是客户端与服务端**传输自定义信息**的方式之一。 | ||
| + | > | ||
| + | > **对于一些特殊情况,可以利用`json to string`进行更详细的内容传输。** | ||
| + | |||
| + | [note2] | ||
| + | |||
| + | 注意:`CMD\RPC`传输支持几个基础类型(`int | float | string | bool | Vector | Color`)。 | ||
| + | |||
| + | [/note] | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerStreamData( player, number, data ) | ||
| + | |||
| + | > 当接收到来自玩家客户端发送的**自定义数据**时调用,**这是客户端与服务端传输自定义信息的方式之一**。 | ||
| + | > | ||
| + | > 自定义信息数据由`float(int)\string`两个参数组成。 | ||
| + | > | ||
| + | > **对于一些特殊情况,可以利用JSON(data参数)进行更详细的内容传输。** | ||
| + | |||
| + | ```javascript | ||
| + | function OnPlayerStreamData( player: Player, number: float, data: string ) | ||
| + | ``` | ||
| 行 27: | 行 93: | ||
| > 当玩家输入指令时调用(以'/' | > 当玩家输入指令时调用(以'/' | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerTypingChange( player, state ) | ||
| + | |||
| + | > 当玩家聊天框输入状态发生改变时调用。 | ||
| + | |||
| + | ```javascript | ||
| + | function OnPlayerTypingChange( player: Player, state: bool ) | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerVoiceStateChange( player, state ) | ||
| + | |||
| + | > 当玩家语音聊天状态发生改变时调用(正在语音聊天)。 | ||
| + | |||
| + | ```javascript | ||
| + | function OnPlayerVoiceStateChange( player: Player, state: bool ) | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerFocusEntityChange( player, entity ) | ||
| + | |||
| + | > 当玩家焦点对象发生改变时调用。 | ||
| + | |||
| + | ```javascript | ||
| + | function OnPlayerFocusEntityChange( player: Player, entity: Entity ) | ||
| + | ``` | ||
| 行 39: | 行 135: | ||
| > 当玩家取消绑定控制实体(Character)时调用。 | > 当玩家取消绑定控制实体(Character)时调用。 | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerKeyDown( player, keyTag ) | ||
| + | |||
| + | > 当玩家按下**服务器监听按键**时调用,只有服务器监听的按键(`RegisterKeyListener`)才会触发。 | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerKeyUp( player, keyTag ) | ||
| + | |||
| + | > 当玩家抬起**服务器监听按键**时调用,只有服务器监听的按键(`RegisterKeyListener`)才会触发。 | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerWorldChange( player, world ) | ||
| + | |||
| + | > 当玩家世界ID发生改变时调用。 | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerColorChange( player, color ) | ||
| + | |||
| + | > 当玩家颜色发生改变时调用。 | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerNameChange( player, name ) | ||
| + | |||
| + | > 当玩家名称发生改变时调用。 | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerBackpackPropOperation( player, slot, isMain, isShift ) | ||
| + | |||
| + | > 当玩家背包请求操作物品时调用。 | ||
| + | > | ||
| + | > 此方法可配合`player.GetBackpackTempProp()`使用。 | ||
| + | |||
| + | - `isMain`:是否为左键(主要)点击(否则为右键) | ||
| + | - `isShift`:是否按住Shift键 | ||
| + | - `return`:默认返回`true`,决定是否允许后续操作 | ||
| + | |||
| + | |||
| + | |||
| + | ### OnPlayerBackpackPropDiscard( player, prop, isDelete ) | ||
| + | |||
| + | > 当玩家背包请求扔掉物品时调用。 | ||
| + | |||
| + | - `isDelete`:是否为请求删除物品(否则视为丢弃) | ||
| + | - `return`:默认返回`true`,决定是否允许后续操作 | ||
| ## Property | ## Property | ||
| + | |||
| + | ### player.ID | ||
| + | |||
| + | > 获取玩家序列ID,每个玩家ID是唯一的。 | ||
| + | > | ||
| + | > 当之前的玩家离开游戏后,空闲的靠前ID将会被后续新玩家重新使用(对于特殊情况,`UUID`是更合适的筛选选择)。 | ||
| + | |||
| + | ```javascript | ||
| + | player.ID: int | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.UUID | ||
| + | |||
| + | > 获取玩家唯一标识值。 | ||
| + | > | ||
| + | > **特别注意:此值并非是绝对安全的,玩家(尤其是Demo版玩家)更换设备、账号、手动修改等行为后会发生改变,通常只有Steam用户的UUID是相对唯一且安全的。** | ||
| + | |||
| + | ```javascript | ||
| + | player.UUID: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Name | ||
| + | |||
| + | > 获取玩家用户名称,长度限制最多`16`。 | ||
| + | > | ||
| + | > 此属性**服务器脚本是可修改的**,但不会真正影响到玩家配置名称,只在本次服务器内生效。 | ||
| + | |||
| + | ```javascript | ||
| + | player.Name: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Address | ||
| + | |||
| + | > 获取玩家**网络\联机标识**地址。 | ||
| + | > | ||
| + | > 在Socket情况下,这可能返回一个IPV4、IPV6网络地址,否则可能返回联机标识地址(如SteamP2P)。 | ||
| + | |||
| + | ```javascript | ||
| + | player.Address: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Data | ||
| + | |||
| + | > 内置的自定义类型属性(建议使用基础类型),可供开发者自行使用,需要自行做好类型Type和生命周期处理。 | ||
| + | |||
| + | ```javascript | ||
| + | player.Data = null; //any | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.UserData | ||
| + | |||
| + | > 获取玩家自定义用户信息。 | ||
| + | > | ||
| + | > 此信息**仅支持字符串**(可用Json扩展),当玩家使用`CreateHost\ConnectHost`方法时可传递对应参数。 | ||
| + | > | ||
| + | > **总结:可在建立\加入服务器时提前告知服务器一些信息,例如部分游戏可能支持在主菜单选择衣服,加入服务器时只需要将衣服参数告知服务器即可,相当于一个前置信息传递。** | ||
| + | |||
| + | ```javascript | ||
| + | player.UserData: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | ### player.GameEdition | ||
| + | |||
| + | > 获取玩家用户游戏版本类型(非版本号)。 | ||
| + | > | ||
| + | |||
| + | ```javascript | ||
| + | player.GameEdition: | ||
| + | ``` | ||
| + | |||
| + | | 索引 | 版本 | ||
| + | | ---- | -------------------- | | ||
| + | | 0 | 标准版(Demo\Steam) | | ||
| + | | 1 | 白金版(Steam+DLC) | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Authority | ||
| + | |||
| + | > 获取玩家用户类型。 | ||
| + | > | ||
| + | |||
| + | ```javascript | ||
| + | player.Authority: | ||
| + | ``` | ||
| + | |||
| + | | 索引 | 账户类型 | ||
| + | | ---- | ------------------------------------- | | ||
| + | | 0 | 本地用户,非Steam用户(可能非安全的) | | ||
| + | | 1 | Steam用户(标准版\白金版) | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Ping | ||
| + | |||
| + | > 获取玩家用户网络延迟。 | ||
| + | > | ||
| + | |||
| + | ```javascript | ||
| + | player.Ping: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.FPS | ||
| + | |||
| + | > 获取玩家用户FPS帧数。 | ||
| + | > | ||
| + | |||
| + | ```javascript | ||
| + | player.FPS: int | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Stats | ||
| + | |||
| + | > 设置玩家自定义信息\状态(短文本,将显示在[TAB]菜单的用户名附近)。 | ||
| + | > | ||
| + | |||
| + | ```javascript | ||
| + | player.Stats = ""; | ||
| + | ``` | ||
| + | |||
| + | |||
| ### player.World | ### player.World | ||
| 行 51: | 行 334: | ||
| > | > | ||
| > **注意:如果世界被修改时玩家绑定的`Character`已存在,那么将同步`Character`修改为新的World,并且不会解除绑定控制。如果不希望这样,可以提前`player.SetEntity(null)`解除绑定,再修改World。** | > **注意:如果世界被修改时玩家绑定的`Character`已存在,那么将同步`Character`修改为新的World,并且不会解除绑定控制。如果不希望这样,可以提前`player.SetEntity(null)`解除绑定,再修改World。** | ||
| + | > | ||
| + | > **==注意:`player.UniqueWorld`的机制是`10000 + player.ID`,因此应该避免手动将世界设置为`10000`及以上的数值。==** | ||
| ```javascript | ```javascript | ||
| 行 60: | 行 345: | ||
| ### player.UniqueWorld | ### player.UniqueWorld | ||
| - | > 读取(只读)玩家**私人同步世界ID**,此项与`player.World`功能相似,不同的是,如果将某个对象设置为`player.UniqueWorld`,则指定对象只有此玩家可见,哪怕此玩家仍然在默认世界(0)。 | + | > 获取玩家**私人同步世界ID**,此项与`player.World`功能相似,不同的是,如果将某个对象设置为`player.UniqueWorld`,则指定对象只有此玩家可见,哪怕此玩家仍然在默认世界(0)。 |
| + | > | ||
| + | > **==注意:`player.UniqueWorld`的机制是`10000 + player.ID`,因此应该避免手动将世界设置为`10000`及以上的数值。==** | ||
| ```javascript | ```javascript | ||
| player.UniqueWorld: | player.UniqueWorld: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Color | ||
| + | |||
| + | > 设置玩家的**标识颜色**,此颜色用于改变玩家的名称颜色、队伍颜色(概念)等,默认值为`Color(255, | ||
| + | |||
| + | ```javascript | ||
| + | player.Color = Color(255, 255, 255); | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Group | ||
| + | |||
| + | > 设置玩家的**组ID**,此值**没有实际的功能意义**,且不同于`Entity.Group`属性,目前只作保留属性用途。 | ||
| + | > | ||
| + | > **扩展:在特殊情况下,可以通过此属性为玩家们分配不同的组ID,以此认为他们是不同的阵营,执行不同的代码。** | ||
| + | |||
| + | ```javascript | ||
| + | player.Group = 0; //int | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Entity | ||
| + | |||
| + | > 获取玩家绑定的实体对象(角色)。 | ||
| + | > | ||
| + | > 此方法也可以设置赋值对象(等同于`player.SetEntity(value, | ||
| + | |||
| + | ```javascript | ||
| + | player.Entity: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.Character | ||
| + | |||
| + | > 获取玩家绑定的实体对象(角色),作用与`player.Entity`完全相同。 | ||
| + | |||
| + | ```javascript | ||
| + | player.Character: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.IsAdmin | ||
| + | |||
| + | > 设置玩家**是否为管理员**,管理员可通过`TAB`菜单进行基础的玩家管理。 | ||
| + | > | ||
| + | > 通常情况下,此属性是一个验证管理员权限的**预制抽象属性**,开发者可考虑自行编写更高级的管理员系统。 | ||
| + | > | ||
| + | > 如果服务器由**本地主机**建立,主机玩家会自动激活此属性。 | ||
| + | |||
| + | ```javascript | ||
| + | player.IsAdmin = false; | ||
| ``` | ``` | ||
| 行 80: | 行 425: | ||
| ### player.Pos | ### player.Pos | ||
| - | > 读取(只读)玩家同步流焦点坐标,通常是屏幕中心的世界坐标。 | + | > 获取玩家**世界坐标**位置(通常是玩家屏幕中心位置),如果玩家正在控制角色,则返回角色坐标位置。 |
| ```javascript | ```javascript | ||
| 行 90: | 行 435: | ||
| ### player.FocusPos | ### player.FocusPos | ||
| - | > 读取(只读)玩家鼠标焦点世界坐标,如果玩家正在控制一个角色,则两者坐标相同。 | + | > 获取玩家视角焦点坐标(屏幕中心、准星& |
| + | > | ||
| + | > 在玩家不同视角模式(`Client.Camera.Mode`)下(鸟瞰、第一人称、第三人称),坐标获取方式会发生变化。 | ||
| + | > | ||
| + | > 主要表现于:[鸟瞰]鼠标坐标、[第三人称]屏幕准星坐标 | ||
| ```javascript | ```javascript | ||
| player.FocusPos: | player.FocusPos: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.FocusEntity | ||
| + | |||
| + | > 获取玩家**视角焦点实体**,如果不存在则返回`null`。 | ||
| + | |||
| + | ```javascript | ||
| + | player.FocusEntity: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.FocusEntityDistance | ||
| + | |||
| + | > 获取玩家**视角焦点实体检测距离**,此数值直接影响`FocusEntity`的检测结果,默认距离为`3.0`(`0.0~512.0`)。 | ||
| + | > | ||
| + | > **注意:对于远距离视角、鸟瞰视角等情况,应该在合理范围内调高此数值,否则可能距离过短导致无法正确检测。** | ||
| + | |||
| + | ```javascript | ||
| + | player.FocusEntityDistance: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.FocusVAngle | ||
| + | |||
| + | > 设置& | ||
| + | |||
| + | ```javascript | ||
| + | player.FocusVAngle: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.FocusHAngle | ||
| + | |||
| + | > 设置& | ||
| + | |||
| + | ```javascript | ||
| + | player.FocusHAngle: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.FocusEulerAngle | ||
| + | |||
| + | > 设置& | ||
| + | > | ||
| + | > 在玩家不同视角模式(`Client.Camera.Mode`)下,坐标处理方式会发生变化。 | ||
| + | |||
| + | [note2] | ||
| + | 注意:多数情况下,应该使用`Client\Camera`实现视角相关逻辑。 | ||
| + | [/note] | ||
| + | |||
| + | ```javascript | ||
| + | player.FocusAngle: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.FocusAngleForward | ||
| + | |||
| + | > 获取玩家**控制焦点**前方向量。 | ||
| + | > | ||
| + | > 在玩家不同视角模式(`Client.Camera.Mode`)下,坐标处理方式会发生变化。 | ||
| + | |||
| + | ```javascript | ||
| + | player.FocusAngleForward: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.EngineLanguage | ||
| + | |||
| + | > 获取玩家正在使用的引擎语言(如果中途改动语言,不会更新)。 | ||
| + | > | ||
| + | > 根据《沙盘引擎》语言机制,通常应该采用此方法作为玩家语言的判定。 | ||
| + | |||
| + | ```javascript | ||
| + | player.EngineLanguage: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.ModLanguage | ||
| + | |||
| + | > 获取玩家正在使用的模组语言(如果中途改动语言,不会更新)。 | ||
| + | |||
| + | ```javascript | ||
| + | player.ModLanguage: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.IsTyping | ||
| + | |||
| + | > 获取玩家聊天框输入状态(是否正在输入)。 | ||
| + | |||
| + | ```javascript | ||
| + | player.IsTyping: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.IsComplete | ||
| + | |||
| + | > 获取玩家是否完全加载完毕。 | ||
| + | |||
| + | ```javascript | ||
| + | player.IsComplete: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.IsObserver | ||
| + | |||
| + | > 获取玩家是否当前为相机观察模式(`Client.Camera.IsObserver`)。 | ||
| + | |||
| + | ```javascript | ||
| + | player.IsObserver: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.VoiceState | ||
| + | |||
| + | > 获取玩家语音聊天状态(是否正在语音聊天)。 | ||
| + | > | ||
| + | > **注意:玩家必须`player.SetVoiceAuthority(true)`给予语音权限(默认),且由玩家主动触发按键才会进行聊天。** | ||
| + | |||
| + | ```javascript | ||
| + | player.VoiceState: | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.CameraMode | ||
| + | |||
| + | > 获取(只读)玩家相机模式(参考`Client.Camera.Mode`)。 | ||
| + | |||
| + | ```javascript | ||
| + | player.CameraMode: | ||
| ``` | ``` | ||
| 行 110: | 行 603: | ||
| - | ### Player.FindByIndex() | + | ### Player.Search() |
| - | > 寻找一个玩家实例(通过索引),不存在则返回`null`。 | + | > 寻找一个玩家实例(通过模糊查找,通常根据玩家名称\ID,不区分大小写),不存在则返回`null`。 |
| ```javascript | ```javascript | ||
| - | function Player.FindByIndex( index: int ): Player | + | function Player.Search( any: string ): Player |
| + | ``` | ||
| + | |||
| + | ```javascript | ||
| + | //Players: " | ||
| + | Player.Search(" | ||
| + | Player.Search(" | ||
| + | Player.Search(" | ||
| + | Player.Search(" | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ### Player.FindByUUID() | ||
| + | |||
| + | > 寻找一个玩家实例(通过UUID),不存在则返回`null`。 | ||
| + | |||
| + | ```javascript | ||
| + | function Player.FindByUUID( uuid: string | ||
| ``` | ``` | ||
| 行 126: | 行 638: | ||
| ```javascript | ```javascript | ||
| function Player.GetCount(): | function Player.GetCount(): | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### Player.Get() | ||
| + | |||
| + | > 获取当前存在的指定索引玩家,通常搭配`GetCount()`遍历使用。 | ||
| + | |||
| + | ```javascript | ||
| + | function Player.Get( index: int ): Player | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### Player.BanUUID() | ||
| + | |||
| + | > 封禁指定**完整UUID**的玩家(仅在当前服务器运行时生效,重启服务器后将清空封禁列表)。 | ||
| + | |||
| + | ```javascript | ||
| + | function Player.BanUUID( uuid: string ) | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### Player.UnbanUUID() | ||
| + | |||
| + | > 取消封禁指定**完整UUID**的玩家(仅在当前服务器运行时生效,重启服务器后将清空封禁列表)。 | ||
| + | |||
| + | ```javascript | ||
| + | function Player.UnbanUUID( uuid: string ) | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### Player.UnbanName() | ||
| + | |||
| + | > 取消封禁指定**完整名称(被封禁时)**的玩家(仅在当前服务器运行时生效,重启服务器后将清空封禁列表)。 | ||
| + | > | ||
| + | > **==此方法只能取消由`player.Ban()`执行封禁的玩家,具体逻辑仍然基于UUID。==** | ||
| + | |||
| + | ```javascript | ||
| + | function Player.UnbanName( name: string ) | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### Player.UnbanAll() | ||
| + | |||
| + | > 取消所有玩家封禁(仅在当前服务器运行时生效,重启服务器后将清空封禁列表)。 | ||
| + | |||
| + | ```javascript | ||
| + | function Player.UnbanAll() | ||
| ``` | ``` | ||
| 行 154: | 行 718: | ||
| - | ### player.CreateNativeMenu() | + | ### player.Kick() |
| - | > 为玩家建立一个`NativeMenu`菜单([NativeMenu菜单](scripting/ | + | > 从服务器踢出玩家。 |
| ```javascript | ```javascript | ||
| - | let view = { | + | function |
| - | Cover: 5, | + | |
| - | Tag: " | + | |
| - | Title: " | + | |
| - | Info: " | + | |
| - | Width: 500, | + | |
| - | Align: 1, | + | |
| - | Layout: 1, | + | |
| - | Items: [ | + | |
| - | { | + | |
| - | Text: " | + | |
| - | OnClick: () => { | + | |
| - | DLog(" | + | |
| - | } | + | |
| - | },{ | + | |
| - | Input: " | + | |
| - | Restrict: " | + | |
| - | OnFocus: (text) | + | |
| - | DLog("输入框文本: | + | |
| - | } | + | |
| - | },{ | + | |
| - | Text: " | + | |
| - | OnClick: () => { | + | |
| - | Vehicle.Create(10, | + | |
| - | player.DestroyNativeMenu(); | + | |
| - | } | + | |
| - | } | + | |
| - | ] | + | |
| - | }; | + | |
| - | + | ||
| - | player.CreateNativeMenu(view); | + | |
| ``` | ``` | ||
| - | ### player.DestroyNativeMenu() | + | ### player.Ban() |
| - | > 为玩家关闭`NativeMenu`菜单,用法与[客户端NativeMenu](scripting/ | + | > 从服务器封禁玩家(仅在服务器运行时生效,重启服务器将清空封禁列表)。 |
| + | > | ||
| + | > 如果希望实现持久化的封禁列表,请考虑自行实现维护一个`txt|json`文件表,在每次服务器建立后读取文件+遍历执行`Player.BanUUID()`。 | ||
| - | + | ```javascript | |
| - | + | function | |
| - | ### player.SetNativeMenuText() | + | ``` |
| - | + | ||
| - | > 为玩家关闭`NativeMenu`菜单,用法与[客户端NativeMenu](scripting/ | + | |
| 行 232: | 行 766: | ||
| ```javascript | ```javascript | ||
| function player.Subtitle( text: string ) | function player.Subtitle( text: string ) | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.NetworkRPC() | ||
| + | |||
| + | > 为玩家发送一条RPC指令。 | ||
| + | > | ||
| + | > 目标玩家客户端脚本通过`OnServerNetworkRPC()`接收数据。 | ||
| + | > | ||
| + | > **注意:`CMD\RPC`方法仅支持基础类型,并且会自动类型转换。** | ||
| + | |||
| + | ```javascript | ||
| + | function NetworkRPC( rpc: string, arg0: any, arg1: any, arg2: any ) | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.SendData() | ||
| + | |||
| + | > 为玩家发送一条**服务端> | ||
| + | > | ||
| + | > 目标玩家客户端脚本通过`OnServerStreamData()`接收数据。 | ||
| + | > | ||
| + | > **注意:这里不应该放置特别大的数据内容(4096),否则可能造成网络阻塞。** | ||
| + | |||
| + | ```javascript | ||
| + | function player.SendData( number: float, data: string = "" | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.ClientExec() | ||
| + | |||
| + | > 为玩家发送一条**客户端脚本代码**,目标玩家**客户端**将执行对应的脚本代码。 | ||
| + | > | ||
| + | > **注意:这里不应该放置特别大的数据内容(2048),否则可能造成网络阻塞。** | ||
| + | |||
| + | ```javascript | ||
| + | function player.ClientExec( code: string ) | ||
| ``` | ``` | ||
| 行 238: | 行 812: | ||
| ### player.PlaySound() | ### player.PlaySound() | ||
| - | > 为玩家播放一段声音,用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家播放一段**声音**,用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 248: | 行 822: | ||
| ### player.Play3DSound() | ### player.Play3DSound() | ||
| - | > 为玩家播放一段3D空间声音,用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家播放一段**3D空间声音**,用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 258: | 行 832: | ||
| ### player.StopSound() | ### player.StopSound() | ||
| - | > 为玩家停止播放并销毁一段声音实例,用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家停止播放并销毁一段**声音实例**,用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 268: | 行 842: | ||
| ### player.PlayMusic() | ### player.PlayMusic() | ||
| - | > 为玩家播放音乐(音乐轨道),用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家播放**音乐**(音乐轨道),用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 278: | 行 852: | ||
| ### player.Play3DMusic() | ### player.Play3DMusic() | ||
| - | > 为玩家播放3D空间音乐(音乐轨道),用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家播放**3D空间音乐**(音乐轨道),用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 288: | 行 862: | ||
| ### player.PauseMusic() | ### player.PauseMusic() | ||
| - | > 为玩家暂停播放音乐(音乐轨道),用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家暂停播放**音乐**(音乐轨道),用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 298: | 行 872: | ||
| ### player.ResumeMusic() | ### player.ResumeMusic() | ||
| - | > 为玩家继续播放音乐(音乐轨道),用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家继续播放**音乐**(音乐轨道),用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 308: | 行 882: | ||
| ### player.StopMusic() | ### player.StopMusic() | ||
| - | > 为玩家停止播放并销毁音乐实例(音乐轨道),用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家停止播放并销毁**音乐实例**(音乐轨道),用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 318: | 行 892: | ||
| ### player.PlayNatural() | ### player.PlayNatural() | ||
| - | > 为玩家播放背景音(背景音轨道),用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家播放**背景环境音**(背景音轨道),用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 328: | 行 902: | ||
| ### player.StopNatural() | ### player.StopNatural() | ||
| - | > 为玩家停止播放并销毁指定背景音实例(背景音轨道),用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家停止播放并销毁指定**背景环境音实例**(背景音轨道),用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 338: | 行 912: | ||
| ### player.StopAllNatural() | ### player.StopAllNatural() | ||
| - | > 为玩家停止播放并销毁全部背景音实例(背景音轨道),用法及详细说明与[客户端Audio](scripting/ | + | > 为玩家停止播放并销毁全部**背景环境音实例**(背景音轨道),用法及详细说明与[客户端Audio](scripting/ |
| ```javascript | ```javascript | ||
| 行 346: | 行 920: | ||
| - | ### player.BindKeyPresser() | + | ### player.RunTaskAction() |
| - | > 为玩家绑定**按键快捷对象**的UI布局方式(2D屏幕、3D坐标、实体对象跟随),具体取决于参数类型。 | + | > 为玩家执行一次**倒计时任务**(UI进度条+倒计时),每个玩家**同一时间**只能执行一个任务 |
| + | |||
| + | ```javascript | ||
| + | function player.RunTaskAction( tag: string, time: float, title: string, onComplete: Action, theme: int = 0 ) | ||
| + | ``` | ||
| + | |||
| + | - `tag`识别标签,仅供参考记录 | ||
| + | - `time`倒计时时间(秒) | ||
| + | - `title`文本标题(支持宏文本) | ||
| + | - `theme`范围0~4,表示不同的颜色 | ||
| + | |||
| + | ```javascript | ||
| + | player.RunTaskAction(" | ||
| + | // | ||
| + | }); | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.StopTaskAction() | ||
| + | |||
| + | > 停止玩家**倒计时任务**。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.StopTaskAction() | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.UpdateTaskActionData() | ||
| + | |||
| + | > 更新玩家**倒计时任务**信息。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.UpdateTaskActionData( title: string, theme: int = -1 ) | ||
| + | ``` | ||
| + | |||
| + | - `title`文本标题(支持宏文本) | ||
| + | - `theme`颜色主题,默认`-1`不进行修改 | ||
| + | |||
| + | |||
| + | |||
| + | ### player.GetTaskActionTag() | ||
| + | |||
| + | > 获取玩家**倒计时任务**标签。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.GetTaskActionTag(): | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.ExistTaskAction() | ||
| + | |||
| + | > 获取玩家**倒计时任务**是否**存在**并进行中。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.ExistTaskAction(): | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.SetVoiceMode() | ||
| + | |||
| + | > 设置玩家语音聊天模式,**默认关闭**。 | ||
| > | > | ||
| - | > ==注意:每次建立的**按键快捷对象**全部移出后,再次建立时,UI布局方式将自动切换至`Null(2D屏幕偏右)`。== | + | > ==**如果希望激活语音聊天功能,请为玩家设定一个非关闭的语音模式。**== |
| ```javascript | ```javascript | ||
| - | function player.BindKeyPresser( target: any ) | + | function player.SetVoiceMode( mode: int = 0 ) |
| - | /* | + | |
| - | target可选类型:null\Vector\Entity(Vector\Entity类型将作为3D坐标展示,Entity会有自动跟随) | + | |
| - | */ | + | |
| ``` | ``` | ||
| + | | 索引 | 语音聊天模式 | ||
| + | | ---- | -------------- | ------------------------------------------------------------ | | ||
| + | | 0 | 关闭 | ||
| + | | 1 | 全局模式 | ||
| + | | 2 | (频道)组模式 | 发送与接收相同频道组(`VoiceGroup`)的聊天,除特定情况及权限、禁言等 | | ||
| - | ### player.AddKeyPresser() | ||
| - | > 为玩家建立一个**按键快捷对象**,默认将加入到玩家**屏幕偏右**位置,如果你希望目标UI作为3D空间、跟随实体效果,使用`BindKeyPresser`提前绑定即可。 | + | ### player.GetVoiceMode() |
| + | |||
| + | > 获取玩家语音聊天模式。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.GetVoiceMode(): | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.SetVoiceWorldMode() | ||
| + | |||
| + | > 设置玩家语音聊天世界模式开关(3D空间音频,跟随玩家的实体对象)。 | ||
| > | > | ||
| - | > 这将在目标玩家的屏幕中显示`[按键] XXXX`的效果(例如`[F]进入此载具`,并为其绑定进入载具的事件)。 | + | > **此选项可能在部分玩法中提高玩家沉浸感,就像其他玩家真的在不远处说话一样。** |
| > | > | ||
| - | > 同时,此功能支持同时**绑定至多6个按键对象**(同列表下,并非不同位置),只需要为其填写不同的index即可。 | + | > *(可通过`GameRule |
| - | > | + | |
| - | > **Index目前只是标签占位,排序仍然根据代码添加顺序。** | + | |
| ```javascript | ```javascript | ||
| - | function player.AddKeyPresser( index: int, keyCode: string, text: string, onPress: Action = null ) | + | function player.SetVoiceWorldMode( active: bool ) |
| - | /* | + | ``` |
| - | index:指引索引(如索引已存在指引,将会替换修改,一个index只能存在并表示一个指引实例),相当于一个标签作用 | + | |
| - | keyCode:绑定按键,最好不要和其他按键冲突,除非知道在做什么 | + | |
| - | text:按键后面的文本内容 | + | |
| - | onPress:当玩家按下后执行的事件 | + | |
| - | */ | + | |
| - | // | + | |
| - | // | + | |
| + | ### player.GetVoiceWorldMode() | ||
| + | |||
| + | > 获取玩家语音聊天世界模式开关。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.GetVoiceWorldMode(): | ||
| ``` | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.SetVoiceAuthority() | ||
| + | |||
| + | > 设置玩家语音聊天**权限**开关(静音\禁言),默认开启(`true`)。 | ||
| + | > | ||
| + | > **==注意:此选项必须设置为`true`,玩家才有资格进行说话,否则玩家将无法在语音聊天中说话(禁言Muted)。==** | ||
| + | > | ||
| + | > ==**(此选项并非是玩家麦克风控制开关,安全考虑,只有玩家自行按住【说话按键】时才会录入音频)**== | ||
| ```javascript | ```javascript | ||
| - | // | + | function |
| - | player.AddKeyPresser(0, | + | ``` |
| - | player.AddKeyPresser(3, | + | |
| - | // | + | |
| - | 【F】进入当前载具 | + | |
| - | 【H】修复当前载具 | + | ### player.GetVoiceAuthority() |
| + | |||
| + | > 获取玩家语音聊天**权限**开关。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.GetVoiceAuthority(): | ||
| ``` | ``` | ||
| - | ### player.RemoveKeyPresser() | + | ### player.SetVoiceIgnore() |
| - | > 为玩家移除一个**按键快捷对象**。 | + | > 设置玩家屏蔽指定玩家语音开关,可用于屏蔽其他玩家的语音输出,但不会屏蔽自身对其他玩家的声音。 |
| - | > | + | |
| - | > ==注意:每次建立的**按键快捷对象**全部移出后,再次建立时,UI布局方式将自动切换至`Null(2D屏幕右下)`。== | + | |
| ```javascript | ```javascript | ||
| - | function player.RemoveKeyPresser( index: int ) | + | function player.SetVoiceIgnore( player: Player, active: bool ) |
| ``` | ``` | ||
| - | ### player.ExistKeyPresser() | + | ### player.GetVoiceIgnore() |
| - | > 获取玩家**指定索引**的**按键快捷对象**是否存在。 | + | > 获取玩家语音聊天**权限**开关。 |
| ```javascript | ```javascript | ||
| - | function player.ExistKeyPresser( index: int ): bool | + | function player.GetVoiceIgnore( player: Player |
| ``` | ``` | ||
| - | ### player.ClearKeyPressers() | ||
| - | > 移除玩家所有**按键快捷对象**。 | + | ### player.TestVisiblePoint() |
| + | |||
| + | > 检测玩家相机是否能看到指定坐标(模糊检测,边缘检测并非绝对准确,模拟本地`Camera.TestVisiblePoint()`)。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.TestVisiblePoint( pos: Vector ): bool | ||
| + | ``` | ||
| + | |||
| + | |||
| + | |||
| + | ### player.SetBackpackOtherTarget() | ||
| + | |||
| + | > 设置玩家**额外的观察背包实例**(除本地对象外的另一个背包)。 | ||
| + | > | ||
| + | > 此功能可扩展许多玩法,例如:商店、交易、背包共享等。 | ||
| > | > | ||
| - | > ==注意:每次建立的**按键快捷对象**全部移出后,再次建立时,UI布局方式将自动切换至`Null(2D屏幕右下)`。== | + | > 如果没有设置其他背包实例,玩家背包UI将仅显示自身对象背包。 |
| ```javascript | ```javascript | ||
| - | function player.ClearKeyPressers() | + | function player.SetBackpackOtherTarget( otherBackpack: |
| ``` | ``` | ||
| + | - `observerMode`:观察模式,默认为`0`(0=可读写,1=只读) | ||
| - | ### player.AddGuider() | ||
| - | > 为玩家建立一个指引目标(屏幕边缘箭头)。 | + | ### player.GetBackpackOtherTarget() |
| + | |||
| + | > 获取玩家**额外的观察背包实例**。 | ||
| ```javascript | ```javascript | ||
| - | function player.AddGuider( index: int, target: any, autoDestroy: | + | function player.GetBackpackOtherTarget(): Backpack |
| - | /* | + | ``` |
| - | index:指引索引(如索引已存在指引,将会替换修改,一个index只能存在并表示一个指引实例),相当于一个标签作用 | + | |
| - | target:目标对象(可以是Vector|Entity等类型,分别表示静态坐标与动态跟随目标) | + | |
| - | autoDestroy:到达指引目标附近是否自动移除指引,默认为false | + | |
| - | */ | + | |
| - | // | + | |
| + | |||
| + | ### player.SetBackpackTempProp() | ||
| + | |||
| + | > 设置玩家**临时背包物品**(随鼠标移动的临时选项),可设置为`null`。 | ||
| + | |||
| + | ```javascript | ||
| + | function player.SetBackpackTempProp( prop: Prop ) | ||
| ``` | ``` | ||
| - | ### player.RemoveGuider() | + | ### player.GetBackpackTempProp() |
| - | > 为玩家移除一个指引目标(屏幕边缘箭头)。 | + | > 获取玩家**临时背包物品**(随鼠标移动的临时选项),如不存在则为`prop.IsValid() == false`。 |
| ```javascript | ```javascript | ||
| - | function player.RemoveGuider( index: int ) | + | function player.GetBackpackTempProp(): Prop |
| ``` | ``` | ||
| - | ### player.ExistGuider() | + | ### player.ReturnBackpackTempProp() |
| - | > 获取玩家**指定索引**的指引实例是否存在。 | + | > 尝试返回玩家**临时背包物品**(随鼠标移动的临时选项),尝试自动将临时物品添加到背包。 |
| + | > | ||
| + | > 此方法与玩家**存在临时物品时关闭背包**效果相同,如果有空位则自动添加到背包并移出临时物品,如果没有空位则触发丢弃事件。 | ||
| + | > | ||
| + | > **注意:有时可能希望处理玩家的背包(例如清空背包),但有可能玩家正在操作临时物品,这样的话`Backpack`常规方式不会处理到临时物品,因此需要留意玩家手中的临时物品。** | ||
| ```javascript | ```javascript | ||
| - | function player.ExistGuider( index: int ): bool | + | function player.ReturnBackpackTempProp(): bool |
| ``` | ``` | ||
| + | |||
| + | - `return`:是否正常返回(如果没有临时物品,也会返回`true`) | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||