/// <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); }
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 ); }