
스파이더맨처럼 느껴지는 밧줄: 그래플링 훅 물리학 기획
그래플링 훅의 핵심은 플레이어를 훅으로 곧장 끌어당기는 것이 아니라 밧줄 길이 제약 아래에서 접선 방향 속도를 유지하게 만드는 데 있다. 구현 가능한 물리 모델과 Unity 기준 코드 구조를 정리한다.
먼저 정할 것: 이 기능이 주는 감각
스파이더맨 같은 이동감은 ‘강한 당김’보다 원호 운동과 속도 보존에서 나온다. 플레이어가 훅 지점 아래로 떨어질 때는 속도가 점점 옆으로 전환되고 가장 낮은 지점을 지나면 기존 운동량으로 앞으로 튀어나가야 한다.
따라서 밧줄은 스프링처럼 계속 플레이어를 끌어당기기보다 최대 길이를 넘지 못하게 하는 제약 조건으로 다루는 편이 자연스럽다. 필요할 때만 약한 당김과 길이 감기를 더한다.

최소 물리 모델
훅 지점을 , 플레이어 위치를 라고 하자. 훅에서 플레이어로 향하는 벡터와 현재 밧줄 길이는 다음과 같다.
밧줄의 기준 길이를 로 두고 일 때만 제약을 적용한다. 이때 바깥쪽으로 벗어나려는 속도 성분을 없애면 플레이어는 훅을 중심으로 한 원호를 따라 움직인다.
정규화한 밧줄 방향을 , 플레이어 속도를 라고 하면 방사 방향 속도는 다음과 같다.
플레이어가 훅에서 멀어지는 경우에만 이 성분을 제거한다.
이 처리가 중요한 이유는 속도의 접선 성분을 남겨 두기 때문이다. 접선 성분이 곧 스윙의 진행 방향과 체감 속도를 만든다.
권장 처리 순서
FixedUpdate에서 훅 상태를 갱신한다. 위치 보정만 하고 속도를 그대로 두면 다음 물리 프레임에 다시 밧줄을 뚫고 나가며 진동하기 쉽다. 위치와 속도를 함께 다뤄야 한다.
flowchart TD
A[훅 발사] --> B{유효한 표면에 명중?}
B -- 아니오 --> A
B -- 예 --> C[훅 지점과 초기 밧줄 길이 저장]
C --> D[중력 및 공중 조작 적용]
D --> E{현재 거리가 밧줄 길이 초과?}
E -- 아니오 --> F[길이 감기와 입력 가속 처리]
E -- 예 --> G[위치를 원 위로 보정]
G --> H[바깥쪽 방사 속도 제거]
H --> F
F --> I{훅 해제?}
I -- 아니오 --> D
I -- 예 --> J[현재 접선 속도를 유지하며 비행]
훅 시작 시점의 속도를 즉시 지우지 않는 것도 중요하다. 달리거나 낙하하며 얻은 속도가 스윙으로 이어져야 연결감이 생긴다.
Unity Rigidbody 예제
아래 코드는 3D Rigidbody 기반의 가장 작은 형태다. 충돌 반응과 캐릭터 이동 방식에 따라 힘의 크기와 위치 보정 비율은 조정해야 한다.
using UnityEngine;
public class GrappleSwing : MonoBehaviour
{
[SerializeField] private Rigidbody body;
[SerializeField] private float reelSpeed = 8f;
[SerializeField] private float minRopeLength = 3f;
[SerializeField] private float airSteerAcceleration = 18f;
[SerializeField] private float outwardDamping = 0.02f;
private bool grappling;
private Vector3 hookPoint;
private float ropeLength;
public void BeginGrapple(Vector3 point)
{
hookPoint = point;
ropeLength = Vector3.Distance(body.position, hookPoint);
grappling = true;
}
public void EndGrapple()
{
grappling = false;
}
private void FixedUpdate()
{
if (!grappling) return;
Vector3 toPlayer = body.position - hookPoint;
float distance = toPlayer.magnitude;
if (distance < 0.001f) return;
Vector3 ropeDirection = toPlayer / distance;
// 플레이어 입력은 카메라 기준으로 계산했다고 가정한다.
Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0f,
Input.GetAxisRaw("Vertical"));
body.AddForce(input.normalized * airSteerAcceleration,
ForceMode.Acceleration);
// 버튼을 누르는 동안 밧줄을 감는다.
if (Input.GetKey(KeyCode.LeftShift))
{
ropeLength = Mathf.Max(minRopeLength,
ropeLength - reelSpeed * Time.fixedDeltaTime);
}
if (distance <= ropeLength) return;
// 밧줄 바깥으로 나온 위치를 원 위로 되돌린다.
body.position = hookPoint + ropeDirection * ropeLength;
float outwardSpeed = Vector3.Dot(body.linearVelocity, ropeDirection);
if (outwardSpeed > 0f)
{
// 접선 속도는 보존하고 바깥쪽 성분만 제거한다.
body.linearVelocity -= ropeDirection * outwardSpeed;
}
// 수치 오차 때문에 생기는 미세한 재이탈을 줄인다.
body.linearVelocity -= ropeDirection * outwardDamping;
}
}
Unity 버전에 따라 Rigidbody.velocity를 사용해야 하는 프로젝트도 있다. 사용하는 Unity 버전의 Rigidbody API에 맞춰 linearVelocity 부분만 바꾸면 된다.
당김은 보조 장치로만 쓴다
스윙이 너무 느리거나 훅을 건 직후 진행 방향이 모호할 때는 훅 방향으로 가속을 더할 수 있다. 다만 이 힘을 상시로 강하게 적용하면 원호 이동이 사라지고 단순한 끌려가기처럼 느껴진다.
거리에 따라 당김을 키우려면 초과 길이 를 사용한다.
여기서 는 당기는 강도이고 는 방사 방향 진동을 줄이는 감쇠 계수다. 이 모델은 탄성 밧줄에 가깝다. 스파이더맨식 스윙을 목표로 한다면 위의 위치 제약을 기본으로 두고 이 힘은 짧은 보정이나 튜토리얼 난이도 완화에만 사용하자.
조작감에 큰 영향을 주는 네 가지 값
밧줄 감기 속도
감기 속도가 너무 빠르면 플레이어가 훅 지점으로 급격히 빨려 들어가고 너무 느리면 고도 조절 수단이 사라진다. 최대 속도와 별개로 초당 줄어드는 길이를 제한하면 튜닝이 안정적이다.
공중 조작 가속도
입력은 즉시 속도를 바꾸기보다 가속도로 적용하는 편이 좋다. 특히 카메라 진행 방향으로 접선 가속을 주면 플레이어가 궤적을 능동적으로 다듬는 느낌을 낸다. 반대로 밧줄 방향으로 향하는 입력은 제한해야 원호가 무너지지 않는다.
훅 해제 시 속도
해제 순간에는 현재 속도를 보존한다. 속도를 임의로 줄이면 축적한 추진력이 사라지고 반대로 추가 가속을 과도하게 주면 매번 훅을 끊는 것이 최적 전략이 된다. 필요하다면 해제 보너스는 접선 방향에 작은 상한값으로만 적용한다.
최대 장력과 안전장치
아주 긴 밧줄, 빠른 낙하, 좁은 지형이 겹치면 큰 위치 보정이 발생한다. 프레임당 보정 거리와 최대 속도를 제한하고 훅 지점과 플레이어 사이에 장애물이 생겼을 때 해제하거나 밧줄을 재검사하는 규칙을 둔다. 멀티플레이어라면 훅 지점, 밧줄 길이, 해제 시점은 서버 권한으로 검증하는 편이 안전하다.
자주 생기는 문제와 해결 방향
- 밧줄이 팽팽해질 때 튄다: 위치 보정만 하지 말고 바깥쪽 방사 속도도 제거한다.
- 스윙이 계속 느려진다: 전체 속도를 감쇠하지 않았는지 확인한다. 감쇠는 방사 방향 성분에만 적용한다.
- 원의 바깥으로 새어 나간다:
Update가 아니라 물리 스텝에서 처리하고 충돌 처리 뒤에도 제약을 한 번 더 적용하는 방식을 검토한다. - 공중 조작이 너무 강하다: 입력 가속을 접선 평면에 투영하거나 최대 접선 속도를 둔다.
- 훅 걸기가 답답하다: 명중 판정 반경과 허용 표면을 조금 넓히되 카메라 중앙 근처를 우선하는 보정을 넣는다.
마무리
그래플링 훅의 핵심은 ‘밧줄 길이를 넘지 못하게 하고 접선 속도를 살려 둔다’는 한 문장으로 정리할 수 있다. 여기에 제한적인 줄 감기, 읽기 쉬운 훅 판정, 해제 시 운동량 보존을 더하면 단순한 이동 기술을 넘어 스윙 자체를 익히는 재미를 만들 수 있다.
처음에는 단일 훅 지점과 고정 길이만 구현한 뒤 충돌 처리와 카메라 조작을 안정화하자. 두 개의 훅, 이동하는 앵커, 밧줄의 시각적 처짐은 그 기반이 흔들리지 않을 때 추가하는 편이 디버깅 비용이 훨씬 낮다.


