7、2D对象

引擎中所有不拥有的 model 的渲染对象都为 2D 渲染对象。与 3D 对象不同,2D 对象本身不拥有 model 信息,其顶点信息是由 UITransform 组件的 Rect 信息持有并由引擎创建的,且本身没有厚度。由于引擎的设计要求,2D 渲染对象需要为 RenderRoot 节点(带有 RenderRoot2D 组件的节点)的子节点才能完成数据的收集操作。

所以 2D 渲染对象的渲染要求有两点:

  1. 自身带有 UITransform 组件
  2. 需要为带有 RenderRoot2D/Canvas 组件节点的子节点(也就是说,2D节点必须以RenderRoot2D/Canvas节点为Parent)

2D对象跟随3D对象

例如,常见的英雄联盟,人物是3D对象,而头上的血条是2D对象,这就需要让2D的血条可以跟随3D的人物移动。

image-20240906115055053

要让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的父节点,否则可能会闪。