[Unity] 성우 하카슨이'벼락의 날'에 참여했습니다.

2016/26,27의 성우 하카슨에 참가했다.https://rakutenwebservice.doorkeeper.jp/events/37786
그래서 나는 붉은 해를 터뜨리는 게임을 만들었다.
타모스 씨가 ADX2를 사용하는 소리 주변의 작업 흐름에 대한 기사를 썼기 때문에 자신도 이 기사를 쓰고 싶어했다.

  • tatmos의 보도.꼭 보십시오.
  • http://qiita.com/tatmos/items/847ae3b57cebb627cce8
  • 게임 비디오

  • 기획 자료
  • http://www.slideshare.net/hogemaru_/rakkathon02-breakdays
  • 게임 내용


    이 캐릭터는 간단한 RPG가 많이 나온다.
    게임 디자인의 특징은 최대한 가볍게 두드리면 진행할 수 있다는 것이다.

    소리의 수록과 소리 주위의 작업


    이 보도는 소리 주위의 업무에 대해 설명하고 싶다.
    이번 하카슨은 성우로부터 사운드를 수록할 수 있어 사운드 파일이 대거 나올 것으로 예상된다.그래서 ADX2로 작전을 했습니다.나는 예전에 ADX2를 조사해 보고 업무 흐름을 알았기 때문에 CRI의 URL만 빈손인 Y군이라는 멤버에게 맡기고 모든 것을 맡겼다.
    http://www.adx2le.com/
    소리 주위에 무엇이 수록되어 있는지 구글의 Spread Sheet으로 다음과 같이 정리했다.

    우선, 최초로 나에게 건네준 파형은 웨이브 파일이다.이것은 수록된 모든 소리를 하나의 문서로 모으는 인수인계 방법이다.
    우선 그 파일을 하나하나 잘라내는 작업을 부탁했는데 힘들어 보이네요.(헤트고트 w)
    제작된 팀 리스트(ADX2 용어)는 다음 3개입니다.
  • SE
  • 파형: 15개
  • VOICE
  • 파형: 90개(30개x3명)
  • BGM
  • 파형: 9개
  • 워크플로우는 다음과 같습니다.
    Y군은 ADX2가 처음이었지만 다시 하는 일이 적고 순조롭다.
    소리의 창고와 게임 측의 프로젝트를 완전히 분리하는 것도 중점일 수 있다.우연히 기획용 서류의 창고를 만들었기 때문에 그 소리를 사용했다.이번에는 창고 하나로 다 완성하기가 좀 어려울 것 같아요.소리 파일이 커서.

    ADX 쪽 작업은 다음과 같은 느낌이다.

    웨이브 파일의 합계는 162MB입니다.
    최소 품질의 HCA로 압축하면 약 11MB 정도로 변해 6.8%의 압축률(삭감률 93.2%)이 된다
  • BGM
  • 9082KB
  • SE
  • 230KB
  • Voice
  • 1152KB
  • 파일 수가 이렇게 많으면 데이터 관리, 업무 분담, 압축률 등이 ADX2의 가치가 있다.

    수록 환경


    수록은 전문적인 시설이 아니라 일반적인 회의실이다.일부는 소리로 가득 찬 소리였는데, 나는 그것이 잘못 수록된 것이라고 생각한다.
    캐릭터 성격 등을 고려해 목소리를 낸 뒤 "어때요?"이렇게 물어보니 난처하다.다행이다. 나는 다른 문제에 대답할 수 없다.비교가 안 되면 좋고 나쁠 줄 모른다는 생각에 같은 소리를 3번 썼고, 그 다음에 좋은 걸 말하라는 방법.결국 그 방법으로 순조롭게 진행되었다.

    출처


    소스를 좀 말리면 CRI의 Example 프로젝트를 이해하고 사용하는 게 좋을 것 같아요.
    SoundManagerAdx2.cs
    using UnityEngine;
    using System.IO;
    using System.Collections;
    
    public class SoundManagerADX2 : MonoBehaviour {
    
        public CriAtomSource atomSourceBGM;
        public CriAtomSource atomSourceSE;
        public CriAtomSource atomSourceVOICE;
        public CriAtom criAtom;
    
        public float volume = 0.35f;
    
        void OnLevelWasLoaded(int level){
            StartCoroutine(initialize ());
        }
    
        // Use this for initialization
        IEnumerator Start () {
    
            StartCoroutine(initialize ());
            yield return null;
    
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    
        public void playSE(string cueSheet, string cueName)
        {
            atomSourceSE.Stop ();
            atomSourceSE.cueSheet = cueSheet;
            atomSourceSE.cueName = cueName;
            atomSourceSE.volume = volume;
            atomSourceSE.Play ();
        }
    
        public void playBGM(string cueSheet, string cueName)
        {
            atomSourceBGM.Stop ();
            atomSourceBGM.cueSheet = cueSheet;
            atomSourceBGM.cueName = cueName;
            atomSourceBGM.volume = volume;
            atomSourceBGM.loop = true;
            atomSourceBGM.Play ();
        }
    
        public void playVoice(string cueSheet, string cueName)
        {
            atomSourceVOICE.Stop ();
            atomSourceVOICE.cueSheet = cueSheet;
            atomSourceVOICE.cueName = cueName;
            atomSourceVOICE.volume = volume;
            atomSourceVOICE.Play ();
        }
    
        public void playVoiceNoStop(string cueSheet, string cueName)
        {
    
            atomSourceVOICE.cueSheet = cueSheet;
            atomSourceVOICE.cueName = cueName;
            atomSourceVOICE.volume = volume;
            atomSourceVOICE.Play ();
        }
    
    
        IEnumerator initialize()
        {
    
    
            if (gameObject.GetComponent<CriAtomSource> () == null) {
                atomSourceBGM = gameObject.AddComponent<CriAtomSource> ();
                atomSourceSE = gameObject.AddComponent<CriAtomSource> ();
                atomSourceVOICE = gameObject.AddComponent<CriAtomSource> ();
                DontDestroyOnLoad (gameObject);
            }
    
    
            string[] files = {"SE", "BGM", "Voice"};
    
    
            foreach (var file in files) {
                var cueSheets = CriAtom.GetCueSheet(file);
                if(cueSheets != null){
                    continue;
                }
                var file1 = Path.Combine (Path.Combine (CriWare.streamingAssetsPath, "ADX2"), file);
                var cueSheetName = Path.GetFileNameWithoutExtension (file1);
                var acbFilePath = file1 + ".acb";
                CriAtom.AddCueSheet (cueSheetName, acbFilePath, acbFilePath, null);
                CriAtom.GetAcb (cueSheetName);
            }
    
            yield return null;
    
    
        }
    }
    
    
    Singleton 모드 결합https://gist.github.com/tsubaki/e0406377a1b014754894
    아래와 같이 사용한다
    Sample.cs
    SoundManagerADX2.Instance.playVoice("Voice", "nomal_voice_jin_01");
    

    잡담


    ADX2를 유닛부터 활용할 때는 주변을 초기화하는 게 좀 어렵다고 생각했어요.별말씀이지만 우선 가볍게 건드리세요.
    먼저 CRIWARE, Initializer, ErrorHandler는 3개의 객체를 강제로 배치합니다.솔직히 말해서, 나는 이것이 좀 없다고 생각한다.매번 새로운 장면을 만들 때마다 세 개를 틀어야 하나요?내 생각엔
    원본 코드로 모든 것을 제어하는 것은 허용되지 않을 것 같습니다.Unity의 CRI가 아니라 원래 오디오 주변(Audio Source)은 구성 요소와 원본 코드 두 가지 측면에서 처리할 수 있기 때문에 그 정도는 아닌 것 같다.유니티 오디오 주변에 이상한 게임object를 강제로 배치하는 건 아니죠?나는 모두에게 같은 사용감을 주고 싶다.예를 들어 다음과 같이 CRIWARE는 넣지 않아도 되겠죠.같은 이니시에이터랑 에로핸들러도 없으면 되잖아.아니면 하나의 구성 요소로 정리하면 되잖아.적어도 세 개는'없다'를 넣어라.
    제멋대로 말해서 미안해요.원래는 공짜가 아니라 유료 제품인데 여러 가지 상황이 있다고 생각해요.
    sample2.cs
            var m = GameObject.Find ("CRIWARE");
            if (m == null) {
                m = new GameObject ("CRIWRE");
                DontDestroyOnLoad (m.gameObject);
            }
    
            if (m.GetComponent<CriAtom> () == null) {
                criAtom = m.GetComponent<CriAtom> ();
                string acfFilePath = Path.Combine (Path.Combine (CriWare.streamingAssetsPath, "ADX2"),"app.acf");
                CriAtomEx.RegisterAcf (null, acfFilePath);
            }
    

    최후


    소리를 둘러싼 예술 작업이 순조롭게 진행되어 만족스럽다.
    동영상을 보실 수 있다는 것을 알지만 이 게임은 아직 완성되지 않았기 때문에 완성하고 싶습니다.

    좋은 웹페이지 즐겨찾기