예제 #1
0
    /// <summary>
    /// 루트모션 적용 시작 (주의! 애니메이션은 다른곳에서 플레이하던지 해야함. 여기서는 루트모션에 이동값만 적용시킴)
    /// </summary>
    /// <param name="animState">루트모션을 수행할 애니메이션</param>
    public void Play(AnimationState animState, bool rootMotion = false, bool ignoreEnemy = false)
    {
        if (null == curveDic || !curveDic.ContainsKey(animState.name))
        {
            if (rootMotion)
            {
                if (GameDefine.TestMode)
                {
                    if (null == curveDic)
                    {
                        Debug.Log("curveDic 가 없습니다");
                    }
                    else if (!curveDic.ContainsKey(animState.name))
                    {
                        Debug.Log("curveDic 에 애니가 없습니다 " + animState.name);
                    }
                }
            }
            return;
        }

        //if (G_GameInfo.GameMode == GAME_MODE.FREEFIGHT)
        //    rootMotion = false;

        _ignoreEnemy      = ignoreEnemy;
        doRootMotion      = rootMotion;
        playingAnimState  = animState;
        playingAnimName   = animState.name;
        playingAnimLength = animState.length;
        playingCurve      = curveDic[playingAnimName];

        prevFramePos = playingCurve.GetOffset(playingAnimState.time);
    }
예제 #2
0
    void LateUpdate()
    {
        if (!doRootMotion)
        {
            return;
        }

        float nextAnimTime = (playingAnimState.time + (Time.deltaTime * playingAnimState.speed));

        // 다음 프레임에 애니메이션이 끝나는지 체크하기 위함.
        // 애니메이션 길이를 1이라고 봤을때, 0.9999라면, 다음 프레임은 내부적으로만 처리되기 때문에,
        // 정확한 위치 값 적용을 위해서 마지막도 계산필요.
        if (nextAnimTime >= playingAnimLength || !playingAnimState.enabled)
        {
            End();

            return;
        }

        Vector3 newPos   = playingCurve.GetOffset(playingAnimState.time);
        Vector3 deltaPos = newPos - prevFramePos;

        if (GameDefine.skillPushTest)
        {
            //if(mover.gameObject.GetComponent<Unit>().UnitType == UnitType.Unit || mover.gameObject.GetComponent<Unit>().UnitType == UnitType.Boss)
            if (!_ignoreEnemy)
            {
                Vector3 nextRealPos = mover.position + (Vector3.Dot(deltaPos, Vector3.forward) * mover.transform.forward);
                Vector3 dir         = (nextRealPos - mover.position).normalized;

                //Debug.DrawRay(mover.position, dir, Color.red, 0.5f);

                RaycastHit hit;
                LayerMask  mask = 1 << LayerMask.NameToLayer("Unit");

                if (Physics.Raycast(mover.position, dir, out hit, 1f, mask))
                //if (Physics.Raycast(mover.position, dir, out hit, 0.5f))
                {
                    //Debug.Log(hit);
                    doRootMotion = false;
                    return;
                }
            }
        }

        // 프레임당 이동값을 더해준다.
        if (null != moverAgent && moverAgent.enabled)
        {
            moverAgent.Move((Vector3.Dot(deltaPos, Vector3.forward) * mover.transform.forward));
        }
        else
        {
            mover.transform.localPosition += (Vector3.Dot(deltaPos, Vector3.forward) * mover.transform.forward);
        }

        // 현재 로컬 위치를 저장해둔다.
        prevFramePos = newPos;

        // 로컬 위치 초기화
        // TODO : die애니메이션의 x, z값 변동이 커서 눈에 띄어서 일단 주석.
        //animatedRoot.localPosition = new Vector3( 0, animatedRoot.localPosition.y, 0 );
    }