[add] first
This commit is contained in:
commit
ae87133568
60
README.md
Normal file
60
README.md
Normal file
@ -0,0 +1,60 @@
|
||||
# Cocos Creater OutputComponent
|
||||
|
||||
## 插件 安裝方式
|
||||
|
||||
1. 安裝在 **項目** 底下
|
||||
> 把插件資料夾放到項目的packages(跟assets同層)
|
||||
|
||||
2. 安裝在 **全局** 底下
|
||||
> 把插件資料夾放到C:\Users\%USERNAME%\.CocosCreator\packages
|
||||
|
||||
## 插件稍微說明(都是搬過來的資料 XD)
|
||||
|
||||
剩下沒寫的可以到參考資料裡面看看😀
|
||||
|
||||
1. 定義你的包描述文件:**package.json**
|
||||
> **name** String - 定義了包的名字,包的名字是全局唯一的,他關係到你今後在官網服務器上登錄時的名字。
|
||||
>
|
||||
> **version** String - 版本號,我們推薦使用semver格式管理你的包版本。
|
||||
>
|
||||
> **description** String(可选) - 一句話描述你的包是做什麼的。
|
||||
>
|
||||
> **author** String(可选) - 擴展包的作者
|
||||
>
|
||||
> **main** String (可选) - 入口程序
|
||||
>
|
||||
> **scene-script** String (可选) - 調用引擎API 和項目腳本
|
||||
>
|
||||
> **main-menu** Object (可选) - 主菜單定義
|
||||
>
|
||||
> **有要使用介面的話:**
|
||||
>
|
||||
> **panel** Object (可选) - 定義的面板在package裡的描述
|
||||
>
|
||||
> **注意panel的type有兩種:**
|
||||
>
|
||||
> dockable:可停靠面板,打開該面板後,可以通過拖拽面板標籤到編輯器裡,實現擴展面板嵌入到編輯器中。下面我們介紹的面板入口程序都是按照可停靠面板的要求聲明的。
|
||||
>
|
||||
> simple:簡單Web面板,不可停靠到編輯器主窗口,相當於一份通用的HTML前端頁面。詳細情況請見定義簡單面板。
|
||||
>
|
||||
> 在simple-package文件夾下面創建一個panel文件夾,然後在panel文件夾下創建一個index.js或者一個html文件都可以
|
||||
|
||||
2. 入口程序:**main.js**
|
||||
|
||||
3. 定義介面以及按鈕綁定的方法,和主進程的通信:**index.js**
|
||||
|
||||
3. 可以使用包括全部引擎API 和用戶組件腳本里聲明的方法和屬性:**scene-obtain..js**
|
||||
> 可以在擴展包中獲取到場景裡的Canvas根節點有多少子節點,當然還可以用來對場景節點進行更多的查詢和操作。
|
||||
|
||||
## 參考資料
|
||||
|
||||
* 你的第一個擴展包
|
||||
> https://docs.cocos.com/creator/manual/zh/extension/your-first-extension.html
|
||||
|
||||
* CocosCreator拓展编辑器
|
||||
> https://blog.csdn.net/qq_34772097/category_9577457.html
|
||||
|
||||
* Cocos Creator Editor 編輯器擴展API記錄
|
||||
> https://blog.csdn.net/kingbook928/article/details/108659319
|
||||
> https://blog.csdn.net/qq_17209641/article/details/106822296
|
||||
> https://forum.cocos.org/t/creator-api/92605
|
46
main.js
Normal file
46
main.js
Normal file
@ -0,0 +1,46 @@
|
||||
"use strict";
|
||||
let fs = require("fs");
|
||||
let path = require("path");
|
||||
|
||||
module.exports = {
|
||||
load() {
|
||||
this.init();
|
||||
},
|
||||
unload() {
|
||||
// Editor.log("卸載執行");
|
||||
},
|
||||
/** 初始化 */
|
||||
init() {
|
||||
// this.createDirectory();
|
||||
},
|
||||
/** 創建Spine節點 */
|
||||
createSpine(...args) {
|
||||
// Editor.log("文件0: " + JSON.stringify(args[0]));
|
||||
// Editor.log("文件1: " + JSON.stringify(args[1]));
|
||||
// Editor.log("文件2: " + JSON.stringify(args[2]));
|
||||
Editor.Scene.callSceneScript("spineset", "get-asset-info", { args: args }, function (err, response) {
|
||||
// Editor.log("callSceneScript: " + response);
|
||||
// let info = JSON.parse(response);
|
||||
// let path = info.path;
|
||||
// let url = info.url;
|
||||
});
|
||||
},
|
||||
messages: {
|
||||
/** 打開面板 */
|
||||
"open-panel"() {
|
||||
Editor.Panel.open("spineset");
|
||||
},
|
||||
/** 保存按鈕點擊 */
|
||||
"create-click"(event, ...args) {
|
||||
this.createSpine(...args);
|
||||
},
|
||||
/** 面板加載完成 */
|
||||
"panel-load-finish"(evnet, ...args) {
|
||||
Editor.Scene.callSceneScript("spineset", "get-default-info", { args: args }, function (err, response) {
|
||||
// Editor.log("callSceneScript: " + response);
|
||||
Editor.Ipc.sendToPanel("spineset", "setDefault", response);
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
}
|
21
package.json
Normal file
21
package.json
Normal file
@ -0,0 +1,21 @@
|
||||
{
|
||||
"name": "spineset",
|
||||
"version": "0.0.1",
|
||||
"description": "Sample-Package",
|
||||
"author": "Sample",
|
||||
"main": "main.js",
|
||||
"scene-script": "scene-obtain.js",
|
||||
"engineSupport": true,
|
||||
"main-menu": {
|
||||
"扩展/Create Spine": {
|
||||
"message": "spineset:open-panel"
|
||||
}
|
||||
},
|
||||
"panel": {
|
||||
"main": "panel/index.js",
|
||||
"type": "dockable",
|
||||
"title": "Create Spine",
|
||||
"width": 400,
|
||||
"height": 350
|
||||
}
|
||||
}
|
101
panel/index.js
Normal file
101
panel/index.js
Normal file
@ -0,0 +1,101 @@
|
||||
let assetPath = "";
|
||||
let defaultPolygonPath = "assets/";
|
||||
let polygonNameHeader = "polygon_";
|
||||
let polygonName = "";
|
||||
Editor.Panel.extend({
|
||||
style:
|
||||
`:host { margin: 5px; }
|
||||
h2 { color: #f90; }
|
||||
.bottom { height: 30px; }`,
|
||||
|
||||
template: `
|
||||
<h2 style="text-align:center">Auto Create Spine Prefab</h2>
|
||||
<hr />
|
||||
<div>
|
||||
1. 把要輸出的節點拉進來<br>
|
||||
2. 把要輸入的資料夾拉進來
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
要輸出的Node
|
||||
<ui-node class="flex-1" type="cc.Node" typename="Node" droppable="node" id="node"></ui-node>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
要輸入的資料夾
|
||||
<ui-asset class="flex-1" type="folder" droppable="asset" id="asset">ui-asset>
|
||||
</div>
|
||||
<div>
|
||||
Spine大小(選填)
|
||||
<ui-input placeholder="Spine大小 ex: 0.25" id="scale"></ui-input>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
要輸入的範例(選填)
|
||||
<ui-node class="flex-1" type="cc.Node" typename="Node" droppable="node" id="example"></ui-node>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
預設動畫名稱(選填)
|
||||
<ui-input placeholder="動畫名稱 ex: Move" id="anim"></ui-input>
|
||||
</div>
|
||||
<div style="text-align:right">
|
||||
<ui-button id="create" class="green">生成</ui-button>
|
||||
</div>
|
||||
`,
|
||||
|
||||
$: {
|
||||
/** Node */
|
||||
node: "#node",
|
||||
/** 資料夾 */
|
||||
asset: "#asset",
|
||||
/** Spine大小 */
|
||||
scale: "#scale",
|
||||
/** 範例 */
|
||||
example: "#example",
|
||||
/** 預設動畫名稱 */
|
||||
anim: "#anim",
|
||||
/** 生成按鈕 */
|
||||
create: "#create",
|
||||
},
|
||||
|
||||
ready() {
|
||||
// Editor.Ipc.sendToMain("spineset:panel-load-finish");
|
||||
this.createBtnClick();
|
||||
|
||||
},
|
||||
/** 保存按鈕點擊事件 */
|
||||
createBtnClick() {
|
||||
this.$create.addEventListener("confirm", () => {
|
||||
if (!this.$node._value) {
|
||||
Editor.error("請拖曳 Node 到視窗");
|
||||
return;
|
||||
} else if (!this.$asset._value) {
|
||||
Editor.error("請拖曳 資料夾 到視窗");
|
||||
return;
|
||||
}
|
||||
Editor.Ipc.sendToMain("spineset:create-click", this.$node, this.$asset, this.$example, this.$scale, this.$anim);
|
||||
// Editor.Ipc.sendToMain("spineset:create-click", this.$asset);
|
||||
});
|
||||
},
|
||||
messages: {
|
||||
"setDefault": function (event, ...agrs) {
|
||||
let Data = JSON.parse(agrs[0]);
|
||||
let node_uuid = Data["node_uuid"];
|
||||
let example_uuid = Data["example_uuid"];
|
||||
// Editor.log(`agrs: ${agrs[0]}`);
|
||||
// Editor.log(`node_uuid: ${node_uuid}`);
|
||||
// Editor.log(`example_uuid: ${example_uuid}`);
|
||||
if (node_uuid && node_uuid !== "") {
|
||||
this.$node.value = node_uuid;
|
||||
}
|
||||
if (example_uuid && example_uuid !== "") {
|
||||
this.$example.value = example_uuid;
|
||||
}
|
||||
if (event.reply) {
|
||||
//if no error, the first argument should be null
|
||||
event.reply(null, "Fine, thank you!");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
223
scene-obtain.js
Normal file
223
scene-obtain.js
Normal file
@ -0,0 +1,223 @@
|
||||
"use strict";
|
||||
let fs = require("fs");
|
||||
let path = require("path");
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* 獲取場景節點下的配置信息
|
||||
* @param event event
|
||||
* @param data 這邊把panel的Node帶進來
|
||||
*/
|
||||
"get-default-info": function (event, request) {
|
||||
let self = this;
|
||||
// Editor.log(`example: ${JSON.stringify(args[2])}`);
|
||||
let Canvas = cc.find("Canvas");
|
||||
var response = null;
|
||||
var args = request.args;
|
||||
let node = cc.find("Canvas/Prefab");
|
||||
let node_uuid = "";
|
||||
if (node) {
|
||||
node_uuid = node.uuid;
|
||||
}
|
||||
let example = cc.find("Canvas/example");
|
||||
let example_uuid = "";
|
||||
if (example) {
|
||||
example_uuid = example.uuid;
|
||||
}
|
||||
response = JSON.stringify({ node_uuid: node_uuid, example_uuid: example_uuid })
|
||||
if (event.reply) {
|
||||
event.reply(null, response);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 獲取場景節點下的配置信息
|
||||
* @param event event
|
||||
* @param data 這邊把panel的Node帶進來
|
||||
*/
|
||||
"get-asset-info": function (event, request) {
|
||||
let self = this;
|
||||
// Editor.log(`example: ${JSON.stringify(args[2])}`);
|
||||
let Canvas = cc.find("Canvas");
|
||||
var response = null;
|
||||
var args = request.args;
|
||||
let node = cc.find(args[0]._name);
|
||||
if (!node) {
|
||||
node = this.getAllChildByUuid(Canvas, args[0]._nodeID);
|
||||
}
|
||||
let asset = args[1];
|
||||
let example = cc.find(args[2]._name);
|
||||
if (!example) {
|
||||
example = this.getAllChildByUuid(Canvas, args[2]._nodeID);
|
||||
}
|
||||
if (!example) {
|
||||
example = cc.instantiate(new cc.Node);
|
||||
}
|
||||
let scale = args[3]._value;
|
||||
let anim = args[4]._value;
|
||||
// Editor.log(`scale: ${scale}`);
|
||||
// Editor.log(`node: ${node.name}`);
|
||||
// Editor.log(`example: ${example.name}`);
|
||||
Editor.assetdb.queryInfoByUuid(asset._value, function (err, info) {
|
||||
// info.path// info.url // info.type
|
||||
if (err) {
|
||||
response = err;
|
||||
}
|
||||
|
||||
let FolderName = [];
|
||||
// Editor.log("讀取資料夾中");
|
||||
fs.readdir(info.path, (err, files) => {
|
||||
files.forEach(file => {
|
||||
if (file.indexOf(".meta") === -1) {
|
||||
FolderName.push(file);
|
||||
// Editor.log(file);
|
||||
}
|
||||
});
|
||||
// Editor.log(`資料夾數量: ${FolderName.length}`);
|
||||
Editor.log(`根據來源生成${FolderName.length}個節點`);
|
||||
node.removeAllChildren();
|
||||
for (let i = 0; i < FolderName.length; i++) {
|
||||
// for (let i = 0; i < 1; i++) {
|
||||
// let i = 11;
|
||||
self.CreateNode(node, example, info.path, FolderName[i], i + 1, scale, anim);
|
||||
}
|
||||
});
|
||||
|
||||
// response = JSON.stringify(info);
|
||||
if (event.reply) {
|
||||
event.reply(null, "response");
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 把節點需要輸出的資料設置到每個json
|
||||
* @param Parent 需要取得資料的節點
|
||||
* @param Node 需要取得資料的節點
|
||||
*/
|
||||
async CreateNode(Parent, Node, path, FolderName, name, scale, anim) {
|
||||
scale = scale ? scale : 1;
|
||||
anim = anim ? anim : null;
|
||||
let file_path = `${path}\\${FolderName}`;
|
||||
let abs_path = `${path}\\${FolderName}\\${FolderName}.json`;
|
||||
let url = Editor.remote.assetdb.fspathToUrl(abs_path);
|
||||
let uuid = Editor.remote.assetdb.urlToUuid(url);
|
||||
// Editor.log(`FolderName: ${FolderName}`);
|
||||
// Editor.log(`abs_path: ${abs_path}`);
|
||||
// Editor.log(`url: ${url}`);
|
||||
// Editor.log(`uuid: ${uuid}`);
|
||||
let NewNode = cc.instantiate(Node);
|
||||
let Spine = NewNode.getChildByName("Spine");
|
||||
if (!Spine) {
|
||||
NewNode.addChild(new cc.Node, 0, "Spine");
|
||||
Spine = NewNode.getChildByName("Spine");
|
||||
}
|
||||
|
||||
let Skeleton = Spine.getComponent(sp.Skeleton);
|
||||
if (!Skeleton) {
|
||||
Skeleton = Spine.addComponent(sp.Skeleton);
|
||||
}
|
||||
NewNode.active = false;
|
||||
Parent.addChild(NewNode, 0, name + "");
|
||||
|
||||
let _pngcount = function () {
|
||||
return new Promise((resolve, reject) => {
|
||||
fs.readdir(file_path, (err, files) => {
|
||||
if (err) {
|
||||
Editor.log(`err: ${err}`);
|
||||
reject(err);
|
||||
}
|
||||
let pngcount = 0;
|
||||
files.forEach(file => {
|
||||
if (file.indexOf(".png") > -1 && file.indexOf(".meta") === -1) {
|
||||
pngcount++;
|
||||
}
|
||||
});
|
||||
resolve(pngcount);
|
||||
});
|
||||
});
|
||||
}
|
||||
let pngcount = await _pngcount();
|
||||
|
||||
//TODO : 此处为你的远程资源路径
|
||||
var image = `${path}\\${FolderName}\\${FolderName}`;
|
||||
var ske = `${path}\\${FolderName}\\${FolderName}.json`;
|
||||
var atlas = `${path}\\${FolderName}\\${FolderName}.atlas`;
|
||||
// Editor.log(`image: ${image}`);
|
||||
// Editor.log(`image2: ${image2}`);
|
||||
|
||||
// let texture = [await this.Load(image), await this.Load(image2)];
|
||||
// let textureName = [`${FolderName}.png`, `${FolderName}2.png`];
|
||||
let texture = [];
|
||||
let textureName = [];
|
||||
|
||||
|
||||
for (let i = 0; i < pngcount; i++) {
|
||||
let num = i + 1;
|
||||
texture.push(await this.Load(`${image}${(num > 1 ? num : "")}.png`));
|
||||
textureName.push(`${FolderName}${(num > 1 ? num : "")}.png`);
|
||||
// Editor.log(`texture ${i}: ${texture[i]}`);
|
||||
}
|
||||
|
||||
let atlasJson = (await this.Load(atlas)).text;
|
||||
// Editor.log(`atlasJson: ${atlasJson}`);
|
||||
let spineJson = (await this.Load(ske)).json;
|
||||
// Editor.log(`spineJson: ${spineJson}`);
|
||||
var asset = new sp.SkeletonData();
|
||||
asset._uuid = uuid;
|
||||
asset.skeletonJson = spineJson;
|
||||
asset.atlasText = atlasJson;
|
||||
asset.textures = texture;
|
||||
asset.textureNames = textureName;
|
||||
Skeleton.skeletonData = asset;
|
||||
// Editor.log(scale);
|
||||
Skeleton.node.scale = +scale;
|
||||
if (anim) {
|
||||
Skeleton.animation = anim;
|
||||
}
|
||||
Skeleton._updateSkeletonData();
|
||||
},
|
||||
|
||||
Load(abs_path) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// cc.loader.load(abs_path, (error, response) => {
|
||||
cc.assetManager.loadRemote(abs_path, (error, response) => {
|
||||
if (error) {
|
||||
Editor.log(`error: ${error}`);
|
||||
reject(error);
|
||||
}
|
||||
// Editor.log(`abs_path: ${abs_path}`);
|
||||
// Editor.log(`response: ${response}`);
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 根據Node去尋找底下每個子節點有沒有符合的UUID
|
||||
* @param Node 需要搜尋的節點
|
||||
* @param UUID 目標的UUID
|
||||
*/
|
||||
getAllChildByUuid(Node, UUID) {
|
||||
for (let i = 0; i < Node.childrenCount; i++) {
|
||||
// Editor.log("Node: " + Node.name, "UUID: " + Node.uuid);
|
||||
if (Node.uuid == UUID) {
|
||||
// Editor.log("找到 Node: " + Node.name, "UUID: " + Node.uuid);
|
||||
return Node;
|
||||
} else {
|
||||
// Editor.log("Node: " + Node.children[i].name, "UUID: " + Node.children[i].uuid);
|
||||
if (Node.children[i].uuid == UUID) {
|
||||
return Node.children[i];
|
||||
}
|
||||
}
|
||||
if (Node.children[i].childrenCount > 0) {
|
||||
// Editor.log(Node.children[i].name + " childrenCount > 0");
|
||||
let getAllChildByUuid = this.getAllChildByUuid(Node.children[i], UUID);
|
||||
if (getAllChildByUuid) {
|
||||
return getAllChildByUuid;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Editor.log("Node: " + Node.children[1].childrenCount);
|
||||
return null;
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue
Block a user