static void Load(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newseg = new Segments.Control(); newseg.controlType = Segments.Control.ControlType.Load; newseg.SetLoadScriptData(protocol.parameters[0]); var newSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo(); newSegInfo.newSeg = newseg; newSegInfo.usePrevPeriod = true; newSegInfo.selfPeriod = true; protocol.PushSegment(newSegInfo); // Load를 하는 시점에서 해당 스크립트가 종료되므로, block var blockseg = new Segments.Control(); blockseg.controlType = Segments.Control.ControlType.Block; var blockSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = blockseg, usePrevPeriod = true }; protocol.PushSegment(blockSegInfo); }
/// <summary> /// BaseObject 계열의 세그먼트를 파싱해주는 함수 /// </summary> /// <typeparam name="SegT"></typeparam> /// <param name="defaultLayer"></param> /// <param name="seg"></param> /// <param name="protocol"></param> /// <param name="useObjName">오브젝트 이름을 사용할 것인지. 기본값은 true, false일 시 맨 첫번째 인자부터 파라미터 파싱을 시작한다.</param> static void _BaseObject_setupSegment <SegT>(int defaultLayer, SegT seg, FSNScriptSequence.Parser.ICommandGenerateProtocol protocol, bool useObjName = true) where SegT : Segments.Object { bool useDefaultLayer = !int.TryParse(protocol.parameters[0], out seg.layerID); // 첫번째 파라미터가 정수라면 지정한 레이어를 사용 if (useDefaultLayer) // 기본 레이어를 사용하는 경우, layerID는 기본값으로 { seg.layerID = defaultLayer; } if (useObjName) { seg.objectName = protocol.parameters[useDefaultLayer? 0 : 1]; } // int settingIndexStart = (useDefaultLayer? 1 : 2) - (useObjName? 0 : 1); // 세팅값이 시작되는 인덱스 int settingCount = (protocol.parameters.Length - settingIndexStart) / 2; // 세팅 pair 갯수 for (int i = 0; i < settingCount; i++) { var pName = protocol.parameters[settingIndexStart + i * 2]; var pParam = protocol.parameters[settingIndexStart + i * 2 + 1]; seg.SetPropertyFromScriptParams(pName, pParam); // 파라미터 하나씩 세팅 } }
/// <summary> /// 글 없는 선택지 표시 /// </summary> /// <param name="protocol"></param> static void Option_end_nontext(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var optionData = protocol.GetStateVar(c_key_optionData) as string[][]; if (optionData == null) { Debug.LogError("You can't make options without starting an option sequence."); } else { // 지정된 레이블로 점프하는 선택지 점프 세그먼트 var userChoiceSeg = new Segments.Control(); userChoiceSeg.controlType = Segments.Control.ControlType.SwipeOption; for (int i = 0; i < 4; i++) { var option = optionData[i]; if (option != null) { userChoiceSeg.SetSwipeOptionData((FSNInGameSetting.FlowDirection)i, optionData[i][0]); } } userChoiceSeg.SetNonTextOptionFlag(); // 글 없는 선택지로 지정 var userOptionControlSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = userChoiceSeg, selfPeriod = false, usePrevPeriod = false, }; protocol.PushSegment(userOptionControlSegInfo); // period 세그먼트 (선택지 표시를 위해서) var periodSeg = new Segments.Period(); periodSeg.isChaining = false; var periodSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = periodSeg }; protocol.PushSegment(periodSegInfo); // 처리 블록 세그먼트 var blockSeg = new Segments.Control(); blockSeg.controlType = Segments.Control.ControlType.Block; var blockControlSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = blockSeg, selfPeriod = false, usePrevPeriod = false, }; protocol.PushSegment(blockControlSegInfo); } }
static void ForceBack(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newseg = new Segments.Control(); newseg.controlType = Segments.Control.ControlType.ForceBack; var newSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo(); newSegInfo.newSeg = newseg; newSegInfo.usePrevPeriod = false; //?? newSegInfo.selfPeriod = true; //?? protocol.PushSegment(newSegInfo); }
static void TextClear(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newseg = new Segments.Text(); newseg.textType = Segments.Text.TextType.Clear; var newSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo(); newSegInfo.newSeg = newseg; newSegInfo.usePrevPeriod = true; newSegInfo.selfPeriod = false; protocol.PushSegment(newSegInfo); }
static void _fillSettingTable(Segments.Setting seg, FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var param = protocol.parameters; if (param != null) { int settingCount = param.Length / 2; // 2개 짝이 안맞는 파라미터값들은 버린다. for (int i = 0; i < settingCount; i += 2) { var name = FSNInGameSetting.ConvertPropertyNameAlias(param[i]); seg[name] = param[i + 1]; } } }
static void PopSetting(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newseg = new Segments.Setting(); newseg.settingMethod = Segments.Setting.SettingMethod.Pop; var newSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newseg, usePrevPeriod = true, }; protocol.PushSegment(newSegInfo); }
static void ReverseGoto(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newseg = new Segments.Control(); newseg.controlType = Segments.Control.ControlType.ReverseGoto; newseg.SetReverseGotoData(protocol.parameters[0]); var newSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo(); newSegInfo.newSeg = newseg; newSegInfo.usePrevPeriod = false; newSegInfo.selfPeriod = false; protocol.PushSegment(newSegInfo); }
static void _setupSegment(ScriptSegment seg, FSNScriptSequence.Parser.ICommandGenerateProtocol protocol, bool useObjName = true) { seg.layerID = FSNLibSequentiaModule.c_layerID; seg.objectName = c_ctrlObjName; // int settingCount = (protocol.parameters.Length) / 2; // 세팅 pair 갯수 for (int i = 0; i < settingCount; i++) { var pName = protocol.parameters[i * 2]; var pParam = protocol.parameters[i * 2 + 1]; seg.SetPropertyFromScriptParams(pName, pParam); // 파라미터 하나씩 세팅 } }
static void UnityCall_ShowSaveDialog(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newCallSeg = new Segments.Control(); newCallSeg.controlType = Segments.Control.ControlType.UnityCall; newCallSeg.SetUnityCallData("__fsnengine_ShowSaveDialog", protocol.parameters); protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newCallSeg, usePrevPeriod = false, selfPeriod = false }); }
static void Image_final(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newImageSeg = new Segments.Image(); newImageSeg.command = Segments.Object.CommandType.SetFinal; _Image_setupSegment(newImageSeg, protocol); // 셋업 protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newImageSeg, usePrevPeriod = true, selfPeriod = false }); }
static void Sound_end(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newObjectSeg = new Segments.Sound(); newObjectSeg.command = Segments.Object.CommandType.Remove; _Sound_setupSegment(newObjectSeg, protocol); // 셋업 protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newObjectSeg, usePrevPeriod = true, selfPeriod = false }); }
static void Set(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newCtrlSeg = new ScriptSegment(); newCtrlSeg.command = Segments.Object.CommandType.SetKey; _setupSegment(newCtrlSeg, protocol); // 셋업 protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newCtrlSeg, usePrevPeriod = true, selfPeriod = false }); }
static void Delay(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newseg = new Segments.Control(); newseg.controlType = Segments.Control.ControlType.Delay; newseg.SetDelay(float.Parse(protocol.parameters[0])); var newSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newseg, usePrevPeriod = false, selfPeriod = true }; protocol.PushSegment(newSegInfo); }
static void Sound_oneshot(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newObjectSeg = new Segments.Sound(); newObjectSeg.command = Segments.Object.CommandType.Custom; //_Sound_setupSegment(newObjectSeg, protocol); // 셋업 _BaseObject_setupSegment <Segments.Sound>((int)FSNSnapshot.PreDefinedLayers.Sound, newObjectSeg, protocol, false); // 원샷 사운드는 오브젝트 이름을 지정하지 않는다. protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newObjectSeg, usePrevPeriod = true, selfPeriod = false }); }
static void ConditionJump_IfValueLesserThan(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newCallSeg = new Segments.Control(); newCallSeg.controlType = Segments.Control.ControlType.ConditionJump; newCallSeg.EnqueueConditionJumpData("__fsnengine_CheckValueIsLesserThan", protocol.parameters[0], protocol.parameters[1]); newCallSeg.SetConditionJumpLabel(protocol.parameters[2]); protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newCallSeg, usePrevPeriod = false, selfPeriod = false }); }
const string c_key_optionTitle = "optionTitleText"; // 선택지 텍스트 static void Option_start(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { // 선택지 시작에서는 세그먼트를 직접 만들지 않는다. if (protocol.GetStateVar(c_key_optionData) != null) { Debug.LogError("You can't make other options without finishing previous option sequence."); } else { var options = new string[4][]; protocol.SetStateVar(c_key_optionData, options); // 선택지 방향 -> 라벨 배열 var text = protocol.parameters.Length > 0? protocol.parameters[0] : ""; // 텍스트를 지정하지 않았을 시 빈 문자열로 protocol.SetStateVar(c_key_optionTitle, text); // 선택지 타이틀 지정 } }
static void _addOptions(FSNInGameSetting.FlowDirection dir, FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var data = protocol.GetStateVar(c_key_optionData) as string[][]; if (data == null) { Debug.LogError("You can't make options without starting an option sequence."); } else { // 0번째 인덱스는 점프할 레이블, 1번째 인덱스는 텍스트 string text = protocol.parameters.Length > 1? protocol.parameters[1] : ""; // 텍스트가 지정되지 않았을 때는 빈 문자열로 대체 data[(int)dir] = new string[2] { protocol.parameters[0], text }; } }
/// <summary> /// 스크립트 안에서 사용하기 전에 호출해야함. /// 실제로는 레이어에 LibSequentia를 컨트롤할 오브젝트를 생성하는 역할을 한다. /// </summary> /// <param name="protocol"></param> static void Ready(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newCtrlSeg = new ScriptSegment(); newCtrlSeg.command = Segments.Object.CommandType.Create; _setupSegment(newCtrlSeg, protocol); // 셋업 // 현재 LibSequentia 엔진의 상태를 가져와 세팅해준다 newCtrlSeg.tension = LibSequentiaMain.instance.tension; newCtrlSeg.songTrans = LibSequentiaMain.instance.songTransition; protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newCtrlSeg, usePrevPeriod = true, selfPeriod = false }); }
static void UnityCall(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newCallSeg = new Segments.Control(); newCallSeg.controlType = Segments.Control.ControlType.UnityCall; string funcname; // 함수 이름 string [] param; // 함수 파라미터 (두번째부터 끝까지) SplitParams_SingleList(protocol.parameters, out funcname, out param); newCallSeg.SetUnityCallData(funcname, param); protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newCallSeg, usePrevPeriod = false, // ? ... 실제 사용 양상에 따라서 정해줘야할듯... 일단 함수콜이 출력에 영향을 미치지는 않으므로 false로 해둠. selfPeriod = false }); }
//------------------------------------------------------------------------------------ static void ConditionJump_UnityCall(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var newCallSeg = new Segments.Control(); newCallSeg.controlType = Segments.Control.ControlType.ConditionJump; string funcname; // 함수 이름 string [] param; // 함수 파라미터 (두번째부터 끝에서 두번째까지) string label; // 맨 마지막은 점프할 레이블 SplitParams_SingleListSingle(protocol.parameters, out funcname, out param, out label); newCallSeg.EnqueueConditionJumpData(funcname, param); newCallSeg.SetConditionJumpLabel(label); protocol.PushSegment(new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newCallSeg, usePrevPeriod = false, selfPeriod = false }); }
/// <summary> /// 프리로드 명령어 /// </summary> /// <param name="protocol"></param> static void Preload(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { FSNResourceCache.Load <LibSequentia.Data.Track>(FSNResourceCache.Category.Script, protocol.parameters[0]); }
static void Option_down(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { _addOptions(FSNInGameSetting.FlowDirection.Down, protocol); }
static void _Object_setupSegment(Segments.GObject seg, FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { _BaseObject_setupSegment <Segments.GObject>((int)FSNSnapshot.PreDefinedLayers.Object_Default, seg, protocol); }
static void _Sound_setupSegment(Segments.Sound seg, FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { _BaseObject_setupSegment <Segments.Sound>((int)FSNSnapshot.PreDefinedLayers.Sound, seg, protocol); }
/// <summary> /// 일반 선택지 표시 /// </summary> /// <param name="protocol"></param> static void Option_end(FSNScriptSequence.Parser.ICommandGenerateProtocol protocol) { var optionData = protocol.GetStateVar(c_key_optionData) as string[][]; if (optionData == null) { Debug.LogError("You can't make options without starting an option sequence."); } else { var newOptionTextSeg = new Segments.Text(); newOptionTextSeg.text = protocol.GetStateVar(c_key_optionTitle) as string; newOptionTextSeg.textType = Segments.Text.TextType.Options; // 선택지 선택 후 해당 선택지를 잠깐 보여주기 위해서, // 가상 Label을 추가한 뒤 LastOption 텍스트 출력, 이후 원래 Label로 점프하는 추가 시퀀스를 만든다. newOptionTextSeg.optionTexts = new string[4]; var optionTransitionLabels = new string[4]; // 트랜지션용 임시 라벨 목록 for (int i = 0; i < 4; i++) { var option = optionData[i]; if (option != null) { optionTransitionLabels[i] = option[0] + "__transition"; newOptionTextSeg.optionTexts[i] = option[1]; } } // 선택지 텍스트 세그먼트 푸시 var newOptionTextSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = newOptionTextSeg, selfPeriod = false, usePrevPeriod = true, }; protocol.PushSegment(newOptionTextSegInfo); // 임시 레이블로 점프하는 선택지 점프 세그먼트 var userChoiceSeg = new Segments.Control(); userChoiceSeg.controlType = Segments.Control.ControlType.SwipeOption; for (int i = 0; i < 4; i++) { userChoiceSeg.SetSwipeOptionData((FSNInGameSetting.FlowDirection)i, optionTransitionLabels[i]); } var userOptionControlSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = userChoiceSeg, selfPeriod = false, usePrevPeriod = false, }; protocol.PushSegment(userOptionControlSegInfo); // period 세그먼트 (선택지 표시를 위해서) var periodSeg = new Segments.Period(); periodSeg.isChaining = false; var periodSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = periodSeg }; protocol.PushSegment(periodSegInfo); // 처리 블록 세그먼트 var blockSeg = new Segments.Control(); blockSeg.controlType = Segments.Control.ControlType.Block; var blockControlSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = blockSeg, selfPeriod = false, usePrevPeriod = false, }; protocol.PushSegment(blockControlSegInfo); // 각 임시 라벨에 해당하는 시퀀스 만들기 // for (int i = 0; i < 4; i++) { if (optionTransitionLabels[i] == null) // 라벨이 지정된 경우만 진행 { continue; } // 라벨 (soft 라벨 모드를 사용한다) var labelSeg = new Segments.Label(); labelSeg.labelName = optionTransitionLabels[i]; labelSeg.labelType = Segments.Label.LabelType.Soft; var labelSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = labelSeg, }; protocol.PushSegment(labelSegInfo); // LastOption 텍스트 var lastOptionSeg = new Segments.Text(); lastOptionSeg.textType = Segments.Text.TextType.LastOption; var lastOptionSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = lastOptionSeg }; protocol.PushSegment(lastOptionSegInfo); // 원래 label로 점프 var gotoSeg = new Segments.Control(); gotoSeg.controlType = Segments.Control.ControlType.Goto; gotoSeg.SetGotoData(optionData[i][0]); var gotoSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = gotoSeg }; protocol.PushSegment(gotoSegInfo); // Period (chaining을 사용한다) var chainPeriodSeg = new Segments.Period(); chainPeriodSeg.isChaining = true; var chainPeriodSegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo() { newSeg = chainPeriodSeg }; protocol.PushSegment(chainPeriodSegInfo); // 블럭 추가 protocol.PushSegment(blockControlSegInfo); } } }