# SimulationBall

SimulationBall : `PVInstance`

## Overview

시뮬레이션 볼은 게임 내에서 물리 엔진의 부정확한 동기화 문제를 해결하기 위해 설계된 Ball 오브젝트입니다. 기존의 피직스 기반 공은 각 클라이언트가 서버 레이턴시의 영향을 받아 서로 다른 위치에 공을 렌더링하는 문제가 있었지만, SimulationBall은 사전에 시뮬레이션된 궤적 데이터를 기반으로 모든 클라이언트가 동일한 위치, 속도, 회전을 공유하도록 합니다.

이 방식을 통해 다음과 같은 장점을 얻을 수 있습니다:

* 레이턴시 보정: 서버-클라이언트 간 지연 시간에 상관없이 동일한 공 움직임 유지
* 고성능 처리: 프레임 단위 물리 연산을 제거하여 성능 향상
* 예측 가능한 결과: 시뮬레이션된 결과를 기반으로 특정 시점의 위치, 속도, 회전을 쉽게 조회 가능
* 복잡한 물리 효과 구현: 마그누스 효과 등 회전에 따른 비선형 움직임 구현 가능

## Properties

### BallMeshCollisionProfile

`string`

시뮬레이션 볼의 메시 컴포넌트에 적용되는 콜리전 프로파일 이름을 지정합니다. 이 값을 설정하면 다른 오브젝트와의 충돌/오버랩 처리 방식이 결정됩니다. 기본값은 `"OverlapAll"`로, 다른 파트와 겹쳐도 물리적으로 차단되지 않고 오버랩 이벤트만 발생합니다. 게임 상황에 따라 `"BlockAll"` 등 다른 프로파일로 교체하여 충돌 응답을 조정할 수 있습니다.

> **참고:** 이 속성은 메시 컴포넌트의 실제 충돌/오버랩 동작에만 영향을 미치며, `Simulate` 호출로 수행되는 궤적 시뮬레이션 과정에는 관여하지 않습니다. 시뮬레이션 단계의 충돌 판정은 `BallTraceChannel`을 통해 수행됩니다.

#### Code Samples

### BallRadius

`number`

공의 반지름을 지정합니다. 시뮬레이션에서 사용되는 물리적 충돌 및 렌더링 크기를 결정하며, 실제 게임에서 공의 크기와 충돌 판정을 일치시키는 데 사용됩니다. 값이 클수록 공의 질량 및 공기 저항 계산에 영향을 줄 수 있습니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")
ball.BallRadius =50
```

### BallState

`Enum.BallState`

시뮬레이션 볼의 현재 상태를 나타냅니다. 다음과 같은 상태값을 가질 수 있습니다:

* `Simulated` (0): 시뮬레이션이 완료되어 재생 준비가 된 상태입니다.
* `Playing` (1): 시뮬레이션이 현재 재생 중인 상태입니다.
* `Stopped` (2): 시뮬레이션이 정지된 상태입니다.
* `Paused` (3): 시뮬레이션이 일시 정지된 상태입니다.

이 속성은 읽기 전용이며, `Play()`, `Pause()`, `Stop()` 메서드를 통해 상태가 변경됩니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

if ball.BallState == Enum.BallState.Playing then
    print("공이 현재 재생 중입니다")
elseif ball.BallState == Enum.BallState.Paused then
    print("공이 일시 정지되었습니다")
end
```

### BallTraceChannel

`number`

시뮬레이션 볼이 궤적을 따라 이동하면서 Sweep(스윕) 검사를 수행할 때 사용할 트레이스 채널을 지정합니다. 이 채널은 내부 볼 시뮬레이터 컴포넌트의 `TraceChannel` 값으로 전달되어 충돌 감지 대상 오브젝트의 범위를 결정합니다. 기본값은 `InteractionTrace` 채널이며, 프로젝트의 콜리전 설정에 맞춰 다른 채널 값으로 변경할 수 있습니다.

#### Code Samples

### CFrame

`CFrame`

시뮬레이션 볼의 현재 위치와 회전을 나타내는 CFrame입니다. 이 속성을 변경하면 공의 위치와 회전이 즉시 업데이트되며, 시뮬레이션 중에는 `PlaybackTime`에 따라 자동으로 갱신됩니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 공의 위치를 (0, 10, 0)으로 설정
ball.CFrame = CFrame.new(0, 10, 0)

-- 공의 위치와 회전을 함께 설정
ball.CFrame = CFrame.new(0, 10, 0) * CFrame.Angles(0, math.rad(45), 0)
```

### Color

`Color3`

공의 색상을 지정합니다. 이 속성은 공의 시각적 표현만을 제어하며, 물리적인 움직임에는 영향을 주지 않습니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 공을 빨간색으로 설정
ball.Color = Color3.new(1, 0, 0)

-- 공을 파란색으로 설정
ball.Color = Color3.fromRGB(0, 100, 255)
```

### EnablePathMarker

`boolean`

공의 이동 궤적을 시각적으로 표시하는 경로 마커의 표시 여부를 제어합니다. `true`로 설정하면 시뮬레이션된 공의 경로가 시각적으로 표시되어 디버깅이나 시각화에 유용합니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 경로 마커 활성화
ball.EnablePathMarker = true

-- 경로 마커 비활성화
ball.EnablePathMarker = false
```

### IsPathMarkerWorldSpace

`boolean`

경로 마커가 월드 공간 좌표계를 사용할지 여부를 지정합니다. `true`로 설정하면 경로 마커가 월드 공간에 고정되어 표시되고, `false`로 설정하면 공의 로컬 공간을 기준으로 표시됩니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 경로 마커를 월드 공간에 표시
ball.IsPathMarkerWorldSpace = true
```

### Material

`Enum.Material`

공의 표면 재질을 지정합니다. 재질에 따라 공의 시각적 표현과 물리적 반응(마찰, 반발 등)이 달라질 수 있습니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 공을 플라스틱 재질로 설정
ball.Material = Enum.Material.Plastic

-- 공을 고무 재질로 설정
ball.Material = Enum.Material.Rubber
```

### MaterialVariant

`string`

재질의 변형(variant)을 지정하는 문자열입니다. 일부 재질은 여러 변형을 지원하며, 이 속성을 통해 특정 변형을 선택할 수 있습니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 재질 변형 설정
ball.MaterialVariant = "Smooth"
```

### PathMarkerScale

`number`

경로 마커의 크기 스케일을 지정합니다. 값이 클수록 경로 마커가 더 크게 표시됩니다. 기본값은 0.2입니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 경로 마커를 더 크게 표시
ball.PathMarkerScale = 0.5
```

### Position

`Vector3`

시뮬레이션 볼의 현재 월드 위치를 나타내는 속성입니다. 이 값은 현재 `CFrame.Position`과 동일하며, 시뮬레이션 중에는 `PlaybackTime`에 따라 자동으로 갱신됩니다.

#### Code Samples

### SlomoFactor

`number`

시뮬레이션 재생 속도의 배율을 지정합니다. 1.0이면 정상 속도, 0.5면 절반 속도, 2.0이면 2배 속도로 재생됩니다. 슬로모션 효과나 타임랩스 구현에 사용할 수 있습니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 절반 속도로 재생
ball.SlomoFactor = 0.5

-- 2배 속도로 재생
ball.SlomoFactor = 2.0
```

### TextureId

`string`

공 표면에 적용할 텍스처의 Asset ID입니다. 시각적인 표현만을 제어하며, 물리적인 움직임에는 영향을 주지 않습니다. 예를 들어 축구공, 농구공 등 다양한 스타일을 표현할 수 있습니다.

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 텍스처 설정
ball.TextureId = "ovdrassetid://123456789"
```

### Transparency

`number`

공의 투명도를 설정합니다. 0은 완전 불투명, 1은 완전 투명을 의미합니다.

#### Code Samples

## Methods

### ClearPathMarkers

시뮬레이션 경로를 시각화하기 위해 생성된 모든 경로 마커를 제거합니다. 새로운 경로를 다시 표시하기 전에 기존 마커를 초기화할 때 유용합니다.

#### Parameters

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

### FindNextBallBounce

현재 재생 시간(`PlaybackTime`) 이후에 발생할 다음 바운스(충돌) 정보를 반환합니다. 바운스가 없거나 슬라이딩 충돌인 경우 빈 `BallBounce` 객체가 반환될 수 있습니다.

#### Parameters

#### Return

| `BallBounce` | 다음 바운스 정보를 담은 `BallBounce` 객체입니다. 바운스가 없으면 빈 객체가 반환됩니다. |
| ------------ | ------------------------------------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 다음 바운스 정보 가져오기
local nextBounce = ball:FindNextBallBounce()

if nextBounce.BouncedTime > 0 then
    print("다음 바운스 시간:", nextBounce.BouncedTime)
    print("바운스 위치:", nextBounce.BouncedPosition)
end
```

### GetAngularVelocityAtTime

시뮬레이션이 시작된 후 특정 시간(Time)이 경과했을 때의 공의 각속도(Vector3)를 반환합니다. 이 값은 공의 회전 방향과 속도를 나타내며, 마그누스 효과나 회전 기반의 궤적 예측 등에 활용할 수 있습니다.

#### Parameters

| `number` Time | 시뮬레이션이 시작된 이후 경과한 시간(초 단위)입니다. 지정한 시점의 공의 각속도를 조회합니다. |
| ------------- | ----------------------------------------------------- |

#### Return

| `Vector3` | 지정한 시점의 공의 각속도입니다. 방향은 회전축을, 크기는 각속도를 나타냅니다. |
| --------- | -------------------------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 2초 후의 각속도 조회
local angularVelocity = ball:GetAngularVelocityAtTime(2.0)
print("각속도:", angularVelocity)
print("회전 속도:", angularVelocity.Magnitude)
```

### GetBallBounceByIndex

지정된 인덱스에 해당하는 바운스 정보를 반환합니다. 인덱스는 시뮬레이션 중 발생한 바운스의 순서를 나타내며, 0부터 시작합니다. 유효하지 않은 인덱스인 경우 빈 `BallBounce` 객체가 반환될 수 있습니다.

#### Parameters

| `number` bounceIndex | 조회할 바운스의 인덱스입니다. 0부터 시작하며, 시뮬레이션 중 발생한 바운스의 순서를 나타냅니다. |
| -------------------- | ------------------------------------------------------ |

#### Return

| `BallBounce` | 지정된 인덱스의 바운스 정보를 담은 `BallBounce` 객체입니다. |
| ------------ | --------------------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 첫 번째 바운스 정보 가져오기
local firstBounce = ball:GetBallBounceByIndex(0)

if firstBounce.BouncedTime > 0 then
    print("첫 번째 바운스 시간:", firstBounce.BouncedTime)
    print("바운스 위치:", firstBounce.BouncedPosition)
end
```

### GetBestDirectionToTargetAtTime

지정된 재생 시간에서 목표 위치로 공을 발사하기 위한 최적의 방향을 계산합니다. 스핀을 고려한 물리 시뮬레이션을 통해 목표에 도달할 가능성이 가장 높은 방향을 반환합니다.

#### Parameters

| `number` InPlaybackTime    | 시뮬레이션 재생 시간입니다. 이 시점에서 공을 발사합니다.   |
| -------------------------- | ---------------------------------- |
| `Vector3` InTargetPosition | 목표 위치입니다.                          |
| `number` InSpeed           | 발사 속도입니다.                          |
| `Vector3` SpinAxis         | 회전축 벡터입니다.                         |
| `number` InSpinSpeed       | 회전 속도입니다.                          |
| `number` InStepCount       | 시뮬레이션 스텝 수입니다.                     |
| `number` InTargetRadius    | 목표 반경입니다. 이 범위 내에 도달하면 성공으로 간주됩니다. |
| `number` InMaxSampleCount  | 최대 샘플링 횟수입니다.                      |

#### Return

| `Vector3` | 목표 위치로 향하는 최적의 방향 벡터입니다. |
| --------- | ------------------------ |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")
local targetPosition = Vector3.new(100, 0, 50)

-- 현재 재생 시간에서 목표로 향하는 최적 방향 계산
local bestDirection = ball:GetBestDirectionToTargetAtTime(
    ball.PlaybackTime,
    targetPosition,
    2000,  -- 속도
    Vector3.new(0, 1, 0),  -- 회전축
    50,  -- 회전 속도
    100,  -- 스텝 수
    5,  -- 목표 반경
    100  -- 최대 샘플 수
)

print("최적 발사 방향:", bestDirection)
```

### GetCFrameAtTime

시뮬레이션 시작 후 지정된 시간(Time)의 공의 위치 및 회전(CFrame)을 반환합니다. 이 메서드는 미래 혹은 과거 시점의 공의 정확한 위치를 얻을 때 유용하며, NPC나 AI가 공의 낙하지점을 예측하는 데 자주 사용됩니다.

#### Parameters

| `number` Time | 시뮬레이션이 시작된 이후 경과한 시간(초 단위)입니다. 지정한 시점의 공 CFrame을 조회합니다. |
| ------------- | ------------------------------------------------------- |

#### Return

| `CFrame` | 지정한 시점의 공의 CFrame입니다. 위치와 회전값을 알 수 있습니다. |
| -------- | ---------------------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 3초 후의 공 위치와 회전 조회
local futureCFrame = ball:GetCFrameAtTime(3.0)
print("3초 후 위치:", futureCFrame.Position)

-- AI가 공의 낙하지점 예측
local landingTime = 5.0
local landingCFrame = ball:GetCFrameAtTime(landingTime)
print("예상 낙하지점:", landingCFrame.Position)
```

### GetCurrentPlaybackPosition

현재 재생 시간(`PlaybackTime`)에서의 공의 위치를 반환합니다. 이 메서드는 `GetCFrameAtTime(ball.PlaybackTime).Position`과 동일한 결과를 반환합니다.

#### Parameters

#### Return

| `Vector3` | 현재 재생 시간에서의 공의 위치입니다. |
| --------- | --------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 현재 공의 위치 확인
local currentPosition = ball:GetCurrentPlaybackPosition()
print("현재 공 위치:", currentPosition)
```

### GetCurrentSnapshotIndex

현재 재생 시간(`PlaybackTime`)에 해당하는 스냅샷의 인덱스를 반환합니다. 스냅샷 인덱스는 시뮬레이션 중 생성된 스냅샷 배열에서의 위치를 나타냅니다.

#### Parameters

#### Return

| `Value` | 현재 재생 시간에 해당하는 스냅샷의 인덱스입니다. |
| ------- | --------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 현재 스냅샷 인덱스 확인
local snapshotIndex = ball:GetCurrentSnapshotIndex()
print("현재 스냅샷 인덱스:", snapshotIndex)
```

### GetLinearVelocityAtTime

시뮬레이션 시작 후 지정된 시간(Time)의 선형 속도(Vector3)를 반환합니다. 공의 이동 방향과 속도를 계산할 때 사용되며, 충돌 시 반사각 계산이나 공의 궤적 시각화에 활용됩니다.

#### Parameters

| `number` Time | 시뮬레이션이 시작된 이후 경과한 시간(초 단위)입니다. 지정한 시점의 공 속도를 조회합니다. |
| ------------- | --------------------------------------------------- |

#### Return

| `Vector3` | 지정한 시점의 공의 속도입니다. 방향은 이동 방향을, 크기는 속도를 나타냅니다. |
| --------- | -------------------------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 2초 후의 속도 조회
local velocity = ball:GetLinearVelocityAtTime(2.0)
print("속도:", velocity)
print("속력:", velocity.Magnitude)
```

### GetPlaybackTime

시뮬레이션의 현재 재생 시간을 반환합니다. 이 값은 시뮬레이션 궤적 타임라인에서 현재 어느 시점까지 진행되었는지를 나타냅니다.

#### Parameters

#### Return

| `number` | 시뮬레이션의 현재 재생 시간(초 단위)입니다. |
| -------- | ------------------------- |

#### Code Samples

### GetRemainedTimeForNextBounce

현재 재생 시간부터 다음 바운스까지 남은 시간을 반환합니다. 바운스가 없거나 슬라이딩 충돌인 경우 매우 큰 값(FLT\_MAX)이 반환됩니다.

#### Parameters

#### Return

| `number` | 다음 바운스까지 남은 시간(초 단위)입니다. 바운스가 없으면 매우 큰 값이 반환됩니다. |
| -------- | ------------------------------------------------ |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 다음 바운스까지 남은 시간 확인
local remainingTime = ball:GetRemainedTimeForNextBounce()

if remainingTime < math.huge then
    print("다음 바운스까지 남은 시간:", remainingTime, "초")
else
    print("다음 바운스가 없습니다")
end
```

### GetSpeedAtTime

시뮬레이션이 시작된 후 지정된 시간(Time)의 스칼라 속력을 반환합니다. `GetLinearVelocityAtTime`과 달리 방향 정보는 없으며, 단순히 속도의 크기만 제공합니다.

#### Parameters

| `number` Time | 시뮬레이션이 시작된 이후 경과한 시간(초 단위)입니다. 지정한 시점의 공 속력을 조회합니다. |
| ------------- | --------------------------------------------------- |

#### Return

| `number` | 지정한 시점의 공의 속력입니다. 단위는 cm/s입니다. |
| -------- | ------------------------------ |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 2초 후의 속력 조회
local speed = ball:GetSpeedAtTime(2.0)
print("2초 후 속력:", speed, "cm/s")
```

### IsValidBounceIndex

지정된 인덱스가 유효한 바운스 인덱스인지 확인합니다. 인덱스가 시뮬레이션 중 발생한 바운스의 범위 내에 있는지 검증합니다.

#### Parameters

| `number` bounceIndex | 확인할 바운스 인덱스입니다. |
| -------------------- | --------------- |

#### Return

| `boolean` | 인덱스가 유효하면 `true`, 그렇지 않으면 `false`를 반환합니다. |
| --------- | ----------------------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 바운스 인덱스 유효성 확인
if ball:IsValidBounceIndex(0) then
    local bounce = ball:GetBallBounceByIndex(0)
    print("첫 번째 바운스 시간:", bounce.BouncedTime)
else
    print("유효하지 않은 바운스 인덱스입니다")
end
```

### Pause

현재 진행 중인 시뮬레이션을 일시 정지합니다. 이 메서드는 `Play()`로 다시 재개할 수 있으며, 정지된 동안의 시간은 시뮬레이션에 반영되지 않습니다. 게임 일시정지나 슬로모션 효과 구현 시 사용됩니다.

#### Parameters

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- Play simulation
ball:Play()

-- Pause after 2 seconds
wait(2)
ball:Pause()

-- Resume
wait(1)
ball:Play()
```

### Play

시뮬레이션 데이터를 재생하여 공의 움직임을 실제로 실행합니다. 모든 클라이언트에서 동일한 타이밍과 결과로 재생되며, `Pause()` 이후 다시 이어서 재생하는 것도 가능합니다.

#### Parameters

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- Set simulation parameters
local params = BallSimParams.new()
params.InitialCFrame = CFrame.new(0, 10, 0)
params.InitialVelocity = Vector3.new(100, 500, 0)
params.Mass = 0.5

-- Run simulation
ball:Simulate(params)

-- Start playback
ball:Play()
```

### ReSimulateSpinToTargetWithDelay

현재 재생 시간에서 지정된 지연 시간 후에 스핀을 포함하여 목표 위치로 향하도록 재시뮬레이션을 수행합니다.

#### Parameters

| `number` InDelayTime       | 현재 재생 시간으로부터의 지연 시간(초 단위)입니다. |
| -------------------------- | ----------------------------- |
| `Vector3` InTargetPosition | 목표 위치입니다.                     |
| `number` InSpeed           | 발사 속도입니다.                     |
| `Vector3` InSpinAxis       | 회전축 벡터입니다.                    |
| `number` InSpinSpeed       | 회전 속도입니다.                     |
| `number` InStepCount       | 시뮬레이션 스텝 수입니다.                |

#### Return

| `boolean` | 재시뮬레이션이 성공적으로 시작되면 true, 실패하면 false를 반환합니다. |
| --------- | ------------------------------------------- |

#### Code Samples

### ReSimulateToTargetWithDelay

현재 재생 시간에서 지정된 지연 시간 후에 목표 위치로 향하도록 재시뮬레이션을 수행합니다. 이 메서드는 공이 특정 시점에 목표 지점으로 향하도록 궤적을 재계산합니다. 스핀은 현재 각속도를 기반으로 자동 계산됩니다.

#### Parameters

| `number` InDelayTime       | 현재 재생 시간으로부터의 지연 시간(초 단위)입니다. |
| -------------------------- | ----------------------------- |
| `Vector3` InTargetPosition | 목표 위치입니다.                     |
| `number` InSpeed           | 발사 속도입니다.                     |
| `number` InStepCount       | 시뮬레이션 스텝 수입니다.                |

#### Return

| `boolean` | 재시뮬레이션이 성공적으로 시작되면 `true`, 실패하면 `false`를 반환합니다. |
| --------- | ----------------------------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")
local targetPosition = Vector3.new(100, 0, 50)

-- 1초 후에 목표로 향하도록 재시뮬레이션
local success = ball:ReSimulateToTargetWithDelay(
    1.0,  -- 1초 후
    targetPosition,
    2000,  -- 속도
    100  -- 스텝 수
)

if success then
    print("재시뮬레이션이 시작되었습니다")
end
```

### ReSimulateWithDelay

현재 재생 시간에서 지정된 지연 시간 후에 지정된 방향과 속도로 재시뮬레이션을 수행합니다. 이 메서드는 공의 궤적을 특정 시점에서 새로운 방향과 속도로 재계산합니다.

#### Parameters

| `number` InDelayTime  | 현재 재생 시간으로부터의 지연 시간(초 단위)입니다. |
| --------------------- | ----------------------------- |
| `Vector3` InDirection | 발사 방향 벡터입니다.                  |
| `number` InSpeed      | 발사 속도입니다.                     |
| `Vector3` InSpinAxis  | 회전축 벡터입니다.                    |
| `number` InSpinSpeed  | 회전 속도입니다.                     |
| `number` InStepCount  | 시뮬레이션 스텝 수입니다.                |

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 1초 후에 새로운 방향으로 재시뮬레이션
ball:ReSimulateWithDelay(
    1.0,  -- 1초 후
    Vector3.new(1, 0, 0),  -- 방향
    2000,  -- 속도
    Vector3.new(0, 1, 0),  -- 회전축
    50,  -- 회전 속도
    100  -- 스텝 수
)
```

### SetPlaybackTime

시뮬레이션의 진행 시간을 임의의 시점으로 변경합니다. 이를 통해 특정 순간으로 되감거나, 테스트 목적으로 미래 시점의 상태를 즉시 확인할 수 있습니다. 예를 들어, `SetPlaybackTime(2.5)`를 호출하면 시뮬레이션이 2.5초 진행된 상태로 설정됩니다.

#### Parameters

| `number` InPlaybackTime | 시뮬레이션 내에서 이동할 목표 시점(초 단위)입니다. 0 이상의 실수 값을 지정하며, 0은 시뮬레이션 시작 시점을 의미합니다. |
| ----------------------- | ---------------------------------------------------------------------- |

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 시뮬레이션 실행
ball:Simulate(params)
ball:Play()

-- 2.5초 시점으로 이동
ball:SetPlaybackTime(2.5)

-- 해당 시점의 공 위치 확인
local position = ball:GetCurrentPlaybackPosition()
print("2.5초 시점의 위치:", position)
```

### Simulate

시뮬레이션 볼의 물리 시뮬레이션을 수행하고, 지정된 파라미터(`BallSimParams`)를 기반으로 공의 움직임 궤적을 미리 계산합니다. 이 함수는 `Play()`로 재생하기 전에 미리 궤적을 준비하거나, 시뮬레이션 결과를 별도로 분석할 때 사용됩니다. 결과는 각 시점별로 계산된 위치, 속도, 회전 등의 정보를 포함한 배열 형태로 반환됩니다.

#### Parameters

| `BallSimParams` InBallSimParams | 시뮬레이션에 사용할 물리 파라미터 구조체입니다. 질량, 중력, 초기 속도, 스핀, 감쇠, 충돌 특성 등의 물리적 특성을 포함하며, 이 값들에 따라 궤적 결과가 달라집니다. |
| ------------------------------- | ----------------------------------------------------------------------------------------------- |

#### Return

| `void` | 시뮬레이션 결과를 담은 배열로, 각 원소는 시간순으로 정렬된 공의 상태(`BallSnapshot`)를 나타냅니다. |
| ------ | --------------------------------------------------------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 시뮬레이션 파라미터 생성
local params = BallSimParams.new()
params.InitialCFrame = CFrame.new(0, 10, 0)
params.InitialVelocity = Vector3.new(100, 500, 0)
params.Mass = 0.5
params.BaseGravity = Vector3.new(0, -980, 0)
params.InitialSpinAxis = Vector3.new(0, 1, 0)
params.InitialSpinSpeed = 50

-- 시뮬레이션 실행
local snapshots = ball:Simulate(params)

print("시뮬레이션 완료. 총 스냅샷 개수:", #snapshots)

-- 재생 시작
ball:Play()
```

### Stop

현재 진행 중인 시뮬레이션을 정지합니다. `Pause()`와 달리 재생을 중단하며, `Play()`를 다시 호출하면 시뮬레이션 시작 시점부터 다시 재생됩니다.

#### Parameters

#### Return

| `void` |   |
| ------ | - |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

-- 시뮬레이션 재생
ball:Play()

-- 3초 후 정지
wait(3)
ball:Stop()

-- 다시 재생 (처음부터)
ball:Play()
```

## Events

### Bounded

시뮬레이션 볼이 다른 파트와 바운스(충돌 반사)했을 때 호출되는 이벤트입니다. `Touched` 이벤트와 달리 바운스가 발생한 경우에만 호출되며, 슬라이딩 충돌은 포함되지 않습니다.

#### Parameters

| `BasePart` otherPart | 공과 충돌한 파트입니다. |
| -------------------- | ------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

ball.Bounded:Connect(function(otherPart)
    print("공이", otherPart.Name, "와 바운스했습니다")

    -- 바운스 정보 가져오기
    local bounce = ball:FindNextBallBounce()
    print("바운스 위치:", bounce.BouncedPosition)
    print("바운스 후 속도:", bounce.BouncedSpeed)
end)
```

### Paused

시뮬레이션이 일시 정지되었을 때 호출되는 이벤트입니다. `Pause()` 메서드가 호출되면 이 이벤트가 발생합니다.

#### Parameters

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

ball.Paused:Connect(function()
    print("시뮬레이션이 일시 정지되었습니다")
end)

ball:Pause()
```

### Played

시뮬레이션이 재생되기 시작했을 때 호출되는 이벤트입니다. `Play()` 메서드가 호출되면 이 이벤트가 발생합니다.

#### Parameters

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

ball.Played:Connect(function()
    print("시뮬레이션이 재생되기 시작했습니다")
end)

ball:Play()
```

### Stopped

시뮬레이션이 정지되었을 때 호출되는 이벤트입니다. `Stop()` 메서드가 호출되면 이 이벤트가 발생합니다.

#### Parameters

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

ball.Stopped:Connect(function()
    print("시뮬레이션이 정지되었습니다")
end)

ball:Stop()
```

### Touched

시뮬레이션 볼이 다른 파트와 충돌했을 때 호출되는 이벤트입니다. 이 이벤트를 사용하여 골 판정, 반사 처리, 사운드 재생 등 충돌 기반 로직을 구현할 수 있습니다.

#### Parameters

| `BasePart` otherPart | 공과 충돌한 파트입니다. |
| -------------------- | ------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

ball.Touched:Connect(function(otherPart)
    print("공이", otherPart.Name, "와 충돌했습니다")

    -- 골 판정 예시
    if otherPart.Name == "Goal" then
        print("골!")
    end
end)
```

### TouchEnded

시뮬레이션 볼이 다른 파트와의 접촉이 끝났을 때 호출되는 이벤트입니다. 공이 파트와 충돌한 후 떨어져 나갈 때 발생합니다.

#### Parameters

| `BasePart` otherPart | 공과 충돌했던 파트입니다. |
| -------------------- | -------------- |

#### Code Samples

```lua
local ball = workspace:FindFirstChild("SimulationBall")

ball.TouchEnded:Connect(function(otherPart)
    print("공이", otherPart.Name, "와의 접촉을 끝냈습니다")
end)
```

## See also

{% content-ref url="/pages/iYYwRA7LVMPQ75P1DqUW" %}
[SimulationBall](/korean/manual/studio-manual/object/simulationball.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.overdare.com/korean/development/api-reference/classes/simulationball.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
