本帖最后由 剑寂万古 于 2023-5-9 14:57 编辑
引言:
吾乃小剑,自今日始,将为诸位带来每周一次之踏险纪录,期望可藉此,稍能协诸位一臂之力也。
前方高能(坑点):
- setInterval和setTimeout的返回值不是number,不要用number来定义
测试代码:
let i = setTimeout(() => {}, 1000);
console.log("-----testTimeOUt-----", typeof (i));
let j = setInterval(() => {}, 1000)
console.log("-----testInterval-----", typeof (j));
结果:
原因:
setInterval与setTimeout会返回一个特殊对象而非number,故不要用number去定义类型,否则有可能会导致清除失败的情况发生。
- 应该优先设置数据存储环境
DataStorage.setTemporaryStorage应该放到class外面作为全局方法运行或者在onStart中优先设置,推荐放到Class外
代码:
// 推荐放到Class外
DataStorage.setTemporaryStorage(false);
@Core.Class
export default class GameStart extends Core.Script { onStart(){} }
- 非玩家对象使用官方文档中的默认代码运行后不显示形象
测试代码:
let guid = "NPC";
let go = await Gameplay.GameObject.asyncSpawn({ guid: guid, replicates: true })
AssetUtil.asyncDownloadAsset("127060");
let character = go as Gameplay.Character;
character.setWorldLocation(new Type.Vector(0, 0, 100));
character.appearanceType = Gameplay.AppearanceType.FourFootStandard;
// 设置Appearance
let Tappearance = character.setAppearance(Gameplay.FourFootStandard)
character.appearanceReady().then(() => {
if (Tappearance) {
// 同步信息,仅客户端需要设置成false
Tappearance.setWholeBody("127060", true);
}
})
结果:
客户端setWholeBody sync为true:
客户端:setWholeBody sync为false:
原因:
客户端单端对象找不到服务端的人形对象,导致没有设置外观,所以setWholeBody的sync要设置成false不同步
- 在脚本加载时调用asyncGetCurrentPlayer会概率超时
解决方法:在脚本OnStart生命周期内调用asyncGetCurrentPlayer()
示例:
@Core.Class
export default class GameStart extends Core.Script {
onStart(){
Gameplay.asyncGetCurrentPlayer().then((player) => {...});
}
}
- 动画相关接口都会调用rpc接口,慎用。
Gameplay.Animation的play,stop,resume都会使用的都是rpc,为避免可靠栈溢出(消息队列缓冲区溢出),请谨慎使用。
最新进展:后续编辑器会对此进行优化。
抓虫子(bug):
- getGameCarryingData 使用 await 没数据会一直阻塞
描述:使用该方法获得数据时,如果当前没有数据,则使用await会一直等待返回数据造成阻塞。
解决方法:利用Promise.race()方法以及一个超时的方法进行比较即可
示例:
//阻塞情况
console.log("-------111-------阻塞")
await RouteService.getInstance().getGameCarryingData()
console.log("-------222-------阻塞")
//利用Promise.race()超时跳出
console.log("-------111-------超时跳出")
function timeout() {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
reject("timeout");
}, 5000); })
return p; }
//5秒后如果没有获得数据则失败跳出
await Promise.race([RouteService.getInstance().getGameCarryingData(), timeout()]).then(() => {
console.log("success");
}).catch(err => {
console.log("fail") })
console.log("-------222-------")
结果1,阻塞运行:
结果2:超时跳出:
- 双端父节点可见性不同步给单端子节点
描述:在一个父子对象结构中,父节点是双端节点,子节点是单端节点,将子节点的可见性都设置为从父对象获取,把父节点的可见性设置为关闭,运行游戏,单端子节点仍然会显示。
- 克隆多级父子结构的对象问题
描述:克隆一个有多级父子结构的对象,第一层子节点位置没问题,第二层子节点之后的位置会发生相对偏移
解决方案:暂时需要重新设置一下obj.relativeLocation.
- 双端模型勾选平滑同步,服务器改变Rotation,客户端不会生效
最新进度:由于平滑同步使用RPC性能上消耗比较大,不用平滑同步
- 脚本切换attachObjcect问题
描述:脚本切换附着物体, 使用script.gameobject = gameobject会再执行一次onStart()。但是使用gameobject.attachComponent()不会导致这个问题。
let scriptA = await Core.Script.spawnScript(PetAni);
go.attachComponent(scriptA);
替代方法:
可以这样生成脚本来挂载到物体上。
static spawnScript<T extends Script>(scriptAssetId: string, bInReplicates?: boolean, target?: GameObject): Promise<T>;
- UI.ProgressBar的sliderButtonReleaseDelegate在mobile端回调触发两次
描述:
mobile端:拖动进度条时sliderButtonReleaseDelegate回调会触发两次,按下去触发一次,release的时候再触发一次。PIE端没有这个问题。
|
|