heliofilho.devNewsletter
Cofre/Vídeos
Vídeo · 16 de out. de 2026

Como fazer a corda de The Last of Us Part II no seu jogo

A palestra da Naughty Dog sobre a corda de 14 metros e como fazer uma no seu jogo: Position Based Dynamics explicado com analogias, código em JavaScript que roda no navegador, a corda esticada que dobra nas quinas e projetos prontos em Unity, Godot e Unreal.

Você veio do vídeo da corda de The Last of Us Part II e aqui está a versão completa. Primeiro, a palestra da Naughty Dog e o que ela cobre. Depois, como fazer uma corda dessas no seu jogo: a física sem matemática pesada, um código curto que roda no navegador e a ideia da corda esticada que dobra nas quinas. No fim tem projetos prontos em Unity, Godot e Unreal, o bastidor, vídeos e um glossário.

Resumo pra quem tem pressa

A corda do jogo funciona em dois modos. Quando está frouxa, ela é uma fileira de pontinhos que a física move a cada quadro. Quando estica, esse jeito começa a falhar, e o jogo passa a desenhar a corda como linhas retas que só dobram nas quinas dos objetos.

ParteO que fazOnde aprender
A palestraConta a história da corda do Uncharted 4 ao TLOU2 e explica os dois modosGDC Vault
Corda frouxa (PBD)Gravidade empurra cada ponto, depois o jogo corrige as posições para manter a distância entre vizinhos e tirar quem entrou na paredeArtigo original de PBD e o Ten Minute Physics
VerletO mesmo espírito, com a velocidade guardada na diferença entre a posição atual e a anteriorAdvanced Character Physics
Corda esticadaUma linha que vai reta e só dobra onde encosta numa quinaTutorial de gancho com pontos de dobra
Pronto pra usarCorda já feita para testar no seu motorObi Rope, Verlet Rope 4, Cable Component

A palestra da Naughty Dog

O nome é "Rope Simulation in 'Uncharted 4' and 'The Last of Us 2'". Quem apresenta é Jaroslav Sinecky, da Naughty Dog, na GDC de 2021, na trilha de programação. A página fica no GDC Vault.

O resumo oficial conta três coisas:

  1. Uncharted 4: a equipe precisou criar uma tecnologia nova de corda para o gancho do Drake e o guincho do jipe. A corda tinha que dobrar e enrolar nos objetos do cenário.
  2. The Last of Us Part II: a mesma tecnologia foi além para os puzzles de corda. O jogador joga 14 metros de corda no cenário e pega de volta em qualquer ponto.
  3. O conteúdo técnico: a palestra passa pela história do desenvolvimento e pelos maiores problemas no caminho. Depois explica a simulação de corpo mole (a corda frouxa) e a técnica usada para resolver a corda esticada enrolando nos objetos.

Como assistir: a palestra completa em vídeo é para assinantes do GDC Vault. Se o player não abrir para você, esta página cobre as ideias principais. Nos slides, um dos títulos é "Rope PBD", na parte de colisão, e outro é "Taut rope simulation" (simulação da corda esticada). Esses dois nomes guiam as duas metades desta página.

Por que uma corda é tão difícil

Parece só uma linha. O problema é tudo que o jogador faz com ela.

  • Ela é comprida: 14 metros, com muita coisa no caminho.
  • Ela cai, dobra, enrola em poste e desliza pelas superfícies. Cada pedacinho precisa respeitar o cenário.
  • Você pega em qualquer ponto. Não existe uma "ponta certa" para segurar.
  • Tudo em tempo real, em poucos milissegundos por quadro, junto com o resto do jogo.

Uma animação pronta não resolve, porque quem decide onde a corda vai parar é o jogador. A corda precisa ser simulada, e na parte frouxa a Naughty Dog usou PBD.

Corda frouxa: Position Based Dynamics (PBD)

A ideia em uma frase

Em vez de calcular forças e esperar que elas levem os pontos ao lugar certo, você move os pontos e depois corrige as posições até as regras serem cumpridas.

Pensa num colar de contas. Você solta o colar, a gravidade puxa cada conta para baixo, e o fio impede que uma conta se afaste demais da vizinha. O PBD faz exatamente isso, em dois tempos: primeiro deixa cada conta cair livre, depois "puxa o fio" para colocar todo mundo de volta na distância certa.

O artigo que deu nome a isso é "Position Based Dynamics", de Matthias Müller, Bruno Heidelberger, Marcus Hennix e John Ratcliff, na época da AGEIA. Ele foi apresentado em 2006 no workshop VRIPHYS, da Eurographics, e saiu em versão de revista em 2007 no Journal of Visual Communication and Image Representation. O resumo diz o que mudou: em vez de passar por forças e velocidades, o método trabalha direto nas posições, o que dá mais controle, evita que a simulação "passe do ponto" e deixa a colisão simples, porque basta empurrar o ponto para um lugar válido.

O laço de cada quadro

O passo de tempo do artigo, em português claro:

  1. Aplique as forças de fora. A gravidade muda a velocidade de cada ponto. Aqui também entra um pouco de amortecimento.
  2. Preveja a posição nova. Cada ponto anda na direção da velocidade dele. Essa é só uma previsão.
  3. Descubra as colisões. Para cada ponto que vai entrar num objeto, crie uma regra: "fique do lado de fora".
  4. Corrija várias vezes. Passe por todas as regras (distância entre vizinhos e colisões) e ajuste as posições previstas. Repita algumas vezes.
  5. Atualize a velocidade. A velocidade nova é o quanto o ponto andou, dividido pelo tempo. A posição prevista vira a posição oficial.

O truque está no passo 5. Como a velocidade sai da posição corrigida, ela já nasce coerente com as regras. Isso deixa a simulação bem estável.

A restrição de distância

A regra principal de uma corda é: cada ponto fica a uma distância fixa do vizinho.

Se dois pontos estão mais longe do que deviam, o jogo puxa os dois um na direção do outro. Se estão perto demais, empurra. Quanto cada um anda depende do peso: o ponto pesado anda pouco e o leve anda muito. Um ponto preso (na mão do personagem, por exemplo) tem "peso infinito" e não anda nada.

No artigo, o peso entra como massa inversa (w = 1 / massa). Um ponto preso tem w = 0. A correção de cada ponto é a fração w_dele / (w1 + w2) do erro, na direção da linha que liga os dois. Com dois pontos de mesmo peso, cada um anda metade do erro. É só isso que o código mais abaixo faz.

Iterações: por que repetir deixa a corda mais dura

Corrigir um par de pontos desarruma o par do lado. Por isso o jogo passa pela corda inteira várias vezes por quadro. Cada passada é uma iteração.

O artigo explica a consequência: quanto mais iterações, mais dura a corda fica. Com poucas, ela estica como elástico. Com muitas, ela se comporta como corda de verdade, mas custa mais processamento.

Pensa numa fila de pessoas de mãos dadas. A da ponta dá um passo, a vizinha acompanha, depois a próxima. Com pouco tempo, a correção não chega ao fim da fila. Numa corda com dezenas de pontos, é isso que acontece.

Dica: em vez de aumentar só as iterações, divida o quadro em passos menores (substeps). O artigo "Small Steps in Physics Simulation" (Macklin e outros, 2019) mostra que vários passos pequenos com uma iteração cada resolvem melhor do que um passo grande com muitas iterações. O projeto de Unity que aparece mais abaixo faz isso.

Colisão: empurra pra fora

Se um ponto entrou no poste, você coloca o ponto de volta na superfície. O artigo faz isso testando o caminho entre a posição antiga e a prevista: se esse trecho entra num objeto, nasce uma regra que mantém o ponto do lado de fora. Se o ponto já está todo dentro, ele é levado para o ponto mais perto da superfície.

Como a velocidade é calculada depois, a corda perde a velocidade que tinha "para dentro" da parede sem você escrever nenhuma conta de quique.

E o Verlet?

Você vai ver muito tutorial chamado "verlet rope". É a mesma família de ideias, um pouco mais antiga. Thomas Jakobsen, chefe de pesquisa da IO Interactive, descreveu no artigo Advanced Character Physics, publicado no Gamasutra em 2003, o sistema usado em Hitman: Codename 47 para pano, plantas e corpos caindo.

A diferença está em onde mora a velocidade:

  • Verlet: cada ponto guarda a posição atual e a anterior. A velocidade é a diferença entre as duas. Não existe variável de velocidade.
  • PBD: cada ponto guarda posição e velocidade, e a velocidade é recalculada no fim do passo.

O resto é igual: prever, corrigir a distância entre vizinhos várias vezes e empurrar para fora de quem colidiu. O próprio artigo de PBD diz que a projeção de distância de Jakobsen é um caso especial do método deles. Jakobsen deixa uma frase que resume a filosofia dos jogos: o que importa é parecer convincente, e o programador pode trapacear o quanto quiser se o jogador continua imerso.

Mão na massa: uma corda PBD em JavaScript

O código abaixo é uma corda em 2D com 30 pontos, presa numa ponta, caindo sobre um poste redondo. Ele usa o estilo Verlet (posição atual e anterior) para a inércia e o PBD para as correções. O código foi testado: depois de 5 segundos simulados, a corda fica apoiada no poste, nenhum ponto fica dentro dele e a maior diferença de distância entre vizinhos fica abaixo de 0,3 pixel.

// Corda PBD simples em 2D (y cresce para baixo, como no canvas)
const N = 30;            // quantos pontinhos
const SEG = 10;          // distância entre vizinhos (pixels)
const GRAVIDADE = 980;   // pixels por segundo ao quadrado
const ITERACOES = 20;    // quantas vezes corrigir por quadro

const pontos = [];
for (let i = 0; i < N; i++) {
  pontos.push({ x: 200 + i * SEG, y: 100, px: 200 + i * SEG, py: 100, w: 1 });
}
pontos[0].w = 0; // w = 1/massa. Zero = preso na mão (não se mexe)

const poste = { x: 300, y: 260, r: 40 }; // obstáculo redondo

function passo(dt) {
  // 1) prever: inércia + gravidade
  for (const p of pontos) {
    if (p.w === 0) continue;
    const vx = (p.x - p.px) * 0.99; // 0.99 = amortecimento leve
    const vy = (p.y - p.py) * 0.99;
    p.px = p.x; p.py = p.y;
    p.x += vx;
    p.y += vy + GRAVIDADE * dt * dt;
  }
  // 2) corrigir: várias passadas pelas restrições
  for (let k = 0; k < ITERACOES; k++) {
    // 2a) distância entre vizinhos
    for (let i = 0; i < N - 1; i++) {
      const a = pontos[i], b = pontos[i + 1];
      const dx = b.x - a.x, dy = b.y - a.y;
      const dist = Math.hypot(dx, dy);
      const somaW = a.w + b.w;
      if (dist === 0 || somaW === 0) continue;
      const erro = (dist - SEG) / dist / somaW;
      a.x += dx * erro * a.w; a.y += dy * erro * a.w;
      b.x -= dx * erro * b.w; b.y -= dy * erro * b.w;
    }
    // 2b) colisão: quem entrou no poste volta para a borda
    for (const p of pontos) {
      if (p.w === 0) continue;
      const dx = p.x - poste.x, dy = p.y - poste.y;
      const dist = Math.hypot(dx, dy);
      if (dist < poste.r && dist > 0) {
        p.x = poste.x + (dx / dist) * poste.r;
        p.y = poste.y + (dy / dist) * poste.r;
      }
    }
  }
}

Para ver na tela, crie um arquivo HTML com <canvas width="600" height="500"></canvas>, cole o código acima num <script> e acrescente o desenho. A ponta presa segue o mouse:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
canvas.addEventListener('mousemove', (e) => {
  pontos[0].x = e.offsetX;
  pontos[0].y = e.offsetY;
});

function quadro() {
  passo(1 / 60);
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.arc(poste.x, poste.y, poste.r, 0, Math.PI * 2);
  ctx.fill();
  ctx.beginPath();
  ctx.moveTo(pontos[0].x, pontos[0].y);
  for (const p of pontos) ctx.lineTo(p.x, p.y);
  ctx.stroke();
  requestAnimationFrame(quadro);
}
quadro();

O que mexer para sentir a física:

  • ITERACOES em 2: a corda vira elástico. Em 50, fica bem mais firme.
  • 0.99 em 1: sem amortecimento, ela balança por muito mais tempo.
  • SEG menor e N maior: a corda fica mais lisa e mais cara de calcular.

Pegar em qualquer ponto

No PBD, pegar a corda em qualquer lugar é quase de graça. Para segurar o ponto 17, você faz pontos[17].w = 0 e coloca esse ponto na mão do personagem a cada quadro. A restrição de distância cuida do resto: os dois lados da corda passam a pender da mão. Para soltar, volte o w para 1. Essa é a forma padrão de prender pontos no PBD, não um detalhe confirmado da implementação da Naughty Dog.

O mesmo laço em C#, num projeto real

O repositório UnityVerletRope faz a versão 3D disso em Unity, em C#. O laço tem a mesma estrutura: substeps, Verlet, várias correções de distância e colisão com a cena usando esferas da física da Unity.

Corda Verlet do projeto UnityVerletRope colidindo com um cubo na Unity (GIF do repositório de alirezaft no GitHub)
Corda Verlet do projeto UnityVerletRope colidindo com um cubo na Unity (GIF do repositório de alirezaft no GitHub)

Corda esticada: o caminho pelas quinas

Por que o PBD sofre quando a corda estica

Com a corda frouxa, as regras quase não brigam. Quando o personagem estica a corda em volta de um poste, elas puxam em direções opostas: a distância entre vizinhos quer encurtar, a colisão empurra para fora e a mão continua puxando. Três coisas pioram o quadro:

  1. A correção demora a percorrer a corda. Como vimos nas iterações, a "notícia" de que a ponta foi puxada leva várias passadas para chegar ao outro lado. Em 14 metros de corda, isso aparece.
  2. Uma quina é um ponto só. A corda é feita de pontinhos separados. Entre dois pontinhos, o segmento reto pode cortar a quina, e os pontos ficam escorregando de um lado para o outro da aresta.
  3. Cada quadro recomeça a briga. O resultado é o que a legenda do vídeo descreve: os pontinhos tremem e escorregam pelas quinas.

Essa explicação é leitura minha, baseada no artigo de PBD. O resumo da palestra confirma que a corda esticada enrolando nos objetos pediu uma técnica própria.

A ideia da Naughty Dog, lida no slide

Pelo desenho do slide "Taut rope simulation", a corda esticada deixa de ser uma fileira de pontinhos soltos. O jogo traça uma linha reta que só dobra nas quinas dos objetos, que é o caminho mais curto em volta do obstáculo. Quando a corda volta a ficar frouxa, a simulação PBD assume de novo.

Um aviso: isso é o que dá para ler no desenho do slide. A explicação falada da palestra não foi ouvida para esta página, então os detalhes de como a Naughty Dog detecta as quinas e troca de modo ficam na palestra.

Pensa num elástico preso num prego e esticado em volta de uma caixa. Ele vai reto até uma quina, dobra e vai reto até a próxima. Quem decide a forma dele são as quinas que ele toca.

Uma versão simples, em 2D

Uma técnica comum em tutoriais de gancho é a dos pontos de dobra (wrap points). O tutorial Make a 2D Grappling Hook Game in Unity, de Sean Duffy (Kodeco, 2017), faz assim: lança um raio do jogador até o último ponto de apoio da corda. Se o raio bate num objeto, o jogo pega a quina do objeto mais perto do ponto de batida e ela vira um novo ponto de apoio. A parte 2 ensina a desenrolar, comparando de que lado da quina o jogador está.

Em pseudocódigo:

caminho = [ancora]          // pontos de dobra, da âncora até a mão

a cada quadro:
    ultimo = caminho[fim]
    se o raio de ultimo até a mão bate num objeto:
        quina = vértice do objeto mais perto da batida
        caminho.adicionar(quina)        // a corda dobrou aqui

    se caminho tem 2 pontos ou mais:
        penultimo = caminho[fim - 1]
        se a mão passou para o outro lado da última quina
           e o raio de penultimo até a mão está livre:
            caminho.remover_ultimo()    // a corda desenrolou

    comprimento_usado = soma dos trechos do caminho + trecho até a mão
    desenhe linhas retas entre os pontos do caminho

Com o comprimento_usado você limita até onde o personagem vai: se chegou ao tamanho da corda, ela está esticada e segura o personagem. É bem mais simples que um jogo 3D comercial, mas mostra a ideia central: na corda esticada, o que importa são as quinas, não os pontinhos.

Dica: se você já mexeu com navegação de personagens, vai reconhecer o padrão. Achar o caminho mais curto que só dobra em quinas é o mesmo problema do "string pulling" em navmesh. O texto Simple Stupid Funnel Algorithm, de Mikko Mononen, mostra um algoritmo curto para isso. A ligação com a corda é leitura minha, não algo dito na palestra.

Juntando os dois modos

Um jeito de organizar o seu código, inspirado na divisão da palestra:

  • Frouxa: simulação PBD com todos os pontos, colisão e gravidade.
  • Esticada: lista de pontos de dobra, linhas retas entre eles e o comprimento total limitando o personagem.
  • Troca: quando a soma dos trechos chega ao comprimento da corda, ela estica. Quando o personagem se aproxima e sobra corda, você distribui os pontinhos de novo ao longo do caminho e volta para o PBD.

As regras exatas de troca do TLOU2 não estão no resumo público. Isso é uma sugestão para o seu projeto.

Pronto pra testar no seu motor

Para ter a corda funcionando hoje e estudar depois:

ProjetoMotorComo funcionaPreço
Obi RopeUnityPartículas com restrições de distância e de dobra, na CPU e na GPU. A corda pode rasgar e mudar de tamanho (documentação)Asset Store da Unity
UnityVerletRopeUnityVerlet com substeps, iterações e colisãoGrátis, código aberto
Verlet Rope 4Godot 4.4 ou mais novo, versão .NETVerlet em C#, com vento, gravidade e colisãoGrátis, licença MIT
Cable ComponentUnreal EnginePartículas ligadas por restrições de distância, integradas com VerletPlugin oficial da Epic

Cable Component (Unreal)

A documentação do Cable Component descreve o modelo desta página: partículas ligadas por restrições de distância, pontas presas e as do meio caindo com a gravidade, integradas com Verlet. Duas opções importam:

  • Solver Iterations: a própria documentação diz que o número de iterações controla o quanto o cabo é duro. É a mesma ideia das iterações do PBD.
  • Enable Collision: faz cada partícula testar o cenário a cada substep. A documentação marca como experimental e avisa que aumenta muito o custo.

Bastidor: três meses numa corda

O jogo saiu em 19 de junho de 2020. No mesmo dia, o desenvolvedor Renji Nikaido postou um vídeo mostrando o quanto dava para enrolar e embaraçar os cabos no jogo, e o vídeo viralizou. Vários desenvolvedores elogiaram o trabalho.

Maksym Zhuravlov, animador técnico da Naughty Dog, contou o tamanho do trabalho. Segundo a Inverse (Danny Paez, 27 de junho de 2020), ele e dois colegas levaram cerca de três meses para criar o sistema de corda, e a equipe de testes (QA) testou até não poder mais antes do lançamento.

A GamePro alemã (22 de junho de 2020) completa o quadro: Kurt Margenau, codiretor do jogo, deu o crédito ao programador Jaroslav Sinecky, e o próprio Zhuravlov disse que Sinecky fez a maior parte do trabalho. Sinecky é justamente quem apresentou a palestra na GDC no ano seguinte.

Uma única mecânica levou meses de três pessoas, mais o time de testes. E ela não nasceu do zero: a base veio do gancho e do guincho do Uncharted 4.

Os erros mais comuns

  1. Poucas iterações numa corda comprida. Ela estica como chiclete. Aumente as iterações ou use substeps.
  2. Esquecer o amortecimento. Sem ele, a corda balança para sempre e parece leve demais.
  3. Pontos espaçados demais para o tamanho do obstáculo. A corda atravessa objetos finos e corta quinas. Ou diminua o espaço entre pontos, ou trate a colisão como uma linha entre vizinhos, não só como pontos.
  4. Passo de tempo variável. O artigo de PBD avisa que a rigidez depende do passo de tempo. Simule com passo fixo, mesmo que o jogo rode em taxas de quadro diferentes.
  5. Tentar resolver a corda esticada só com mais iterações. Uma hora o custo explode e a corda continua escorregando nas quinas. É o momento de pensar em pontos de dobra.

Vídeos

Matthias Müller, primeiro autor do artigo de PBD, simula um pêndulo triplo com restrições de distância no canal Ten Minute Physics. A mesma técnica serve para corda, cabelo e pano (em inglês):

06 - The simplest way to simulate a triple pendulum, Ten Minute Physics

O passo seguinte é o XPBD, versão do PBD em que a rigidez não depende do número de iterações (em inglês):

09 Getting ready to simulate the world with XPBD, Ten Minute Physics

Pra ir mais fundo

A palestra e o bastidor

A teoria

Tutoriais

Glossário rápido

TermoEm português claro
PBD (Position Based Dynamics)Simular movendo os pontos e depois corrigindo as posições até as regras serem cumpridas
VerletJeito de simular em que a velocidade é a diferença entre a posição atual e a anterior
RestriçãoUma regra que a simulação precisa cumprir, como "fique a 10 cm do vizinho"
Restrição de distânciaA regra que faz a corda ser corda: vizinhos sempre na mesma distância
IteraçãoUma passada corrigindo todas as regras. Mais passadas, corda mais dura
SubstepDividir um quadro em passos menores para a simulação ficar mais precisa
Massa inversa1 dividido pela massa. Zero quer dizer ponto preso, que não se mexe
Corda esticada (taut rope)A corda sob tensão, que vai reta e só dobra onde encosta
Ponto de dobra (wrap point)A quina onde a corda esticada muda de direção

Salve esta página para quando for fazer a sua primeira corda. Tem mais material assim no Cofre, e todo dia sai vídeo novo de tecnologia no @heliofilhou.