void PlayNextFrame(float delta) { TryPlayEffect(); ChangeAttack(); ChangeWeaponTrail(); if (PoseEvent.ContainsKey(po.Idx)) { //当218发射飞轮,很快返回,还未到219动作时,下次播放219,就得立即取消循环,221 223 if ((PoseEvent[po.Idx] & (int)PoseEvt.WeaponIsReturned) != 0) { PoseEvent[po.Idx] &= ~(int)PoseEvt.WeaponIsReturned; loop = false; curIndex = po.LoopEnd; } } //有连招. if (TestInputLink()) { return; } if (loop) { if (curIndex > po.LoopEnd) { if (curIndex > po.LoopStart) { PlayPosEvent(); curIndex = po.LoopStart; if (loop) { return; } } curIndex = po.LoopStart; } } else { if (curIndex > po.End) { if (single) { Pause = true; } else { posMng.OnActionFinished(); } return; } if (TheFirstFrame == curIndex) { ActionEvent.HandlerFirstActionFrame(mOwner, po.Idx); } if (TheLastFrame == curIndex) { ActionEvent.HandlerFinalActionFrame(mOwner, po.Idx); } } BoneStatus status = null; if (po.SourceIdx == 0) { status = AmbLoader.CharCommon[curIndex]; } else if (po.SourceIdx == 1) { status = AmbLoader.FrameBoneAni[CharacterIdx][curIndex]; } if (mOwner.Attr.IsPlayer && FightWnd.Exist) { FightWnd.Instance.UpdatePoseStatus(po.Idx, curIndex); } for (int i = 0; i < bo.Count; i++) { bo[i].localRotation = status.BoneQuat[i]; if (i == 0) { bo[i].localPosition = status.BonePos; } } bool IgnoreActionMoves = IgnoreActionMove(po.Idx); for (int i = 0; i < dummy.Count; i++) { if (i == 0) { if (lastPosIdx == po.Idx) { Vector3 targetPos = status.DummyPos[i]; Vector3 vec = transform.rotation * (targetPos - lastDBasePos) * moveScale; if (IgnoreActionMoves) { vec.x = 0; vec.z = 0; vec.y = 0; } else { } moveDelta += vec; lastDBasePos = targetPos; } } else { dummy[i].localRotation = status.DummyQuat[i]; dummy[i].localPosition = status.DummyPos[i]; } } lastFrameIndex = curIndex; curIndex++; lastSource = po.SourceIdx; lastPosIdx = po.Idx; }
public void PlayFrame(float timeRatio) { TryPlayEffect(); ChangeAttack(); ChangeWeaponTrail(); ActionEvent.HandlerActionEvent(owner, po.Idx, curIndex); if (PoseEvent.ContainsKey(po.Idx)) { //当218发射飞轮,很快返回,还未到219动作时,下次播放219,就得立即取消循环,221 223 PoseEvent.Remove(po.Idx); loop = false; curIndex = po.LoopEnd; } if (TestInputLink()) { return; } if (loop) { if (LockCurrentFrame) { if (PoseStraight <= 0.0f) { loop = false; curIndex = po.LoopEnd + 1; LockCurrentFrame = false; return; } } if (curIndex >= po.LoopEnd) { LoopCount++; PlayPosEvent(); if (loop) { curIndex = po.LoopStart; } return; } } else { if (curIndex > po.End) { posMng.OnActionFinished(); return; } if (TheFirstFrame <= curIndex && TheFirstFrame != -1) { ActionEvent.HandlerFirstActionFrame(mOwner, po.Idx); TheFirstFrame = -1; } if (TheLastFrame <= curIndex && TheLastFrame != -1) { ActionEvent.HandlerFinalActionFrame(mOwner, po.Idx); TheLastFrame = -1; } } //Debug.Log("PlayKeyFrame:" + Time.frameCount); //curIndex = targetIndex; BoneStatus status = null; BoneStatus lastStatus = null; if (lastSource == 0 && AmbLoader.CharCommon.Count > lastFrameIndex && lastFrameIndex >= 0) { lastStatus = AmbLoader.CharCommon[lastFrameIndex]; } else if (AmbLoader.PlayerAnimation.ContainsKey(owner.UnitId) && AmbLoader.PlayerAnimation[owner.UnitId].Count > lastFrameIndex && lastFrameIndex >= 0) { lastStatus = AmbLoader.PlayerAnimation[owner.UnitId][lastFrameIndex]; } if (po.SourceIdx == 0) { status = AmbLoader.CharCommon[curIndex]; } else if (po.SourceIdx == 1) { status = AmbLoader.PlayerAnimation[owner.UnitId][curIndex]; } else { status = AmbLoader.GetBoneStatus(po.SourceIdx, owner.UnitId, curIndex); } if (status != null && lastStatus != null) { bo[0].localRotation = Quaternion.Slerp(lastStatus.BoneQuat[0], status.BoneQuat[0], timeRatio); bo[0].localPosition = Vector3.Lerp(lastStatus.BonePos, status.BonePos, timeRatio); for (int i = 1; i < bo.Count; i++) { bo[i].localRotation = Quaternion.Slerp(lastStatus.BoneQuat[i], status.BoneQuat[i], timeRatio); } } bool IgnoreActionMoves = PoseStatus.IgnoreActionMove(po.Idx); if (owner.IsDebugUnit()) { if (OnAnimationFrame != null) { OnAnimationFrame(po.SourceIdx, po.Idx, curIndex, timeRatio); } //IgnoreActionMoves = false; } bool IgnoreActionXZMove = PoseStatus.IgnoreXZMove(po.Idx); if (lastStatus != null && status != null) { if (lastPosIdx == po.Idx) { Vector3 targetPos = Vector3.Lerp(lastStatus.DummyPos[0], status.DummyPos[0], timeRatio); Vector3 vec = Target.rotation * (targetPos - lastDBasePos) * moveScale; if (IgnoreActionMoves) { vec.x = 0; vec.z = 0; vec.y = 0; } else if (IgnoreActionXZMove) { vec.x = vec.z = 0; } moveDelta += vec; lastDBasePos = targetPos; } for (int i = 1; i < dummy.Count; i++) { dummy[i].localRotation = Quaternion.Slerp(lastStatus.DummyQuat[i], status.DummyQuat[i], timeRatio); dummy[i].localPosition = Vector3.Lerp(lastStatus.DummyPos[i], status.DummyPos[i], timeRatio); } } }
public void SetPosData(Pose pos, float BlendTime = 0.0f) { //一些招式,需要把尾部事件执行完才能切换武器. LoopCount = 0; LockCurrentFrame = false; if (TheLastFrame != -1 && po != null) { ActionEvent.HandlerFinalActionFrame(mOwner, po.Idx); TheLastFrame = -1; } else { if (po != null && po.Link != 0) { //一些动作,默认连接其他动作,类似,486第一帧会收刀,收刀会切换武器为2 ActionEvent.HandlerPoseAction(mOwner, po.Link); } } //一些招式,动作结束会给使用者加上BUFF,另外一些招式,会让受击方得到BUFF int lastPosIdx = 0; if (po != null && po.Idx != 0) { lastPosIdx = po.Idx; } moveScale = 1.0f; attackTarget = Vector3.zero; //重置速度 bool isAttackPos = false; if (po == null) { isAttackPos = false; } else { //isAttackPos = po.Idx >= CommonAction.AttackActStart && po.Idx != CommonAction.GunIdle; isAttackPos = posMng.IsAttackPose(po.Idx); } //从IDLE往IDLE是不许融合的,否则武器位置插值非常难看 if (pos != null && po != null && pos.Idx == po.Idx && pos.Idx == 0) { BlendTime = 0.0f; } //保存当前帧的姿势,用于和下个动作融合 //当前状态下有姿势,且帧存在状态缓存 if (po != null) { lastPosIdx = po.Idx; } else { lastPosIdx = pos.Idx; } if (BlendTime != 0.0f) { GetCurrentSnapShot(); //如果有混合,重置混合位置. nextDBasePos = lastFrameStatus.DummyPos[0]; } //动画帧率与运行帧率可能要转换一下. blendTime = BlendTime; lastFramePlayedTimes = 0; po = pos; loop = (pos.LoopStart != 0 && pos.LoopEnd != 0);//2帧相同不为0 //查看第一个blend的最后一帧,如果有,切换目标帧设置为这个,若第一个是act则目标帧为起始帧 //PosAction blend = null; PosAction act = null; if (pos.ActionList.Count != 0) { if (isAttackPos) { for (int i = 0; i < pos.ActionList.Count; i++) { //过滤掉565,刀雷电斩的头一个 第一个混合段与整个动画一致. if (pos.ActionList[i].Start == pos.Start && pos.ActionList[i].End == pos.End) { continue; } act = pos.ActionList[i]; break; } } else { act = pos.ActionList[0]; } } TheLastFrame = pos.End - 1; TheFirstFrame = pos.Start; //算第一个过渡帧条件很多,有切换目的帧是否设定,第一个过渡帧是否存在,上一个动作是否攻击动作,锤绝325BUG,其他招式接325,还要在地面等,应该不需要在地面等 //curIndex = targetFrame != 0 ? targetFrame : (act != null ? (act.Type == "Action" ? act.Start: (isAttackPos ? act.End : pos.Start)): pos.Start); curIndex = act != null ? (act.Type == "Action" ? (isAttackPos ? act.Start : pos.Start) : (isAttackPos ? act.End : act.Start)) : pos.Start; //部分动作混合帧比开始帧还靠前 if (curIndex < pos.Start) { curIndex = pos.Start; } blendStart = curIndex; //if (blendTime != 0.0f && (pos.Idx == CommonAction.JumpFall || pos.Idx == CommonAction.Jump || pos.Idx == CommonAction.JumpFallOnGround)) // Debug.Log("过渡帧为" + blendStart + " 转换到动作:" + pos.Idx); effectPlayed = false; sfxEffect = null; playedTime = 0; //下一个动作的第一帧所有虚拟物体 if (po.SourceIdx == 0) { lastDBasePos = AmbLoader.CharCommon[curIndex].DummyPos[0]; } else if (po.SourceIdx == 1) { lastDBasePos = AmbLoader.PlayerAnimation[owner.UnitId][curIndex].DummyPos[0]; } if (lastPosIdx != 0) { Option poseInfo = Main.Ins.MenuResLoader.GetPoseInfo(lastPosIdx); if (poseInfo.first.Length != 0 && poseInfo.first[0].flag[0] == 18 && lastPosIdx != 468) //18为,使用招式后获取物品ID 468-469都会调用微尘,hack掉468pose的 { owner.GetItem(poseInfo.first[0].flag[1]); //忍刀小绝,同归于尽,会获得微尘物品,会即刻死亡 } } curPos = pos.Idx; }
void PlayNextKeyFrame() { TryPlayEffect(); ChangeAttack(); ChangeWeaponTrail(); ActionEvent.HandlerActionEvent(owner, po.Idx, curIndex); if (PoseEvent.ContainsKey(po.Idx)) { //当218发射飞轮,很快返回,还未到219动作时,下次播放219,就得立即取消循环,221 223 PoseEvent.Remove(po.Idx); loop = false; curIndex = po.LoopEnd; } //有连招. if (TestInputLink()) { return; } if (loop) { if (LockCurrentFrame) { if (PoseStraight <= 0.0f) { loop = false; curIndex = po.LoopEnd + 1; LockCurrentFrame = false; return; } } if (curIndex > po.LoopEnd) { if (curIndex > po.LoopStart) { LoopCount++; PlayPosEvent(); if (loop) { curIndex = po.LoopStart; } return; } curIndex = po.LoopStart; } } else { if (curIndex > po.End) { posMng.OnActionFinished(); return; } if (TheFirstFrame <= curIndex && TheFirstFrame != -1) { ActionEvent.HandlerFirstActionFrame(mOwner, po.Idx); TheFirstFrame = -1; } if (TheLastFrame <= curIndex && TheLastFrame != -1) { ActionEvent.HandlerFinalActionFrame(mOwner, po.Idx); TheLastFrame = -1; } } //Debug.Log("PlayKeyFrame:" + Time.frameCount); BoneStatus status = null; if (po.SourceIdx == 0) { status = AmbLoader.CharCommon[curIndex]; } else if (po.SourceIdx == 1) { status = AmbLoader.PlayerAnimation[owner.UnitId][curIndex]; } else { status = AmbLoader.GetBoneStatus(po.SourceIdx, owner.UnitId, curIndex); } //Debug.LogError("play keyframe " + " idx:" + curIndex); if (bo.Count != 0) { bo[0].localRotation = status.BoneQuat[0]; bo[0].localPosition = status.BonePos; } for (int i = 1; i < bo.Count; i++) { bo[i].localRotation = status.BoneQuat[i]; } bool IgnoreActionMoves = PoseStatus.IgnoreActionMove(po.Idx); //if (owner.IsDebugUnit()) // IgnoreActionMoves = false; bool IgnoreActionXZMove = PoseStatus.IgnoreXZMove(po.Idx); if (lastPosIdx == po.Idx) { Vector3 targetPos = status.DummyPos[0]; Vector3 vec = Target.rotation * (targetPos - lastDBasePos) * moveScale; //如果忽略位移,或者在动作的循环帧中,即第一次从循环头开始播放后,不再计算位移. if (IgnoreActionMoves) { vec.x = 0; vec.z = 0; vec.y = 0; } else if (IgnoreActionXZMove) { vec.x = vec.z = 0; } moveDelta += vec; //if (po.Idx == 151) // Debug.LogError(string.Format("pose:{0} frame:{1} move: x ={2}, y ={3} z = {4}", po.Idx, curIndex, moveDelta.x, moveDelta.y, moveDelta.z)); lastDBasePos = targetPos; } for (int i = 1; i < dummy.Count; i++) { dummy[i].localRotation = status.DummyQuat[i]; dummy[i].localPosition = status.DummyPos[i]; } lastFrameIndex = curIndex; curIndex++; lastSource = po.SourceIdx; lastPosIdx = po.Idx; }