유니티 스크립트
2015.08.24 23:31

구간 루프 음악 스크립트

조회 수 242 추천 수 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 메서드 호출시키시면 됩니다 ^^

?

  1. 구간 루프 음악 스크립트

    Date2015.08.24 Category유니티 스크립트 By맛난호빵 Views242 Votes0
    Read More
  2. [C#] 보안 64비트 정수

    Date2016.01.04 Category유니티 스크립트 By맛난호빵 Views389 Votes0
    Read More
  3. Custom Icon Sheets (커스텀 아이콘 적용 스크립트)

    Date2016.01.10 CategoryRPGVX Ace 스크립트 Byplam Views478 Votes0
    Read More
  4. [JS] 세이브 갯수를 20개에서 변경하기.

    Date2015.10.26 CategoryRPGMV 플러그인 By천무 Views517 Votes0
    Read More
  5. Ace로 만든 습작 랜덤 위치로 지형변환.

    Date2014.10.04 CategoryRPGVX Ace 스크립트 ByJunkMan Views519 Votes0
    Read More
  6. 배틀미스트(전투중포그효과) 플러그인

    Date2015.10.26 CategoryRPGMV 플러그인 By파란별빛 Views547 Votes0
    Read More
  7. RPG MV 와 AJAX를 이용한 웹 통신 플러그인

    Date2015.10.26 CategoryRPGMV 플러그인 By파란별빛 Views556 Votes0
    Read More
  8. Universal Message System 1.8.0 by ccoa

    Date2013.10.01 CategoryRPGXP 스크립트 By Views584 Votes0
    Read More
  9. Switchless Common Events

    Date2013.10.01 CategoryRPGXP 스크립트 By Views591 Votes0
    Read More
  10. Initial Switches and Variables

    Date2013.10.01 CategoryRPGXP 스크립트 By Views605 Votes0
    Read More
  11. 메뉴에서 실제시간 보는 스크립트

    Date2013.09.24 CategoryRPGXP 스크립트 By청담 Views609 Votes0
    Read More
  12. 현실 시간 변수 대입 플러그인

    Date2015.10.26 CategoryRPGMV 플러그인 By최빛빛 Views612 Votes1
    Read More
  13. Random Dungeon Generator - Random Cave

    Date2014.10.08 CategoryRPGVX Ace 스크립트 ByJunkMan Views618 Votes0
    Read More
  14. Damage Popup by Dargor (데미지 수치 팝업하는 스크립트)

    Date2016.01.10 CategoryRPGVX Ace 스크립트 Byplam Views625 Votes0
    Read More
  15. 파일 존재의 유무 체크

    Date2013.09.30 CategoryRPGVX Ace 스크립트 By휴리드 Views643 Votes0
    Read More
  16. 한글조합입력기(영어가능)

    Date2019.11.10 CategoryRPGXP 스크립트 By조규진1 Views651 Votes0
    Read More
  17. 텍스트 파일생성

    Date2013.09.30 CategoryRPGVX Ace 스크립트 By휴리드 Views658 Votes0
    Read More
  18. 셀프 스위치 조작

    Date2013.09.29 CategoryRPGXP 스크립트 By청담 Views659 Votes0
    Read More
  19. 레벨업시 전회복 스크립트

    Date2013.09.24 CategoryRPGXP 스크립트 By청담 Views699 Votes0
    Read More
  20. 프리로드 매니저 (소재를 미리 불러서 게임진행을 빠르게)

    Date2015.10.26 CategoryRPGMV 플러그인 By파란별빛 Views701 Votes0
    Read More
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(김원배) | 사신지(김병국)