meta data for this page
  •  

📚 差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
scripting:world:player [2023/06/07 12:08] bibiboxsscripting:world:player [2025/08/29 15:50] (当前版本) bibiboxs
行 1: 行 1:
 <markdown> <markdown>
-Player [World]+# World/Player 
 + 
 +玩家对象是一个**抽象的概念**,它**并不是**一个可以看见的世界实例。 
 + 
 +**任何加入到当前服务器的玩家(包括本地玩家)均被认定为`Player`。** 
 + 
  
 ## Event ## Event
行 6: 行 12:
 ### OnPlayerJoin( player ) ### OnPlayerJoin( player )
  
-> 当新玩家加入到房间时调用。+> 当新玩家**加入主机**时调用,此事件通常较少使用。 
 +
 +> 注意:此时玩家只是连接成功,并非加载完成,完整加载使用`OnPlayerComplete`
  
  
  
-### OnPlayerPart ( player, reason )+### OnPlayerComplete( player )
  
-> 当玩家离开房间时调用。+> 当玩家**完全加载**时调用。
 > >
-> Reason:离开原因(int)+通常情况下,应该使用此事件作为玩家的**入口事件**。 
 + 
 + 
 + 
 +### OnPlayerPart ( player, reason ) 
 + 
 +> 当玩家**离开主机**时调用。 
 +>  
 +> 注意:如果玩家是主机,且直接关闭游戏进程时,此方法可能**不会按照预期**工作。 
 + 
 +- **Reason:**离开原因(int)(0=断开连接;1=被服务器踢出;2=被服务器封禁
  
  
行 21: 行 39:
  
 > 当玩家发送消息时调用。 > 当玩家发送消息时调用。
 +>
 +> 此事件有**返回值机制**,如果返回为`false`则不使用内置的聊天输出(不会输出任何消息),默认返回`true`。
 +>
 +> 如果有**自定义聊天样式**需求,可以通过`return 0`然后使用`Message("[color#=ff0000]"+player.Name+":"+text)`等方式实现。
 +>
 +> 注意:默认聊天消息经过了`Native.FormatRichText()`格式化,这将使文本支持`[URL\@AT\Emoji]`等高亮显示,如果有自定义输出需求并希望支持这些功能,可以在手动发送Message前使用API格式化一次。**
 +
 +[note]
 +游戏聊天框默认支持`UBB|HTML`格式的消息,如果不希望玩家随意使用,可以通过`Misc.IsUBBText()`或其他方式检测文本,并决定哪些内容允许被发送。
 +[/note]
 +
 +```javascript
 +function OnPlayerChat( player, text )
 +{
 +    //以下2行内容实现了自定义聊天消息的扩展
 +    //举一反三,也可以扩展出私聊、团队信息、前缀、关键词替换等
 +    Message("[DIY CHAT] " + player.Name + ": " + text);
 +    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: string
 +```
 +
 +
 +
 +### player.Name
 +
 +> 获取玩家用户名称,长度限制最多`16`。
 +>
 +> 此属性**服务器脚本是可修改的**,但不会真正影响到玩家配置名称,只在本次服务器内生效。
 +
 +```javascript
 +player.Name: string
 +```
 +
 +
 +
 +### player.Address
 +
 +> 获取玩家**网络\联机标识**地址。
 +>
 +> 在Socket情况下,这可能返回一个IPV4、IPV6网络地址,否则可能返回联机标识地址(如SteamP2P)。
 +
 +```javascript
 +player.Address: string
 +```
 +
 +
 +
 +### player.Data
 +
 +> 内置的自定义类型属性(建议使用基础类型),可供开发者自行使用,需要自行做好类型Type和生命周期处理。
 +
 +```javascript
 +player.Data = null; //any
 +```
 +
 +
 +
 +### player.UserData
 +
 +> 获取玩家自定义用户信息。
 +>
 +> 此信息**仅支持字符串**(可用Json扩展),当玩家使用`CreateHost\ConnectHost`方法时可传递对应参数。
 +>
 +> **总结:可在建立\加入服务器时提前告知服务器一些信息,例如部分游戏可能支持在主菜单选择衣服,加入服务器时只需要将衣服参数告知服务器即可,相当于一个前置信息传递。**
 +
 +```javascript
 +player.UserData: string
 +```
 +
 +
 +### player.GameEdition
 +
 +> 获取玩家用户游戏版本类型(非版本号)。
 +>
 +
 +```javascript
 +player.GameEdition: int
 +```
 +
 +| 索引 | 版本                 |
 +| ---- | -------------------- |
 +| 0    | 标准版(Demo\Steam) |
 +| 1    | 白金版(Steam+DLC)  |
 +
 +
 +
 +### player.Authority
 +
 +> 获取玩家用户类型。
 +>
 +
 +```javascript
 +player.Authority: int
 +```
 +
 +| 索引 | 账户类型                              |
 +| ---- | ------------------------------------- |
 +| 0    | 本地用户,非Steam用户(可能非安全的) |
 +| 1    | Steam用户(标准版\白金版)            |
 +
 +
 +
 +### player.Ping
 +
 +> 获取玩家用户网络延迟。
 +>
 +
 +```javascript
 +player.Ping: int
 +```
 +
 +
 +
 +### player.FPS
 +
 +> 获取玩家用户FPS帧数。
 +>
 +
 +```javascript
 +player.FPS: int
 +```
 +
 +
 +
 +### player.Stats
 +
 +> 设置玩家自定义信息\状态(短文本,将显示在[TAB]菜单的用户名附近)。
 +>
 +
 +```javascript
 +player.Stats = ""; //string
 +```
 +
 +
 +
 +### player.World
 +
 +> 设置玩家**同步世界ID**(不同世界将不可视\不可交互)。
 +>
 +> 当此属性被修改后,任何`实例.World != 自身.World`的对象都将不可见、不可操作,就像不存在一样。
 +>
 +> **注意:如果世界被修改时玩家绑定的`Character`已存在,那么将同步`Character`修改为新的World,并且不会解除绑定控制。如果不希望这样,可以提前`player.SetEntity(null)`解除绑定,再修改World。**
 +>
 +> **==注意:`player.UniqueWorld`的机制是`10000 + player.ID`,因此应该避免手动将世界设置为`10000`及以上的数值。==**
 +
 +```javascript
 +player.World = 0; //int
 +```
 +
 +
 +
 +### player.UniqueWorld
 +
 +> 获取玩家**私人同步世界ID**,此项与`player.World`功能相似,不同的是,如果将某个对象设置为`player.UniqueWorld`,则指定对象只有此玩家可见,哪怕此玩家仍然在默认世界(0)。
 +>
 +> **==注意:`player.UniqueWorld`的机制是`10000 + player.ID`,因此应该避免手动将世界设置为`10000`及以上的数值。==**
 +
 +```javascript
 +player.UniqueWorld: int //10000 + player.ID
 +```
 +
 +
 +
 +### player.Color
 +
 +> 设置玩家的**标识颜色**,此颜色用于改变玩家的名称颜色、队伍颜色(概念)等,默认值为`Color(255, 255, 255)`。
 +
 +```javascript
 +player.Color = Color(255, 255, 255);
 +```
 +
 +
 +
 +### player.Group
 +
 +> 设置玩家的**组ID**,此值**没有实际的功能意义**,且不同于`Entity.Group`属性,目前只作保留属性用途。
 +>
 +> **扩展:在特殊情况下,可以通过此属性为玩家们分配不同的组ID,以此认为他们是不同的阵营,执行不同的代码。**
 +
 +```javascript
 +player.Group = 0; //int
 +```
 +
 +
 +
 +### player.Entity
 +
 +> 获取玩家绑定的实体对象(角色)。
 +
 +> 此方法也可以设置赋值对象(等同于`player.SetEntity(value, true)`,默认执行`isBind`)。
 +
 +```javascript
 +player.Entity: Character
 +```
 +
 +
 +
 +### player.Character
 +
 +> 获取玩家绑定的实体对象(角色),作用与`player.Entity`完全相同。
 +
 +```javascript
 +player.Character: Character
 +```
 +
 +
 +
 +### player.IsAdmin
 +
 +> 设置玩家**是否为管理员**,管理员可通过`TAB`菜单进行基础的玩家管理。
 +>
 +> 通常情况下,此属性是一个验证管理员权限的**预制抽象属性**,开发者可考虑自行编写更高级的管理员系统。
 +
 +> 如果服务器由**本地主机**建立,主机玩家会自动激活此属性。
 +
 +```javascript
 +player.IsAdmin = false;
 +```
 +
 +
 +
 +### player.IsBindEntity
 +
 +> 如果设定为`true`则玩家断开时同时销毁角色(通过`player.SetEntity()`绑定的角色实例),否则将会保留角色,默认为`true`。
 +
 +```javascript
 +player.IsBindEntity = true;
 +```
 +
 +
 +
 +### player.Pos
 +
 +> 获取玩家**世界坐标**位置(通常是玩家屏幕中心位置),如果玩家正在控制角色,则返回角色坐标位置。
 +
 +```javascript
 +player.Pos: Vector
 +```
 +
 +
 +
 +### player.FocusPos
 +
 +> 获取玩家视角焦点坐标(屏幕中心、准星&鼠标位置)。
 +>
 +> 在玩家不同视角模式(`Client.Camera.Mode`)下(鸟瞰、第一人称、第三人称),坐标获取方式会发生变化。
 +>
 +> 主要表现于:[鸟瞰]鼠标坐标、[第三人称]屏幕准星坐标
 +
 +```javascript
 +player.FocusPos: Vector
 +```
 +
 +
 +
 +### player.FocusEntity
 +
 +> 获取玩家**视角焦点实体**,如果不存在则返回`null`。
 +
 +```javascript
 +player.FocusEntity: Entity
 +```
 +
 +
 +
 +### player.FocusEntityDistance
 +
 +> 获取玩家**视角焦点实体检测距离**,此数值直接影响`FocusEntity`的检测结果,默认距离为`3.0`(`0.0~512.0`)。
 +>
 +> **注意:对于远距离视角、鸟瞰视角等情况,应该在合理范围内调高此数值,否则可能距离过短导致无法正确检测。**
 +
 +```javascript
 +player.FocusEntityDistance: float
 +```
 +
 +
 +
 +### player.FocusVAngle
 +
 +> 设置&获取玩家**控制视角上下角度**(`Camera.VAngle`)。
 +
 +```javascript
 +player.FocusVAngle: float
 +```
 +
 +
 +
 +### player.FocusHAngle
 +
 +> 设置&获取玩家**控制视角横向角度**(`Camera.HAngle`)。
 +
 +```javascript
 +player.FocusHAngle: float
 +```
 +
 +
 +
 +### player.FocusEulerAngle
 +
 +> 设置&获取玩家**控制焦点(游戏视角+屏幕方向)**XY角度(`Vector2(x, y)`)。
 +>
 +> 在玩家不同视角模式(`Client.Camera.Mode`)下,坐标处理方式会发生变化。
 +
 +[note2]
 +注意:多数情况下,应该使用`Client\Camera`实现视角相关逻辑。
 +[/note]
 +
 +```javascript
 +player.FocusAngle: Vector2
 +```
 +
 +
 +
 +### player.FocusAngleForward
 +
 +> 获取玩家**控制焦点**前方向量。
 +>
 +> 在玩家不同视角模式(`Client.Camera.Mode`)下,坐标处理方式会发生变化。
 +
 +```javascript
 +player.FocusAngleForward: Vector2
 +```
 +
 +
 +
 +### player.EngineLanguage
 +
 +> 获取玩家正在使用的引擎语言(如果中途改动语言,不会更新)。
 +>
 +> 根据《沙盘引擎》语言机制,通常应该采用此方法作为玩家语言的判定。
 +
 +```javascript
 +player.EngineLanguage: string
 +```
 +
 +
 +
 +### player.ModLanguage
 +
 +> 获取玩家正在使用的模组语言(如果中途改动语言,不会更新)。
 +
 +```javascript
 +player.ModLanguage: string
 +```
 +
 +
 +
 +### player.IsTyping
 +
 +> 获取玩家聊天框输入状态(是否正在输入)。
 +
 +```javascript
 +player.IsTyping: bool
 +```
 +
 +
 +
 +### player.IsComplete
 +
 +> 获取玩家是否完全加载完毕。
 +
 +```javascript
 +player.IsComplete: bool
 +```
 +
 +
 +
 +### player.IsObserver
 +
 +> 获取玩家是否当前为相机观察模式(`Client.Camera.IsObserver`)。
 +
 +```javascript
 +player.IsObserver: bool
 +```
 +
 +
 +
 +### player.VoiceState
 +
 +> 获取玩家语音聊天状态(是否正在语音聊天)。
 +>
 +> **注意:玩家必须`player.SetVoiceAuthority(true)`给予语音权限(默认),且由玩家主动触发按键才会进行聊天。**
 +
 +```javascript
 +player.VoiceState: bool
 +```
 +
 +
 +
 +### player.CameraMode
 +
 +> 获取(只读)玩家相机模式(参考`Client.Camera.Mode`)。
 +
 +```javascript
 +player.CameraMode: int
 +```
 +
 +
 +
 +## Static Function
 +
 +### Player.Find()
 +
 +> 寻找一个玩家实例(通过ID),不存在则返回`null`。
 +
 +```javascript
 +function Player.Find( id: int ): Player
 +```
 +
 +
 +
 +### Player.Search()
 +
 +> 寻找一个玩家实例(通过模糊查找,通常根据玩家名称\ID,不区分大小写),不存在则返回`null`。
 +
 +```javascript
 +function Player.Search( any: string ): Player
 +```
 +
 +```javascript
 +//Players: "Alnny", "Tommy", "Tom"
 +Player.Search("Tom"); //Tom(完整匹配)
 +Player.Search("Tomm"); //Tommy(相似匹配)
 +Player.Search("To"); //Tommy(以最先搜索到的为主)
 +Player.Search("0"); //By ID
 +```
 +
 +
 +
 +
 +### Player.FindByUUID()
 +
 +> 寻找一个玩家实例(通过UUID),不存在则返回`null`。
 +
 +```javascript
 +function Player.FindByUUID( uuid: string ): Player
 +```
 +
 +
 +
 +### Player.GetCount()
 +
 +> 获取当前所有存在玩家数量。
 +
 +```javascript
 +function Player.GetCount(): int
 +```
 +
 +
 +
 +### 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()
 +```
  
  
行 51: 行 699:
  
 > 为玩家设置一个实体(Character),在多数玩法框架的实现过程中,一个角色(Character)是基本的入口点。 > 为玩家设置一个实体(Character),在多数玩法框架的实现过程中,一个角色(Character)是基本的入口点。
 +
 +```javascript
 +function player.SetEntity( entity: Character, isBind: bool = true )
 +/*
 + entity:要绑定的角色对象(如果为null则解除绑定)
 + isBind:是否绑定实体(等同于player.IsBindEntity = isBind),如果设定为true则玩家断开时同时销毁角色,否则将会保留角色
 +*/
 +```
  
 ```javascript ```javascript
行 62: 行 718:
  
  
-### player.CreateMenu()+### player.Kick()
  
-玩家建立一个`NativeMenu`菜单(NativeMenu菜单)+从服务器踢出玩家。
  
 ```javascript ```javascript
-let view = { +function player.Kick( reasonstring = "Kicked" ) 
-    Cover: 5, +```
-    Tag: "Test", +
-    Title: "XXX", +
-    Info: "ABC", +
-    Width: 500, +
-    Align: 1, +
-    Layout: 1, +
-    Items: [ +
-        { +
-            Text: "点击:输出玩家Name", +
-            OnClick: () => { +
-                DLog("PlayerName: " + player.Name); +
-            } +
-        },{ +
-            Input"xxx", +
-            Restrict: "*", +
-            OnFocus: (text) => { +
-                DLog("输入框文本: + text)+
-            } +
-        },{ +
-            Text: "点击:刷一辆载具+关闭菜单", +
-            OnClick: () => { +
-                Vehicle.Create(10, player.Entity.Pos, player.Entity.Angle); +
-                player.DestroyNativeMenu(); +
-            } +
-        } +
-    ] +
-};+
  
-player.CreateNativeMenu(view);+ 
 + 
 +### player.Ban() 
 + 
 +> 从服务器封禁玩家(仅在服务器运行时生效,重启服务器将清空封禁列表)。 
 +
 +> 如果希望实现持久化的封禁列表,请考虑自行实现维护一个`txt|json`文件表,在每次服务器建立后读取文件+遍历执行`Player.BanUUID()`。 
 + 
 +```javascript 
 +function player.Ban( reason: string = "Banned" )
 ``` ```
  
  
-![](asset:1686063636772.png)+ 
 +### player.Message() 
 + 
 +> 为玩家发送一条单独公屏消息(在消息框中)。 
 + 
 +```javascript 
 +function player.Message( text: string ) 
 +``` 
 + 
 + 
 + 
 +### player.Announce() 
 + 
 +> 为玩家发送一条单独**公告\大文字**消息。 
 + 
 +```javascript 
 +function player.Announce( text: string, type: int = 0, time: float = 6 ) 
 +``` 
 + 
 + 
 + 
 +### player.Subtitle() 
 + 
 +> 为玩家发送一条单独**底部字幕**消息。 
 + 
 +```javascript 
 +function player.Subtitle( text: string ) 
 +``` 
 + 
 + 
 + 
 +### player.NetworkRPC() 
 + 
 +> 为玩家发送一条RPC指令。 
 +
 +> 目标玩家客户端脚本通过`OnServerNetworkRPC()`接收数据。 
 +
 +> **注意:`CMD\RPC`方法仅支持基础类型,并且会自动类型转换。** 
 + 
 +```javascript 
 +function NetworkRPC( rpc: string, arg0: any, arg1: any, arg2: any ) 
 +``` 
 + 
 + 
 + 
 +### player.SendData() 
 + 
 +> 为玩家发送一条**服务端>客户端**的自定义Stream数据信息。 
 +
 +> 目标玩家客户端脚本通过`OnServerStreamData()`接收数据。 
 +
 +> **注意:这里不应该放置特别大的数据内容(4096),否则可能造成网络阻塞。** 
 + 
 +```javascript 
 +function player.SendData( number: float, data: string = ""
 +``` 
 + 
 + 
 + 
 +### player.ClientExec() 
 + 
 +> 为玩家发送一条**客户端脚本代码**,目标玩家**客户端**将执行对应的脚本代码。 
 +
 +> **注意:这里不应该放置特别大的数据内容(2048),否则可能造成网络阻塞。** 
 + 
 +```javascript 
 +function player.ClientExec( code: string ) 
 +``` 
 + 
 + 
 + 
 +### player.PlaySound() 
 + 
 +> 为玩家播放一段**声音**,用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.PlaySound( audioIDint, loop: bool = false, volume: float = 1f, tag: string = null ): string 
 +``` 
 + 
 + 
 + 
 +### player.Play3DSound() 
 + 
 +> 为玩家播放一段**3D空间声音**,用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.Play3DSound( audioID: int, pos: Vector, radius: float, loop: bool = false, volume: float = 1f, tag: string = null ): string 
 +``` 
 + 
 + 
 + 
 +### player.StopSound() 
 + 
 +> 为玩家停止播放并销毁一段**声音实例**,用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.StopSound( uuid: string, fadeTime: float = 0 ) 
 +``` 
 + 
 + 
 + 
 +### player.PlayMusic() 
 + 
 +> 为玩家播放**音乐**(音乐轨道),用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.PlayMusic( audioID: int, loop: bool = false, volume: fadeTime = 3 ) 
 +``` 
 + 
 + 
 + 
 +### player.Play3DMusic() 
 + 
 +> 为玩家播放**3D空间音乐**(音乐轨道),用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.Play3DMusic( audioID: int, pos: Vector, radius: float, loop: bool = false, fadeTime: float = 3f ) 
 +``` 
 + 
 + 
 + 
 +### player.PauseMusic() 
 + 
 +> 为玩家暂停播放**音乐**(音乐轨道),用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.PauseMusic( fadeTime: float = 3 ) 
 +``` 
 + 
 + 
 + 
 +### player.ResumeMusic() 
 + 
 +> 为玩家继续播放**音乐**(音乐轨道),用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.ResumeMusic( fadeTime: float = 3 ) 
 +``` 
 + 
 + 
 + 
 +### player.StopMusic() 
 + 
 +> 为玩家停止播放并销毁**音乐实例**(音乐轨道),用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.StopMusic( fadeTime: float = 3 ) 
 +``` 
 + 
 + 
 + 
 +### player.PlayNatural() 
 + 
 +> 为玩家播放**背景环境音**(背景音轨道),用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.PlayNatural( audioID: int, channel: int, loop: bool = true, volume: fadeTime = 3 ) 
 +``` 
 + 
 + 
 + 
 +### player.StopNatural() 
 + 
 +> 为玩家停止播放并销毁指定**背景环境音实例**(背景音轨道),用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.StopNatural( channel: int, fadeTime: float = 3 ) 
 +``` 
 + 
 + 
 + 
 +### player.StopAllNatural() 
 + 
 +> 为玩家停止播放并销毁全部**背景环境音实例**(背景音轨道),用法及详细说明与[客户端Audio](scripting/client/audio)相同。 
 + 
 +```javascript 
 +function player.StopAllNatural( fadeTime: float = 3 ) 
 +``` 
 + 
 + 
 + 
 +### player.RunTaskAction() 
 + 
 +> 为玩家执行一次**倒计时任务**(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("install", 5, "Installation in progress...", () => { 
 +    //OnComplete 
 +}); 
 +``` 
 + 
 + 
 + 
 +### 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(): string 
 +``` 
 + 
 + 
 + 
 +### player.ExistTaskAction() 
 + 
 +> 获取玩家**倒计时任务**是否**存在**并进行中。 
 + 
 +```javascript 
 +function player.ExistTaskAction(): bool 
 +``` 
 + 
 + 
 + 
 +### player.SetVoiceMode() 
 + 
 +> 设置玩家语音聊天模式,**默认关闭**。 
 +
 +> ==**如果希望激活语音聊天功能,请为玩家设定一个非关闭的语音模式。**== 
 + 
 +```javascript 
 +function player.SetVoiceMode( mode: int = 0 ) 
 +``` 
 + 
 +| 索引 | 语音聊天模式   | 说明                                                         | 
 +| ---- | -------------- | ------------------------------------------------------------ | 
 +| 0    | 关闭           | 不会发送与接收任何语音聊天                                   | 
 +| 1    | 全局模式       | 发送与接收所有聊天,除特定情况及权限、禁言等                 | 
 +| 2    | (频道)组模式 | 发送与接收相同频道组(`VoiceGroup`)的聊天,除特定情况及权限、禁言等 | 
 + 
 + 
 + 
 +### player.GetVoiceMode() 
 + 
 +> 获取玩家语音聊天模式。 
 + 
 +```javascript 
 +function player.GetVoiceMode(): int 
 +``` 
 + 
 + 
 + 
 +### player.SetVoiceWorldMode() 
 + 
 +> 设置玩家语音聊天世界模式开关(3D空间音频,跟随玩家的实体对象)。 
 +
 +> **此选项可能在部分玩法中提高玩家沉浸感,就像其他玩家真的在不远处说话一样。** 
 +
 +> *(可通过`GameRule > voice_worlddistance `控制3D空间声音的传播距离)* 
 + 
 +```javascript 
 +function player.SetVoiceWorldMode( active: bool ) 
 +``` 
 + 
 + 
 + 
 +### player.GetVoiceWorldMode() 
 + 
 +> 获取玩家语音聊天世界模式开关。 
 + 
 +```javascript 
 +function player.GetVoiceWorldMode(): bool 
 +``` 
 + 
 + 
 + 
 +### player.SetVoiceAuthority() 
 + 
 +> 设置玩家语音聊天**权限**开关(静音\禁言),默认开启(`true`)。 
 +
 +> **==注意:此选项必须设置为`true`,玩家才有资格进行说话,否则玩家将无法在语音聊天中说话(禁言Muted)。==** 
 +
 +> ==**(此选项并非是玩家麦克风控制开关,安全考虑,只有玩家自行按住【说话按键】时才会录入音频)**== 
 + 
 +```javascript 
 +function player.SetVoiceAuthority( active: bool ) 
 +``` 
 + 
 + 
 + 
 +### player.GetVoiceAuthority() 
 + 
 +> 获取玩家语音聊天**权限**开关。 
 + 
 +```javascript 
 +function player.GetVoiceAuthority(): bool 
 +``` 
 + 
 + 
 + 
 +### player.SetVoiceIgnore() 
 + 
 +> 设置玩家屏蔽指定玩家语音开关,可用于屏蔽其他玩家的语音输出,但不会屏蔽自身对其他玩家的声音。 
 + 
 +```javascript 
 +function player.SetVoiceIgnore( player: Player, active: bool ) 
 +``` 
 + 
 + 
 + 
 +### player.GetVoiceIgnore() 
 + 
 +> 获取玩家语音聊天**权限**开关。 
 + 
 +```javascript 
 +function player.GetVoiceIgnore( player: Player ): bool 
 +``` 
 + 
 + 
 + 
 + 
 +### player.TestVisiblePoint() 
 + 
 +> 检测玩家相机是否能看到指定坐标(模糊检测,边缘检测并非绝对准确,模拟本地`Camera.TestVisiblePoint()`)。 
 + 
 +```javascript 
 +function player.TestVisiblePoint( pos: Vector ): bool 
 +``` 
 + 
 + 
 + 
 +### player.SetBackpackOtherTarget() 
 + 
 +> 设置玩家**额外的观察背包实例**(除本地对象外的另一个背包)。 
 +
 +> 此功能可扩展许多玩法,例如:商店、交易、背包共享等。 
 +
 +> 如果没有设置其他背包实例,玩家背包UI将仅显示自身对象背包。 
 + 
 +```javascript 
 +function player.SetBackpackOtherTarget( otherBackpack: Backpack, observerMode: int = 0 ) 
 +``` 
 + 
 +- `observerMode`:观察模式,默认为`0`(0=可读写,1=只读) 
 + 
 + 
 + 
 +### player.GetBackpackOtherTarget() 
 + 
 +> 获取玩家**额外的观察背包实例**。 
 + 
 +```javascript 
 +function player.GetBackpackOtherTarget(): Backpack 
 +``` 
 + 
 + 
 + 
 +### player.SetBackpackTempProp() 
 + 
 +> 设置玩家**临时背包物品**(随鼠标移动的临时选项),可设置为`null`。 
 + 
 +```javascript 
 +function player.SetBackpackTempProp( prop: Prop ) 
 +``` 
 + 
 + 
 + 
 +### player.GetBackpackTempProp() 
 + 
 +> 获取玩家**临时背包物品**(随鼠标移动的临时选项),如不存在则为`prop.IsValid() == false`。 
 + 
 +```javascript 
 +function player.GetBackpackTempProp(): Prop 
 +``` 
 + 
 + 
 + 
 +### player.ReturnBackpackTempProp() 
 + 
 +> 尝试返回玩家**临时背包物品**(随鼠标移动的临时选项),尝试自动将临时物品添加到背包。 
 +
 +> 此方法与玩家**存在临时物品时关闭背包**效果相同,如果有空位则自动添加到背包并移出临时物品,如果没有空位则触发丢弃事件。 
 +
 +> **注意:有时可能希望处理玩家的背包(例如清空背包),但有可能玩家正在操作临时物品,这样的话`Backpack`常规方式不会处理到临时物品,因此需要留意玩家手中的临时物品。** 
 + 
 +```javascript 
 +function player.ReturnBackpackTempProp(): bool 
 +``` 
 + 
 +- `return`:是否正常返回(如果没有临时物品,也会返回`true`) 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
 + 
  
 </markdown> </markdown>