本帖最后由 俊记牛腩面 于 2023-10-31 15:42 编辑
1 .定义在subdata类中的Action,在调用this.saveData(true)后,Action.call()客户端才有回调
描述:当action.call()的调用在this.save(true)之前的话,实际上的数据还没有同步到C端,就会造成在客户端调用不生效的情况。
export class GameData extends Subdata {
@Decorator.persistence()
aa: number;
onNumChanged: Action = new Action();
export class GameData extends Subdata {
@Decorator.saveProperty
aa: number;
onNumChanged: Action = new Action();
// 第一次改变数据调用的onNumChanged不会在客户端响应
changeNum(num: number): void {
this.aa = num;
this.onNumChanged.call();
this.save(true);
}
// 第一次改变数据调用的onNumChanged会在客户端响应
changeNum(num: number): void {
this.aa = num;
this.save(true);
this.onNumChanged.call();
}
}
export class GameModuleC extends ModuleC<GameModuleS, GameData> {
protected onStart(): void {
this.data.onNumChanged.add(() => {
console.log("num changed", this.data.aa);
})
}
}
2.使用交互物对象实现玩家与NPC/玩家交互时,需要关闭碰撞
描述:将玩家之间通过交互物对象实现attach的效果时,需要关闭碰撞。不然一个对象会一直给另一个对象作用力,撞着移动,导致摇杆操控失去效果。
this.bindNpc.switchToFlying()
this.interactObj = mw.Interactor.spawn("Interactor") as mw.Interactor;
this.interactObj.enter(this.bindNpc, Gameplay.InteractiveSlot.Buns)
// 如果不关闭碰撞,会导致被绑定角色和绑定角色之间一直产生碰撞,无法操控。
// this.bindNpc.collisionWithOtherCharacterEnable = false
p.attachToSlot(this.interactObj,mw.HumanoidSlotType.Head);
3. 将对象attach到修改了scale或身高的Character身上,需要重置这个对象的scale
踩坑描述:
将一个物体重复attach到一个放大了的character身上(无论是character的scale或者是角色编辑器中的身高),如果不设置这个对象的scale,会变得越来越大。
@Component
export default class Test extends Script {
char: Character = null
item: mw.GameObject = null
protected async onStart() {
if (SystemUtil.isClient()) {
const p = await Player.asyncGetLocalPlayer()
this.char = p.character
this.char.worldTransform.scale = new Vector(1.5)
this.item = await mw.GameObject.asyncSpawn("197402")
InputUtil.onKeyDown(mw.Keys.One, () => {
this.attach()
})
InputUtil.onKeyDown(mw.Keys.Two, () => {
this.detach()
})
}
}
private attach() {
if (!this.char || !this.item)
return
this.char.attachToSlot(this.item, mw.HumanoidSlotType.Head)
this.item.localTransform.position = Vector.zero
}
private detach() {
if (!this.char || !this.item)
return
this.char.detachFromSlot(this.item)
}
}
解决方法:设计如此,detach不会恢复物体之前的缩放,在attach之后需要重新设置物体的缩放。
4. 注册事件时,事件名不要包含“server_”
踩坑描述:
026之前版本,事件名中如果包含"server_", 客户端向服务端发送事件,会丢失player对象。
026修复了这个问题。如果在026之前,事件的绑定方法中因为这个bug没有写player参数,在026版本后,第一个参数会变成player对象,导致逻辑出错。
Event.addClientListener(this.server_DeleteWeaponByGuid.name, this.server_DeleteWeaponByGuid.bind(this));
/*** 销毁一个冷兵器实例*
@param weapon 实例
*/
public client_DestroyWeapon(weapon: Weapon) {
weapon.stopPlay();
Event.dispatchToServer(this.server_DeleteWeaponByGuid.name, weapon.guid);
}
/** * 服务器删除一个冷兵器
* @param weaponGuid 冷兵器guid
*/
protected async server_DeleteWeaponByGuid(weaponGuid: string) {
// 026之前 接收到的参数仅有weaponGuid
// 026之后 接收到的参数为player,weaponGuid
let weapon: Weapon = await ScriptManager.asyncFindScript(weaponGuid) as Weapon;
if (weapon && !weapon.isDestroy && this.cacheWeapon.has(weapon["charGuid"])) {
const index = this.cacheWeapon.get(weapon["charGuid"]).indexOf(weapon);
this.cacheWeapon.get(weapon["charGuid"]).splice(index, 1);
console.log("server_OnDeleteWeaponByGuid", weaponGuid);
try {
weapon.gameObject.destroy();
weapon.destroy();
} catch (error) {
console.error("[WeaponManagerSvr] 销毁存在异常", error);
}
}
}
解决方法:
事件名中不要包含"server_", 以此来兼容不同版本编辑器。
5. 025在服务端创建单端预制体,会创建出空对象,而不是null
踩坑描述:
025编辑器在服务器中创建头结点是客户端单端的预制件,能创建出一个空对象。026已修复,创建出的对象为null。
解决方法:不要在服务端创建单端预制体,或在客户端创建单端预制体。
6. 直接修改GameSetting.ini文件的重力参数不生效
描述:
直接修改GameSetting.ini文件的重力参数不生效,目前仅能通过编辑器设置页面修改重力参数才有效
7. 在场景中设置单端NPC的可见性为关闭,运行后不生效
解决方法:代码调用setvisability 或者拖到场景下方让它看不到
|