初次提交
This commit is contained in:
435
source/scene.ts
Normal file
435
source/scene.ts
Normal file
@@ -0,0 +1,435 @@
|
||||
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 };
|
||||
}
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user