스킬 트리

Skill Tree

노드를 선으로 연결해 어떤 능력을 배우려면 무엇을 먼저 배워야 하는지 나뭇가지 구조로 보여주는 성장 화면.

다른 이름: 탤런트 트리Talent tree성장 트리
···
html
<svg class="stsvg" id="svg" viewBox="0 0 300 180" preserveAspectRatio="none"><line x1="150" y1="150" x2="90" y2="100" class="stline" id="l1"/><line x1="150" y1="150" x2="210" y2="100" class="stline" id="l2"/><line x1="90" y1="100" x2="60" y2="45" class="stline" id="l3"/><line x1="90" y1="100" x2="120" y2="45" class="stline" id="l4"/><line x1="210" y1="100" x2="240" y2="45" class="stline" id="l5"/></svg>
<div class="stnode locked" id="n0" style="left:50%;top:83.3%">R</div>
<div class="stnode locked" id="n1" style="left:30%;top:55.6%">A</div>
<div class="stnode locked" id="n2" style="left:70%;top:55.6%">B</div>
<div class="stnode locked" id="n3" style="left:20%;top:25%">C</div>
<div class="stnode locked" id="n4" style="left:40%;top:25%">D</div>
<div class="stnode locked" id="n5" style="left:80%;top:25%">E</div>
css
.stsvg{position:absolute;inset:0;width:100%;height:100%}
.stline{stroke:var(--line);stroke-width:2;transition:stroke .4s}
.stline.on{stroke:var(--accent)}
.stnode{position:absolute;width:clamp(20px,8vmin,32px);height:clamp(20px,8vmin,32px);margin:-16px 0 0 -16px;border-radius:50%;
  display:grid;place-items:center;font:800 clamp(9px,3vmin,12px) monospace;color:var(--muted);
  background:var(--surface);border:2px solid var(--line);transition:all .35s cubic-bezier(.3,1.4,.4,1)}
.stnode.ready{border-color:var(--accent);color:var(--accent);box-shadow:0 0 0 4px color-mix(in srgb,var(--accent) 18%,transparent)}
.stnode.unlocked{background:var(--accent);border-color:var(--accent);color:#fff;transform:scale(1.08)}
js
const order=[['n0',null],['n1','l1'],['n2','l2'],['n3','l3'],['n4','l4'],['n5','l5']];
const nodes=order.map(function(o){ return document.getElementById(o[0]); });
function setReady(i){
  if(i<nodes.length) nodes[i].classList.add('ready');
}
setReady(0);
let i=0;
function unlockNext(){
  const [nid,lid]=order[i];
  const node=document.getElementById(nid);
  node.classList.remove('ready');
  node.classList.add('unlocked');
  if(lid) document.getElementById(lid).classList.add('on');
  i++;
  if(i<order.length) setReady(i);
  if(i>=order.length){
    setTimeout(function(){
      order.forEach(function(o){
        document.getElementById(o[0]).classList.remove('unlocked');
        if(o[1]) document.getElementById(o[1]).classList.remove('on');
      });
      i=0; setReady(0);
      setTimeout(unlockNext, 800);
    }, 1200);
  } else {
    setTimeout(unlockNext, 750);
  }
}
setTimeout(unlockNext, 600);

스킬 트리는 노드(능력)와 그 사이를 잇는 선(선행 조건)으로 이뤄진 그래프다. 잠긴 노드는 어둡게, 해금된 노드는 밝게, 지금 바로 배울 수 있는(선행 조건이 충족된) 노드는 테두리나 글로우로 한 번 더 강조하는 3단계 상태가 흔하다 — 이 구분이 없으면 플레이어는 클릭해보기 전까진 뭘 배울 수 있는지 알 수 없다.

선을 그릴 때는 SVG line이나 CSS로 각도·길이를 계산한 div를 쓴다. 노드를 해금하면 그 노드로 들어오는 선이 잠깐 빛을 따라 흐르는 애니메이션을 주면 "능력이 흘러들어온다"는 인과관계가 시각적으로 이어진다.

트리가 커지면 화면 하나에 다 담기 어려워서 확대/축소나 스크롤이 필요해지는데, 그러면 지금 어디를 보고 있는지 길을 잃기 쉽다. 카테고리별로 구역을 나누고 색을 다르게 주는 것이 방향 감각을 지키는 흔한 방법이다.

언제 쓰나

RPG 캐릭터 성장, 연구 트리, 업그레이드 시스템처럼 선택에 선후관계가 있는 진행 화면.