using asap.core; using cfg; using DG.Tweening; using Game; using GameCore; using System; using System.Collections; using System.Collections.Generic; using System.Threading.Tasks; using UnityEngine; using UnityEngine.AddressableAssets; using Random = UnityEngine.Random; public partial class FishingBehaviorB : MonoBehaviour { #region 进出水面 float OldFishPos = -3f; float jumpoutMaxCD = 0.2f; float jumpoutCD = 0f; public void JumpWater() { if (jumpoutCD > jumpoutMaxCD) { jumpoutCD = 0; float newFishPos = GetFishPos().y; if ((newFishPos - _waterHeight) * (OldFishPos - _waterHeight) < 0) { //进出水面 if (newFishPos > _waterHeight - 0.00001f) { Vector3 vector = _fish.transform.position; vector.y = _waterHeight; if (fx_fishing_water != null) { fx_fishing_water.transform.position = vector; fx_fishing_water.gameObject.SetActive(false); fx_fishing_water.gameObject.SetActive(true); } else if (fx_fishing_jumpout != null) { fx_fishing_jumpout.transform.position = vector; fx_fishing_jumpout.gameObject.SetActive(false); fx_fishing_jumpout.gameObject.SetActive(true); } //播音效 GContext.Publish(new EventFishingSound(SoundType.audio_fishing_jumpout)); } else if (newFishPos < _waterHeight + 0.00001f) { Vector3 vector = _fish.transform.position; vector.y = _waterHeight; //进水面 if (fx_fishing_water != null) { fx_fishing_water.transform.position = vector; fx_fishing_water.gameObject.SetActive(false); fx_fishing_water.gameObject.SetActive(true); } else if (fx_fishing_jumpinto != null) { fx_fishing_jumpinto.transform.position = vector; fx_fishing_jumpinto.gameObject.SetActive(false); fx_fishing_jumpinto.gameObject.SetActive(true); } //播音效 GContext.Publish(new EventFishingSound(SoundType.audio_fishing_jumpinto)); } } OldFishPos = newFishPos; } jumpoutCD += Time.deltaTime; } #endregion 进出水面 //跳跃相关 bool isJumping = false; float JumpDistance = 1; GameObject fx_fishing_water; GameObject fxHeadFishSkill; GameObject fxFishJumpWaterSkill; GameObject fxFishStruggleSkill; GameObject fxAppendFishSkill; public async void PlayFxFishSkill(IFishSpSkillData fishSpSkillData) { string fxFish = ""; string fxFishJumpWater = ""; string fxFishStruggle = ""; switch (fishSpSkillData.fishSkill.PerformanceType) { case FishPerformanceType.Jump: //技能表现 fxFish = fishSpSkillData.FxFishJump(); fxFishJumpWater = fishSpSkillData.FxFishJumpWater(); break; //case FishPerformanceType.Dash: // break; case FishPerformanceType.Struggle: fxFishStruggle = fishSpSkillData.FxFishStruggle(); break; } string rootFx = fishSpSkillData.FxFishSkillAppend(); string fxWater = fishSpSkillData.FxWater(); if (!string.IsNullOrEmpty(fxWater) && fx_fishing_water == null) { fx_fishing_water = await Addressables.InstantiateAsync(fxWater, transform, true).Task; fx_fishing_water?.SetActive(false); } if (!string.IsNullOrEmpty(fxFishJumpWater) && fxFishJumpWaterSkill == null) { fxFishJumpWaterSkill = await Addressables.InstantiateAsync(fxFishJumpWater, transform).Task; } if (!string.IsNullOrEmpty(fxFishStruggle) && fxFishStruggleSkill == null && FishBehaviour != null) { fxFishStruggleSkill = await Addressables.InstantiateAsync(fxFishStruggle, FishBehaviour.transform).Task; } if (!string.IsNullOrEmpty(fxFish) && fxHeadFishSkill == null && FishBehaviour != null && FishBehaviour.Head != null) { fxHeadFishSkill = await Addressables.InstantiateAsync(fxFish, FishBehaviour.Head).Task; } if (!string.IsNullOrEmpty(rootFx) && fxAppendFishSkill == null && FishBehaviour != null && FishBehaviour.Head != null) { fxAppendFishSkill = await Addressables.InstantiateAsync(rootFx, FishBehaviour.Head).Task; } fxHeadFishSkill?.SetActive(false); fxHeadFishSkill?.SetActive(true); fxAppendFishSkill?.SetActive(false); fxAppendFishSkill?.SetActive(true); fxFishStruggleSkill?.SetActive(false); fxFishStruggleSkill?.SetActive(true); fxFishJumpWaterSkill?.SetActive(true); } public void StopFxFishSkill() { fxHeadFishSkill?.SetActive(false); } public void SkillRelease() { if (fxHeadFishSkill != null) { Addressables.ReleaseInstance(fxHeadFishSkill); fxHeadFishSkill = null; } if (fxAppendFishSkill != null) { Addressables.ReleaseInstance(fxAppendFishSkill); fxAppendFishSkill = null; } if (fx_fishing_water != null) { Addressables.ReleaseInstance(fx_fishing_water); fx_fishing_water = null; } if (fxFishStruggleSkill != null) { Addressables.ReleaseInstance(fxFishStruggleSkill); fxFishStruggleSkill = null; } if (fxFishJumpWaterSkill != null) { Addressables.ReleaseInstance(fxFishJumpWaterSkill); fxFishJumpWaterSkill = null; } } public async void PlayJump() { FishData curFishData = fishingData.curFishData; isJumping = true; fishAnimator.SetTrigger($"_jumping0{fishingData.FishJump.AnimatorState}"); fishAnimator.SetTrigger("_jumping"); fishAnimator.SetTrigger($"_drawing0{curFishData.ShowAnimation}"); if (FishBehaviour != null) { FishBehaviour.SetSkillInt(fishingData.FishJump.SkillIndex); FishBehaviour.SetTrigger("Skill"); } FishJump fishJump = fishingData.FishJump; if (fishJump != null) { _ = StartCoroutine(PlayerJumpOutDelay(fishJump.FxJumpOutDelay, fishJump.JumpDistance)); _ = StartCoroutine(PlayerJumpIntoDelay(fishJump.FxJumpIntoDelay)); float jumpEndTime = fishJump.JumpEndTime; await Awaiters.Seconds(jumpEndTime); } isJumping = false; JumpDistance = 1; if (fishingData.FishJump == null) return; if (fxFishJumpWaterSkill != null) { fxFishJumpWaterSkill.SetActive(true); } if (fx_fishing_splashloop != null) { fx_fishing_splashloop.transform.localScale = Vector3.one * fishingData.curFishData.SlashFxScale; fx_fishing_splashloop.SetActive(true); } if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.transform.localScale = Vector3.one * fishingData.curFishData.SlashFxScale; fx_fishing_splashwaveloop.SetActive(true); } } IEnumerator PlayerJumpOutDelay(float fxJumpOutDelay, float jumpDistance) { if (fx_fishing_splashloop != null) { fx_fishing_splashloop.transform.DOScale(Vector3.zero, fxJumpOutDelay).SetEase(Ease.Linear); } if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.transform.DOScale(Vector3.zero, fxJumpOutDelay).SetEase(Ease.Linear); } yield return new WaitForSeconds(fxJumpOutDelay); GContext.Publish(new EventFishingSound(SoundType.HPEvent)); CloseBaitDoTween(); JumpDistance = jumpDistance; if (fx_fishing_splashloop != null) { fx_fishing_splashloop.SetActive(false); } if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.SetActive(false); } if (fxFishJumpWaterSkill != null) { fxFishJumpWaterSkill.SetActive(false); } } IEnumerator PlayerJumpIntoDelay(float fxJumpIntoDelay) { yield return new WaitForSeconds(fxJumpIntoDelay); GContext.Publish(new EventFishingSound(SoundType.HPEvent)); CloseBaitDoTween(); JumpDistance = 1; } public void StartSplashloopScale() { Vector3 localScale = Vector3.one * fishingData.curFishData.SlashFxScale * 1.5f; if (fx_fishing_splashloop != null) { fx_fishing_splashloop.transform.DOKill(); fx_fishing_splashloop.transform.localScale = localScale; } if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.transform.DOKill(); fx_fishing_splashwaveloop.transform.localScale = localScale; } if (fishingData.superDashSpSkillData != null) { HideSpSkillFx("dashFx"); HideSpSkillFx("dashWaterFx"); } } public void EndSplashloopScale() { Vector3 localScale = Vector3.one * fishingData.curFishData.SlashFxScale; if (fx_fishing_splashloop != null) { fx_fishing_splashwaveloop.transform.DOKill(); fx_fishing_splashloop.transform.DOScale(localScale, 1).SetEase(Ease.Linear); } if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.transform.DOKill(); fx_fishing_splashwaveloop.transform.DOScale(localScale, 1).SetEase(Ease.Linear); } } //====跳跃相关 //=====================鱼移动算法挪位置 private float timer = 1f; float dashTime = 0f; private float moveTimer = 0f; private Vector3 _strugglePoint; private Vector3 _startPos; private Vector3 _curStartPos; Tweener baitDoTween; //X轴偏移 float _nearDistance = 1; float _farDistance = 1; float distance = 1; float fishSpeed = 1; public bool Far => _fish.transform.position.z >= _farDistance; void SetBaitStartPos() { _nearDistance = _fishSwimAreaZNear; _nearDistance = Mathf.Clamp(_nearDistance, _fishSwimAreaZNear, _fishSwimAreaZFar); _farDistance = _fishSwimAreaZFar; _farDistance = Mathf.Clamp(_farDistance, _fishSwimAreaZNear, _fishSwimAreaZFar); _startPos = _fish.transform.position; _curStartPos = _startPos; float z = Random.Range(_nearDistance, _farDistance); _strugglePoint = GeneratePoint(z, 0) / 2; timer = 10; } public async void OnFail(float z, float speed) { EscapeFish(z); var targetPos = Vector3.Lerp(_curStartPos, _strugglePoint, fishSpeed / distance); _fish.transform.DOMove(targetPos, 1); await Awaiters.Seconds(1); GetFish.gameObject.SetActive(false); if (fx_fishing_splashloop != null) { fx_fishing_splashloop.SetActive(false); } if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.SetActive(false); } } //往安全区域外移动 public void EscapeFish(float z) { moveTimer = 0; _strugglePoint.z = z; _strugglePoint.x = 0; _curStartPos = _fish.transform.position; distance = Vector3.Distance(_curStartPos, _strugglePoint); FishTurn(); } void SimulateFishEscape(float fishSpeed) { moveTimer += Time.deltaTime * fishSpeed; if (moveTimer / distance < 1) { _fish.transform.position = Vector3.Lerp(_curStartPos, _strugglePoint, moveTimer / distance); Debug.Log("moveTimer / distance:" + _strugglePoint); } } //停止正常的移动,贝塞尔DoTween public void CloseBaitDoTween() { if (baitDoTween != null) { baitDoTween.Kill(); baitDoTween = null; timer = 10; } } float dashSpeedInc; public void DashStayTime(float dashSpeedInc) { IsPrepareDash = false; SetFishDash(); dashTime = 0; timer = 10; this.dashSpeedInc = dashSpeedInc; } void SetFishDash() { fishingData.DashStay = GetFishDash(); if (FishBehaviour != null && fishingData.DashStay != null) { FishBehaviour.SetSkillInt(fishingData.DashStay.SkillIndex); } dashPrepareTime = 0; } public void SetStruggle() { if (FishBehaviour != null && fishingData.FishStruggle != null) { FishBehaviour.SetSkillInt(fishingData.FishStruggle.SkillIndex); FishBehaviour.SetTrigger("Skill"); } } public void StartMoveFish() { timer = 10; } //能随时修改速度的移动轨迹 void SimulateFish(float curFishSpeed, float nearDistance, float farDistance) { fishSpeed = curFishSpeed; if (NotMove) { CloseBaitDoTween(); return; } _nearDistance = nearDistance * (_fishSwimAreaZFar - _fishSwimAreaZNear) + _fishSwimAreaZNear; _nearDistance = Mathf.Clamp(_nearDistance, _fishSwimAreaZNear, _fishSwimAreaZFar); _farDistance = farDistance * (_fishSwimAreaZFar - _fishSwimAreaZNear) + _fishSwimAreaZFar; _farDistance = Mathf.Clamp(_farDistance, _fishSwimAreaZNear, _fishSwimAreaZFar); timer += Time.deltaTime; float rangeTimer = Random.Range(5f, 10f); if (fishingData.superDashSpSkillData != null && IsPrepareDash && dashPrepareTime > 0) { dashPrepareTime -= Time.deltaTime; if (dashPrepareTime <= 0) { timer = 10; } } if (timer > rangeTimer || Vector3.Distance(_fish.transform.position, _strugglePoint) < 1) { CloseBaitDoTween(); float escapeDistanceMag = GContext.container.Resolve().GrtEscapeDistanceMag(); if (fishingData.DashStay != null) { if (!DashMove()) { return; } } else { isDashMove = false; float z = Random.Range(_nearDistance, _farDistance); if (fishingData.MaxZEscape > 0.001f) { z = fishingData.MaxZEscape * escapeDistanceMag; } _strugglePoint = GeneratePoint(z, _fish.transform.position.x); } timer = 0; moveTimer = 0; _strugglePoint.y = GetFishUnderwaterOffset(); if (fishingData.MaxYEscape > 0.001f) { _strugglePoint.y = fishingData.MaxYEscape * escapeDistanceMag; } if (fishingData.MaxZEscape > 0.001f) { _strugglePoint.z = fishingData.MaxZEscape * escapeDistanceMag; if (_strugglePoint.z < _fishSwimAreaZFar) { _strugglePoint.z = _fishSwimAreaZFar; } if (fishingData.DashStayTime <= 0 && !isJumping && _fish.transform.position.z < _strugglePoint.z - 5) { _strugglePoint.x = 0; } if (fishingData.NextPointEMin > 0.001f && fishingData.NextPointEMax > 0.001f) { _strugglePoint.z = _fish.transform.position.z + Random.Range(fishingData.NextPointEMin, fishingData.NextPointEMax); } } _curStartPos = _fish.transform.position; _curStartPos.y = GetFishUnderwaterOffset(); distance = Vector3.Distance(_curStartPos, _strugglePoint); //开始转向 FishTurn(); Vector3 offset = _strugglePoint - _curStartPos; Vector3 mid = (_strugglePoint + _curStartPos) / 2; float x; if (Math.Abs(offset.x) > Math.Abs(offset.z)) { x = offset.x * Random.Range(0, 0.25f); mid.z += offset.x * Random.Range(-0.25f, 0.25f); } else { //z轴比较长 x = offset.z * Random.Range(0, 0.25f); mid.z += offset.z * Random.Range(-0.25f, 0.25f); } if (mid.x * x > 0) { mid.x -= x; } else { mid.x += x; } float turnTime = 0; Vector3 fishPos = _fish.transform.position; Vector3[] path = new Vector3[] { _curStartPos, mid, _strugglePoint };// GetBezierCurvePoints(_curStartPos, mid, _strugglePoint, 10); baitDoTween = _fish.transform.DOPath(path, fishSpeed, PathType.CatmullRom).SetSpeedBased(true) .OnUpdate((() => { if (turnTime > GetTurnTime() + 0.2) { Quaternion rotation = Quaternion.LookRotation(fishPos - _fish.transform.position); _fish.transform.rotation = rotation; } else if (turnTime > GetTurnTime()) { Quaternion rotation = Quaternion.LookRotation(fishPos - _fish.transform.position); _fish.transform.rotation = Quaternion.Lerp(_fish.transform.rotation, rotation, (turnTime - GetTurnTime()) * 5); } fishPos = _fish.transform.position; turnTime += Time.deltaTime; })); if (fishingData.DashStayTime > 0.001f) { baitDoTween.SetEase(Ease.OutCubic); } else { baitDoTween.SetEase(Ease.Linear); } } } public void FishTurn() { FishingPanel_Advanced.Instance?.SetFishIconDir(_fish.transform.position.x > _strugglePoint.x); Quaternion rotation = Quaternion.LookRotation(_fish.transform.position - _strugglePoint); _fish.transform.DORotateQuaternion(rotation, GetTurnTime())/*.SetEase(Ease.InOutSine);*/; } Vector3 GeneratePoint(float z, float curX) { float x1 = (_fishSwimAreaXFar - _fishSwimAreaXNear) / (_fishSwimAreaZFar - _fishSwimAreaZNear) * (z - _fishSwimAreaZNear) + _fishSwimAreaXNear; //float x = Random.Range(_fishSwimAreaXNear, x1); float min = curX - x1; float max = curX + x1; if (min < -x1) { min = -x1; } if (max > x1) { max = x1; } float x = Random.Range(min, max); return new Vector3(x, 0, z); } bool isDashMove; bool DashMove() { fx_fishing_splashloopreeling.SetActive(false); string dashPerformanceFx = ""; if (fishingData.fishSpSkillData != null) { dashPerformanceFx = fishingData.fishSpSkillData.DashPerformanceFx(); } if (!isDashMove) { isDashMove = true; StartSplashloopScale(); FishBehaviour.SetTrigger("Skill"); if (!string.IsNullOrEmpty(dashPerformanceFx)) { LoadEffectNoMove(dashPerformanceFx, transform); } } dashTime += Time.deltaTime; if (dashTime < fishingData.DashStayTime) { DOTween.Kill("FishSkillStaminaParam"); fishingData.FishSkillStaminaState = 3; fishingData.FishSkillStaminaParam = 1 - dashTime / fishingData.DashStayTime; if (fishingData.superDashSpSkillData != null) { HideSpSkillFx("dashFx"); HideSpSkillFx("dashWaterFx"); } return false; } if (!string.IsNullOrEmpty(dashPerformanceFx)) { LoadEffectNoMove(dashPerformanceFx, false); } isDashMove = false; EndSplashloopScale(); if (fishingData.DashStayTime < 0) { fishingData.DashStay = null; return false; } else { fishingData.FishSkillStaminaState = 2; fishingData.FishSkillStaminaParam = 1; if (fishingData.superDashSpSkillData != null) { if (!IsPrepareDash) { IsPrepareDash = true; SetFishDash(); } else { IsPrepareDash = false; } } else { SetFishDash(); } } if (FishBehaviour) { FishBehaviour.PlaySwim01(); } DOTween.To(() => fishingData.FishSkillStaminaParam, x => fishingData.FishSkillStaminaParam = x, 0, Random.Range(5f, 10f)).SetId("FishSkillStaminaParam"); if (fishingData.fishSpSkillData != null) { string dashFx = fishingData.fishSpSkillData.FxDash(); if (!string.IsNullOrEmpty(dashFx)) { PlaySpSkillFx("dashFx", dashFx); } if (!IsPrepareDash) { //播放 DashWaterFx; string dashWaterFx = fishingData.fishSpSkillData.DashWaterFx(); if (!string.IsNullOrEmpty(dashWaterFx)) { PlaySpSkillFx("dashWaterFx", dashWaterFx, FishBehaviour.Tail); } } } if (fishingData.superDashSpSkillData == null || IsPrepareDash) { _strugglePoint = DashPoint(_fish.transform.position.x); } if (fishingData.superDashSpSkillData != null && IsPrepareDash) { fishSpeed /= dashSpeedInc; dashPrepareTime = fishingData.superDashSpSkillData.GetDashPrepareTime(fishingData.DashStay.SkillIndex - 1); dashTime = fishingData.DashStayTime; } else { if (fishingData.superDashSpSkillData != null) { MapData mapData = _tables.TbMapData.GetOrDefault(fishingData.MapId); fishSpeed *= mapData.EscapeSpeedMag; } dashTime = 0; } GContext.Publish(new EventFishingSound(SoundType.audio_fishing_dash)); fx_fishing_splashloopreeling.SetActive(true); return true; } FishDash GetFishDash() { List animationTypeList = fishingData.curFishData.AnimationTypeList; if (animationTypeList.Count <= 1) { return _tables.TbFishDash.GetOrDefault(animationTypeList[0]); } List fishDashes = new List(); int weight = 0; foreach (var item in animationTypeList) { FishDash fishDash = _tables.TbFishDash.GetOrDefault(item); if (fishDash != null) { fishDashes.Add(fishDash); weight += fishDash.Weight; } } if (fishDashes.Count == 1) { return fishDashes[0]; } int random = Random.Range(0, weight); foreach (var item in fishDashes) { random -= item.Weight; if (random <= 0) { return item; } } Debug.LogError("Not FishDash FishDataID =" + fishingData.curFishData.ID); return null; } bool IsPrepareDash = false; float dashPrepareTime; Vector3 DashPoint(float curX) { float near = _nearDistance; float far = _farDistance; if (fishingData.superDashSpSkillData != null) { var super = fishingData.superDashSpSkillData; int chargeCount = super.ChargeCount; float posz = super.PosZChange * chargeCount; near = super.PosZInit[0] + posz; far = super.PosZInit[1] + posz; super.AddChargeCount(); chargeCount = super.ChargeCount; fishSpeed *= (1 + super.DashSpeedChange * chargeCount); fishingData.StrugglingPower += super.StrengthChange; } float z = Random.Range(near, far); float x1 = (_fishSwimAreaXFar - _fishSwimAreaXNear) / (_farDistance - _nearDistance) * (z - _nearDistance) + _fishSwimAreaXNear; float nextPointNear = x1 * fishingData.NextPointMin; float nextPointFar = x1 * fishingData.NextPointMax; float point = Random.Range(nextPointNear, nextPointFar); float x = point; if (curX > 0) { x = -point; } return new Vector3(x, 0, z); } Dictionary spKillFxDict = new Dictionary(); public void HideSpSkillFx(string key) { if (spKillFxDict.TryGetValue(key, out GameObject fx)) { if (fx != null) { fx.SetActive(false); } } } public async void PlaySandStorm(float delay, SandStorm sandStorm) { await Task.Delay((int)(delay * 1000)); var fx = await PlaySpSkillFx("sandStormFx", sandStorm.JumpFx, transform); if (fx != null) { fx.SetActive(false); fx.SetActive(true); } } public async Task PlaySpSkillFx(string key, string fxName, Transform parent = null) { if (!spKillFxDict.TryGetValue(key, out GameObject fx)) { spKillFxDict[key] = null; if (key == "struggleFx") { parent = FishBehaviour.Neck; } if (parent == null) { parent = FishBehaviour.Root; } fx = await Addressables.InstantiateAsync(fxName, parent).Task; if (fx == null) { return null; } spKillFxDict[key] = fx; } else { fx = spKillFxDict[key]; } if (fx != null) { fx.SetActive(true); } return fx; } }