# 동작 원리

## 개요

액션시퀀스의 세부 기능을 설명하기에 앞서 액션시퀀스의 동작 원리를 먼저 설명합니다. 이를 통해 액션시퀀스 실행 시 내부적으로 어떤 방식으로 동작하는지 이해하고, 기능 사용 시 고려해야 할 기술적 특성을 함께 파악할 수 있습니다.

## 런타임 동작 방식

액션시퀀스는 **정적 데이터 기반**으로 정의된 객체로, 런타임에서 Instance.new 또는 Clone을 통해 직접 생성할 수 없습니다.

Play 메서드를 통해 실행이 요청되면, 원본 인스턴스는 **Humanoid.ActionRunner 하위로 복제**되며, 이후 복제된 인스턴스를 기반으로 액션이 실행됩니다.

<div align="left"><figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2FjkFwtcAe7rFeyiSlvKzK%2FActionSequencer-Runtime-Clone.png?alt=media&#x26;token=04580c7e-80b2-48c4-8dbd-17eae28fba87" alt="" width="343"><figcaption></figcaption></figure></div>

이와 같은 동작 구조로 인해, **액션시퀀스 내부 스크립트에서 이벤트를 연결**할 때는 원본 인스턴스가 아닌 런타임에 복제된 인스턴스를 기준으로 접근해야 합니다. 따라서 **절대 경로를 사용하는 대신 script.Parent를 기준으로 참조**해야 합니다.

```lua
local ActionSequence = script.Parent

ActionSequence:Hit("Hit"):Connect(function(self, other)
    local caster = self.Humanoid
    local target = other.Humanoid
    -- ...
end)
```

## 실행 흐름

```mermaid
flowchart TD
    A["Play 메서드 호출<br>(Client 또는 Server)"] --> B["서버에서 처리"]

    B --> C["시퀀스 실행 시작 (Server)"]

    C --> D1["Client 1"]
    C --> D2["Client 2"]
    C --> D3["Client 3"]

    D1 --> E1["연출 실행 (Client)"]
    D2 --> E2["연출 실행 (Client)"]
    D3 --> E3["연출 실행 (Client)"]
```

액션 실행 요청이 발생하면, 호출 위치(Client 또는 Server)에 관계없이 **서버에서 시퀀스 실행이 시작**됩니다. 이후 액션시퀀스 하위에 있는 **스크립트 이벤트가 연결**되고, 시퀀스와 자식 객체가 **모든 클라이언트로 복제**됩니다.

복제가 완료되면 **각 클라이언트에서 타임라인이 재생**되며, 애니메이션, 이펙트, 사운드 등의 연출이 실행됩니다.

즉, 액션시퀀스는 런타임에서 스크립트로 동적으로 생성하거나 직접 복제하는 구조가 아니라, **사전에 정의된 데이터를 기반으로 실행 시 복제**되어 연출을 수행하는 방식으로 동작합니다.

서버는 시퀀스 실행 시점을 기준으로 전체 진행 상태를 동기화하며, 클라이언트 간 발생할 수 있는 **시간 차이는 자동으로 보정**됩니다. 또한 게임 플레이의 일관성을 유지하기 위해 공격 **충돌 판정과 같은 핵심 로직은 서버에서 처리**됩니다.

## 생성 및 제거 흐름

```mermaid
flowchart TD
    A["액션 실행 요청"]
    B["스크립트 이벤트 연결"]
    C["액션시퀀스 복제<br>(서버 → 클라이언트)"]
    D["타임라인 실행<br>(애니메이션 / 사운드 등)"]
    E["연출 종료"]
    F["복제된 액션시퀀스 객체<br>제거"]

    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
```

액션시퀀스는 정의된 재생 길이까지 타임라인이 재생되며 연출이 진행됩니다. **연출이 종료되면** 실행을 위해 **복제된 액션시퀀스 객체는 자동으로 제거**되며, 액션시퀀스에 연결된 이벤트 또한 함께 정리됩니다.

### 재생 길이 관련 주의 사항

액션시퀀스 실행 시 생성되는 복제 객체의 생성 및 파괴 시점을 명확히 하기 위해, 액션이 종료된 경우 재생 길이도 함께 정리하는 것이 좋습니다. **재생 길이이 불필요하게 길 경우 객체 제거 시점**이 지연될 수 있습니다.

* 나쁜 예

  <figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2FnuyBUm3EcabXdpW8nSVX%2FActionSequencer-Timeline-GoodCase.png?alt=media&#x26;token=1eebc54a-ee42-4f8a-8812-de9d3c53026a" alt=""><figcaption></figcaption></figure>
* 좋은 예

  <figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2FPBN69fJ5NYgyFKIWAhVx%2FActionSequencer-Timeline-BadCase.png?alt=media&#x26;token=b306c806-6bbd-407a-9599-0a7ee968b35f" alt=""><figcaption></figcaption></figure>

재생 길이은 타임라인 상단의 **시작/종료 시간 필드**에 값을 입력하거나, 스크러버를 원하는 위치로 이동한 뒤 **종료 위치 설정 버튼**을 사용해 조정할 수 있습니다.

<figure><img src="https://2697870212-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FhRPi87oM9ttlk5nyu7L7%2Fuploads%2F2EG1TCnI1QLbucrrP6Pk%2FActionSequencer-Timeline-SetPlayRangeButton.png?alt=media&#x26;token=ca380bec-9dc0-4b4a-970c-e847f3a71785" alt=""><figcaption></figcaption></figure>
