# Sound

Sound : `Instance`

## Overview

Sound는 사운드를 발생시키는 객체입니다.

Sound가 BasePart 또는 Attachment의 자식으로 배치되면 해당 위치에서 사운드가 발생하며, 청취자와의 거리에 따라 볼륨이 변화합니다. 그 외의 경우 플레이스 전체에서 동일한 볼륨으로 재생됩니다.

Sound의 재생 범위는 PlaybackRegionsEnabled, StartTimePosition, PlaybackRegion, LoopRegion, Looped 속성의 조합에 따라 결정됩니다. 상세한 재생 범위 제어 가이드는 [Sound 매뉴얼](https://docs.overdare.com/korean/manual/studio-manual/object/sound#재생-범위-제어)을 참조하세요.

## Properties

### IsLoaded

`bool`

사운드가 서버에서 로드되어 재생 가능한 상태인지를 나타냅니다. Loaded 이벤트와 함께 사용하여 사운드를 재생하기 전에 로드 여부를 확인할 수 있습니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

if Sound.IsLoaded then
    Sound:Play()
else
    Sound.Loaded:Wait()
    Sound:Play()
end
```

### IsPaused

`bool`

사운드가 재생 중이지 않을 때 true를 반환합니다. Pause(), Stop()으로 중지되었거나 한 번도 재생되지 않은 경우 true입니다.

읽기 전용 속성이므로 사운드 제어에는 Pause() 또는 Stop() 메서드를 사용하세요.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

if Sound.IsPaused then
    Sound:Resume()
end
```

### IsPlaying

`bool`

사운드가 현재 재생 중일 때 true를 반환합니다. Playing 속성과 달리 읽기 전용이므로 사운드 제어에는 Play() 메서드를 사용하세요.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

if not Sound.IsPlaying then
    Sound:Play()
end
```

### Looped

`bool`

사운드를 반복 재생할지 여부를 설정합니다. true로 설정하면 사운드가 끝까지 재생된 후 처음(또는 루프 시작점)부터 다시 재생됩니다.

DidLoop 이벤트로 루프 횟수를 추적할 수 있습니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Looped = true
```

### LoopRegion

`NumberRange`

PlaybackRegion 내에서 원하는 루프 시작 및 종료 시간을 초 단위로 나타내는 범위입니다.

이 속성을 사용하려면 PlaybackRegionsEnabled = true이고 Looped = true여야 합니다. 이 속성은 루프 재생 중에만 적용되며, 처음 재생 시에는 PlaybackRegion이 사용됩니다.

LoopRegion은 다음과 같이 적용됩니다:

* 처음 재생 시 (DidLoop = 0): PlaybackRegion 범위로 재생되고, LoopRegion은 무시됩니다.
* 루프 재생 시 (DidLoop ≥ 1): LoopRegion과 PlaybackRegion 중 더 작은(제한적인) 범위가 적용됩니다.
  * `LoopRegion.Min > PlaybackRegion.Min`: LoopRegion.Min부터 시작
  * `LoopRegion.Min ≤ PlaybackRegion.Min`: PlaybackRegion.Min부터 시작
  * `LoopRegion.Max < PlaybackRegion.Max`: LoopRegion.Max에서 종료
  * `LoopRegion.Max ≥ PlaybackRegion.Max`: PlaybackRegion.Max에서 종료
* `LoopRegion.Min = LoopRegion.Max`: 이 속성이 비활성화되고 PlaybackRegion이 루프에도 사용됩니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackRegionsEnabled = true
Sound.PlaybackRegion = NumberRange.new(0, 30)

Sound.LoopRegion = NumberRange.new(10, 25)
Sound.Looped = true

Sound:Play()
```

### PlaybackLoudness

`number`

현재 재생 중인 사운드의 음량(진폭)을 0\~1000 범위로 나타냅니다. 오디오 시각화나 사운드 반응 효과를 만드는 데 유용합니다.

이 속성은 클라이언트가 실제로 듣는 사운드의 음량을 나타내므로, 서버에서 조회하면 항상 0을 반환합니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound
local Part = Workspace.Part

game:GetService("RunService").Heartbeat:Connect(function()
    local loudness = Sound.PlaybackLoudness
    Part.Size = Vector3.new(1, 1 + loudness / 100, 1)
end)
```

### PlaybackRegion

`NumberRange`

TimeLength 내에서 원하는 시작 및 종료 시간을 초 단위로 나타내는 범위입니다.

이 속성을 사용하려면 PlaybackRegionsEnabled를 true로 설정해야 합니다.

다음과 같이 동작합니다:

* `PlaybackRegion.Min > 0`: 사운드가 PlaybackRegion.Min 시간부터 재생을 시작합니다.
* `PlaybackRegion.Min ≤ 0`: 사운드가 0부터 재생을 시작합니다 (음수 값은 0으로 클램핑).
* `PlaybackRegion.Max < TimeLength`: 사운드가 정확히 해당 시간에 종료됩니다.
* `PlaybackRegion.Max ≥ TimeLength`: 사운드가 TimeLength에서 종료됩니다.
* `PlaybackRegion.Min = PlaybackRegion.Max`: 이 속성이 비활성화됩니다 (0부터 TimeLength까지 재생).

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackRegionsEnabled = true
Sound.PlaybackRegion = NumberRange.new(5, 20)

Sound:Play()
```

### PlaybackRegionsEnabled

`bool`

PlaybackRegion과 LoopRegion을 활성화하여 사운드의 특정 구간만 재생하거나 반복 구간을 지정할 수 있습니다. PlaybackRegionsEnabled가 활성화되면 StartTimePosition은 무시됩니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackRegionsEnabled = true
Sound.PlaybackRegion = NumberRange.new(5, 20)

Sound.LoopRegion = NumberRange.new(10, 15)
Sound.Looped = true

Sound:Play()
```

### PlaybackSpeed

`number`

사운드의 재생 속도를 설정합니다. 1.0이 정상 속도이며, 값이 클수록 빠르게, 작을수록 느리게 재생됩니다. 재생 속도가 변하면 음높이(피치)도 함께 변합니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackSpeed = 2.0
Sound:Play()
```

### Playing

`bool`

사운드의 재생 상태를 나타내며, 직접 설정할 수 있습니다.

다음과 같이 동작합니다:

* Playing = false: 사운드를 일시 정지합니다 (TimePosition은 유지).
* Playing = true: 현재 TimePosition부터 재생을 재개합니다.
* Play() 메서드와의 차이: Play()는 StartTimePosition(또는 PlaybackRegion.Min)부터 재생합니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound:Play()
wait(2)
Sound.Playing = false 
wait(1)
Sound.Playing = true 
```

### PlayOnRemove

`bool`

true로 설정하면 사운드 객체가 제거될 때 재생됩니다. 사운드가 재생 중이지 않을 때 제거되면 처음부터 재생되고, 재생 중일 때 제거되면 현재 위치부터 계속 재생됩니다.

폭발이나 파괴 효과 등 객체가 사라질 때 사운드를 재생하는 데 유용합니다.

아래의 경우에 사운드가 재생됩니다:

* `sound:Destroy()`
* `sound.Parent = nil`
* `sound.Parent.Parent = nil`

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlayOnRemove = true
Sound:Destroy() 
```

### RollOffMaxDistance

`number`

3D 사운드(BasePart 또는 Attachment의 자식)가 들리는 최대 거리를 스터드 단위로 설정합니다. 이 거리를 초과하면 사운드가 들리지 않습니다.

RollOffMode에 따라 사운드가 감쇠되는 방식이 달라집니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local Sound = part.Sound

Sound.RollOffMaxDistance = 100
```

### RollOffMinDistance

`number`

3D 사운드(BasePart 또는 Attachment의 자식)가 최대 볼륨으로 들리는 최소 거리를 스터드 단위로 설정합니다. 이 거리를 초과하면 RollOffMode에 따라 사운드가 감쇠되기 시작합니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local Sound = part.Sound

Sound.RollOffMinDistance = 10 
Sound.RollOffMaxDistance = 100
```

### RollOffMode

`Enum.RollOffMode`

3D 사운드(BasePart 또는 Attachment의 자식)의 거리에 따른 볼륨 감쇠 방식을 설정합니다. RollOffMinDistance와 RollOffMaxDistance 사이에서 사운드가 어떻게 감쇠될지 결정합니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local part = Workspace.Part
local Sound = part.Sound

Sound.RollOffMode = Enum.RollOffMode.Linear
```

### SoundGroup

`SoundGroup`

이 사운드가 속한 SoundGroup을 설정합니다. SoundGroup에 속한 모든 사운드는 그룹의 Volume 설정에 영향을 받아 볼륨을 일괄적으로 제어할 수 있습니다.

#### Code Samples

```lua
local SoundService = game:GetService("SoundService")
local Workspace = game:GetService("Workspace")

local musicGroup = SoundService.MusicGroup
local Sound = Workspace.Sound

Sound.SoundGroup = musicGroup
```

### SoundId

`string`

재생할 사운드 파일의 에셋 ID입니다. `ovdrassetid://` 형식으로 사운드 에셋을 지정합니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.SoundId = "ovdrassetid://1234567890"
Sound:Play()
```

### StartTimePosition

`number`

Play() 메서드로 재생할 때 시작할 위치를 초 단위로 설정합니다. 이 속성은 PlaybackRegionsEnabled = false일 때만 동작합니다.

주요 특성은 다음과 같습니다:

* 음수 값은 0으로 클램핑됩니다.
* Looped = true일 때: 처음 재생 시에만 적용되고, 루프 시에는 0부터 시작합니다.
* Resume()이나 Playing = true는 StartTimePosition이 아닌 현재 TimePosition부터 재생합니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.StartTimePosition = 50
Sound:Play()

wait(5)
Sound:Play() 
```

### TimeLength

`number`

사운드의 전체 길이를 초 단위로 나타냅니다. 로드되지 않은 경우 0입니다.

PlaybackSpeed와 함께 사용하여 사운드가 특정 시간 동안 재생되도록 속도를 조정할 수 있습니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.PlaybackSpeed = Sound.TimeLength / 5
Sound:Play()
```

### TimePosition

`number`

사운드의 현재 재생 위치를 초 단위로 나타냅니다. 이 값을 변경하여 재생 중에 사운드의 재생 위치를 즉시 이동할 수 있습니다.

사운드가 재생되는 동안 TimePosition은 초당 PlaybackSpeed 비율로 증가하며, TimeLength에 도달하면 Looped가 아닌 경우 사운드가 중지됩니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound:Play()
wait(2)
Sound.TimePosition = 10

local progress = Sound.TimePosition / Sound.TimeLength * 100
print("재생 진행도:", progress, "%")
```

### Volume

`number`

사운드의 볼륨을 설정합니다. 0(무음)에서 10(최대) 사이의 값이며 기본값은 0.5입니다.

SoundGroup에 속한 경우, 그룹의 Volume 설정에도 영향을 받습니다.

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Volume = 2.0
Sound:Play()
```

## Methods

### Pause

사운드를 일시 정지합니다. TimePosition은 유지되므로 Resume()으로 이어서 재생할 수 있습니다.

#### Parameters

#### Return

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

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound:Play()
wait(2)
Sound:Pause() 
```

### Play

사운드를 재생합니다. 재생 시작 위치는 PlaybackRegionsEnabled 설정에 따라 달라집니다.

재생 시작 위치는 다음과 같습니다:

* PlaybackRegionsEnabled = false: StartTimePosition부터 시작
* PlaybackRegionsEnabled = true: PlaybackRegion.Min부터 시작

재생 중에 Play()를 다시 호출하면 시작 위치로 되돌아갑니다.

#### Parameters

#### Return

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

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.StartTimePosition = 10
Sound:Play()
```

### Resume

일시 정지된 사운드를 현재 TimePosition부터 재개합니다. Pause()와 함께 사용됩니다.

#### Parameters

#### Return

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

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound:Play()
wait(2)
Sound:Pause()
wait(1)
Sound:Resume()
```

### Stop

사운드를 중지하고 TimePosition을 0으로 리셋하고 나머지 속성들은 유지됩니다.

따라서 Stop() 후 Play()를 호출하면 StartTimePosition부터 재생됩니다.

#### Parameters

#### Return

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

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.StartTimePosition = 10
Sound:Play()
wait(2)
Sound:Stop()

Sound:Play()
```

## Events

### DidLoop

사운드가 루프될 때마다 발생합니다. Stop()을 호출하면 루프 카운터가 0으로 리셋됩니다.

#### Parameters

| `string` SoundId          | 루프된 사운드의 SoundId |
| ------------------------- | ---------------- |
| `number` numOfTimesLooped | 사운드가 루프된 횟수      |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.DidLoop:Connect(function(soundId, numOfTimesLooped)
    print("루프 횟수:", numOfTimesLooped)
    if numOfTimesLooped >= 3 then
        Sound:Stop()
    end
end)

Sound.Looped = true
Sound:Play()
```

### Ended

사운드가 끝까지 재생되어 중지될 때 발생합니다.

단, 아래의 경우에는 발생되지 않습니다.

* Looped = true인 경우 발생하지 않습니다.
* 중간에 Stop()으로 중지한 경우 발생하지 않습니다(Stopped 이벤트 사용).

#### Parameters

| `string` SoundId | 재생이 종료된 사운드의 SoundId |
| ---------------- | -------------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Ended:Connect(function(soundId)
    print("재생 완료:", soundId)
    Sound:Destroy() 
end)

Sound:Play()
```

### Loaded

사운드가 로드될 때 발생합니다. 이미 로드된 경우 발생하지 않으므로 IsLoaded를 먼저 확인하는 것이 좋습니다.

#### Parameters

| `string` SoundId | 로드된 사운드의 SoundId |
| ---------------- | ---------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

local function OnLoaded()
    print("Sound has been loaded.")
end
Sound.Loaded:Connect(OnLoaded)
```

### Paused

Pause() 메서드로 사운드가 일시 정지될 때 발생합니다.

#### Parameters

| `string` SoundId | 일시 정지된 사운드의 SoundId |
| ---------------- | ------------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Paused:Connect(function(soundId)
    print("일시 정지됨:", soundId)
end)

Sound:Play()
wait(1)
Sound:Pause()
```

### Played

Play() 메서드로 사운드가 재생될 때마다 발생합니다.

PlayOnRemove = true로 인한 재생에서는 발생하지 않습니다.

#### Parameters

| `string` SoundId | 재생된 사운드의 SoundId |
| ---------------- | ---------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

local function OnPlayed(soundId)
    print("Sound has started playing:", soundId)
end
Sound.Played:Connect(OnPlayed)
```

### Resumed

Resume() 메서드로 사운드가 재개될 때 발생합니다.

#### Parameters

| `string` SoundId | 재개된 사운드의 SoundId |
| ---------------- | ---------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Resumed:Connect(function(soundId)
    print("재생 재개:", soundId)
end)

Sound:Play()
wait(1)
Sound:Pause()
wait(1)
Sound:Resume()
```

### Stopped

다음 경우에 발생합니다:

* Stop() 메서드로 중지할 때
* 재생 중 SoundId가 변경될 때

사운드를 Destroy()로 파괴하는 경우에는 발생하지 않습니다.

#### Parameters

| `string` SoundId | 중지된 사운드의 SoundId |
| ---------------- | ---------------- |

#### Code Samples

```lua
local Workspace = game:GetService("Workspace")
local Sound = Workspace.Sound

Sound.Stopped:Connect(function(soundId)
    print("사운드 중지됨:", soundId)
end)

Sound:Play()
wait(2)
Sound:Stop() 
```
