레슨 2 / 3·20분
컴포넌트와 엔티티
ECS(Entity-Component-System) 아키텍처
A-Frame은 ECS 아키텍처를 기반으로 합니다. Entity(
html
<!-- a-entity + 컴포넌트 조합 — a-box와 동일한 결과 -->
<a-entity
geometry="primitive: box; width: 1; height: 1; depth: 1"
material="color: #e74c3c; metalness: 0.5; roughness: 0.3"
position="0 1 -3"
rotation="0 45 0"
></a-entity>
<!-- 구 + 커스텀 재질 -->
<a-entity
geometry="primitive: sphere; radius: 0.8; segmentsWidth: 64"
material="color: #3498db; shader: standard; metalness: 0.8"
position="-2 1 -4"
></a-entity>
<!-- 조명 컴포넌트 -->
<a-entity
light="type: directional; color: #ffffff; intensity: 0.8"
position="1 4 2"
></a-entity>
<a-entity
light="type: point; color: #ff6600; intensity: 1; distance: 10"
position="0 3 -3"
></a-entity>
<a-entity
light="type: ambient; color: #404060; intensity: 0.4"
></a-entity>카메라, 커서, 커스텀 컴포넌트
html
<!-- 카메라와 커서 설정 -->
<a-entity
camera
look-controls
wasd-controls="acceleration: 30"
position="0 1.6 0"
>
<!-- 시선 커서 (VR에서 응시로 선택) -->
<a-entity
cursor="fuse: true; fuseTimeout: 1500"
position="0 0 -1"
geometry="primitive: ring; radiusInner: 0.015; radiusOuter: 0.025"
material="color: white; shader: flat"
></a-entity>
</a-entity>javascript
// ── 커스텀 컴포넌트 등록 ──
AFRAME.registerComponent('color-change', {
// schema — 컴포넌트의 속성(파라미터) 정의
schema: {
baseColor: { type: 'color', default: '#3498db' },
hoverColor: { type: 'color', default: '#e74c3c' },
},
// init — 컴포넌트 초기화 시 1회 실행
init: function () {
const el = this.el;
const data = this.data;
el.setAttribute('material', 'color', data.baseColor);
el.addEventListener('mouseenter', () => {
el.setAttribute('material', 'color', data.hoverColor);
});
el.addEventListener('mouseleave', () => {
el.setAttribute('material', 'color', data.baseColor);
});
},
// tick — 매 프레임 실행 (선택사항)
tick: function (time, deltaTime) {
// 매 프레임 실행할 로직
},
// remove — 컴포넌트 제거 시 정리
remove: function () {
// 이벤트 리스너 정리 등
},
});
// HTML에서 사용:
// <a-box color-change="baseColor: #2ecc71; hoverColor: #f39c12"></a-box>- •
— 빈 엔티티, 컴포넌트를 붙여 기능 부여 - •geometry 컴포넌트 — 형태 정의 (primitive, width, height 등)
- •material 컴포넌트 — 외형 정의 (color, metalness, roughness)
- •light 컴포넌트 — 조명 (directional, point, ambient, spot)
- •camera + look-controls + wasd-controls — 1인칭 카메라
- •cursor — 마우스/시선 기반 선택 (fuse: VR 응시 선택)
- •AFRAME.registerComponent — 커스텀 동작을 정의하는 핵심 API
💡
AFRAME.registerComponent의 schema에서 타입을 정의하면 HTML 속성 문자열이 자동으로 파싱됩니다. type: "vec3"이면 "1 2 3" 문자열이 {x:1, y:2, z:3} 객체로 변환됩니다. schema 없이도 컴포넌트를 만들 수 있지만, schema를 정의하면 재사용성과 가독성이 높아집니다.