> For the complete documentation index, see [llms.txt](https://docs.decentraland.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.decentraland.org/creator/content-creator-ko/sdk7/3d/sounds.md).

# 사운드

씬에 사운드를 추가하는 방법을 알아봅니다.

소리는 플레이어의 행동과 이벤트에 피드백을 제공하는 좋은 방법이며, 배경음은 장면에 더 많은 맥락을 부여하고 플레이어의 몰입감을 높여줄 수도 있습니다.

{% hint style="warning" %}
**📔 참고**: 소리는 소리가 생성된 장면을 구성하는 parcel 안에 서 있는 플레이어만 들을 수 있다는 점을 기억하세요. 비록 청취 범위 안에 있더라도 마찬가지입니다. 플레이어는 설정에서 모든 소리를 끄도록 선택할 수도 있습니다.
{% endhint %}

지원되는 사운드 형식은 브라우저에 따라 다르지만, 다음 형식을 사용하는 것이 권장됩니다 *.mp3*.

*.wav* 파일도 지원되지만 크기가 훨씬 크기 때문에 일반적으로 권장되지는 않습니다.

## 소리 재생

소리를 재생하는 가장 쉬운 방법은 **Audio Source** 구성 요소를 시각적으로 [Creator Hub의 Scene Editor에서](/creator/content-creator-ko/scene-editor/get-started/about-editor.md) 에 추가한 뒤 **재생 시작** 및 **반복**. 참고 [구성 요소 추가](/creator/content-creator-ko/scene-editor/build/components.md#add-components).

![](https://3980763956-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FoPnXBby9S6MrsW83Y9qZ%2Fuploads%2Fgit-blob-ae588633ad20c357cfcb71a63216e4b8e02802ae%2FAudioSource-component.png?alt=media\&token=266f32b9-95c4-4d4b-a7c0-bd84d50c2dfe)

또한 코드 없이 **Actions**를 통해 소리 재생을 트리거할 수도 있습니다. 참고 [어떤 항목이든 스마트하게 만들기](/creator/content-creator-ko/scene-editor/interactivity/make-any-item-smart.md).

코드로 소리를 재생하려면 `AudioSource.playSound` 함수를 사용하세요.

```ts
// 엔티티 생성
const sourceEntity = engine.addEntity()
Transform.create(sourceEntity, { position: Vector3.create(8, 1, 8) })

// 소리 재생
AudioSource.playSound(sourceEntity, 'assets/sounds/sound-effect.mp3')
```

{% hint style="warning" %}
**📔 참고**: \`AudioSource\`가 있는 모든 엔티티는 `AudioSource` 또한 `Transform`도 필요합니다. 글로벌 사운드도 포함됩니다. 이것이 없으면 아무것도 재생되지 않고 오류도 기록되지 않아서 문제를 발견하기 어렵습니다. Scene Editor에 배치한 항목에는 항상 `Transform`가 있으므로, 이는 코드로 생성한 엔티티에만 영향을 줍니다.
{% endhint %}

사운드 파일은 프로젝트 폴더 안에 있어야 합니다. 위 예시에서 오디오 파일은 `assets/sounds` 폴더에 있으며, 이 폴더는 장면 프로젝트 폴더의 루트 수준에 있습니다.

{% hint style="warning" %}
**📔 참고**:  `AudioSource` 구성 요소는 다음을 통해 가져와야 합니다

> `import { AudioSource } from "@dcl/sdk/ecs"`

참고 [가져오기](/creator/content-creator-ko/sdk7/getting-started/coding-scenes.md#imports) 를 통해 쉽게 처리하는 방법을 확인하세요.
{% endhint %}

이 `AudioSource.playSound()` 함수는 다음 인수를 사용합니다:

* `entity`: 소리를 적용할 엔티티입니다. 소리는 이 엔티티의 위치에서 들리며, 플레이어가 가까워질수록 더 크게 들립니다.
* `src`: 프로젝트 내에서 사운드 파일의 위치입니다.

{% hint style="info" %}
**💡 팁**: 더 명확하게 하기 위해 사운드 파일을 별도의 `assets/sounds` 폴더로 장면 안에 보관하는 것을 권장합니다.
{% endhint %}

* `resetCursor`: *(선택 사항)* true이면 사운드는 항상 처음부터 시작됩니다. 그렇지 않으면 현재 커서 위치에서 이어서 재생됩니다. 일시 중지 및 재개에 유용합니다.

소리를 재생하는 또 다른 방법은 엔티티에 `AudioSource` 구성 요소를 수동으로 만드는 것입니다. 이 방법을 사용하면 소리를 더 세밀하게 제어할 수 있습니다. 예를 들어 반복 재생하거나 볼륨을 설정할 수 있습니다.

```ts
// 엔티티 생성
const sourceEntity = engine.addEntity()
Transform.create(sourceEntity, { position: Vector3.create(8, 1, 8) })

// AudioSource 구성 요소 생성
AudioSource.create(sourceEntity, {
	audioClipUrl: 'sounds/sound-effect.mp3',
	loop: true,
	playing: true,
})
```

다음 속성을 설정할 수 있습니다:

* `audioClipUrl`: 프로젝트 내에서 사운드 파일의 위치입니다.
* `playing`: true이면 사운드 재생이 시작됩니다. 다음과 같이 사운드를 만들 수 있습니다 `playing` 를 false로 설정한 다음, 나중에 true로 설정할 수 있습니다.
* `volume`: *(선택 사항)* 사운드 파일의 볼륨입니다. 기본값은 1이며, 최대 볼륨입니다.
* `pitch`: *(선택 사항)* 사운드의 피치를 조정합니다. 기본값은 1이며, 더 낮게 하면 더 깊은 소리가 되고 더 높게 하면 더 높은 음의 소리가 됩니다.

{% hint style="info" %}
**💡 팁**: 게임 중 사운드 효과가 너무 반복적으로 들리는 것을 방지하려면, 재생될 때마다 피치에 약간의 변화를 무작위로 주는 것이 유용합니다.
{% endhint %}

* `currentTime`: *(선택 사항)* 기본값은 0입니다. 사운드 파일의 처음부터 시작하지 않으려면 이 값을 설정하세요.

각 엔티티에는 하나의 `AudioSource` 구성 요소만 있을 수 있으며, 한 번에 하나의 클립만 재생할 수 있습니다. 이 제한은 새 소리를 재생할 때 오디오 소스를 수정하거나, 각각 고유한 소리를 가진 여러 개의 보이지 않는 자식 엔티티를 포함하면 쉽게 극복할 수 있습니다.

{% hint style="warning" %}
**📔 참고**: 소리는 각 플레이어의 로컬 인스턴스에서 재생됩니다. 주변의 다른 플레이어는 자신의 로컬 장면에서도 명시적으로 재생하지 않는 한 같은 소리를 듣지 못합니다.
{% endhint %}

### 사운드 사전 로드

엔티티가 사운드를 사용하지만 장면 런타임에서 즉시 재생되지 않으면 다운로드에 시간이 걸릴 수 있습니다. 다음을 사용하면 장면 런타임에서 사용할 수 있습니다 `AssetLoad` 구성 요소.

```ts
import { AssetLoad } from "@dcl/sdk/ecs"

AssetLoad.create(engine.RootEntity, {
  assets: [
    "assets/scene/bundle1/explosionSound.mp3",
  ],
})
```

자세한 내용은 [리소스 사전 로드](/creator/content-creator-ko/sdk7/optimizing/pre-load-resources.md) 문서를 확인하세요.

## 소리 중지

엔티티의 소리 재생을 중지하려면 `AudioSource.stopSound()` 함수를 사용하세요. 각 엔티티에는 하나의 `AudioSource` 구성 요소만 있으므로 엔티티만 지정하면 됩니다. 각 `AudioSource` 구성 요소는 한 번에 하나의 파일만 재생합니다.

```ts
AudioSource.stopSound(sourceEntity)
```

소리를 중지하는 또 다른 방법은 `playing` 속성을 false로 설정하는 것입니다.

```ts
// 엔티티 생성
const sourceEntity = engine.addEntity()

// AudioSource 구성 요소 생성
AudioSource.create(sourceEntity, {
	audioClipUrl: 'sounds/explosion.mp3',
	playing: true,
})

// 간단한 함수 정의
function stopSound(entity: Entity) {
	// 오디오 소스 구성 요소의 변경 가능한 버전 가져오기
	const audioSource = AudioSource.getMutable(entity)

	// playing 값을 수정
	audioSource.playing = false
}

// 함수 호출
stopSound(sourceEntity)
```

## 사운드가 끝나는 시점 감지

반복하지 않는 사운드가 자체적으로 재생을 마치면 엔진은 `playing` 의 속성을 `AudioSource` 구성 요소의 상태를 다시 *false*로 설정합니다. 장면의 코드는 이 값을 읽어 사운드가 언제 끝났는지 알 수 있으며, 예를 들어 바로 뒤에 다른 사운드나 액션을 이어서 실행할 수 있습니다.

```ts
let wasPlaying = false

engine.addSystem(() => {
	const audio = AudioSource.get(sourceEntity)
	const isPlaying = audio.playing ?? false

	if (wasPlaying && !isPlaying) {
		console.log('sound finished playing')
		// 여기서 반응: 다른 소리 재생, 시퀀스 진행 등
	}

	wasPlaying = isPlaying
})
```

{% hint style="warning" %}
**📔 참고**: 매 프레임마다 구성 요소를 폴링할 때는 항상 다음으로 읽으세요 `AudioSource.get()` (읽기 전용). `AudioSource.getMutable()` 를 사용하면 매 프레임마다 구성 요소가 변경된 것으로 표시되어 불필요한 동기화 작업이 발생합니다.

이 `playing` 속성은 사운드가 스스로 끝날 때만 엔진에 의해 변경됩니다. 장면이 소리를 명시적으로 중지하면( `AudioSource.stopSound()` 또는 다음을 설정하여 `playing` 를 *false*),
{% endhint %}

또는 다음을 사용하세요 `audioEventsSystem.registerAudioEventsEntity` 엔티티 오디오의 재생 상태가 변경될 때마다 실행되는 함수를 정의합니다. 이는 [비디오 이벤트](/creator/content-creator-ko/sdk7/media/video-playing.md#video-events) 와 마찬가지입니다. 함수는 `state` 필드를 가진 이벤트를 받으며, 다음 `MediaState` 열거형을 사용합니다.

```ts
import { engine, AudioSource, audioEventsSystem, MediaState } from '@dcl/sdk/ecs'

// ... AudioSource 구성 요소가 있는 sourceEntity 생성 ...

audioEventsSystem.registerAudioEventsEntity(sourceEntity, (audioEvent) => {
	switch (audioEvent.state) {
		case MediaState.MS_LOADING:
			console.log('audio event - sound is LOADING')
			break
		case MediaState.MS_READY:
			console.log('audio event - sound is READY (loaded, or finished playing)')
			break
		case MediaState.MS_PLAYING:
			console.log('audio event - sound started PLAYING')
			break
		case MediaState.MS_ERROR:
			console.log('audio event - sound ERROR (e.g. the file failed to load)')
			break
	}
})
```

에서 `MS_PLAYING` 를 `MS_READY` 로의 전환은 소리 재생이 중지되었음을 의미합니다. 전체 `MediaState` 열거형에는 또한 `MS_NONE`, `MS_LOADING`, `MS_PAUSED`, `MS_BUFFERING`, `MS_SEEKING` 및 `MS_ERROR`그리고 각 이벤트에는 `timestamp` 상태 변경이 발생한 시점의 타임스탬프가 포함됩니다. 또한 언제든지 최신 보고 상태를 다음으로 조회할 수 있습니다 `audioEventsSystem.getAudioState(entity)`콜백을 해제하려면 `audioEventsSystem.removeAudioEventsEntity(entity)`또는 엔티티가 등록되어 있는지 확인하려면 `audioEventsSystem.hasAudioEventsEntity(entity)`. 동일한 시스템은 [`AudioStream`](/creator/content-creator-ko/sdk7/media/audio-streaming.md) 구성 요소.

{% hint style="warning" %}
**📔 참고**: 이러한 기능은 데스크톱 클라이언트에서만 지원됩니다.
{% endhint %}

## 반복 재생

소리를 계속 반복해서 재생하려면 `loop` 필드를 `AudioSource` 구성 요소의 *true* 로 설정한 다음 재생을 시작하세요.

```ts
// 엔티티 생성
const sourceEntity = engine.addEntity()

// AudioSource 구성 요소 생성
AudioSource.create(sourceEntity, {
	audioClipUrl: 'sounds/sound-effect.mp3',
	playing: true,
	loop: true,
})
```

반복 재생은 배경 음악이나 다른 배경음을 추가할 때 특히 유용합니다.

## 볼륨 설정

다음을 설정하여 `volume` 의 속성을 `AudioSource` 구성 요소로 사운드의 볼륨을 변경할 수 있습니다.

볼륨은 다음 범위의 숫자로 표현됩니다 *0* 를 *1*.

```ts
// 엔티티 생성
const sourceEntity = engine.addEntity()

// AudioSource 구성 요소 생성
AudioSource.create(sourceEntity, {
	audioClipUrl: 'sounds/sound-effect.mp3',
	playing: true,
	volume: 0.5,
})
```

{% hint style="warning" %}
**📔 참고**: 물론 사운드의 볼륨은 플레이어와 오디오 소스 사이의 거리에도 영향을 받습니다. 플레이어가 멀어질수록 볼륨은 더 낮아집니다.
{% endhint %}

## 전역 사운드

기본적으로 `AudioSource` 의 모든 소리는 위치 기반입니다. 즉, 소리가 `Transform` 구성 요소의 위치에서 생성되는 것처럼 들리며, 플레이어가 가까워질수록 더 크게 들립니다. 하지만 사운드를 전역으로 설정하여 플레이어가 어디에 서 있든 볼륨이 일정하게 유지되도록 할 수도 있습니다. 이는 배경 음악, 알림 소리 및 기타 비위치성 사운드에 이상적입니다.

{% hint style="warning" %}
**📔 참고**: Global Sounds는 DCL 2.0 데스크톱 클라이언트에서만 지원되는 기능입니다.
{% endhint %}

사운드를 전역으로 만들려면 `global` 속성을 *true*.

```ts
AudioSource.create(sourceEntity, {
	audioClipUrl: 'sounds/music.mp3',
	playing: true,
	global: true,
})
```

전역 사운드에도 여전히 `Transform` 엔티티에 하나가 필요합니다. 위치는 더 이상 플레이어가 듣는 소리에 영향을 주지 않지만 아무 위치나 괜찮습니다.

## 사운드의 일부 구간 재생

더 긴 사운드 파일의 일부 구간을 재생하려면 `playSoundSegment()` SDK Utils 라이브러리의 기능을 사용하세요. 참고: [SDK7 Utils](https://github.com/decentraland/sdk7-utils).

또한 다음을 명시적으로 설정하여 이를 구현할 수도 있습니다 `currentTime` 속성을 `AudioSource` 구성 요소에 설정한 뒤 일정 시간 기다린 후 중지하는 방법입니다.

## 오디오 스트리밍

참고 [오디오 스트리밍](/creator/content-creator-ko/sdk7/media/audio-streaming.md) 외부 소스에서 실시간 오디오 스트림을 재생하는 방법을 알아보세요.

## 오디오 분석

참고 [오디오 분석](/creator/content-creator-ko/sdk7/media/audio-analysis.md) 에서 실시간 진폭 및 주파수 데이터를 읽는 방법을 알아보세요 `AudioSource` 그리고 이를 바탕으로 베이스에 맞춰 펄스하는 큐브나 이퀄라이저 스타일 막대 시각화 같은 반응형 비주얼을 구동할 수 있습니다.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

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

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.decentraland.org/creator/content-creator-ko/sdk7/3d/sounds.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
