Ejemplo n.º 1
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);
        });
    }
Ejemplo n.º 2
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);                          // 추가동작
    }
Ejemplo n.º 3
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);                                // 추가 동작
    }
Ejemplo n.º 4
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]);
        }
    }
Ejemplo n.º 5
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);                                                             // 추가 동작
    }
Ejemplo n.º 6
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);
    }
Ejemplo n.º 7
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으로
    }
Ejemplo n.º 8
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]);
        }
    }