360 tris0.86 × 1.78 × 0.73 m
Use it in code
Remix in the editorblocky-character.js · 204 lines
Self-contained ES module — only depends on three. Call the factory and add the group to your scene.
/**
* Blocky Character — Codels 3D model library
* License: CC0-1.0 · Units: meters · Y-up · Front: +Z · Origin: center of the base (y = 0)
* Triangles: 360 · Size (W × H × D): 0.86 × 1.78 × 0.72 m
*
* Usage:
* import { createBlockyCharacter } from './blocky-character.js';
*
* const model = createBlockyCharacter();
* model.position.set(0, 0, 0);
* scene.add(model);
*/
import * as THREE from 'three';
const deg = THREE.MathUtils.degToRad;
export function createBlockyCharacter() {
const root = new THREE.Group();
root.name = 'BlockyCharacter';
// Materials
const skinMat = new THREE.MeshStandardMaterial({ name: 'skin', color: 0xf1c29a, roughness: 0.8, flatShading: true });
const hairMat = new THREE.MeshStandardMaterial({ name: 'hair', color: 0x5b3a24, roughness: 0.9, flatShading: true });
const shirtMat = new THREE.MeshStandardMaterial({ name: 'shirt', color: 0x3f8fd6, roughness: 0.85, flatShading: true });
const pantsMat = new THREE.MeshStandardMaterial({ name: 'pants', color: 0x34405e, roughness: 0.85, flatShading: true });
const shoeMat = new THREE.MeshStandardMaterial({ name: 'shoe', color: 0x2b2626, roughness: 0.7, flatShading: true });
const eyeWhiteMat = new THREE.MeshStandardMaterial({ name: 'eyeWhite', color: 0xfbfaf7, roughness: 0.5, flatShading: true });
const eyeMat = new THREE.MeshStandardMaterial({ name: 'eye', color: 0x262130, roughness: 0.4, flatShading: true });
const mouthMat = new THREE.MeshStandardMaterial({ name: 'mouth', color: 0x9a4b45, roughness: 0.7, flatShading: true });
const capMat = new THREE.MeshStandardMaterial({ name: 'cap', color: 0xe04a3b, roughness: 0.8, flatShading: true });
const goldMat = new THREE.MeshStandardMaterial({ name: 'gold', color: 0xf2c24a, roughness: 0.3, metalness: 0.65, flatShading: true });
// Shared geometries
const boxGeo = new THREE.BoxGeometry(0.2, 0.54, 0.22);
const boxGeo2 = new THREE.BoxGeometry(0.21, 0.09, 0.27);
const boxGeo3 = new THREE.BoxGeometry(0.16, 0.22, 0.2);
const boxGeo4 = new THREE.BoxGeometry(0.15, 0.3, 0.18);
const boxGeo5 = new THREE.BoxGeometry(0.06, 0.12, 0.3);
const boxGeo6 = new THREE.BoxGeometry(0.1, 0.1, 0.01);
const boxGeo7 = new THREE.BoxGeometry(0.05, 0.08, 0.01);
const boxGeo8 = new THREE.BoxGeometry(0.06, 0.03, 0.006);
// Parts
const legL = new THREE.Group();
legL.name = 'legL';
legL.position.set(0.11, 0.62, 0);
root.add(legL);
const pantLegL = new THREE.Mesh(boxGeo, pantsMat);
pantLegL.name = 'pantLegL';
pantLegL.position.set(0, -0.27, 0);
legL.add(pantLegL);
const shoeL = new THREE.Mesh(boxGeo2, shoeMat);
shoeL.name = 'shoeL';
shoeL.position.set(0, -0.575, 0.025);
legL.add(shoeL);
const legR = new THREE.Group();
legR.name = 'legR';
legR.position.set(-0.11, 0.62, 0);
root.add(legR);
const pantLegR = new THREE.Mesh(boxGeo, pantsMat);
pantLegR.name = 'pantLegR';
pantLegR.position.set(0, -0.27, 0);
legR.add(pantLegR);
const shoeR = new THREE.Mesh(boxGeo2, shoeMat);
shoeR.name = 'shoeR';
shoeR.position.set(0, -0.575, 0.025);
legR.add(shoeR);
const body = new THREE.Group();
body.name = 'body';
root.add(body);
const torso = new THREE.Mesh(new THREE.BoxGeometry(0.46, 0.54, 0.26), shirtMat);
torso.name = 'torso';
torso.position.set(0, 0.88, 0);
body.add(torso);
const belt = new THREE.Mesh(new THREE.BoxGeometry(0.47, 0.07, 0.27), pantsMat);
belt.name = 'belt';
belt.position.set(0, 0.64, 0);
body.add(belt);
const buckle = new THREE.Mesh(new THREE.BoxGeometry(0.08, 0.05, 0.02), goldMat);
buckle.name = 'buckle';
buckle.position.set(0, 0.64, 0.138);
body.add(buckle);
const neckline = new THREE.Mesh(new THREE.BoxGeometry(0.18, 0.06, 0.02), skinMat);
neckline.name = 'neckline';
neckline.position.set(0, 1.12, 0.133);
body.add(neckline);
const armL = new THREE.Group();
armL.name = 'armL';
armL.position.set(0.315, 1.1, 0);
armL.rotation.set(0, 0, deg(5));
root.add(armL);
const sleeveL = new THREE.Mesh(boxGeo3, shirtMat);
sleeveL.name = 'sleeveL';
sleeveL.position.set(0, -0.09, 0);
armL.add(sleeveL);
const forearmL = new THREE.Mesh(boxGeo4, skinMat);
forearmL.name = 'forearmL';
forearmL.position.set(0, -0.33, 0);
armL.add(forearmL);
const armR = new THREE.Group();
armR.name = 'armR';
armR.position.set(-0.315, 1.1, 0);
armR.rotation.set(0, 0, deg(-5));
root.add(armR);
const sleeveR = new THREE.Mesh(boxGeo3, shirtMat);
sleeveR.name = 'sleeveR';
sleeveR.position.set(0, -0.09, 0);
armR.add(sleeveR);
const forearmR = new THREE.Mesh(boxGeo4, skinMat);
forearmR.name = 'forearmR';
forearmR.position.set(0, -0.33, 0);
armR.add(forearmR);
const head = new THREE.Group();
head.name = 'head';
head.position.set(0, 1.12, 0);
root.add(head);
const neck = new THREE.Mesh(new THREE.BoxGeometry(0.16, 0.06, 0.16), skinMat);
neck.name = 'neck';
neck.position.set(0, 0.02, 0);
head.add(neck);
const skull = new THREE.Mesh(new THREE.BoxGeometry(0.5, 0.5, 0.5), skinMat);
skull.name = 'skull';
skull.position.set(0, 0.28, 0);
head.add(skull);
const hairTop = new THREE.Mesh(new THREE.BoxGeometry(0.512, 0.12, 0.512), hairMat);
hairTop.name = 'hairTop';
hairTop.position.set(0, 0.476, 0);
head.add(hairTop);
const hairBack = new THREE.Mesh(new THREE.BoxGeometry(0.512, 0.3, 0.1), hairMat);
hairBack.name = 'hairBack';
hairBack.position.set(0, 0.33, -0.206);
head.add(hairBack);
const fringe = new THREE.Mesh(new THREE.BoxGeometry(0.22, 0.06, 0.02), hairMat);
fringe.name = 'fringe';
fringe.position.set(-0.1, 0.38, 0.256);
head.add(fringe);
const sideburnL = new THREE.Mesh(boxGeo5, hairMat);
sideburnL.name = 'sideburnL';
sideburnL.position.set(0.226, 0.37, -0.1);
head.add(sideburnL);
const sideburnR = new THREE.Mesh(boxGeo5, hairMat);
sideburnR.name = 'sideburnR';
sideburnR.position.set(-0.226, 0.37, -0.1);
head.add(sideburnR);
const eyeWhiteL = new THREE.Mesh(boxGeo6, eyeWhiteMat);
eyeWhiteL.name = 'eyeWhiteL';
eyeWhiteL.position.set(0.11, 0.3, 0.253);
head.add(eyeWhiteL);
const pupilL = new THREE.Mesh(boxGeo7, eyeMat);
pupilL.name = 'pupilL';
pupilL.position.set(0.088, 0.29, 0.259);
head.add(pupilL);
const blushL = new THREE.Mesh(boxGeo8, mouthMat);
blushL.name = 'blushL';
blushL.position.set(0.17, 0.21, 0.253);
head.add(blushL);
const eyeWhiteR = new THREE.Mesh(boxGeo6, eyeWhiteMat);
eyeWhiteR.name = 'eyeWhiteR';
eyeWhiteR.position.set(-0.11, 0.3, 0.253);
head.add(eyeWhiteR);
const pupilR = new THREE.Mesh(boxGeo7, eyeMat);
pupilR.name = 'pupilR';
pupilR.position.set(-0.088, 0.29, 0.259);
head.add(pupilR);
const blushR = new THREE.Mesh(boxGeo8, mouthMat);
blushR.name = 'blushR';
blushR.position.set(-0.17, 0.21, 0.253);
head.add(blushR);
const mouth = new THREE.Mesh(new THREE.BoxGeometry(0.12, 0.03, 0.01), mouthMat);
mouth.name = 'mouth';
mouth.position.set(0, 0.17, 0.253);
head.add(mouth);
const cap = new THREE.Group();
cap.name = 'cap';
cap.position.set(0, 0.486, 0);
head.add(cap);
const capCrown = new THREE.Mesh(new THREE.BoxGeometry(0.54, 0.14, 0.54), capMat);
capCrown.name = 'capCrown';
capCrown.position.set(0, 0.07, 0);
cap.add(capCrown);
const capBrim = new THREE.Mesh(new THREE.BoxGeometry(0.45, 0.03, 0.2), capMat);
capBrim.name = 'capBrim';
capBrim.position.set(0, 0.015, 0.35);
cap.add(capBrim);
const capButton = new THREE.Mesh(new THREE.BoxGeometry(0.06, 0.03, 0.06), capMat);
capButton.name = 'capButton';
capButton.position.set(0, 0.155, 0);
cap.add(capButton);
const capBand = new THREE.Mesh(new THREE.BoxGeometry(0.55, 0.03, 0.55), eyeWhiteMat);
capBand.name = 'capBand';
capBand.position.set(0, 0.02, 0);
cap.add(capBand);
root.traverse((o) => {
if (o.isMesh) {
o.castShadow = true;
o.receiveShadow = true;
}
});
return root;
}
export default createBlockyCharacter;
Ratings & comments
0 comments
No comments yet. Share how you used this model or what could be better.
Related models
Same category or similar tags









