using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using GameCore; using Random = UnityEngine.Random; using cfg; using UnityEngine.AddressableAssets; using asap.core; using Game; using UniRx; using System.Threading.Tasks; public class GetFishingBehaviorB { public FishingBehaviorB fishingBehavior; } public class ShowHandEvent { public bool isShow; } [DefaultExecutionOrder(10000)] public partial class FishingBehaviorB : MonoBehaviour { Tables _tables; [Header("RELATED OBJECT SETTINGS")] [SerializeField] private GameObject _bait; GameObject baitAB; public GameObject GetBait => _bait; [SerializeField] private GameObject _fish; [HideInInspector] public Transform FishAnimationRoot; public FishCome fishCome; [HideInInspector] public Transform FishComeAnimationRoot; public GameObject GetFish => _fish; //private Vector3 _baitInitPoint; //private Vector3 _baitSpawnPoint; private Vector3 _baitFowardDirection; [Header("FISHINGROD SETTINGS")] //相机初始化 public Animator _cameraAnimator; public Animator cameraAnimator => _cameraAnimator; int rodType; public int RodType => rodType; [SerializeField] private GameObject _fishingRodHandle; public Animator rodHandleAni; private Vector3 _targetPos; [HideInInspector] public Animator fishingRodAnimator; // [HideInInspector] public Animator reelAni; [HideInInspector] public Animator fishAnimator; [HideInInspector] public Fish FishBehaviour; Material F_whitemarli_P; bool isShowFish = false; [HideInInspector] public Fish FishSwimBehaviour; //private Bait BaitBehaviour; [HideInInspector] public Rod RodBehaviour; GameObject rodPrefab; [Header("FISHING LINE SETTINGS")] [Tooltip("_lineResolution:The length of the line section depends on the distance. X = close, Y = far")] [SerializeField] private Vector2 _lineResolution; // 钓鱼线的分辨率 [SerializeField] private Transform _lineStartPos; // 钓鱼线的起始位置 [SerializeField] private Vector2 _lineStartOffsetScreen = new Vector2(0.3f, 1.5f); //鱼线起始位置停留位置偏移 [SerializeField] private float _lineMoveTimer = 1f; //鱼线移动时间 FishingBehaviorConf fishingBehaviorConf; [Space(10)] //相机偏转最大角度 [SerializeField] private float _cameraMaxAngel = 11f; //相机偏转最大角度 //相机偏转最大角度鱼的X轴偏移 [SerializeField] private float _cameraMaxAngelOffset = 15f; //相机偏转最大角度鱼的X轴偏移 [Space(10)] //水面高度 [SerializeField] private float _waterHeight = -2.7f; //水面高度 //鱼游动区域 float _fishSwimAreaZFar = 75f; //鱼游动Z轴远端 float _fishSwimAreaZNear = 15f; //鱼游动Z轴近端 float _fishSwimAreaXFar = 17.5f; //鱼游动X轴远端 float _fishSwimAreaXNear = 5f; //鱼游动X轴近端 public float XAxisMaxProportion = 0.5f; public float fishSwimAreaZFar => _fishSwimAreaZFar; public float fishSwimAreaZNear => _fishSwimAreaZNear; HandController HandController; GameObject handAB; //============================================================================================= //private Vector3 _startPos; //状态判断 private bool _isReeling; private bool _isFishComeOutWater; private Dictionary _effectDic = new Dictionary(); [HideInInspector] public GameObject _curFishEffect; //_drawing [HideInInspector] public GameObject fx_fishing_splashloop; [HideInInspector] public GameObject fx_fishing_splashwaveloop; [HideInInspector] public GameObject fx_fishing_splashloopreeling; //[HideInInspector] public GameObject fx_fishing_splashpull; [HideInInspector] public GameObject fx_fishing_jumpout; [HideInInspector] public GameObject fx_fishing_jumpinto; [HideInInspector] public GameObject fx_fishing_splashinto; GameObject fxWaterDrop; //_drawing private int Count = 20; //private float ReelVibrationInterval = 0; private DropAfterDrop dropAfterDrop = null; Transform dropAfterDropParent = null; GameObject collectingEffect = null; public Vector3 image_extra_pos { set; get; } GameObject FishPrefab; GameObject FishSwimPrefab; public GameObject fx_fishbosscome; GameObject curFish; string currentFishPath; string currentSwimFishPath; // 参数设置 private float _simulateGravityOnLine = -0.7f; // 模拟重力 private float _currentGravityOnLine = 0f; // 当前重力 private float _gravityonLineTimer = 0f; // 重力计时器 public float LineDistance { get; private set; } private Vector3 _endLinePos; //结束时鱼线的位置 //================================================================================================ [Space(10)] //代码设置属性 private bool _isChangelineStartPos = false; public bool IsChangelineStartPos { set { _isChangelineStartPos = value; } } private bool _isCastLine; //mainCamera 是否对准鱼 public bool CameraToFish { set; get; } //private float curPressForce = 0f; Quaternion camStartRotation; public Vector3 GetFishPos() { if (FishBehaviour == null) { return _fish.transform.position; } if (FishBehaviour.mouthPos == null) { return FishBehaviour.transform.position; } return FishBehaviour.mouthPos.transform.position; } //UI吃鱼大鱼游过来 [HideInInspector] public bool NotMove = false; FishingData fishingData; CollectingData collectingData; float FinUnderwaterOffset; protected CompositeDisposable disposables = new CompositeDisposable(); private void OnEnable() { StartRodSpidleTime(); rodHandleAni = _fishingRodHandle.GetComponent(); fishAnimator = _fish.transform.GetComponent(); SetRodType(); } public void Init() { fishingData = GContext.container.Resolve(); fishingBehaviorConf = fishingData.fishingBehaviorConf; collectingData = GContext.container.Resolve(); GContext.OnEvent().Subscribe((e) => { IsCancelled(); }).AddTo(disposables); GContext.OnEvent().Subscribe((e) => { IsRecast(e.isRecast); }).AddTo(disposables); ; GContext.OnEvent().Subscribe((e) => { e.fishingBehavior = this; }).AddTo(disposables); GContext.OnEvent().Subscribe(OnEnableHand).AddTo(disposables); var _camera = _cameraAnimator.transform.Find("Camera"); fishingData.SetCamera(_camera); LoadBait(); fishAnimator = _fish.transform.GetComponent(); FishAnimationRoot = _fish.transform.Find("FishAnimationRoot"); FishComeAnimationRoot = fishCome.transform.Find("FishAnimationRoot"); _tables = GContext.container.Resolve(); //初始地图配置 var SwimmingAreaX = fishingData.SwimmingAreaX(); var SwimmingAreaZ = fishingData.SwimmingAreaZ(); _fishSwimAreaXNear = SwimmingAreaX[0]; _fishSwimAreaXFar = SwimmingAreaX[1]; _fishSwimAreaZNear = SwimmingAreaZ[0]; _fishSwimAreaZFar = SwimmingAreaZ[1]; _cameraMaxAngel = ConvertTools.CalculateActualRotationAngle(fishingData.CameraMaxAngle()); _cameraMaxAngelOffset = fishingData.FishMaxAngle(); rodHandleAni = _fishingRodHandle.GetComponent(); } public async Task LoadHand() { GloveData gloveData = GContext.container.Resolve().GetGloveData; string path = gloveData.Fbx; if (handAB != null) { Addressables.ReleaseInstance(handAB); } Debug.Log("InitRodHand" + path); handAB = await Addressables.InstantiateAsync(gloveData.Fbx, transform).Task; if (handAB != null) { HandController = handAB.GetComponent(); if (RodBehaviour != null) { HandController.SetHandTargets(RodBehaviour.RightHandTargets, RodBehaviour.LeftHandTargets, RodBehaviour.BodyTargets); } } } async void LoadBait() { baitAB = await Addressables.InstantiateAsync("BaitRoot", _bait.transform).Task; baitAB.transform.localPosition = Vector3.zero; baitAB.transform.localRotation = Quaternion.identity; baitAB.transform.localScale = Vector3.one; } public float GetSpeedHpCurveValue(float key) { return fishingBehaviorConf.speedHpCurve.Evaluate(key); } public void OnFishingEnable() { //初始化鱼饵组件、投掷位置、方向 //_baitSpawnPoint = _fishingRodHandle.transform.position + new Vector3(0, 1f, 0); _baitFowardDirection = _fishingRodHandle.transform.forward; //将_fishingrodhandle的transform的y轴-90 _baitFowardDirection = Quaternion.AngleAxis(-90, Vector3.up) * _baitFowardDirection; //_baitInitPoint = _bait.transform.position; camStartRotation = fishingData.mainCamera.rotation; } public async void GMInitFishAsync(string path, float scale) { currentFishPath = path; //准备开始钓鱼 if (FishBehaviour != null) { FishBehaviour.gameObject.SetActive(false); if (FishBehaviour.modeGo) { Addressables.ReleaseInstance(FishBehaviour.modeGo); } Addressables.Release(FishPrefab); DestroyImmediate(FishBehaviour.gameObject); FishBehaviour = null; } Transform parent = _fish.transform.Find("FishAnimationRoot"); var fishPrefab = await Addressables.LoadAssetAsync(path).Task; if (fishPrefab != null) { if (currentFishPath != path || FishBehaviour != null) { Addressables.Release(fishPrefab); return; } var go = Instantiate(fishPrefab, parent); if (go == null) return; go.transform.localPosition = Vector3.zero; FishPrefab = fishPrefab; FishBehaviour = go.GetComponent(); FishBehaviour.transform.localScale = Vector3.one * scale; Vector3 vector3 = Vector3.zero; if (FishBehaviour.mouthPos != null) { FishBehaviour.animator.Play("Idle01", 0, 0); vector3 = -FishBehaviour.animator.transform.InverseTransformPoint(FishBehaviour.mouthPos.position); vector3.z = -vector3.z; } FishBehaviour.animator.transform.localPosition = vector3; FishBehaviour.transform.localRotation = Quaternion.identity; GContext.Publish(new FishRotateEvent(0, 1, rodType)); } } public void InitFishAsync(string path, float scale, bool isShow, DropAfterDrop dropAfterDrop = null) { currentFishPath = path; //准备开始钓鱼 if (FishBehaviour != null) { FishBehaviour.gameObject.SetActive(false); if (FishBehaviour.modeGo) { Addressables.ReleaseInstance(FishBehaviour.modeGo); } //if (fx_fishing_splashloop != null) //{ // Addressables.ReleaseInstance(fx_fishing_splashloop); // DestroyImmediate(fx_fishing_splashloop); // fx_fishing_splashloop = null; //} Addressables.Release(FishPrefab); DestroyImmediate(FishBehaviour.gameObject); FishBehaviour = null; } LoadFish(path, scale, isShow, dropAfterDrop: dropAfterDrop); if (isShow) { ShowDefaultFish(); } } public void DestroySwimFish() { if (FishSwimBehaviour != null) { FishSwimBehaviour.gameObject.SetActive(false); Addressables.Release(FishSwimPrefab); DestroyImmediate(FishSwimBehaviour.gameObject); FishSwimBehaviour = null; } currentSwimFishPath = null; if (fx_fishbosscome != null) { Addressables.ReleaseInstance(fx_fishbosscome); DestroyImmediate(fx_fishbosscome); fx_fishbosscome = null; } } public async void InitSwimFishAsync(FishData swimFishData) { if (fishCome == null) { return; } var path = swimFishData.Fbx; var scale = swimFishData.CruiseScale; if (currentSwimFishPath != path) { currentSwimFishPath = path; //准备开始钓鱼 if (FishSwimBehaviour != null) { FishSwimBehaviour.gameObject.SetActive(false); Addressables.ReleaseInstance(fx_fishbosscome); Addressables.Release(FishSwimPrefab); DestroyImmediate(FishSwimBehaviour.gameObject); FishSwimBehaviour = null; fx_fishbosscome = null; } Transform parent = fishCome.transform.Find("FishAnimationRoot"); var fishPrefab = await Addressables.LoadAssetAsync(path).Task; if (fishPrefab != null) { if (currentSwimFishPath != path) { Addressables.Release(fishPrefab); return; } var go = Instantiate(fishPrefab, parent); if (go != null) { go.SetActive(false); go.transform.localPosition = Vector3.zero; FishSwimPrefab = fishPrefab; FishSwimBehaviour = go.GetComponent(); Vector3 vector3 = Vector3.zero; if (FishSwimBehaviour.mouthPos != null) { vector3 = -FishSwimBehaviour.animator.transform.InverseTransformPoint(FishSwimBehaviour.mouthPos.position); vector3.z = -vector3.z; } FishSwimBehaviour.animator.transform.localPosition = vector3; FishSwimBehaviour.transform.localRotation = Quaternion.identity; FishSwimBehaviour.transform.localScale = Vector3.one * scale; FishSwimBehaviour.FishAnimSpeed = swimFishData.AnimSpeed; fishCome.animator.speed = swimFishData.AnimSpeed; fx_fishbosscome = await Addressables.InstantiateAsync("fx_fishing_fishbosscome", transform).Task; if (fx_fishbosscome) { fx_fishbosscome.transform.localScale = Vector3.one * swimFishData.SlashFxScale; fx_fishbosscome.SetActive(false); } float offset = fishingData.swimFishData.UnderwaterOffset; if (FishSwimBehaviour != null && FishSwimBehaviour.Fin != null) { offset -= FishSwimBehaviour.Fin.position.y - fishCome.transform.position.y; } fishCome.SetPosY(offset); } } } } public void SetFishScale(float fishScale) { if (FishBehaviour != null) { FishBehaviour.transform.localScale = Vector3.one * fishScale; } } void SetRodType() { cameraAnimator.SetInteger("_rodtype", rodType); rodHandleAni.SetInteger("_rodtype", rodType); fishAnimator.SetInteger("_rodtype", rodType); } public async System.Threading.Tasks.Task InitFishRodAsync(RodData fishRodData) { rodType = (int)fishRodData.Type; fishingData.rodType = rodType; SetRodType(); int skindID = GContext.container.Resolve().GetRodSkin(fishRodData.ID); if (skindID <= 0) { return; } var fishRodSkinData = _tables.TbRodSkinData.GetOrDefault(skindID); if (fishRodSkinData == null) { return; } string path = fishRodSkinData.Fbx; float FishingScale = fishRodSkinData.FishingScale; var goPrefab = await Addressables.LoadAssetAsync(path).Task; _bait.transform.SetParent(transform); if (goPrefab != null) { if (rodPrefab) { Addressables.Release(rodPrefab); } rodPrefab = goPrefab; var go = Instantiate(goPrefab, transform.Find("FishingRodHandle")); //await Addressables.InstantiateAsync(path, transform.Find("FishingRodHandle")).Task; go.transform.localPosition = Vector3.zero; go.transform.localScale = Vector3.one * FishingScale; if (RodBehaviour != null) { DestroyImmediate(RodBehaviour.gameObject); } RodBehaviour = go.GetComponent(); Debug.Log("RodBehaviour" + RodBehaviour); fishingRodAnimator = RodBehaviour.rod.GetComponent(); if (gameObject.activeInHierarchy) StartRodSpidleTime(); //Set HandIK Target if (HandController != null) { HandController.SetHandTargets(RodBehaviour.RightHandTargets, RodBehaviour.LeftHandTargets, RodBehaviour.BodyTargets); } if (RodBehaviour.cCDIK != null) { RodBehaviour.cCDIK.enabled = false; } //准备开始钓鱼 SetShowRod(true); PrepareFishing(); } } Coroutine spIdle; public void ShowRod(bool isShow) { if (RodBehaviour != null) { RodBehaviour.rod.SetActive(isShow); if (HandController != null) { HandController.SetActive(isShow); } GContext.Publish(ERightState.Idle); } } public void OnEnableHand(ShowHandEvent value) { if (HandController != null) { HandController.SetActive(value.isShow); } } void StartRodSpidleTime() { if (spIdle != null) { StopCoroutine(spIdle); spIdle = null; } if (fishingRodAnimator != null) { spIdle = StartCoroutine(RodSpidleTime()); } } IEnumerator RodSpidleTime() { while (true) { yield return new WaitForSeconds(fishingBehaviorConf.rodSpidleTime); float spidle = Random.value; if (spidle <= fishingBehaviorConf.rodSpidle) { fishingRodAnimator.SetTrigger("_spidle"); } } } //准备开始钓鱼 public void PrepareFishing() { if (fxWaterDrop != null) { fxWaterDrop.SetActive(false); } _isCastLine = false; _isReeling = false; _currentGravityOnLine = 0f; _gravityonLineTimer = 0f; _isChangelineStartPos = false; fishAnimator.SetTrigger("_idle"); cameraAnimator.SetBool("_maxcomboExit", false); cameraAnimator.SetBool("_maxcombo", false); } public void SetShowRod(bool isShowRod) { if (RodBehaviour != null) { if (RodBehaviour.rod != null) { ShowRod(isShowRod); } RodBehaviour.fishingLineRenderer.enabled = true; RodBehaviour.fishingLineRenderer.gameObject.SetActive(isShowRod); _bait.transform.SetParent(RodBehaviour.Bait); _bait.transform.localPosition = Vector3.zero; //-Vector3.up * 0.1f; _bait.transform.localRotation = Quaternion.Euler(Vector3.forward * 90); _bait.gameObject.SetActive(true); } } public async void LoadEffect(string path, bool active = true) { if (_effectDic.ContainsKey(path)) { _curFishEffect = _effectDic[path]; _curFishEffect.SetActive(false); if (active) { _curFishEffect.SetActive(true); } Vector3 vector = _fish.transform.position; vector.y = _waterHeight; _curFishEffect.transform.position = vector; } else { _curFishEffect = null; var prefab = await Addressables.InstantiateAsync(path, transform, true).Task; if (prefab != null) { _curFishEffect = prefab; // _curFishEffect.transform.localPosition = Vector3.zero; _curFishEffect.gameObject.SetActive(active); Vector3 vector = _fish.transform.position; vector.y = _waterHeight; _curFishEffect.transform.position = vector; _effectDic.Add(path, _curFishEffect); } } if (path == "fx_fishing_splashwaveloop") { fx_fishing_splashwaveloop = _curFishEffect; _curFishEffect.transform.localScale = Vector3.one * fishingData.curFishData.SlashFxScale; } else if (path == "fx_fishing_splashloopreeling") { fx_fishing_splashloopreeling = _curFishEffect; } //else if (path == "fx_fishing_splashpull") //{ // fx_fishing_splashpull = _curFishEffect; //} else if (path == "fx_fishing_jumpout") { fx_fishing_jumpout = _curFishEffect; } else if (path == "fx_fishing_jumpinto") { fx_fishing_jumpinto = _curFishEffect; } else if (path == "fx_fishing_splashinto") { fx_fishing_splashinto = _curFishEffect; } } public void SetCurFishEffectPos() { if (_curFishEffect != null) { Vector3 vector; if (FishBehaviour != null && FishBehaviour.Tail != null) { vector = FishBehaviour.Tail.position; } else { vector = _fish.transform.position; } //if (fxWaterSplash != null) //{ // fxWaterSplash.transform.rotation = _fish.transform.rotation; // fxWaterSplash.transform.position = vector; // fxWaterSplash.SetActive(true); // fx_fishing_splashloop.SetActive(false); //} //else if (fx_fishing_splashloop) { fx_fishing_splashloop.transform.rotation = _fish.transform.rotation; fx_fishing_splashloop.transform.position = vector; } vector = _fish.transform.position; vector.y = _waterHeight; _curFishEffect.transform.rotation = _fish.transform.rotation; _curFishEffect.transform.position = vector; fx_fishing_splashloopreeling.transform.position = vector; } if (fx_fishbosscome != null && FishSwimBehaviour != null) { Vector3 vector; if (FishSwimBehaviour.Tail != null) { vector = FishSwimBehaviour.Tail.position; fx_fishbosscome.transform.rotation = FishComeAnimationRoot.rotation; } else { vector = FishSwimBehaviour.transform.position; } vector.y = _waterHeight; fx_fishbosscome.transform.position = vector; } } public void PlayCollectingEffect() { if (dropAfterDrop != null && _effectDic.ContainsKey(dropAfterDrop.Fx)) { collectingEffect = _effectDic[dropAfterDrop.Fx]; if (FishBehaviour != null && FishBehaviour.modeGo != null) { GameObject effect = Instantiate(collectingEffect, FishBehaviour.modeGo.transform); effect.transform.localPosition = Vector3.zero; effect.SetActive(true); } else { collectingEffect.transform.position = FishAnimationRoot.transform.position; collectingEffect.SetActive(true); } } } //void CollectingEffectOff() //{ // if (FishBehaviour != null && FishBehaviour.modeGo != null) // { // FishBehaviour.modeGo.SetActive(false); // } //} //Vector3 CollectingEffectPos() //{ // if (FishBehaviour != null && FishBehaviour.modeGo != null) // { // return ConvertTools.WorldToScreenPoint(FishBehaviour.modeGo.transform.position); // } // return Vector3.zero; //} public void SetEffectActive(string path, bool active) { if (_effectDic.ContainsKey(path)) { GameObject effect = _effectDic[path]; effect.SetActive(active); } } //开始抛鱼线 public async void CastLineBehavior() { //计算主画布分辨率下的宽高和屏幕的宽高的比列: fishingData.mainCamera.DOLocalRotateQuaternion(Quaternion.identity, 0.1f); //_endTargetPos = Camera.main.ViewportToWorldPoint(new Vector3(_widthScreen, _heightScreen, 5)); //_endLinePos = Camera.main.ViewportToWorldPoint(new Vector3(_lineStartOffsetScreen.x, _lineStartOffsetScreen.y, 5)); //_endLinePos.x = 0f; //_endLinePos.y = 8; await Awaiters.NextFrame; CastBait(); //播放抛竿动画 fishingRodAnimator.SetTrigger("_throwing"); GContext.Publish(ERightState.Throwing); _cameraAnimator.SetTrigger("_throwing"); rodHandleAni.SetBool("_idle", false); rodHandleAni.SetTrigger("_drawing"); await Awaiters.Seconds(fishingBehaviorConf.audioDelay); GContext.Publish(new EventFishingSound(SoundType.ThrowingAudio)); GContext.Publish(new VibrationData(1)); } private void ConsumeBait() { if (fishingData.IsFree) { WaitForFishBiteED(); } else { DoConsumeBait(); } } private void DoConsumeBait() { if (Application.internetReachability == NetworkReachability.NotReachable) { NoInternet(); } else { ConsumeBaitOnPlayfab(); WaitForFishBiteED(); } } private async void NoInternet() { GameObject go = await UIManager.Instance.ShowUI(UITypes.NoticeConfirmPopupPanel); var NoticeConfirmPopupPanel = go.GetComponent(); string info = LocalizationMgr.GetText("UI_FishingReconnectPanel_101003"); string label = LocalizationMgr.GetText("UI_FishingRewardPanel_101022"); string title = LocalizationMgr.GetText("UI_FishingReconnectPanel_101002"); NoticeConfirmPopupPanel.Init(1, title, info, onClickLeft: DoConsumeBait, onClose: DoConsumeBait, btn_left_text: label); } private async void ConsumeBaitOnPlayfab() { var playerData = GContext.container.Resolve(); EnergyDef energyDef = _tables.TbEnergyDef.DataList[playerData.magnification]; var energy = energyDef.Mag; if (fishingData.IsRetry) { energy = energyDef.RetryCost; } var commonDatas = new Dictionary(playerData.PlayerDataDic); commonDatas["energy"] = (playerData.Energy - energy).ToString(); playerData.ReduceEnergy(energy, false); var success = await PlayFabMgr.Instance.SyncDataImmidiate("NewPlayerDataDic", Newtonsoft.Json.JsonConvert.SerializeObject(commonDatas)); Debug.Log($"[FishBehaviourB::ConsumeBaitOnPlayfab] {success}"); } void LoadFish() { if (FishBehaviour == null) { int id = _tables.GetItemData(_tables.TbGlobalConfig.FishUnDownloadAlter[fishingData.curFishData.Quality - 1]).RedirectID; var curFishData = _tables.GetFishData(id); string path = curFishData.Fbx; float scale = curFishData.MaxScale; currentFishPath = path; LoadFish(path, scale, isShowFish, false); } } public float GetFishUnderwaterOffset() { float offset = fishingData.curFishData.UnderwaterOffset; offset -= FinUnderwaterOffset; offset += fishingData.ExtraUnderwaterOffset; return offset; } async void LoadFish(string path, float scale, bool isShow = true, bool showDefault = true, DropAfterDrop dropAfterDrop = null) { this.dropAfterDrop = dropAfterDrop; isShowFish = isShow; Transform parent = _fish.transform.Find("FishAnimationRoot"); var fishPrefab = await Addressables.LoadAssetAsync(path).Task; if (fishPrefab != null) { if (this == null || currentFishPath != path || FishBehaviour != null) { Addressables.Release(fishPrefab); return; } var go = Instantiate(fishPrefab, parent); if (go == null) return; go.transform.localPosition = Vector3.zero; FishPrefab = fishPrefab; FishBehaviour = go.GetComponent(); SetFishScale(scale); Vector3 vector3 = Vector3.zero; if (FishBehaviour.mouthPos != null) { FishBehaviour.animator.Play("Swim01", 0, 0); vector3 = -FishBehaviour.animator.transform.InverseTransformPoint(FishBehaviour.mouthPos.position); vector3.z = -vector3.z; } go.SetActive(false); FishBehaviour.animator.transform.localPosition = vector3; FishBehaviour.transform.localRotation = Quaternion.identity; if (FishBehaviour.Fin != null) { FinUnderwaterOffset = FishBehaviour.Fin.position.y - _fish.transform.position.y; Vector3 ver = _fish.transform.position; ver.y = GetFishUnderwaterOffset(); _fish.transform.position = ver; } if (dropAfterDrop != null && dropAfterDrop.Bone != "None") { curFish = FishBehaviour?.gameObject; dropAfterDropParent = FishBehaviour.Find(dropAfterDrop.Bone); if (dropAfterDropParent != null) { var modeGo = await Addressables.InstantiateAsync(dropAfterDrop.Mode).Task; if (FishBehaviour == null || curFish == null || curFish != FishBehaviour.gameObject) { Addressables.ReleaseInstance(modeGo); return; } if (modeGo != null) { CollectingPropScale collectingPropScale = _tables.TbCollectingPropScale[fishingData.curFishData.Quality]; var eulerAngles = modeGo.transform.localEulerAngles; var localPosition = modeGo.transform.localPosition; modeGo.transform.SetParent(dropAfterDropParent); modeGo.transform.localScale *= collectingPropScale.Scale; modeGo.transform.localEulerAngles = eulerAngles; modeGo.transform.localPosition = localPosition; FishBehaviour.modeGo = modeGo; } if (dropAfterDrop.Fx != "None" && !_effectDic.ContainsKey(dropAfterDrop.Fx)) { var fxGo = await Addressables.InstantiateAsync(dropAfterDrop.Fx, transform, true).Task; if (fxGo != null) { fxGo.SetActive(false); fxGo.transform.localPosition = Vector3.zero; _effectDic.Add(dropAfterDrop.Fx, fxGo); } } } } FishBehaviour.gameObject.SetActive(isShowFish); if (fx_fishing_splashloop == null) { fx_fishing_splashloop = await Addressables.InstantiateAsync("fx_fishing_splashloop", transform).Task; } if (fx_fishing_splashloop != null) { fx_fishing_splashloop.SetActive(isShowFish); fx_fishing_splashloop.transform.localScale = Vector3.one * fishingData.curFishData.SlashFxScale; } if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.transform.localScale = Vector3.one * fishingData.curFishData.SlashFxScale; } } else if (showDefault) { LoadFish(); } } async void ShowDefaultFish() { if (FishBehaviour == null) { await Awaiters.Seconds(3f); LoadFish(); } } //鱼咬钩,显示按钮 void WiattingForFish() { ShowDefaultFish(); NotMove = false; var pos = _bait.transform.position; pos.y = GetFishUnderwaterOffset(); _fish.transform.position = pos; LoadEffect("fx_fishing_splashtip"); fishingRodAnimator.SetTrigger("_biting"); } //public void Waiting01() //{ // CloseIK(); // fishingRodAnimator.Play("Waiting01", 0, 0); // float EnhancedWaitingTime = fishingData.EnhancedWaitingTime; // float timer = Mathf.Lerp(fishingBehaviorConf.waitingMinTime, fishingBehaviorConf.waitingMaxTime, Random.value) * EnhancedWaitingTime; // if (timer < 0) // { // timer = 0.01f; // } // GContext.Publish(new EventFishingSound(SoundType.audio_fishing_throwing_baitintowater)); // GContext.Publish(new EventFishingSound(SoundType.audio_fishing_waiting_fishgathering)); // StartCoroutine(PlayWaitingFx(timer)); // StartCoroutine(WaitForFishBite(timer)); //} public float WaitingZ() { return fishingBehaviorConf.flyDistance - fishingBehaviorConf.waitingDistance; } public void BaitMove() { flyEndPosTrue = _bait.transform.position; float EnhancedWaitingTime = fishingData.EnhancedWaitingTime; float z = WaitingZ(); float timer = Mathf.Lerp(fishingBehaviorConf.waitingMinTime, fishingBehaviorConf.waitingMaxTime, Random.value) * EnhancedWaitingTime; if (timer < 0) { timer = 0.01f; } GContext.Publish(new EventFishingSound(SoundType.audio_fishing_throwing_baitintowater)); GContext.Publish(new EventFishingSound(SoundType.audio_fishing_waiting_fishgathering)); StartCoroutine(PlayWaitingFx(timer)); LoadEffect("fx_fishing_splashloopwaiting"); var fishEffect = _effectDic["fx_fishing_splashloopwaiting"]; _bait.transform.DOLocalMoveZ(z, timer).OnUpdate( (() => { flyEndPosTrue = _bait.transform.position; if (fishEffect) { Vector3 vector = _bait.transform.position; vector.y = _waterHeight; fishEffect.transform.position = vector; } })); ; StartCoroutine(WaitForFishBite(timer)); } IEnumerator PlayWaitingFx(float timer) { Vector3 vector = _bait.transform.position; vector.y = _waterHeight; vector.z = WaitingZ(); var waitFx = timer - 1.5f + fishingBehaviorConf.waitingPlay; if (waitFx < 0) { waitFx = 0; } yield return new WaitForSeconds(waitFx); var fishEffect = _effectDic.ContainsKey("fx_fishing_splashwaiting") ? _effectDic["fx_fishing_splashwaiting"] : null; if (fishEffect != null) { fishEffect.transform.position = vector; fishEffect.gameObject.SetActive(true); } } private IEnumerator WaitForFishBite(float timer) { EventFishingSound eventFishingSound1 = new EventFishingSound(SoundType.audio_fishing_waiting); EventFishingSound eventFishingSound2 = new EventFishingSound(SoundType.ReelingAudio, loop: true); GContext.Publish(eventFishingSound1); GContext.Publish(eventFishingSound2); yield return new WaitForSeconds(timer); GContext.Publish(new FadeOutEvent(eventFishingSound2.Sound)); SetBaitStartPos(); ConsumeBait(); //WaitForFishBiteED(); } void WaitForFishBiteED() { WiattingForFish(); if (FishingPanel_Advanced.Instance != null) { FishingPanel_Advanced.Instance?.ShowDrawButton(); } SetEffectActive("fx_fishing_splashloopwaiting", false); GContext.Publish(new VibrationData(2)); } void InitEffect() { LoadEffect("fx_fishing_splashinto", false); //水线 LoadEffect("fx_fishing_splashloopwaiting", false); //鱼群 LoadEffect("fx_fishing_splashwaiting", false); LoadEffect("fx_fishing_splashwaveloop", false); LoadEffect("fx_fishing_splashloopreeling", false); LoadEffect("fx_fishing_splashpull", false); LoadEffect("fx_fishing_splashtip", false); LoadEffect("fx_fishing_jumpout", false); LoadEffect("fx_fishing_jumpinto", false); if (fx_fishing_splashloop != null) { fx_fishing_splashloop.SetActive(false); } } List vector3s = new List(); bool _isLineSin = false; Vector3 flyEndPosTrue; async void AddLinePos() { float allTime = fishingBehaviorConf.flyToWaterTime * fishingBehaviorConf.fishApproachingZRatio; float time = allTime; float timeInterval = 0; vector3s.Clear(); flyEndPosTrue = new Vector3(0, _waterHeight, fishingBehaviorConf.flyDistance); float zeroTime = allTime + fishingBehaviorConf.flyToWaterTime; float elapsedTime = 0.03f; while (_isCastLine) { float subTime = elapsedTime; timeInterval += subTime; zeroTime -= subTime; await Awaiters.Seconds(elapsedTime); if (time > 0) { time -= subTime; _isLineSin = true; ParabolaHarmonicSimulation parabolaHarmonicSimulation = new ParabolaHarmonicSimulation(); parabolaHarmonicSimulation.startPos = _lineStartPos.transform.position; parabolaHarmonicSimulation.starTime = timeInterval; parabolaHarmonicSimulation.allTime = allTime; //GameObject obj = GameObject.CreatePrimitive(PrimitiveType.Cube); //parabolaHarmonicSimulation.obj = obj; vector3s.Add(parabolaHarmonicSimulation); } for (int i = 0; i < vector3s.Count; i++) { vector3s[i].curTime = timeInterval; } } _isLineSin = false; } Vector3 GetCurPos(ParabolaHarmonicSimulation data, out float zeroTime) { float starTime = data.starTime; float curTime = data.curTime - starTime; //归0时间 zeroTime = curTime / data.allTime; Vector3 startPos = Vector3.Lerp(data.startPos, _lineStartPos.transform.position, zeroTime); float time = curTime / fishingBehaviorConf.flyToWaterTime; Vector3 vector3 = flyEndPosTrue; if (time < 1) { float x = Mathf.Lerp(startPos.x, flyEndPosTrue.x, time); float yTime = fishingBehaviorConf.flyDownCurve.Evaluate(time); float y = Mathf.Lerp(startPos.y, flyEndPosTrue.y, time); float zTime = fishingBehaviorConf.flyForwardCurve.Evaluate(time); float z = Mathf.Lerp(startPos.z, flyEndPosTrue.z, zTime); vector3 = new(x, y, z); } return vector3; } private async void CastBait() { InitEffect(); if (fishingBehaviorConf.fishFreeControlTime > 0f) { await new WaitForSeconds(fishingBehaviorConf.fishFreeControlTime); _isCastLine = true; _bait.transform.SetParent(transform); _bait.transform.DOMoveX(0, fishingBehaviorConf.flyToWaterTime); _bait.transform.DOMoveZ(fishingBehaviorConf.flyDistance, fishingBehaviorConf.flyToWaterTime).SetEase(fishingBehaviorConf.flyForwardCurve); _cameraAnimator.SetTrigger("_waiting"); _bait.transform.DOMoveY(_waterHeight, fishingBehaviorConf.flyToWaterTime) .SetEase(fishingBehaviorConf.flyDownCurve).OnComplete((() => { fishingRodAnimator.SetTrigger("_waiting"); GContext.Publish(ERightState.Waiting); LoadEffect("fx_fishing_splashinto"); Vector3 vector = _bait.transform.position; vector.y = _waterHeight; _curFishEffect.transform.position = vector; BaitMove(); _bait.SetActive(false); })); AddLinePos(); } else { await new WaitForSeconds(1.15f); //当前动画_fishingRodAnimator播放时间 float time = fishingRodAnimator.GetCurrentAnimatorStateInfo(0).normalizedTime; _isCastLine = true; _cameraAnimator.SetTrigger("_waiting"); await new WaitForSeconds(time); _bait.transform.SetParent(transform); _bait.SetActive(false); //鱼漂位置 Vector3 ver = _bait.transform.position; ver.y = _waterHeight; _bait.transform.position = ver; fishingRodAnimator.SetTrigger("_waiting"); GContext.Publish(ERightState.Waiting); LoadEffect("fx_fishing_splashinto"); Vector3 vector = _bait.transform.position; vector.y = _waterHeight; _curFishEffect.transform.position = vector; BaitMove(); } } #if UNITY_EDITOR public async void GMPiercingIndex(int index) { rodHandleAni.SetTrigger("_drawing"); _ = StartCoroutine(PiercingTimeScale(index - 1)); _cameraAnimator.SetInteger("_piercingState", index); fishingRodAnimator.SetInteger("_piercingState", index); _cameraAnimator.Play($"Piercing_{rodType}_0{index}"); fishingRodAnimator.Play($"Piercing0{index}"); GContext.Publish(ERightState.Piercing); _cameraAnimator.SetTrigger("_drawing"); await Awaiters.Seconds(fishingBehaviorConf.PiercingAnimExitTime[index - 1]); RodDrawing(); } public void GMPiercingDIndex(int index) { rodHandleAni.SetTrigger("_drawing"); fishingRodAnimator.SetBool("_piercingExit", false); _cameraAnimator.SetInteger("_piercingState", index); fishingRodAnimator.SetInteger("_piercingState", index); _cameraAnimator.Play($"PiercingSp_{rodType}_0{index}"); fishingRodAnimator.Play($"PiercingSp0{index}"); rodHandleAni.SetTrigger("_piercingSp"); _cameraAnimator.SetTrigger("_piercingSp"); fishingRodAnimator.SetTrigger("_piercingSp"); GContext.Publish(ERightState.PiercingSp); _cameraAnimator.SetBool("_pullingbottle", false); _cameraAnimator.SetBool("_pullingkeepsake", false); _cameraAnimator.SetBool("_pullingfish", false); _cameraAnimator.SetBool("_claim", false); StartCoroutine(DeathTimeScale()); } #endif private void Update() { #if UNITY_EDITOR if (Input.GetKey(KeyCode.C)) { if (Input.GetKeyDown(KeyCode.Alpha1)) { GMPiercingIndex(1); } else if (Input.GetKeyDown(KeyCode.Alpha2)) { GMPiercingIndex(2); } else if (Input.GetKeyDown(KeyCode.Alpha3)) { GMPiercingIndex(3); } } else if (Input.GetKey(KeyCode.V)) { if (Input.GetKeyDown(KeyCode.Alpha1)) { GMPiercingDIndex(1); } else if (Input.GetKeyDown(KeyCode.Alpha2)) { GMPiercingDIndex(2); } else if (Input.GetKeyDown(KeyCode.Alpha3)) { GMPiercingDIndex(3); } } #endif //如果鱼线还在空中,鱼线的张力动态更新 if (_isCastLine) { _gravityonLineTimer += Time.deltaTime; //0~0.5秒后,鱼线上的重力从0到0.7f,鱼线类似向上的抛物线 if (_gravityonLineTimer < 0.5f) _currentGravityOnLine = Mathf.Lerp(0, -_simulateGravityOnLine, _gravityonLineTimer / 0.5f); else _currentGravityOnLine = Mathf.Lerp(-_simulateGravityOnLine, _simulateGravityOnLine, (_gravityonLineTimer - 0.5f) / 1f); } //if (fishingData.IsCatchingFish && _isReeling) //{ // ControlFishReeling(); //} } private void LateUpdate() { DrawFishingLine(); } public void InitAni() { if (fishingRodAnimator != null) { fishingRodAnimator.SetBool("_shock", false); fishingRodAnimator.SetBool("_drawing", false); fishingRodAnimator.SetBool("_piercing", false); } rodHandleAni.SetBool("_drawing", false); _cameraAnimator.SetBool("_shock", false); _cameraAnimator.SetBool("_drawing", false); _cameraAnimator.SetBool("_piercing", false); } public void OnFild() { CloseIK(); _bait.transform.SetParent(RodBehaviour.Bait); _bait.transform.localPosition = Vector3.zero; //-Vector3.up * 0.1f; StartCoroutine(FailHideLine()); } public void CloseIK(/*bool ani = false*/) { if (RodBehaviour.cCDIK) { //if (ani) //{ // StartCoroutine("CloseIKCo"); //} //else //{ RodBehaviour.cCDIK.solver.IKPositionWeight = 0; RodBehaviour.cCDIK.enabled = false; //} } } //IEnumerator CloseIKCo() //{ // StopCoroutine("OpenIKCo"); // float startTime = 0; // while (startTime < 0.5f) // { // startTime += Time.deltaTime; // RodBehaviour.cCDIK.solver.IKPositionWeight = Mathf.Lerp(1, 0, startTime / 0.5f); // yield return null; // } // RodBehaviour.cCDIK.enabled = false; //} IEnumerator OpenIKCo() { StopCoroutine("CloseIKCo"); float startTime = 0; RodBehaviour.cCDIK.enabled = true; RodBehaviour.cCDIK.solver.target = FishAnimationRoot.transform; while (startTime < 0.5f) { startTime += Time.deltaTime; RodBehaviour.cCDIK.solver.IKPositionWeight = Mathf.Lerp(0, 1, startTime / 0.5f); yield return null; } } public void StartDrawing() { if (RodBehaviour.cCDIK != null) { StartCoroutine("OpenIKCo"); } isShowFish = true; if (FishBehaviour != null) { FishBehaviour.gameObject.SetActive(true); if (fx_fishing_splashloop != null) { Vector3 vector; if (FishBehaviour != null && FishBehaviour.Tail != null) { vector = FishBehaviour.Tail.position; } else { vector = _fish.transform.position; } fx_fishing_splashloop.transform.position = vector; fx_fishing_splashloop.SetActive(true); } } if (FishSwimBehaviour != null) { FishSwimBehaviour.gameObject.SetActive(true); fishCome.FishComeMove(fishingBehaviorConf.bigFishSwimSpeed); if (fx_fishbosscome != null) { Vector3 vector; if (FishSwimBehaviour.Tail != null) { vector = FishSwimBehaviour.Tail.position; fx_fishbosscome.transform.rotation = FishComeAnimationRoot.rotation; } else { vector = FishSwimBehaviour.transform.position; } vector.y = _waterHeight; fx_fishbosscome.transform.position = vector; fx_fishbosscome.SetActive(true); } } _isCastLine = false; //这里要基于鱼线的张力,来决定鱼线受重力的影响程度 _currentGravityOnLine = 0f; //To do } public float GetTurnTime() { var FishSpeedParam = _tables.TbFishStatsConfig.FishSpeedParam; //鱼的转弯时间 = 配置的转弯时间 * 参数1 / (1 + 移动速度属性 * 参数2) var turnTime = fishingBehaviorConf.turnTime * FishSpeedParam[2] / (1 + fishingData.FishSpeed * FishSpeedParam[3]); turnTime = Math.Clamp(turnTime, FishSpeedParam[0], FishSpeedParam[1]); return turnTime / fishingData.FishAnimSpeed; } void SetFfishWeight() { var _random = fishingData.curFishData.PointExtraParam * Random.Range(1 - fishingData.curFishData.WeightRandom, 1 + fishingData.curFishData.WeightRandom); fishingData.random = _random; //鱼的重量 var _fishWeight = fishingData.curFishData.BaseWeight * _random; var ExtraPoint = fishingData.WeightIncEvent; if (fishingData.IsNewItemFish()) { ExtraPoint = GContext.container.Resolve().benefitsEventFishCashMag; } _fishWeight *= (1 + ExtraPoint); _fishWeight = Mathf.Round(_fishWeight * 100) / 100; fishingData.fishWeight = _fishWeight; } public async void SetCatchStatus() { NotMove = false; if (isJumping) { FishJump fishJump = fishingData.FishJump; if (fishJump != null) { int Delay = (int)fishJump.JumpEndTime * 1000; while (isJumping && Delay > 0) { Delay -= 100; await System.Threading.Tasks.Task.Delay(100); // Wait for 100ms before checking again } } } GContext.Publish(new EventFishingSound(SoundType.audio_fishing_waiting_fishgathering)); EventFishingSound eventFishingSound = new EventFishingSound(SoundType.ReelingAudioReeling, loop: true); EventFishingSound eventFishingSound1 = new EventFishingSound(SoundType.LineAudioReeling, loop: true); //float ExtraPoint = GContext.container.Resolve().GetEquipRodSuffixValue(RodSuffixType.SuperRandom); //随机参数 SetFfishWeight(); GContext.Publish(eventFishingSound); GContext.Publish(eventFishingSound1); //ReelVibrationInterval = _tables.TbGlobalConfig.ReelVibrationInterval; _isReeling = true; //_fish.transform.position = _bait.transform.position; //_fish.SetActive(true); _targetPos = new Vector3(0, -3, fishingBehaviorConf.reelingToPullLength); fishAnimator.speed = 1; fishingRodAnimator.SetTrigger("_reeling"); rodHandleAni.SetTrigger("_reeling"); _cameraAnimator.SetTrigger("_reeling"); fishAnimator.SetBool("_drawing01", false); fishAnimator.SetBool("_drawing02", false); fishAnimator.SetBool("_drawing", false); fishAnimator.SetBool("_idle", false); SetPulling(); fishAnimator.SetTrigger("_reeling"); LoadEffect("fx_fishing_splashloopreeling"); //拉鱼路径 //可以用2阶贝塞尔,起点和终点的控制杆均朝向点: //x = 起点和终点 1/3靠近终点的位置 //y = 30 Vector3 controlPoint = new Vector3(0, _targetPos.y, _fish.transform.position.z); controlPoint.x = Mathf.Lerp(_targetPos.x, _fish.transform.position.x, 1.0f / 3.0f); controlPoint.z = Mathf.Lerp(_targetPos.z, _fish.transform.position.z, 2.0f / 3.0f); float distance = Vector3.Distance(_fish.transform.position, controlPoint) + Vector3.Distance(_targetPos, controlPoint); float time = distance / fishingBehaviorConf.reelingSpeed; if (time > fishingBehaviorConf.comebackTimeUpperLimit) { time = fishingBehaviorConf.comebackTimeUpperLimit; } RodBehaviour.transform.DOLocalRotateQuaternion(Quaternion.Euler(0, -fishingBehaviorConf.yRotationRodOffset, 0), time); RodBehaviour.transform.DOLocalMove(Vector3.zero, time); fishingData.mainCamera.transform.DOLocalRotate(Vector3.zero, time); HandController.SetShoulderRota(Vector3.zero); // Create the path //Vector3 ta = 2 * _fish.transform.position - _targetPos; //_fish.transform.LookAt(ta); _fish.transform.DOKill(); Quaternion rotation = Quaternion.LookRotation(_fish.transform.position - controlPoint); _fish.transform.DORotateQuaternion(rotation, GetTurnTime()); Vector3[] path = new Vector3[] { _fish.transform.position, controlPoint, _targetPos }; if (FishBehaviour != null) { FishBehaviour.FishAnimSpeed = 1; FishBehaviour.transform.DOKill(); FishBehaviour.transform.localPosition = Vector3.zero; //ReelingScale 鱼缩放 Vector3 localScale = FishBehaviour.transform.localScale * fishingData.curFishData.ReelingScale; FishBehaviour.animator.Play("Swim01", 0, 0); FishBehaviour.transform.DOScale(localScale, time).OnUpdate ( () => { if (FishBehaviour.mouthPos != null) { Vector3 vector3 = Vector3.zero; vector3 = -FishBehaviour.animator.transform.InverseTransformPoint(FishBehaviour.mouthPos.position); vector3.z = -vector3.z; FishBehaviour.animator.transform.localPosition = vector3; } } ).SetEase(Ease.Linear); } Vector3 zero = Vector3.one * fishingData.curFishData.SlashFxScale * 0.25f; if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.SetActive(true); fx_fishing_splashwaveloop.transform.DOScale(zero, time).SetEase(Ease.Linear); } if (fx_fishing_splashloop != null) { fx_fishing_splashloop.SetActive(true); fx_fishing_splashloop.transform.DOScale(zero, time).SetEase(Ease.Linear); } float turnTime = 0; Vector3 fishPos = _fish.transform.position; // Move the fish along the path _fish.transform.DOPath(path, time, PathType.CatmullRom)/*.SetDelay(GetTurnTime())*/ .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; //reeling中 SetCurFishEffectPos(); Vector3 vector = _fish.transform.position; vector.y = _waterHeight; if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.transform.rotation = _fish.transform.rotation; fx_fishing_splashwaveloop.transform.position = vector; } })) .SetEase(fishingBehaviorConf.reelCurve) .OnComplete( () => { if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.SetActive(false); } if (fx_fishing_splashloop != null) { fx_fishing_splashloop.SetActive(false); } _fish.transform.DOKill(); //CloseIK(true); _fish.transform.localRotation = Quaternion.identity; _fish.transform.position = _targetPos; var audios = fishingData.curFishData.AudioPullingOut; string pullingOutSound = audios[Random.Range(0, audios.Count)]; GContext.Publish(new EventFishingSound(pullingOutSound)); GContext.Publish(new FadeOutEvent(eventFishingSound.Sound)); GContext.Publish(new FadeOutEvent(eventFishingSound1.Sound)); //_bait.transform.position = _fish.transform.position; _isReeling = false; _cameraAnimator.SetBool("_claim", false); fishAnimator.speed = 1; GContext.Publish(new PlayNewItemFxEvent() { type = 1 }); GContext.Publish(ERightState.Pulling); if (FishBehaviour != null) { FishBehaviour.FishAnimSpeed = 1; //ReelingScale 鱼缩放 Vector3 localScale = FishBehaviour.transform.localScale * fishingData.curFishData.PullingScale; FishBehaviour.transform.DOScale(localScale, fishingBehaviorConf.jumpScaleTime).OnUpdate ( () => { if (FishBehaviour.mouthPos != null) { Vector3 vector3 = Vector3.zero; vector3 = -FishBehaviour.animator.transform.InverseTransformPoint(FishBehaviour.mouthPos.position); vector3.z = -vector3.z; FishBehaviour.animator.transform.localPosition = vector3; } } ); FishBehaviour.Pulling(); if (!string.IsNullOrEmpty(fishingData.curFishData.FxWaterDrop)) { FxWaterDrop(fishingData.curFishData.FxWaterDrop); } //开始变材质 //if (dropAfterDrop != null) { MaterialChange(); } } //动画吃鱼劫持 if (fishingData.IsEact()) { GContext.Publish(ERightState.Preparing); fishAnimator.SetTrigger("Biten"); StartAniEat(); } else { if (fishingData.IsEventGameFish()) { StartCoroutine(HideLine()); } _cameraAnimator.SetTrigger("_pulling"); fishAnimator.SetTrigger("_pulling"); StartCoroutine(TimeScale()); StartCoroutine(ControlFishOutWater()); } fishingRodAnimator.SetTrigger("_pulling"); StartCoroutine(Changeline()); StartCoroutine(PlayPullingSound()); if (fx_fishing_splashloop != null) { fx_fishing_splashloop.SetActive(false); } LoadEffect("fx_fishing_splashpull"); //if (GContext.container.Resolve().GetDataProficiency(FishingSystemB.Instance.curFishData.MasteryID) == 0) //{ FishingPanel_Advanced.Instance?.ShowRankInfo(); //} if (!string.IsNullOrEmpty(fishingData.curFishData.FxWaterSplash)) GContext.Publish(new PlayerRaindropEvent() { FxWaterSplash = fishingData.curFishData.FxWaterSplash }); GContext.Publish(new VibrationData(21)); }); } async void FxWaterDrop(string fxName) { if (fxWaterDrop != null) { if (fxName != fxWaterDrop.name) { Addressables.ReleaseInstance(fxWaterDrop); fxWaterDrop = null; } else { fxWaterDrop.SetActive(false); } } await new WaitForSeconds(fishingData.curFishData.DelayWaterDrop); if (fxWaterDrop == null) { fxWaterDrop = await Addressables.InstantiateAsync(fxName, FishAnimationRoot).Task; if (fxWaterDrop != null) { fxWaterDrop.name = fxName; if (FishBehaviour == null) { Addressables.ReleaseInstance(fxWaterDrop); fxWaterDrop = null; return; } } } if (fxWaterDrop != null) { fxWaterDrop.SetActive(true); } } /// /// 是否需要变换 /// public void MaterialChange() { ETChangeMaterial eTDropAfterDrop = collectingData.MaterialChange(); if (eTDropAfterDrop != null) { if (eTDropAfterDrop.MaterialChange != "None") { MaterialChangeDelay(); } if (eTDropAfterDrop.FxChange != "None") { FxChangeDelay(); } if (eTDropAfterDrop.Mode != "None") { ModeChangeDelay(); } } } async void ModeChangeDelay() { ETChangeMaterial eTDropAfterDrop = collectingData.MaterialChange(); curFish = FishBehaviour?.gameObject; await new WaitForSeconds(eTDropAfterDrop.ModeDelay); dropAfterDropParent = FishBehaviour.Find(eTDropAfterDrop.Bone); if (dropAfterDropParent != null) { var modeGo = await Addressables.InstantiateAsync(eTDropAfterDrop.Mode).Task; if (modeGo != null) { if (FishBehaviour == null || curFish == null || curFish != FishBehaviour.gameObject) { Addressables.ReleaseInstance(modeGo); return; } CollectingPropScale collectingPropScale = _tables.TbCollectingPropScale[fishingData.curFishData.Quality]; var eulerAngles = modeGo.transform.localEulerAngles; var localPosition = modeGo.transform.localPosition; modeGo.transform.SetParent(dropAfterDropParent); modeGo.transform.localScale *= collectingPropScale.Scale; modeGo.transform.localEulerAngles = eulerAngles; modeGo.transform.localPosition = localPosition; FishBehaviour.modeGo = modeGo; } } } /// /// 变换材质 /// /// async void MaterialChangeDelay() { ETChangeMaterial eTDropAfterDrop = collectingData.MaterialChange(); curFish = FishBehaviour?.gameObject; await new WaitForSeconds(eTDropAfterDrop.MaterialChangeDelay); F_whitemarli_P = await Addressables.LoadAssetAsync(eTDropAfterDrop.MaterialChange).Task; if (FishBehaviour == null || curFish == null || curFish != FishBehaviour.gameObject) { Addressables.Release(F_whitemarli_P); F_whitemarli_P = null; return; } Renderer[] meshRenderer = FishBehaviour.gameObject.GetComponentsInChildren(); if (F_whitemarli_P != null && meshRenderer != null && meshRenderer.Length > 0) { var render = meshRenderer[0]; var materials = render.materials; for (int i = 0; i < materials.Length; i++) { var material = materials[i]; var material_P = new Material(F_whitemarli_P); //material_P.SetTexture("_texture", material.GetTexture("_BaseMap")); //material_P.SetTexture("_normalMap", material.GetTexture("_BumpMap")); material_P.SetTexture("_BaseMap", material.GetTexture("_BaseMap")); material_P.SetTexture("_BumpMap", material.GetTexture("_BumpMap")); materials[i] = material_P; } render.materials = materials; } } async void FxChangeDelay() { ETChangeMaterial eTDropAfterDrop = collectingData.MaterialChange(); curFish = FishBehaviour?.gameObject; await new WaitForSeconds(eTDropAfterDrop.FxChangeDelay); GContext.Publish(new EventUISound(eTDropAfterDrop.AudioChange)); var prefab = await Addressables.LoadAssetAsync(eTDropAfterDrop.FxChange).Task; GameObject fishEffect; if (prefab != null) { if (FishBehaviour == null || curFish == null || curFish != FishBehaviour.gameObject) { Addressables.Release(prefab); return; } fishEffect = Instantiate(prefab, transform, true); fishEffect.transform.position = FishBehaviour.animator.transform.position; CollectingPropScale collectingPropScale = _tables.TbCollectingPropScale[fishingData.curFishData.Quality]; fishEffect.transform.localScale *= collectingPropScale.Scale; await Awaiters.Seconds(5); Addressables.Release(prefab); Destroy(fishEffect); } } IEnumerator Changeline() { yield return new WaitForSeconds(fishingBehaviorConf.fishingRodDisappearsPulling); SetEffectActive("fx_fishing_splashloopreeling", false); ChangelineStartPos(); } IEnumerator PlayPullingSound() { var audios = fishingData.curFishData.AudioSplashPulling; if (audios.Count > 0) { string pullingOutSound = audios[Random.Range(0, audios.Count)]; yield return new WaitForSeconds(fishingData.curFishData.DelaySplashPulling); GContext.Publish(new EventFishingSound(pullingOutSound)); if (!string.IsNullOrEmpty(fishingData.curFishData.FxWaterSplash)) GContext.Publish(new PlayerRaindropEvent() { FxWaterSplash = fishingData.curFishData.FxWaterSplash }); } } IEnumerator TimeScale() { yield return new WaitForSeconds(fishingBehaviorConf.timeStartScale); DOTween.To(() => 0.01f, x => Time.timeScale = x, 1, fishingBehaviorConf.timeEndScale - fishingBehaviorConf.timeStartScale) .SetEase(fishingBehaviorConf.timeScaleCurve); yield return new WaitForSeconds(fishingBehaviorConf.timeEndScale); Time.timeScale = 1f; } public void UIPreSwimB() { //天气压黑 var _fishEatfish = _tables.TbFishEatFish.GetOrDefault(fishingData.swimFishData.EatFishID); if (_fishEatfish != null) { if (_fishEatfish.IsDarkness) { WeatherEvent weatherEvent = new WeatherEvent() { State = 1 }; GContext.Publish(weatherEvent); fishingData.isWeather = true; if (weatherEvent.IsPlay) { GContext.Publish(new EventBGMSound("BGM_WeatherChange")); } } FishingPanel_Advanced.Instance?.ShowWarning(_fishEatfish.WarningAfterEat); } NotMove = true; timer = 10; fishCome.FishComeStop(); Shock(); } public void PlayEatEndAni() { if (fx_fishbosscome != null) { fx_fishbosscome.SetActive(false); } DestroySwimFish(); SetDrawingForce(1); StartCoroutine(UIEatFish()); } public IEnumerator UIPreSwim() { //天气压黑 var _fishEatfish = _tables.TbFishEatFish.GetOrDefault(fishingData.swimFishData.EatFishID); if (_fishEatfish != null) { if (_fishEatfish.IsDarkness) { WeatherEvent weatherEvent = new WeatherEvent() { State = 1 }; GContext.Publish(weatherEvent); fishingData.isWeather = true; if (weatherEvent.IsPlay) { GContext.Publish(new EventBGMSound("BGM_WeatherChange")); } } FishingPanel_Advanced.Instance?.ShowWarning(_fishEatfish.WarningAfterEat); } if (FishSwimBehaviour != null) { FishSwimBehaviour.gameObject.SetActive(true); } if (fx_fishbosscome != null) { fx_fishbosscome.SetActive(true); } yield return fishCome.FishEatMove(fishingBehaviorConf.bigFishEatSpeed).AsIEnumerator(); NotMove = true; timer = 10; fishCome.FishComeStop(); float FishSwimSpeedTime = fishingBehaviorConf.bigFishEatTime; float SwimDistance = fishSpeed * FishSwimSpeedTime; var position = _fish.transform.position; //勾股定理求X偏移 float z = (position.z - _strugglePoint.z); float zQ = z * z; float SwimDistanceQ = SwimDistance * SwimDistance; float xS = SwimDistanceQ - zQ; float x = 0; if (xS > 0) { x = Mathf.Sqrt(xS); } else { _strugglePoint.z = position.z + SwimDistance; } //Mathf.Sqrt(y) if (position.x < 0) { _strugglePoint.x = position.x + x; } else { _strugglePoint.x = position.x - x; } //转弯 Quaternion rotation = Quaternion.LookRotation(position - _strugglePoint); _fish.transform.DORotateQuaternion(rotation, 0.1f); _fish.transform.DOMove(_strugglePoint, FishSwimSpeedTime); Vector3 posMid = (position + _strugglePoint) / 2; //转弯 position.y = fishCome.transform.position.y; var new_strugglePoint = _strugglePoint; new_strugglePoint.y = fishCome.transform.position.y; var posMidnew = (position + new_strugglePoint) / 2; Quaternion rotation1 = Quaternion.LookRotation(fishCome.transform.position - posMid); fishCome.transform.DORotateQuaternion(rotation1, 0.1f); //Vector3[] path1 = new Vector3[] { fishCome.transform.position, posMidnew, new_strugglePoint }; float turnTime1 = 0; Vector3 fishPos1 = fishCome.transform.position; // Move the fish along the path fishCome.transform.DOMove(new_strugglePoint, FishSwimSpeedTime) .OnUpdate( (() => { turnTime1 += Time.deltaTime; if (turnTime1 > 0.1f) { Quaternion rotationC = Quaternion.LookRotation(fishPos1 - fishCome.transform.position); fishCome.transform.rotation = rotationC; } fishPos1 = fishCome.transform.position; })); Shock(); } void Shock() { GContext.Publish(ERightState.Shock); int _shockIndex = Random.Range(1, fishingBehaviorConf.shockCount + 1); _cameraAnimator.SetInteger("_shockIndex", _shockIndex); fishingRodAnimator.SetInteger("_shockIndex", _shockIndex); _cameraAnimator.SetTrigger("_shock"); fishingRodAnimator.SetTrigger("_shock"); FishingPanel_Advanced.Instance?.ShowState(2); } //结束UI吃鱼 IEnumerator UIEatFish() { yield return new WaitForSeconds(fishingBehaviorConf.UIEatExitTime); NotMove = false; isShowFish = true; if (FishBehaviour != null) { FishBehaviour.gameObject.SetActive(true); if (fx_fishing_splashloop != null) { Vector3 vector; if (FishBehaviour.Tail != null) { vector = FishBehaviour.Tail.position; } else { vector = _fish.transform.position; } fx_fishing_splashloop.transform.position = vector; fx_fishing_splashloop.SetActive(true); } } } //吃鱼延时播放跳跃动画 void StartAniEat() { //大鱼停止游弋 fishCome.FishComeStop(); if (fishCome != null) { fishCome.transform.localPosition = _fish.transform.localPosition; fishCome.transform.localRotation = _fish.transform.localRotation; } IsComeEact = false; //开始timeScale缩放 AniEatTimeScale(); //延时播放动画 EatFishActionDelay(); //延时换嘴 EatenFishVanishedDelay(); RodApearDelay(); RodDrawingForceMaxDelay(); FishSwimmingDelay(); AniExitTime(); DarknessTimeDelay(); } async void AniEatTimeScale() { await Awaiters.Seconds(fishingBehaviorConf.timeEatStartScale); float time = fishingBehaviorConf.timeEatEndScale - fishingBehaviorConf.timeEatStartScale; DOTween.To(() => fishingBehaviorConf.timeEatMinScale, x => Time.timeScale = x, 1, time) .SetEase(fishingBehaviorConf.timeEatScaleCurve); await Awaiters.Seconds(fishingBehaviorConf.timeEatEndScale); Time.timeScale = 1f; } async void EatFishActionDelay() { await Awaiters.Seconds(fishingBehaviorConf.eatFishActionDelay); fishCome.animator.SetTrigger("Bite"); if (FishSwimBehaviour != null) { FishSwimBehaviour.PlayBite(); } } //是否鱼线挂在大鱼嘴上 bool IsComeEact; //延时换嘴 async void EatenFishVanishedDelay() { await Awaiters.Seconds(fishingBehaviorConf.eatenFishVanishedDelay); //小鱼消失鱼嘴切换 IsComeEact = true; } async void RodApearDelay() { await Awaiters.Seconds(fishingBehaviorConf.rodApearDelay); fishingRodAnimator.SetBool("_reeling", false); _cameraAnimator.SetBool("_reeling", false); //继续钓鱼 DestroySwimFish(); IsComeEact = false; fishingRodAnimator.SetBool("_pulling", false); CameraPullingEnd(); RodBehaviour.transform.localEulerAngles = Vector3.zero; RodBehaviour.transform.localPosition = Vector3.zero; SetShowRod(true); PrepareFishing(); IsRecast(true); InitEffect(); //重置鱼饵位置 _bait.transform.SetParent(transform); Vector3 ver = _bait.transform.position; ver.y = GetFishUnderwaterOffset(); ver.z = fishingBehaviorConf.flyDistance - fishingBehaviorConf.waitingDistance; ver.x = -20; _fish.transform.position = ver; fishAnimator.Play("Idle01"); _strugglePoint = new Vector3(0, ver.y, ver.z); _bait.transform.position = ver; LoadEffect("fx_fishing_splashwaveloop"); SetCurFishEffectPos(); GContext.Publish(new LoadFishListEvent() { isShow = true }); StartDrawing(); } async void FishSwimmingDelay() { await Awaiters.Seconds(fishingBehaviorConf.fishSwimmingDelay); _fish.transform.DOMove(_strugglePoint, fishingBehaviorConf.fishSwimmingToMapTime).OnUpdate( (() => { //_bait.transform.position = _fish.transform.position; SetCurFishEffectPos(); })); FishTurn(); } async void DarknessTimeDelay() { //天气压黑 var _fishEatfish = _tables.TbFishEatFish.GetOrDefault(fishingData.swimFishData.EatFishID); if (_fishEatfish != null) { await Awaiters.Seconds(fishingBehaviorConf.darknessTimeDelay); if (_fishEatfish.IsDarkness) { WeatherEvent weatherEvent = new WeatherEvent() { State = 1 }; GContext.Publish(weatherEvent); fishingData.isWeather = true; if (weatherEvent.IsPlay) { GContext.Publish(new EventBGMSound("BGM_WeatherChange")); } } FishingPanel_Advanced.Instance?.ShowWarning(_fishEatfish.WarningAfterEat); } } async void AniExitTime() { await Awaiters.Seconds(fishingBehaviorConf.aniEatExitTime); timer = 10; moveTimer = 0; GContext.Publish(new OnEatEndEvent()); } async void RodDrawingForceMaxDelay() { await Awaiters.Seconds(fishingBehaviorConf.rodDrawingForceMaxDelay); SetDrawingForce(1); } public void ChangelineStartPos() { _isChangelineStartPos = true; ShowRod(false); StartCoroutine(SetLineStartPos()); } private IEnumerator ControlFishOutWater() { float time = fishingBehaviorConf.jumpDuration + fishingBehaviorConf.caughtFishDelayTime; yield return new WaitForSeconds(time); fishingRodAnimator.SetBool("_reeling", false); _cameraAnimator.SetBool("_reeling", false); fishingRodAnimator.SetBool("_pulling", false); CameraPullingEnd(); fishingData.IsCaughtFish = true; PlayCollectingEffect(); if (fx_fishing_splashwaveloop != null) { fx_fishing_splashwaveloop.SetActive(false); } } void CameraPullingEnd() { _cameraAnimator.SetBool("_pullingfish", false); _cameraAnimator.SetBool("_pullingkeepsake", false); _cameraAnimator.SetBool("_pullingbottle", false); _cameraAnimator.SetBool("_pulling", false); } IEnumerator HideLine() { yield return new WaitForSeconds(fishingBehaviorConf.caughtFishHideLineTime); RodBehaviour.fishingLineRenderer.gameObject.SetActive(false); } IEnumerator FailHideLine() { yield return new WaitForSeconds(fishingBehaviorConf.rodFailResetTime); RodBehaviour.fishingLineRenderer.gameObject.SetActive(false); } void IsCancelled() { float time = fishingBehaviorConf.rodFailResetTime; RodBehaviour.transform.DOLocalRotateQuaternion(Quaternion.identity, time); RodBehaviour.transform.DOLocalMove(Vector3.zero, time); fishingRodAnimator.SetBool("_recast", false); fishingRodAnimator.SetBool("_restart", false); rodHandleAni.SetBool("_recast", false); rodHandleAni.SetBool("_restart", false); _cameraAnimator.SetBool("_recast", false); _cameraAnimator.SetBool("_restart", false); fishingRodAnimator.SetTrigger("_cancelled"); rodHandleAni.SetTrigger("_cancelled"); _cameraAnimator.SetTrigger("_cancelled"); } void IsRecast(bool value) { if (!value) { _cameraAnimator.SetTrigger("_restart"); fishingRodAnimator.SetTrigger("_restart"); rodHandleAni.SetTrigger("_restart"); GContext.Publish(ERightState.Idle); rodHandleAni.SetBool("_drawing", false); rodHandleAni.SetTrigger("_idle"); } else { fishingRodAnimator.SetTrigger("_recast"); rodHandleAni.SetTrigger("_recast"); GContext.Publish(ERightState.Throwing); _cameraAnimator.SetTrigger("_recast"); } fishingRodAnimator.SetBool("_throwing", false); _cameraAnimator.SetBool("_throwing", false); CameraToFish = false; if (F_whitemarli_P) { Addressables.Release(F_whitemarli_P); F_whitemarli_P = null; } } private IEnumerator SetLineStartPos() { _endLinePos = new Vector3(_lineStartPos.position.x, fishingBehaviorConf.lineHeight, _lineStartPos.position.z); _lineStartPos.DOMove(_endLinePos, fishingBehaviorConf.lineMoveToTopTime); yield return new WaitForSeconds(fishingBehaviorConf.lineMoveToTopTime + fishingBehaviorConf.lineHoldTopTime); _endLinePos = new Vector3(0f, fishingBehaviorConf.lineHeight, RodBehaviour.transform.position.z + fishingBehaviorConf.reelingToPullLength - 5); _lineStartPos.DOMove(_endLinePos, fishingBehaviorConf.lineMoveToMidTime); } //鱼竿播放Drawing public void RodDrawing() { fishingRodAnimator.SetTrigger("_piercingExit"); fishingRodAnimator.SetTrigger("_drawing"); GContext.Publish(ERightState.Drawing); } public void CameraDrawing() { _cameraAnimator.SetBool("_pullingkeepsake", false); _cameraAnimator.SetTrigger("_drawing"); fishingRodAnimator.SetBool("_biting", false); fishAnimator.SetTrigger($"_drawing0{fishingData.curFishData.ShowAnimation}"); fishAnimator.SetTrigger("_drawing"); CameraToFish = true; } //bool isClickIng; //模拟玩家操控鱼竿的体验 public void ControlFishingRodAnim(FishingStateName stateName, float fishSpeed, float nearDistance, float farDistance) { Vector3 dir = _fish.transform.position - transform.position; dir.y = 0; float angelX = Vector3.Angle(transform.right, dir); angelX -= fishingBehaviorConf.cameraDrawingOffset; // 判断是否按下鼠标左键 Vector2 mousePosition = Input.mousePosition; if (Input.GetMouseButtonDown(0) && FishingPanel_Advanced.Instance != null && FishingPanel_Advanced.Instance.IsDown()) { _cameraAnimator.SetTrigger(angelX < 0 ? "_drawL" : "_drawR"); } if (stateName == FishingStateName.Move || stateName == FishingStateName.UIEating) { SimulateFish(fishSpeed, nearDistance, farDistance); } else if (stateName == FishingStateName.Jump) { fishSpeed *= JumpDistance; SimulateFish(fishSpeed, nearDistance, farDistance); } else if (stateName == FishingStateName.Escape) { CloseBaitDoTween(); SimulateFishEscape(fishSpeed); } else { CloseBaitDoTween(); } //_bait.transform.position = _fish.transform.position; //控制鱼竿旋转 angelX += fishingBehaviorConf.RodRotationOffset; float angelZ = angelX * fishingBehaviorConf.zRotationRodParam + fishingBehaviorConf.zRotationRodOffset; float angelY = angelX * fishingBehaviorConf.yRotationRodParam + fishingBehaviorConf.yRotationRodOffset; RodBehaviour.transform.localRotation = Quaternion.Lerp(RodBehaviour.transform.localRotation, Quaternion.Euler(0, -angelY, -angelZ), Time.deltaTime * 5); RodBehaviour.transform.localPosition = Vector3.right * (Mathf.Sin(RodBehaviour.transform.localRotation.z) * fishingBehaviorConf.xPosRodParam + fishingBehaviorConf.xPosRodOffset); SetCurFishEffectPos(); if (CameraToFish) { MoveCam(); } } void MoveCam() { //相机位置朝着_bait //相机差值朝向bait //var rotation = Quaternion.LookRotation(_bait.transform.position - mainCamera.position); var angle = GetFishPos() - fishingData.mainCamera.position; angle.y = 0; var camY = Vector3.Angle(Vector3.forward, angle) / _cameraMaxAngelOffset; camY = Mathf.Clamp(camY, 0, 1); if (angle.x < 0) { camY = -camY; } //float offset = (Screen.height / (float)Screen.width - 1) / 0.78f; //offset = Mathf.Clamp(offset, 0, 1); float cameraMaxAngel = _cameraMaxAngel /** offset*/; camY *= cameraMaxAngel; float camZ = (camY + fishingBehaviorConf.cameraDrawingOffset - 90) * fishingBehaviorConf.zAngelParam; camZ = Mathf.Clamp(camZ, -fishingBehaviorConf.zAngelMax, fishingBehaviorConf.zAngelMax); //fishingData.mainCamera.eulerAngles = new Vector3(0, camY, camZ); Quaternion rotation = Quaternion.Euler(fishingData.mainCamera.eulerAngles.x, camY, camZ); Quaternion result = Quaternion.Lerp(fishingData.mainCamera.rotation, /*camStartRotation **/ rotation, Time.deltaTime * 10); fishingData.mainCamera.rotation = result; if (HandController != null) { Vector3 vector = fishingData.mainCamera.localEulerAngles; vector.x *= fishingBehaviorConf.xRotationHandParam; vector.y *= fishingBehaviorConf.yRotationHandParam; vector.z *= fishingBehaviorConf.zRotationHandParam; HandController.SetShoulderRota(vector); } } public void SetDrawingForce(float forcePower) { fishingRodAnimator.SetFloat("_drawingForce", forcePower); cameraAnimator.SetFloat("_drawingForce", forcePower); } public void SetFishAnimSpeed(float speed) { if (isJumping || isDashMove) { fishAnimator.speed = 1; if (FishBehaviour != null) { FishBehaviour.FishAnimSpeed = 1; } } else { fishAnimator.speed = speed; if (FishBehaviour != null) { FishBehaviour.FishAnimSpeed = speed; } } } public void RodReset() { fishingRodAnimator.SetBool("_biting", false); CloseIK(); RodBehaviour.transform.localEulerAngles = Vector3.zero; RodBehaviour.transform.localPosition = Vector3.zero; SetRodType(); } public void CameraReset(bool isSupplyDrop = false) { _cameraAnimator.SetBool("_preparing", false); _cameraAnimator.SetBool("_shock", false); _cameraAnimator.SetBool("_drawing", false); if (isSupplyDrop) { StartCoroutine(PlayAfterpulling()); } else { _cameraAnimator.SetTrigger("_preparing"); _cameraAnimator.SetTrigger("_afterpulling"); _cameraAnimator.SetTrigger("_claim"); } } public void PlaySupplyDropClaim() { _cameraAnimator.SetTrigger("_supplydropclaim"); } IEnumerator PlayAfterpulling() { _cameraAnimator.SetTrigger("_supplydrop"); yield return new WaitForSeconds(fishingBehaviorConf.supplyDropAppearDelay); _cameraAnimator.SetTrigger("_afterpulling"); _cameraAnimator.SetTrigger("_claim"); } // 绘制钓鱼线 private void DrawFishingLine() { if (RodBehaviour == null) { return; } Vector3 targetPos = _bait.transform.position; if (fishingData.IsCatchingFish || fishingData.IsDrawing || fishingData.IsShowRewardPanel) { targetPos = GetMouthPos(); } if (!_isChangelineStartPos) { if (RodBehaviour.TopLine != null) { _lineStartPos.position = RodBehaviour.TopLine.position; } } Vector3 startPos = _lineStartPos.position; //计算钓鱼线的长度和分段数 float distance = Vector3.Distance(startPos, targetPos); LineDistance = distance * _tables.TbGlobalConfig.LineLengthParam; if (RodBehaviour != null && RodBehaviour.lineLength != null) { if (LineDistance > fishingData.MaxLinelength) { RodBehaviour.lineLength.text = fishingData.MaxLinelength.ToString("000"); } else RodBehaviour.lineLength.text = LineDistance.ToString("000"); } int segments = Mathf.FloorToInt(distance / CalculateSegmetLenght(distance, _lineResolution)); List pos1 = new List(); if (_isLineSin) { int count = vector3s.Count; for (int i = 1; i <= count; i++) { Vector3 vector = GetCurPos(vector3s[^i], out float zeroTime); //if (zeroTime < 1) { pos1.Add(vector); } } pos1 = CalculateBezierPoint(pos1); segments = pos1.Count; } if (segments > 0) { // 计算钓鱼线上的点 Vector3[] linePoints; int addCount = 0; if (_isChangelineStartPos) { linePoints = new Vector3[segments]; linePoints[0] = startPos; } else { addCount = RodBehaviour.LineList.Count + 2; linePoints = new Vector3[segments + addCount]; linePoints[0] = RodBehaviour.LineHole.position; linePoints[1] = RodBehaviour.EndLine.position; for (int i = 0; i < RodBehaviour.LineList.Count; i++) { linePoints[i + 2] = RodBehaviour.LineList[i].position; } linePoints[addCount] = startPos; } if (_isLineSin) { for (int i = 1; i < segments; i++) { linePoints[i + addCount] = pos1[i]; } } else { for (int i = 1; i < segments; i++) { float t = i / (float)segments; Vector3 controlPoint = Vector3.Lerp(startPos, targetPos, 0.5f) + Vector3.up * _currentGravityOnLine; linePoints[i + addCount] = CalculateBezierPoint(startPos, controlPoint, targetPos, t); } } linePoints[segments - 1 + addCount] = targetPos; // 绘制钓鱼线 RodBehaviour.fishingLineRenderer.positionCount = segments + addCount; RodBehaviour.fishingLineRenderer.SetPositions(linePoints); } else { RodBehaviour.fishingLineRenderer.positionCount = 0; } } private float CalculateSegmetLenght(float distance, Vector2 lineResolution) { float x = Mathf.InverseLerp(1, 50, distance); float value = Mathf.Lerp(lineResolution.x, lineResolution.y, x); return value; } private List CalculateBezierPoint(List curPoints) { List points = new List(); points.Add(curPoints[0]); for (int i = 1; i < curPoints.Count - 1; i++) { points.Add(CalculateBezierPoint(curPoints[i - 1], curPoints[i], curPoints[i + 1], 0.4f)); } points.Add(curPoints[curPoints.Count - 1]); return points; } //2次贝塞尔曲线 private Vector3 CalculateBezierPoint(Vector3 start, Vector3 midPoint, Vector3 end, float t) { Vector3 P0 = start; Vector3 P1 = midPoint; Vector3 P2 = end; float u = 1 - t; float tt = t * t; float uu = u * u; Vector3 p = uu * P0; p += 2 * u * t * P1; p += tt * P2; return p; } //三次贝塞尔曲线 private Vector3 CalculateBezierPoint(Vector3 start, Vector3 control1, Vector3 control2, Vector3 end, float t) { Vector3 P0 = start; Vector3 P1 = control1; Vector3 P2 = control2; Vector3 P3 = end; float u = 1 - t; float tt = t * t; float uu = u * u; float uuu = uu * u; float ttt = tt * t; Vector3 p = uuu * P0; p += 3 * uu * t * P1; p += 3 * u * tt * P2; p += ttt * P3; return p; } private void OnDisable() { CloseAllEffect(); } public void CloseAllEffect() { foreach (var o in _effectDic) { o.Value.SetActive(false); } } private void OnDestroy() { disposables?.Dispose(); disposables = null; foreach (var o in _effectDic) { Addressables.ReleaseInstance(o.Value); } if (fxWaterDrop != null) { Addressables.ReleaseInstance(fxWaterDrop); fxWaterDrop = null; } _effectDic.Clear(); Addressables.Release(rodPrefab); Addressables.ReleaseInstance(baitAB); if (handAB != null) { Addressables.ReleaseInstance(handAB); } if (FishBehaviour != null) { if (FishBehaviour.modeGo) { Addressables.ReleaseInstance(FishBehaviour.modeGo); } Addressables.Release(FishPrefab); } if (fx_fishing_splashloop != null) { Addressables.ReleaseInstance(fx_fishing_splashloop); fx_fishing_splashloop = null; } DestroySwimFish(); } Vector3 GetMouthPos() { if (IsComeEact && fishCome != null) { //鱼被吃掉大鱼的嘴巴位置 return fishCome.FishAnimationRoot.position; } if (FishBehaviour == null || FishBehaviour.mouthPos == null) { return _fish.transform.position; } return FishBehaviour.mouthPos.position; } //刺鱼表现 public async void PiercingIndex(int index, bool isDeath) { fishingRodAnimator.SetBool("_piercingExit", false); _cameraAnimator.SetInteger("_piercingState", index); fishingRodAnimator.SetInteger("_piercingState", index); if (isDeath) { OnStartEternalDeath(); } else { _ = StartCoroutine(PiercingTimeScale(index - 1)); _cameraAnimator.SetTrigger("_piercing"); fishingRodAnimator.SetTrigger("_piercing"); GContext.Publish(ERightState.Piercing); _cameraAnimator.SetTrigger("_drawing"); await Awaiters.Seconds(fishingBehaviorConf.PiercingAnimExitTime[index - 1]); RodDrawing(); } } void SetPulling() { //_cameraAnimator.SetBool("_pullingbottle", false); //_cameraAnimator.SetBool("_pullingkeepsake", false); //_cameraAnimator.SetBool("_pullingfish", false); //if (fishingData.IsKeepsakeFish() || fishingData.IsPackItemFish()) //{ // //_cameraAnimator.SetTrigger("_pullingkeepsake"); // _cameraAnimator.SetInteger("_pullingOver", -1); //} //else if (fishingData.IsEventGameFish()) //{ // //_cameraAnimator.SetTrigger("_pullingbottle"); // _cameraAnimator.SetInteger("_pullingOver", -2); //} //else //{ // _cameraAnimator.SetInteger("_pullingOver", fishingData.fishItem.Quality); //} _cameraAnimator.SetInteger("_pullingOver", fishingData.curFishData.PullingOverIndex); //_cameraAnimator.SetTrigger("_pullingfish"); } IEnumerator PiercingTimeScale(int index) { float piercingState = fishingBehaviorConf.piercingTime[index]; var a = DOTween.To(() => 0.01f, x => Time.timeScale = x, 1, piercingState) .SetEase(fishingBehaviorConf.piercingTimeScaleCurve); yield return new WaitForSeconds(piercingState); a.Kill(); Time.timeScale = 1; } public void PlayNewItem() { if (fishingData.fishEatDataList.Count > 0) return; var etNewItem = collectingData.ETNewItemFx(); if (etNewItem != null) { PlayNewItemFxEvent playNewItemFxEvent = new PlayNewItemFxEvent(); playNewItemFxEvent.fxName = etNewItem.FxScene[fishingData.NewIndex]; playNewItemFxEvent.audioName = etNewItem.AudioScene[fishingData.NewIndex]; playNewItemFxEvent.IsDarkness = etNewItem.IsDarkness[fishingData.NewIndex]; playNewItemFxEvent.PerformanceDelay = etNewItem.PerformanceDelay[fishingData.NewIndex]; GContext.Publish(playNewItemFxEvent); } } }