scene-info.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. 'use strict';
  2. const path = require('path');
  3. const fs = require('fs');
  4. const md5 = require('md5');
  5. const fe = Editor.require('packages://simple-code/tools/tools.js');
  6. // 工作路径
  7. let prsPath = Editor.importPath.split('library'+path.sep)[0] ;
  8. var eventFuncs =
  9. {
  10. // 获得活动面板
  11. getActiveUuid()
  12. {
  13. let activeInfo = Editor.Selection.curGlobalActivate() // 检测面板焦点在资源管理器还是层级管理器
  14. if (activeInfo && activeInfo.type == "asset")
  15. {
  16. return [activeInfo.id];
  17. }else{
  18. let ls = this.getJsFileList( this.findNode( Editor.Selection.curSelection('node')[0]) );
  19. let uuidList = [];
  20. ls.forEach((v,i)=>uuidList.push(v.__scriptUuid));
  21. return uuidList;
  22. }
  23. },
  24. // 获得当前所有选中的节点
  25. getSelectdNodes()
  26. {
  27. let selects = Editor.Selection.curSelection('node')
  28. let arrNode = []
  29. selects.forEach((uuid)=>{
  30. let node = this.findNode(uuid)
  31. arrNode.push(node)
  32. })
  33. return arrNode
  34. },
  35. // 检测场景是否存在该子节点并返回相关信息
  36. findNode(select_uuid)
  37. {
  38. var canvas = cc.director.getScene();
  39. var ret_node
  40. if (canvas && select_uuid) {
  41. this.getNodeChildren(canvas,(node)=>{
  42. if (node.uuid == select_uuid){
  43. ret_node = node;
  44. return ret_node;
  45. }
  46. })
  47. }
  48. return ret_node;
  49. },
  50. // 遍历所有深层子节点
  51. getNodeChildren(node,callFunc)
  52. {
  53. if (!node) return;
  54. let nodes = node.getChildren();
  55. nodes.forEach((v)=>{
  56. v._path_str = (node._path_str || node.name)+"/" + v.name;
  57. this.getNodeChildren(v,callFunc)
  58. });
  59. callFunc(node)
  60. },
  61. getNodeReChildren(node,callFunc)
  62. {
  63. if (!node) return;
  64. let nodes = node.getChildren();
  65. callFunc(node)
  66. nodes.forEach((v)=>{
  67. v._path_str = (node._path_str || node.name)+"/" + v.name;
  68. this.getNodeReChildren(v,callFunc)
  69. });
  70. },
  71. isHasJsFile(node){
  72. if(!node) {return false};
  73. return this.getJsFileList(node)[0];
  74. },
  75. getJsFileList(node){
  76. if(!node) {return []};
  77. let list = [];
  78. node.getComponents(cc.Component).forEach((v)=>{
  79. if(v.__classname__ && v.__classname__.indexOf(".") == -1) list.push(v); //js脚本
  80. });
  81. return list;
  82. },
  83. // 创建目录,绝对路径
  84. createDir(dirPath){
  85. if ( fs.existsSync(dirPath) ) return;
  86. let paths = dirPath.split(path.sep);//分割路径
  87. let path_ = "";
  88. for (let n = 0; n < paths.length; n++) {
  89. path_ += paths[n] + path.sep;
  90. if(!fs.existsSync(path_)){
  91. fs.mkdirSync(path_);
  92. }
  93. }
  94. },
  95. // 获得当前打开的场景文件路径
  96. getCurrSceneUrl(callFunc){
  97. let scene = cc.director.getScene();
  98. if(!scene) return callFunc();
  99. // 获得scene路径
  100. let url = Editor.remote.assetdb.uuidToUrl(scene.uuid);
  101. if (url) return callFunc(url,true,scene.uuid);
  102. // 当前打开的预制节点路径
  103. Editor.Ipc.sendToMain('simple-code:getPrefabUuid',{}, function (error, uuid)
  104. {
  105. if (uuid != null){
  106. callFunc( Editor.remote.assetdb.uuidToUrl(uuid),false,uuid)
  107. }
  108. });
  109. },
  110. uuidToUrl(uuids,callback){
  111. // 当前打开的预制节点路径
  112. Editor.Ipc.sendToMain('simple-code:uuidToUrl',{uuids:uuids}, function (error, answer)
  113. {
  114. if (answer && answer.urls && answer.urls[0]) return callFunc( answer.urls)
  115. });
  116. },
  117. // 获得场景下所有节点信息
  118. getSceneChildrensInfo(){
  119. var canvas = cc.director.getScene();
  120. if(!canvas) return [];
  121. let list = []
  122. this.getNodeChildren(canvas,(node)=>{
  123. list.push({
  124. name:node.name+"",
  125. uuid:node.uuid,
  126. path:node._path_str || node.name+"",
  127. })
  128. })
  129. return list;
  130. },
  131. // 调用原生JS的定时器
  132. setTimeoutToJS (func,time=1,{count=-1,dt=time}={}) {
  133. // 执行多少次
  134. if (count === 0) {
  135. let headler = setTimeout(func,time*1000);
  136. return () => clearTimeout(headler)
  137. }else{
  138. // 小于0就永久执行
  139. if (count<0) { count = cc.macro.REPEAT_FOREVER };
  140. let headler1,headler2;
  141. headler1 = setTimeout(() => {
  142. let i = 0;
  143. let funcGo = function(){
  144. i++;
  145. if (i === count) { clearInterval(headler2) }
  146. func();
  147. }
  148. // 小于0就永久执行
  149. if (count<0) { funcGo = function(){ func() } }
  150. headler2 = setInterval(funcGo,time*1000);
  151. funcGo();
  152. },dt*1000);
  153. return () => {
  154. clearTimeout(headler1);
  155. clearInterval(headler2);
  156. }
  157. }
  158. },
  159. // 是否新场景
  160. isNewScene(){
  161. let node =cc.director.getScene()
  162. // 空场景
  163. if (!node){
  164. return false;
  165. // 是新场景
  166. }else if(node.name == "New Node" && node.getChildByName('Canvas')!= null && node.getChildByName('Canvas').getComponent(cc.Canvas) != null){
  167. return true;
  168. }else{
  169. false;
  170. }
  171. return false
  172. },
  173. // 运行新场景
  174. runNewScene(call){
  175. // if (this.isNewScene()){
  176. // call(1)
  177. // }else{
  178. Editor.Ipc.sendToPanel('scene', 'scene:new-scene');
  179. setTimeout(()=>
  180. {
  181. if (this.isNewScene())
  182. {
  183. call(1)
  184. Editor.info("成功切换到新场景")
  185. }else
  186. {
  187. call(0)
  188. }
  189. }, 1000);
  190. // }
  191. },
  192. // 打开测试场景
  193. openDebugScene(uuid,isScene,call){
  194. this.runNewScene((is_new)=>
  195. {
  196. if(!is_new){
  197. call(0)
  198. return Editor.info("请保存场景后再运行调试")
  199. }
  200. if(isScene){
  201. cc.director._loadSceneByUuid_temp(uuid,(err,scene)=>
  202. {
  203. if (err){
  204. call(0)
  205. Editor.error("加载调试场景失败:\n",err)
  206. return
  207. }
  208. setTimeout(()=>{
  209. Editor.info("成功加载模拟场景")
  210. scene.name = "New Node";
  211. call(1);
  212. },100)
  213. });
  214. }else
  215. {
  216. let scene = cc.director.getScene()
  217. let canvas = scene.getChildByName("Canvas")
  218. if (canvas){
  219. canvas.removeAllChildren(true)
  220. Editor.Ipc.sendToPanel("scene","scene:create-nodes-by-uuids",[uuid],canvas.uuid,{unlinkPrefab:null},(err,e)=>{
  221. call(1)
  222. });
  223. }else{
  224. call(0)
  225. }
  226. }
  227. })
  228. },
  229. 'hint-node'(event,name){
  230. var canvas = cc.director.getScene();
  231. if (canvas) {
  232. this.getNodeChildren(canvas,(node)=>{
  233. if (node.name == name){
  234. Editor.Selection.select('node', [node.uuid]);
  235. return node;
  236. }
  237. })
  238. }
  239. },
  240. 'select-node'(event,args)
  241. {
  242. let is_file_self = false;
  243. let ret_node = null;
  244. let name_list = {};
  245. let uuid_list = Editor.Selection.curSelection('node');
  246. for (var i = 0; i < uuid_list.length; i++)
  247. {
  248. let node = this.findNode(uuid_list[i]);
  249. if (node) name_list[node.name] = true;
  250. }
  251. if (uuid_list.length==0){
  252. Editor.info("请您先选中节点后再操作");
  253. return;
  254. }
  255. let call = ()=>
  256. {
  257. let scene = cc.director.getScene()
  258. this.getNodeChildren(scene,(node)=>
  259. {
  260. if (ret_node == null && name_list[node.name]) {
  261. if (uuid_list.indexOf(node.uuid) == -1){
  262. if (is_file_self)
  263. {
  264. ret_node = node;
  265. uuid_list.push(ret_node.uuid)
  266. Editor.Selection.select('node', uuid_list);
  267. Editor.Ipc.sendToAll('hint', uuid_list)
  268. return ret_node;
  269. }
  270. }else{
  271. is_file_self = true
  272. }
  273. }
  274. })
  275. };
  276. call();
  277. if (!ret_node){
  278. is_file_self = true;
  279. call();
  280. }
  281. },
  282. 'select-node-by-name'(event,args)
  283. {
  284. let uuid_list = [];
  285. let scene = this.findNode(args.parent_uuid)
  286. if (!scene){
  287. Editor.info("请您先选中节点后再操作..");
  288. return;
  289. }
  290. this.getNodeChildren(scene,(node)=>
  291. {
  292. if (node.name.indexOf(args.name) != -1) {
  293. uuid_list.push(node.uuid)
  294. }
  295. });
  296. Editor.Selection.select('node', uuid_list);
  297. Editor.Ipc.sendToAll('hint', uuid_list)
  298. },
  299. // 获得选中的节点信息
  300. 'get-select-node-info': function (event) {
  301. // 获得当前选中的节点信息
  302. let nodes = this.getSelectdNodes()
  303. let arrInfo = []
  304. nodes.forEach((v)=>{
  305. arrInfo.push({
  306. uuid:v.uuid,
  307. name:v.name,
  308. path:v._path_str,
  309. })
  310. })
  311. event.reply(null,arrInfo);
  312. },
  313. // 获得文本内容
  314. 'get-node-code': function (event,uuids) {
  315. if (uuids && uuids.length >0){
  316. let list = []
  317. let max = uuids.length;
  318. uuids.forEach((uuid)=>{
  319. Editor.assetdb.queryInfoByUuid(uuid,(e,a)=>
  320. {
  321. if(!e && a && a.path){
  322. let name = a.path.substr(a.path.lastIndexOf(path.sep)+1)
  323. let file_type = name.substr(name.lastIndexOf('.')+1)
  324. if (file_type != name && file_type != "png" ){
  325. let text = fs.readFileSync(a.path).toString();
  326. list.push({ data:text, uuid:uuid,path:a.url,name:name ,file_type:file_type});
  327. }else{
  328. max --;
  329. }
  330. }else{
  331. max --;
  332. }
  333. if (max == list.length){
  334. event.reply(null,list);
  335. }
  336. })
  337. });
  338. }else{
  339. event.reply(null,[]);
  340. }
  341. },
  342. // 获得当前焦点uuid的信息
  343. 'get-active-uuid': function (event) {
  344. event.reply(null,{uuids:this.getActiveUuid()});
  345. },
  346. // 文件外部打开
  347. 'open-file-by-outside': function (event) {
  348. let id = this.getActiveUuid()[0]
  349. if (id){
  350. Editor.Ipc.sendToMain('assets:open-text-file',id);
  351. }else{
  352. Editor.info("当前活动面板没有发现可打开的资源")
  353. }
  354. },
  355. // 获取场景内所有子节点信息
  356. 'scene-children-info': function (event) {
  357. event.reply(null,JSON.stringify(this.getSceneChildrensInfo()))
  358. },
  359. // 控制動畫定時器
  360. 'cc-engine-animatin-mode': function (event,is_cmd_mode) {
  361. cc.engine.animatingInEditMode = is_cmd_mode //引擎需要开放这个才有动画效果
  362. cc.engine._animatingInEditMode = is_cmd_mode
  363. },
  364. // 标记场景切换时需要保存
  365. 'scene-need-save'(){
  366. let node = cc.director.getScene().children[0];
  367. if(!node){
  368. return;
  369. }
  370. let uuid = node.uuid;
  371. let opacity = node.opacity;
  372. // Editor.Ipc.sendToPanel('scene', 'scene:undo-commit');
  373. // Editor.Ipc.sendToAll('scene:undo-record',uuid,{id:uuid});
  374. // Editor.Ipc.sendToPanel('scene', 'scene:set-property',{
  375. // id: uuid,
  376. // path: "opacity",//要修改的属性
  377. // type: "number",
  378. // value: 2555,
  379. // isSubProp: false,
  380. // });
  381. Editor.Ipc.sendToPanel('scene', 'scene:set-property',{
  382. id: uuid,
  383. path: "opacity",//要修改的属性
  384. type: "number",
  385. value: opacity,
  386. isSubProp: false,
  387. });
  388. // 撤销
  389. Editor.Ipc.sendToPanel('scene', 'scene:undo');
  390. // 重做
  391. Editor.Ipc.sendToPanel('scene', 'scene:redo')
  392. Editor.Ipc.sendToPanel('scene', 'scene:undo-commit');
  393. // 恢复 nodeTree 选择状态
  394. let list = Editor.Selection.curSelection('node');
  395. setTimeout(()=>Editor.Selection.select('node', list),1)
  396. },
  397. // 运行命令
  398. 'run-command-code': function (event,args) {
  399. let require = cc.require;
  400. var scene = cc.director.getScene();
  401. var node = this.findNode( Editor.Selection.curSelection('node')[0])
  402. var ui = {}
  403. this.getNodeChildren(scene,(node)=>{
  404. ui[node.name] = node;
  405. })
  406. let miniCmd =
  407. {
  408. scene: scene,
  409. node : node,
  410. ui:ui,//场景上所有的节点
  411. run : function()
  412. {
  413. try {
  414. let log = eval(""+args.data+"");
  415. if (log && (typeof log == "object")){
  416. this.dump(log)
  417. console.log(log)
  418. }else{
  419. Editor.log(log);
  420. console.log(log);
  421. }
  422. } catch(t) {
  423. if(t && t.stack){
  424. let head = t.stack.substr(0,t.stack.indexOf("\n"))
  425. let endd = t.stack.substr(t.stack.indexOf(">")+1)
  426. endd = endd.substr(0,endd.indexOf(")"))
  427. Editor.info("调试命令 ERROR:",head+endd)
  428. }
  429. }
  430. },
  431. dump(obj){
  432. let str = ""
  433. let i = 0
  434. for(let name in obj) {
  435. try{
  436. str += name + ": " + obj[name] + "\n"
  437. }catch(err){
  438. str += name + ": " + typeof obj[name] + "\n"
  439. }
  440. i ++;
  441. if (i>100){
  442. str+="...more"
  443. break;
  444. }
  445. }
  446. Editor.log("dump:"+obj,str)
  447. },
  448. }
  449. miniCmd.run();
  450. // 引擎需要开放这个才有动画效果
  451. cc.engine._animatingInEditMode = 1
  452. cc.engine.animatingInEditMode = 1
  453. if (args.type == "scene")
  454. {
  455. }else if(args.uuid){
  456. this['run-js-file'](null,args);// 执行代码脚本
  457. }
  458. },
  459. 'run-js-file'(event,args){
  460. this.getNodeReChildren(cc.director.getScene(),(v)=>
  461. {
  462. let list = this.getJsFileList(v);
  463. list.forEach((js)=>
  464. {
  465. if(js.__scriptUuid == args.uuid){
  466. if(js.onLoad) {js.onLoad()}
  467. if(js.start) {js.start()}
  468. if(js.update) {
  469. this.setTimeoutToJS(()=>{
  470. if(js.isValid) js.update(0.02);
  471. },0.02,{count:60})
  472. }
  473. }
  474. })
  475. })
  476. },
  477. // 运行场景所有节点绑定的脚本
  478. 'run-node-js': function (event,args) {
  479. // mm.prototype.constructor._executeInEditMode = true; mm.prototype.constructor._playOnFocus = true
  480. let node = cc.director.getScene() // this.findNode( children[0] );
  481. if (node == null){
  482. return Editor.log("调试节点脚本:没有发现运行的场景")
  483. }
  484. let dt = 0.01
  485. let stopRuncFunc = ()=>{
  486. if (this._run_scene_update_times_id){
  487. this._run_scene_update_times_id()
  488. delete this._run_scene_update_times_id;
  489. CC_EDITOR = true
  490. Editor.info("调试节点脚本:已停止模拟运行环境调试")
  491. }
  492. }
  493. if(this._run_scene_update_times_id){
  494. stopRuncFunc();
  495. return
  496. }
  497. // 忽略组件
  498. let ignore_list = {
  499. "cc.Camera" :{"onEnable":1,"onDisable":1,"onLoad":1,"start":1,"update":1},
  500. "cc.Canvas" :{"onEnable":1,"onDisable":1,"onLoad":1,"start":1,"update":1},
  501. "cc.MeshRenderer" :{"onEnable":1,"onDisable":1,"onLoad":1,"start":1,"update":1},
  502. "cc.Sprite" :{"onEnable":1,"onDisable":1,"onLoad":1,"start":1,"update":1},
  503. "cc.Label" :{"onEnable":1,"onDisable":1,"onLoad":1,"start":1,"update":1},
  504. "cc.Label" :{"onEnable":1,"onDisable":1,"onLoad":1,"start":1,"update":1},
  505. }
  506. let runCompFunc = (v,funcName,args,isOneRun=true)=>
  507. {
  508. //let comps = getComponents(cc.Component)
  509. v._components.forEach((jsComp)=>
  510. {
  511. if(jsComp && jsComp.enabled && (ignore_list[jsComp.__classname__] == null || ignore_list[jsComp.__classname__][funcName] == null) )//|| !jsComp.__proto__.constructor._executeInEditMode) )
  512. {
  513. let hasName = funcName+jsComp.name+"_is_run_testScene_";
  514. if(jsComp[funcName] && (!isOneRun || !v[hasName])) {
  515. v[hasName] = true
  516. CC_EDITOR = jsComp.__classname__ && jsComp.__classname__.indexOf("cc.") == -1;// 使用引擎的方法
  517. // console.log(jsComp.__classname__,funcName)
  518. jsComp[funcName](args)
  519. CC_EDITOR = true
  520. }
  521. }
  522. })
  523. }
  524. Editor.info("调试节点脚本:开始模拟运行环境调试")
  525. this._run_scene_update_times_id = this.setTimeoutToJS(()=>
  526. {
  527. try{
  528. if (!node.isValid) return stopRuncFunc();
  529. this.getNodeReChildren(node,(v)=>
  530. {
  531. if (v.isValid && ( v == node || v.activeInHierarchy) )
  532. {
  533. if(v._scene_test_loop_count == null)
  534. {
  535. v._scene_test_loop_count = 1;
  536. v.on("child-added",(event)=>{
  537. // runCompFunc(event.detail,"onLoad");
  538. // if (event.detail.activeInHierarchy()
  539. // runCompFunc(event.detail,"start");
  540. })
  541. v.on("active-in-hierarchy-changed",(event)=>{
  542. let child = event.detail || event
  543. if (child.active){
  544. runCompFunc(child,"onEnable",null,false);
  545. }
  546. })
  547. v.on("child-removed",(event)=>{
  548. let child = event.detail || event
  549. runCompFunc(child,"onDisable",null,false);
  550. })
  551. runCompFunc(v,"onLoad");
  552. runCompFunc(v,"onEnable",null,false);
  553. }else if(v._scene_test_loop_count == 1){
  554. v._scene_test_loop_count = 2
  555. runCompFunc(v,"start");
  556. }else if(v._scene_test_loop_count == 2){
  557. runCompFunc(v,"update",dt,false);
  558. }
  559. }
  560. })
  561. cc.engine._animatingInEditMode = 1
  562. cc.engine.animatingInEditMode = 1
  563. }catch(t){
  564. Editor.error("调试脚本ERROR:\n",t)
  565. stopRuncFunc();
  566. }
  567. },dt,{count:-1})
  568. // node.on("child-added",(event)=>{
  569. // let v = event.detail
  570. // if (v.activeInHierarchy)
  571. // {
  572. // Editor.log(v.name)
  573. // let comps = v.getComponents(cc.Component)
  574. // comps.forEach((jsComp)=>{
  575. // if(jsComp){
  576. // if(jsComp.onLoad) jsComp.onLoad()
  577. // if(jsComp.start) jsComp.start()
  578. // }
  579. // })
  580. // }
  581. // })
  582. },
  583. };
  584. // 合并事件函数,分发
  585. let info = Editor.require('packages://simple-code/tools/eventMerge').eventMerge(eventFuncs,"scene_ex.js")
  586. let fileList = fe.getDirAllFiles(Editor.url("packages://simple-code/extensions"),[])
  587. eventFuncs = info.messages
  588. module.exports = eventFuncs;