Módulo 9 · Aula 9.3 · CharacterBody3D: andar no chão em 3D
| Carga horária | Dificuldade | Ferramenta | Competências |
|---|---|---|---|
| 10 h/a | ⭐⭐⭐ | Godot 4.7 | C1, C2 |
Objetivos de aprendizagem
- Montar um personagem 3D com
CharacterBody3D,CollisionShape3De formas prontas. - Fazer o personagem cair com gravidade e parar no chão.
- Programar o controle "de tanque": girar com esquerda e direita, andar com frente e trás.
- Explicar por que a frente de um nó 3D é o Z negativo.
Pré-requisitos
Aulas 9.1 e 9.2; Aula 8.3 (Mapa de Entrada e move_and_slide).
Materiais
Godot 4.7; projeto chave-da-porteira (cenas/jogador.tscn, scripts/jogador.gd).
Conceitos
O mesmo trio do Módulo 8. Corpo que anda e bate (CharacterBody3D), forma de colisão (CollisionShape3D) e desenho (MeshInstance3D). A colisão do sertanejo é uma cápsula de 1,6 m de altura e 0,35 m de raio; o desenho é feito de cinco formas.
Chão de verdade. No 2D de cima (Sementes), não havia chão. No 3D, o personagem cai se não tiver onde pisar. O chão do labirinto é um StaticBody3D com uma caixa de colisão; o plano de areia é só o desenho.
Gravidade. O Godot guarda a gravidade nas configurações do projeto (9,8 m/s²). O script lê esse valor e, enquanto o personagem não está no chão (is_on_floor()), aumenta a velocidade para baixo a cada quadro.
Controle de tanque. Duas formas comuns de andar em 3D:
| Jeito | Esquerda e direita | Usado em |
|---|---|---|
| tanque | giram o corpo | Chave da Porteira (mais fácil de programar e de jogar no teclado) |
| relativo à câmera | andam para o lado da tela | jogos com câmera girada pelo mouse |
Para onde é a frente? Todo nó 3D tem três setas próprias, guardadas em transform.basis: basis.x (direita dele), basis.y (cima dele) e basis.z (costas dele). A frente é o contrário das costas: -transform.basis.z. Quando o personagem gira, essas setas giram junto.
Ângulo em radianos. O Godot gira em radianos: uma volta inteira é TAU (cerca de 6,28). GIRO := 2.5 quer dizer 2,5 radianos por segundo, cerca de 143 graus.
Exemplos
| Comando | Efeito |
|---|---|
rotate_y(1.0) | gira 1 radiano (cerca de 57°) em volta do eixo Y |
-transform.basis.z | seta que aponta para a frente do personagem |
Input.get_axis("tras", "frente") | -1, 0 ou 1 (ou meio-termo com controle) |
is_on_floor() | verdadeiro quando está pisando em algo |
Tutorial passo a passo
Parte A. Ler o jogador pronto (60 min)
- Abra
cenas/jogador.tscn. Na aba Cena:Jogador(CharacterBody3D),Colisao,Corpo,Cabeca,Nariz,Aba,CopaeBracocomCamera(Aula 9.4). - Selecione
Colisao: a cápsula aparece como um contorno. Ela é maior que o corpo azul porque cobre também a cabeça. - Note o
Nariz: está em Z negativo (-0,27). É ele que mostra para onde o sertanejo olha. - O nó raiz está no grupo
jogador(aba Grupos). A chave, a porteira e a saída usam isso.
Parte B. Mapa de Entrada (40 min)
- Projeto → Configurações do Projeto... → aba Mapa de Entrada: ações
frente,tras,esquerda,direita(setas e W A S D) ecomecar(Espaço e Enter). É igual à Aula 8.3.
Parte C. Fazer o seu personagem (200 min)
- Cena nova com raiz
CharacterBody3D(Jogador). Filhos:CollisionShape3DcomShape→ New CapsuleShape3D, e pelo menos três formas de desenho. Uma delas deve mostrar a frente (em Z negativo). - Anexe um script e escreva o
jogador.gdabaixo, linha por linha, explicando para a dupla. - Numa cena de teste, ponha um chão (
StaticBody3DcomCollisionShape3Dde caixa larga e umMeshInstance3DcomPlaneMesh), um sol, uma câmera alta olhando para baixo e o seu jogador. Execute.
Parte D. Testar (100 min)
- Comece o jogador a 3 m de altura (
Position.y = 3). Ele cai e para no chão? - Segure a seta para cima: ele anda para onde o nariz aponta? Gire e ande de novo.
- Mude
VELOCIDADEeGIRO. Anote no diário qual combinação ficou mais gostosa de jogar.
Imagens
../../../recursos/imagens/godot/captura-godot3d-jogador.png
: a cena do jogador no editor, com a árvore de nós.../../../recursos/imagens/godot/captura-godot3d-script-jogador.png
: o script do jogador no editor.
Indicação da interface
| Item | Nome na tela |
|---|---|
| criar a cápsula de colisão | no Inspetor, Shape → New CapsuleShape3D |
| grupo | aba Grupos, ao lado de Inspetor e Sinais |
| ações | Projeto → Configurações do Projeto... → Mapa de Entrada |
| executar só esta cena | Executar Cena Atual |
O texto New CapsuleShape3D segue o mesmo padrão de New StandardMaterial3D (em inglês); não foi fotografado.
O código completo
scripts/jogador.gd:
extends CharacterBody3D
## Sertanejo do labirinto. Controle "de tanque": esquerda e direita giram o corpo,
## frente e trás andam para onde ele está olhando. A câmera vai presa atrás dele.
const VELOCIDADE := 4.0 # metros por segundo
const GIRO := 2.5 # radianos por segundo (cerca de 143 graus)
var gravidade: float = ProjectSettings.get_setting("physics/3d/default_gravity")
var tem_chave := false
@onready var braco: SpringArm3D = $Braco
func _ready() -> void:
# Sem esta linha, o braço da câmera "bate" no próprio corpo do jogador e encolhe.
braco.add_excluded_object(get_rid())
func _physics_process(delta: float) -> void:
var giro := Input.get_axis("direita", "esquerda")
rotate_y(giro * GIRO * delta)
var andar := Input.get_axis("tras", "frente")
# No Godot, a "frente" de um nó 3D é o eixo Z negativo.
var frente := -transform.basis.z
velocity.x = frente.x * andar * VELOCIDADE
velocity.z = frente.z * andar * VELOCIDADE
if not is_on_floor():
velocity.y -= gravidade * delta
move_and_slide()Explicação do código
get_axis("direita", "esquerda"): esquerda dá +1 e gira no sentido anti-horário visto de cima (é o sentido positivo do eixo Y).velocity.xevelocity.zvêm da seta da frente vezes o quanto apertou vezes a velocidade. Ovelocity.yfica por conta da gravidade.move_and_slide()move e escorrega nas paredes, igual ao 2D.tem_chavee obracosão usados nas Aulas 9.4 e 9.6.
O teste automático mediu: em 0,5 s segurando a frente, o sertanejo anda cerca de 2 m (4 m/s); em 0,4 s segurando a esquerda, gira cerca de 1 radiano (2,5 rad/s).
Resultado esperado
Personagem próprio que cai, para no chão, gira e anda para onde olha.
Problemas comuns
| Sintoma | Causa | Solução |
|---|---|---|
| cai para sempre | chão sem CollisionShape3D, ou só o desenho | pôr colisão no chão |
| anda de costas | nariz em Z positivo, ou usou transform.basis.z sem o sinal de menos | frente é -transform.basis.z |
| gira ao contrário | trocou a ordem em get_axis | get_axis("direita", "esquerda") |
| atravessa a parede | parede sem colisão, ou mexeu em position em vez de velocity | usar velocity e move_and_slide() |
| desliza para longe depois de soltar | velocity não volta a zero | calcular velocity.x e .z a cada quadro, como no código |
Exercício guiado
Se o personagem está virado 90° para a esquerda e você aperta "frente", para qual eixo ele anda? (Resposta: para o X negativo. A seta da frente girou junto com ele: era -Z e virou -X.)
Desafio individual
Faça o personagem correr com Shift: crie a ação correr e use o dobro da velocidade enquanto ela estiver apertada.
Desafio avançado (opcional)
Adicione pulo: ação pular (Espaço) e velocity.y = 5.0 só quando is_on_floor(). Cuidado: no Chave da Porteira o Espaço também começa a partida na tela de início.
Critérios de avaliação
- Personagem com colisão e frente visível.
- Gravidade e chão funcionando.
- Explica
-transform.basis.z.
Checklist de conclusão
Extensão
Jogue de olhos na tela e mão no teclado por 2 minutos e conte quantas vezes bateu na parede. Mude o GIRO e conte de novo.