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);
    }
Example #2
0
    private void AddLastOptionText(FSNSnapshot.Layer layer, Segments.Text textSeg, IInGameSetting setting)
    {
        // TODO : 상하좌우 여백, 정렬 등도 따져야함
        // NOTE : 선택한 방향은 setting 쪽에 설정되어 오는 것으로...

        SnapshotElems.Text optionText = null;
        foreach (var elem in layer.Elements)                                                                                                    // * 이전 레이어를 전부 뒤져서 진행 방향이 같은 선택지 텍스트를 찾아온다
        {
            var textElem = elem as SnapshotElems.Text;
            if (textElem.type == SnapshotElems.Text.Type.OptionTexts && textElem.optionDir == setting.CurrentFlowDirection)
            {
                optionText = textElem;
                break;
            }
        }

        if (optionText != null)                                                                                                                                 // * 찾은 경우에 한해서...
        {
            // 텍스트를 새로 만드는 것이 아니라 기존 것을 변경한다.
            // PushTextsToDirection 에서는 이 시점의 LastOption텍스트는 건들지 않는다.

            var textSize    = CalculateTextSize(optionText.text, setting);
            var posToCenter = optionText.Position;

            TextPositionToCenter(ref posToCenter, textSize, optionText.optionDir, setting);             // 중앙 위치 맞추기

            optionText.Position = posToCenter;
            optionText.type     = SnapshotElems.Text.Type.LastOption;                                           // LastOption 타입으로 변경
            CopyCurrentToFinal(optionText);                                                                     // 임시 FinalState

            PushTextsToDirection(layer, setting.CurrentFlowDirection, Vector2.zero);                            // 기존 텍스트 일괄적으로 해당 방향으로 밀기 (내부 조건체크에 따라 LastOption은 이 타이밍에는 제외된다)
        }
        else
        {
            Debug.LogError("cannot find option text to direction : " + setting.CurrentFlowDirection.ToString());
        }
    }
Example #3
0
        /// <summary>
        /// 문자열으로 스크립트 파싱
        /// </summary>
        /// <param name="scriptData"></param>
        /// <returns></returns>
        public static FSNScriptSequence FromString(string scriptData, FSNSession session)
        {
            // 디버깅 세션 세팅
            FSNDebug.currentRuntimeStage = FSNDebug.RuntimeStage.Compile;

            var sequence = new FSNScriptSequence();

            sequence.OriginalScriptPath = "(string)";
            sequence.ScriptHashKey      = GenerateHashKeyFromScript(scriptData);                    // 해시키 생성해두기 (세이브 파일과 스크립트 파일 버전 체크용)

            // ===== FIRST PASS : 헤더 파일 먼저 해석 ==================================

            ProcessHeaders(scriptData, sequence, session);


            // ===== SECOND PASS : 나머지 스크립트 요소들 해석 =========================
            var strstream = new System.IO.StringReader(scriptData);

            // 스크립트 해석 상태값들
            CommandGenerateProtocol protocol = new CommandGenerateProtocol();

            // flags
            Segments.Period periodSeg         = null;                                                   // Period 세그먼트. 먼저 만들어놓고 있다가 적당한 때에 삽입한다. (스크립트와 실제 세그먼트 순서가 다르기 때문)
            bool            textMultilineMode = false;                                                  // 텍스트 여러줄 처리중인지 (//)
            string          multilineText     = "";                                                     // 멀티라인 모드에서, 텍스트 처리중일 때
            //

            // ** 스크립트 로드 후 첫번째 스냅샷에서 다시 이전으로 돌아가는 것은 불가능하므로, 맨 처음에 oneway 컨트롤 세그먼트를 추가해준다
            var onewayAtFirstSeg = new Segments.Control();

            onewayAtFirstSeg.controlType = Segments.Control.ControlType.Oneway;
            var onewaySegInfo = new FSNScriptSequence.Parser.GeneratedSegmentInfo()
            {
                newSeg = onewayAtFirstSeg
            };

            protocol.PushSegment(onewaySegInfo);
            //

            string line       = null;
            int    linenumber = 0;                           // 줄 번호

            while ((line = strstream.ReadLine()) != null)    // 줄 단위로 읽는다.
            {
                line = sequence.Header.Macros.Replace(line); // 정적 매크로 치환

                linenumber++;
                FSNDebug.currentProcessingScriptLine = linenumber;                      // 디버깅 정보 설정

                if (!textMultilineMode && line.Length == 0)                             // * 빈 줄은 스루. 단 여러줄 텍스트 모드일 경우 빈 줄에서는 여러줄 모드를 끝내게 한다.
                {
                    continue;
                }

                if (line.EndsWith(c_token_LineConcat))                                                  // * 여러줄 텍스트로 지정된 경우, 자동으로 여러줄 모드로. 해당 라인 붙이기
                {
                    textMultilineMode = true;

                    if (multilineText.Length > 0)                                                               // 이미 쌓여있는 텍스트가 있다면 공백 추가
                    {
                        multilineText += "\n";
                    }
                    multilineText += line.Substring(0, line.Length - c_token_LineConcat.Length);
                }
                else
                {
                    var pretoken = line.Length > 0? line.Substring(0, 1) : "";
                    switch (pretoken)                                                                                           // 앞쪽 토큰으로 명령 구분
                    {
                    case c_token_Comment:                                                                                       // * 주석
                        // 스루. 뭐 왜 뭐 주석인데 뭐
                        break;

                    case c_token_PreProcessor:                                                                                  // * 전처리 구문
                        // 프리프로세서는 첫번째 패스에서 처리함.
                        break;

                    case c_token_Command:                                                                                       // * 명령
                    {
                        var commandAndParam = line.Substring(1).Split(c_whiteSpaceArray, 2);                                    // 명령어 파라미터 구분
                        var command         = commandAndParam[0];
                        var paramStr        = commandAndParam.Length > 1? commandAndParam[1] : "";

                        CommandSegmentGenerateFunc genfunc = null;
                        s_aliasToSegFunction.TryGetValue(command, out genfunc);
                        if (genfunc == null)                                                                                                                                                                    // 등록된 명령어인지 체크
                        {
                            Debug.LogError("Unknown command : " + command);
                        }
                        else
                        {
                            protocol.parameters = ParseParameters(paramStr);
                            genfunc(protocol);
                        }
                    }
                    break;

                    case c_token_HardLabel:                                                                                     // * hard label
                    {
                        var labelSeg = new Segments.Label();
                        labelSeg.labelName = line.Substring(1);
                        labelSeg.labelType = Segments.Label.LabelType.Hard;

                        var segInfo = new GeneratedSegmentInfo();
                        segInfo.newSeg        = labelSeg;
                        segInfo.usePrevPeriod = true;                                                                   // Label 전에 period로 다 출력해야함
                        segInfo.selfPeriod    = false;
                        protocol.PushSegment(segInfo);
                    }
                    break;

                    case c_token_SoftLabel:                                                                                     // * soft label
                    {
                        var labelSeg = new Segments.Label();
                        labelSeg.labelName = line.Substring(1);
                        labelSeg.labelType = Segments.Label.LabelType.Soft;

                        var segInfo = new GeneratedSegmentInfo();
                        segInfo.newSeg        = labelSeg;
                        segInfo.usePrevPeriod = true;                                                                   // Label 전에 period로 다 출력해야함
                        segInfo.selfPeriod    = false;
                        protocol.PushSegment(segInfo);
                    }
                    break;

                    case c_token_Period:                                                                                        // * period
                        if (line.Length == 1)                                                                                   // . 한글자일 때 - 일반 period
                        {
                            if (periodSeg != null)                                                                              // * 이미 period 명령어가 대기중일 때, 기존 명령어를 먼저 처리한다
                            {
                                sequence.m_segments.Add(periodSeg);
                            }
                            periodSeg = new Segments.Period();
                        }
                        else if (line.Length == 2 && line[1].ToString() == c_token_Period)                                      // .. 으로 두 글자일 때 - 연결 period, 만약 period가 이전에 등장했다면 연결으로 변경
                        {
                            Segments.Period lastPeriodseg;

                            if (periodSeg != null)                                                                                                                      // 처리 안된 period가 있을 경우, 이것을 chaining으로 변경해준다
                            {
                                lastPeriodseg = periodSeg;
                            }
                            else if ((lastPeriodseg = sequence.m_segments[sequence.m_segments.Count - 1] as Segments.Period)
                                     .type == Segment.Type.Period)                                                                                              // 아닐 경우, 가장 마지막으로 추가된 세그먼트가 period를 chaining으로 변경한다
                            {
                                //
                            }
                            else
                            {                                                                                                                                                                   // 그도 아닐 경우 새로 period 생성
                                periodSeg     = new Segments.Period();
                                lastPeriodseg = periodSeg;
                            }

                            lastPeriodseg.isChaining = true;                                                                                                    // 선택한 period에 chaining속성 부여
                        }
                        else
                        {
                            Debug.LogError("invalid command... is it a period command?");
                        }
                        break;

                    case c_token_ForceText:
                    default:                                                                                                    // * 아무 토큰도 없음 : 텍스트
                    {
                        if (line.Length > 0 && line[0].ToString() == c_token_ForceText)                                         // 만약 강제 텍스트 토큰 (~) 이 붙어있었다면, 해당 토큰 제거
                        {
                            line = line.Substring(1);
                        }

                        multilineText += multilineText.Length > 0? "\n" + line : line;
                        var textSeg = new Segments.Text();
                        textSeg.text     = multilineText;
                        textSeg.textType = Segments.Text.TextType.Normal;

                        multilineText     = "";                                                 // 멀티라인 텍스트 보관되어있던 것을 초기화
                        textMultilineMode = false;

                        var segInfo = new GeneratedSegmentInfo();
                        segInfo.newSeg        = textSeg;
                        segInfo.usePrevPeriod = true;                                           // 출력 명령어임
                        segInfo.selfPeriod    = true;                                           // 스스로 period를 포함함
                        protocol.PushSegment(segInfo);
                    }
                    break;
                    }

                    GeneratedSegmentInfo newSegInfo = null;
                    while ((newSegInfo = protocol.PullSegment()) != null)                       // 새로 생성된 시퀀스 모두 처리
                    {
                        if (newSegInfo.usePrevPeriod && periodSeg != null)                      // * 선행 period를 먼저 처리해야하는 상황
                        {
                            periodSeg.scriptLineNumber = linenumber;                            // 줄번호 기록?
                            sequence.m_segments.Add(periodSeg);
                            periodSeg = null;
                        }

                        newSegInfo.newSeg.scriptLineNumber = linenumber;                                // 줄번호 기록
                        sequence.m_segments.Add(newSegInfo.newSeg);                                     // 시퀀스 추가
                        if (newSegInfo.newSeg.type == Segment.Type.Label)                               // 라벨일 경우 등록
                        {
                            sequence.RegisterLabelSegment();
                        }

                        if (newSegInfo.selfPeriod)                                                                              // * 방금 추가된 세그먼트가 period를 포함하는 개념이라면, period 대기시켜놓기
                        {
                            periodSeg = new Segments.Period();
                        }
                    }
                }
            }

            if (periodSeg != null)                                                                              // 끝날 때까지 처리되지 않은 period가 있다면 여기서 추가해준다
            {
                periodSeg.scriptLineNumber = linenumber;                                                        // 줄번호 기록?
                sequence.m_segments.Add(periodSeg);
                periodSeg = null;
            }

            // 디버깅 세션 세팅
            FSNDebug.currentRuntimeStage = FSNDebug.RuntimeStage.Runtime;

            return(sequence);
        }
    /// <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);
            }
        }
    }
Example #5
0
    private void ShowOptionTexts(FSNSnapshot.Layer layer, Segments.Text textSeg, IInGameSetting setting)
    {
        // TODO : 상하좌우 여백, 정렬 등도 따져야함

        Vector2 screenDim = FSNEngine.Instance.ScreenDimension;                 // (계산용) 화면 크기
        Vector3 fadePosOffset;

        switch (setting.CurrentFlowDirection)                                                   // 흐름 방향에 따라 이동 오프셋 세팅
        {
        case FSNInGameSetting.FlowDirection.Up:
            fadePosOffset = new Vector3(0, screenDim.y / 2);
            break;

        case FSNInGameSetting.FlowDirection.Down:
            fadePosOffset = new Vector3(0, -screenDim.y / 2);
            break;

        case FSNInGameSetting.FlowDirection.Right:
            fadePosOffset = new Vector3(screenDim.x / 2, 0);
            break;

        case FSNInGameSetting.FlowDirection.Left:
            fadePosOffset = new Vector3(-screenDim.x / 2, 0);
            break;

        default:
            throw new System.Exception("HUH???");
        }

        // 새 텍스트 엘레먼트 세팅 : 선택지 질문 텍스트

        var newTextSize = CalculateTextSize(textSeg.text, setting);

        var questionTextElem = new SnapshotElems.Text(setting);

        questionTextElem.text           = textSeg.text;
        questionTextElem.fontSize       = setting.FontSize;
        questionTextElem.Color          = Color.white;                //TODO
        questionTextElem.Alpha          = 1;
        questionTextElem.TransitionTime = setting.TextTransitionTime; //TODO
        questionTextElem.type           = SnapshotElems.Text.Type.OptionTexts;
        questionTextElem.MakeItUnique();

        questionTextElem.InitialState.Alpha = 0;
        questionTextElem.FinalState.Alpha   = 0;
        CopyCurrentToFinal(questionTextElem);                                                           // 임시 FinalState

        // 새 텍스트 엘레먼트 - 위치 세팅 (시작 위치만. 끝 위치는 프로세스 끝에 결정된다)
        var qtextPos = new Vector3(-newTextSize.x / 2f, newTextSize.y / 2f);

        ApplyCenterTextMargin(ref qtextPos, setting);                                           // 여백 지정

        questionTextElem.Position = qtextPos;
        questionTextElem.InitialState.Position = questionTextElem.Position - fadePosOffset;

        layer.AddElement(questionTextElem);                                                                     // 텍스트 엘리멘트 추가

        //
        int    dirIndex;
        string dirText;

        // 선택지 : 위쪽 (등장 위치는 아래쪽)
        dirIndex = (int)FSNInGameSetting.FlowDirection.Up;
        dirText  = textSeg.optionTexts[dirIndex];
        if (textSeg.optionTexts.Length - 1 >= dirIndex && !string.IsNullOrEmpty(dirText))
        {
            var upTextSize = CalculateTextSize(dirText, setting);

            var upTextElem = new SnapshotElems.Text(setting);

            upTextElem.text           = dirText;
            upTextElem.fontSize       = setting.FontSize;
            upTextElem.Color          = Color.white;                                  //TODO
            upTextElem.Alpha          = 1;
            upTextElem.TransitionTime = setting.TextTransitionTime;                   //TODO
            upTextElem.type           = SnapshotElems.Text.Type.OptionTexts;
            upTextElem.optionDir      = (FSNInGameSetting.FlowDirection)dirIndex;
            upTextElem.MakeItUnique();

            upTextElem.InitialState.Alpha = 0;
            upTextElem.FinalState.Alpha   = 0;
            CopyCurrentToFinal(upTextElem);                                                                     // 임시 FinalState

            // 새 텍스트 엘레먼트 - 위치 세팅 (시작 위치만. 끝 위치는 프로세스 끝에 결정된다)
            var tpos = new Vector3(upTextSize.x / 2f, -screenDim.y / 2f + upTextSize.y);
            ApplySideTextMargin(ref tpos, setting, FSNInGameSetting.FlowDirection.Up);
            upTextElem.Position = tpos;
            upTextElem.InitialState.Position = upTextElem.Position - fadePosOffset;

            layer.AddElement(upTextElem);                                                                       // 텍스트 엘리멘트 추가
        }

        // 선택지 : 아래쪽 (등장 위치는 위쪽)
        dirIndex = (int)FSNInGameSetting.FlowDirection.Down;
        dirText  = textSeg.optionTexts[dirIndex];
        if (textSeg.optionTexts.Length - 1 >= dirIndex && !string.IsNullOrEmpty(dirText))
        {
            var downTextSize = CalculateTextSize(dirText, setting);

            var downTextElem = new SnapshotElems.Text(setting);

            downTextElem.text           = dirText;
            downTextElem.fontSize       = setting.FontSize;
            downTextElem.Color          = Color.white;                                //TODO
            downTextElem.Alpha          = 1;
            downTextElem.TransitionTime = setting.TextTransitionTime;                 //TODO
            downTextElem.type           = SnapshotElems.Text.Type.OptionTexts;
            downTextElem.optionDir      = (FSNInGameSetting.FlowDirection)dirIndex;
            downTextElem.MakeItUnique();

            downTextElem.InitialState.Alpha = 0;
            downTextElem.FinalState.Alpha   = 0;
            CopyCurrentToFinal(downTextElem);                                                                   // 임시 FinalState

            // 새 텍스트 엘레먼트 - 위치 세팅 (시작 위치만. 끝 위치는 프로세스 끝에 결정된다)
            var tpos = new Vector3(downTextSize.x / 2f, screenDim.y / 2f);
            ApplySideTextMargin(ref tpos, setting, FSNInGameSetting.FlowDirection.Down);
            downTextElem.Position = tpos;
            downTextElem.InitialState.Position = downTextElem.Position - fadePosOffset;

            layer.AddElement(downTextElem);                                                                     // 텍스트 엘리멘트 추가
        }

        // 선택지 : 왼쪽 (등장 위치는 오른쪽)
        dirIndex = (int)FSNInGameSetting.FlowDirection.Left;
        dirText  = textSeg.optionTexts[dirIndex];
        if (textSeg.optionTexts.Length - 1 >= dirIndex && !string.IsNullOrEmpty(dirText))
        {
            var leftTextSize = CalculateTextSize(dirText, setting);

            var leftTextElem = new SnapshotElems.Text(setting);

            leftTextElem.text           = dirText;
            leftTextElem.fontSize       = setting.FontSize;
            leftTextElem.Color          = Color.white;                                //TODO
            leftTextElem.Alpha          = 1;
            leftTextElem.TransitionTime = setting.TextTransitionTime;                 //TODO
            leftTextElem.type           = SnapshotElems.Text.Type.OptionTexts;
            leftTextElem.optionDir      = (FSNInGameSetting.FlowDirection)dirIndex;
            leftTextElem.MakeItUnique();

            leftTextElem.InitialState.Alpha = 0;
            leftTextElem.FinalState.Alpha   = 0;
            CopyCurrentToFinal(leftTextElem);                                                                   // 임시 FinalState

            // 새 텍스트 엘레먼트 - 위치 세팅 (시작 위치만. 끝 위치는 프로세스 끝에 결정된다)
            var tpos = new Vector3(screenDim.x / 2f - leftTextSize.x, -leftTextSize.y * 3f);
            ApplySideTextMargin(ref tpos, setting, FSNInGameSetting.FlowDirection.Left);
            leftTextElem.Position = tpos;
            leftTextElem.InitialState.Position = leftTextElem.Position - fadePosOffset;

            layer.AddElement(leftTextElem);                                                                     // 텍스트 엘리멘트 추가
        }

        // 선택지 : 오른쪽 (등장 위치는 왼쪽)
        dirIndex = (int)FSNInGameSetting.FlowDirection.Right;
        dirText  = textSeg.optionTexts[dirIndex];
        if (textSeg.optionTexts.Length - 1 >= dirIndex && !string.IsNullOrEmpty(dirText))
        {
            var rightTextSize = CalculateTextSize(dirText, setting);

            var rightTextElem = new SnapshotElems.Text(setting);

            rightTextElem.text           = dirText;
            rightTextElem.fontSize       = setting.FontSize;
            rightTextElem.Color          = Color.white;                              //TODO
            rightTextElem.Alpha          = 1;
            rightTextElem.TransitionTime = setting.TextTransitionTime;               //TODO
            rightTextElem.type           = SnapshotElems.Text.Type.OptionTexts;
            rightTextElem.optionDir      = (FSNInGameSetting.FlowDirection)dirIndex;
            rightTextElem.MakeItUnique();

            rightTextElem.InitialState.Alpha = 0;
            rightTextElem.FinalState.Alpha   = 0;
            CopyCurrentToFinal(rightTextElem);                                                                          // 임시 FinalState

            // 새 텍스트 엘레먼트 - 위치 세팅 (시작 위치만. 끝 위치는 프로세스 끝에 결정된다)
            var tpos = new Vector3(-screenDim.x / 2f, rightTextSize.y * 3f);
            ApplySideTextMargin(ref tpos, setting, FSNInGameSetting.FlowDirection.Right);
            rightTextElem.Position = tpos;
            rightTextElem.InitialState.Position = rightTextElem.Position - fadePosOffset;

            layer.AddElement(rightTextElem);                                                                            // 텍스트 엘리멘트 추가
        }
    }
Example #6
0
    private void AddNormalText(FSNSnapshot.Layer layer, Segments.Text textSeg, IInGameSetting setting)
    {
        // TODO : 상하좌우 여백, 정렬 등도 따져야함

        var newTextSize = CalculateTextSize(textSeg.text, setting);                                             // 텍스트 영역 크기 미리 구하기


        // 새 텍스트 엘레먼트 세팅

        var newTextElem = new SnapshotElems.Text(setting);

        newTextElem.text           = textSeg.text;
        newTextElem.fontSize       = setting.FontSize;
        newTextElem.Color          = Color.white;                     //TODO
        newTextElem.Alpha          = 1;
        newTextElem.TransitionTime = setting.TextTransitionTime;      //TODO
        newTextElem.MakeItUnique();

        newTextElem.InitialState.Alpha = 0;
        newTextElem.FinalState.Alpha   = 0;

        // 새 텍스트 엘레먼트 - 위치 세팅 (시작 위치만. 끝 위치는 프로세스 끝에 결정된다)

        Vector2 screenDim = FSNEngine.Instance.ScreenDimension;                                                 // (계산용) 화면 크기
        Vector3 fadeinpos;

        switch (setting.CurrentFlowDirection)                                                                                   // 흐름 방향에 따라 시작 위치를 지정해준다
        {
        case FSNInGameSetting.FlowDirection.Up:
            fadeinpos = new Vector3(-screenDim.x / 2, -screenDim.y / 2);
            break;

        case FSNInGameSetting.FlowDirection.Down:
            fadeinpos = new Vector3(-screenDim.x / 2, screenDim.y / 2 + newTextSize.y);
            break;

        case FSNInGameSetting.FlowDirection.Right:
            fadeinpos = new Vector3(-screenDim.x / 2 - newTextSize.x, 0);
            break;

        case FSNInGameSetting.FlowDirection.Left:
            fadeinpos = new Vector3(screenDim.x / 2, 0);
            break;

        default:
            throw new System.Exception("HUH???");
        }
        ApplySideTextMargin(ref fadeinpos, setting, setting.CurrentFlowDirection);              // 여백 적용

        newTextElem.Position = fadeinpos;                                                       // 나중에 일괄적으로 이동시킬 것이기 때문에 시작 위치랑 화면 밖 위치를 같게 설정한다
        newTextElem.InitialState.Position = fadeinpos;

        if (!setting.StackTexts || setting.ScreenCenterText)                                                    // 텍스트를 쌓지 않는 경우, 기존 텍스트를 전부 Clear한다.
        // 가운데텍스트 모드일 경우에도 (텍스트 쌓기 여부와는 상관 없이) 기존 텍스트를 지운다.
        {
            ClearTextsToDirection(layer, setting.CurrentFlowDirection);
        }

        if (setting.ScreenCenterText)                                                                                                   // * 가운데 텍스트일 경우,
        {
            layer.AddElement(newTextElem);                                                                                              // 텍스트 엘리멘트 추가

            var posToCenter = newTextElem.Position;
            TextPositionToCenter(ref posToCenter, newTextSize, setting.CurrentFlowDirection, setting);            // 텍스트 중앙으로 움직이기
            newTextElem.Position = posToCenter;
            CopyCurrentToFinal(newTextElem);                                                                      // 임시 FinalState
        }
        else
        {                                                                                                                       // * 일반 텍스트
            layer.AddElement(newTextElem);                                                                                      // 텍스트 엘리멘트 추가
            PushTextsToDirection(layer, setting.CurrentFlowDirection, newTextSize, setting.ParagraphSpacing);                   // 텍스트 일괄적으로 해당 방향으로 밀기
        }
    }