protected override void OnCreateElement(Segments.Image segment, FSNSnapshot.Layer layer, SnapshotElems.Image elemCreated) { base.OnCreateElement(segment, layer, elemCreated); if (segment.combinedImgPath != null) // 조합 이미지를 사용하는 경우 { var combimg = FSNResourceCache.Load <FSNCombinedImage>(FSNResourceCache.Category.Script, segment.combinedImgPath); if (combimg == null) { Debug.LogErrorFormat("조합 이미지 파일을 열 수 없습니다. : {0}", segment.texturePath); } elemCreated.combimg = combimg; // 실행 순서 문제 때문에 initial/finalstate의 텍스쳐를 직접 세팅해줘야함 (initial state가 이미 초기화된 상태, 값이 자동으로 복사되지 않음) elemCreated.InitialState.combimg = combimg; elemCreated.FinalState.combimg = combimg; } else { // 일반 텍스쳐를 사용하는 경우 var texture = FSNResourceCache.Load <Texture2D>(FSNResourceCache.Category.Script, segment.texturePath); if (texture == null) { Debug.LogErrorFormat("텍스쳐 파일을 열 수 없습니다. : {0}", segment.texturePath); } elemCreated.texture = texture; // 실행 순서 문제 때문에 initial/finalstate의 텍스쳐를 직접 세팅해줘야함 (initial state가 이미 초기화된 상태, 값이 자동으로 복사되지 않음) elemCreated.InitialState.texture = texture; elemCreated.FinalState.texture = texture; } var pivotVec = Segments.Image.ConvertPivotPresetToVector(segment.pivot); elemCreated.pivot = pivotVec; elemCreated.InitialState.pivot = pivotVec; elemCreated.FinalState.pivot = pivotVec; }
/// <summary> /// 리소스 로더를 설치 /// </summary> public static void InstallLoaders() { if (s_loaderInstalled) // 로더를 이미 설치한 경우엔 무시 { return; } s_loaderInstalled = true; FSNResourceCache.InstallLoader <SpriteSheet>(new SpriteSheetLoader()); // 스프라이트 시트 로더 FSNResourceCache.InstallLoader <FSNCombinedImage>(new Loader()); // FSNCombinedImage 로더 }
public override void Initialize() { // 필수 요소 설치 FSNResourceCache.InstallLoader <LibSequentia.Data.Track>(new LibSequentia.TrackLoader()); FSNResourceCache.InstallLoader <LibSequentia.Data.TransitionScenario>(new LibSequentia.TransitionScenarioLoader()); LibSequentia.ScriptCommands.Install(); m_layerID = c_layerID; // 레이어 번호 강제 지정 acceptClearCommand = false; // 전체 클리어 명령에 반응하지 않게 한다. (컨트롤 오브젝트가 사라지면 안됨) Debug.Log("FSNLibSequentiaModule installed"); }
protected override void OnCreateElement(Segments.Sound segment, FSNSnapshot.Layer layer, SnapshotElems.Sound elemCreated) { base.OnCreateElement(segment, layer, elemCreated); var clip = FSNResourceCache.Load <AudioClip>(FSNResourceCache.Category.Script, segment.clipPath); elemCreated.clip = clip; elemCreated.InitialState.clip = clip; // 실행 순서 문제 때문에 initial/finalstate의 텍스쳐를 직접 세팅해줘야함 elemCreated.FinalState.clip = clip; elemCreated.looping = segment.looping; elemCreated.InitialState.looping = segment.looping; elemCreated.FinalState.looping = segment.looping; }
protected override void OnCreateElement(Segments.GObject segment, FSNSnapshot.Layer layer, SnapshotElems.GObject elemCreated) { base.OnCreateElement(segment, layer, elemCreated); var prefab = FSNResourceCache.Load <GameObject>(FSNResourceCache.Category.Script, segment.prefabPath); if (prefab == null) { Debug.LogErrorFormat("프리팹을 열 수 없습니다. : {0}", segment.prefabPath); } elemCreated.prefab = prefab; elemCreated.InitialState.prefab = prefab; // 실행 순서 문제 때문에 initial/finalstate의 프리팹을 직접 세팅해줘야함 elemCreated.FinalState.prefab = prefab; }
/// <summary> /// json 파일을 통해 생성하기 /// </summary> /// <param name="path"></param> /// <returns></returns> public static FSNCombinedImage CreateFromResource(string path) { var res = Resources.Load <TextAsset>(path); if (res) { var combined = new FSNCombinedImage(); var sprdata = new Data(); combined.spriteData = sprdata; var json = new JSONObject(res.text); // JSON 파싱하기 var sprpath = json[c_json_spriteSheet].str; // 스프라이트 시트 var sprsheet = FSNResourceCache.Load <SpriteSheet>(FSNResourceCache.Category.Script, sprpath); var baseimage = json.GetField(c_json_baseSprite).str; // 바탕 이미지 sprdata.SetBaseSprite(sprsheet[baseimage]); json.GetField(c_json_subSprite, (subsprarr) => // 서브 스프라이트 { var list = subsprarr.list; var count = list.Count; for (int i = 0; i < count; i++) { var subspr = subsprarr[i]; var sprname = subspr[c_json_subSprite_name].str; var poslist = subspr[c_json_subSprite_pos].list; sprdata.AddSubSprite(sprsheet[sprname], (int)poslist[0].n, (int)poslist[1].n); } }); sprdata.BuildSubSpriteInfo(); // 서브 스프라이트 데이터 빌드 return(combined); } else { Debug.LogError("[FSNCombinedImage.CreateFromResource] Cannot load " + path); return(null); } }
protected override void OnLayerTransitionStart(FSNSnapshot.Layer toLayer) { //base.OnLayerTransitionStart(toLayer); var oneshotSounds = toLayer.GetCustomData(c_oneshotSoundData) as List <Segments.Sound>; if (oneshotSounds != null) // one-shot sound가 있는 경우에만, 트랜지션 시작시에 사운드 재생 { foreach (var sound in oneshotSounds) // 사운드마다 게임 오브젝트, 오디오소스 생성 등등... { var clip = FSNResourceCache.Load <AudioClip>(FSNResourceCache.Category.Script, sound.clipPath); var go = new GameObject("Sound oneshot"); go.transform.SetParent(ObjectRoot, false); var source = go.AddComponent <AudioSource>(); source.volume = sound.volume; source.panStereo = sound.panning; source.PlayOneShot(clip); Destroy(go, clip.length + 0.1f); // 오디오 재생 길이만큼만 게임 오브젝트 유지 } } }
/// <summary> /// 스크립트 실행 /// </summary> /// <param name="filepath"></param> /// <param name="session">실행 중에 사용할 Session. 지정하지 않을 경우 새 세션을 사용</param> /// <param name="snapshotIndex">불러오기 시에만 사용. 시작할 Snapshot Index를 지정</param> public void RunScript(string filepath, ExecuteType exeType = ExecuteType.NewStart, int snapshotIndex = 0) { FSNResourceCache.StartLoadingSession(FSNResourceCache.Category.Script); // 리소스 로딩 세션 시작 if (exeType == ExecuteType.NewStart) // 새 세션을 열어야하는 경우 미리 세션 생성하기 (새 게임) { m_seqEngine.PrepareNewSession(); } FSNScriptSequence scriptSeq = FSNScriptSequence.Parser.FromAsset(filepath, m_seqEngine.CurrentSession); // 스크립트 해석 // TODO : header 적용, 여기에 코드를 삽입하는 것이 맞는지는 잘 모르겠음. 리팩토링이 필요할수도. // 인게임 세팅 var stchain = new FSNInGameSetting.Chain(FSNInGameSetting.DefaultInGameSetting); // 디폴트 속성을 베이스로 chain 만들기 foreach (var pair in scriptSeq.Header.InGameSettings) { var alias = FSNInGameSetting.ConvertPropertyNameAlias(pair.Key); stchain.SetPropertyByString(alias, pair.Value); } m_inGameSetting = stchain.Freeze(); // 속성값 고정, 현재 엔진의 디폴트 속성을 덮어씌운다. // var sshotSeq = FSNSnapshotSequence.Builder.BuildSnapshotSequence(scriptSeq); // Snapshot 시퀀스 생성 FSNResourceCache.EndLoadingSession(); // 리소스 로딩 세션 종료 bool overwriteScriptInfoToSession = exeType != ExecuteType.LoadFromSession; // 불러오기한 경우가 아니면 스크립트 정보를 세션에 덮어써야한다. m_seqEngine.StartSnapshotSequence(sshotSeq, overwriteScriptInfoToSession, snapshotIndex); // 실행 ControlSystem.ScriptLoadComplete(); // 스크립트 로딩 완료 이벤트 }
/// <summary> /// 프리로드 명령어 /// </summary> /// <param name="protocol"></param> static void Preload(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { FSNResourceCache.Load <LibSequentia.Data.Track>(FSNResourceCache.Category.Script, protocol.parameters[0]); }
protected override void UpdateComponentParam(string to) { if (to == null) { return; } Debug.Log("parameter in : " + to); // 파싱해서 LibSequentia의 메세지로 보낸다. // 형식 : 현재 트랙 경로, 현재 트랙 스텝[, 새 트랙 경로, 새 트랙 스텝] var lsengine = LibSequentiaMain.instance; var ctrl = lsengine.stepControl; var split = to.Split(','); if (split.Length == 2) // 일반 재생 { var curtrpath = split[0].Trim(); var cur = new StepState() { curtrack = FSNResourceCache.Load <LibSequentia.Data.Track>(FSNResourceCache.Category.Script, curtrpath), step = int.Parse(split[1].Trim()), }; if (!m_reverse && cur.step == 0 || m_reverse && cur.step == (cur.curtrack.sectionCount + 1) * 2) { // 정방향일 때 스텝이 0이거나 역방향일 때 (섹션수+1)*2 스텝일 경우엔 재생하지 않고 무시해준다. (각 방향의 끝점으로 갔을 때 재생 중지를 하기 위한 스텝임) } else { if (!lsengine.isPlaying) // 재생중이 아닐 때는 트랙 새로 올리기 { ctrl.StartWithOneTrack(cur.curtrack, cur.step, m_reverse); UpdateTension(m_tension); // 파라미터 초기화 UpdateSongTransition(m_songTrans); } else { // 재생중일 때는 스텝 변경 메세지 (1트랙짜리) // TODO : 스테이트가 복잡해서 실수를 최대한 막기 위해 불필요한 코드들을 작성함. 나중에 줄여야함. if (m_reverse == false) // (정방향) { ctrl.StepMove(cur.step, -1, m_reverse); } else { // (역방향) ctrl.StepMove(cur.step, -1, m_reverse); } } } s_prevState = cur; // 현재 상태 저장 } else if (split.Length >= 4) // 트랙 전환 재생 { var curtrpath = split[0].Trim(); var newtrpath = split[2].Trim(); var tscenpath = split.Length >= 5? split[4].Trim() : ((FSNLibSequentiaModule)ParentModule).defaultTransitionScenarioPath; var cur = new StepState() { curtrack = FSNResourceCache.Load <LibSequentia.Data.Track>(FSNResourceCache.Category.Script, curtrpath), step = int.Parse(split[1].Trim()), newtrack = FSNResourceCache.Load <LibSequentia.Data.Track>(FSNResourceCache.Category.Script, newtrpath), newstep = int.Parse(split[3].Trim()), tscen = FSNResourceCache.Load <LibSequentia.Data.TransitionScenario>(FSNResourceCache.Category.Script, tscenpath) }; if (!lsengine.isPlaying) // 재생중이 아닐 때는 트랙 새로 올리기 { m_reverse = false; // 트랙 두 개가 갑자기 올라가는 경우는 로딩 상황뿐 : 정방향 진행 상태 ctrl.StartWithTwoTrack(cur.curtrack, cur.step, cur.newtrack, cur.newstep, cur.tscen); UpdateTension(m_tension); // 파라미터 초기화 UpdateSongTransition(m_songTrans); } else { // 재생중일 때는 스텝 변경 메세지 (2트랙짜리, 곡 전환) // TODO : 스테이트가 복잡해서 실수를 최대한 막기 위해 불필요한 코드들을 작성함. 나중에 줄여야함. if (m_reverse == false) // (정방향) { if (cur.newtrack != null && s_prevState.newtrack == null) { m_newTrackReverse = m_reverse; ctrl.StepMove(cur.step, cur.newtrack, cur.tscen, cur.newstep, m_reverse); } else if (m_newTrackReverse && s_prevState.newstep == 1) { // 특수 케이스 처리 : 이전에 역방향으로 다음 트랙으로 넘어가는 자연 진행을 건 경우. // 새 트랙을 다시 올려줘야한다. m_newTrackReverse = m_reverse; ctrl.StepMove(cur.step, cur.newtrack, cur.tscen, cur.newstep, m_reverse); } else if (cur.newtrack != null && s_prevState.newtrack != null) { if (m_newTrackReverse) { ctrl.StepMove(cur.newstep, cur.newtrack, cur.tscen, cur.step, m_reverse); } else { ctrl.StepMove(cur.step, cur.newtrack, cur.tscen, cur.newstep, m_reverse); } } else { ctrl.StepMove(cur.step, cur.newstep, m_reverse); } } else { // (역방향) if (cur.newtrack != null && s_prevState.newtrack == null) { m_newTrackReverse = m_reverse; ctrl.StepMove(cur.newstep, cur.curtrack, cur.tscen, cur.step, m_reverse); } else if (!m_newTrackReverse && s_prevState.newstep == 3) { // 특수 케이스 처리 : 이전에 역방향으로 다음 트랙으로 넘어가는 자연 진행을 건 경우. // 새 트랙을 다시 올려줘야한다. m_newTrackReverse = m_reverse; ctrl.StepMove(cur.newstep, cur.curtrack, cur.tscen, cur.step, m_reverse); } else if (cur.newtrack != null && s_prevState.newtrack != null) { if (m_newTrackReverse) { ctrl.StepMove(cur.newstep, cur.curtrack, cur.tscen, cur.step, m_reverse); } else { ctrl.StepMove(cur.step, cur.curtrack, cur.tscen, cur.newstep, m_reverse); } } else { ctrl.StepMove(cur.step, cur.newstep, m_reverse); } } } s_prevState = cur; // 현재 상태 저장 } else { // Error Debug.LogError("wrong parameter : " + to); } }