[开发者心得] 【027】关于父子结点关系的一点小细节

[复制链接]
1080 |0
喵喵哭唧唧 发表于 2023-6-1 13:32:31 | 显示全部楼层 |阅读模式
本帖最后由 哭唧唧的细狗 于 2023-11-23 14:10 编辑

经常听到有好哥哥反应,唉,我这里getChildren获取不到子节点,亦或者find一个对象后获取parent返回null

为啥丫,明明预制体里看到了父子关系的丫
我们设计一个小实验,制作四个预制体,他们分别对应了四种情况,并且分别在客户端和服务器上创建它们,最终的效果即是最终的答案。

全是客户端对象(由圆柱组成)全是服务器对象 (由四棱台组成)子节点有客户端有服务器 (由环和三角锥组成)全是双端对象 (由球体组成)
image.png image.png image.png image.png



@Component
export default class NewScript extends Script {

    /** 当脚本被实例后,会在第一帧更新前调用此函数 */
    protected onStart(): void {
        if(SystemUtil.isServer()){
            Event.addClientListener("Spawn", (p, param)=>{
                GameObject.asyncSpawn("2532638A49DAE134C223BDB96722EC6F", {replicates: true}).then(goPrefab=>{
                    goPrefab.worldTransform.position = new Vector(100, 100, 100)
                    console.log("服务器测试1 全客户端 ", goPrefab.getChildren().length)
                })

                GameObject.asyncSpawn("419CE4F94AC10A1411245F8F254076A6", {replicates: true}).then(goPrefab=>{
                    goPrefab.worldTransform.position = new Vector(400, 100, 100)

                    console.log("服务器测试2 全服务器 ", goPrefab.getChildren().length)
                })

                GameObject.asyncSpawn("164E325B422277EAA7BA2395B6F6B2E7", {replicates: true}).then(goPrefab=>{
                    goPrefab.worldTransform.position = new Vector(700, 100, 100)

                    console.log("服务器测试3 部分C部分S ", goPrefab.getChildren().length)
                })

                GameObject.asyncSpawn("E808005149495252A305F3AD8806C664", {replicates: true}).then(goPrefab=>{
                    goPrefab.worldTransform.position = new Vector(1000, 100, 100)

                    console.log("服务器测试4 全双端 ", goPrefab.getChildren().length)
                })
            })
        } else {
            InputUtil.onKeyDown(Keys.U, ()=>{
                Event.dispatchToServer("Spawn")
            })

            InputUtil.onKeyDown(Keys.P, ()=>{
                GameObject.asyncSpawn("2532638A49DAE134C223BDB96722EC6F", {replicates: true}).then(goPrefab=>{
                    goPrefab.worldTransform.position = new Vector(100, 400, 100)

                    console.log("客户端测试1 全客户端 ", goPrefab.getChildren().length)
                })

                GameObject.asyncSpawn("419CE4F94AC10A1411245F8F254076A6", {replicates: true}).then(goPrefab=>{
                    goPrefab.worldTransform.position = new Vector(100, 700, 100)

                    console.log("客户端测试2 全服务器 ", goPrefab.getChildren().length)
                })

                GameObject.asyncSpawn("164E325B422277EAA7BA2395B6F6B2E7", {replicates: true}).then(goPrefab=>{
                    goPrefab.worldTransform.position = new Vector(100, 1000, 100)
                    console.log("客户端测试3 部分C部分S ", goPrefab.getChildren().length)
                })

                GameObject.asyncSpawn("E808005149495252A305F3AD8806C664", {replicates: true}).then(goPrefab=>{
                    goPrefab.worldTransform.position = new Vector(100, 1300, 100)

                    console.log("客户端测试4 全双端 ", goPrefab.getChildren().length)
                })
            })
        }
    }
}


根据上边的代码,我们通过按P键在客户端创建输出了客户端测试的1-4结果,按U键发消息给服务器创建预制体并输出了服务器测试的1-4结果:
  客户端测试结果 服务器测试结果
image.png
image.png
image.png
image.png
总结
客户端创建:
1、纯客户端会保留父子结构,会显示所有客户端对象(运动器也能正常执行)

2、双端预制体会直接报错

服务器创建:
1、客户端单端预制体会直接报错

2、服务端单端预制体,会保留完整的父子级结构,不会显示该预制体的任何对象

3、部分客户端部分服务器预制体,会保留服务端和双端相关结构,但是只会显示双端和客户端对象
4、双端预制体,会保留完整的父子级结构,会显示所有双端对象

使用方式推荐:
双端预制体在服务器创建使用,客户端会同步到结构并显示(如果有大量对象,那么服务器同步给客户端结构这一过程会有延迟)


测试工程:
testParent.rar (86.36 KB, 下载次数: 53)
回复

使用道具 举报

热门版块
快速回复 返回顶部 返回列表