유니티 스크립트
2015.08.24 23:31

구간 루프 음악 스크립트

조회 수 230 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
using UnityEngine;
using System.Collections.Generic;
using System;

/// <summary>
/// 구간 루프를 지원하는 배경음악 스크립트입니다.
/// </summary>
public class SectionLoopingMusic : MonoBehaviour
{
    #region Inspector
    [Space(8)]
    [SerializeField]
    [Tooltip("구간 루프를 적용시킬 AudioClip입니다.")]
    private AudioClip audioClip;
    [Space(8)]
    [SerializeField]
    [Tooltip("로딩후 바로 재생합니다.")]
    private bool playAfterLoad;
    [Space(8)]
    [SerializeField]
    [Tooltip("루프 섹션이 시작될 초단위의 지점입니다.")]
    private float loopSectionStartPoint;
    [SerializeField]
    [Tooltip("루프 섹션이 끝날 초단위의 지점입니다.")]
    private float loopSectionEndPoint;
    #endregion

    #region Member variable
    AudioSource audioSource;
    float[] audioBuffer;
    int position;
    int loopStartPoint;
    int loopEndPoint;
    #endregion

    #region Property
    /// <summary>
    /// 현재 AudioClip 인스턴스를 가져옵니다.
    /// </summary>
    /// <remarks>
    /// 현재 재생중인 AudioClip을 변경하려면 <seealso cref="Renew(AudioClip, float)"/>를 확인하세요.
    /// </remarks>
    public AudioClip AudioClip
    {
        get
        {
            return this.audioClip;
        }
    }
    /// <summary>
    /// 루프 구간 시작 지점을 가져옵니다.
    /// </summary>
    /// <remarks>
    /// 단위는 '초'입니다.
    /// 루프 구간 종료 지점을 가져오려면 <seealso cref="LoopSectionEndPoint"/>를 참조하세요.
    /// </remarks>
    public float LoopSectionStartPoint
    {
        get
        {
            return this.loopSectionStartPoint;
        }
    }
    /// <summary>
    /// 루프 구간 종료 지점을 가져옵니다.
    /// </summary>
    /// <remarks>
    /// 단위는 '초'입니다.
    /// 루프 구간 시작 지점을 가져오려면 <seealso cref="LoopSectionStartPoint"/>를 참조하세요.
    /// </remarks>
    public float LoopSectionEndPoint
    {
        get
        {
            return this.loopSectionEndPoint;
        }
    }
    /// <summary>
    /// 진행 시간을 가져오거나 설정합니다.
    /// </summary>
    public float TimePosition
    {
        get
        {
            return this.position / this.audioBuffer.Length * this.audioClip.length;
        }
        set
        {
            this.position = (int)(value * this.audioBuffer.Length / this.audioClip.length);
        }
    }
    /// <summary>
    /// 현재 버퍼의 위치를 가져오거나 설정합니다.
    /// </summary>
    public int Position
    {
        get
        {
            return this.position;
        }
        set
        {
            if (value < audioBuffer.Length || value >= 0)
            {
                position = value;
            }
            else if (value < 0)
            {
                throw new System.ArgumentException("Value is lesser then 0.");
            }
            else
            {
                throw new System.ArgumentException("Value is larger then AudioClip.Samples * AudioClip.chennels.");
            }
        }
    }
    /// <summary>
    /// 현재 <see cref="UnityEngine.AudioSource"/> 인스턴스를 가져옵니다.
    /// </summary>
    /// <remarks>
    /// <see cref="UnityEngine.AudioSource"/>에 직접 접근하는 것은 안전하지 않습니다.
    /// 배경 음악 재생에 필요한 기능들은 거의 이 스크립트에서 제공하고 있습니다.
    /// 정말 필요한 경우에만 제한적으로 접근하십시오.
    /// </remarks>
    [Obsolete("AudioSource에 직접 접근 하는 것은 안전하지 않습니다.")]
    AudioSource AudioSource
    {
        get
        {
            return this.audioSource;
        }
    }
    #endregion

    #region Related to audio
    #region Method
    /// <summary>
    /// 재생합니다.
    /// </summary>
    public void Play()
    {
        this.audioSource.Play();
    }
    /// <summary>
    /// 중지합니다.
    /// </summary>
    public void Stop()
    {
        this.audioSource.Stop();
        this.position = 0;
    }
    /// <summary>
    /// 일시중지합니다.
    /// </summary>
    public void Pause()
    {
        this.audioSource.Pause();
    }
    #endregion

    #region Property
    /// <summary>
    /// 음의 크기를 설정하거나 가져옵니다.
    /// </summary>
    public float Volume
    {
        get
        {
            return this.audioSource.volume;
        }
        set
        {
            this.audioSource.volume = value;
        }
    }
    /// <summary>
    /// 음의 높이를 설정하거나 가져옵니다.
    /// </summary>
    public float Pitch
    {
        get
        {
            return this.audioSource.pitch;
        }
        set
        {
            this.audioSource.pitch = value;
        }
    }
    /// <summary>
    /// 음의 좌우 위치를 설정하거나 가져옵니다.
    /// </summary>
    public float Pan
    {
        get
        {
            return this.audioSource.panStereo;
        }
        set
        {
            this.audioSource.panStereo = value;
        }
    }
    #endregion
    #endregion

    #region Script control
    /// <summary>
    /// AudioClip과 루프 구간을 갱신합니다.
    /// </summary>
    /// <param name="audioClip">새 AudioClip 인스턴스입니다.</param>
    /// <param name="loopSectionStartPoint">새 루프 구간 시작 지점입니다. 단위는 '초'입니다.</param>
    /// <param name="loopSectionEndPoint">새 루프 구간 종료 지점입니다. 단위는 '초'입니다.</param>
    public void Renew(AudioClip audioClip, float loopSectionStartPoint, float loopSectionEndPoint)
    {
        this.audioSource.Stop();
        // 할당
        this.audioClip = audioClip;
        this.loopSectionStartPoint = loopSectionStartPoint;
        this.loopSectionEndPoint = loopSectionEndPoint;

        // 지역변수는 멤버변수보다 빠름.
        var channelCount = this.audioClip.channels;

        // 버퍼에 대한 루프 시작점을 연산해둔다.
        this.loopStartPoint = (int)((this.loopSectionStartPoint / this.audioClip.length) * this.audioClip.samples * channelCount);
        this.loopEndPoint = (int)((this.loopSectionEndPoint / this.audioClip.length) * this.audioClip.samples * channelCount);

        // 오디오 버퍼를 생성한다.
        this.audioBuffer = new float[this.audioClip.samples * channelCount];
        this.audioClip.GetData(audioBuffer, 0);

        // 제어할 AudioClip생성. 이후에는 audioClip에 접근하지 않는 것이 좋음.
        this.audioClip = AudioClip.Create(this.audioClip.name + "_loop", this.audioClip.samples, channelCount, this.audioClip.frequency, true, this.AudioRead);

        if (this.loopSectionEndPoint < this.loopSectionStartPoint)
        {
            this.loopSectionEndPoint = this.audioBuffer.Length;
        }

        this.audioSource.loop = true;
        this.audioSource.clip = this.audioClip;
        this.position = 0;
        if (this.playAfterLoad)
            this.Play();
    }
    /// <summary>
    /// 스크립트 초기화시 호출됩니다.
    /// </summary>
    /// <exception cref="System.NullReferenceException">
    /// AudioSource를 찾을 수 없을 경우 발생합니다.
    /// </exception>
    public void Start()
    {
        // AudioSource 컴포넌트 가져오기.
        this.audioSource = GetComponent<AudioSource>();
        if (audioSource == null)
        {
            throw new System.NullReferenceException("Not found AudioSource component.");
        }

        this.Renew(this.audioClip, this.loopSectionStartPoint, this.loopSectionEndPoint);
    }
    void AudioRead(float[] buffer)
    {
        var dataLength = buffer.Length;
        int bufferPosition = this.position;

        for (int i = 0; i < dataLength; i++)
        {
            buffer[i] = this.audioBuffer[bufferPosition];
            bufferPosition++;
            if (bufferPosition >= this.loopEndPoint)
            {
                bufferPosition = this.loopStartPoint;
            }
        }
        this.position = bufferPosition;
    }
    #endregion

}

시작후 알아서 이 스크립트 얻어내서 Play 메서드 호출시키시면 됩니다 ^^

?

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수 추천 수
288 RPGMV 플러그인 전투 도중 멤버교체가 가능해지는 플러그인 2 file Wailer 2016.01.13 1298 0
287 RPGMV 플러그인 Wave Filter 1 러닝은빛 2016.01.14 961 0
286 RPGMV 플러그인 Bind Pictures To Map (이미지 결합 플러그인) 3 file 이녕 2015.10.30 1048 0
285 RPGXP 스크립트 특정범위내에들어오면이동하기 2 file A.M.S 2010.10.14 3082 0
284 RPGVX Ace 스크립트 Custom Icon Sheets (커스텀 아이콘 적용 스크립트) plam 2016.01.10 470 0
283 RPGVX Ace 스크립트 Damage Popup by Dargor (데미지 수치 팝업하는 스크립트) plam 2016.01.10 612 0
282 RPGXP 스크립트 아이템소지 한계돌파 file A.M.S 2010.10.24 1964 0
281 RPGXP 스크립트 상점에서 상세정보보여주기 file A.M.S 2010.10.24 1818 0
280 RPGXP 스크립트 부드러운화면이동 file A.M.S 2010.10.24 2046 0
279 RPGXP 스크립트 직업명 표시 file A.M.S 2010.10.24 1787 0
278 RPGXP 스크립트 8방향이동 1 1 file A.M.S 2010.10.14 2151 0
277 RPGXP 스크립트 반칸이동 1 1 file A.M.S 2010.07.18 2183 0
276 RPGXP 스크립트 그레고리우스력 원리. 1 협객 2011.06.22 2506 0
275 RPGVX 스크립트 vx 전용 오토세이브<자동저장> 고진수 2011.08.31 2729 0
274 RPGVX Ace 스크립트 1인용메뉴 file A.M.S 2010.07.18 2608 0
273 RPGXP 스크립트 아이템획득 표시 1 file A.M.S 2010.10.14 2276 0
» 유니티 스크립트 구간 루프 음악 스크립트 맛난호빵 2015.08.24 230 0
271 RPGXP 스크립트 UNR (아시려나... ) - 상태 이상 2 file 동동주 2013.01.20 936 0
270 RPGVX 스크립트 vx 전용 오토세이브<자동저장> 고진수 2011.08.31 2800 0
269 RPGVX 스크립트 1인용메뉴 file A.M.S 2010.07.18 2560 0
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 15 Next
/ 15






[개인정보취급방침] | [이용약관] | [제휴문의] | [후원창구] | [인디사이드연혁]

Copyright © 1999 - 2016 INdiSide.com/(주)씨엘쓰리디 All Rights Reserved.
인디사이드 운영자 : 천무(이지선) | kernys(김원배) | 사신지(김병국)