引擎中所有不拥有的 model 的渲染对象都为 2D 渲染对象。与 3D 对象不同,2D 对象本身不拥有 model 信息,其顶点信息是由 UITransform 组件的 Rect 信息持有并由引擎创建的,且本身没有厚度。由于引擎的设计要求,2D 渲染对象需要为 RenderRoot 节点(带有 RenderRoot2D 组件的节点)的子节点才能完成数据的收集操作。
所以 2D 渲染对象的渲染要求有两点:
例如,常见的英雄联盟,人物是3D对象,而头上的血条是2D对象,这就需要让2D的血条可以跟随3D的人物移动。
要让BloodLabel跟随玩家Player移动,代码如下
// 血条控制类
@ccclass('BloodController')
export class BloodController extends Component {
// 3D场景的主摄像机节点
@property(Node)
private mainCamera: Node = null;
@property(Node)
private bloodLabelParent: Node = null;
@property(Node)
private bloodLabel: Node = null;
start() {
}
update(deltaTime: number) {
this.bloodLabelFollowPlayer();
}
/**
* 主角血量跟随主角移动
*/
private bloodLabelFollowPlayer(){
// 该脚本组件挂载在Player节点上面,获取玩家的世界坐标
var pos = this.node.getWorldPosition()
// Label在Player的头顶,所以增加了y轴的偏移量
Vec3.add(pos,pos,new Vec3(0,2.5,0))
// 接收坐标
var out = new Vec3(0,0,0)
// 将三维坐标转换成bloodLabelParent所在二维场景的坐标
this.mainCamera.getComponent(CameraComponent).convertToUINode(pos,this.bloodLabelParent,out)
// 设置坐标
this.bloodLabel.position = out
}
}
注意:使用convertToUINode
的第二个参数,要使用最终Label的父节点,否则可能会闪。