Пример #1
0
    //========================================================================

    /// <summary>
    /// 오브젝트 생성 커맨드 처리
    /// </summary>
    /// <param name="segment"></param>
    /// <param name="layer"></param>
    void CreateElement(SegT segment, FSNSnapshot.Layer layer)
    {
        {
            int uid;
            if (FindUIDFromLookupDict(segment.objectName, out uid, layer))              // 이미 해당 이름으로 오브젝트가 존재한다면 에러
            {
                Debug.LogError("there is already a SnapshotElem named " + segment.objectName);
            }
        }

        var newElem = new ElemT();

        newElem.Alpha          = 1;
        newElem.Color          = Color.white;
        newElem.TransitionTime = 1;
        SetElemBySegProperties(newElem, segment);                                       // 세팅하기
        newElem.MakeItUnique();

        var initialState = newElem.InitialState as ElemT;                       // Inital State 기본값 주기 - 시작 세팅에서 알파만 0

        initialState.Alpha          = 0;
        initialState.TransitionTime = 1;
        SetElemBySegProperties(initialState, segment);

        AutoSetFinalState(newElem, false);                                                 // Final State 임시로 세팅

        newElem.motionState = SnapshotElems.ObjectBase <ElemT> .State.MotionKey;           // Key로 지정

        layer.AddElement(newElem);
        AddToLookupDict(segment.objectName, newElem, layer);            // 오브젝트 이름 등록

        OnCreateElement(segment, layer, newElem);                       // 추가 동작 실행
    }
Пример #2
0
    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;
    }
Пример #3
0
    // 트랜지션 관련


    /// <summary>
    /// 타겟 레이어 비교. 이전에 비교한 레이어라면 캐싱된 것을 사용, 새로운 타겟이라면 캐시 업데이트.
    /// </summary>
    /// <param name="target"></param>
    void UpdateTargetLayerDiff(FSNSnapshot.Layer target)
    {
        if (m_lastTargetLayerRef != target)
        {
            m_lastTargetLayerDiff = m_curLayerRef.CompareAndReturnElements(target);
            m_lastTargetLayerRef  = target;
        }
    }
Пример #4
0
    protected override void OnSetElement(LibSequentia.ScriptSegment segment, FSNSnapshot.Layer layer, LibSequentia.SnapshotElement elemToSet)
    {
        //base.OnSetElement(segment, layer, elemToSet);

        var elem = elemToSet as LibSequentia.SnapshotElement;

        elem.CountUpScriptProgress();           // 진행 방향을 알 수 있도록
    }
Пример #5
0
    protected override void OnCreateElement(LibSequentia.ScriptSegment segment, FSNSnapshot.Layer layer, LibSequentia.SnapshotElement elemCreated)
    {
        //base.OnCreateElement(segment, layer, elemCreated);

        var elem = elemCreated as LibSequentia.SnapshotElement;

        elem.CountUpScriptProgress();           // 진행 방향을 알 수 있도록
        elem.InitialState.SetNegativeProgress();
    }
Пример #6
0
    static void RemoveFromLookupDict(string name, FSNSnapshot.Layer layer)
    {
        var nameDict = layer.GetCustomData(c_customDataName) as Dictionary <string, int>;

        if (nameDict == null)
        {
            nameDict = new Dictionary <string, int>();
            layer.SetCustomData(c_customDataName, nameDict);
        }

        nameDict.Remove(name);
    }
Пример #7
0
    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;
    }
Пример #8
0
    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;
    }
Пример #9
0
    /// <summary>
    /// 오브젝트 초기 세팅
    /// </summary>
    /// <param name="segment"></param>
    /// <param name="layer"></param>
    void SetElementInitial(SegT segment, FSNSnapshot.Layer layer)
    {
        int uid;

        if (!FindUIDFromLookupDict(segment.objectName, out uid, layer))         // 이름으로 uid 찾기
        {
            Debug.LogError("cannot find SnapshotElem named " + segment.objectName);
        }

        var elem = layer.GetElement(uid) as ElemT;

        SetElemBySegProperties(elem.InitialState as ElemT, segment);        // 설정값들 세팅

        OnSetElementInitial(segment, layer, elem);                          // 추가동작
    }
Пример #10
0
    /// <summary>
    /// 오브젝트 파괴 세팅
    /// </summary>
    /// <param name="segment"></param>
    /// <param name="layer"></param>
    void SetElementFinal(SegT segment, FSNSnapshot.Layer layer)
    {
        int uid;

        if (!FindUIDFromLookupDict(segment.objectName, out uid, layer))         // 이름으로 uid 찾기
        {
            Debug.LogError("cannot find SnapshotElem named " + segment.objectName);
        }

        var elem = layer.GetElement(uid) as ElemT;

        AutoSetFinalState(elem);                                                // Final State가 하나도 세팅되지 않은 경우, 기본값부터 세팅
        SetElemBySegProperties(elem.FinalState as ElemT, segment);              // 마지막 설정값들 세팅

        OnSetElementFinal(segment, layer, elem);                                // 추가 동작
    }
Пример #11
0
    public override void ProcessCustomElementCommand(Segments.Sound segment, FSNSnapshot.Layer layer)
    {
        //base.ProcessCustomElementCommand(segment, layer);

        // One-Shot 사운드에 대한 처리

        // 레이어에 one-shot 사운드 리스트가 없다면 생성
        var oneshotSounds = layer.GetCustomData(c_oneshotSoundData) as List <Segments.Sound>;

        if (oneshotSounds == null)
        {
            oneshotSounds = new List <Segments.Sound>();
            layer.SetCustomData(c_oneshotSoundData, oneshotSounds);
        }

        oneshotSounds.Add(segment);                                                     // 세그먼트채로 집어넣는다.
    }
Пример #12
0
    /// <summary>
    /// 텍스트들을 일정 방향으로 모두 밀어내며 삭제한다.
    /// </summary>
    /// <param name="layer"></param>
    /// <param name="direction"></param>
    private static void ClearTextsToDirection(FSNSnapshot.Layer layer, FSNInGameSetting.FlowDirection direction)
    {
        Vector3 screenHalf = FSNEngine.Instance.ScreenDimension * 0.5f;                                 // 화면 크기 절반
        Vector3 dirVec     = FSNInGameSetting.GetUnitVectorFromFlowDir(direction);                      // 흐름 방향 벡터

        var uidList = layer.UniqueIDList;
        int count   = uidList.Count;

        int[] removeIDList = new int[uidList.Count];
        uidList.CopyTo(removeIDList, 0);

        for (int i = 0; i < count; i++)
        {
            var textElem = layer.GetElement(removeIDList[i]) as SnapshotElems.Text;

            textElem.FinalState.Position = textElem.Position + Vector3.Scale(screenHalf, dirVec);                       // 화면 절반 거리만큼 해당 방향으로 이동
            layer.RemoveElement(removeIDList[i]);
        }
    }
Пример #13
0
    //=================================================================

    public override FSNSnapshot.Layer GenerateNextLayerImage(FSNSnapshot.Layer curLayer, params FSNProcessModuleCallParam[] callParams)
    {
        FSNSnapshot.Layer newLayer = curLayer.Clone();

        foreach (var callParam in callParams)
        {
            if (callParam.segment.type == FSNScriptSequence.Segment.Type.Text)                  // ** 텍스트 세그먼트 처리 **
            {
                var textSeg = callParam.segment as Segments.Text;                               // 타입 변환

                switch (textSeg.textType)                                                       // * 텍스트 종류에 따라 처리 분기
                {
                case Segments.Text.TextType.Normal:
                    AddNormalText(newLayer, textSeg, callParam.setting);
                    break;

                case Segments.Text.TextType.Clear:
                    ClearTextsToDirection(newLayer, callParam.setting.CurrentFlowDirection);
                    break;

                case Segments.Text.TextType.Options:
                    ClearTextsToDirection(newLayer, callParam.setting.CurrentFlowDirection);                                    // 선택지 텍스트는 clear를 먼저 한 뒤에 표시
                    ShowOptionTexts(newLayer, textSeg, callParam.setting);
                    break;

                case Segments.Text.TextType.LastOption:
                    AddLastOptionText(newLayer, textSeg, callParam.setting);
                    break;
                }
            }
            else if (callParam.segment.type == FSNScriptSequence.Segment.Type.Control &&
                     (callParam.segment as Segments.Control).controlType == Segments.Control.ControlType.Clear)                 // Clear 명령에 반응
            {
                ClearTextsToDirection(newLayer, callParam.setting.CurrentFlowDirection);
            }
            else if (callParam.segment.type == FSNScriptSequence.Segment.Type.HardClone)                // 레이어 Hard-Clone
            {
                newLayer.MakeAllElemsHardClone();
            }
        }

        return(newLayer);
    }
Пример #14
0
    static bool AddToLookupDict(string name, ElemT elem, FSNSnapshot.Layer layer)
    {
        var nameDict = layer.GetCustomData(c_customDataName) as Dictionary <string, int>;

        if (nameDict == null)
        {
            nameDict = new Dictionary <string, int>();
            layer.SetCustomData(c_customDataName, nameDict);
        }

        if (nameDict.ContainsKey(name))
        {
            return(false);
        }
        else
        {
            nameDict[name] = elem.UniqueID;
            return(true);
        }
    }
Пример #15
0
    /// <summary>
    /// 오브젝트 세팅 커맨드
    /// </summary>
    /// <param name="segment"></param>
    /// <param name="layer"></param>
    void SetElement(SegT segment, FSNSnapshot.Layer layer)
    {
        int uid;

        if (!FindUIDFromLookupDict(segment.objectName, out uid, layer))         // 이름으로 uid 찾기
        {
            Debug.LogError("cannot find SnapshotElem named " + segment.objectName);
        }

        var elem = layer.GetElement(uid) as ElemT;

        SetElemBySegProperties(elem, segment);                                                  // 설정값들 세팅
        elem.motionState = SnapshotElems.ObjectBase <ElemT> .State.MotionKey;

        AutoSetFinalState(elem, false);                                                                 // Final State가 세팅되지 않은 객체에 한해서만 Final State를 임시로 계속 만들어주기

        CalculateStates(elem);                                                                          // 지금까지 좌표값들 보간

        OnSetElement(segment, layer, elem);                                                             // 추가 동작
    }
Пример #16
0
    /// <summary>
    /// 오브젝트 이름으로 UID 찾기
    /// </summary>
    /// <param name="name"></param>
    /// <param name="uid"></param>
    /// <returns></returns>
    protected static bool FindUIDFromLookupDict(string name, out int uid, FSNSnapshot.Layer layer)
    {
        var nameDict = layer.GetCustomData(c_customDataName) as Dictionary <string, int>;

        if (nameDict == null)
        {
            nameDict = new Dictionary <string, int>();
            layer.SetCustomData(c_customDataName, nameDict);
        }

        if (!nameDict.ContainsKey(name))
        {
            uid = 0;
            return(false);
        }
        else
        {
            uid = nameDict[name];
            return(true);
        }
    }
Пример #17
0
    /// <summary>
    /// 현재 존재하는 오브젝트들만 toLayer 의 상태에 맞춰 트랜지션. (자동재생 아님)
    /// 다음으로 넘기기 위해 Swipe하는 도중에 화면에 보여지는 상태.
    /// </summary>
    /// <param name="toLayer"></param>
    /// <param name="ratio">트랜지션 비율. 0 : 현재 상태 그대로, 1 : 완전히 toLayer 상태로</param>
    /// <param name="backward">진행 반대 방향으로 swipe를 한 경우에는 false</param>
    public void OldElementOnlyTransition(FSNSnapshot.Layer toLayer, float ratio, bool backward)
    {
        UpdateTargetLayerDiff(toLayer);                                                                                         // 비교 업데이트

        // *** 유지되는 오브젝트들
        IterateMatchingUIDs((int uId) =>
        {
            m_objectDict[uId].TransitionWith(toLayer.GetElement(uId) as ElmT, ratio);
        });

        // *** 다음에 사라지는 오브젝트들
        IterateOnlyInThisUIDs((int uId) =>
        {
            var currentElem = toLayer.GetRemovedElementOrNull(uId)                                                       // (정방향) 다음 레이어에 지워지는 해당 오브젝트에 관한 정보가 있다면 얻어오고
                              ?? m_curLayerRef.GetElement(uId);                                                          // 아니면 현재 레이어의 해당 오브젝트를 얻는다

            var finalElem = (!backward)?  currentElem.GenericFinalState                                                  // 정방향일 경우 마지막 스테이트로 움직인 뒤 소멸,
                                                                                :       currentElem.GenericInitialState; // 역방향일 경우 최초 스테이트로 움직인 뒤 소멸해야한다.

            m_objectDict[uId].TransitionWith(finalElem as ElmT, ratio);
        });
    }
Пример #18
0
    /// <summary>
    /// 오브젝트 삭제 커맨드 처리
    /// </summary>
    /// <param name="segment"></param>
    /// <param name="layer"></param>
    void RemoveElement(SegT segment, FSNSnapshot.Layer layer)
    {
        int uid;

        if (!FindUIDFromLookupDict(segment.objectName, out uid, layer))         // 이름으로 uid 찾기
        {
            Debug.LogError("cannot find SnapshotElem named " + segment.objectName);
        }

        var elem = layer.GetElement(uid) as ElemT;

        AutoSetFinalState(elem);                                                                // Final State가 하나도 세팅되지 않은 경우, 기본값부터 세팅

        SetElemBySegProperties(elem, segment);                                                  // 마지막 설정값들 세팅
        elem.motionState = SnapshotElems.ObjectBase <ElemT> .State.MotionKey;

        OnRemoveElement(segment, layer, elem);                                          // 추가 동작 실행

        CalculateStates(elem);                                                          // 지금까지 좌표값들 보간

        RemoveFromLookupDict(segment.objectName, layer);                                // 제거
        layer.RemoveElement(uid);
    }
Пример #19
0
    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);                                        // 오디오 재생 길이만큼만 게임 오브젝트 유지
            }
        }
    }
Пример #20
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());
        }
    }
Пример #21
0
 /// <summary>
 /// 오브젝트 생성 커맨드, 추가 처리
 /// </summary>
 /// <param name="segment"></param>
 /// <param name="layer"></param>
 /// <param name="elemCreated"></param>
 protected virtual void OnCreateElement(SegT segment, FSNSnapshot.Layer layer, ElemT elemCreated)
 {
 }
Пример #22
0
    /// <summary>
    /// Layer 안에 들어있는 텍스트들을 특정 방향으로 모두 밀어낸다. 알파값도 변경. 수명이 다 된 것은 제거 처리.
    /// </summary>
    /// <param name="layer">변경할 레이어 (이미 복제된 상태여야함)</param>
    /// <param name="direction"></param>
    /// <param name="newTextSize"></param>
    private static void PushTextsToDirection(FSNSnapshot.Layer layer, FSNInGameSetting.FlowDirection direction, Vector2 newTextSize, float paraSpacing = 0)
    {
        Vector2    dirVec      = FSNInGameSetting.GetUnitVectorFromFlowDir(direction);
        List <int> UIDtoRemove = new List <int>();              // 삭제 리스트

        foreach (var uId in layer.UniqueIDList)
        {
            var textElem = layer.GetElement(uId) as SnapshotElems.Text;
            int elemAge  = textElem.ChainedParentCount;

            // 텍스트의 종류에 따라서 다른 룰을 적용한다.

            if (textElem.type == SnapshotElems.Text.Type.Normal)                                                        // ** 일반 텍스트
            {
                Vector3 transVec = Vector2.Scale(newTextSize, dirVec);                                                  // 이동할 벡터 양
                if (elemAge > 0)
                {
                    transVec += (Vector3)(dirVec * paraSpacing);                                                                        // 최초에 등장한 이후엔 문단 간격도 적용
                }
                if (elemAge < c_textLife)                                                                                               // 텍스트가 아직 살아있어야하는 경우
                {
                    textElem.Alpha    = (float)(c_textLife - elemAge) / (float)c_textLife;
                    textElem.Position = textElem.Position + transVec;
                    CopyCurrentToFinal(textElem);                                                                                               // 임시 FinalState
                }
                else
                {                                                                                                                                                               // 텍스트가 죽어야하는 경우
                    textElem.FinalState.Position = textElem.Position + transVec;
                    UIDtoRemove.Add(uId);
                }
            }
            else
            {                                                                                                 // ** 기타 (선택지 관련 텍스트)
                int killAge = textElem.type == SnapshotElems.Text.Type.OptionTexts? 1 : 2;                    //(선택한 텍스트는 1턴 더 살아있어야 하므로)

                if (elemAge == killAge)                                                                       // 없어지는 타이밍
                {
                    // NOTE : 현재 구조상의 문제로 인해 분기점 이후 바로 없어지는 오브젝트의 FinalState를 여러개 둘 수 없음.
                    // 따라서 분기점 이후에도 한번은 오브젝트를 살려놓은 뒤 안보이게만 하고 다음번에 없애는 식으로.

                    Vector2 halfScreen = FSNEngine.Instance.ScreenDimension / 2f;
                    Vector3 transVec   = Vector2.Scale(dirVec, halfScreen);

                    textElem.Position = textElem.Position + transVec;
                    textElem.Alpha    = 0f;

                    // TODO : Alpha를 0으로 하는 것 이외에 실제로 visible을 끌 수 있는 방법이 있다면 사용하도록 한다. 지금도 딱히 문제는 없긴 한데...
                }
                else if (elemAge == killAge + 1)                                                                                                // 원래 없어져야했던 타이밍이 지나고 나서 실제로 없앤다.
                {
                    UIDtoRemove.Add(uId);
                }
            }
        }

        int rmvCount = UIDtoRemove.Count;

        for (int i = 0; i < rmvCount; i++)                                                                                                      // 삭제 리스트 처리
        {
            layer.RemoveElement(UIDtoRemove[i]);
        }
    }
Пример #23
0
 /// <summary>
 /// 오브젝트 삭제 커맨드, 추가 처리
 /// </summary>
 /// <param name="segment"></param>
 /// <param name="layer"></param>
 /// <param name="elemToBeRemoved"></param>
 protected virtual void OnRemoveElement(SegT segment, FSNSnapshot.Layer layer, ElemT elemToBeRemoved)
 {
 }
Пример #24
0
 /// <summary>
 /// 특정 레이어로 트랜지션하는 애니메이션이 시작될 때 호출됨
 /// </summary>
 /// <param name="toLayer"></param>
 protected virtual void OnLayerTransitionStart(FSNSnapshot.Layer toLayer)
 {
 }
Пример #25
0
    /// <summary>
    /// 트랜지션 애니메이션 시작.
    /// </summary>
    /// <param name="toLayer"></param>
    /// <param name="startRatioForOlds">기존 오브젝트들은 해당 비율부터 애니메이션 시작</param>
    /// <param name="backward">진행 반대 방향으로 swipe를 한 경우에는 false</param>
    /// <returns>트랜지션이 모두 끝나는데 걸리는 시간</returns>
    public float StartTransition(FSNSnapshot.Layer toLayer, IInGameSetting nextSetting, float startRatioForOlds, bool backward)
    {
        UpdateTargetLayerDiff(toLayer);                                                                                         // 비교 업데이트
        float longestDuration = 0f;                                                                                             // 트랜지션 중 제일 오래걸리는 것의 시간

        // *** 유지되는 오브젝트들
        IterateMatchingUIDs((int uId) =>
        {
            var elem     = toLayer.GetElement(uId) as ElmT;
            float trTime = elem.TransitionTime / nextSetting.TransitionSpeedRatio;                // 전환속도 비율 적용

            m_objectDict[uId].DoTransition(elem, startRatioForOlds, trTime, false);

            if (longestDuration < trTime)
            {
                longestDuration = trTime;                                                               // 제일 긴 트랜지션 시간 추적하기
            }
        });

        // *** 다음에 사라지는 오브젝트들
        IterateOnlyInThisUIDs((int uId) =>
        {
            var currentElem = m_curLayerRef.GetElement(uId);                                                         // 다음 레이어에 없어질 현재 레이어 객체

            var refelem = toLayer.GetRemovedElementOrNull(uId)                                                       // (정방향) 다음 레이어에 지워지는 해당 오브젝트에 관한 정보가 있다면 이것을 사용
                          ?? currentElem;                                                                            // 아니면 현재 레이어의 해당 오브젝트를 사용하여 finalState를 구한다
            var finalElem = (!backward)?  refelem.GenericFinalState                                                  // 정방향일 경우 마지막 스테이트로 움직인 뒤 소멸,
                                                                                :       refelem.GenericInitialState; // 역방향일 경우 최초 스테이트로 움직인 뒤 소멸해야한다.
            float trTime = finalElem.TransitionTime / nextSetting.TransitionSpeedRatio;                              // 전환속도 비율 적용

            m_objectDict[uId].DoTransition(finalElem as ElmT, startRatioForOlds, trTime, true);

            if (longestDuration < trTime)
            {
                longestDuration = trTime;                                                               // 제일 긴 트랜지션 시간 추적하기
            }
        });

        // *** 다음에 처음 등장하는 오브젝트들
        IterateOnlyInOtherUIDs((int uId) =>
        {
            var currentElem = toLayer.GetElement(uId);                                                       // 다음 레이어의 해당 객체

            var refelem = m_curLayerRef.GetRemovedElementOrNull(uId)                                         // (역방향) 현재 레이어에 지워진 오브젝트의 정보가 있다면 그것을 사용,
                          ?? currentElem;                                                                    // 아니면 다음 레이어의 오브젝트를 참조해서 InitialState를 구한다
            var initialElem = backward?     refelem.GenericFinalState
                                                                        :       refelem.GenericInitialState; // 역방향이면 finalState, 정방향이면 InitialState 로 초기세팅한다
            float trTime = initialElem.TransitionTime / nextSetting.TransitionSpeedRatio;                    // 현재 상태로 transition하지만 시간값은 최초 상태값에 지정된 걸 사용한다.

            var newobj = AddNewLayerObject(initialElem as ElmT, nextSetting);
            newobj.DoTransition(currentElem as ElmT, 0, trTime, false);

            if (longestDuration < trTime)
            {
                longestDuration = trTime;                                                               // 제일 긴 트랜지션 시간 추적하기
            }
        });


        // NOTE : 트랜지션이 완전히 끝난 뒤에 레이어를 교체해야할 수도 있다. 이슈가 생기면 그때 바꾸자...
        m_curLayerRef = toLayer;                                                                                                // 현재 레이어를 트랜지션 타겟 레이어로 교체.

        OnLayerTransitionStart(toLayer);                                                                                        // 이벤트 호출


        return(m_useTransitionDelay? longestDuration : 0);                                                      // 트랜지션 딜레이를 사용하지 않는다면 딜레이 시간은 0으로
    }
Пример #26
0
 /// <summary>
 /// 레이어에 후처리 필요할 때
 /// </summary>
 /// <param name="newLayer"></param>
 protected virtual void OnAfterGenerateNextLayerImage(FSNSnapshot.Layer newLayer)
 {
 }
Пример #27
0
 /// <summary>
 /// 해당 layer와 다음 명령어 조각을 사용해서 다음 layer 상태를 생성하여 리턴한다.
 /// 현재 Snapshot에 특정 명령어가 적용된 후의 Snapshot을 만들어내는 데 사용.
 /// </summary>
 /// <param name="curLayer"></param>
 /// <param name="nextSeg"></param>
 /// <returns></returns>
 public abstract FSNSnapshot.Layer GenerateNextLayerImage(FSNSnapshot.Layer curLayer, params FSNProcessModuleCallParam[] callParams);
Пример #28
0
    public override FSNSnapshot.Layer GenerateNextLayerImage(FSNSnapshot.Layer curLayer, params FSNProcessModuleCallParam[] callParams)
    {
        FSNSnapshot.Layer newLayer = curLayer.Clone();
        if (curLayer.GetCustomData(c_customDataName) != null)                   // 이름 dictionary 카피
        {
            newLayer.SetCustomData(c_customDataName, new Dictionary <string, int>(curLayer.GetCustomData(c_customDataName) as Dictionary <string, int>));
        }

        foreach (var callParam in callParams)
        {
            if (callParam.segment.type == FSNScriptSequence.Segment.Type.Object)
            {
                var objSeg = callParam.segment as SegT;

                switch (objSeg.command)
                {
                case Segments.Object.CommandType.Create:
                    CreateElement(objSeg, newLayer);
                    break;

                case Segments.Object.CommandType.Remove:
                    RemoveElement(objSeg, newLayer);
                    break;

                case Segments.Object.CommandType.SetInitial:
                    SetElementInitial(objSeg, newLayer);
                    break;

                case Segments.Object.CommandType.SetFinal:
                    SetElementFinal(objSeg, newLayer);
                    break;

                case Segments.Object.CommandType.SetKey:
                    SetElement(objSeg, newLayer);
                    break;

                case Segments.Object.CommandType.Custom:
                    ProcessCustomElementCommand(objSeg, newLayer);
                    break;
                }
            }
            else if (callParam.segment.type == FSNScriptSequence.Segment.Type.Control)
            {
                var controlSeg = callParam.segment as Segments.Control;
                if (controlSeg.controlType == Segments.Control.ControlType.Clear && acceptClearCommand)                 // Clear 명령에 반응
                {
                    foreach (var rawelem in newLayer.Elements)                                                          // finalstate가 세팅되지 않은 오브젝트에 한해서 디폴트 세팅
                    {
                        var elem = rawelem as ElemT;
                        AutoSetFinalState(elem);
                    }

                    newLayer = new FSNSnapshot.Layer();                                                                                         // 완전히 새로운 레이어로 교체

                    // TODO : 힘들게 복제한 레이어를 버리는 구조임. 최적화 여지가 있음.
                }
            }
            else if (callParam.segment.type == FSNScriptSequence.Segment.Type.HardClone)                // 레이어 Hard-Clone
            {
                newLayer.MakeAllElemsHardClone();
            }
            else
            {
            }
        }

        // TODO : call 처리 이후, snapshot 마무리
        OnAfterGenerateNextLayerImage(newLayer);

        return(newLayer);
    }
Пример #29
0
 public virtual void ProcessCustomElementCommand(SegT segment, FSNSnapshot.Layer layer)
 {
 }
Пример #30
0
 /// <summary>
 /// 오브젝트 파괴 세팅, 추가 처리
 /// </summary>
 /// <param name="segment"></param>
 /// <param name="layer"></param>
 /// <param name="elemToSet"></param>
 protected virtual void OnSetElementFinal(SegT segment, FSNSnapshot.Layer layer, ElemT elemToSet)
 {
 }