提了很多关于节点层级改变时相关操作的问题,大家都很积极的帮助,现在把代码分享出来,谢谢大家。
cocos creator考虑升级时内置类似的功能吧。
主要就是变换父节点时,选择性保持原有世界变换。
1赞
var utils = {
node: {
/**
* 将parentNode设置为childNode的父节点
* @param {cc.Node} parentNode
* @param {cc.Node} childNode
* @param {bool} keepWorldTransform true,则维持childNode之前的世界变换
*/
setParent(parentNode, childNode, keepWorldTransform) {
if (parentNode === childNode.parent)
return;
if (keepWorldTransform === true) {
// keep world transform not changed
let worldPos = utils.node.getWorldPosition(childNode);
let worldRotation = utils.node.getWorldRotation(childNode);
let lossyScale = utils.node.getWorldScale(childNode);
childNode.parent = parentNode;
// restore world transform
utils.node.setWorldPosition(childNode, worldPos);
utils.node.setWorldRotation(childNode, worldRotation);
if (parentNode) {
let parentWorldScale = utils.node.getWorldScale(parentNode);
lossyScale.x /= parentWorldScale.x;
lossyScale.y /= parentWorldScale.y;
childNode.scale = lossyScale;
} else {
childNode.scale = lossyScale;
}
} else {
childNode.parent = parentNode;
}
},
/**
* 获得node的世界坐标
* @param {cc.Node} node
* @returns {cc.Vec2}
*/
getWorldPosition(node) {
return node.parent.convertToWorldSpaceAR(node.position);
},
/**
* 将node设置到世界坐标worldPos处
* @param {cc.Node} node
* @param {cc.Vec2} worldPos
*/
setWorldPosition(node, worldPos) {
var parent = node.parent;
if (parent) {
node.position = parent.convertToNodeSpaceAR(worldPos);
} else {
node.position = worldPos;
}
return node.position;
},
/**
* 获得node在世界坐标系下的旋转
* @param {cc.Node} node
* @return {float}
*/
getWorldRotation(node) {
return utils.node.getNodeToWorldRotation(node.parent, node.rotation);
},
/**
* 将node设置为世界坐标系下旋转worldRotation的姿态
* @param {cc.Node} node
* @param {cc.Vec2} worldRotation
*/
setWorldRotation(node, worldRotation){
node.rotation = utils.node.getWorldToNodeRotation(node.parent, worldRotation);
//
return node.rotation;
},
/**
* 获得node在世界坐标下的缩放
* @param {cc.Node} node
* @returns {cc.Vec2}
*/
getWorldScale(node){
return utils.node.getNodeToWorldScale(node.parent, node.scaleX, node.scaleY);
},
/**
* 将node设置为在世界坐标下缩放worldScale的形态
* @param {cc.Node} node
* @param {*} worldScale
*/
setWorldScale(node, worldScale){
var s = utils.node.getWorldToNodeScale(node.parent, worldScale.x, worldScale.y);
node.scale = s;
//
return node.scale;
},
/**
* 获得node本地坐标系下的点在世界坐标系下的位置
* @param {cc.Node} node
* @param {cc.Vec2} positionInNode
*/
getNodeToWorldPosition(node, positionInNode){
if (node === null)
return positionInNode;
return node.convertToWorldSpaceAR(positionInNode);
},
/**
* 获得世界坐标系下的点在node本地坐标下的位置
* @param {cc.Node} node
* @param {cc.Vec2} positionInWorld
*/
getWorldToNodePosition(node, positionInWorld){
if (node === null)
return positionInWorld;
return node.convertToNodeSpaceAR(positionInWorld);
},
/**
* 获得node本地坐标下的缩放在世界坐标下的缩放量
* @param {cc.Node} node
* @param {float} scaleXInNode
* @param {float} scaleYInNode
*/
getNodeToWorldScale(node, scaleXInNode, scaleYInNode) {
// if (node === null)
// return new cc.Vec2(scaleXInNode, scaleYInNode);
var scaleX = scaleXInNode;//node.scaleX;
var scaleY = scaleYInNode;//node.scaleY;
var parent = node;//.parent;
while (parent){// && parent.parent) {
scaleX *= parent.scaleX;
scaleY *= parent.scaleY;
parent = parent.parent;
}
// return new cc.Vec2(scaleX, scaleY);
return new cc.Vec2(scaleX, scaleY);
},
/**
* 获得世界缩放在node本地坐标下的缩放量
* @param {cc.Node} node
* @param {float} scaleXInWorld
* @param {float} scaleYInWorld
*/
getWorldToNodeScale(node, scaleXInWorld, scaleYInWorld) {
// if (node === null)
// return new cc.Vec2(scaleXInWorld, scaleYInWorld);
// var scale = utils.node.getNodeToWorldScale(node.parent, node.scaleX, node.scaleY);
var scale = utils.node.getWorldScale(node);
return new cc.Vec2(scaleXInWorld / scale.x, scaleYInWorld / scale.y);
},
/**
* 获得node本地坐标下的旋转在世界坐标下的旋转量
* @param {cc.Node} node
* @param {float} rotationInNode
*/
getNodeToWorldRotation(node, rotationInNode) {
// if (node === null)
// return rotationInNode;
var rot = rotationInNode;//node.rotationX;
var parent = node;//.parent;
while (parent){//} && parent.parent) {
rot += parent.rotation;
parent = parent.parent;
}
return rot;
},
/**
* 获得世界坐标下的旋转在node本地坐标下的旋转量
* @param {cc.Node} node
* @param {float} rotationInWorld
*/
getWorldToNodeRotation(node, rotationInWorld) {
// if (node === null)
// return rotationInWorld;
var rotation = rotationInWorld;
// rotation -= node.rotation;
var parent = node;//.parent;
while (parent){//} && parent.parent) {
rotation -= parent.rotation;
parent = parent.parent;
}
return rotation;
},
},
};
module.exports = utils;
5赞
很好的代码,记录一下
感谢分享代码,正需要这个功能,不知道官方有没有类似的API。
你好,谢谢你的热心反馈,我们现在已经计划在 3.x 版本支持这个设计。具体支持版本尚不明确。