刚学Cocos Creator,想实现一个效果:立方体切换每面的颜色,网上搜索了一堆例子都是整个立方体的纹理切换,而且每个面的效果都是一样的,官方文档也没有给出合适的例子,后面通过查看引擎代码,终于摸索出一些效果。现在分享出来,欢迎批评指正。
1、实现的效果:
2、代码:
import { _decorator, SystemEvent,Component, Graphics, primitives,log, Mesh,
MeshRenderer, ModelComponent, Quat, Node, Vec3, systemEvent, EventMouse, EventTouch, gfx,
v3, utils, Material, color, Color} from 'cc';
const { ccclass, property } = _decorator;
@ccclass('Typescript')
export class Typescript extends Component {
private createMesh(): Mesh | null {
var verts2: any = [];
verts2.push(-1,-1,1); // 0
verts2.push(-1,-1,-1); // 1
verts2.push(-1,1,-1); // 2
verts2.push(-1,-1,1); // 0
verts2.push(-1,1,-1); // 2
verts2.push(-1,1,1); // 3
///
verts2.push(-1,-1,1); // 0
verts2.push(-1,1,1); // 3
verts2.push(1,1,1); // 7
verts2.push(-1,-1,1); // 0
verts2.push(1,1,1); // 7
verts2.push(1,-1,1); // 4
///
verts2.push(-1,1,-1); // 2
verts2.push(-1,1,1); // 3
verts2.push(1,1,-1); // 6
verts2.push(-1,1,1); // 3
verts2.push(1,1,-1); // 6
verts2.push(1,1,1); // 7
///
verts2.push(-1,-1,-1); // 1
verts2.push(-1,1,-1); // 2
verts2.push(1,1,-1); // 6
verts2.push(-1,-1,-1); // 1
verts2.push(1,-1,-1); // 5
verts2.push(1,1,-1); // 6
///
verts2.push(-1,-1,1); // 0
verts2.push(-1,-1,-1); // 1
verts2.push(1,-1,-1); // 5
verts2.push(-1,-1,1); // 0
verts2.push(1,-1,1); // 4
verts2.push(1,-1,-1); // 5
///
verts2.push(1,-1,1); // 4
verts2.push(1,-1,-1); // 5
verts2.push(1,1,-1); // 6
verts2.push(1,-1,1); // 4
verts2.push(1,1,1); // 7
verts2.push(1,1,-1); // 6
var ver_uvs: any = [];
ver_uvs.push(0)
ver_uvs.push(0)
ver_uvs.push(0)
ver_uvs.push(0.5)
ver_uvs.push(0.5)
ver_uvs.push(0.5)
var ver_colors: any=[]
ver_colors.push(255,0,0,0);
ver_colors.push(255,0,0,0);
ver_colors.push(255,0,0,0);
ver_colors.push(255,0,0,0);
ver_colors.push(255,0,0,0);
ver_colors.push(255,0,0,0);
ver_colors.push(0,255,0,0);
ver_colors.push(0,255,0,0);
ver_colors.push(0,255,0,0);
ver_colors.push(0,255,0,0);
ver_colors.push(0,255,0,0);
ver_colors.push(0,255,0,0);
ver_colors.push(0,0,255,0);
ver_colors.push(0,0,255,0);
ver_colors.push(0,0,255,0);
ver_colors.push(0,0,255,0);
ver_colors.push(0,0,255,0);
ver_colors.push(0,0,255,0);
ver_colors.push(0,255,255,0);
ver_colors.push(0,255,255,0);
ver_colors.push(0,255,255,0);
ver_colors.push(0,255,255,0);
ver_colors.push(0,255,255,0);
ver_colors.push(0,255,255,0);
ver_colors.push(255,0,255,0);
ver_colors.push(255,0,255,0);
ver_colors.push(255,0,255,0);
ver_colors.push(255,0,255,0);
ver_colors.push(255,0,255,0);
ver_colors.push(255,0,255,0);
ver_colors.push(255,255,0,0);
ver_colors.push(255,255,0,0);
ver_colors.push(255,255,0,0);
ver_colors.push(255,255,0,0);
ver_colors.push(255,255,0,0);
ver_colors.push(255,255,0,0);
var meshConfig = {
positions: verts2,
//indices:ver_indices,
colors: ver_colors,
//uvs:ver_uvs,
};
console.log(meshConfig)
var mesh = utils.createMesh(meshConfig);
console.log(mesh);
return mesh;
}
start () {
//const box = primitives.box({ width: 5, length: 5, height:5});
//const mesh = utils.createMesh(box);
systemEvent.on(SystemEvent.EventType.TOUCH_MOVE, this.onTouchMove, this);
let mesh = this.createMesh()
var renderer = this.getComponent(MeshRenderer);
if (renderer)
renderer.mesh = mesh;
}
onTouchMove(event: EventTouch) {
let dif = event.getDelta();
let q_tmp = new Quat();
let v_tmp = new Vec3(-dif.y, dif.x, 0);
v_tmp.normalize();
let out_Q = Quat.rotateAround(q_tmp, this.node.rotation, v_tmp, Math.PI * 0.01);
this.node.setRotation(out_Q.x, out_Q.y, out_Q.z, out_Q.w);
}
}
3、meterial 设置
这是我踩坑比较深的地方,立方体能构建出来,也设置了顶点颜色,始终颜色出不来的原因。需要在材质中设置下面两项,如图所示:
如果想基于纹理贴图的方式,需要勾选USE TEXTURE,同时在创建Mesh网格时要指定uv分量。
4、个人理解:
3D物体贴图,就是Mesh+material。Mesh是网格模型,里面包含顶点,以及顶点如何构成面,面如何构成体的。material是一些绘制的方法(是纹理贴图、还是顶点着色、光照效果等)
创建网格:
utils.createMesh(meshConfig),utils库里面有个API
/**
* @en
* The definition of the geometry, this struct can build a mesh.
* @zh
* 几何体信息。
*/
export interface IGeometry {
/**
* @en
* Vertex positions.
* @zh
* 顶点位置。
*/
positions: number[];
/**
* @en
* Vertex normals.
* @zh
* 顶点法线。
*/
normals?: number[];
/**
* @en
* Texture coordinates.
* @zh
* 纹理坐标。
*/
uvs?: number[];
/**
* @en
* Vertex Tangents.
* @zh
* 顶点切线。
*/
tangents?: number[];
/**
* @en
* Vertex colors.
* @zh
* 顶点颜色。
*/
colors?: number[];
positions是顶点坐标,uvs在纹理贴图时需要指定,colors在顶点着色时需要指定,每个顶点一个颜色,indices是顶点索引,顶点索引是构成面的顺序,每三个索引顶点构成一个面。当不指定indices时,按positions的默认顺序每三个顶点构成一个面。在我的例子中,很多顶点是重复的,我是以每一个三角面设置3个顶点,3个顶点设置同一个顶点颜色,这样面的颜色就确定下来了,如果采用顶点索引顶点共用,顶点颜色也是共用的,面的颜色不好控制。