Compare commits
2
Commits
0ffb03979f
...
5e0546f675
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e0546f675 | ||
|
|
0024cd6d18 |
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "1.2.0",
|
||||
"importer": "directory",
|
||||
"imported": true,
|
||||
"uuid": "1ea6ed41-6740-4317-8367-c6148c90d599",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
+438
@@ -0,0 +1,438 @@
|
||||
[
|
||||
{
|
||||
"__type__": "cc.Prefab",
|
||||
"_name": "BackHall_Layer",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_native": "",
|
||||
"data": {
|
||||
"__id__": 1
|
||||
},
|
||||
"optimizationPolicy": 0,
|
||||
"persistent": false
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "BackHall_Layer",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": null,
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 2
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 16
|
||||
},
|
||||
{
|
||||
"__id__": 18
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 20
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "group-55",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_children": [
|
||||
{
|
||||
"__id__": 3
|
||||
}
|
||||
],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 11
|
||||
},
|
||||
{
|
||||
"__id__": 13
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 15
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Node",
|
||||
"_name": "Spirit465",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [
|
||||
{
|
||||
"__id__": 4
|
||||
},
|
||||
{
|
||||
"__id__": 6
|
||||
},
|
||||
{
|
||||
"__id__": 8
|
||||
}
|
||||
],
|
||||
"_prefab": {
|
||||
"__id__": 10
|
||||
},
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 569.5,
|
||||
"y": 168.5,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 5
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 91,
|
||||
"height": 91
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "A2sIjmpL1x2hbML5ygakTb"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.ProgressBar",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 7
|
||||
},
|
||||
"_customMaterial": null,
|
||||
"_srcBlendFactor": 2,
|
||||
"_dstBlendFactor": 4,
|
||||
"_color": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 255,
|
||||
"g": 255,
|
||||
"b": 255,
|
||||
"a": 255
|
||||
},
|
||||
"_spriteFrame": {
|
||||
"__uuid__": "8e3905be-b629-4c4d-858b-b8a76e9f7752@f9941",
|
||||
"__expectedType__": "cc.SpriteFrame"
|
||||
},
|
||||
"_type": 0,
|
||||
"_reverse": false,
|
||||
"_totalLength": 100,
|
||||
"_progress": 0,
|
||||
"_barSprite": null,
|
||||
"_mode": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "K8YqgyJnan2FlwJMxWVnfV"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 3
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 9
|
||||
},
|
||||
"_alignFlags": 16,
|
||||
"_target": null,
|
||||
"_horizontalCenter": 569.5,
|
||||
"_verticalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 0,
|
||||
"_originalHeight": 0,
|
||||
"_alignMode": 2,
|
||||
"_lockFlags": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "ey553NOch3SxyjSb3Jfwvz"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "9obX1v6tA73be4mRh2lVzP",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 12
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 1600,
|
||||
"height": 720
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "4WRBrM1MZPaAfdPdW0J52P"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 14
|
||||
},
|
||||
"_alignFlags": 45,
|
||||
"_target": null,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 100,
|
||||
"_originalHeight": 100,
|
||||
"_alignMode": 2,
|
||||
"_lockFlags": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "YjUAxznzLTvKcYbmD3l9gB"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "087OreBRh0E0GalegcF822",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
},
|
||||
{
|
||||
"__type__": "cc.UITransform",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 17
|
||||
},
|
||||
"_contentSize": {
|
||||
"__type__": "cc.Size",
|
||||
"width": 1600,
|
||||
"height": 720
|
||||
},
|
||||
"_anchorPoint": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 0.5,
|
||||
"y": 0.5
|
||||
},
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "rVG5SEIkx7eqJtYaF7WKNE"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Widget",
|
||||
"_name": "",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"node": {
|
||||
"__id__": 1
|
||||
},
|
||||
"_enabled": true,
|
||||
"__prefab": {
|
||||
"__id__": 19
|
||||
},
|
||||
"_alignFlags": 45,
|
||||
"_target": null,
|
||||
"_left": 0,
|
||||
"_right": 0,
|
||||
"_top": 0,
|
||||
"_bottom": 0,
|
||||
"_horizontalCenter": 0,
|
||||
"_verticalCenter": 0,
|
||||
"_isAbsLeft": true,
|
||||
"_isAbsRight": true,
|
||||
"_isAbsTop": true,
|
||||
"_isAbsBottom": true,
|
||||
"_isAbsHorizontalCenter": true,
|
||||
"_isAbsVerticalCenter": true,
|
||||
"_originalWidth": 100,
|
||||
"_originalHeight": 100,
|
||||
"_alignMode": 2,
|
||||
"_lockFlags": 0,
|
||||
"_id": ""
|
||||
},
|
||||
{
|
||||
"__type__": "cc.CompPrefabInfo",
|
||||
"fileId": "sIoxX9Tn15dHlUE2YiAh2c"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PrefabInfo",
|
||||
"root": {
|
||||
"__id__": 1
|
||||
},
|
||||
"asset": {
|
||||
"__id__": 0
|
||||
},
|
||||
"fileId": "vnMBhUWbB968O6kpSW2FBh",
|
||||
"instance": null,
|
||||
"targetOverrides": null,
|
||||
"nestedPrefabInstanceRoots": null
|
||||
}
|
||||
]
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"ver": "1.1.50",
|
||||
"importer": "prefab",
|
||||
"imported": true,
|
||||
"uuid": "32b4b792-ad83-4fd5-9542-5bd64ba7d9da",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {
|
||||
"syncNodeName": "BackHall_Layer"
|
||||
}
|
||||
}
|
||||
+231
@@ -0,0 +1,231 @@
|
||||
[
|
||||
{
|
||||
"__type__": "cc.SceneAsset",
|
||||
"_name": "BackHall_Layer",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_native": "",
|
||||
"scene": {
|
||||
"__id__": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"__type__": "cc.Scene",
|
||||
"_name": "BackHall_Layer",
|
||||
"_objFlags": 0,
|
||||
"__editorExtras__": {},
|
||||
"_parent": null,
|
||||
"_children": [],
|
||||
"_active": true,
|
||||
"_components": [],
|
||||
"_prefab": null,
|
||||
"_lpos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"_lrot": {
|
||||
"__type__": "cc.Quat",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0,
|
||||
"w": 1
|
||||
},
|
||||
"_lscale": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"z": 1
|
||||
},
|
||||
"_mobility": 0,
|
||||
"_layer": 1073741824,
|
||||
"_euler": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"z": 0
|
||||
},
|
||||
"autoReleaseAssets": false,
|
||||
"_globals": {
|
||||
"__id__": 2
|
||||
},
|
||||
"_id": "72251396-a92b-4205-8995-3df0a2a573dc"
|
||||
},
|
||||
{
|
||||
"__type__": "cc.SceneGlobals",
|
||||
"ambient": {
|
||||
"__id__": 3
|
||||
},
|
||||
"shadows": {
|
||||
"__id__": 4
|
||||
},
|
||||
"_skybox": {
|
||||
"__id__": 5
|
||||
},
|
||||
"fog": {
|
||||
"__id__": 6
|
||||
},
|
||||
"octree": {
|
||||
"__id__": 7
|
||||
},
|
||||
"skin": {
|
||||
"__id__": 8
|
||||
},
|
||||
"lightProbeInfo": {
|
||||
"__id__": 9
|
||||
},
|
||||
"postSettings": {
|
||||
"__id__": 10
|
||||
},
|
||||
"bakedWithStationaryMainLight": false,
|
||||
"bakedWithHighpLightmap": false
|
||||
},
|
||||
{
|
||||
"__type__": "cc.AmbientInfo",
|
||||
"_skyColorHDR": {
|
||||
"__type__": "cc.Vec4",
|
||||
"x": 0.2,
|
||||
"y": 0.5,
|
||||
"z": 0.8,
|
||||
"w": 1
|
||||
},
|
||||
"_skyColor": {
|
||||
"__type__": "cc.Vec4",
|
||||
"x": 0.2,
|
||||
"y": 0.5,
|
||||
"z": 0.8,
|
||||
"w": 1
|
||||
},
|
||||
"_skyIllumHDR": 20000,
|
||||
"_skyIllum": 20000,
|
||||
"_groundAlbedoHDR": {
|
||||
"__type__": "cc.Vec4",
|
||||
"x": 0.2,
|
||||
"y": 0.2,
|
||||
"z": 0.2,
|
||||
"w": 1
|
||||
},
|
||||
"_groundAlbedo": {
|
||||
"__type__": "cc.Vec4",
|
||||
"x": 0.2,
|
||||
"y": 0.2,
|
||||
"z": 0.2,
|
||||
"w": 1
|
||||
},
|
||||
"_skyColorLDR": {
|
||||
"__type__": "cc.Vec4",
|
||||
"x": 0.2,
|
||||
"y": 0.5,
|
||||
"z": 0.8,
|
||||
"w": 1
|
||||
},
|
||||
"_skyIllumLDR": 20000,
|
||||
"_groundAlbedoLDR": {
|
||||
"__type__": "cc.Vec4",
|
||||
"x": 0.2,
|
||||
"y": 0.2,
|
||||
"z": 0.2,
|
||||
"w": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"__type__": "cc.ShadowsInfo",
|
||||
"_enabled": false,
|
||||
"_type": 0,
|
||||
"_normal": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"z": 0
|
||||
},
|
||||
"_distance": 0,
|
||||
"_planeBias": 1,
|
||||
"_shadowColor": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 0,
|
||||
"g": 0,
|
||||
"b": 0,
|
||||
"a": 76
|
||||
},
|
||||
"_maxReceived": 4,
|
||||
"_size": {
|
||||
"__type__": "cc.Vec2",
|
||||
"x": 1024,
|
||||
"y": 1024
|
||||
}
|
||||
},
|
||||
{
|
||||
"__type__": "cc.SkyboxInfo",
|
||||
"_envLightingType": 0,
|
||||
"_envmapHDR": null,
|
||||
"_envmap": null,
|
||||
"_envmapLDR": null,
|
||||
"_diffuseMapHDR": null,
|
||||
"_diffuseMapLDR": null,
|
||||
"_enabled": false,
|
||||
"_useHDR": true,
|
||||
"_editableMaterial": null,
|
||||
"_reflectionHDR": null,
|
||||
"_reflectionLDR": null,
|
||||
"_rotationAngle": 0
|
||||
},
|
||||
{
|
||||
"__type__": "cc.FogInfo",
|
||||
"_type": 0,
|
||||
"_fogColor": {
|
||||
"__type__": "cc.Color",
|
||||
"r": 200,
|
||||
"g": 200,
|
||||
"b": 200,
|
||||
"a": 255
|
||||
},
|
||||
"_enabled": false,
|
||||
"_fogDensity": 0.3,
|
||||
"_fogStart": 0.5,
|
||||
"_fogEnd": 300,
|
||||
"_fogAtten": 5,
|
||||
"_fogTop": 1.5,
|
||||
"_fogRange": 1.2,
|
||||
"_accurate": false
|
||||
},
|
||||
{
|
||||
"__type__": "cc.OctreeInfo",
|
||||
"_enabled": false,
|
||||
"_minPos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": -1024,
|
||||
"y": -1024,
|
||||
"z": -1024
|
||||
},
|
||||
"_maxPos": {
|
||||
"__type__": "cc.Vec3",
|
||||
"x": 1024,
|
||||
"y": 1024,
|
||||
"z": 1024
|
||||
},
|
||||
"_depth": 8
|
||||
},
|
||||
{
|
||||
"__type__": "cc.SkinInfo",
|
||||
"_enabled": true,
|
||||
"_blurRadius": 0.01,
|
||||
"_sssIntensity": 3
|
||||
},
|
||||
{
|
||||
"__type__": "cc.LightProbeInfo",
|
||||
"_giScale": 1,
|
||||
"_giSamples": 1024,
|
||||
"_bounces": 2,
|
||||
"_reduceRinging": 0,
|
||||
"_showProbe": true,
|
||||
"_showWireframe": true,
|
||||
"_showConvex": false,
|
||||
"_data": null,
|
||||
"_lightProbeSphereVolume": 1
|
||||
},
|
||||
{
|
||||
"__type__": "cc.PostSettingsInfo",
|
||||
"_toneMappingType": 0
|
||||
}
|
||||
]
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"ver": "1.1.50",
|
||||
"importer": "scene",
|
||||
"imported": true,
|
||||
"uuid": "72251396-a92b-4205-8995-3df0a2a573dc",
|
||||
"files": [
|
||||
".json"
|
||||
],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"ver": "4.0.24",
|
||||
"importer": "typescript",
|
||||
"imported": true,
|
||||
"uuid": "a1189c99-b4cc-4af1-9603-86893bc6bd66",
|
||||
"files": [],
|
||||
"subMetas": {},
|
||||
"userData": {}
|
||||
}
|
||||
@@ -0,0 +1,236 @@
|
||||
# Interface Conversion Playbook
|
||||
|
||||
> **Status**: Draft v1 (2026-09-03)
|
||||
> **Purpose**: 为其他工程师 + 后续 plan 提供 YouleNexus 界面转换规范
|
||||
> **适用**: 把 `projects/Game_Surface_3/` (旧 HTML5 Cocos-JS 平台) 迁移到 `cocoscreator_projects/YouleNexus/` (新 Cocos 3.8.8 TS 平台)
|
||||
|
||||
## 决策树:代码迁移 vs MCP 手工复刻
|
||||
|
||||
```
|
||||
原 Layer XML 含业务 UI 节点吗?
|
||||
├── 否 → ✅ 代码迁移(legacy-layer-to-cocos-prefab.mjs 已支持)
|
||||
│ 适用场景: Login_Layer, BackHall_Layer 等纯 spirit 表达的场景
|
||||
│
|
||||
└── 是 → ❌ 代码迁移不足 + ⚠️ 改用 funplay MCP 手工复刻
|
||||
适用场景: YouleNexus 现有 prefab 含原 XML 没有的手工 UI 节点
|
||||
例: Bg / 装饰 / 状态显示 / 多按钮等
|
||||
```
|
||||
|
||||
**如何判断 "原 XML 是否含业务 UI"**:
|
||||
|
||||
| 信号 | 说明 |
|
||||
|---|---|
|
||||
| 原 Layer XML 的 spirit 数 ≥ YouleNexus 现有 prefab 的 node 数 | ✅ 代码迁移足够 |
|
||||
| 原 Layer XML 的 spirit 数 < YouleNexus 现有 prefab 的 node 数(差 ≥ 3) | ⚠️ MCP 手工 |
|
||||
| 包含 `SpiritName` 像 `Bg / 装饰 / 状态` 等 | ⚠️ MCP 手工(业务 UI 命名约定) |
|
||||
| YouleNexus prefab 含 `_string` Label 含业务文案("准备中" / "游戏中") | ⚠️ MCP 手工 |
|
||||
|
||||
**量化证据**(2026-09-02 实测):
|
||||
|
||||
| Layer | 原 XML spirits | YouleNexus nodes | 差 | 路径 |
|
||||
|---|---|---|---|---|
|
||||
| Layer00002 Login | 18 | 20 | +2 | ✅ 代码迁移(PlayerInfoView 16/18 PASS + Login_Layer Cocos 编辑器验证) |
|
||||
| Layer00619 BackHall | 1 | 6 | +5 | ⚠️ MCP 手工 |
|
||||
| Layer00616 Kick | (待查) | 6 | ? | ⚠️ MCP 手工(diff 1381 行) |
|
||||
| Layer00614 Loading | (待查) | (待查) | ? | ⚠️ MCP 手工(diff 1012 行) |
|
||||
| Layer00010 Protol | 4 | (待查) | ? | ⚠️ MCP 手工(diff 1161 行) |
|
||||
|
||||
## 数据契约
|
||||
|
||||
### 原工程数据来源(`projects/Game_Surface_3/`)
|
||||
|
||||
```
|
||||
projects/Game_Surface_3/
|
||||
├── save/ ← 68 个 Layer XML (GB18030/UTF-8, 子集按 Layer ID)
|
||||
│ ├── Layer00002.xml ← Login_Layer
|
||||
│ ├── Layer00619.xml ← BackHall_Layer (1 spirit)
|
||||
│ └── ... (66 more)
|
||||
├── output/
|
||||
│ ├── gameabc_Layer.json ← Layer 索引 (ObjectList = spirit IDs)
|
||||
│ ├── gameabc_Image.json ← ImgResID → SpriteFrame 真 UUID (440 entries)
|
||||
│ ├── gameabc_Project.json ← ScreenWidth/Height/GameSceneWidth/Height/ScreenFitMode
|
||||
│ ├── gameabc_GameTxt.json ← 多语言文案(未迁移)
|
||||
│ └── ... (5 more)
|
||||
└── js/
|
||||
└── gameabc.min.js ← 引擎核心(compiled-to-JS, 185KB, 5544 行)
|
||||
← 难逆向(汇编输出 SIt2/L$qig3/PzF5 寄存器命名)
|
||||
```
|
||||
|
||||
### Spirit XML schema(关键字段)
|
||||
|
||||
```xml
|
||||
<Spirit>
|
||||
<Property Name="SpiritType" Value="0|1|3|4|5"/> <!-- 组件类型:Sprite/Label/ProgressBar/EditBox/(SLICED Sprite) -->
|
||||
<Property Name="ID" Value="<spirit_id>"/> <!-- 唯一 ID -->
|
||||
<Property Name="Name" Value="<chinese_name>"/> <!-- 中文节点名(YouleNexus 复刻保留) -->
|
||||
<Property Name="ImgResID" Value="<sprite_id>"/> <!-- SpriteFrame 引用(→ gameabc_Image.json) -->
|
||||
<Property Name="X" Value="<left_top_x>"/> <!-- 1280×720 屏幕坐标,左上角锚点 -->
|
||||
<Property Name="Y" Value="<left_top_y>"/> <!-- 1280×720 屏幕坐标,左上角锚点 -->
|
||||
<Property Name="Width" Value="<w>"/> <!-- spirit 尺寸(SizeCalcMode=0 直接用) -->
|
||||
<Property Name="Height" Value="<h>"/> <!-- spirit 尺寸(SizeCalcMode=0 直接用) -->
|
||||
<Property Name="BelongGroupID" Value="<group_id>"/> <!-- group-X 父节点(0 = 直挂 Layer 根) -->
|
||||
<Property Name="IndexOfLayer" Value="<order>"/> <!-- 同 group 内排序 -->
|
||||
</Spirit>
|
||||
```
|
||||
|
||||
### Cocos prefab schema(YouleNexus 复刻基准)
|
||||
|
||||
每个 prefab 是 JSON 数组(按 schema 顺序):
|
||||
|
||||
```
|
||||
[
|
||||
cc.Prefab, ← 1 个: _name + data.__id__=1
|
||||
cc.Node (root), ← 1 个: _name + 包含 cc.UITransform + cc.Widget + cc.PrefabInfo
|
||||
cc.Node (group-X), ← N 个 (group>0): children = spirit ids
|
||||
cc.Node (spirit), ← M 个: 包含 cc.UITransform + 组件 + cc.Widget + cc.CompPrefabInfo
|
||||
cc.UITransform, ← 每个 Node 一个
|
||||
cc.Sprite/Label/..., ← 每个 spirit 一个主组件(按 SpiritType)
|
||||
cc.Widget, ← 每个 Node 一个(含 alignFlags + horizontalCenter/verticalCenter)
|
||||
cc.CompPrefabInfo, ← 每个组件一个(fileId 随机字符串)
|
||||
cc.PrefabInfo, ← 每个 Node 一个(root/asset/fileId)
|
||||
]
|
||||
```
|
||||
|
||||
**对照参考**:`cocoscreator_projects/YouleNexus/assets/framework/ui/prefabs/Login_Layer.prefab`(157 objects, 20 nodes, 1:1 验证通过)
|
||||
|
||||
### 锚点转换公式(实测验证)
|
||||
|
||||
```
|
||||
cocos_lpos.x = original_X + original_W/2 - 640 # 原坐标系半宽 1280/2
|
||||
cocos_lpos.y = 360 - (original_Y + original_H/2) # Y-up 翻转 + 半高 720/2
|
||||
```
|
||||
|
||||
参考:`PlayerInfoView` 在 Login_Layer 中 16/18 spirit 精度 < 0.001 匹配(fixed in final fix wave commit `ec550ba`)
|
||||
|
||||
## 转换流程
|
||||
|
||||
### Step 1: 分析数据完整度
|
||||
|
||||
```bash
|
||||
# 1. 读 Layer XML
|
||||
cat cocoscreator_projects/YouleNexus/../projects/Game_Surface_3/save/LayerXXXXX.xml
|
||||
|
||||
# 2. 读 YouleNexus 现有 prefab 作 baseline
|
||||
cat cocoscreator_projects/YouleNexus/assets/framework/ui/prefabs/<LayerName>.prefab
|
||||
|
||||
# 3. 对比节点数 (XML spirit 数 vs YouleNexus node 数)
|
||||
python -c "
|
||||
import xml.etree.ElementTree as ET, json
|
||||
with open('projects/Game_Surface_3/save/LayerXXXXX.xml', 'rb') as f:
|
||||
text = f.read().decode('utf-8', errors='replace')
|
||||
root = ET.fromstring(text)
|
||||
xml_spirits = len(root.find('SpiritList').findall('Spirit'))
|
||||
with open('cocoscreator_projects/YouleNexus/assets/framework/ui/prefabs/<LayerName>.prefab', encoding='utf-8') as f:
|
||||
data = json.load(f)
|
||||
ynex_nodes = sum(1 for obj in data if obj.get('__type__') == 'cc.Node')
|
||||
print(f'XML spirits: {xml_spirits} YouleNexus nodes: {ynex_nodes} diff: {ynex_nodes - xml_spirits}')
|
||||
"
|
||||
```
|
||||
|
||||
### Step 2: 决策路径
|
||||
|
||||
- **diff ≤ 2**: 代码迁移足够 → 见 `docs/superpowers/specs/2026-09-02-legacy-layer-migration-design.md`
|
||||
- **diff ≥ 3**: MCP 手工复刻 → 跳到 Step 3
|
||||
|
||||
### Step 3: MCP 手工复刻流程(仅当代码迁移不足时)
|
||||
|
||||
参考 `cocoscreator_projects/YouleNexus/CLAUDE.md`(所有 Cocos 编辑器操作必须走 `mcp__funplay_cocos__*` 工具)
|
||||
|
||||
```bash
|
||||
# 1. 打开 YouleNexus 现有 prefab 作为 baseline(看现有手工 UI 节点结构)
|
||||
mcp__funplay_cocos__open_asset
|
||||
target: db://assets/framework/ui/prefabs/<LayerName>.prefab
|
||||
|
||||
# 2. 在新路径复制为 _test_legacy_migration/<LayerName>.prefab(spec "不覆盖" 原则)
|
||||
mcp__funplay_cocos__duplicate_prefab
|
||||
source: db://assets/framework/ui/prefabs/<LayerName>.prefab
|
||||
target: assets/framework/ui/prefabs/_test_legacy_migration/<LayerName>.prefab
|
||||
|
||||
# 3. 打开新复制的 prefab,编辑 name 字段匹配原 XML 的 LayerName
|
||||
mcp__funplay_cocos__edit_prefab_json
|
||||
target: db://assets/framework/ui/prefabs/_test_legacy_migration/<LayerName>.prefab
|
||||
jsonPath: /0/_name
|
||||
valueJson: '"<LayerName from XML>"'
|
||||
|
||||
# 4. 对每个 XML spirit 的 Sprite 引用:在 _test_legacy_migration prefab 中
|
||||
# 找到原 YouleNexus prefab 对应节点,更新 _spriteFrame.__uuid__ 为 resolveSpriteFrameUuid(imgResID) 输出
|
||||
|
||||
# 5. 验证加载
|
||||
mcp__funplay_cocos__refresh_assets
|
||||
mcp__funplay_cocos__validate_prefab_references
|
||||
target: db://assets/framework/ui/prefabs/_test_legacy_migration/<LayerName>.prefab
|
||||
|
||||
# 6. 删除 _test_legacy_migration/ 临时文件(不 commit)
|
||||
```
|
||||
|
||||
## 8 项 1:1 匹配验证清单
|
||||
|
||||
每个 prefab 迁移完成后,必须验证以下 8 项(任一不符则**禁止 commit**):
|
||||
|
||||
| # | 验证项 | 检查方法 |
|
||||
|---|---|---|
|
||||
| 1 | spirit 节点数匹配 | count `cc.Node` === XML spirits count |
|
||||
| 2 | spirit id 一致 | 每个 spirit id 在 prefab 中能找到(_prefab.root 等) |
|
||||
| 3 | 中文 Name 一致 | 每个 spirit._name 严格匹配 XML Spirit Name |
|
||||
| 4 | _lpos 精度 < 0.001 | 用 `computeLpos` 公式对比 (渠道logo 123.5/143, 游客登录 60/-75.5 等) |
|
||||
| 5 | _contentSize 一致 | W/H 匹配(SizeCalcMode=0 直接读) |
|
||||
| 6 | SpriteFrame UUID 解析 | `_spriteFrame.__uuid__` 是有效 UUID(含 `@f9941` 后缀) |
|
||||
| 7 | group 层级正确 | `BelongGroupID > 0` 的 spirit 必须在 group-X 父节点下;`==0` 的必须在 Layer 根下 |
|
||||
| 8 | 加载 0 报错 | `mcp__funplay_cocos__open_asset` + `validate_prefab_references` + `search_project_logs` 无 error |
|
||||
|
||||
## 已知限制(2026-09-02 实测)
|
||||
|
||||
### 类型 4 = cc.EditBox 是 best-fit
|
||||
|
||||
- `phoneInfo` (Layer00029): 3 个 type-4 spirit 真的是 EditBox (42×28 输入框)
|
||||
- `Pay_Layer` (Layer00014): 11 个 type-4 spirit (id 446-455, ImgResID=191, 52×32) 可能是 Button 而非 EditBox
|
||||
- **行动**: 加载 Pay_Layer 进 Cocos 后人工验证 UI 实际行为;若不是 EditBox,更新 `fixtures/spirit-semantics.json` type-4 为 cc.Button + rerun
|
||||
|
||||
### 类型 5 SLICED 9-slice borders 丢失
|
||||
|
||||
- `fixtures/spirit-semantics.json` 标 type=5 = cc.Sprite(_type=1 SLICED)
|
||||
- 但 Login_Layer Spirit465 引用的 SpriteFrame `capInsets = [0, 0, 0, 0]`(**不是 9-slice**)
|
||||
- 当前代码硬编码 `_type=1` 与 YouleNexus 现有手工 prefab 一致,运行时 SpriteFrame 实际是 SIMPLE
|
||||
- **行动**: 扩展 `resolveSpriteFrameUuid()` 返回 capInsets → emitPrefabJson 根据 capInsets 决定 `_type`(详见 `docs/superpowers/plans/2026-09-02-legacy-layer-migration.md` final fix wave 后 Deferred)
|
||||
|
||||
### 6 个 expected-fail Layer sprite atlas 缺失
|
||||
|
||||
| Layer | 缺失 ImgResID | 影响 |
|
||||
|---|---|---|
|
||||
| Layer00002 Login | 14, 30, 97, 380, 427, 429 | `Login_Layer.prefab` 生成 throw(PoC 3 fallback 用 filter 跳过这些 spirit) |
|
||||
| Layer00029 phoneInfo | 同上 | Group106_PhoneVerify.prefab 抛 |
|
||||
| Layer00609 Setting | 同上 | Layer609_Setting.prefab 抛 |
|
||||
| Layer00615 Reconnect | 同上 | Layer615_Reconnect.prefab 抛 |
|
||||
| Layer00008 Notice | 同上 | Layer617_Notice.prefab 抛 |
|
||||
| Layer00620 recordLayer | 同上 | Layer620_Record.prefab 抛 |
|
||||
|
||||
**行动**: 独立 content-import 任务(不在本 playbook 范围):把缺失 sprite 导入 `cocoscreator_projects/YouleNexus/assets/framework/ui/atlas-login/` 然后 rerun legacy-layer migration batch。
|
||||
|
||||
## 实验结果:BackHall_Layer (Layer00619) — MCP 手工复刻 vs 代码迁移
|
||||
|
||||
**待执行**(本 playbook v1 草稿时未完成,作为 v1 实施的第一个验证 case)
|
||||
|
||||
预期步骤:
|
||||
|
||||
1. 打开 `YouleNexus/assets/framework/ui/prefabs/widgets/Layer619_BackOtherGame.prefab`(1172 行)
|
||||
2. 复制到 `_test_legacy_migration/BackHall_Layer.prefab`
|
||||
3. 修改 `_name`: `Layer619_BackOtherGame` → `BackHall_Layer`
|
||||
4. 唯一 spirit (`Spirit465` ProgressBar): 替换 `_spriteFrame.__uuid__` 为 `resolveSpriteFrameUuid("191")` 输出
|
||||
5. 验证 8 项清单
|
||||
6. 报告 diff size + 验证 Playbook 8 项清单是否足够
|
||||
|
||||
## 相关文档 + 索引
|
||||
|
||||
- **Spec**: `docs/superpowers/specs/2026-09-02-legacy-layer-migration-design.md`(代码迁移方案)
|
||||
- **Spec**: `docs/superpowers/specs/2026-09-03-interface-conversion-playbook.md`(本文档)
|
||||
- **Plan**: `docs/superpowers/plans/2026-09-02-legacy-layer-migration.md`(12 task + 4 fix round)
|
||||
- **Fixtures**: `cocoscreator_projects/YouleNexus/framework-tests/legacy-layer-migration/fixtures/spirit-semantics.json`(SpiritType 4/5 + SizeCalcMode 公式)
|
||||
- **CLAUDE.md 第二准则**: `数据源权威唯一、下游不兜底` —— 缺失字段 throw 不 fallback
|
||||
- **CLAUDE.md 第三准则**: 所有 Cocos 编辑器操作走 `mcp__funplay_cocos__*` 工具
|
||||
- **memory `legacy-ui-data-and-resolution`**: "旧 UI 是可程序化转换的结构化数据;但零锚定,1280x720 适配是全新工作"
|
||||
|
||||
## Rulings (committed in this playbook)
|
||||
|
||||
- **Ruling F (Migration strategy)**: 决策树用 "原 XML 是否含业务 UI 节点" 作为分流条件 —— 这是**架构选择**不是技术约束
|
||||
- **Ruling G (Validation gate)**: 8 项验证清单是 commit 前的强制检查 —— 任一不符禁止 commit
|
||||
- **Ruling H (Known limits)**: type-4 best-fit + type-5 SLICED borders + 6 expected-fail sprites 都是后续子任务,本 playbook 不掩盖而是 park
|
||||
Reference in New Issue
Block a user