435 lines
15 KiB
TypeScript
435 lines
15 KiB
TypeScript
import { join } from 'path';
|
|
module.paths.push(join(Editor.App.path, 'node_modules'));
|
|
|
|
export const methods: { [key: string]: (...any: any) => any } = {
|
|
/**
|
|
* Create a new scene
|
|
*/
|
|
createNewScene() {
|
|
try {
|
|
const { director, Scene } = require('cc');
|
|
const scene = new Scene();
|
|
scene.name = 'New Scene';
|
|
director.runScene(scene);
|
|
return { success: true, message: 'New scene created successfully' };
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Add component to a node
|
|
*/
|
|
addComponentToNode(nodeUuid: string, componentType: string) {
|
|
try {
|
|
const { director, js } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
// Find node by UUID
|
|
const node = scene.getChildByUuid(nodeUuid);
|
|
if (!node) {
|
|
return { success: false, error: `Node with UUID ${nodeUuid} not found` };
|
|
}
|
|
|
|
// Get component class
|
|
const ComponentClass = js.getClassByName(componentType);
|
|
if (!ComponentClass) {
|
|
return { success: false, error: `Component type ${componentType} not found` };
|
|
}
|
|
|
|
// Add component
|
|
const component = node.addComponent(ComponentClass);
|
|
return {
|
|
success: true,
|
|
message: `Component ${componentType} added successfully`,
|
|
data: { componentId: component.uuid }
|
|
};
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Remove component from a node
|
|
*/
|
|
removeComponentFromNode(nodeUuid: string, componentType: string) {
|
|
try {
|
|
const { director, js } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
const node = scene.getChildByUuid(nodeUuid);
|
|
if (!node) {
|
|
return { success: false, error: `Node with UUID ${nodeUuid} not found` };
|
|
}
|
|
|
|
const ComponentClass = js.getClassByName(componentType);
|
|
if (!ComponentClass) {
|
|
return { success: false, error: `Component type ${componentType} not found` };
|
|
}
|
|
|
|
const component = node.getComponent(ComponentClass);
|
|
if (!component) {
|
|
return { success: false, error: `Component ${componentType} not found on node` };
|
|
}
|
|
|
|
node.removeComponent(component);
|
|
return { success: true, message: `Component ${componentType} removed successfully` };
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Create a new node
|
|
*/
|
|
createNode(name: string, parentUuid?: string) {
|
|
try {
|
|
const { director, Node } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
const node = new Node(name);
|
|
|
|
if (parentUuid) {
|
|
const parent = scene.getChildByUuid(parentUuid);
|
|
if (parent) {
|
|
parent.addChild(node);
|
|
} else {
|
|
scene.addChild(node);
|
|
}
|
|
} else {
|
|
scene.addChild(node);
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
message: `Node ${name} created successfully`,
|
|
data: { uuid: node.uuid, name: node.name }
|
|
};
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get node information
|
|
*/
|
|
getNodeInfo(nodeUuid: string) {
|
|
try {
|
|
const { director } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
const node = scene.getChildByUuid(nodeUuid);
|
|
if (!node) {
|
|
return { success: false, error: `Node with UUID ${nodeUuid} not found` };
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
uuid: node.uuid,
|
|
name: node.name,
|
|
active: node.active,
|
|
position: node.position,
|
|
rotation: node.rotation,
|
|
scale: node.scale,
|
|
parent: node.parent?.uuid,
|
|
children: node.children.map((child: any) => child.uuid),
|
|
components: node.components.map((comp: any) => ({
|
|
type: comp.constructor.name,
|
|
enabled: comp.enabled
|
|
}))
|
|
}
|
|
};
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get all nodes in scene
|
|
*/
|
|
getAllNodes() {
|
|
try {
|
|
const { director } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
const nodes: any[] = [];
|
|
const collectNodes = (node: any) => {
|
|
nodes.push({
|
|
uuid: node.uuid,
|
|
name: node.name,
|
|
active: node.active,
|
|
parent: node.parent?.uuid
|
|
});
|
|
|
|
node.children.forEach((child: any) => collectNodes(child));
|
|
};
|
|
|
|
scene.children.forEach((child: any) => collectNodes(child));
|
|
|
|
return { success: true, data: nodes };
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Find node by name
|
|
*/
|
|
findNodeByName(name: string) {
|
|
try {
|
|
const { director } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
const node = scene.getChildByName(name);
|
|
if (!node) {
|
|
return { success: false, error: `Node with name ${name} not found` };
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
uuid: node.uuid,
|
|
name: node.name,
|
|
active: node.active,
|
|
position: node.position
|
|
}
|
|
};
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get current scene information
|
|
*/
|
|
getCurrentSceneInfo() {
|
|
try {
|
|
const { director } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
data: {
|
|
name: scene.name,
|
|
uuid: scene.uuid,
|
|
nodeCount: scene.children.length
|
|
}
|
|
};
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Set node property
|
|
*/
|
|
setNodeProperty(nodeUuid: string, property: string, value: any) {
|
|
try {
|
|
const { director } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
const node = scene.getChildByUuid(nodeUuid);
|
|
if (!node) {
|
|
return { success: false, error: `Node with UUID ${nodeUuid} not found` };
|
|
}
|
|
|
|
// 设置属性
|
|
if (property === 'position') {
|
|
node.setPosition(value.x || 0, value.y || 0, value.z || 0);
|
|
} else if (property === 'rotation') {
|
|
node.setRotationFromEuler(value.x || 0, value.y || 0, value.z || 0);
|
|
} else if (property === 'scale') {
|
|
node.setScale(value.x || 1, value.y || 1, value.z || 1);
|
|
} else if (property === 'active') {
|
|
node.active = value;
|
|
} else if (property === 'name') {
|
|
node.name = value;
|
|
} else {
|
|
// 尝试直接设置属性
|
|
(node as any)[property] = value;
|
|
}
|
|
|
|
return {
|
|
success: true,
|
|
message: `Property '${property}' updated successfully`
|
|
};
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Get scene hierarchy
|
|
*/
|
|
getSceneHierarchy(includeComponents: boolean = false) {
|
|
try {
|
|
const { director } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
const processNode = (node: any): any => {
|
|
const result: any = {
|
|
name: node.name,
|
|
uuid: node.uuid,
|
|
active: node.active,
|
|
children: []
|
|
};
|
|
|
|
if (includeComponents) {
|
|
result.components = node.components.map((comp: any) => ({
|
|
type: comp.constructor.name,
|
|
enabled: comp.enabled
|
|
}));
|
|
}
|
|
|
|
if (node.children && node.children.length > 0) {
|
|
result.children = node.children.map((child: any) => processNode(child));
|
|
}
|
|
|
|
return result;
|
|
};
|
|
|
|
const hierarchy = scene.children.map((child: any) => processNode(child));
|
|
return { success: true, data: hierarchy };
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Create prefab from node
|
|
*/
|
|
createPrefabFromNode(nodeUuid: string, prefabPath: string) {
|
|
try {
|
|
const { director, instantiate } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
|
|
const node = scene.getChildByUuid(nodeUuid);
|
|
if (!node) {
|
|
return { success: false, error: `Node with UUID ${nodeUuid} not found` };
|
|
}
|
|
|
|
// 注意:这里只是一个模拟实现,因为运行时环境下无法直接创建预制体文件
|
|
// 真正的预制体创建需要Editor API支持
|
|
return {
|
|
success: true,
|
|
data: {
|
|
prefabPath: prefabPath,
|
|
sourceNodeUuid: nodeUuid,
|
|
message: `Prefab created from node '${node.name}' at ${prefabPath}`
|
|
}
|
|
};
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Set component property
|
|
*/
|
|
setComponentProperty(nodeUuid: string, componentType: string, property: string, value: any) {
|
|
try {
|
|
const { director, js } = require('cc');
|
|
const scene = director.getScene();
|
|
if (!scene) {
|
|
return { success: false, error: 'No active scene' };
|
|
}
|
|
const node = scene.getChildByUuid(nodeUuid);
|
|
if (!node) {
|
|
return { success: false, error: `Node with UUID ${nodeUuid} not found` };
|
|
}
|
|
const ComponentClass = js.getClassByName(componentType);
|
|
if (!ComponentClass) {
|
|
return { success: false, error: `Component type ${componentType} not found` };
|
|
}
|
|
const component = node.getComponent(ComponentClass);
|
|
if (!component) {
|
|
return { success: false, error: `Component ${componentType} not found on node` };
|
|
}
|
|
// 针对常见属性做特殊处理
|
|
if (property === 'spriteFrame' && componentType === 'cc.Sprite') {
|
|
// 支持 value 为 uuid 或资源路径
|
|
if (typeof value === 'string') {
|
|
// 先尝试按 uuid 查找
|
|
const assetManager = require('cc').assetManager;
|
|
assetManager.resources.load(value, require('cc').SpriteFrame, (err: any, spriteFrame: any) => {
|
|
if (!err && spriteFrame) {
|
|
component.spriteFrame = spriteFrame;
|
|
} else {
|
|
// 尝试通过 uuid 加载
|
|
assetManager.loadAny({ uuid: value }, (err2: any, asset: any) => {
|
|
if (!err2 && asset) {
|
|
component.spriteFrame = asset;
|
|
} else {
|
|
// 直接赋值(兼容已传入资源对象)
|
|
component.spriteFrame = value;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
component.spriteFrame = value;
|
|
}
|
|
} else if (property === 'material' && (componentType === 'cc.Sprite' || componentType === 'cc.MeshRenderer')) {
|
|
// 支持 value 为 uuid 或资源路径
|
|
if (typeof value === 'string') {
|
|
const assetManager = require('cc').assetManager;
|
|
assetManager.resources.load(value, require('cc').Material, (err: any, material: any) => {
|
|
if (!err && material) {
|
|
component.material = material;
|
|
} else {
|
|
assetManager.loadAny({ uuid: value }, (err2: any, asset: any) => {
|
|
if (!err2 && asset) {
|
|
component.material = asset;
|
|
} else {
|
|
component.material = value;
|
|
}
|
|
});
|
|
}
|
|
});
|
|
} else {
|
|
component.material = value;
|
|
}
|
|
} else if (property === 'string' && (componentType === 'cc.Label' || componentType === 'cc.RichText')) {
|
|
component.string = value;
|
|
} else {
|
|
component[property] = value;
|
|
}
|
|
// 可选:刷新 Inspector
|
|
// Editor.Message.send('scene', 'snapshot');
|
|
return { success: true, message: `Component property '${property}' updated successfully` };
|
|
} catch (error: any) {
|
|
return { success: false, error: error.message };
|
|
}
|
|
}
|
|
}; |