角色系统 / Player
Player Class
角色管理器
Player 包含当前连接到MW服务器的Player对象。它负责管理角色的各种唯一标识符(ID)并提供创建、获取并管理玩家的功能。
角色管理器类会维护一个字典,用于存储所有角色的唯一标识符。用于区分不同的角色。
角色管理器会提供方法来添加、删除和检索角色的 ID。当创建一个新角色时,该角色的ID会被分配并添加到管理器的列表中。当角色不再存在时,该ID会被从列表中删除。通过这些方法,可以方便地管理角色的ID集合。
角色管理器还提供获取玩家的功能。通过玩家的 ID,可以轻松地从管理器中获取对应的角色对象。这样,其他部分的代码可以使用玩家的ID来获取与之相关联的角色实例,进行进一步的处理和操作。
值得注意的是可通过 Player.localPlayer.character 获取本地玩家角色,开启本地角色玩家的配置。
Table of contents
Properties
onCharacterAdd: MulticastDelegate <(character : Character ) => void > |
---|
玩家的角色创建时,执行绑定函数 |
onCharacterRemove: MulticastDelegate <(character : Character ) => void > |
玩家的角色被移除时,执行绑定函数 |
onPlayerAdd: MulticastDelegate <(player : Player ) => void > |
玩家新增时,执行绑定函数 |
onPlayerDisconnect: MulticastDelegate <(player : Player ) => void > |
玩家断线委托 |
onPlayerReconnect: MulticastDelegate <(player : Player ) => void > |
玩家重连委托 |
onPlayerRemove: MulticastDelegate <(player : Player ) => void > |
玩家被移除时,执行绑定函数 |
onUserAvatarUpdated: MulticastDelegate <() => void > client |
用户平台形象变化时,执行绑定函数 |
Accessors
character(): Character |
---|
控制角色 |
nickname(): string |
玩家昵称 |
ping(): number |
用于记录和显示玩家的网络延迟。 |
playerId(): number |
玩家ID |
teamId(): string |
队伍ID |
teleportId(): string |
传送ID |
userId(): string |
用户平台ID |
localPlayer(): Player client |
客户端正在运行的玩家。 |
Methods
control(pawn : Pawn ): boolean server |
---|
控制一个 Pawn 对象 |
getPlayerState<T : extends PlayerState <T >>(type : (...args : unknown []) => T : extends PlayerState <T >): T : extends PlayerState <T > |
获取 PlayerState 实例 |
asyncGetLocalPlayer(): Promise <Player > client |
异步获取本地玩家。 |
asyncGetPlayer(uniqueId : string number ): Promise <Player > |
异步获取玩家 |
getAllPlayers(): Player [] |
获取当前所有玩家。 |
getControllerRotation(outer? : Rotation ): Rotation client |
获取控制器的旋转 |
getPlayer(uniqueId : string number ): Player |
获取玩家,根据userId找到对应的玩家 |
setControllerRotation(newRotation : Rotation ): void client |
覆写控制器的旋转 |
Properties
onCharacterAdd
• Readonly
onCharacterAdd: MulticastDelegate
<(character
: Character
) => void
>
玩家的角色创建时,执行绑定函数
Precautions
在创建玩家后,会接着创建玩家的角色,当事件触发时角色的骨骼和碰撞体已经创建完毕,可以开始移动,而角色的外观和挂件则可能需要等待一段时间才能创建完成。如果需要等待角色的彻底完成可以使用Character:asyncReady来进行等待,又或者通过监听Character.onDescriptionComplete事件来确保角色拥有完整的外观和挂件。
ts
export default class Example_Player_onCharacterAdd extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
Player.onPlayerAdd.add((player) => {
player.onCharacterAdd.add((character) => {
character.displayName = "John";
});
});
}
}
}
export default class Example_Player_onCharacterAdd extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
Player.onPlayerAdd.add((player) => {
player.onCharacterAdd.add((character) => {
character.displayName = "John";
});
});
}
}
}
onCharacterRemove
• Readonly
onCharacterRemove: MulticastDelegate
<(character
: Character
) => void
>
玩家的角色被移除时,执行绑定函数
Precautions
该事件在移除玩家角色之前触发,此时可以回收玩家角色身上挂载的对象或者访问身上的数据用作存档。
ts
export default class Example_Player_onCharacterRemove extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
Player.onPlayerAdd.add((player) => {
player.onCharacterRemove.add((character) => {
let effect = GameObject.spawn("298313") as Effect;
effect.worldTransform.position = character.worldTransform.position;
effect.play();
});
});
}
}
}
export default class Example_Player_onCharacterRemove extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
Player.onPlayerAdd.add((player) => {
player.onCharacterRemove.add((character) => {
let effect = GameObject.spawn("298313") as Effect;
effect.worldTransform.position = character.worldTransform.position;
effect.play();
});
});
}
}
}
onPlayerAdd
▪ Static
Readonly
onPlayerAdd: MulticastDelegate
<(player
: Player
) => void
>
玩家新增时,执行绑定函数
Precautions
当新玩家加入游戏创建Player对象时触发该事件。需注意客户端无法监听到本地玩家的加入,通常建议在服务端给该事件绑定函数。
ts
export default class Example_Player_onPlayerAdd extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
Player.onPlayerAdd.add((player) => {
console.log("Player ID " + player.playerId + "User ID " + player.userId);
});
}
}
}
export default class Example_Player_onPlayerAdd extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
Player.onPlayerAdd.add((player) => {
console.log("Player ID " + player.playerId + "User ID " + player.userId);
});
}
}
}
onPlayerDisconnect
▪ Static
Readonly
onPlayerDisconnect: MulticastDelegate
<(player
: Player
) => void
>
玩家断线委托
Precautions
当玩家掉线时执行绑定函数。该委托双端触发机制不同。在客户端只被本地玩家掉线事件触发,触发时机为掉线的瞬间。在服务端被任意玩家掉线事件触发,触发时机为5秒内未收到客户端玩家消息即为掉线。 当客户端切后台、看广告等OnPause操作时,该回调在服务器上也会被触发。
ts
@Component
export default class Example_Player_OnPlayerDisconnect extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
// 给【玩家加入】委托添加一个函数,打印玩家加入游戏消息
Player.onPlayerJoin.add((player) => {
console.log("Player " + player.userId + " joined the Game");
});
// 给【玩家离开】委托添加一个函数,打印玩家离开游戏消息
Player.onPlayerLeave.add((player) => {
console.log("Player " + player.userId + " Left the Game");
});
// 给【玩家断线】委托添加一个函数,打印玩家断线消息
Player.onPlayerDisconnect.add((player) => {
console.log("Player " + player.userId + " is disconnected");
});
// 给【玩家重连】委托添加一个函数,打印玩家重连消息
Player.onPlayerReconnect.add((player) => {
console.log("Player " + player.userId + " is reconnected");
});
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myself = Player.localPlayer;
// 给【玩家断线】委托添加一个函数,打印玩家断线消息
Player.onPlayerDisconnect.add((player) => {
console.log("Player " + player.userId + " is disconnected");
});
// 给【玩家重连】委托添加一个函数,打印玩家重连消息
Player.onPlayerReconnect.add((player) => {
console.log("Player " + player.userId + " is reconnected");
});
}
}
}
@Component
export default class Example_Player_OnPlayerDisconnect extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
// 给【玩家加入】委托添加一个函数,打印玩家加入游戏消息
Player.onPlayerJoin.add((player) => {
console.log("Player " + player.userId + " joined the Game");
});
// 给【玩家离开】委托添加一个函数,打印玩家离开游戏消息
Player.onPlayerLeave.add((player) => {
console.log("Player " + player.userId + " Left the Game");
});
// 给【玩家断线】委托添加一个函数,打印玩家断线消息
Player.onPlayerDisconnect.add((player) => {
console.log("Player " + player.userId + " is disconnected");
});
// 给【玩家重连】委托添加一个函数,打印玩家重连消息
Player.onPlayerReconnect.add((player) => {
console.log("Player " + player.userId + " is reconnected");
});
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myself = Player.localPlayer;
// 给【玩家断线】委托添加一个函数,打印玩家断线消息
Player.onPlayerDisconnect.add((player) => {
console.log("Player " + player.userId + " is disconnected");
});
// 给【玩家重连】委托添加一个函数,打印玩家重连消息
Player.onPlayerReconnect.add((player) => {
console.log("Player " + player.userId + " is reconnected");
});
}
}
}
onPlayerReconnect
▪ Static
Readonly
onPlayerReconnect: MulticastDelegate
<(player
: Player
) => void
>
玩家重连委托
Precautions
当玩家重连时执行绑定函数,断线回调会先触发,之后连续收到客户端消息则触发重连回调。
ts
@Component
export default class Example_Player_OnPlayerReconnect extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
// 给【玩家加入】委托添加一个函数,打印玩家加入游戏消息
Player.onPlayerJoin.add((player) => {
console.log("Player " + player.userId + " joined the Game");
});
// 给【玩家离开】委托添加一个函数,打印玩家离开游戏消息
Player.onPlayerLeave.add((player) => {
console.log("Player " + player.userId + " Left the Game");
});
// 给【玩家断线】委托添加一个函数,打印玩家断线消息
Player.onPlayerDisconnect.add((player) => {
console.log("Player " + player.userId + " is disconnected");
});
// 给【玩家重连】委托添加一个函数,打印玩家重连消息
Player.onPlayerReconnect.add((player) => {
console.log("Player " + player.userId + " is reconnected");
});
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myself = Player.localPlayer;
// 给【玩家断线】委托添加一个函数,打印玩家断线消息
Player.onPlayerDisconnect.add((player) => {
console.log("Player " + player.userId + " is disconnected");
});
// 给【玩家重连】委托添加一个函数,打印玩家重连消息
Player.onPlayerReconnect.add((player) => {
console.log("Player " + player.userId + " is reconnected");
});
}
}
}
@Component
export default class Example_Player_OnPlayerReconnect extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
// 给【玩家加入】委托添加一个函数,打印玩家加入游戏消息
Player.onPlayerJoin.add((player) => {
console.log("Player " + player.userId + " joined the Game");
});
// 给【玩家离开】委托添加一个函数,打印玩家离开游戏消息
Player.onPlayerLeave.add((player) => {
console.log("Player " + player.userId + " Left the Game");
});
// 给【玩家断线】委托添加一个函数,打印玩家断线消息
Player.onPlayerDisconnect.add((player) => {
console.log("Player " + player.userId + " is disconnected");
});
// 给【玩家重连】委托添加一个函数,打印玩家重连消息
Player.onPlayerReconnect.add((player) => {
console.log("Player " + player.userId + " is reconnected");
});
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myself = Player.localPlayer;
// 给【玩家断线】委托添加一个函数,打印玩家断线消息
Player.onPlayerDisconnect.add((player) => {
console.log("Player " + player.userId + " is disconnected");
});
// 给【玩家重连】委托添加一个函数,打印玩家重连消息
Player.onPlayerReconnect.add((player) => {
console.log("Player " + player.userId + " is reconnected");
});
}
}
}
onPlayerRemove
▪ Static
Readonly
onPlayerRemove: MulticastDelegate
<(player
: Player
) => void
>
玩家被移除时,执行绑定函数
Precautions
当玩家退出游戏准备移除Player对象时触发该事件。
ts
export default class Example_Player_onPlayerRemove extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
Player.onPlayerRemove.add((player) => {
console.log("Player ID " + player.playerId + "User ID " + player.userId);
});
}
}
}
export default class Example_Player_onPlayerRemove extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
Player.onPlayerRemove.add((player) => {
console.log("Player ID " + player.playerId + "User ID " + player.userId);
});
}
}
}
onUserAvatarUpdated
▪ Static
onUserAvatarUpdated: MulticastDelegate
<() => void
> client
用户平台形象变化时,执行绑定函数
Precautions
当玩家切出游戏,进入角色编辑器修改外观保存后,切回游戏时触发该事件。
ts
@Component
export default class Example_Player_onUserAvatarUpdated extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
Player.onUserAvatarUpdated.add(() => {
AccountService.downloadData(Player.localPlayer.character, () => {}, 0);
});
}
}
}
@Component
export default class Example_Player_onUserAvatarUpdated extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
Player.onUserAvatarUpdated.add(() => {
AccountService.downloadData(Player.localPlayer.character, () => {}, 0);
});
}
}
}
Accessors
character
• | ||
---|---|---|
控制角色 Precautions 玩家控制的角色,属于Pawn对象的一种。在玩家切换控制角色时, 客户端上无法立即获取到最新值。其余情况下,只要获取到玩家就可以同时获取到加载完成的控制角色。 Returns
|
ts
@Component
export default class Example_Player_Character extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家控制的character对象的guid和名字
console.log("My character: " + myPlayer.character.gameObjectId + " " + myPlayer.character.displayName);
}
}
}
@Component
export default class Example_Player_Character extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家控制的character对象的guid和名字
console.log("My character: " + myPlayer.character.gameObjectId + " " + myPlayer.character.displayName);
}
}
}
nickname
• | ||
---|---|---|
玩家昵称 Returns
|
ts
@Class
export default class Example_Player_Nickname extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家的昵称
console.log("My nickname: " + myPlayer.nickname);
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
@Class
export default class Example_Player_Nickname extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家的昵称
console.log("My nickname: " + myPlayer.nickname);
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
ping
• | ||
---|---|---|
用于记录和显示玩家的网络延迟。 网络延迟是指从玩家在游戏中执行某个操作到该操作在其他玩家的游戏中显示出来所需的时间。通常以毫秒(ms)为单位表示。较低的延迟意味着玩家的操作能够快速传输到服务器和其他玩家,并且游戏的响应更加即时。 Precautions 玩家客户端的网络延迟。以毫秒为单位;-1时表示获取失败。 Returns
|
ts
@Component
export default class Example_Player_Ping extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teamId) {
console.log("My teamId: " + myPlayer.teamId);
} else {
console.log("My teamId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
@Component
export default class Example_Player_Ping extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teamId) {
console.log("My teamId: " + myPlayer.teamId);
} else {
console.log("My teamId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
playerId
• | ||
---|---|---|
玩家ID playerID是运行时ID,每次进入游戏时ID都会更换;userID 是唯一标识玩家ID,不会改变的ID Returns
|
ts
@Component
export default class Example_Player_PlayerId extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teamId) {
console.log("My teamId: " + myPlayer.teamId);
} else {
console.log("My teamId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
@Component
export default class Example_Player_PlayerId extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teamId) {
console.log("My teamId: " + myPlayer.teamId);
} else {
console.log("My teamId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
teamId
• | ||
---|---|---|
队伍ID Precautions 玩家的队伍ID(通过游戏跳转自动形成)。如玩家不在任何队伍中则该值为空。 Returns
|
ts
@Component
export default class Example_Player_TeamId extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teamId) {
console.log("My teamId: " + myPlayer.teamId);
} else {
console.log("My teamId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
@Component
export default class Example_Player_TeamId extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teamId) {
console.log("My teamId: " + myPlayer.teamId);
} else {
console.log("My teamId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
teleportId
• | ||
---|---|---|
传送ID Precautions 玩家的传送ID(通过传送自动形成)。如玩家不是通过传送进入的当前场景则该值为空。 Returns
|
ts
@Component
export default class Example_Player_TeleportId extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teleportId) {
console.log("My teleportId: " + myPlayer.teleportId);
} else {
console.log("My teleportId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
@Component
export default class Example_Player_TeleportId extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teleportId) {
console.log("My teleportId: " + myPlayer.teleportId);
} else {
console.log("My teleportId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
userId
• | ||
---|---|---|
用户平台ID 玩家的用户平台ID。该值是多端同步的,可以作为玩家唯一ID使用。玩家对象准备好后需等待一段时间该值才能准备好。 Returns
|
ts
@Component
export default class Example_Player_UserId extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teamId) {
console.log("My teamId: " + myPlayer.teamId);
} else {
console.log("My teamId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
@Component
export default class Example_Player_UserId extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家的平台用户ID
console.log("My userId: " + myPlayer.userId);
// 打印本地玩家游戏内的玩家ID
console.log("My playerId: " + myPlayer.playerId);
// 打印本地玩家的队伍ID,如果当前没有队伍则打印null
if(myPlayer.teamId) {
console.log("My teamId: " + myPlayer.teamId);
} else {
console.log("My teamId: " + "null");
}
// 打印本地玩家的网络延迟
console.log("My ping: " + myPlayer.ping);
}
}
}
localPlayer
• |
---|
客户端正在运行的玩家。 LocalPlayer 是一个只读属性。 因为在客户端上运行。 对于 Script 对象运行其代码的服务器,此属性为 null。 当前客户端对应的玩家。仅客户端调用返回本地玩家,服务端调用无效并在控制台打印警告。 Returns |
ts
@Component
export default class Example_Player_LocalPlayer extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家控制的character对象的guid和名字
console.log("My character: " + myPlayer.character.gameObjectId + " " + myPlayer.character.displayName);
// 添加一个按键方法:按下键盘“1”,角色隐身2秒
InputUtil.onKeyDown(Keys.One, () => {
myPlayer.character.setVisibility(PropertyStatus.Off);
TimeUtil.delaySecond(2).then(() => {
myPlayer.character.setVisibility(PropertyStatus.On);
});
});
}
}
}
@Component
export default class Example_Player_LocalPlayer extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 打印本地玩家控制的character对象的guid和名字
console.log("My character: " + myPlayer.character.gameObjectId + " " + myPlayer.character.displayName);
// 添加一个按键方法:按下键盘“1”,角色隐身2秒
InputUtil.onKeyDown(Keys.One, () => {
myPlayer.character.setVisibility(PropertyStatus.Off);
TimeUtil.delaySecond(2).then(() => {
myPlayer.character.setVisibility(PropertyStatus.On);
});
});
}
}
}
Player |
---|
Methods
control
• control(pawn
): boolean
server
控制一个 Pawn 对象
Parameters
pawn Pawn | 目标控制对象 |
---|
Returns
boolean | 操纵结果 |
---|
ts
@Component
export default class Example_Player_Control extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
// 在服务端添加一个【创建角色并控制】事件监听器
mw.Event.addClientListener("SpawnCharacterAndControl", (player) => {
let newPawn = Player.spawnDefaultCharacter();
newPawn.worldTransform.position = new Vector(200, 0, 500);
player.control(newPawn);
});
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 给本地玩家的【玩家控制对象变化】委托添加一个函数:在生成并控制的新角色位置播放一个特效
myPlayer.onPawnChange.add((pawn) => {
EffectService.playAtPosition("7750", new Vector(200, 0, 500));
});
// 添加一个按键方法:按下键盘“1”,向服务端发送事件【创建角色并控制】
InputUtil.onKeyDown(Keys.One, () => {
mw.Event.dispatchToServer("SpawnCharacterAndControl");
});
}
}
}
@Component
export default class Example_Player_Control extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
// 在服务端添加一个【创建角色并控制】事件监听器
mw.Event.addClientListener("SpawnCharacterAndControl", (player) => {
let newPawn = Player.spawnDefaultCharacter();
newPawn.worldTransform.position = new Vector(200, 0, 500);
player.control(newPawn);
});
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 获取当前客户端的玩家(自己)
let myPlayer = Player.localPlayer;
// 给本地玩家的【玩家控制对象变化】委托添加一个函数:在生成并控制的新角色位置播放一个特效
myPlayer.onPawnChange.add((pawn) => {
EffectService.playAtPosition("7750", new Vector(200, 0, 500));
});
// 添加一个按键方法:按下键盘“1”,向服务端发送事件【创建角色并控制】
InputUtil.onKeyDown(Keys.One, () => {
mw.Event.dispatchToServer("SpawnCharacterAndControl");
});
}
}
}
getPlayerState
• getPlayerState<T
>(type
): T
获取 PlayerState 实例
Parameters
type (...args : unknown []) => T | PlayerState 派生类 default: null |
---|
Returns
T | PlayerState实例 |
---|
PlayerState 对象的作用是帮助游戏追踪和管理玩家的个人数据。它存储了与每个玩家相关的信息,这样游戏就可以根据需要随时访问和更新这些信息。
举个例子来说,假设你正在玩一款多人射击游戏。每个玩家都有一个 PlayerState 对象,其中包含了玩家的得分、击杀数和死亡数等数据。当玩家击败敌人时,游戏会将得分加到对应玩家的PlayerState中。这样,游戏就可以根据每个玩家的PlayerState来显示排行榜或者判断胜负。
总的来说,用于跟踪和存储与每个玩家相关的数据和状态。它帮助游戏管理玩家的个人信息,如得分、生命值等,并在多人游戏中确保玩家状态的同步。通过 PlayerState,游戏可以更好地处理多人游戏中的个人和团队数据,以提供更丰富的游戏体验。
使用示例: 创建一个名为"PlayerStateExample"的脚本,放置在对象栏中,打开脚本,输入以下代码保存。把启动参数的玩家数量改为2,运行游戏按下R键将看到其中一个客户端收到test同步。按下P键将打印客户端的test值。ts
// 服务端每个玩家进入游戏时会自动创建一个实例
export class GamePlayerState extends mw.PlayerState {
@Property({replicated: true, onChanged: "onRepTest"})
test = "";
onRepTest(path: string[], value: string, oldVal: string) {
console.log(`onRepTest path: ${path} value: ${value} oldVal: ${oldVal}`);
}
}
@Component
export default class PlayerStateExample extends mw.Script {
protected onStart(): void {
// 按下R建在服务端随机一个玩家修改GamePlayerState的test属性
InputUtil.onKeyDown(Keys.R, () => this.random());
// 按下P建打印主控端玩家GamePlayState的test属性
InputUtil.onKeyDown(Keys.P, () => {
const playerState = Player.localPlayer.getPlayerState(GamePlayerState);
console.log(`test: ${playerState.test}`);
});
}
@RemoteFunction(Server)
random() {
const players = Player.getAllPlayers();
// 随机一个玩家
const luckPlayer = players[Math.floor(Math.random() * players.length)];
// 获取到GamePlayerState实例
const playerState = luckPlayer.getPlayerState(GamePlayerState);
playerState.test = `random: ${ Math.floor(Math.random() * 100)}`;
}
}
// 服务端每个玩家进入游戏时会自动创建一个实例
export class GamePlayerState extends mw.PlayerState {
@Property({replicated: true, onChanged: "onRepTest"})
test = "";
onRepTest(path: string[], value: string, oldVal: string) {
console.log(`onRepTest path: ${path} value: ${value} oldVal: ${oldVal}`);
}
}
@Component
export default class PlayerStateExample extends mw.Script {
protected onStart(): void {
// 按下R建在服务端随机一个玩家修改GamePlayerState的test属性
InputUtil.onKeyDown(Keys.R, () => this.random());
// 按下P建打印主控端玩家GamePlayState的test属性
InputUtil.onKeyDown(Keys.P, () => {
const playerState = Player.localPlayer.getPlayerState(GamePlayerState);
console.log(`test: ${playerState.test}`);
});
}
@RemoteFunction(Server)
random() {
const players = Player.getAllPlayers();
// 随机一个玩家
const luckPlayer = players[Math.floor(Math.random() * players.length)];
// 获取到GamePlayerState实例
const playerState = luckPlayer.getPlayerState(GamePlayerState);
playerState.test = `random: ${ Math.floor(Math.random() * 100)}`;
}
}
Type parameters
T | extends PlayerState <T > |
---|
asyncGetLocalPlayer
• Static
asyncGetLocalPlayer(): Promise
<Player
> client
异步获取本地玩家。
Returns
Promise <Player > | 返回本地玩家 |
---|
通常在UI脚本中使用,当获取还未创建出的本地玩家角色时,会使用此异步加载接口,最长等待10秒,等待本地角色加载出来再获取。
当正常获取本地玩家时,使用 Player.localPlayer 即可。
仅在UI脚本中需要使用此异步方法获取 localPlayer。仅客户端调用返回本地玩家,服务端调用无效并在控制台打印警告。
asyncGetPlayer
• Static
asyncGetPlayer(uniqueId
): Promise
<Player
>
异步获取玩家
Parameters
uniqueId string number | 玩家ID range: 依据玩家 ID 决定 type: 整数 |
---|
Returns
Promise <Player > | 玩家对象 |
---|
ts
@Component
export default class Example_Player extends Script {
protected onStart(): void {
Player.asyncGetPlayer(Player.localPlayer.playerId).then((player)=>{
console.log(player.playerId)
});
}
}
@Component
export default class Example_Player extends Script {
protected onStart(): void {
Player.asyncGetPlayer(Player.localPlayer.playerId).then((player)=>{
console.log(player.playerId)
});
}
}
getAllPlayers
• Static
getAllPlayers(): Player
[]
获取当前所有玩家。
Returns
Player [] | 服务器中所有玩家的数组 |
---|
此方法返回当前连接的所有玩家的数组,当与 for 循环结合使用时,它对于迭代游戏中的所有玩家非常有用。
使用示例:将使用到的资源:“27087”拖入优先加载栏。创建一个名为"Example_Player_GetAllPlayers"的脚本,放置在对象栏中,打开脚本,输入以下代码保存,运行游戏,你将在服务端添加一个【打印游戏内全部玩家信息】事件监听器,监听事件后在场景中看到一个皇冠在玩家角色的头顶生成的效果并在控制台打印玩家们的 userId,遇到发起事件的客户端玩家时提示 This is me。 代码如下:ts
@Component
export default class Example_Player_GetAllPlayers extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
// 在服务端添加一个【打印游戏内全部玩家信息】事件监听器
mw.Event.addClientListener("PrintPlayersInfo", (player) => {
// 遍历Players数组,打印他们的userId,遇到发起事件的客户端玩家时提示This is me,并生成一个皇冠在玩家角色的头顶
Player.getAllPlayers().forEach((value) => {
if(value.playerId == player.playerId) {
console.log(" Player " + player.userId + " This is me");
let crown = GameObject.spawn<Model>("27087");
crown.setCollision(CollisionStatus.Off);
value.character.attachToSlot(crown, HumanoidSlotType.Rings);
} else {
console.log(" Player " + player.userId);
}
});
});
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下键盘“1”,向服务端发送事件【打印游戏内全部玩家信息】
InputUtil.onKeyDown(Keys.One, () => {
mw.Event.dispatchToServer("PrintPlayersInfo");
});
}
}
}
@Component
export default class Example_Player_GetAllPlayers extends Script {
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在服务端执行
if(SystemUtil.isServer()) {
// 在服务端添加一个【打印游戏内全部玩家信息】事件监听器
mw.Event.addClientListener("PrintPlayersInfo", (player) => {
// 遍历Players数组,打印他们的userId,遇到发起事件的客户端玩家时提示This is me,并生成一个皇冠在玩家角色的头顶
Player.getAllPlayers().forEach((value) => {
if(value.playerId == player.playerId) {
console.log(" Player " + player.userId + " This is me");
let crown = GameObject.spawn<Model>("27087");
crown.setCollision(CollisionStatus.Off);
value.character.attachToSlot(crown, HumanoidSlotType.Rings);
} else {
console.log(" Player " + player.userId);
}
});
});
}
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
// 添加一个按键方法:按下键盘“1”,向服务端发送事件【打印游戏内全部玩家信息】
InputUtil.onKeyDown(Keys.One, () => {
mw.Event.dispatchToServer("PrintPlayersInfo");
});
}
}
}
getControllerRotation
• Static
getControllerRotation(outer?
): Rotation
client
获取控制器的旋转
Parameters
outer? Rotation | 接收旋转的变量 default:undefined |
---|
Returns
Rotation | 当前控制器输入的旋转 |
---|
Precautions
如果 outer 不为空, 返回 outer,否则返回一个新的 Vector 对象, 建议传入 outer 来减少 new 对象且 outer 不能为 null/undefined
ts
@Component
export default class Example_Player_GetControllerRotation extends Script {
// 声明变量
flag: boolean;
rot: Rotation;
stride: Rotation;
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
this.flag = false;
this.rot = Rotation.zero;
this.stride = new Rotation(0, 0, 1);
// 开启循环周期函数
this.useUpdate = true;
// 添加一个按键方法:按下键盘“1”,向服务端发送事件【创建角色并控制】
InputUtil.onKeyDown(Keys.One, () => {
this.flag = !this.flag;
});
}
}
// 周期函数每帧执行,此函数执行需要将this.useUpdate赋值为true,dt是当前帧与上一帧的延迟(秒)
protected onUpdate(dt: number): void {
if(SystemUtil.isClient() && this.flag) {
// 获取当前控制器输入的旋转并叠加步长进行覆盖
Player.getControllerRotation(this.rot);
Player.setControllerRotation(this.rot.add(this.stride));
}
}
}
@Component
export default class Example_Player_GetControllerRotation extends Script {
// 声明变量
flag: boolean;
rot: Rotation;
stride: Rotation;
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
this.flag = false;
this.rot = Rotation.zero;
this.stride = new Rotation(0, 0, 1);
// 开启循环周期函数
this.useUpdate = true;
// 添加一个按键方法:按下键盘“1”,向服务端发送事件【创建角色并控制】
InputUtil.onKeyDown(Keys.One, () => {
this.flag = !this.flag;
});
}
}
// 周期函数每帧执行,此函数执行需要将this.useUpdate赋值为true,dt是当前帧与上一帧的延迟(秒)
protected onUpdate(dt: number): void {
if(SystemUtil.isClient() && this.flag) {
// 获取当前控制器输入的旋转并叠加步长进行覆盖
Player.getControllerRotation(this.rot);
Player.setControllerRotation(this.rot.add(this.stride));
}
}
}
getPlayer
• Static
getPlayer(uniqueId
): Player
获取玩家,根据userId找到对应的玩家
Parameters
uniqueId string number | 用户ID或者玩家玩家ID |
---|
Returns
Player | 玩家对象 |
---|
Precautions
根据ID获取玩家。ID可以是playerId或userId。
ts
@Component
export default class Example_Player extends Script {
protected onStart(): void {
Player.getPlayer(Player.localPlayer.playerId);
}
}
@Component
export default class Example_Player extends Script {
protected onStart(): void {
Player.getPlayer(Player.localPlayer.playerId);
}
}
setControllerRotation
• Static
setControllerRotation(newRotation
): void
client
覆写控制器的旋转
Parameters
newRotation Rotation | 新旋转值 |
---|
ts
@Component
export default class Example_Player_SetControllerRotation extends Script {
// 声明变量
flag: boolean;
rot: Rotation;
stride: Rotation;
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
this.flag = false;
this.rot = Rotation.zero;
this.stride = new Rotation(0, 0, 1);
// 开启循环周期函数
this.useUpdate = true;
// 添加一个按键方法:按下键盘“1”,向服务端发送事件【创建角色并控制】
InputUtil.onKeyDown(Keys.One, () => {
this.flag = !this.flag;
});
}
}
// 周期函数每帧执行,此函数执行需要将this.useUpdate赋值为true,dt是当前帧与上一帧的延迟(秒)
protected onUpdate(dt: number): void {
if(SystemUtil.isClient() && this.flag) {
// 获取当前控制器输入的旋转并叠加步长进行覆盖
Player.getControllerRotation(this.rot);
Player.setControllerRotation(this.rot.add(this.stride));
}
}
}
@Component
export default class Example_Player_SetControllerRotation extends Script {
// 声明变量
flag: boolean;
rot: Rotation;
stride: Rotation;
// 当脚本被实例后,会在第一帧更新前调用此函数/
protected onStart(): void {
// 下列代码仅在客户端执行
if(SystemUtil.isClient()) {
this.flag = false;
this.rot = Rotation.zero;
this.stride = new Rotation(0, 0, 1);
// 开启循环周期函数
this.useUpdate = true;
// 添加一个按键方法:按下键盘“1”,向服务端发送事件【创建角色并控制】
InputUtil.onKeyDown(Keys.One, () => {
this.flag = !this.flag;
});
}
}
// 周期函数每帧执行,此函数执行需要将this.useUpdate赋值为true,dt是当前帧与上一帧的延迟(秒)
protected onUpdate(dt: number): void {
if(SystemUtil.isClient() && this.flag) {
// 获取当前控制器输入的旋转并叠加步长进行覆盖
Player.getControllerRotation(this.rot);
Player.setControllerRotation(this.rot.add(this.stride));
}
}
}