备份CatanBuilding瘦身独立工程

This commit is contained in:
JSD\13999
2026-05-26 16:15:54 +08:00
commit 2d0e6a61b7
12001 changed files with 2431925 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 113970d88d2004a1e9dd9e8197b7f931
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,222 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AppsFlyerSDK;
using System.Threading.Tasks;
using System;
[DefaultExecutionOrder(-100)]
public class AFHelper : MonoBehaviour, IAppsFlyerConversionData, IAppsFlyerUserInvite
{
public bool DidReceivedDeepLink { get; private set; } // marks if we got a DL and processed it
private Dictionary<string, object> _conversionDataDictionary;
private Dictionary<string, object> _deepLinkParamsDictionary;
public bool IsFirstLaunch { get; private set; }
public string AFState { get; private set; }
public IReadOnlyDictionary<string, object> DeepLinkParamsDictionary => _deepLinkParamsDictionary;
public IReadOnlyDictionary<string, object> ConversionDataDictionary => _conversionDataDictionary;
public string AttributionData { get; private set; }
private string _referrerUID;
private string _inviteLink;
private TaskCompletionSource<string> _tcs;
public string StoreLink { get; private set; }
public bool GetDLReferer(out string pid, out string uid)
{
pid = null;
uid = null;
if (!DidReceivedDeepLink)
return false;
if (_deepLinkParamsDictionary == null)
return false;
if (_deepLinkParamsDictionary.TryGetValue("deep_link_value", out var deep_link_value))
{
if ((string)deep_link_value != "friend_invite")
return false;
if (_deepLinkParamsDictionary.TryGetValue("deep_link_sub2", out var referrer_pid))
pid = (string)referrer_pid;
if (_deepLinkParamsDictionary.TryGetValue("deep_link_sub1", out var referrer_uid))
uid = (string)referrer_uid;
if (!string.IsNullOrEmpty(pid) && !string.IsNullOrEmpty(uid))
return true;
}
return false;
}
public static AFHelper Instance { get; private set; }
public void Awake()
{
if (Instance != null && Instance != this)
{
Destroy(this);
}
else
{
Instance = this;
DontDestroyOnLoad(this);
}
}
public void Init(string afkey, string afAppID, string customerUserID, string oneLinkID, bool debugMode = false)
{
AppsFlyer.setIsDebug(debugMode);
AppsFlyer.setAppInviteOneLinkID(oneLinkID);
AppsFlyer.initSDK(afkey, afAppID, this);
AppsFlyer.setCustomerUserId(customerUserID);
AppsFlyer.OnDeepLinkReceived += OnDeepLink;
#if UNITY_IOS
AppsFlyerSDK.AppsFlyer.waitForATTUserAuthorizationWithTimeoutInterval(30);
#endif
AppsFlyer.startSDK();
AppsFlyerSDK.AppsFlyerAdRevenue.start();
}
public async Task<string> GenInviteLink(string referrerUID, string referrerPID)
{
if (referrerUID == _referrerUID && !string.IsNullOrEmpty(_inviteLink))
return _inviteLink;
_inviteLink = string.Empty;
#if UNITY_EDITOR
await Awaiters.NextFrame;
#else
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("channel", "mobile_share");
parameters.Add("campaign", "friend_invite");
parameters.Add("deep_link_value", "friend_invite");
parameters.Add("deep_link_sub1", referrerUID);
parameters.Add("deep_link_sub2", referrerPID);
// Optional; makes the referrer ID available in the installs raw-data report
parameters.Add("af_sub1", referrerPID);
_tcs = new TaskCompletionSource<string>();
AppsFlyer.generateUserInviteLink(parameters, this);
_inviteLink = await _tcs.Task;
#endif
return _inviteLink;
}
#region Implement IAppsFlyerConversionData
public void onConversionDataSuccess(string conversionData)
{
Debug.Log("[AFDeepLinkHelper::didReceiveConversionData] success");
Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
_conversionDataDictionary = conversionDataDictionary;
// af_status and is_first_launch always received with onConversionDataSuccess, no need to check if the keys exist
AFState = _conversionDataDictionary["af_status"].ToString();
IsFirstLaunch = (bool)_conversionDataDictionary["is_first_launch"];
}
public void onConversionDataFail(string error)
{
Debug.LogWarning("[AFDeepLinkHelper::didReceiveConversionData] error: " + error);
_conversionDataDictionary = null;
}
public void onAppOpenAttribution(string attributionData)
{
Debug.Log("[AFDeepLinkHelper::onAppOpenAttribution] " + attributionData);
AttributionData = attributionData;
}
public void onAppOpenAttributionFailure(string error)
{
Debug.LogWarning("[AFDeepLinkHelper::onAppOpenAttributionFailure] error: " + error);
AttributionData = null;
}
#endregion // Implement IAppsFlyerConversionData
#region Implement IAppsFlyerUserInvite
public void onInviteLinkGenerated(string link)
{
if (_tcs != null)
{
_tcs.SetResult(link);
}
}
public void onInviteLinkGeneratedFailure(string error)
{
if (_tcs != null)
{
_tcs.SetResult(string.Empty);
}
}
public void onOpenStoreLinkGenerated(string link)
{
Debug.Log("[AFDeepLinkHelper::onOpenStoreLinkGenerated] " + link);
StoreLink = link;
}
#endregion // Implement IAppsFlyerUserInvite
#region Deeplink
/** All the DeepLink handling has to be done under the onDeepLink handler **/
void OnDeepLink(object sender, EventArgs args)
{
Debug.Log($"[AFDeepLinkHelper::onDeepLink] {args.GetType().Name}");
if (!(args is DeepLinkEventsArgs deepLinkEventArgs)) return;
Debug.Log($"[AFDeepLinkHelper::onDeepLink] DeepLink Status {deepLinkEventArgs.status.ToString()}");
switch (deepLinkEventArgs.status)
{
case DeepLinkStatus.FOUND:
DidReceivedDeepLink = true;
if (deepLinkEventArgs.isDeferred())
{
Debug.Log($"[AFDeepLinkHelper::onDeepLink] DeepLink is deferred");
}
else
{
Debug.Log($"[AFDeepLinkHelper::onDeepLink] This is a direct deep link");
}
_deepLinkParamsDictionary = GetDeepLinkParamsDictionary(deepLinkEventArgs);
break;
case DeepLinkStatus.NOT_FOUND:
Debug.Log($"[AFDeepLinkHelper::onDeepLink] DeepLink not found");
break;
default:
Debug.LogWarning($"[AFDeepLinkHelper::onDeepLink] DeepLink error");
break;
}
}
/** Get the DeepLink params depending on the device OS **/
private Dictionary<string, object> GetDeepLinkParamsDictionary(DeepLinkEventsArgs deepLinkEventArgs)
{
#if UNITY_IOS && !UNITY_EDITOR
if (deepLinkEventArgs.deepLink.ContainsKey("click_event") && deepLinkEventArgs.deepLink["click_event"] != null)
{
return deepLinkEventArgs.deepLink["click_event"] as Dictionary<string, object>;
}
#elif UNITY_ANDROID && !UNITY_EDITOR
return deepLinkEventArgs.deepLink;
#endif
return null;
}
#endregion // Deeplink
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5c70943931a9d4d4c89d8f687378f5f3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using System.Threading.Tasks;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class AgreementsPolicesPanel : MonoBehaviour, IPointerClickHandler
{
[SerializeField]
private Button aggreementBtn;
[SerializeField]
private Button quitBtn;
[SerializeField]
private TMP_Text title;
[SerializeField]
private TMP_Text text;
private const string prf_key = "AgreementsPolicesPanel";
void OnDisable()
{
aggreementBtn.onClick.RemoveAllListeners();
quitBtn.onClick.RemoveAllListeners();
}
public void OnPointerClick(PointerEventData eventData)
{
int linkIndex = TMP_TextUtilities.FindNearestLink(text, Input.mousePosition, null);
if (linkIndex != -1)
{
TMP_LinkInfo linkInfo = text.textInfo.linkInfo[linkIndex];
var linkID = linkInfo.GetLinkID();
if (linkID == "Privacy")
{
#if UNITY_IOS
linkID = GConstant.V_IOS_Privacy_Policy_URL;
#else
linkID = GConstant.V_Android_Privacy_Policy_URL;
#endif
}
Application.OpenURL(linkID);
}
}
private void OnAggreementBtnClicked()
{
Debug.Log("OnaggreementBtnClicked");
}
public async Task<bool> Agreement()
{
if(PlayerPrefs.HasKey(prf_key))
return true;
gameObject.SetActive(true);
var taskSource = new TaskCompletionSource<bool>();
aggreementBtn.onClick.AddListener(() =>
{
PlayerPrefs.SetInt(prf_key, 1);
taskSource.SetResult(true);
});
quitBtn.onClick.AddListener(() => taskSource.SetResult(false));
var aggree = await taskSource.Task;
aggreementBtn.onClick.RemoveAllListeners();
quitBtn.onClick.RemoveAllListeners();
gameObject.SetActive(false);
return aggree;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ca9397553a1e24044ae5e118b50c5c69
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,615 @@
// #######
// # # #### # # # # # ####
// # # # # # # ## # # #
// ##### # #### ###### # # # # #
// # # # # # # # # # # ###
// # # # # # # # # ## # #
// # # #### # # # # # ####
using System;
using System.Threading.Tasks;
using asap.core;
using game;
using UnityEngine;
using UnityEngine.Networking;
using Task = System.Threading.Tasks.Task;
using UnityEngine.AddressableAssets;
using System.Linq;
using System.Reflection;
using UnityEngine.ResourceManagement.AsyncOperations;
using System.Collections.Generic;
//using HybridCLR;
using tysdk;
using System.Collections;
public class Boostrap : MonoBehaviour
{
[SerializeField]
private RootCtx ctx;
private IConfig config;
[SerializeField]
private BoostrapLoading bsLoading;
[SerializeField]
private SimpleDialog reconnectDialog;
[SerializeField]
private SimpleDialog updateDialog;
[SerializeField]
private SimpleDialog updateSugetDialog;
[SerializeField]
private SimpleDialog maintanceDialog;
[SerializeField]
private AgreementsPolicesPanel agreementPanel;
[SerializeField]
private AssetLabelReference preloadGroup;
private System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
private double elapsed;
void Start()
{
//This will override OS specific culture
//settings and ensure predictable behavior when writing/reading string or text files.
System.Globalization.CultureInfo.DefaultThreadCurrentCulture
= new System.Globalization.CultureInfo("en-US");
ctx.OnInited += OnContextInited;
bsLoading.Show();
bsLoading.SetProgress(0);
bsLoading.SetDownloadSize(-1, -1);
}
// Callback from GContex when its ready
private void OnContextInited()
{
config = GContext.container.Resolve<IConfig>();
Boost();
ctx.OnInited = null;
}
private async void Boost()
{
Boostrapi18n.Instance.Init();
bsLoading.SetInfo(Boostrapi18n.Instance.GetText("msg_initializing"));
if(! await agreementPanel.Agreement())
{
RootCtx.ExitGame();
return;
}
tysdk.UnityBridgeFunc.RequestATT();
if (!await CheckNetwork())
{
await RetryDialog(reconnectDialog, CheckNetwork, "network");
}
await Awaiters.NextFrame;
// __ _
// _____ _____ _____ _____ ___ ___ _ __ / _(_) __ _ _____ _____ _____
//|_____|_____|_____|_____| / __/ _ \| '_ \| |_| |/ _` | |_____|_____|_____|
//|_____|_____|_____|_____| | (_| (_) | | | | _| | (_| | |_____|_____|_____|
// \___\___/|_| |_|_| |_|\__, |
// |___/
#if AGG
using (var e = GEvent.TackEvent("loading"))
{
e.AddContent("step", 1);
e.AddContent("elapsed", 0);
}
#endif
await Awaiters.NextFrame;
sw.Start();
// if (!await LoadConfig())
// await RetryDialog(reconnectDialog, LoadConfig, "config");
var isSuccessLoadRemoteConfigFile = await LoadConfig();
sw.Stop();
elapsed = sw.Elapsed.TotalSeconds;
sw.Reset();
#if AGG
using (var e = GEvent.TackEvent("loading"))
{
e.AddContent("step", 2);
e.AddContent("elapsed", elapsed);
}
#endif
await Awaiters.NextFrame;
var maintanceMsg = config.Get(GConstant.K_Maintance, string.Empty);
if (!string.IsNullOrEmpty(maintanceMsg))
{
ShowMantainceDialog(maintanceMsg);
return;
}
await Awaiters.NextFrame;
if (!await CheckVerion())
{
return;
}
#if AGG
// Change AGG server
var aggserver = config.Get("AGG_SERVER", string.Empty);
if (!string.IsNullOrEmpty(aggserver))
{
//更新服务器
UnityBridgeFunc.UnityResetServerUrl(aggserver);
}
#endif
await Awaiters.NextFrame;
/*
*
* _ _ _
* _____ _____ _____ _____ (_)___ ___ _ __ __| | __ _| |_ __ _ _____ _____ _____
*|_____|_____|_____|_____| | / __|/ _ \| '_ \ / _` |/ _` | __/ _` | |_____|_____|_____|
*|_____|_____|_____|_____| | \__ \ (_) | | | | | (_| | (_| | || (_| | |_____|_____|_____|
* _/ |___/\___/|_| |_| \__,_|\__,_|\__\__,_|
* |__/
*/
#if !UNITY_EDITOR
sw.Start();
// if (!await UpdateCfg(isSuccessLoadRemoteConfigFile))
// await RetryDialog(reconnectDialog, UpdateCfg, "cfg");
await UpdateCfg(isSuccessLoadRemoteConfigFile);
sw.Stop();
elapsed = sw.Elapsed.TotalSeconds;
sw.Reset();
#if AGG
using (var e = GEvent.TackEvent("loading"))
{
e.AddContent("step", 3);
e.AddContent("elapsed", elapsed);
}
#endif //AGG
await Awaiters.NextFrame;
#endif // !UNITY_EDITOR
/*
* _ _ _
* _____ _____ _____ _____ / \ __| | __| |_ __ _____ _____ _____
*|_____|_____|_____|_____| / _ \ / _` |/ _` | '__| |_____|_____|_____|
*|_____|_____|_____|_____| / ___ \ (_| | (_| | | |_____|_____|_____|
* /_/ \_\__,_|\__,_|_|
*/
/* sw.Start(); */
/**/
/* Addressables.WebRequestOverride = (UnityWebRequest request) => request.timeout = 15; */
/**/
/* while(!await UpdateAsset()) */
/* { */
/* #if AGG */
/* using (var e = GEvent.TackEvent("retry")) */
/* { */
/* e.AddContent("type", "update"); */
/* } */
/* #endif */
/* Debug.LogWarning("UpdateAsset failed"); */
/* } */
/**/
/* sw.Stop(); */
/* elapsed = sw.Elapsed.TotalSeconds; */
/* sw.Reset(); */
/**/
/* #if AGG */
/* using (var e = GEvent.TackEvent("loading")) */
/* { */
/* e.AddContent("step", 5); */
/* e.AddContent("elapsed", elapsed); */
/* } */
/* #endif */
/*
sw.Start();
await AfterAssetUpdate();
sw.Stop();
elapsed = sw.Elapsed.TotalSeconds;
sw.Reset();
*/
/*
* _
* _____ _____ _____ _____ ___ ___| |_ _ _ _ __ _____ _____ _____
*|_____|_____|_____|_____| / __|/ _ \ __| | | | '_ \ |_____|_____|_____|
*|_____|_____|_____|_____| \__ \ __/ |_| |_| | |_) | |_____|_____|_____|
* |___/\___|\__|\__,_| .__/
* |_|
*/
await AfterAssetUpdateV2();
#if AGG
using (var e = GEvent.TackEvent("loading"))
{
e.AddContent("step", 6);
e.AddContent("elapsed", elapsed);
}
#endif
//StopUpdateLoadingInfo();
await GoToStageV2();
}
private async Task<bool> CheckNetwork()
{
await Awaiters.NextFrame;
return Application.internetReachability != NetworkReachability.NotReachable;
}
private async Task<bool> LoadConfig()
{
var success = await config.InitConfig();
// Change Addressable remote location, using custom assetbundle server
var customAddressableRemoteURL = config.Get(GConstant.K_Custom_Addressable, string.Empty);
var originAddressableRemoteURL = config.Get(GConstant.K_Origin_Addressable, string.Empty);
if (!string.IsNullOrEmpty(customAddressableRemoteURL)
&& !string.IsNullOrEmpty(originAddressableRemoteURL))
{
ctx.ChangeAddressableRemoteUrl(customAddressableRemoteURL, originAddressableRemoteURL);
}
await Awaiters.NextFrame;
bsLoading.SetProgress(0.02f);
Debug.Log($"[Boostrap]::LoadConfig Done success: {success}");
return success;
}
private async Task<bool> UpdateCfg(bool isSuccessLoadRemoteConfigFile)
{
var result = await cfg.Tables.UpdateCfg(config, isSuccessLoadRemoteConfigFile);
bsLoading.SetProgress(0.05f);
return result;
}
private async Task<bool> CheckVerion()
{
var remoteVer = VersionTool.FromString(config.Get(GConstant.K_Ver, string.Empty));
var localVer = VersionTool.FromLocal();
if (remoteVer > localVer)
{
updateDialog.Config(new SimpleDialog.Context()
{
message = Boostrapi18n.Instance.GetText("title_hardupdate"),
message2 = Boostrapi18n.Instance.GetText("content_hardupdate"),
okAction = () =>
{
#if UNITY_IOS
var url = config.Get(GConstant.K_APP_Store_URL, string.Empty);
#else
var url = config.Get(GConstant.K_Google_Play_URL, string.Empty);
#endif
Application.OpenURL(url);
RootCtx.ExitGame();
}
});
return false;
}
var newVer = config.Get(GConstant.K_Ver_New, string.Empty);
if (!string.IsNullOrEmpty(newVer))
{
var confirm = new TaskCompletionSource<bool>();
updateSugetDialog.Config(new SimpleDialog.Context()
{
message = Boostrapi18n.Instance.GetText("title_hardupdate"),
message2 = Boostrapi18n.Instance.GetText("content_hardupdate"),
okAction = () =>
{
#if UNITY_IOS
var url = config.Get(GConstant.K_APP_Store_URL, string.Empty);
#else
var url = config.Get(GConstant.K_Google_Play_URL, string.Empty);
#endif
Application.OpenURL(url);
confirm.SetResult(false);
RootCtx.ExitGame();
},
closeAction = () =>
{
confirm.SetResult(true);
}
});
return await confirm.Task;
}
return true;
}
private async Task<bool> UpdateAsset()
{
#if UNITY_EDITOR
await Awaiters.NextFrame;
return true;
#else
await Awaiters.NextFrame;
bsLoading.SetVersionInfo(VersionTool.FromLocal().ToVerString());
try
{
Debug.Log("Start UpdateAsset");
//Addressables.WebRequestOverride = (UnityWebRequest request) => request.timeout = 6;
List<string> update_catalogs = null;
var updateCheckHandle = Addressables.CheckForCatalogUpdates(false);
update_catalogs = await updateCheckHandle.Task;
if(updateCheckHandle.OperationException != null || updateCheckHandle.Status == AsyncOperationStatus.Failed)
{
Debug.LogError($"update checked failed: { updateCheckHandle.OperationException.Message }");
return false;
}
Addressables.Release(updateCheckHandle);
if(null != update_catalogs)
{
Debug.Log($"update catalogs count: {update_catalogs.Count}");
}
if(null != update_catalogs && update_catalogs.Count > 0)
{
var updateCatalogHandle = Addressables.UpdateCatalogs(update_catalogs, false);
await updateCatalogHandle.Task;
if(updateCatalogHandle.OperationException != null || updateCatalogHandle.Status == AsyncOperationStatus.Failed)
{
Debug.LogError($"update catalogs failed: {updateCatalogHandle.OperationException.Message}");
return false;
}
Addressables.Release(updateCatalogHandle);
}
var locationsHandle = Addressables.LoadResourceLocationsAsync(preloadGroup.labelString);
var locations = await locationsHandle.Task;
if(locationsHandle.OperationException != null || locationsHandle.Status == AsyncOperationStatus.Failed)
{
Debug.LogError($"load resource locations failed: {locationsHandle.OperationException.Message}");
return false;
}
Addressables.Release(locationsHandle);
var downloadSizeHandle = Addressables.GetDownloadSizeAsync(locations);
var downloadSize = await downloadSizeHandle.Task;
if(downloadSizeHandle.OperationException != null || downloadSizeHandle.Status == AsyncOperationStatus.Failed)
{
Debug.LogError($"get download size failed: {downloadSizeHandle.OperationException.Message}");
return false;
}
Addressables.Release(downloadSizeHandle);
if(downloadSize > 0)
{
bsLoading.SetInfo(Boostrapi18n.Instance.GetText("msg_downloading"));
var downloadHandle = Addressables.DownloadDependenciesAsync(locations);
DownloadStatus downloadStatus;
long downloadedBytes = 0;
float percent = 0;
while (!downloadHandle.IsDone && downloadHandle.OperationException == null && downloadHandle.Status != AsyncOperationStatus.Failed)
{
downloadStatus = downloadHandle.GetDownloadStatus();
if(downloadStatus.DownloadedBytes > downloadedBytes)
downloadedBytes = downloadStatus.DownloadedBytes;
if(downloadStatus.Percent > percent)
percent = downloadStatus.Percent;
bsLoading.SetProgress(percent);
bsLoading.SetInfo(Boostrapi18n.Instance.GetText("msg_downloading"));
bsLoading.SetDownloadSize(downloadedBytes, downloadStatus.TotalBytes);
//bsLoading.SetSubProgress(downloadHandle.PercentComplete);
await Awaiters.NextFrame;
}
if(downloadHandle.OperationException != null)
{
Debug.LogError($"Download Fail: {downloadHandle.OperationException.Message}");
return false;
}
if(downloadHandle.Status == AsyncOperationStatus.Failed)
{
Debug.LogError($"Download Fail Status: {downloadHandle.Status}");
return false;
}
downloadStatus = downloadHandle.GetDownloadStatus();
if(downloadStatus.TotalBytes == 0 && downloadStatus.DownloadedBytes == 0)
{
Debug.LogError($"Download Fail: {downloadStatus.TotalBytes} {downloadStatus.DownloadedBytes}");
return false;
}
Addressables.Release(downloadHandle);
}
//bsLoading.SetSubProgress(-1);
}
catch(System.Exception e)
{
Debug.LogError($"[Boostrap]::UpdateAsset error: {e.Message}");
return false;
}
//finally
//{
//Addressables.WebRequestOverride = null;
//}
bsLoading.SetProgress(0.1f);
bsLoading.SetInfo(Boostrapi18n.Instance.GetText("msg_loadingresource"));
await Awaiters.NextFrame;
var remoteVer = VersionTool.FromString(config.Get(GConstant.K_Ver, string.Empty));
remoteVer.Save();
bsLoading.SetVersionInfo(remoteVer.ToVerString());
await Awaiters.NextFrame;
return true;
#endif
}
private async Task AfterAssetUpdateV2()
{
bsLoading.SetProgress(0.15f);
await SubBoostrap.RegisterServices(ctx.gameObject);
bsLoading.SetProgress(0.16f);
await SubBoostrap.AfterAssetUpdate(config, bsLoading.SetProgress);
bsLoading.SetProgress(0.18f);
}
private async Task GoToStageV2()
{
Debug.Log("Boostrap Done");
await SubBoostrap.ShowLoadingScreen(config, ctx.gameObject);
await Awaiters.NextFrame;
bsLoading.Hide();
_ = GContext.container.Resolve<IStageService>().SwitchStageAsync("LoginStage");
}
/*
private Type _hotUpdateBoostrapType;
private async Task AfterAssetUpdate()
{
var hotUpdateAsset = await LoadDll();
bsLoading.SetProgress(0.15f);
Debug.Log($"[Boostrap]::AfterAssetUpdate LoadDll Done");
_hotUpdateBoostrapType = hotUpdateAsset.GetType("HotUpateBoostrap");
var task = (Task)_hotUpdateBoostrapType.GetMethod("RegisterServices").Invoke(null, new object[] { ctx.gameObject });
await task;
bsLoading.SetProgress(0.16f);
var progressAction = Delegate.CreateDelegate(typeof(Action<float>), bsLoading, "SetProgress");
task = (Task)_hotUpdateBoostrapType.GetMethod("AfterAssetUpdate").Invoke(null, new object[] { config, progressAction });
await task;
Debug.Log($"[Boostrap]::AfterAssetUpdate RegisterServices Done");
bsLoading.SetProgress(0.18f);
}
private async Task<Assembly> LoadDll()
{
#if !UNITY_EDITOR
//Load HotUpdate dll
var dllAsset = await Addressables.LoadAssetAsync<TextAsset>("Hotupdate.dll").Task;
var bytes = dllAsset.bytes;
var hotUpdateAsset = Assembly.Load(bytes);
Addressables.Release(dllAsset);
//Load Aot dll
var aotDllTasks = GConstant.AOT_Dlls.Select(aotDllName => Addressables.LoadAssetAsync<TextAsset>(aotDllName).Task);
await Task.WhenAll(aotDllTasks);
var dllLoadTasks = new List<Task>();
foreach (var aotDllTask in aotDllTasks)
{
var aotDllBytes = aotDllTask.Result.bytes;
dllLoadTasks.Add(Task.Run(() => {
HybridCLR.RuntimeApi.LoadMetadataForAOTAssembly(aotDllBytes, HomologousImageMode.SuperSet);
}));
}
await Task.WhenAll(dllLoadTasks);
#else
var hotUpdateAsset = System.AppDomain.CurrentDomain.GetAssemblies().First(a => a.GetName().Name == "HotUpdate");
await Awaiters.NextFrame;
#endif
return hotUpdateAsset;
}
private async Task GoToStage()
{
Debug.Log("Boostrap Done");
var task = (Task)_hotUpdateBoostrapType.GetMethod("ShowLoadingScreen").Invoke(null, new object[] { config });
await task;
await Awaiters.NextFrame;
bsLoading.Hide();
_ = GContext.container.Resolve<IStageService>().SwitchStageAsync("LoginStage");
}
*/
void OnDestory()
{
ctx.OnInited -= OnContextInited;
}
private void ShowMantainceDialog(string maintanceMessage)
{
maintanceDialog.Config(new SimpleDialog.Context()
{
message = Boostrapi18n.Instance.GetText("title_maintenance"),
message2 = string.Format(Boostrapi18n.Instance.GetText("content_maintenance"), maintanceMessage),
okAction = () => RootCtx.ExitGame(),
});
}
private async Task RetryDialog(SimpleDialog dialog, Func<Task<bool>> func, string retryType)
{
while (true)
{
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", retryType);
}
#endif
var retry = new TaskCompletionSource<bool>();
dialog.Config(new SimpleDialog.Context()
{
message = Boostrapi18n.Instance.GetText("subtitle_networkfailed"),
message2 = Boostrapi18n.Instance.GetText("content_networkfailed"),
okAction = async () => retry.SetResult(await func()),
});
if (await retry.Task) return;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dbaf5fb72da8a6f4cb1dd6f29cd60b86
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,94 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class BoostrapLoading : MonoBehaviour
{
[SerializeField]
private TMP_Text loadingInfo;
[SerializeField]
private TMP_Text versionInfo;
[SerializeField]
private Image progressBar;
[SerializeField]
private Image subProgressBar;
[SerializeField]
private TMP_Text ProgressLabel;
[SerializeField]
private TMP_Text DownloadSize;
public void Show()
{
gameObject.SetActive(true);
}
public void Hide()
{
gameObject.SetActive(false);
}
public void SetVersionInfo(string verStr)
{
versionInfo.text = verStr;
}
public void SetProgress(float progress)
{
progressBar.fillAmount = progress;
var percent_text = (progress * 100f);
ProgressLabel.text = $"{percent_text.ToString("0.00")}%";
//bool visible = progress != 0;
bool visible = progress >= 0;
progressBar.transform.parent.gameObject.SetActive(visible);
ProgressLabel.gameObject.SetActive(visible);
}
private const double byte2mb = 1024 * 1024;
public void SetProgress(float progress, long downloadBytes, long totalBytes)
{
bool visible = progress >= 0;
progressBar.transform.parent.gameObject.SetActive(visible);
ProgressLabel.gameObject.SetActive(visible);
if(visible)
{
progressBar.fillAmount = progress;
var progressStr = $"{(downloadBytes/byte2mb).ToString("0.00")}MB/{(totalBytes/byte2mb).ToString("0.00")}MB ({(progress * 100f).ToString("0.00")}%)";
ProgressLabel.text = progressStr;
}
}
public void SetSubProgress(float progress)
{
bool visible = progress >= 0;
subProgressBar.gameObject.SetActive(visible);
if(visible)
{
subProgressBar.fillAmount = progress;
}
}
public void SetDownloadSize(long downloadBytes, long totalBytes)
{
if(downloadBytes <0 || downloadBytes == totalBytes)
DownloadSize.text = string.Empty;
else
DownloadSize.text = $"{(downloadBytes/byte2mb).ToString("0.0")}MB/{(totalBytes/byte2mb).ToString("0.0")}MB";
}
public void SetInfo(string info)
{
loadingInfo.text = info;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 39873ea9f0d504546ab58d2ae5d178fa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,102 @@
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
public class Boostrapi18n
{
private static Boostrapi18n _Instance;
private Dictionary<string, string[]> textDic;
int currentIndex = 2; //default en
public Boostrapi18n()
{
textDic = ReadFromCsv();
}
public static Boostrapi18n Instance
{
get
{
if (_Instance == null)
{
_Instance = new Boostrapi18n();
}
return _Instance;
}
}
public void Init()
{
textDic = ReadFromCsv();
}
private Dictionary<string, string[]> ReadFromCsv()
{
//read tsv
var tsv = BetterStreamingAssets.ReadAllText("boostrapi18n.tsv");
textDic = new Dictionary<string, string[]>();
var lines = tsv.Split('\n');
if (lines.Length < 2) return textDic;
var header = lines[0];
var headers = header.Split('\t');
if (headers.Length < 2) return textDic;
string Language = "en";
if (!PlayerPrefs.HasKey("Lang"))
{
CultureInfo info = System.Globalization.CultureInfo.CurrentUICulture;
Language = info.TwoLetterISOLanguageName;
if (Language == "zh")
{
if (info.DisplayName.Contains("Simplified"))
{
Language = "zh_Hans";
}
else
{
Language = "zh_Hant";
}
}
}
else
{
Language = PlayerPrefs.GetString("Lang");
}
for (int i = 1; i < headers.Length; i++)
{
//把value[1]里面的"\n","\r","\r\n"替换为""
string v = headers[i].Replace("\n", "").Replace("\r", "").Replace("\r\n", "");
if (v == "text_" + Language)
{
currentIndex = i - 1;
break;
}
}
for (int i1 = 1; i1 < lines.Length; i1++)
{
string line = lines[i1];
var values = line.Split('\t');
if (values.Length < 2) continue;
var key = values[0];
string[] value = new string[values.Length - 1];
for (int i = 1; i < values.Length; i++)
{
//把value[1]里面的"\n","\r","\r\n"替换为""
string v = values[i].Replace("\n", "").Replace("\r", "").Replace("\r\n", "").Replace("\\r\\n", "\r\n");
value[i - 1] = v;
//value[i - 1] = values[i];
}
textDic.TryAdd(key, value);
}
return textDic;
}
public string GetText(string key)
{
if (!textDic.ContainsKey(key))
{
return string.Empty;
}
return textDic[key][currentIndex];
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a2b4a2cd74aff68448085a1c9b5f568a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
public class CertHandler : UnityEngine.Networking.CertificateHandler
{
protected override bool ValidateCertificate(byte[] certificateData)
{
return true;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b7269d611fae2410885300a7755f4c11
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,372 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using asap.core;
using SimpleJSON;
using UnityEngine;
using UnityEngine.Networking;
public static class ConfigExtension
{
private const string defaultconfig = "9Nf/P8vm2+7Ciph2jH1QnEaHCK3cAl7lNnCJc/uxSKGVqcJgWilN3VgaC/74coHRiRpxEelC2+ia7qcjnHhA3OQN82rcVJOP24pGKrSbSgOIGbH9cCEUhdYRo5vnVgLBqlTS/c/AajowTkN59O0AYxDC7J3jq6ptLXdmuG27JYS9NXOQDkgxpzEpG7JTtczHKxhWAv+9uSzbJRCs16KeusbJX1YtNZM8wjCD9esTv4zXXMIpZPlXb86NjHiI02TakAdHo0plO+Di9n5UCC8/4+QGoKNyQgtvIkzMyoGziO4DOLy/VkfITenFv/+9DY0LmpZGa7Cog89znaYyVMTiC/3R2IefXXh04+8uqmyzeVKqh0grcU9qmz485wCoUl/TM9F8+s1Jhp/eaB/E7luOjc57Kz0Eyw2Qko7Fo+lCaRJE1uex9fB46v0LhddSHCEWw8QERmqG9KcmvG4LsyafupA8kliDzj7a7XIzGrgnNnsMxLgeYsSbNiBvXXESeeNCoqiOQTTBpk/br0QuTHTG2DRxUZZ4KM3SKZtHEZ2bZV2FUS4azFpfDXUGoc86O+xz6hAIMbdKCHyqyEeKMmHIzQI9OlIaa3KGwk+w1eFDUuq4zyTh+qGuClZynanUkfNe8mTmFtBax2f3MJHjGpXJT0VdtY/R+5ZQO0nCU30THfnryG0GURsrv6MQYiQX5hsLqG9Z72ybbbbqIR2rvE2w13DM/tqTb4i/hN0+pbeTKkUpdNIWEsR94Q==";
private static string RemoteConfigUrl { get; set; }
public static void Rest(this IConfig config)
{
RemoteConfigUrl = null;
}
public static async Task<bool> InitConfig(this IConfig config)
{
JSONNode streamingAssetConfig = null;
JSONNode persistConfig = null;
bool isSuccessLoadRemoteConfigFile = true;
if (RemoteConfigUrl == null)
{
streamingAssetConfig = GetStreamingAssetConfig();
persistConfig = GetPersistConfig();
}
if (RemoteConfigUrl == null)
{
RemoteConfigUrl = string.Format(GConstant.V_Static_Res_URL, VersionTool.PackVer);
}
JSONNode remoteConfig = await GetRemoteConfig();
if (remoteConfig == null)
{
var remoteConfigStr = Decrypt(defaultconfig);
remoteConfig = JSON.Parse(remoteConfigStr);
remoteConfig["Ver"] = VersionTool.FromLocal().ToVerString();
isSuccessLoadRemoteConfigFile = false;
}
foreach (var element in remoteConfig)
{
config.Set(element.Key, element.Value.Value);
}
if (streamingAssetConfig != null)
{
foreach (var element in streamingAssetConfig)
{
config.Set(element.Key, element.Value.Value);
}
}
if (persistConfig != null)
{
foreach (var element in persistConfig)
{
config.Set(element.Key, element.Value.Value);
}
}
config.Set(GConstant.K_Static_Res_URL, RemoteConfigUrl);
return isSuccessLoadRemoteConfigFile;
}
private static readonly float[] timeoutValues = new float[] { 1, 2, 2 };
public static async Task<JSONNode> GetRemoteConfig()
{
UnityEngine.Assertions.Assert.IsNotNull(RemoteConfigUrl, "Config is not inited");
await Awaiters.NextFrame;
var maxRetryTimes = timeoutValues.Length;
for (int retryTime = 0; retryTime < maxRetryTimes; retryTime++)
{
var rawConfig = await DoGetRawConfigUWR(timeoutValues[retryTime], retryTime, maxRetryTimes);
if (!string.IsNullOrEmpty(rawConfig))
{
Debug.Log($"<color=orange>Load remote config success {retryTime + 1}/{maxRetryTimes}</color>");
return JSON.Parse(rawConfig);
}
}
return null;
}
private static async Task<string> DoGetRawConfigUWR(float timeoutInSec, int retryTimes, int maxRetryTimes)
{
using (var req = UnityWebRequest.Get($"{RemoteConfigUrl}/{GConstant.V_Remote_Config_Path}"))
{
var stopwatch = new System.Diagnostics.Stopwatch();
var cts = new CancellationTokenSource();
cts.CancelAfter(TimeSpan.FromSeconds(timeoutInSec));
var ct = cts.Token;
stopwatch.Start();
req.timeout = (int)timeoutInSec;
req.SetRequestHeader("Accept", "application/json");
var op = req.SendWebRequest();
try
{
while (!op.isDone && !ct.IsCancellationRequested)
{
await Awaiters.NextFrame;
}
ct.ThrowIfCancellationRequested();
stopwatch.Stop();
if (req.result == UnityWebRequest.Result.Success)
{
return Decrypt(req.downloadHandler.text);
}
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", stopwatch.ElapsedMilliseconds);
e.AddContent("reason", req.result.ToString());
e.AddContent("skip", retryTimes >= maxRetryTimes - 1);
e.AddContent("error", req.error);
}
#endif // AGG
Debug.LogWarning($"Load remote config failed {req.result.ToString()} {req.error} {retryTimes + 1}/{maxRetryTimes}");
}
catch (OperationCanceledException)
{
req.Abort();
stopwatch.Stop();
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", stopwatch.ElapsedMilliseconds);
e.AddContent("reason", "cancel");
e.AddContent("skip", retryTimes >= maxRetryTimes - 1);
e.AddContent("error", req.error ?? "cancel");
}
#endif // AGG
Debug.LogWarning($"Load remote config cancel {req.result.ToString()} {req.error} {retryTimes + 1}/{maxRetryTimes}");
}
finally
{
cts.Dispose();
}
return null;
}
}
/**
private static async Task<string> DoGetRawConfig(float timeoutInSec, int retryTimes)
{
var timeout = TimeSpan.FromSeconds(timeoutInSec);
var handler = new System.Net.Http.HttpClientHandler(){
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 | System.Security.Authentication.SslProtocols.Tls11 | System.Security.Authentication.SslProtocols.Tls,
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }
};
using (var httpClient = new System.Net.Http.HttpClient(handler))
{
httpClient.Timeout = timeout;
var stopwatch = new System.Diagnostics.Stopwatch();
try
{
stopwatch.Start();
var respon = await httpClient.GetAsync($"{RemoteConfigUrl}/{GConstant.V_Remote_Config_Path}");
stopwatch.Stop();
if (respon.IsSuccessStatusCode)
{
string remoteConfigStr = await respon.Content.ReadAsStringAsync();
await Awaiters.NextFrame;
return Decrypt(remoteConfigStr);
}
else
{
var elapsed = stopwatch.ElapsedMilliseconds;
Debug.LogWarning($"Load remote config failed {respon.StatusCode.ToString()}");
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed);
e.AddContent("reason", respon.StatusCode.ToString());
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", "http_request_failed");
}
#endif//AGG
}
}
catch (System.Net.Http.HttpRequestException httpEx)
{
if (stopwatch.IsRunning)
stopwatch.Stop();
var elapsed = stopwatch.Elapsed;
var errorMessage = $"HTTP request failed: {httpEx.Message}";
if (httpEx.InnerException != null)
{
errorMessage += $" Inner: {httpEx.InnerException.Message}";
if(httpEx.InnerException.InnerException != null)
{
errorMessage += $" InnerInner: {httpEx.InnerException.InnerException.Message}";
}
}
Debug.LogWarning(errorMessage);
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed.TotalMilliseconds);
e.AddContent("reason", "httpEx");
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", errorMessage);
}
#endif//AGG
}
catch (System.Threading.Tasks.TaskCanceledException timeoutEx)
{
if (stopwatch.IsRunning)
stopwatch.Stop();
var elapsed = stopwatch.Elapsed;
Debug.LogWarning($"Request timeout after {timeoutInSec}s: {timeoutEx.Message}");
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed.TotalMilliseconds);
e.AddContent("reason", $"timeout");
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", timeoutEx.Message);
}
#endif//AGG
}
catch (System.Security.Cryptography.CryptographicException cryptoEx)
{
if (stopwatch.IsRunning)
stopwatch.Stop();
var elapsed = stopwatch.Elapsed;
Debug.LogError($"Decryption failed: {cryptoEx.Message}");
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed.TotalMilliseconds);
e.AddContent("reason", "cryptoEx");
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", cryptoEx.Message);
}
#endif//AGG
}
catch (Exception exception)
{
if (stopwatch.IsRunning)
stopwatch.Stop();
var elapsed = stopwatch.ElapsedMilliseconds;
var errorMessage = $"Unexpected error loading remote config: {exception.Message}";
if (exception.InnerException != null)
{
errorMessage += $" Inner: {exception.InnerException.Message}";
}
Debug.LogError(errorMessage);
#if AGG
using (var e = GEvent.TackEvent("retry"))
{
e.AddContent("type", "config");
e.AddContent("duration_ms", elapsed);
e.AddContent("reason", "unexpected_error");
e.AddContent("skip", retryTimes >= 2);
e.AddContent("error", errorMessage);
}
#endif//AGG
}
}
return null;
}
*/
/*
* public static async Task<JSONNode> GetRemoteConfig()
* {
* UnityEngine.Assertions.Assert.IsNotNull(RemoteConfigUrl, "Config is not inited");
* var request = UnityWebRequest.Get($"{RemoteConfigUrl}/{GConstant.V_Remote_Config_Path}");
* request.timeout = 5;
* await request.SendWebRequest();
*
* if (request.result != UnityWebRequest.Result.Success)
* {
* return null;
* }
*
* string remoteConfigStr = request.downloadHandler.text;
* remoteConfigStr = Decrypt(remoteConfigStr);
* return SimpleJSON.JSON.Parse(remoteConfigStr);
* }
*/
const string RTMKey = "tbambooz";
private static string Decrypt(string text)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = Encoding.ASCII.GetBytes(RTMKey);
des.IV = Encoding.ASCII.GetBytes(RTMKey);
ICryptoTransform decryptor = des.CreateDecryptor(des.Key, des.IV);
byte[] inputBytes = Convert.FromBase64String(text);
byte[] outputBytes = decryptor.TransformFinalBlock(inputBytes, 0, inputBytes.Length);
return Encoding.UTF8.GetString(outputBytes);
}
private static JSONNode GetStreamingAssetConfig()
{
var debugConfigPath = GConstant.V_Debug_Config_Path;
var text = BetterStreamingAssets.ReadAllText(debugConfigPath);
//如果第一个字符是#e就返回false
if (!text.StartsWith("#"))
{
var debugConfig = SimpleJSON.JSON.Parse(text);
if (debugConfig.HasKey(GConstant.K_Static_Res_URL))
{
RemoteConfigUrl = debugConfig[GConstant.K_Static_Res_URL];
Debug.Log($"<color=yellow>Debug Static Res URL => {RemoteConfigUrl}</color>");
}
return debugConfig;
}
return null;
}
private static JSONNode GetPersistConfig()
{
var debugConfigPath = Path.Combine(Application.persistentDataPath, GConstant.V_Debug_Config_Path);
if (File.Exists(debugConfigPath))
{
var debugConfig = SimpleJSON.JSON.Parse(File.ReadAllText(debugConfigPath));
if (debugConfig.HasKey(GConstant.K_Static_Res_URL))
{
RemoteConfigUrl = debugConfig[GConstant.K_Static_Res_URL];
Debug.Log($"<color=yellow>Debug Static Res URL => {RemoteConfigUrl}</color>");
}
return debugConfig;
}
return null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9f6b7f8a5010f4daa82832584171069f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,99 @@
// #####
// # # #### # # #### ##### ## # # #####
// # # # ## # # # # # ## # #
// # # # # # # #### # # # # # # #
// # # # # # # # # ###### # # # #
// # # # # # ## # # # # # # ## #
// ##### #### # # #### # # # # # #
/*
*---------------------------------------------------------------
* V_XXXXX for Config Values
* K_XXXXX for Config Keys
*===============================================================
*/
using System.Collections.Generic;
public class GConstant
{
public const string V_Debug_Config_Path = "debugconfig.json";
#if UNITY_ANDROID
public const string V_Remote_Config_Path = "androidconfig.json";
#elif UNITY_IOS
public const string V_Remote_Config_Path = "iosconfig.json";
#else
public const string V_Remote_Config_Path = "config.json";
#endif
public const string K_Static_Res_URL = "StaticResURL";
public const string V_Static_Res_URL = "https://128-ft-cdn-aws.arksgame.com/ab/{0}";
public const string K_Event_API_URL = "EventApiURL";
public const string K_Maintance = "Maintance";
public const string K_Ver = "Ver";
public const string K_Ver_New = "Ver_New";
public const string K_PlayFab_Title = "PlayFabTitle";
public const string K_PlayFab_TimeOut = "PlayFabTimeOut";
public const string K_Custom_Addressable = "Custom_Addressable_URL";
public const string K_Origin_Addressable = "Origin_Addressable_URL";
public const string K_Android_Privacy_Policy_URL = "PrivacyPolicy";
public const string V_Android_Privacy_Policy_URL = "https://arksgame.com/privacyGoogle.html";
public const string K_IOS_Privacy_Policy_URL = "PrivacyPolicy";
public const string V_IOS_Privacy_Policy_URL = "https://arksgame.com/ps.html";
public const string K_User_Agreement_URL = "UserAgreement";
public const string V_User_Agreement_URL = "https://arksgame.com/terms.html";
public const string K_APP_Store_URL = "APP_Store_URL";
public const string K_Google_Play_URL = "Google_Play_URL";
public const string V_Debug_PF_Title = "6DC6D";
public const string K_BuglyAppID = "BuglyAppID";
public const string V_BuglyAppID = "af5ac6a2c2";
public const string K_BuglyAppKey = "BuglyAppKey";
public const string V_BuglyAppKey = "5de4f8e4-9552-4bb9-9423-82ce8daf2d6c";
public const string K_HeartBeat = "HeartBeat";
public const string K_FPS = "FPS";
public const string K_RTMP_ID = "RTMPid";
public const string K_RTM_Server_Endpoint = "RTMServerEndpoint";
public const string K_RTM_Hmac_Secret = "RTMHmacSecret";
public const string K_FuncUrl = "FuncUrl";
public const string V_FuncUrl = "http://192.168.9.101:7071";
public const string K_FuncKey = "FuncKey";
public const string V_FuncKey = "testKey";
public const string TA_URL = "https://ta-event.bamboogames.fun";
public const string TA_APPID = "9876bb56ee484b528064d1db40a57ec4";
public const string AF_KEY = "rSySeWtvKabfbPZE7Lmx7C";
public const string AF_APPID = "6505145935";
public const string AF_OneLinkID = "jT1Q";
public static readonly IReadOnlyList<string> AOT_Dlls = new List<string>()
{
"mscorlib.dll",
"System.dll",
"System.Core.dll",
"Newtonsoft.Json.dll",
"asap.core.dll",
"UniRx.dll",
"IngameDebugConsole.Runtime.dll"
};
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6ba3f3f5ca3183a419aa7fd179b03a67
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,222 @@
using System;
using System.Collections;
using System.Collections.Generic;
using AppsFlyerSDK;
using asap.core;
using Newtonsoft.Json.Linq;
using tysdk;
using UnityEngine;
public class GEvent : IDisposable
{
private JObject content = new JObject();
private string eventName;
private bool afSend = false;
private bool gaSend = true;
private const string TA_APPID_KEY = "ta_appid";
private const string TA_URL_KEY = "ta_url";
private static bool _hasInit = false;
public static void Init()
{
if (_hasInit) return;
TaInit();
InitAppsFlyer();
_hasInit = true;
}
public static void SetProp(string key, object prop)
{
var props = new Dictionary<string, object>(){{key, prop}};
SetProps(props);
}
public static void SetProps(Dictionary<string, object> props)
{
ThinkingData.Analytics.TDAnalytics.SetSuperProperties( props);
tysdk.UnityBridgeFunc.SetGaCommonInfo(Newtonsoft.Json.JsonConvert.SerializeObject(props));
}
public static void SetUserProp(string key, object prop, bool once = false)
{
var props = new Dictionary<string, object>(){{key, prop}};
SetUserProps(props, once);
}
public static void SetUserProps(Dictionary<string, object> props, bool once = false)
{
if(once)
{
ThinkingData.Analytics.TDAnalytics.UserSetOnce(props);
}
else
{
ThinkingData.Analytics.TDAnalytics.UserSet(props);
}
}
private static void InitAppsFlyer()
{
var afKey = GConstant.AF_KEY;
var afAppID = GConstant.AF_APPID;
var afOneLinkID = GConstant.AF_OneLinkID;
var afCustomerUserID = ThinkingData.Analytics.TDAnalytics.GetDistinctId();
AFHelper.Instance.Init(afKey, afAppID, afCustomerUserID, afOneLinkID, false);
Debug.Log("[GEvent::InitAppsFlyer] AppsFlyer inited");
}
private static void TaInit()
{
var taAppId = GConstant.TA_APPID;
var taUrl = GConstant.TA_URL;
var autoTrackEventType = ThinkingData.Analytics.TDAutoTrackEventType.AppStart
| ThinkingData.Analytics.TDAutoTrackEventType.AppEnd
| ThinkingData.Analytics.TDAutoTrackEventType.AppInstall;
ThinkingData.Analytics.TDAnalytics.Init(taAppId, taUrl);
ThinkingData.Analytics.TDAnalytics.EnableThirdPartySharing(ThinkingData.Analytics.Utils.TDThirdPartyType.APPSFLYER);
ThinkingData.Analytics.TDAnalytics.EnableAutoTrack(autoTrackEventType);
ThinkingData.Analytics.TDAnalytics.EnableLog(false);
Debug.Log("[GEvent::TaInit] ThinkingData inited");
}
public static void OnLogin(string userID, string customUserID)
{
ThinkingData.Analytics.TDAnalytics.Login(customUserID);
ThinkingData.Analytics.TDAnalytics.EnableThirdPartySharing(ThinkingData.Analytics.Utils.TDThirdPartyType.APPSFLYER);
}
private GEvent(string eventName, bool afSend = false, bool gaSend = true)
{
this.eventName = eventName;
this.afSend = afSend;
this.gaSend = gaSend;
}
public GEvent AddContent(string key, string value)
{
content[key] = value;
return this;
}
public GEvent AddContent(string key, int value)
{
content[key] = value;
return this;
}
public GEvent AddContent(string key, bool value)
{
content[key] = value;
return this;
}
public GEvent AddContent(string key, float value)
{
content[key] = value;
return this;
}
public GEvent AddContent(string key, JToken value)
{
content[key] = value;
return this;
}
public GEvent WithGAEvent(string eventName)
{
this.eventName = eventName;
this.afSend = true;
this.gaSend = true;
return this;
}
public void Dispose()
{
Dictionary<string, object> properties = content.ToObject<Dictionary<string, object>>();
ThinkingData.Analytics.TDAnalytics.Track(eventName, properties);
Dictionary<string, string> eventValues = content.ToObject<Dictionary<string, string>>();
if(afSend)
{
AppsFlyer.sendEvent(eventName, eventValues);
}
if(gaSend)
{
TYSdkFacade.Instance.EventTrack((int)GATrackType.GA_TRACK, eventName, Newtonsoft.Json.JsonConvert.SerializeObject(properties));
}
content.RemoveAll();
content = null;
}
public static GEvent TackEvent(string eventName, bool afSend = false, bool gaSend = true)
{
return new GEvent(eventName, afSend, gaSend);
}
public static GEvent GameEvent(string eventName, bool afSend = false, bool gaSend = true)
{
return new GEvent(eventName, afSend, gaSend);
}
public static GEvent SpendCreditEvent(bool afSend = false, bool gaSend = true)
{
return new GEvent(AFInAppEvents.SPENT_CREDIT, afSend, gaSend);
}
public static GEvent CompleteRegistrationEvent()
{
return new GEvent(AFInAppEvents.COMPLETE_REGISTRATION, true, true);
}
public static GEvent RegistrationEvent()
{
return new GEvent(AFInAppEvents.REGSITRATION_METHOD, true, true);
}
public static GEvent LoginEvent()
{
return new GEvent(AFInAppEvents.LOGIN, true, true);
}
public static GEvent RevenueEvent()
{
return new GEvent(AFInAppEvents.PURCHASE, true, true);
//.WithGAEvent("recharge_state");
}
public static void ADRevenueEvent(string adUnitId, MaxSdkBase.AdInfo adInfo)
{
JObject content = new JObject();
content.Add(AFAdRevenueEvent.COUNTRY, MaxSdk.GetSdkConfiguration().CountryCode);
content.Add("ad_id", adUnitId);
content.Add(AFAdRevenueEvent.AD_TYPE, "Reward");
content.Add(AFAdRevenueEvent.PLACEMENT, adInfo.Placement);
content.Add("value_micros", adInfo.Revenue);
content.ToObject<Dictionary<string, string>>();
AppsFlyerAdRevenue.logAdRevenue(
adInfo.NetworkName,
AppsFlyerAdRevenueMediationNetworkType.AppsFlyerAdRevenueMediationNetworkTypeGoogleAdMob,
adInfo.Revenue,
"USD",
content.ToObject<Dictionary<string, string>>());
content.Add("revenue", adInfo.Revenue);
content.Add("currency", "USD");
content.Add("precision", adInfo.RevenuePrecision);
ThinkingData.Analytics.TDAnalytics.Track("af_ad_revenue", content.ToObject<Dictionary<string, object>>());
AppsFlyer.sendEvent("af_ad_revenue", content.ToObject<Dictionary<string, string>>());
TYSdkFacade.Instance.EventTrack((int)GATrackType.GA_TRACK, "af_ad_revenue", Newtonsoft.Json.JsonConvert.SerializeObject(content));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 86c1a73af4778472a9e7fb25ed9adf54
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,65 @@
using UnityEngine;
using UnityEngine.AddressableAssets;
using System.Linq;
using tysdk;
public class GpuEvaluation
{
private class GpuData
{
public int tier;
public string[] keywords;
}
private static GpuData[] _devdatas;
private static GpuData[] DevDatas
{
get{
if(_devdatas == null)
{
var handle = Addressables.LoadAssetAsync<TextAsset>("gpudata");
handle.WaitForCompletion();
_devdatas = Newtonsoft.Json.JsonConvert.DeserializeObject<GpuData[]>(handle.Result.text);
}
return _devdatas;
}
}
public static int? GetTier(string deviceName)
{
foreach (var device in DevDatas)
{
var keywords = device.keywords;
if (keywords.All(k => deviceName.IndexOf(k) >= 0))
{
var info = string.Join(" ", keywords);
Debug.Log($"[GpuEvaluation] Found Match Gpu {info} Tier {device.tier}");
#if AGG
using(var track = GEvent.TackEvent("GpuEvaluation"))
{
track.AddContent("record", true);
track.AddContent("gpu", deviceName);
track.AddContent("tier", device.tier);
}
#endif
return device.tier;
}
}
#if AGG
using(var track = GEvent.TackEvent("GpuEvaluation"))
{
track.AddContent("record", false);
track.AddContent("gpu", deviceName);
track.AddContent("tier", 1);
}
#endif
return null;
}
#if UNITY_EDITOR
public static int Tier => 3;
#else
public static int Tier => GetTier(SystemInfo.graphicsDeviceName) ?? 2;
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c1d3fb87095f0ab4dbc5770f5baced06
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,49 @@
using asap.core;
using System;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.UI;
namespace GameC
{
public enum TextType
{
Text, // UGUI Text
TextMeshPro, // TextMeshPro - Text
TextMeshPro_UGUI // TextMeshPro - Text(UI)
}
public class Localize : MonoBehaviour
{
[SerializeField] private string key;
[SerializeField] private TextType textType = TextType.TextMeshPro_UGUI;
private TMP_Text text_UGUI;
private IDisposable disposable;
void Awake()
{
if (string.IsNullOrEmpty(key))
{
return;
}
text_UGUI = gameObject.GetComponent<TextMeshProUGUI>();
OnChangeLanguage();
}
void OnChangeLanguage()
{
string localized_text = Boostrapi18n.Instance.GetText(key);
if (!string.IsNullOrEmpty(localized_text))
if (text_UGUI)
{
text_UGUI.text = localized_text;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1806ed8053370f14d900347897ef8b5d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.SceneManagement;
[DefaultExecutionOrder(2)]
public class PreBoot : MonoBehaviour
{
[SerializeField]
private SimpleDialog reconnectDialog;
private bool HasNetwork => Application.internetReachability != NetworkReachability.NotReachable;
private void Start()
{
BetterStreamingAssets.Initialize();
StartCoroutine(CheckNetwork());
}
private void ShowRetryDialog()
{
reconnectDialog.Config(new SimpleDialog.Context()
{
message = Boostrapi18n.Instance.GetText("subtitle_networkfailed"),
message2 = Boostrapi18n.Instance.GetText("content_networkfailed"),
okAction = () => StartCoroutine(CheckNetwork()),
});
}
private IEnumerator CheckNetwork()
{
yield return new WaitForSeconds(0.3f);
if(!HasNetwork)
{
ShowRetryDialog();
}
else
{
GEvent.Init();
SceneManager.LoadScene("BoostrapScene");
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0a3bc0fefcb6449c2961668d6a7a1f9c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,144 @@
using asap.core;
using System;
using UnityEngine;
using UniRx;
public struct QualityChangedEvt { }
public class QualityManager
{
private const string Quality_Level = "QualityLevel";
public static void ChangeQuality(int level)
{
string[] names = QualitySettings.names;
if (level >= names.Length)
{
return;
}
QualitySettings.SetQualityLevel(level);
PlayerPrefs.SetInt(Quality_Level, level);
GContext.Publish(new QualityChangedEvt());
}
public static void ChangeQuality(string levelName)
{
var names = QualitySettings.names;
for (int i = 0; i < names.Length; i++)
{
if (names[i] == levelName)
{
ChangeQuality(i);
return;
}
}
}
public static void AutoSetQualityLevel()
{
var level=PlayerPrefs.GetInt(Quality_Level, -1);
if (level == -1)
{
level = GpuEvaluation.Tier;
}
ChangeQuality(level);
}
public static string[] QualityNames => QualitySettings.names;
}
[Serializable]
public class QualityAdapter : MonoBehaviour
{
[Serializable]
private class AdapterData
{
public GameObject[] enableObjects;
public GameObject[] disableObjects;
public Renderer renderer;
public string[] keywordsToEnable;
public string[] keywordsToDisable;
public string[] propToEnable;
public string[] propToDisable;
}
[SerializeField]
private AdapterData[] adapterDatas;
private IDisposable disposable = null;
private void Start()
{
disposable = GContext.OnEvent<QualityChangedEvt>().Subscribe(_ => SetQualityLevel());
SetQualityLevel();
}
private void SetQualityLevel()
{
int level = QualitySettings.GetQualityLevel();
if (level >= adapterDatas.Length)
{
level = adapterDatas.Length - 1;
}
var adapterData = adapterDatas[level];
if (adapterData.enableObjects != null)
{
foreach (var go in adapterData.enableObjects)
{
go.SetActive(true);
}
}
if (adapterData.disableObjects != null)
{
foreach (var go in adapterData.disableObjects)
{
go.SetActive(false);
}
}
if (adapterData.renderer != null)
{
var mat = adapterData.renderer.material;
var keywordsToEnable = adapterData.keywordsToEnable;
if (keywordsToEnable != null)
{
foreach (var keyword in keywordsToEnable)
{
mat.EnableKeyword(keyword);
}
}
var keywordsToDisable = adapterData.keywordsToDisable;
if (keywordsToDisable != null)
{
foreach (var keyword in keywordsToDisable)
{
mat.DisableKeyword(keyword);
}
}
var propToEnable = adapterData.propToEnable;
if (propToEnable != null)
{
foreach (var prop in propToEnable)
{
mat.SetInt(prop, 1);
}
}
var propToDisable = adapterData.propToDisable;
if (propToDisable != null)
{
foreach (var prop in propToDisable)
{
mat.SetInt(prop, 0);
}
}
}
}
private void OnDestroy()
{
disposable?.Dispose();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9bd5b8b9de24984593b2cb1f1aab54e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,223 @@
using asap.core;
using System;
using System.Collections;
using System.IO;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.ResourceLocations;
using UnityEngine.ResourceManagement.ResourceProviders;
namespace game
{
public class RootCtx : GContext
{
#if !UNITY_EDITOR && AGG
private void Start()
{
Debug.Log("InitSDK");
tysdk.TYSdkFacade.Instance.Init();
}
#endif
protected override async Task SetupAsync()
{
container.Register<IStageService, StageService>().AsSingleton();
//container.Register<IDataService, LubanDataService>().AsSingleton();
container.Register<IObjectSerializer, ObjectSerializer>().AsSingleton();
container.Register<IConfig, Config>().AsSingleton();
await Awaiters.NextFrame;
BetterStreamingAssets.Initialize();
// using remote assets locally if exists
Addressables.InternalIdTransformFunc += DoIdTransform;
UnityEngine.Random.InitState((int)System.DateTime.Now.Ticks);
// Initialize DOTween with the preferences set in DOTween's Utility Panel
DG.Tweening.DOTween.Init();
// Set Tweens capacity accordingly based on DOTween warnings
DG.Tweening.DOTween.SetTweensCapacity(200, 125);
Application.lowMemory += OnLowMemory;
//SceneManager.sceneLoaded += OnSceneLoaded;
Screen.sleepTimeout = SleepTimeout.NeverSleep;
}
//void OnSceneLoaded(Scene scene, LoadSceneMode mode)
//{
//GameDebug.Log("[GameEngine]OnSceneLoaded: Name: {0}, Mode: {1}", scene.name, mode);
//SetCamStack();
//}
float _lowMemCleanupTime;
bool _isUnloadingMem;
const float LOW_MEM_CLEANUP_CD = 10f; // in secs
void OnLowMemory()
{
GameDebug.LogWarning("[GameEngine]OnLowMemory: Memory is low!");
// Add a cool-down time to prevent consecutive cleaning up process, which
// will cause a long performance hiccup
if (!_isUnloadingMem &&
Time.realtimeSinceStartup - _lowMemCleanupTime > LOW_MEM_CLEANUP_CD)
{
StartCoroutine(UnloadMemory());
}
}
IEnumerator UnloadMemory(Action back = null)
{
GameDebug.Log("[GameEngine]UnloadMemory: Start cleaning up!");
_isUnloadingMem = true;
System.GC.Collect();
var op = Resources.UnloadUnusedAssets();
while (!op.isDone)
{
yield return null;
}
back?.Invoke();
_lowMemCleanupTime = Time.realtimeSinceStartup;
_isUnloadingMem = false;
GameDebug.Log("[GameEngine]UnloadMemory: Cleaning up is done!");
}
private string customAddressableRemoteURL;
private string originAddressableRemoteURL;
public void ChangeAddressableRemoteUrl(string customUrl, string originUrl)
{
Debug.Log($"[RootCtx::ChangeAddressableRemoteUrl] customUrl: {customUrl}, originUrl: {originUrl}");
customAddressableRemoteURL = customUrl;
originAddressableRemoteURL = originUrl;
Addressables.InternalIdTransformFunc -= DoIdTransform;
Addressables.InternalIdTransformFunc += DoIdTransformUsingCustomURL;
}
private const string Remote_Prefix = "http";
private string DoIdTransformUsingCustomURL(IResourceLocation location)
{
var id = location.InternalId;
if (id.StartsWith(Remote_Prefix))
{
if (location.ResourceType.IsAssignableFrom(typeof(IAssetBundleResource)))
{
var primaryKey = location.PrimaryKey;
if (BetterStreamingAssets.FileExists(primaryKey))
return Path.Combine(Application.streamingAssetsPath, primaryKey);
}
id = id.Replace(originAddressableRemoteURL, customAddressableRemoteURL);
}
return id;
}
private string DoIdTransform(IResourceLocation location)
{
var id = location.InternalId;
if (id.StartsWith(Remote_Prefix))
{
if (location.ResourceType.IsAssignableFrom(typeof(IAssetBundleResource)))
{
var primaryKey = location.PrimaryKey;
if (BetterStreamingAssets.FileExists(primaryKey))
return Path.Combine(Application.streamingAssetsPath, primaryKey);
}
}
return id;
}
public static void ExitGame()
{
PlayerPrefs.Save();
Application.runInBackground = false;
if (Application.platform == RuntimePlatform.Android)
{
// Calling Application.Quit on some devices will cause ANR, so
// directly calling system action instead
try
{
new AndroidJavaClass("java.lang.System").CallStatic("exit", 0);
}
catch (Exception ex)
{
Debug.LogError($"[GameStateMgr]ExitGame: {ex}");
}
}
else
{
Application.Quit();
}
}
public static bool showFPS = false;
public static float fps;
private static float frameCount;
private static float elapse;
private GUIStyle _fpsStyle;
public GUIStyle fpsStyle
{
get
{
if (_fpsStyle == null)
{
int h = Screen.height;
_fpsStyle = new GUIStyle();
_fpsStyle.alignment = TextAnchor.UpperLeft;
_fpsStyle.fontSize = h * 2 / 100;
_fpsStyle.normal.textColor = Color.magenta;
}
return _fpsStyle;
}
}
void OnGUI()
{
frameCount++;
elapse += Time.unscaledDeltaTime;
if (elapse >= 1)
{
fps = frameCount / elapse;
elapse = 0;
frameCount = 0;
}
if (!showFPS) return;
string text = string.Format("FPS: {0:0.}", fps);
int w = Screen.width, h = Screen.height;
Rect rect = new Rect(20, h * 0.4f, w * 0.5f, h * 2 / 100);
GUI.Label(rect, text, fpsStyle);
}
protected override void OnDestroy()
{
Debug.Log("[RootCtx::OnDestroy]");
base.OnDestroy();
Addressables.InternalIdTransformFunc = null;
Application.lowMemory -= OnLowMemory;
root = null;
Ready = false;
IsInited = false;
eventAggregator = new EventAggregator();
container.Dispose();
container = new Container();
}
public static void DestoryRootCtx()
{
if (root != null)
{
GameObject.DestroyImmediate(root.gameObject);
root = null;
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae9c8daf5f84ae74fadaa7da5289caeb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,188 @@
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class SimpleDialog : MonoBehaviour
{
public class Context
{
public Action okAction;
public Action closeAction;
public string message;
public string message2;
public string formatMessage;
}
[SerializeField]
private Button btn_ok;
[SerializeField]
private Button btn_close;
[SerializeField]
TMP_Text message;
[SerializeField]
TMP_Text message2;
public string DefaultMessage {get; private set;}
private Action onOk;
private Action onClose;
void Awake()
{
if(message != null)
{
DefaultMessage = message.text;
}
}
void OnEnable()
{
btn_ok.onClick.AddListener(OnOkClicked);
if(btn_close != null)
btn_close.onClick.AddListener(OnCloseClicked);
}
void OnDisable()
{
btn_ok.onClick.RemoveAllListeners();
if(btn_close != null)
btn_close.onClick.RemoveAllListeners();
}
public async void Config(Context context)
{
this.onOk = context.okAction;
this.onClose = context.closeAction;
gameObject.SetActive(true);
await Awaiters.NextFrame;
if(message != null)
{
message.text = context.message;
}
if(message2!=null)
{
message2.text = context.message2;;
}
}
private void OnCloseClicked()
{
onClose?.Invoke();
Close();
}
private void OnOkClicked()
{
onOk?.Invoke();
Close();
}
private void Close()
{
gameObject.SetActive(false);
if(message != null) message.text = DefaultMessage;
onOk = null;
onClose = null;
}
}
/*
public class SimpleDialog : MonoBehaviour
{
public class Context
{
public string title;
public string message;
public string okBtnText;
public Action okAction;
public Action closeAction;
}
[SerializeField]
private Text tile;
[SerializeField]
private Text message;
[SerializeField]
private Button btn_ok;
[SerializeField]
private Text btn_ok_text;
[SerializeField]
private Button btn_close;
private Action onOk;
private Action onClose;
private string defaultOkBtnText;
void Awake()
{
defaultOkBtnText = btn_ok_text.text;
}
void OnEnable()
{
btn_ok.onClick.AddListener(OnOkClicked);
btn_close.onClick.AddListener(OnCloseClicked);
}
void OnDisable()
{
btn_ok.onClick.RemoveAllListeners();
btn_close.onClick.RemoveAllListeners();
}
public void Config(Context context)
{
this.tile.text = context.title ?? string.Empty;
this.message.text = context.message ?? string.Empty;
this.btn_ok_text.text = context.okBtnText ?? defaultOkBtnText;
this.onOk = context.okAction;
this.onClose = context.closeAction;
gameObject.SetActive(true);
}
private void OnCloseClicked()
{
onClose?.Invoke();
Close();
}
private void OnOkClicked()
{
onOk?.Invoke();
Close();
}
private void Close()
{
gameObject.SetActive(false);
tile.text = string.Empty;
message.text = string.Empty;
btn_ok_text.text = defaultOkBtnText;
onOk = null;
onClose = null;
}
}
*/

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5ae19f17d9371654aa05c9db637f326c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,100 @@
using UnityEngine;
using System;
using System.Linq;
using System.IO;
public class VersionTool : IComparable<VersionTool>
{
public const string Build_Ver_File_Name = "buildver.txt";
public static string PackVer
{
get
{
string[] splitVersion = Application.version.Split('.');
return $"{splitVersion[0]}_{splitVersion[1]}";
}
}
public int Major { get; private set; }
public int Minor { get; private set; }
public string Build { get; private set; }
private VersionTool(int major, int minor, string build)
{
Major = major;
Minor = minor;
Build = build;
}
public static VersionTool FromString(string version)
{
string[] splitVersion = version.Split('.');
return new VersionTool(int.Parse(splitVersion[0]), int.Parse(splitVersion[1]), splitVersion[2]);
}
public static VersionTool FromLocal()
{
string appVerStr = Application.version;
string [] splitVersion = appVerStr.Split('.');
return new VersionTool(int.Parse(splitVersion[0]), int.Parse(splitVersion[1]), GetLoacalBuild());
}
private static string GetLoacalBuild()
{
var persisterBVerFile = $"{Application.persistentDataPath}/{Build_Ver_File_Name}";
if(File.Exists(persisterBVerFile))
{
return File.ReadAllText(persisterBVerFile);
}
if (BetterStreamingAssets.FileExists(Build_Ver_File_Name))
return BetterStreamingAssets.ReadAllText(Build_Ver_File_Name);
return "None";
}
public int CompareTo(VersionTool other)
{
int result = Major.CompareTo(other.Major);
if (result == 0)
{
result = Minor.CompareTo(other.Minor);
}
return result;
}
public static bool operator >(VersionTool a, VersionTool b)
{
return a.CompareTo(b) > 0;
}
public static bool operator <(VersionTool a, VersionTool b)
{
return a.CompareTo(b) < 0;
}
public static bool operator ==(VersionTool a, VersionTool b)
{
return a.CompareTo(b) == 0;
}
public static bool operator !=(VersionTool a, VersionTool b)
{
return a.CompareTo(b) !=0 ;
}
public override string ToString()
{
return $"Ver {Major}_{Minor}_{Build}";
}
public string ToVerString()
{
Debug.Log($"{Major}.{Minor}.{Build}");
return $"{Major}.{Minor}.{Build}";
}
public void Save()
{
var persisterBVerFile = $"{Application.persistentDataPath}/{Build_Ver_File_Name}";
File.Delete(persisterBVerFile);
File.WriteAllText(persisterBVerFile, Build);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5fa0017cbacf37549a4e495f0b108567
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f276a060c5fd76d46b82fa46124e2295
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,168 @@
using cfg;
using Cinemachine;
using DG.Tweening;
using System.Collections.Generic;
using UnityEngine;
public class AquariumCameraManager : MonoBehaviour
{
public CinemachineVirtualCamera cameraVirtual;
public CinemachineVirtualCamera[] followFishCameras;
CinemachineVirtualCamera followFishCamera;
int showCameraIndex = 0;
public GameObject crossbowGo;
public CinemachineVirtualCamera followArrowCamera;
public Camera crossbowCamera;
public Transform handRoot;
public Vector2 cameraOffset = Vector2.zero;
public float startPosZ = -2;
public float moveTimeZ = 0.5f;
public float cameraToFishDis = 3;//鱼最长包围盒的倍率,用于控制箭飞行时相机距离鱼的距离,和把鱼拉回来时距离相机的距离
public float zoomFishExtraDistance = 1.5f;
CrossbowCameraMove crossbowCameraMove;
AquariumCameraMove aquariumCameraMove;
public RenderTexture rt;
FishMovement followFish;
private void Awake()
{
for (int i = 0; i < followFishCameras.Length; i++)
{
followFishCameras[i].gameObject.SetActive(false);
}
crossbowGo.SetActive(false);
crossbowCamera.gameObject.SetActive(false);
}
public Vector2 SetRotationAngle()
{
float halfFOV = 30;
float maxX = Mathf.Max(0, cameraOffset.y - halfFOV);
//float aspect = (float)Screen.height / Screen.width;
//aspect = Mathf.Min(Mathf.Max(aspect, 1f), 2.2f);
//float halfFOVInRadians = halfFOV * Mathf.Deg2Rad;
//float tanHalfFOV = Mathf.Tan(halfFOVInRadians);
//float angle = cameraOffset.x - Mathf.Atan(tanHalfFOV / aspect) * Mathf.Rad2Deg;
//float maxY = Mathf.Max(0, angle);
float maxY = ConvertTools.CalculateActualRotationAngle(cameraOffset.x);
return new Vector2(maxX, maxY);
}
public void PlayAquarium(FishingAquariumAct fishingAquariumAct)
{
aquariumCameraMove = gameObject.AddComponent<AquariumCameraMove>();
Vector2 vector = SetRotationAngle();
aquariumCameraMove.Init(vector, fishingAquariumAct);
transform.position = new Vector3(0, 0, startPosZ);
}
public void FollowFishCamera(FishMovement fish)
{
followFish = fish;
if (fish == null)
{
StopFollowFishCamera();
return;
}
NextCamera();
followFishCamera.gameObject.SetActive(true);
}
void NextCamera()
{
if (followFishCamera != null)
{
followFishCamera.gameObject.SetActive(false);
}
showCameraIndex++;
showCameraIndex %= followFishCameras.Length;
followFishCamera = followFishCameras[showCameraIndex];
}
public void FollowFishCamera(FishEgg egg)
{
followFish = null;
if (egg == null)
{
StopFollowFishCamera();
return;
}
NextCamera();
followFishCamera.gameObject.SetActive(true);
Vector3 targetPos = egg.transform.position;
float r = /*followFish.AvoidRadius * cameraToFishDis + */zoomFishExtraDistance;
targetPos.z -= r;
followFishCamera.transform.position = targetPos;
}
public void StopFollowFishCamera()
{
for (int i = 0; i < followFishCameras.Length; i++)
{
followFishCameras[i].gameObject.SetActive(false);
}
followFish = null;
}
private void Update()
{
if (followFish != null)
{
Vector3 targetPos = followFish.transform.position;
float r = followFish.AvoidRadius * cameraToFishDis + zoomFishExtraDistance;
targetPos.z -= r;
followFishCamera.transform.position = targetPos;
}
}
public void MoveCamera()
{
transform.DOMoveZ(0, moveTimeZ).SetDelay(0.66f);
}
public void PlayCrossbow(FishMovement guide)
{
crossbowGo.SetActive(true);
crossbowCamera.gameObject.SetActive(true);
crossbowCamera.targetTexture = rt;
crossbowCameraMove = gameObject.AddComponent<CrossbowCameraMove>();
Vector2 vector = SetRotationAngle();
crossbowCameraMove.Init(this, handRoot, vector, guide);
}
public void Target()
{
crossbowCameraMove.Target();
}
public void TriggerCrossbow(string value)
{
crossbowCameraMove.TriggerCrossbow(value);
}
public void Shoot(float[] FxScale, Dictionary<string, GameObject> fx_hunt_prefab, bool isRob, float shootTime, FishMovement targetMovement)
{
crossbowCameraMove.Shoot(FxScale, fx_hunt_prefab, isRob, cameraToFishDis, shootTime, targetMovement);
}
public float Capture(float fishToCameraDistance, float lineDrawMinTime, float lineDrawSpeed, FishMovement targetMovement)
{
return crossbowCameraMove.Capture(fishToCameraDistance, lineDrawMinTime, cameraToFishDis, lineDrawSpeed, targetMovement);
}
public void Captureed()
{
crossbowCameraMove.Captureed();
}
public void Escape(float arrowEscapeTime)
{
crossbowCameraMove.Escape(arrowEscapeTime);
}
public void HideCrossbow(bool isHide)
{
crossbowCameraMove.HideCrossbow(isHide);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3f7a57aea558e2a4391082863cca5477
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,104 @@
using DG.Tweening;
using UnityEngine;
public class AquariumCameraMove : MonoBehaviour
{
int layerMask;
//屏幕拖动比例
float dragCameraScale = 0.03f;
private Vector3 initialRotation;
Vector3 _curMousePos;
Vector3 _offsetEuler;
Quaternion targetRotation;
Vector2 cameraOffset;
Quaternion startRot;
float duration = 0.65f;
FishingAquariumAct fishingAquariumAct;
GameObject curClick;
private void Awake()
{
layerMask = 1 << LayerMask.NameToLayer("fish");
startRot = transform.rotation;
}
public void Init(Vector2 cameraOffset, FishingAquariumAct fishingAquariumAct)
{
this.fishingAquariumAct = fishingAquariumAct;
this.cameraOffset = cameraOffset;
}
float CheckAngle(float value)
{
float angle = value - 180;
if (angle > 0)
return angle - 180;
return angle + 180;
}
private void LateUpdate()
{
if (Input.GetMouseButtonDown(0) && fishingAquariumAct.CanDragMove())
{
transform.DOKill();
_curMousePos = Input.mousePosition;
_offsetEuler = Vector3.zero;
initialRotation = transform.rotation.eulerAngles;
initialRotation.x = CheckAngle(initialRotation.x);
initialRotation.y = CheckAngle(initialRotation.y);
targetRotation = transform.rotation;
curClick = SelectTarget();
}
else if (Input.GetMouseButton(0) && fishingAquariumAct.CanDragMove())
{
Vector3 ver = Input.mousePosition - _curMousePos;
if (ver.magnitude > 5)
{
_offsetEuler.x -= ver.y * dragCameraScale;
_offsetEuler.y += ver.x * dragCameraScale;
var targetEulerAngles = initialRotation + _offsetEuler;
// Clamp the rotation angles
targetEulerAngles.x = Mathf.Clamp(targetEulerAngles.x, -cameraOffset.x, cameraOffset.x);
targetEulerAngles.y = Mathf.Clamp(targetEulerAngles.y, -cameraOffset.y, cameraOffset.y);
targetEulerAngles.z = 0;
_offsetEuler = targetEulerAngles - initialRotation;
targetRotation = Quaternion.Euler(targetEulerAngles);
//transform.rotation = targetRotation;
_curMousePos = Input.mousePosition;
}
transform.rotation = Quaternion.Angle(targetRotation, transform.rotation) > 0.1f
? Quaternion.Lerp(transform.rotation, targetRotation, 0.2f)
: targetRotation;
}
else if (Input.GetMouseButtonUp(0))
{
transform.DORotateQuaternion(startRot, duration);
GameObject localClick = SelectTarget();
if (localClick != null && localClick == curClick)
{
var fish = curClick.GetComponentInParent<AquariumFishBase>();
fishingAquariumAct.OnClickFish(fish.slotData.index);
curClick = null;
}
}
}
private GameObject SelectTarget()
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out var hit, 100, layerMask))
{
//Debug.Log($"<color=#e94242>hit: {hit.collider.gameObject.layer}</color>");
//if (hit.collider.gameObject.layer == layerMask)
//{
//Debug.Log($"<color=#e94242>hit position: {hit.point}</color>");
return hit.collider.gameObject;
//}
}
return null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a7236a82e1dcf1a489024646d0137b77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
using UnityEngine;
public class AquariumFishBase : MonoBehaviour
{
public AquariumSlotData slotData;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: db4bb73fec24a654fa17755d1d38762b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using UnityEngine;
public class AquariumFishController : MonoBehaviour
{
public AquariumCameraManager cameraManager;
public FishManager fishManager;
public FishEggManager fishEggManager;
public AquariumObstacleManager obstacleManager;
private void Awake()
{
if (obstacleManager != null && fishManager != null)
{
fishManager.obstacleGo = obstacleManager.obstacleGo;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6b0d6aac7ffaac6419c521ff2b34958d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class AquariumObstacleManager : MonoBehaviour
{
public List<GameObject> obstacleGo = new List<GameObject>();
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f880fefae71a49a4d9da4c02cdee80cb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,29 @@
using System.Collections.Generic;
using UnityEngine;
public class Crossbow : MonoBehaviour
{
public GameObject root;
public Transform crosshair_P;
public GameObject icon_nml;
public GameObject icon_notarget;
public Animator animator;
public Transform TopLine;
public Transform EndLine;
public List<Transform> LineList;
public LineRenderer fishingLineRenderer;
public Transform LeftHandTargets;
public Transform RightHandTargets;
private void Awake()
{
if (icon_nml != null)
{
icon_nml.transform.localPosition = new Vector3(0, 0.005f, 0);
}
if (icon_notarget != null)
{
icon_notarget.transform.localPosition = new Vector3(0, 0.005f, 0);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 670586c38ef7915448bd1fadd54a9c04
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
using System.Collections.Generic;
using UnityEngine;
public class CrossbowArrow : MonoBehaviour
{
public GameObject crossbow;
public Animator animator;
public Transform TopLine;
public Transform EndLine;
public List<Transform> LineList;
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e814686283d4e20429f6e45c5697bd57
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,510 @@
using asap.core;
using cfg;
using DG.Tweening;
using Game;
using GameCore;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AddressableAssets;
public class CrossbowCameraMove : MonoBehaviour
{
Vector3 _curMousePos;
Vector3 _offsetEuler;
Quaternion targetRotation;
//屏幕拖动比例
float dragCameraScale = 0.03f;
private Vector3 initialRotation;
bool isFinish;
Transform handRoot;
HandController HandController;
GameObject handAB;
Crossbow crossbow;
CrossbowArrow crossbowArrow;
AquariumCameraManager manager;
int state = 0;//0:未开始 1:射击结束 2:收紧线 3:逃脱
Vector2 cameraOffset;
public FishMovement guide;
private void Awake()
{
crossbow = GetComponentInChildren<Crossbow>();
crossbowArrow = GetComponentInChildren<CrossbowArrow>();
crossbowArrow.gameObject.SetActive(false);
crossbow.fishingLineRenderer.enabled = false;
crossbowPos = crossbow.animator.transform.localPosition;
}
public void Init(AquariumCameraManager aquariumCameraManager, Transform handRoot, Vector2 cameraOffset, FishMovement guide)
{
this.manager = aquariumCameraManager;
this.cameraOffset = cameraOffset;
this.handRoot = handRoot;
this.guide = guide;
LoadHand();
}
public void LoadHand()
{
GloveData gloveData = GContext.container.Resolve<PlayerFishData>().GetGloveData;
InitRodHandAsync(gloveData);
}
async void InitRodHandAsync(GloveData gloveData)
{
string path = gloveData.Fbx;
if (handAB != null)
{
Addressables.ReleaseInstance(handAB);
}
handAB = await Addressables.InstantiateAsync(gloveData.Fbx, handRoot).Task;
if (handAB != null)
{
HandController = handAB.GetComponent<HandController>();
if (crossbow != null)
{
HandController.SetHandTargets(crossbow.RightHandTargets, crossbow.LeftHandTargets, null);
}
}
}
public float CheckAngle(float value)
{
float angle = value - 180;
if (angle > 0)
return angle - 180;
return angle + 180;
}
//收线音效
Sound soundLine;
AudioClip lineAudio;
async void PlaySoundLine(string audioName)
{
StopSoundLine();
lineAudio = await Addressables.LoadAssetAsync<AudioClip>(audioName).Task;
if (lineAudio)
{
soundLine = GContext.container.Resolve<ISoundService>().GetNewFishingSound(lineAudio);
soundLine.audioSource.Play();
soundLine.audioSource.loop = true;
}
}
void StopSoundLine()
{
if (soundLine)
{
soundLine.audioSource.Stop();
soundLine.ReturnPool();
soundLine = null;
}
}
public void TriggerCrossbow(string value)
{
crossbow.animator.SetBool("Aim", value == "Aim");
crossbow.animator.SetBool("Back", value == "Back");
crossbow.animator.SetBool("Shoot", value == "Shoot");
//crossbow.animator.SetTrigger(value);
}
public async void Shoot(float[] FxScale, Dictionary<string, GameObject> fx_hunt_prefab, bool isRob, float cameraToFishDis, float shootTime, FishMovement fish)
{
crossbow.animator.SetTrigger("Shoot");
Vector3 targetPos = fish.targetPos;
manager.crossbowCamera.gameObject.SetActive(false);
Vector3 cameraposition = manager.crossbowCamera.transform.position;
float r = fish.AvoidRadius * cameraToFishDis;
float t = 1 - r / (targetPos - cameraposition).magnitude;
if (t < 0)
{
t = 0;
}
Vector3 newVector = Vector3.Lerp(cameraposition, targetPos, t);
GContext.Publish(new EventFishingSound("audio_huntingfish_shoot"));
crossbowArrow.gameObject.SetActive(true);
crossbow.fishingLineRenderer.enabled = true;
manager.cameraVirtual.gameObject.SetActive(false);
var cameraParent = manager.followArrowCamera.transform.parent;
//parent.position = manager.crossbowCamera.transform.position;
await Awaiters.NextFrame;
cameraParent.gameObject.SetActive(true);
manager.followArrowCamera.transform.localPosition = new Vector3(0.25f, 0.25f, -0.25f);
//cameraParent.position = manager.crossbowCamera.transform.position;
cameraParent.DOMove(newVector, shootTime).SetEase(Ease.Linear);
manager.followArrowCamera.LookAt = crossbowArrow.transform;
PlaySoundLine("audio_huntingfish_airflow");
transform.rotation = Quaternion.LookRotation(targetPos - transform.position);
crossbow.root.SetActive(false);
handRoot.gameObject.SetActive(false);
GameObject hunt_shoot_go = null;
if (fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_shoot", out GameObject hunt_shoot))
{
hunt_shoot_go = Instantiate(hunt_shoot, crossbowArrow.transform);
}
crossbowArrow.transform.DOMove(targetPos, shootTime).SetEase(Ease.Linear);
await Awaiters.Seconds(shootTime);
manager.followArrowCamera.LookAt = null;
state = 1;
AddLinePos();
crossbowArrow.animator.SetTrigger("Shoot");
if (hunt_shoot_go != null)
{
Destroy(hunt_shoot_go);
}
if (fish.fish != null)
{
int q = fish.slotData.aquariumFishID - 1;
float fxScale = FxScale[q] / fish.transform.localScale.x;
GameObject hunt_fishhitbig_go = null;
GameObject hunt_fishhitsmall_go = null;
GameObject hunt_fishhurt_go = null;
Transform fishPos = isRob ? fish.fish.mouthPos : fish.fishPos;
if (fish.fish.Root && fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_fishhitbig", out GameObject hunt_fishhitbig))
{
hunt_fishhitbig_go = Instantiate(hunt_fishhitbig, fish.fish.Root);
hunt_fishhitbig_go.transform.localScale = Vector3.one * fxScale;
hunt_fishhitbig_go.transform.rotation = Quaternion.identity;
}
if (fishPos && fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_fishhitsmall", out GameObject hunt_fishhitsmall))
{
hunt_fishhitsmall_go = Instantiate(hunt_fishhitsmall, fishPos);
hunt_fishhitsmall_go.transform.localScale = Vector3.one * fxScale;
hunt_fishhitsmall_go.transform.rotation = Quaternion.identity;
}
if (fishPos && fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_fishhurt", out GameObject hunt_fishhurt))
{
hunt_fishhurt_go = Instantiate(hunt_fishhurt, fishPos);
hunt_fishhurt_go.transform.localScale = Vector3.one * fxScale;
}
if (isRob)
{
GameObject hunt_capture_go = null;
if (fish.fish.Root && fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_capture", out GameObject hunt_capture))
{
hunt_capture_go = Instantiate(hunt_capture, fish.fish.Root);
hunt_capture_go.transform.localScale = Vector3.one * fxScale;
}
}
else
{
GameObject hunt_escape_go = null;
if (fx_hunt_prefab.TryGetValue("fx_aquarium_hunt_escape", out GameObject hunt_escape))
{
hunt_escape_go = Instantiate(hunt_escape, fish.fish.Root);
hunt_escape_go.transform.localScale = Vector3.one * fxScale;
}
}
crossbowArrow.transform.parent = fishPos;
crossbowArrow.transform.localPosition = Vector3.zero;
if (isRob)
{
GContext.Publish(new EventFishingSound("audio_huntingfish_hitbig"));
}
else
{
GContext.Publish(new EventFishingSound("audio_huntingfish_hitsmall"));
}
}
StopSoundLine();
HideCrossbow(false);
crossbow.animator.SetTrigger("Capture");
}
Vector3 crossbowPos;
public void HideCrossbow(bool isHide)
{
guide = null;
if (isHide)
{
crossbowPos = crossbow.animator.transform.localPosition;
crossbow.animator.transform.localPosition = Vector3.back * 100;
}
else
{
crossbow.animator.transform.localPosition = crossbowPos;
}
//handRoot.localPosition = isHide ? Vector3.back * 100 : new Vector3(0, 1, -0.5f);
}
List<ParabolaHarmonicSimulation> vector3s = new List<ParabolaHarmonicSimulation>();
float lineChengeTime = 1;
public void Escape(float arrowEscapeTime)
{
GContext.Publish(new EventFishingSound("audio_huntingfish_escape"));
manager.followArrowCamera.LookAt = null;
HideCrossbow(false);
crossbowArrow.animator.SetTrigger("Escape");
crossbow.animator.SetTrigger("Escape");
crossbowArrow.transform.parent = crossbow.transform.parent;
crossbowArrow.transform.DOMoveY(-5, arrowEscapeTime).OnComplete(() =>
{
state = 2;
vector3s.Clear();
});
state = 1;
AddLinePos();
}
public void Target()
{
isFinish = true;
}
public float Capture(float fishToCameraDistance, float lineDrawMinTime, float cameraToFishDis, float lineDrawSpeed, FishMovement targetMovement)
{
manager.cameraVirtual.transform.DOKill();
manager.cameraVirtual.transform.localPosition = Vector3.zero;
manager.followArrowCamera.transform.position = manager.cameraVirtual.transform.position;
manager.followArrowCamera.transform.rotation = manager.cameraVirtual.transform.rotation;
manager.followArrowCamera.LookAt = targetMovement.transform;
crossbow.root.SetActive(true);
handRoot.gameObject.SetActive(true);
crossbowArrow.animator.SetTrigger("Capture");
PlaySoundLine("audio_huntingfish_capture");
state = 2;
vector3s.Clear();
Vector3 vector3 = targetMovement.targetPos;
Vector3 targetPos = crossbow.transform.position;
float r = targetMovement.AvoidRadius * cameraToFishDis;
float t = 1 - r / (targetPos - vector3).magnitude;
if (t < 0)
{
t = 0;
}
Vector3 newVector = Vector3.Lerp(vector3, targetPos, t);
newVector.z += fishToCameraDistance;
var captureTime = (crossbowArrow.transform.position - newVector).magnitude / lineDrawSpeed;
if (captureTime < lineDrawMinTime)
{
captureTime = lineDrawMinTime;
}
targetMovement.transform.DOMove(newVector, captureTime).SetEase(Ease.Linear)
.OnComplete(() => crossbow.animator.SetTrigger("CaptureEnd"));
return captureTime;
}
public void Captureed()
{
StopSoundLine();
crossbowArrow.transform.parent = crossbow.transform.parent;
crossbowArrow.transform.DOMoveY(-10, 3)
.OnComplete(() => crossbow.fishingLineRenderer.enabled = false);
}
async void AddLinePos()
{
float allTime = 1f;
float time = allTime;
float timeInterval = 0;
vector3s.Clear();
float elapsedTime = 0.02f;
while (time > 0)
{
elapsedTime = Time.deltaTime;
timeInterval += elapsedTime;
await Awaiters.Seconds(elapsedTime);
time -= elapsedTime;
ParabolaHarmonicSimulation parabolaHarmonicSimulation = new ParabolaHarmonicSimulation();
parabolaHarmonicSimulation.startPos = crossbowArrow.EndLine.position;
parabolaHarmonicSimulation.starTime = timeInterval;
parabolaHarmonicSimulation.curTime = timeInterval;
parabolaHarmonicSimulation.allTime = allTime;
vector3s.Add(parabolaHarmonicSimulation);
}
}
Vector3 GetCurPos(ParabolaHarmonicSimulation data, out float zeroTime)
{
data.curTime += Time.deltaTime;
float starTime = data.starTime;
float curTime = data.curTime - starTime;
//归0时间
zeroTime = curTime / data.allTime;
Vector3 vector3 = (crossbow.TopLine.position + crossbowArrow.EndLine.position) / 2;
if (zeroTime < 1)
{
Vector3 startPos = Vector3.Lerp(data.startPos, crossbowArrow.EndLine.position, zeroTime);
float time = curTime / lineChengeTime;
if (time < 1)
{
return Vector3.Lerp(startPos, vector3, time);
}
}
return vector3;
}
public float maxSegmentLength = 0.5f;
private List<Vector3> CalculateBezierPoint(List<Vector3> curPoints)
{
List<Vector3> points = new List<Vector3>();
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 void LateUpdate()
{
if (crossbow != null && crossbowArrow.gameObject.activeSelf
&& crossbow.fishingLineRenderer != null
&& crossbow.fishingLineRenderer.enabled)
{
// 计算钓鱼线上的点
List<Vector3> linePoints = new List<Vector3>();
linePoints.Add(crossbow.EndLine.position);
for (int i = 0; i < crossbow.LineList.Count; i++)
{
linePoints.Add(crossbow.LineList[i].position);
}
linePoints.Add(crossbow.TopLine.position);
if (state == 1)
{
List<Vector3> newPoints = new List<Vector3>();
int count = vector3s.Count;
for (int i = 0; i < count; i++)
{
Vector3 vector = GetCurPos(vector3s[i], out float zeroTime);
if (zeroTime < 1)
{
newPoints.Add(vector);
}
}
List<Vector3> refinedPoints = new List<Vector3>();
if (newPoints.Count > 0)
{
refinedPoints.Add(newPoints[0]);
for (int i = 1; i < newPoints.Count; i++)
{
Vector3 lastPoint = refinedPoints[refinedPoints.Count - 1];
Vector3 currentPoint = newPoints[i];
float distance = Vector3.Distance(lastPoint, currentPoint);
if (distance > maxSegmentLength)
{
int segments = Mathf.FloorToInt(distance / maxSegmentLength);
for (int j = 1; j <= segments; j++)
{
float t = j / (float)segments;
Vector3 intermediatePoint = Vector3.Lerp(lastPoint, currentPoint, t);
refinedPoints.Add(intermediatePoint);
}
}
else
{
refinedPoints.Add(currentPoint);
}
}
}
refinedPoints.Add(crossbowArrow.EndLine.position);
for (int i = 0; i < crossbowArrow.LineList.Count; i++)
{
refinedPoints.Add(crossbowArrow.LineList[i].position);
}
linePoints.AddRange(CalculateBezierPoint(refinedPoints));
}
else
{
linePoints.Add(crossbowArrow.LineList[^1].position);
}
// 绘制钓鱼线
crossbow.fishingLineRenderer.positionCount = linePoints.Count;
crossbow.fishingLineRenderer.SetPositions(linePoints.ToArray());
}
//}
//private void LateUpdate()
//{
if (isFinish)
{
return;
}
if (Input.GetMouseButtonDown(0))
{
_curMousePos = Input.mousePosition;
_offsetEuler = Vector3.zero;
initialRotation = transform.rotation.eulerAngles;
initialRotation.x = CheckAngle(initialRotation.x);
initialRotation.y = CheckAngle(initialRotation.y);
targetRotation = transform.rotation;
}
else if (Input.GetMouseButton(0))
{
Vector3 ver = Input.mousePosition - _curMousePos;
if (ver.magnitude > 5)
{
_offsetEuler.x -= ver.y * dragCameraScale;
_offsetEuler.y += ver.x * dragCameraScale;
var targetEulerAngles = initialRotation + _offsetEuler;
//Debug.Log($"<color=#e94242> targetEulerAngles: {targetEulerAngles}</color>");
// Clamp the rotation angles
targetEulerAngles.x = Mathf.Clamp(targetEulerAngles.x, -cameraOffset.x, cameraOffset.x);
targetEulerAngles.y = Mathf.Clamp(targetEulerAngles.y, -cameraOffset.y, cameraOffset.y);
targetEulerAngles.z = 0;
_offsetEuler = targetEulerAngles - initialRotation;
//Debug.Log($"<color=#e94242> targetEulerAngles ===: {targetEulerAngles}</color>");
targetRotation = Quaternion.Euler(targetEulerAngles);
//transform.rotation = targetRotation;
_curMousePos = Input.mousePosition;
}
transform.rotation = Quaternion.Angle(targetRotation, transform.rotation) > 0.1f
? Quaternion.Lerp(transform.rotation, targetRotation, 0.2f)
: targetRotation;
}
else
{
if (guide != null)
{
//Vector3 targetDirection = target.transform.position - crossbowlowCamera.position;
//Vector3 currentDirection = crossbowlowCamera.forward;
//Quaternion rotationToTarget = Quaternion.FromToRotation(currentDirection, targetDirection);
//Quaternion rotation = rotationToTarget * transform.rotation;
Quaternion rotation = Quaternion.LookRotation(guide.transform.position - transform.position);
rotation = Quaternion.Slerp(transform.rotation, rotation, Time.deltaTime * 2);
transform.eulerAngles = new Vector3(rotation.eulerAngles.x, rotation.eulerAngles.y, 0);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: df1bce10e9444a742ab8634a1c7bf2f1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 0b2b0621c926cf74ebf77318beb3ec48
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,654 @@
using asap.core;
using cfg;
using game;
using GameCore;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
public class AquariumManager
{
public const string AquariumEventDataKey = "AquariumEventDataKey";
private cfg.Tables _tables;
private ICustomServerMgr customServerMgr;
public AquariumManagerData data { get; private set; }
public int MapId => data.mapId;
public int Slot => data.slot;
public List<string> eggNames;
public List<AquariumSlotData> sellList;
public AquariumManager()
{
_tables = GContext.container.Resolve<Tables>();
customServerMgr = GContext.container.Resolve<ICustomServerMgr>();
}
public async Task Synchrodata()
{
//从服务器拿数据
string dataStr = PlayFabMgr.Instance.GetLocalData(AquariumEventDataKey);
if (string.IsNullOrEmpty(dataStr))
{
//新数据
data = new AquariumManagerData();
data.startTime = ZZTimeHelper.UtcNow().AddDays(-2);
data.refreshCount = 0;
data.adCount = 0;
data.refreshDay = ZZTimeHelper.UtcNow().UtcNowOffset().Date.DayOfYear;
data.slot = GContext.container.Resolve<PlayerData>().benefitsAquariumLimit;
}
else
{
data = Newtonsoft.Json.JsonConvert.DeserializeObject<AquariumManagerData>(dataStr);
if (data.slotDatas == null || data.slotDatas.Count < data.slot)
{
return;
}
GetAquariumDataRequest request = new GetAquariumDataRequest();
request.playFabId = GContext.container.Resolve<IUserService>().UserId;
string result = await customServerMgr.CustomServerPost("aquarium/GetAquariumData", Newtonsoft.Json.JsonConvert.SerializeObject(request));
AquariumServerData serverData = null;
if (result != null)
{
var resp = JsonConvert.DeserializeObject<GetAquariumDataResp>(result);
if (resp.code == 0)
{
serverData = resp.data;
}
else if (resp.code == 1)
{
Debug.LogWarning("GetAquariumDataRequest Null");
}
else
{
Debug.LogError("GetAquariumDataRequest Null");
}
}
if (serverData != null)
{
data.aquariumHurtDatas = serverData.aquariumHurtDatas ?? new List<AquariumHurtData>();
int count = data.slot - data.aquariumHurtDatas.Count;
if (count > 0)
{
for (int i = 0; i < count; i++)
{
AquariumHurtData aquariumHurtData = new AquariumHurtData();
data.aquariumHurtDatas.Add(aquariumHurtData);
}
}
data.aquariumResultDatas = serverData.aquariumResultDatas ?? new List<AquariumResultData>();
count = data.slot - data.aquariumResultDatas.Count;
if (count > 0)
{
for (int i = 0; i < count; i++)
{
AquariumResultData aquariumResultData = new AquariumResultData();
data.aquariumResultDatas.Add(aquariumResultData);
}
}
PlayFabMgr.Instance.UpdateUserDataValue(AquariumEventDataKey, Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
//for (int i = 0; i < data.aquariumResultDatas.Count; i += 2)
//{
// data.aquariumResultDatas[i].playerID = GContext.container.Resolve<IUserService>().UserId;
// data.aquariumResultDatas[i].displayName = GContext.container.Resolve<IUserService>().DisplayName;
//}
SetJury();
//保存 数据
SaveData(serverData == null);
}
}
void SetJury()
{
var dateTime = ZZTimeHelper.UtcNow();
AquariumFish aquariumFish = null;
for (int i = 0; i < data.slot; i++)
{
AquariumSlotData slotData = data.slotDatas[i];
slotData.index = i;
AquariumHurtData aquariumHurtData = data.aquariumHurtDatas[i];
//没有受新伤
if (aquariumHurtData.injuryTime < slotData.allRecoveryTime + 0.0001f)
{
continue;
}
var HatchTime = slotData.FishHatchTime();
//还没孵化
if (HatchTime > dateTime)
{
continue;
}
//检查是否受伤
//正常的成长时间 自然时间+加速成长-总恢复时间
float normalH = (float)(dateTime - HatchTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
//受伤时的成长时间 受伤时的时间+加速成长-受伤时的总恢复时间
float injuryH = slotData.injuryGrowthTime;
aquariumFish = _tables.TbAquariumFish.GetOrDefault(slotData.aquariumFishID);
//受伤时的成长进度大于正常的成长进度=还没恢复
if (injuryH > normalH)
{
var recoveryTime = UnityEngine.Random.Range(aquariumFish.RecoveryTime[0], aquariumFish.RecoveryTime[1]);
slotData.recoveryTime = recoveryTime;
recoveryTime -= injuryH - normalH;
//处于受伤状态刷新时间
if (recoveryTime > 0)
{
slotData.allRecoveryTime += recoveryTime;
}
}
else
{
//不处于受伤状态添加受伤时间
//当前正常的成长进度 自然时间+加速成长 - 全部恢复时间
//受伤时的成长时间 受伤时的时间+加速成长-受伤时的总恢复时间
slotData.injuryGrowthTime = (float)(dateTime - HatchTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
slotData.recoveryTime = UnityEngine.Random.Range(aquariumFish.RecoveryTime[0], aquariumFish.RecoveryTime[1]);
slotData.allRecoveryTime += slotData.recoveryTime;
}
}
}
public void GetRandmMap()
{
PlayerData playerData = GContext.container.Resolve<PlayerData>();
PlayerFishData playerFishData = GContext.container.Resolve<PlayerFishData>();
data.startTime = ZZTimeHelper.UtcNow();
data.slot = playerData.benefitsAquariumLimit;
List<AquariumInit> inits = _tables.TbAquariumInit.DataList;
if (data.startCount < inits.Count)
{
NewSlotInitData(inits[data.startCount]);
}
else
{
NewSlotData();
}
data.refreshCount++;
data.isHome = false;
data.startCount++;
//保存 数据
SaveData(true);
GContext.container.Resolve<TriggerPackData>().RefreshTriggerPackData(4000201, data.mapId);
#if AGG
int fishcard_totallevel = playerFishData.GetFishLevelByMap(data.mapId);
string egg_quality_list = data.slotDatas[0].eggId.ToString();
for (int i = 1; i < data.slotDatas.Count; i++)
{
egg_quality_list = $"{egg_quality_list},{data.slotDatas[i].eggId}";
}
using (var e = GEvent.GameEvent("aquarium_start"))
{
e.AddContent("map_id", data.mapId)
.AddContent("total_eggpots", data.slot)
.AddContent("fishcard_totallevel", fishcard_totallevel)
.AddContent("egg_quality_list", egg_quality_list);
}
#endif
}
void NewSlotInitData(AquariumInit init)
{
data.mapId = init.MapID;
List<AquariumSlotData> slotDatas = new List<AquariumSlotData>();
List<AquariumHurtData> aquariumHurtDatas = new List<AquariumHurtData>();
List<AquariumResultData> aquariumResultDatas = new List<AquariumResultData>();
DateTime dateTime = ZZTimeHelper.UtcNow();
List<AquariumEgg> TankEggList = _tables.TbAquariumEgg.DataList;
eggNames = new List<string>();
for (int i = 0; i < TankEggList.Count; i++)
{
eggNames.Add(TankEggList[i].Icon);
}
List<int> Egglist = init.Egglist;
List<int> FishQualitylist = init.FishQualitylist;
List<int> FishList = init.Fishlist;
List<int> FishQuatitylist = init.FishQuatitylist;
List<int> FishMutantlist = init.FishMutantlist;
for (int i = 0; i < data.slot; i++)
{
AquariumSlotData aquariumSlotData = new AquariumSlotData();
aquariumSlotData.eggId = Egglist[i];
aquariumSlotData.aquariumFishID = FishQualitylist[i];
aquariumSlotData.fishMQ = FishQuatitylist[i];
aquariumSlotData.fishItemID = FishList[i];
var tankEgg = _tables.TbAquariumEgg.GetOrDefault(Egglist[i]);
aquariumSlotData.startTime = dateTime;
aquariumSlotData.hatchTime = UnityEngine.Random.Range(tankEgg.HatchTime[0], tankEgg.HatchTime[1]);
AquariumFish aquariumFish = _tables.TbAquariumFish.GetOrDefault(FishQualitylist[i]);
float allCash = SetRewardCount(aquariumFish.SoldReward);
float soldRewardRand = UnityEngine.Random.Range(0, aquariumFish.SoldRewardRand) - aquariumFish.SoldRewardRand * 0.5f;
aquariumSlotData.allCash = allCash * (1 + soldRewardRand);
aquariumSlotData.growthTime = UnityEngine.Random.Range(aquariumFish.GrowthTime[0], aquariumFish.GrowthTime[1]);
aquariumSlotData.mutants = FishMutantlist[i];
aquariumSlotData.index = i;
slotDatas.Add(aquariumSlotData);
AquariumHurtData aquariumHurtData = new AquariumHurtData();
aquariumHurtDatas.Add(aquariumHurtData);
AquariumResultData aquariumResultData = new AquariumResultData();
aquariumResultDatas.Add(aquariumResultData);
}
data.slotDatas = slotDatas;
data.aquariumHurtDatas = aquariumHurtDatas;
data.aquariumResultDatas = aquariumResultDatas;
}
void SetAquariumFish(MapData mapData, AquariumSlotData aquariumSlotData, AquariumEgg tankEgg)
{
List<FishItemList> fishList = mapData.DropFishList;
//权重取鱼
int allProb = tankEgg.HatchFishQualityProb.Sum();
int prob = UnityEngine.Random.Range(0, allProb);
int curProb = 0;
int fishQuality = tankEgg.HatchFishQuality[^1];
for (int k = 0; k < tankEgg.HatchFishQuality.Count; k++)
{
curProb += tankEgg.HatchFishQualityProb[k];
if (curProb > prob)
{
fishQuality = tankEgg.HatchFishQuality[k];
break;
}
}
//品质大于6
if (6 > fishQuality)
{
List<int> FishIDList = fishList[fishQuality - 1].FishIDList;
aquariumSlotData.fishItemID = FishIDList[UnityEngine.Random.Range(0, FishIDList.Count)];
}
else
{
List<int> FishIDList = _tables.TbAquariumConfig.AquariumSpFishList;
aquariumSlotData.fishItemID = FishIDList[UnityEngine.Random.Range(0, FishIDList.Count)];
}
aquariumSlotData.aquariumFishID = fishQuality;
//取鱼的数量
allProb = tankEgg.HatchFishQuantityProb.Sum();
prob = UnityEngine.Random.Range(0, allProb);
curProb = 0;
int fishCount = tankEgg.HatchFishQuantity[0];
for (int k = 0; k < tankEgg.HatchFishQuantity.Count; k++)
{
curProb += tankEgg.HatchFishQuantityProb[k];
if (curProb > prob)
{
fishCount = tankEgg.HatchFishQuantity[k];
break;
}
}
aquariumSlotData.fishMQ = fishCount;
}
void SetTime(AquariumSlotData aquariumSlotData, AquariumEgg tankEgg)
{
aquariumSlotData.hatchTime = UnityEngine.Random.Range(tankEgg.HatchTime[0], tankEgg.HatchTime[1]);
AquariumFish aquariumFish = _tables.TbAquariumFish.GetOrDefault(aquariumSlotData.aquariumFishID);
float allCash = SetRewardCount(aquariumFish.SoldReward);
float soldRewardRand = UnityEngine.Random.Range(0, aquariumFish.SoldRewardRand) - aquariumFish.SoldRewardRand * 0.5f;
aquariumSlotData.allCash = allCash * (1 + soldRewardRand);
aquariumSlotData.growthTime = UnityEngine.Random.Range(aquariumFish.GrowthTime[0], aquariumFish.GrowthTime[1]);
aquariumSlotData.mutants = 0;
for (int j = 0; j < aquariumSlotData.fishMQ; j++)
{
if (UnityEngine.Random.Range(0, 1f) < aquariumFish.MutantProb)
{
aquariumSlotData.mutants++;
}
}
}
void NewSlotData()
{
int curMapId = MapId;
var mapDatas = _tables.TbMapData.DataList;
var maxMapID = GContext.container.Resolve<PlayerData>().lastMapId;
//非当前地图
var mapIDs = new List<int>();
for (int i = 0; i < mapDatas.Count; i++)
{
if (mapDatas[i].ID <= maxMapID)
{
if (mapDatas[i].ID != curMapId)
{
mapIDs.Add(mapDatas[i].ID);
}
}
else
{
break;
}
}
if (mapIDs.Count == 0)
{
data.mapId = maxMapID;
}
else
{
data.mapId = mapIDs[UnityEngine.Random.Range(0, mapIDs.Count)];
}
List<AquariumSlotData> slotDatas = new List<AquariumSlotData>();
List<AquariumHurtData> aquariumHurtDatas = new List<AquariumHurtData>();
List<AquariumResultData> aquariumResultDatas = new List<AquariumResultData>();
DateTime dateTime = ZZTimeHelper.UtcNow();
MapData mapData = _tables.TbMapData.GetOrDefault(data.mapId);
List<AquariumEgg> TankEggList = _tables.TbAquariumEgg.DataList;
float eggAllWeight = -0.0001f;
eggNames = new List<string>();
for (int i = 0; i < TankEggList.Count; i++)
{
eggNames.Add(TankEggList[i].Icon);
eggAllWeight += TankEggList[i].Weight;
}
for (int i = 0; i < data.slot; i++)
{
AquariumSlotData aquariumSlotData = new AquariumSlotData();
//权重取蛋
float eggWeight = UnityEngine.Random.Range(0, eggAllWeight);
float curEggWeight = 0;
AquariumEgg tankEgg = TankEggList[0];
foreach (var item in TankEggList)
{
curEggWeight += item.Weight;
if (curEggWeight > eggWeight)
{
tankEgg = item;
break;
}
}
aquariumSlotData.eggId = tankEgg.ID;
SetAquariumFish(mapData, aquariumSlotData, tankEgg);
aquariumSlotData.startTime = dateTime;
SetTime(aquariumSlotData, tankEgg);
aquariumSlotData.index = i;
slotDatas.Add(aquariumSlotData);
AquariumHurtData aquariumHurtData = new AquariumHurtData();
aquariumHurtDatas.Add(aquariumHurtData);
AquariumResultData aquariumResultData = new AquariumResultData();
aquariumResultDatas.Add(aquariumResultData);
}
data.slotDatas = slotDatas;
data.aquariumHurtDatas = aquariumHurtDatas;
data.aquariumResultDatas = aquariumResultDatas;
}
public void Speedup(bool isGuide)
{
var dateTime = ZZTimeHelper.UtcNow();
float AdAccelerate = _tables.TbAquariumConfig.AdAccelerate;
if (isGuide)
{
AdAccelerate = _tables.TbAquariumConfig.AdAccelerateFirst;
}
List<AquariumSlotData> slotDataList = data.slotDatas;
List<AquariumResultData> aquariumReportDatas = data.aquariumResultDatas;
for (int i = 0; i < slotDataList.Count; i++)
{
var slotData = slotDataList[i];
//售卖或者丢失
if (slotData.IsResult() || aquariumReportDatas[slotData.index].IsResult())
{ continue; }
var HatchTime = slotData.FishHatchTime();
if (HatchTime <= dateTime)
{
//鱼加速
slotData.accelerationGrowth += AdAccelerate;
}
else
{
float s = (float)(HatchTime - dateTime).TotalHours;
if (s <= 0)
{
slotData.accelerationGrowth += AdAccelerate;
}
else if (AdAccelerate > s)
{
slotData.accelerationHatch += s;
slotData.accelerationGrowth += AdAccelerate - s;
}
else
{
slotData.accelerationHatch += AdAccelerate;
}
}
}
data.adCount++;
SaveData();
}
public void SellFish(List<AquariumSlotData> slotDataList)
{
sellList = new List<AquariumSlotData>();
var dateTime = ZZTimeHelper.UtcNow();
PlayerData playerData = GContext.container.Resolve<PlayerData>();
var weight = GetWeightMag();
AquariumFish aquariumFish;
FishData fishData;
DateTime startTime;
float injuryH;
float weightIncEvent;
List<ItemData> itemDatas = new List<ItemData>();
PlayerFishData playerFishData = GContext.container.Resolve<PlayerFishData>();
float CashMag = (1 + playerData.benefitsCashMag) * (1 + playerData.benefitsAquariumCashMag);
for (int i = 0; i < slotDataList.Count; i++)
{
var slotData = slotDataList[i];
sellList.Add(slotData);
if (slotData.allCash == 0)
{
slotData.allCash = 1;
}
//奖励
aquariumFish = _tables.TbAquariumFish.GetOrDefault(slotData.aquariumFishID);
startTime = slotData.FishHatchTime();
injuryH = slotData.injuryGrowthTime;
weightIncEvent = (1 + weight[slotData.aquariumFishID - 1]) * CashMag;
float normalH = (float)(dateTime - startTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
float rewardProgress = normalH / slotData.growthTime;
if (injuryH > normalH && injuryH > slotData.growthTime)
{
rewardProgress = 1 - ((injuryH - normalH) / slotData.growthTime);
}
if (rewardProgress > 1)
{
rewardProgress = 1;
}
//金币显示
ItemData itemData = new ItemData();
int fishQ = slotData.fishMQ;
bool is_injured = false;
if (injuryH > normalH)
{
fishQ -= data.aquariumHurtDatas[slotData.index].fishLQ;
is_injured = true;
if (fishQ <= 0)
{
fishQ = 1;
}
}
for (int j = 0; j < fishQ; j++)
{
if (j < slotData.mutants)
{
itemData.count += (int)(slotData.allCash * (1 + aquariumFish.MutantGrowthExtraSoldReward * rewardProgress) * (1 + aquariumFish.MutantExtraSoldReward) * weightIncEvent);
}
else
{
itemData.count += (int)(slotData.allCash * (1 + aquariumFish.GrowthExtraSoldReward * rewardProgress) * weightIncEvent);
}
}
itemData.id = 1002;
itemDatas.Add(itemData);
slotData.cash = itemData.count;
//重量
Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID);
fishData = _tables.TbFishData.GetOrDefault(item.RedirectID);
float weightCount = fishData.BaseWeight * (1 + aquariumFish.GrowthExtraSoldReward * rewardProgress) * weightIncEvent;
playerFishData.SetWeight(fishData.ID, weightCount);
#if AGG
int cardLevel = playerFishData.GetDataLevel(fishData.ID);
using (var e = GEvent.GameEvent("aquarium_sell"))
{
e.AddContent("map_id", data.mapId)
.AddContent("total_eggpots", data.slot)
.AddContent("fish_eggs_quality", slotData.eggId)
.AddContent("mature_percent", rewardProgress)
.AddContent("fish_id", fishData.ID)
.AddContent("fishcard_level", cardLevel)
.AddContent("fish_quality", slotData.aquariumFishID)
.AddContent("mutant_count", slotData.mutants)
.AddContent("is_injured", is_injured)
.AddContent("fish_count", slotData.fishMQ)
.AddContent("is_dead", false)
.AddContent("reward_cash", slotData.cash);
}
#endif
}
//GContext.Publish(new ShowData(itemDatas));
GContext.container.Resolve<PlayerItemData>().AddItem(itemDatas);
//GContext.Publish(new ShowData());
CheckInHome();
SaveData();
}
public float SetRewardCount(int dropID)
{
DropPackageList dropPackageList = _tables.TbDrop[dropID].DropList;
return dropPackageList.DropCountList[0];
}
public void CheckInHome()
{
data.isHome = true;
List<AquariumResultData> aquariumResultDatas = data.aquariumResultDatas;
var slotDatas = data.slotDatas;
for (int i = 0; i < data.slot; i++)
{
if (!slotDatas[i].IsResult() && !aquariumResultDatas[i].IsResult())
{
data.isHome = false;
}
}
if (data.isHome)
{
#if AGG
PlayerFishData playerFishData = GContext.container.Resolve<PlayerFishData>();
for (int i = 0; i < data.slot; i++)
{
if (!slotDatas[i].IsResult() && aquariumResultDatas[i].IsResult())
{
var fishItem = _tables.TbItem.GetOrDefault(slotDatas[i].fishItemID);
int cardLevel = playerFishData.GetDataLevel(fishItem.RedirectID);
using (var e = GEvent.GameEvent("aquarium_sell"))
{
e.AddContent("map_id", data.mapId)
.AddContent("total_eggpots", data.slot)
.AddContent("fish_eggs_quality", slotDatas[i].eggId)
.AddContent("mature_percent", 0)
.AddContent("fish_id", fishItem.RedirectID)
.AddContent("fishcard_level", cardLevel)
.AddContent("fish_quality", slotDatas[i].aquariumFishID)
.AddContent("mutant_count", slotDatas[i].mutants)
.AddContent("is_injured", true)
.AddContent("is_dead", true)
.AddContent("fish_count", 0)
.AddContent("reward_cash", 0);
}
}
}
#endif
//_ = UIManager.Instance.ShowUI(UITypes.AquariumReportPopupPanel);
SaveData();
}
}
void SaveData(bool all = false)
{
if (all)
{
UpdateAquariumAllDataRequest request = new UpdateAquariumAllDataRequest();
request.playFabId = GContext.container.Resolve<IUserService>().UserId;
request.data = new AquariumServerData()
{
startTime = data.startTime,
mapId = data.mapId,
slot = data.slot,
slotDatas = data.slotDatas,
aquariumResultDatas = data.aquariumResultDatas,
aquariumHurtDatas = data.aquariumHurtDatas,
};
customServerMgr.CustomServerPost("aquarium/UpdateAquariumData", Newtonsoft.Json.JsonConvert.SerializeObject(request));
}
else
{
UpdateSlotDatasRequest request = new UpdateSlotDatasRequest();
request.playFabId = GContext.container.Resolve<IUserService>().UserId;
request.slotDatas = data.slotDatas;
customServerMgr.CustomServerPost("aquarium/UpdateSlotData", Newtonsoft.Json.JsonConvert.SerializeObject(request));
}
PlayFabMgr.Instance.UpdateUserDataValue(AquariumEventDataKey, Newtonsoft.Json.JsonConvert.SerializeObject(data));
}
public List<float> GetWeightMag()
{
PlayerFishData playerFishData = GContext.container.Resolve<PlayerFishData>();
PlayerData playerData = GContext.container.Resolve<PlayerData>();
List<float> weight = new List<float>() { 0, 0, 0, 0, 0, 0 };
List<int> fishCount = new List<int>() { 0, 0, 0, 0, 0, 0 };
MapData mapData = _tables.TbMapData.GetOrDefault(data.mapId);
var fishList = mapData.FishList;
for (int j = 0; j < fishList.Count; j++)
{
var data = _tables.TbFishData.GetOrDefault(fishList[j]);
fishCount[data.Quality - 1]++;
int level = playerFishData.GetDataLevel(fishList[j]);
if (level > 0)
{
FishCard fishCard = _tables.TbFishCard.GetOrDefault(data.FishCardID);
weight[data.Quality - 1] += fishCard.WeightMagList[level - 1];
}
}
for (int i = 0; i < weight.Count; i++)
{
weight[i] /= fishCount[i];
}
weight[5] = playerData.benefitsEventFishCashMag;
return weight;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f5a8f2ba5bd36404a93bdf3474936205
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,188 @@
using System.Collections.Generic;
using System;
public class AquariumSlotData
{
public int index { get; set; }
public int eggId { set; get; }
public int fishItemID { set; get; }
public int aquariumFishID { set; get; }
/// <summary>
/// 是否变异
/// </summary>
public int mutants { set; get; }
/// <summary>
/// maximum quantity 孵化的数量
/// </summary>
public int fishMQ { set; get; }
/// <summary>
/// 鱼卵开始孵化
/// </summary>
public DateTime startTime { set; get; }
/// <summary>
/// 孵化时间
/// </summary>
public float hatchTime { set; get; }
/// <summary>
/// 成长时间
/// </summary>
public float growthTime { set; get; }
/// <summary>
/// 孵化加速时间 每次加量不会超出当前剩余时间
/// </summary>
public float accelerationHatch { set; get; }
/// <summary>
/// 成长加速时间
/// </summary>
public float accelerationGrowth { set; get; }
/// <summary>
/// 多次受伤的恢复时间
/// </summary>
public float allRecoveryTime { set; get; }
public float recoveryTime { set; get; }
/// <summary>
/// 发现受伤时的成长时间 自然时间+加速成长 - 当时全部恢复时间
/// </summary>
public float injuryGrowthTime { set; get; }
/// <summary>
/// 全部结算的钱
/// </summary>
public float allCash { get; set; }
/// <summary>
/// 结算的钱
/// </summary>
public int cash { get; set; }
/// <summary>
/// 鱼从孵化到成熟的时间 孵化间+成长时间-加速孵化-加速成长+恢复时间
/// </summary>
/// <returns></returns>
public DateTime FishGrowthTime()
{
return startTime.AddHours(hatchTime + growthTime - accelerationHatch - accelerationGrowth + allRecoveryTime);
}
public DateTime FishHatchTime()
{
return startTime.AddHours(hatchTime - accelerationHatch);
}
public bool IsResult()
{
return cash > 0;
}
}
public class AquariumHurtData
{
/// <summary>
/// lost quantity 被刺数量服务器修改
/// </summary>
public int fishLQ { set; get; }
/// <summary>
/// 服务器标记受伤 injuryTime > slotData.allRecoveryTime 受新伤
/// </summary>
public float injuryTime { set; get; }
}
public class AquariumResultData
{
/// <summary>
/// 如果鱼被刺走
/// </summary>
public string playerID { set; get; }
public string avatar { get; set; }
public string displayName { get; set; }
public bool IsResult()
{
return !string.IsNullOrEmpty(playerID);
}
}
public class AquariumManagerData
{
/// <summary>
/// 客户端维护数据
/// </summary>
//CCCCCCCCCCCCCC客户端维护数据CCCCCCCCCCCCCC
public DateTime startTime { set; get; }
public int mapId { set; get; } = 101;
public int slot { set; get; }
public List<AquariumSlotData> slotDatas { set; get; }
//CCCCCCCCCCCCCC客户端维护数据CCCCCCCCCCCCCC
//SSSSSSSSSSSSSS结算服务器刺鱼刺走SSSSSSSSSSSSSS
public List<AquariumResultData> aquariumResultDatas { set; get; }
public List<AquariumHurtData> aquariumHurtDatas { set; get; }
//SSSSSSSSSSSSSS被刺鱼受伤SSSSSSSSSSSSSS
public int adCount { set; get; }
public bool isHome { set; get; }
public int startCount { set; get; }
public int refreshCount { set; get; }
public int refreshDay { set; get; }
}
public class AquariumServerData
{
public DateTime startTime { set; get; }
public int mapId { set; get; }
public int slot { set; get; }
public List<AquariumSlotData> slotDatas { set; get; }
public List<AquariumResultData> aquariumResultDatas { set; get; }
public List<AquariumHurtData> aquariumHurtDatas { set; get; }
}
public class UpdateAquariumAllDataRequest
{
public string playFabId { set; get; }
public AquariumServerData data { get; set; }
}
public class GetAquariumDataRequest
{
public string playFabId { set; get; }
}
public class GetAquariumDataResp
{
public int code { set; get; }
public string playFabId { set; get; }
public AquariumServerData data { get; set; }
}
public class UpdateSlotDatasRequest
{
public string playFabId { set; get; }
public List<AquariumSlotData> slotDatas { set; get; }
}
public class RobFishRequest
{
//GContext.container.Resolve<SmallGameData>().AlbumEventID
public int timeEventId { set; get; }
public string playerId { set; get; }
/// <summary>
/// 被抢的人
/// </summary>
public string playFabId { set; get; }
/// <summary>
/// 被抢的槽位
/// </summary>
public int slotIndex { set; get; }
/// <summary>
/// 是否抢走
/// </summary>
public bool isRob { set; get; }
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e26b89693a95b8e478a02397c17a2f36
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,491 @@
using asap.core;
using cfg;
using game;
using GameCore;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
public class AquariumShooterFishManager
{
private cfg.Tables _tables;
private ICustomServerMgr customServerMgr;
public AquariumServerData serverData { get; private set; }
public int MapId => serverData?.mapId ?? 101;
List<int> HuntResult = null;
List<int> DropID = null;
public AquariumShooterFishManager()
{
_tables = GContext.container.Resolve<Tables>();
customServerMgr = GContext.container.Resolve<ICustomServerMgr>();
}
void RobotSetFish(MapData mapData, AquariumSlotData aquariumSlotData, AquariumEgg tankEgg)
{
//权重取鱼
List<int> FishIDList;
List<FishItemList> fishList = mapData.DropFishList;
float allProb = tankEgg.HatchFishQualityProb.Sum();
float prob = UnityEngine.Random.Range(0, allProb);
float curProb = 0;
int fishQuality = tankEgg.HatchFishQuality[^1];
for (int k = 0; k < tankEgg.HatchFishQuality.Count; k++)
{
curProb += tankEgg.HatchFishQualityProb[k];
if (curProb > prob)
{
fishQuality = tankEgg.HatchFishQuality[k];
break;
}
}
//品质大于6
if (6 > fishQuality)
{
FishIDList = fishList[fishQuality - 1].FishIDList;
aquariumSlotData.fishItemID = FishIDList[UnityEngine.Random.Range(0, FishIDList.Count)];
}
else
{
FishIDList = _tables.TbAquariumConfig.AquariumSpFishList;
aquariumSlotData.fishItemID = FishIDList[UnityEngine.Random.Range(0, FishIDList.Count)];
}
aquariumSlotData.aquariumFishID = fishQuality;
}
void RobotSetFishCount(AquariumSlotData aquariumSlotData, AquariumEgg tankEgg)
{
int allProb = tankEgg.HatchFishQuantityProb.Sum();
int prob = UnityEngine.Random.Range(0, allProb);
int curProb = 0;
int fishCount = tankEgg.HatchFishQuantity[0];
for (int k = 0; k < tankEgg.HatchFishQuantity.Count; k++)
{
curProb += tankEgg.HatchFishQuantityProb[k];
if (curProb > prob)
{
fishCount = tankEgg.HatchFishQuantity[k];
break;
}
}
aquariumSlotData.fishMQ = fishCount;
}
void RobotSetTime(AquariumSlotData aquariumSlotData, AquariumEgg tankEgg)
{
AquariumFish tankFish = _tables.TbAquariumFish.GetOrDefault(aquariumSlotData.aquariumFishID);
aquariumSlotData.growthTime = UnityEngine.Random.Range(tankFish.GrowthTime[0], tankFish.GrowthTime[1]);
aquariumSlotData.hatchTime = UnityEngine.Random.Range(tankEgg.HatchTime[0], tankEgg.HatchTime[1]);
aquariumSlotData.mutants = 0;
for (int j = 0; j < aquariumSlotData.fishMQ; j++)
{
if (UnityEngine.Random.Range(0, 1f) < tankFish.MutantProb)
{
aquariumSlotData.mutants++;
}
}
}
AquariumServerData SetRobot(string playFabId)
{
int b = Convert.ToInt32(playFabId, 16);
Robot robot = _tables.TbRobot.GetOrDefault(b);
string AquariumServerDataStr = PlayerPrefs.GetString("AquariumServerData" + playFabId[^1]);
DateTime dateTime = ZZTimeHelper.UtcNow();
AquariumServerData localServerData = new AquariumServerData();
if (!string.IsNullOrEmpty(AquariumServerDataStr))
{
try
{
localServerData = JsonConvert.DeserializeObject<AquariumServerData>(AquariumServerDataStr);
//防止改时间导致的机器人数据错误(蛋未孵化)
if (localServerData.startTime < ZZTimeHelper.UtcNow())
{
Debug.Log($"nextOpponent InitFish SetRobotMapId {localServerData.mapId}");
return localServerData;
}
}
catch (Exception)
{
Debug.LogError("AquariumServerDataStr Error");
}
}
localServerData.mapId = GContext.container.Resolve<SmallGameData>().RobotMapId;
localServerData.startTime = ZZTimeHelper.UtcNow();
localServerData.slot = robot.HatchEggPots;
List<AquariumSlotData> slotData = new List<AquariumSlotData>();
List<AquariumResultData> aquariumResultDatas = new List<AquariumResultData>();
List<AquariumHurtData> aquariumHurtDatas = new List<AquariumHurtData>();
List<AquariumEgg> TankEggList = _tables.TbAquariumEgg.DataList;
float eggAllWeight = -0.0001f;
for (int i = 0; i < TankEggList.Count; i++)
{
eggAllWeight += TankEggList[i].Weight;
}
bool isGrowth = false;
MapData mapData = _tables.TbMapData.GetOrDefault(localServerData.mapId);
for (int i = 0; i < localServerData.slot; i++)
{
AquariumSlotData aquariumSlotData = new AquariumSlotData();
//权重取蛋
float eggWeight = UnityEngine.Random.Range(0, eggAllWeight);
float curEggWeight = 0;
AquariumEgg tankEgg = TankEggList[0];
foreach (var item in TankEggList)
{
curEggWeight += item.Weight;
if (curEggWeight > eggWeight)
{
tankEgg = item;
break;
}
}
aquariumSlotData.eggId = tankEgg.ID;
RobotSetFish(mapData, aquariumSlotData, tankEgg);
//取鱼的数量
RobotSetFishCount(aquariumSlotData, tankEgg);
RobotSetTime(aquariumSlotData, tankEgg);
aquariumSlotData.startTime = dateTime;
if (robot != null)
{
if (robot.HatchProb > UnityEngine.Random.Range(0, 1f))
{
isGrowth = true;
aquariumSlotData.accelerationHatch = aquariumSlotData.hatchTime + 1;
aquariumSlotData.accelerationGrowth = aquariumSlotData.growthTime *
UnityEngine.Random.Range(robot.MatureProgress[0], robot.MatureProgress[1]);
}
}
aquariumSlotData.index = i;
slotData.Add(aquariumSlotData);
aquariumResultDatas.Add(new AquariumResultData());
aquariumHurtDatas.Add(new AquariumHurtData());
}
if (!isGrowth)
{
slotData[0].accelerationHatch = slotData[0].hatchTime + 1;
slotData[0].accelerationGrowth = slotData[0].growthTime *
UnityEngine.Random.Range(robot.MatureProgress[0], robot.MatureProgress[1]);
}
localServerData.slotDatas = slotData;
localServerData.aquariumResultDatas = aquariumResultDatas;
localServerData.aquariumHurtDatas = aquariumHurtDatas;
PlayerPrefs.SetString("AquariumServerData" + playFabId[^1], JsonConvert.SerializeObject(localServerData));
//保存 数据
return localServerData;
}
public AquariumServerData GetDataFishHuntInit(string playFabId, FishHuntInit inti)
{
int b = Convert.ToInt32(playFabId, 16);
Robot robot = _tables.TbRobot.GetOrDefault(b);
HuntResult = inti.HuntResult;
DropID = inti.DropID;
DateTime dateTime = ZZTimeHelper.UtcNow();
AquariumServerData localServerData = new AquariumServerData();
localServerData.mapId = inti.MapID;
localServerData.startTime = ZZTimeHelper.UtcNow();
List<int> Fishlist = inti.Fishlist;
List<int> FishQuatitylist = inti.FishQuatitylist;
List<int> FishQualitylist = inti.FishQualitylist;
List<int> FishMutantlist = inti.FishMutantlist;
List<float> FishGrowthlist = inti.FishGrowthlist;
localServerData.slot = Fishlist.Count;
List<AquariumSlotData> slotData = new List<AquariumSlotData>();
List<AquariumResultData> aquariumResultDatas = new List<AquariumResultData>();
List<AquariumHurtData> aquariumHurtDatas = new List<AquariumHurtData>();
for (int i = 0; i < localServerData.slot; i++)
{
AquariumSlotData aquariumSlotData = new AquariumSlotData();
aquariumSlotData.eggId = 1;
aquariumSlotData.fishItemID = Fishlist[i];
aquariumSlotData.aquariumFishID = FishQualitylist[i];
aquariumSlotData.fishMQ = FishQuatitylist[i];
aquariumSlotData.startTime = dateTime;
aquariumSlotData.hatchTime = 1;
aquariumSlotData.growthTime = 1;
aquariumSlotData.accelerationHatch = 1.1f;
aquariumSlotData.accelerationGrowth = aquariumSlotData.growthTime * FishGrowthlist[i];
aquariumSlotData.mutants = FishMutantlist[i];
aquariumSlotData.index = i;
slotData.Add(aquariumSlotData);
aquariumResultDatas.Add(new AquariumResultData());
aquariumHurtDatas.Add(new AquariumHurtData());
}
localServerData.slotDatas = slotData;
localServerData.aquariumResultDatas = aquariumResultDatas;
localServerData.aquariumHurtDatas = aquariumHurtDatas;
serverData = localServerData;
//保存 数据
return serverData;
}
public async Task<AquariumServerData> GetData(string playFabId, bool isRobot, bool canEmpty)
{
HuntResult = null;
DropID = null;
if (isRobot)
{
serverData = SetRobot(playFabId);
return serverData;
}
GetAquariumDataRequest request = new GetAquariumDataRequest();
request.playFabId = playFabId;
string result = await customServerMgr.CustomServerPost("aquarium/GetAquariumData", Newtonsoft.Json.JsonConvert.SerializeObject(request));
if (result != null)
{
var resp = JsonConvert.DeserializeObject<GetAquariumDataResp>(result);
if (resp.code == 0)
{
var data = resp.data;
List<AquariumSlotData> slotDatas = data.slotDatas;
if (slotDatas == null)
{
return null;
}
if (canEmpty)
{
serverData = resp.data;
return serverData;
}
var time = ZZTimeHelper.UtcNow();
List<AquariumResultData> aquariumResultDatas = data.aquariumResultDatas;
for (int i = 0; i < slotDatas.Count; i++)
{
AquariumSlotData slotData = slotDatas[i];
slotData.index = i;
var HatchTime = slotData.FishHatchTime();
if (HatchTime < time)
{
if (!slotData.IsResult() && aquariumResultDatas.Count > i && !aquariumResultDatas[i].IsResult())
{
serverData = resp.data;
return serverData;
}
}
}
}
else
{
Debug.LogWarning("GetAquariumDataRequest Null");
if (canEmpty)
{
PlayerData playerData = GContext.container.Resolve<PlayerData>();
AquariumServerData data = new AquariumServerData();
data.startTime = ZZTimeHelper.UtcNow();
data.slot = playerData.benefitsAquariumLimit;
List<AquariumInit> inits = _tables.TbAquariumInit.DataList;
NewSlotInitData(inits[0], data);
serverData = data;
return serverData;
}
}
}
return null;
}
void NewSlotInitData(AquariumInit init, AquariumServerData data)
{
data.mapId = init.MapID;
List<AquariumSlotData> slotDatas = new List<AquariumSlotData>();
List<AquariumHurtData> aquariumHurtDatas = new List<AquariumHurtData>();
List<AquariumResultData> aquariumResultDatas = new List<AquariumResultData>();
DateTime dateTime = ZZTimeHelper.UtcNow();
List<int> Egglist = init.Egglist;
List<int> FishQualitylist = init.FishQualitylist;
List<int> FishList = init.Fishlist;
List<int> FishQuatitylist = init.FishQuatitylist;
List<int> FishMutantlist = init.FishMutantlist;
for (int i = 0; i < data.slot; i++)
{
AquariumSlotData aquariumSlotData = new AquariumSlotData();
aquariumSlotData.eggId = Egglist[i];
aquariumSlotData.aquariumFishID = FishQualitylist[i];
aquariumSlotData.fishMQ = FishQuatitylist[i];
aquariumSlotData.fishItemID = FishList[i];
var tankEgg = _tables.TbAquariumEgg.GetOrDefault(Egglist[i]);
aquariumSlotData.startTime = dateTime;
aquariumSlotData.hatchTime = UnityEngine.Random.Range(tankEgg.HatchTime[0], tankEgg.HatchTime[1]);
AquariumFish aquariumFish = _tables.TbAquariumFish.GetOrDefault(FishQualitylist[i]);
aquariumSlotData.growthTime = UnityEngine.Random.Range(aquariumFish.GrowthTime[0], aquariumFish.GrowthTime[1]);
aquariumSlotData.mutants = FishMutantlist[i];
aquariumSlotData.index = i;
slotDatas.Add(aquariumSlotData);
AquariumHurtData aquariumHurtData = new AquariumHurtData();
aquariumHurtDatas.Add(aquariumHurtData);
AquariumResultData aquariumResultData = new AquariumResultData();
aquariumResultDatas.Add(aquariumResultData);
}
data.slotDatas = slotDatas;
data.aquariumHurtDatas = aquariumHurtDatas;
data.aquariumResultDatas = aquariumResultDatas;
}
public float RobFishRequest(int changeTargetCount, int multiple, string playFabId, int index, int groupId, OpponentItemData opponentItemData, out bool isRob, out int addRankCount)
{
GContext.container.Resolve<SmallGameData>().SaveFishHuntGameCount();
AquariumSlotData slotData = serverData.slotDatas[groupId];
AquariumFish aquariumFish = _tables.TbAquariumFish.GetOrDefault(slotData.aquariumFishID);
//刺鱼奖励
float extra = 0;
if (index < slotData.mutants)
{
extra += aquariumFish.AttackMutantExtraReward;
}
isRob = false;
ItemData itemDatas = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(aquariumFish.AttackReward);
float ExtraReward = 0;
if (HuntResult != null)
{
itemDatas = GContext.container.Resolve<PlayerItemData>().GetItemDataOne(DropID[groupId]);
if (HuntResult[groupId] == 1)
{
if (index < slotData.mutants)
{
ExtraReward = aquariumFish.StealMutantExtraReward;
}
else
{
ExtraReward = aquariumFish.StealExtraReward;
}
isRob = true;
}
}
else
{
float random = UnityEngine.Random.Range(0, 1f);
if (index < slotData.mutants)
{
if (random <= aquariumFish.StealMutantProb)
{
ExtraReward = aquariumFish.StealMutantExtraReward;
isRob = true;
}
}
else
{
if (random <= aquariumFish.StealProb)
{
ExtraReward = aquariumFish.StealExtraReward;
isRob = true;
}
}
}
extra += UnityEngine.Random.Range(0, aquariumFish.StealRewardRand) - aquariumFish.StealRewardRand * 0.5f;
itemDatas.count = (int)(itemDatas.count * (1 + extra) * multiple * (1 + ExtraReward));
SuperHunt superHunt = GContext.container.Resolve<BuffDataCenter>().GetWeelyBuffTimeData<SuperHunt>();
float superCashBonus = 0;
if (superHunt != null)
{
superCashBonus = superHunt.CashBonus;
}
//itemDatas.count *= (1 + superCashBonus);
//获取奖励
GContext.container.Resolve<PlayerItemData>().AddItem(itemDatas);
var _fishingEventData = GContext.container.Resolve<FishingEventData>();
if (_fishingEventData.rankInit != null)
{
int point = _fishingEventData.rankInit.PointRobbery[1];
if (isRob)
{
point = _fishingEventData.rankInit.PointRobbery[2];
}
if (index < slotData.mutants)
{
point += _fishingEventData.rankInit.PointRobbery[3];
}
addRankCount = point * multiple;
_fishingEventData.AddRankTarget(addRankCount);
}
else
{
addRankCount = 0;
}
if (opponentItemData.isRobot)
{
int i = groupId;
List<AquariumHurtData> aquariumHurtDatas = serverData.aquariumHurtDatas;
//鱼被刺走
if (isRob)
{
//aquariumHurtDatas[i].fishLQ++;
////鱼全部被刺走,重置
//if (aquariumHurtDatas[i].fishLQ >= slotData.fishMQ)
//{
// aquariumHurtDatas[i].fishLQ = 0;
//}
PlayerPrefs.DeleteKey("AquariumServerData" + playFabId[^1]);
//PlayerPrefs.SetString("AquariumServerData" + playFabId[^1], JsonConvert.SerializeObject(serverData));
}
}
else
{
//通知服务器刺伤谁的鱼
RobFishRequest request = new RobFishRequest();
request.timeEventId = GContext.container.Resolve<SmallGameData>().AlbumEventID;
request.playFabId = playFabId;
request.slotIndex = groupId;
if (UnityEngine.Random.Range(0, 1f) <= aquariumFish.RealStealProb)
{
request.isRob = isRob;
}
request.playerId = GContext.container.Resolve<IUserService>().UserId;
customServerMgr.CustomServerPost("aquarium/RobFish", Newtonsoft.Json.JsonConvert.SerializeObject(request));
}
Debug.Log($"target_source isRobot: {opponentItemData.isRobot} target_group: {opponentItemData.target_group} target_source {opponentItemData.target_source}");
#if AGG
using (var e = GEvent.GameEvent("fish_raid"))
{
Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID);
e.AddContent("fish_id", item.RedirectID)
.AddContent("fish_quality", slotData.aquariumFishID)
.AddContent("is_mutant", slotData.mutants > index)
.AddContent("result", isRob ? 1 : 0)
.AddContent("target_accountid", opponentItemData.isRobot ? "-1" : playFabId)
.AddContent("target_group", opponentItemData.target_group)
.AddContent("target_source", opponentItemData.target_source)
.AddContent("fish_multiple",multiple)
.AddContent("target_change_count", changeTargetCount)
.AddContent("reward_cash", itemDatas.count);
}
#endif
return itemDatas.count;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 55c617580dedfa648bd2c424c41eb8b0
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
using asap.core;
using cfg;
using UnityEngine;
using UnityEngine.AddressableAssets;
public class FishEgg : AquariumFishBase
{
GameObject goPrefab;
AquariumEgg egg;
public async void LoadEgg(AquariumSlotData slotData)
{
this.slotData = slotData;
if (egg != null)
{
return;
}
Tables tables = GContext.container.Resolve<Tables>();
egg = tables.TbAquariumEgg.GetOrDefault(slotData.eggId);
goPrefab = await Addressables.InstantiateAsync(egg.Prefab, transform).Task;
if (egg == null)
{
Addressables.ReleaseInstance(goPrefab);
goPrefab = null;
}
else if (goPrefab != null)
{
goPrefab.transform.localPosition = Vector3.zero;
}
}
public void RemoveEgg()
{
egg = null;
if (goPrefab != null)
{
Addressables.ReleaseInstance(goPrefab);
goPrefab = null;
}
}
private void OnDestroy()
{
RemoveEgg();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 19b5047fa7a6a4142a5566284ae29046
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
using UnityEngine;
public class FishEggManager : MonoBehaviour
{
public FishEgg[] eggs;
public void AddEgg(AquariumSlotData slotData)
{
eggs[slotData.index].LoadEgg(slotData);
}
public void RemoveEgg(int index)
{
//蛋孵化的动画
//await Awaiters.NextFrame;
eggs[index].RemoveEgg();
}
public FishEgg GetEgg(int index)
{
if (eggs.Length > index)
{
return eggs[index];
}
return null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 52eef0a5dc6412941af35d884cfe6e9b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,204 @@
using asap.core;
using cfg;
using System;
using System.Collections.Generic;
using UnityEngine;
using Random = UnityEngine.Random;
public class FishManager : MonoBehaviour
{
[SerializeField] private GameObject fishPrefab;
public Vector3 tankSize;
private Vector3 _tankCenter = Vector3.zero;
public Vector3 tankCenter => _tankCenter;
[Header("Fish Parameters")]
public float avoidRadius;
public float alignRadius;
public float obstacleDetectionRadius;
public float avoidance, alignment, cohesion, trigger, obstacle, areaConstrain, maxVel, minVel, angularAcc, magnitudeAcc, dvLerp;
public float zMoveRatio = 0.4f;
private Vector3 HalfSize => tankSize / 2;
public Dictionary<int, GameObject> fishUnDownloadAlter;
Dictionary<int, List<FishMovement>> _fishGroups = new Dictionary<int, List<FishMovement>>();
[NonSerialized]
public List<FishMovement> allFish = new List<FishMovement>();
[NonSerialized]
public List<GameObject> obstacleGo = new List<GameObject>();
public float MaxLoadTime { set; get; } = 50;
private void Start()
{
_tankCenter = transform.position;
fishPrefab.gameObject.SetActive(false);
}
/// <summary>
/// 初始鱼群
/// </summary>
/// <param name="mutantMaterial"> 是否变异 变异材质 </param>
/// <param name="fishItemID">鱼的item ID</param>
/// <param name="count">鱼当前剩余的数量</param>
/// <param name="groupId">鱼群分组</param>
///
public void AddFish(Material mutantMaterial, GameObject fxLeftEye, GameObject fxRightEye,
AquariumSlotData slotData, int count, int groupId)
{
if (_fishGroups.ContainsKey(groupId))
{
return;
}
var fishGroup = new List<FishMovement>();
_fishGroups[groupId] = fishGroup;
Tables tables = GContext.container.Resolve<Tables>();
Item item = tables.TbItem.GetOrDefault(slotData.fishItemID);
var fishData = tables.TbFishData.GetOrDefault(item.RedirectID);
float startSizeZ = (slotData.aquariumFishID - 1) * zMoveRatio * tankSize.z;
var position = GetRandomPositionAndRotation(startSizeZ);
var rot = Random.rotation;
for (int i = 0; i < count; i++)
{
var go = Instantiate(fishPrefab, position + Random.onUnitSphere, rot, transform);
go.SetActive(true);
go.name = $"fish{groupId}_{i}";
var movement = go.GetComponent<FishMovement>();
movement.index = i;
movement.groupId = groupId;
float mutantScale = 1;
if (i < slotData.mutants)
{
mutantScale = tables.TbFishMutant.AquariumScale[fishData.Quality - 1];
}
go.transform.localScale = Vector3.one * fishData.AquariumMinScale * mutantScale;
movement.Init(this, slotData, startSizeZ, fishData, mutantScale);
fishGroup.Add(movement);
allFish.Add(movement);
}
LoadFish(fishGroup, mutantMaterial, fxLeftEye, fxRightEye);
}
async void LoadFish(List<FishMovement> fishMovements, Material mutantMaterial, GameObject fxLeftEye, GameObject fxRightEye)
{
for (int i = 0; i < fishMovements.Count; i++)
{
if (fishMovements[i] == null || fishMovements[i].isResult)
{
return;
}
await fishMovements[i].LoadFish(mutantMaterial, fxLeftEye, fxRightEye);
}
}
private Vector3 GetRandomPositionAndRotation(float startSizeZ)
{
var HalfSize = tankSize / 2;
var pos = new Vector3(
x: UnityEngine.Random.Range(-HalfSize.x, HalfSize.x),
y: UnityEngine.Random.Range(-HalfSize.y, HalfSize.y) / 2,
z: UnityEngine.Random.Range(-HalfSize.z, HalfSize.z));
pos += tankCenter;
pos.z += startSizeZ;
return pos;
}
public void RemoveFish(int groupId)
{
if (!_fishGroups.TryGetValue(groupId, out List<FishMovement> fishGroup))
{
return;
}
if (fishGroup.Count > 0)
{
for (int i = 0; i < fishGroup.Count; i++)
{
Destroy(fishGroup[i].gameObject);
allFish.Remove(fishGroup[i]);
}
}
_fishGroups.Remove(groupId);
}
public void SetFishScale(int groupId, float scale, int mutants, float aquariumScale)
{
if (!_fishGroups.TryGetValue(groupId, out List<FishMovement> fishGroup))
{
return;
}
if (fishGroup.Count > 0)
{
for (int i = 0; i < fishGroup.Count; i++)
{
if (i < mutants)
{
fishGroup[i].transform.localScale = Vector3.one * scale * aquariumScale;
}
else
{
fishGroup[i].transform.localScale = Vector3.one * scale;
}
}
}
}
public FishMovement GetFish(int groupId)
{
if (!_fishGroups.TryGetValue(groupId, out List<FishMovement> fishGroup))
{
return null;
}
if (fishGroup.Count > 0)
{
return fishGroup[0];
}
return null;
}
public void AllEscape()
{
for (int i = 0; i < allFish.Count; i++)
{
allFish[i].AllEscape();
}
}
#if UNITY_EDITOR
private void OnDrawGizmos()
{
_tankCenter = transform.position;
Gizmos.color = Color.cyan;
// Gizmos.DrawCube(_tankCenter, tankSize);
var halfSize = tankSize / 2;
// Define the 8 vertices of the cube
var vertices = new Vector3[8]
{
_tankCenter + new Vector3(-halfSize.x, -halfSize.y, -halfSize.z),
_tankCenter + new Vector3(halfSize.x, -halfSize.y, -halfSize.z),
_tankCenter + new Vector3(halfSize.x, -halfSize.y, halfSize.z),
_tankCenter + new Vector3(-halfSize.x, -halfSize.y, halfSize.z),
_tankCenter + new Vector3(-halfSize.x, halfSize.y, -halfSize.z),
_tankCenter + new Vector3(halfSize.x, halfSize.y, -halfSize.z),
_tankCenter + new Vector3(halfSize.x, halfSize.y, halfSize.z),
_tankCenter + new Vector3(-halfSize.x, halfSize.y, halfSize.z)
};
// Draw bottom square
Gizmos.DrawLine(vertices[0], vertices[1]);
Gizmos.DrawLine(vertices[1], vertices[2]);
Gizmos.DrawLine(vertices[2], vertices[3]);
Gizmos.DrawLine(vertices[3], vertices[0]);
// Draw top square
Gizmos.DrawLine(vertices[4], vertices[5]);
Gizmos.DrawLine(vertices[5], vertices[6]);
Gizmos.DrawLine(vertices[6], vertices[7]);
Gizmos.DrawLine(vertices[7], vertices[4]);
// Draw vertical edges
Gizmos.DrawLine(vertices[0], vertices[4]);
Gizmos.DrawLine(vertices[1], vertices[5]);
Gizmos.DrawLine(vertices[2], vertices[6]);
Gizmos.DrawLine(vertices[3], vertices[7]);
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ebf1294747a3c53458d79902e35db7dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,482 @@
using asap.core;
using cfg;
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.AddressableAssets;
public class FishMovement : AquariumFishBase
{
[SerializeField] private Rigidbody rb;
private Vector3 Orientation => transform.rotation * Vector3.forward;
public int index = 0, groupId = -1;
public Rigidbody Rb => rb;
FishManager fishManager;
GameObject goPrefab;
float startSizeZ = 0;
float avoidRadius = 0;
float maxPitchAngle = 30f;
GameObject leftEye;
GameObject rightEye;
public float AvoidRadius => avoidRadius * transform.localScale.x;
public Vector3 targetPos;
public Transform fishPos;
GameObject fishUnDownloadAlter;
public FishData fishData;
public Fish fish;
List<Collider> colliders = new List<Collider>();
//public int triggerCount;
public bool isResult;
public float mutantScale;
float loadTime;
float startLoadTime;
public void Init(FishManager fishManager, AquariumSlotData slotData, float startSizeZ, FishData fishData, float mutantScale)
{
this.mutantScale = mutantScale;
this.slotData = slotData;
this.fishData = fishData;
this.fishManager = fishManager;
this.startSizeZ = startSizeZ;
rb.velocity = rb.rotation * Vector3.forward;
LoadFishUnDownloadAlter(fishData.Quality - 1);
startLoadTime = Time.time;
}
public void RemoveEye()
{
if (leftEye != null)
{
DestroyImmediate(leftEye);
}
if (rightEye != null)
{
DestroyImmediate(rightEye);
}
}
void LoadFishUnDownloadAlter(int quality)
{
if (fishManager.fishUnDownloadAlter != null && fishManager.fishUnDownloadAlter.ContainsKey(quality))
{
fishUnDownloadAlter = Instantiate(fishManager.fishUnDownloadAlter[quality], transform);
fish = fishUnDownloadAlter.GetComponent<Fish>();
fish.animator.transform.localPosition = Vector3.zero;
fish.EnableCollider();
avoidRadius = fish.GetColliderSize(fishManager.avoidRadius);
fishUnDownloadAlter.transform.localPosition = Vector3.zero;
fishUnDownloadAlter.transform.localEulerAngles = Vector3.up * 180;
fishUnDownloadAlter.transform.localScale = Vector3.one;
fishUnDownloadAlter.name = $"{fishUnDownloadAlter.name}_{index}";
}
}
public async Task LoadFish(Material mutantMaterial, GameObject fxLeftEye, GameObject fxRightEye)
{
goPrefab = await Addressables.InstantiateAsync(fishData.Fbx, transform).Task;
loadTime = Time.time - startLoadTime;
if (rb == null || isResult || loadTime > fishManager.MaxLoadTime)
{
Debug.LogWarning($"LoadFish TimeOut:{loadTime} {fishData.Fbx}");
Addressables.ReleaseInstance(goPrefab);
goPrefab = null;
}
else if (goPrefab != null)
{
//Destroy(fishUnDownloadAlter);
//fishUnDownloadAlter = null;
if (fishUnDownloadAlter != null)
{
fishUnDownloadAlter.SetActive(false);
}
fish = goPrefab.GetComponent<Fish>();
fish.animator.transform.localPosition = Vector3.zero;
fish.EnableCollider();
fish.animator.Play("Swim01", 0, UnityEngine.Random.Range(0, 0.8f));
avoidRadius = fish.GetColliderSize(fishManager.avoidRadius);
goPrefab.transform.localPosition = Vector3.zero;
goPrefab.transform.localEulerAngles = Vector3.up * 180;
goPrefab.transform.localScale = Vector3.one;
goPrefab.name = $"{fishData.Fbx}_{index}";
if (slotData.mutants <= index)
{
return;
}
var _tables = GContext.container.Resolve<Tables>();
float eyeScale = _tables.TbFishMutant.FxAquariumScale[fishData.Quality - 1];
if (fish.LeftEye != null && fxLeftEye != null)
{
leftEye = Instantiate(fxLeftEye);
leftEye.transform.localScale = Vector3.one * eyeScale;
leftEye.transform.parent = fish.LeftEye;
leftEye.transform.localPosition = Vector3.zero;
leftEye.transform.localRotation = Quaternion.identity;
}
if (fish.RightEye != null && fxRightEye != null)
{
rightEye = Instantiate(fxRightEye);
rightEye.transform.localScale = Vector3.one * eyeScale;
rightEye.transform.parent = fish.RightEye;
rightEye.transform.localPosition = Vector3.zero;
rightEye.transform.localRotation = Quaternion.identity;
}
Renderer[] meshRenderer = goPrefab.GetComponentsInChildren<Renderer>();
if (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(mutantMaterial);
material_P.SetTexture("_BaseMap", material.GetTexture("_BaseMap"));
material_P.SetTexture("_BumpMap", material.GetTexture("_BumpMap"));
materials[i] = material_P;
}
render.materials = materials;
}
}
}
public void OnShoot(bool isRob, float speed, float time, Vector3 reasonableCenter, Vector3 reasonableLocation, float reasonableDistance)
{
rb.isKinematic = true;
isResult = true;
var pos = transform.position;
var startPos = Vector3.zero;
startPos.z = UnityEngine.Random.Range(-reasonableLocation.z, reasonableLocation.z);
if (pos.x > fishManager.tankCenter.x)
{
startPos.x = UnityEngine.Random.Range(0, reasonableLocation.x);
}
else
{
startPos.x = UnityEngine.Random.Range(-reasonableLocation.x, 0);
}
if (pos.y > fishManager.tankCenter.y)
{
startPos.y = UnityEngine.Random.Range(0, reasonableLocation.y);
}
else
{
startPos.y = UnityEngine.Random.Range(-reasonableLocation.y, 0);
}
transform.position = startPos + reasonableCenter;
targetPos = startPos + reasonableCenter + rb.rotation * Vector3.forward * reasonableDistance;
float l = speed * time;
float t = l / (targetPos - transform.position).magnitude;
if (t < 1)
{
targetPos = Vector3.Lerp(transform.position, targetPos, t);
}
//转弯
//Quaternion rotation1 = Quaternion.LookRotation(targetPos - transform.position);
//transform.DORotateQuaternion(rotation1, time * 0.8f);
// Move the fish along the path
transform.DOMove(targetPos, time).SetEase(Ease.Linear);
SetTargetPos(isRob);
}
void SetTargetPos(bool isRob)
{
fishPos = fish.mouthPos;
if (!isRob)
{
int i = UnityEngine.Random.Range(0, 3);
if (i == 0)
{
fishPos = fish.Fin;
}
else if (i == 1)
{
fishPos = fish.Neck;
}
else if (i == 2)
{
fishPos = fish.Tail;
}
}
if (fishPos != null)
{
targetPos += fishPos.position - transform.position;
}
}
public void AllEscape()
{
if (!isResult)
{
rb.isKinematic = true;
isResult = true;
var ta = transform.position + rb.rotation * Vector3.forward * 50;
transform.DOMove(ta, 3).OnComplete(() => fish.gameObject.SetActive(false)).SetEase(Ease.Linear);
}
}
public void SetFishSpeed(float speed, float time)
{
if (fish != null)
{
float curSpeed = speed;
DOTween.To(() => speed, x => curSpeed = x, 1f, time).OnUpdate(() =>
{
fish.FishAnimSpeed = curSpeed;
});
}
}
public void Shock(float distance, float time, AnimationCurve shockCurve)
{
transform.DOMoveZ(transform.position.z + distance, time).SetEase(shockCurve);
}
public void Capture(float minSpeed, float maxSpeed, float addRotation, float addRotationPeriod)
{
fish.FishAnimSpeed = UnityEngine.Random.Range(minSpeed, maxSpeed);
//鱼的朝向y轴 增加 rotation
float add = UnityEngine.Random.Range(-addRotation, addRotation);
Quaternion rotation = Quaternion.AngleAxis(add, Vector3.up);
rb.rotation = rb.rotation * rotation; //rb.transform.forward;
StartCoroutine(AddRotation(addRotation, addRotationPeriod));
}
IEnumerator AddRotation(float addRotation, float addRotationPeriod)
{
Quaternion startRotation = rb.rotation;
while (enabled)
{
float add = UnityEngine.Random.Range(-addRotation, addRotation);
Quaternion rotation = Quaternion.AngleAxis(add, Vector3.up);
//rb.rotation = startRotation * rotation; //rb.transform.forward;
transform.DORotateQuaternion(startRotation * rotation, addRotationPeriod);
yield return new WaitForSeconds(addRotationPeriod);
}
}
public void Escape(float distance, float duration)
{
transform.DOKill();
rb.isKinematic = true;
isResult = true;
var ta = transform.position + rb.rotation * Vector3.forward * distance;
transform.DOMove(ta, duration).OnComplete(() => fish.gameObject.SetActive(false)).SetEase(Ease.InSine);
}
public void OnShooted(bool isRob)
{
if (fish != null)
{
fish.animator.SetInteger("HurtIndex", isRob ? 2 : 1);
fish.animator.SetTrigger("Hurt");
}
rb.isKinematic = true;
isResult = true;
}
private void OnTriggerEnter(Collider other)
{
colliders.Add(other);
}
private void OnTriggerExit(Collider other)
{
colliders.Remove(other);
}
private Vector3 _dv = Vector3.zero;
private Vector3 _lastDv = Vector3.zero;
private void FixedUpdate()
{
if (fishManager == null || isResult)
{
return;
}
var s = fishManager.tankSize / 2;
float offsetX = fishManager.tankCenter.x;
float offsetY = fishManager.tankCenter.y;
float offsetZ = fishManager.tankCenter.z + startSizeZ;
//区域外
_dv = Vector3.zero;
// Area Constraint
if (rb.position.x > s.x + offsetX)
{
_dv += Vector3.left * (rb.position.x - s.x - offsetX);
}
else if (rb.position.x < -s.x + offsetX)
{
_dv += Vector3.right * (-s.x + offsetX - rb.position.x);
}
if (rb.position.y > s.y + offsetY)
{
_dv += Vector3.down * (rb.position.y - s.y - offsetY);
}
else if (rb.position.y < -s.y + offsetY)
{
_dv += Vector3.up * (-s.y + offsetY - rb.position.y);
}
if (rb.position.z > s.z + offsetZ)
{
_dv += Vector3.back * (rb.position.z - s.z - offsetZ);
}
else if (rb.position.z < -s.z + offsetZ)
{
_dv += Vector3.forward * (-s.z + offsetZ - rb.position.z);
}
_dv *= fishManager.areaConstrain;
// Boids Constraint
var colliderCount = fishManager.allFish.Count;
// var flockMates = new List<Rigidbody>();
var alignVelocity = Vector3.zero;
var avoidPosition = Vector3.zero;
var coherePosition = Vector3.zero;
int alignBoidCount = 0, avoidBoidCount = 0, cohereBoidCount = 0;
for (int i = colliders.Count - 1; i >= 0; i--)
{
if (colliders[i] == null)
{
colliders.RemoveAt(i);
continue;
}
Transform obstacleTransform = colliders[i].transform;
var fromToVector = obstacleTransform.position - transform.position;
var distance = fromToVector.magnitude;
_dv -= fromToVector.normalized / distance * fishManager.trigger;
}
for (int i = 0; i < fishManager.obstacleGo.Count; i++)
{
Transform obstacleTransform = fishManager.obstacleGo[i].transform;
Vector3 localScale = obstacleTransform.localScale / 2;
Vector3 localPos = obstacleTransform.position;
if (transform.position.x < localPos.x - localScale.x)
{
localPos.x -= localScale.x;
}
else if (transform.position.x > localPos.x + localScale.x)
{
localPos.x += localScale.x;
}
if (transform.position.y < localPos.y - localScale.y)
{
localPos.y -= localScale.y;
}
else if (transform.position.y > localPos.y + localScale.y)
{
localPos.y += localScale.y;
}
if (transform.position.z < localPos.z - localScale.z)
{
localPos.z -= localScale.z;
}
else if (transform.position.z > localPos.z + localScale.z)
{
localPos.z += localScale.z;
}
var fromToVector = localPos - transform.position;
var distance = fromToVector.magnitude;
// Obstacle has a higher weight than other boids
if (distance <= fishManager.obstacleDetectionRadius)
{
_dv -= fromToVector.normalized / distance * fishManager.obstacle;
}
}
for (int i = 0; i < colliderCount; i++)
{
var flockMate = fishManager.allFish[i];
var fromToVector = fishManager.allFish[i].transform.position - transform.position;
var distance = fromToVector.magnitude;
if (fishManager.allFish[i].gameObject.name == gameObject.name || flockMate is null)
continue;
if (flockMate.groupId == groupId && distance <= fishManager.alignRadius)
{
alignBoidCount++;
alignVelocity += flockMate.Rb.velocity;
}
if (flockMate.fishData.Quality >= fishData.Quality
&& distance <= (AvoidRadius + flockMate.AvoidRadius))
// && ((triggerCount > 0 && flockMate.groupId == groupId) || flockMate.groupId != groupId)
//)
{
avoidBoidCount++;
avoidPosition += flockMate.Rb.position;
}
if (flockMate.groupId == groupId)
{
cohereBoidCount++;
coherePosition += flockMate.Rb.position;
}
}
if (avoidBoidCount > 0)
_dv += (rb.position - avoidPosition / avoidBoidCount) * fishManager.avoidance;
if (alignBoidCount > 0)
_dv += (alignVelocity / alignBoidCount - rb.velocity) * fishManager.alignment;
if (cohereBoidCount > 0)
_dv += (coherePosition / cohereBoidCount - rb.position) * fishManager.cohesion;
_dv = Vector3.Lerp(_lastDv, _dv, math.saturate(fishManager.dvLerp));
_lastDv = _dv;
var targetVelocity = rb.velocity + _dv * Time.fixedDeltaTime;
var newVelocity = Vector3.RotateTowards(rb.transform.forward * rb.velocity.magnitude, targetVelocity, fishManager.angularAcc,
fishManager.magnitudeAcc);
//仰角限制
float maxPitchAngle = 30f;
float maxY = Mathf.Sin(maxPitchAngle * Mathf.Deg2Rad) * newVelocity.magnitude;
newVelocity.y = Mathf.Clamp(newVelocity.y, -maxY, maxY);
if (newVelocity.magnitude < 0.001)
{
return;
}
rb.rotation = Quaternion.LookRotation(newVelocity);
newVelocity = Vector3.RotateTowards(newVelocity, targetVelocity, fishManager.angularAcc,
fishManager.magnitudeAcc);
maxY = Mathf.Sin(maxPitchAngle * Mathf.Deg2Rad) * newVelocity.magnitude;
newVelocity.y = Mathf.Clamp(newVelocity.y, -maxY, maxY);
float angle = Vector3.Angle(rb.velocity, targetVelocity);
newVelocity *= 1 - (angle / 185);
rb.velocity = newVelocity;
//Max-Min Constraint
if (rb.velocity.magnitude > fishManager.maxVel)
rb.velocity = rb.velocity.normalized * fishManager.maxVel;
else if (rb.velocity.magnitude < fishManager.minVel)
rb.velocity = rb.velocity.normalized * fishManager.minVel;
}
private void OnDestroy()
{
if (goPrefab != null)
{
Addressables.ReleaseInstance(goPrefab);
goPrefab = null;
}
}
private void OnDrawGizmosSelected()
{
// Display the explosion radius when selected
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, AvoidRadius);
Gizmos.color = Color.blue;
Gizmos.DrawLine(transform.position, transform.position + _dv * (5 * Time.fixedDeltaTime));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6e7c78a74fd0f644a8902ed80899c1f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,483 @@
using asap.core;
using System.Threading.Tasks;
using UniRx;
using UnityEngine.AddressableAssets;
using GameCore;
using UnityEngine;
using System.Collections.Generic;
using cfg;
using System;
using System.Collections;
public struct AquariumEnterMapScene
{
public bool isShowUI;
}
public struct EnterMaped
{
}
public struct ChangeFishEvent
{
public List<int> addFish;
public List<int> removeFish;
}
public class FishingAquariumAct : AGameAct
{
/// <summary>
/// 1 == 进匹配 2 == 退出匹配 3 == 进水族馆 4 == 退出水族馆 5 == 退到匹配
/// </summary>
public static int CloudType = 0;
AquariumManager AM;
CompositeDisposable disposables;
GameObject aquarium;
GameObject _light;
AquariumFishController aquariumFishController;
cfg.Tables _tables;
AquariumInit aquariumInit;
Material mutantMaterial;
GameObject fxLeftEye;
GameObject fxRightEye;
AquariumPanel aquariumPanel;
Dictionary<int, GameObject> fishUnDownloadAlter = new Dictionary<int, GameObject>();
public static EventAggregator eventAggregator;
public override async Task<bool> StartAsync()
{
eventAggregator = new EventAggregator();
_tables = GContext.container.Resolve<cfg.Tables>();
aquariumInit = _tables.TbAquariumInit.DataList[0];
disposables = new CompositeDisposable();
GContext.container.Unregister<AquariumManager>();
GContext.container.Unregister<FishingData>();
var fishingData = new FishingData();
GContext.container.RegisterInstance(fishingData);
AM = new AquariumManager();
await AM.Synchrodata();
GContext.container.RegisterInstance(AM);
eventAggregator.GetEvent<AquariumEnterMapScene>().Subscribe(OnEnterMapScene).AddTo(disposables);
eventAggregator.GetEvent<ChangeFishEvent>().Subscribe(OnChangeFishEvent).AddTo(disposables);
disposables.Add(GContext.OnEvent<InGradeAquariumEvent>().Subscribe(OnInAquariumEnevt));
// 加载场景
GContext.Publish(new HideHomePanelEvent());
mutantMaterial = await Addressables.LoadAssetAsync<Material>(_tables.TbFishMutant.Material).Task;
fxLeftEye = await Addressables.LoadAssetAsync<GameObject>(_tables.TbFishMutant.FxLeftEye).Task;
fxRightEye = await Addressables.LoadAssetAsync<GameObject>(_tables.TbFishMutant.FxRightEye).Task;
if (AM.data.isHome || AM.data.slotDatas == null)
{
await EnterStartScene();
}
else
{
await EnterMapScene();
await Awaiters.Seconds(1);
ShowAquariumPanel();
}
return await base.StartAsync();
}
async void ShowAquariumPanel()
{
GameObject go = await UIManager.Instance.ShowUILoad(UITypes.AquariumPanel);
aquariumPanel = go.GetComponent<AquariumPanel>();
aquariumPanel.Init(this);
_ = StartCoroutine(StartTime());
aquariumFishController.cameraManager.MoveCamera();
}
async Task EnterStartScene()
{
await LoadScene();
await UIManager.Instance.ShowUILoad(UITypes.AquariumDetectPanel);
}
/// <summary>
/// 提前加载地图之后加载UI
/// </summary>
/// <returns></returns>
async Task EnterMapScene()
{
List<AquariumSlotData> slotDatas = AM.data.slotDatas;
for (int i = 0; i < AM.data.slot; i++)
{
AquariumSlotData slotData = slotDatas[i];
Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID);
if (!fishUnDownloadAlter.ContainsKey(item.Quality - 1))
{
int id = _tables.GetItemData(_tables.TbGlobalConfig.FishUnDownloadAlter[item.Quality - 1]).RedirectID;
FishData fishData = _tables.TbFishData.GetOrDefault(id);
fishUnDownloadAlter[item.Quality - 1] = await Addressables.LoadAssetAsync<GameObject>(fishData.Fbx).Task;
}
}
await LoadScene();
InitFish();
}
async Task LoadScene()
{
ReleaseAquarium();
var mapData = _tables.TbMapData.DataMap[AM.MapId];
string prefabName = mapData.AquariumPrefab;
aquarium = await Addressables.InstantiateAsync(prefabName).Task;
if (disposables == null)
{
ReleaseAquarium();
return;
}
aquariumFishController = aquarium.GetComponent<AquariumFishController>();
aquariumFishController.fishManager.MaxLoadTime = 50;
aquariumFishController.cameraManager.PlayAquarium(this);
}
async void OnEnterMapScene(AquariumEnterMapScene aem)
{
if (aem.isShowUI)
{
ShowAquariumPanel();
}
else if (AM.data.isHome || AM.data.slotDatas == null)
{
CloudType = 5;
await UIManager.Instance.ShowUINotLoading(UITypes.AquariumCloudPanel);
await Awaiters.Seconds(0.75f);
await EnterStartScene();
UIManager.Instance.DestroyUI(UITypes.AquariumReportPopupPanel);
aquariumPanel = null;
UIManager.Instance.DestroyUI(UITypes.AquariumPanel);
GContext.Publish(new EndTransition());
}
else
{
await EnterMapScene();
eventAggregator.Publish(new EnterMaped());
}
}
void OnChangeFishEvent(ChangeFishEvent e)
{
List<int> removeFish = e.removeFish;
if (removeFish != null && removeFish.Count > 0)
{
for (int i = 0; i < removeFish.Count; i++)
{
aquariumFishController.fishManager.RemoveFish(removeFish[i]);
}
}
List<int> addFish = e.addFish;
if (addFish != null && addFish.Count > 0)
{
List<AquariumSlotData> slotDatas = AM.data.slotDatas;
List<AquariumResultData> aquariumResultDatas = AM.data.aquariumResultDatas;
for (int i = 0; i < addFish.Count; i++)
{
//当蛋孵化时添加鱼
int index = addFish[i];
AquariumSlotData slotData = slotDatas[index];
var time = ZZTimeHelper.UtcNow();
if (slotData.FishHatchTime() < time && !slotData.IsResult() && !aquariumResultDatas[index].IsResult())
{
EggToFish(slotData, index);
}
}
}
}
/// <summary>
///蛋孵化 添加鱼
/// </summary>
/// <param name="slotData"></param>
/// <param name="index"></param>
void EggToFish(AquariumSlotData slotData, int index)
{
aquariumFishController.fishEggManager.RemoveEgg(index);
AddFish(slotData, index, slotData.fishMQ);
}
void OnInAquariumEnevt(InGradeAquariumEvent e)
{
Debug.Log("OnInAquariumEnevt");
if (aquarium != null)
{
aquarium.SetActive(e.type == 1);
}
}
void InitFish()
{
List<AquariumSlotData> slotDatas = AM.data.slotDatas;
if (slotDatas == null)
{
return;
}
aquariumFishController.fishManager.fishUnDownloadAlter = fishUnDownloadAlter;
var time = ZZTimeHelper.UtcNow();
List<AquariumResultData> aquariumResultDatas = AM.data.aquariumResultDatas;
for (int i = 0; i < AM.data.slot; i++)
{
AquariumSlotData slotData = slotDatas[i];
slotData.index = i;
var HatchTime = slotData.FishHatchTime();
if (HatchTime < time)
{
if (!slotData.IsResult() && !aquariumResultDatas[i].IsResult())
{
//检查是否受伤
//正常的成长时间 自然时间+加速成长-总恢复时间
float normalH = (float)(time - HatchTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
float injuryH = slotData.injuryGrowthTime;
int fishQ = slotData.fishMQ;
if (injuryH < normalH)
{
AM.data.aquariumHurtDatas[i].fishLQ = 0;
}
else
{
fishQ -= AM.data.aquariumHurtDatas[i].fishLQ;
if (fishQ <= 0)
{
fishQ = 1;
}
}
AddFish(slotData, i, fishQ);
}
}
else
{
//初始化蛋
aquariumFishController.fishEggManager.AddEgg(slotData);
}
}
}
IEnumerator StartTime()
{
List<AquariumSlotData> slotDatas = AM.data.slotDatas;
List<AquariumResultData> aquariumResultDatas = AM.data.aquariumResultDatas;
for (int i = 0; i < AM.Slot; i++)
{
if (!aquariumResultDatas[i].IsResult() && !slotDatas[i].IsResult())
{
SetFishScale(slotDatas[i], i);
}
}
while (aquariumPanel != null)
{
DateTime dateTime = ZZTimeHelper.UtcNow();
aquariumPanel.OnUpdate(dateTime);
for (int i = 0; i < AM.Slot; i++)
{
if (!aquariumResultDatas[i].IsResult() && !slotDatas[i].IsResult() && slotDatas[i].FishGrowthTime() > dateTime)
{
SetFishScale(slotDatas[i], i);
}
}
yield return Awaiters.Seconds(1);
}
}
/// <summary>
/// 加载鱼的模型
/// </summary>
/// <param name="aquariumSlotData"></param>
/// <param name="index"></param>
void AddFish(AquariumSlotData aquariumSlotData, int index, int count)
{
aquariumFishController.fishManager.AddFish(
mutantMaterial, fxLeftEye, fxRightEye,
aquariumSlotData, count, index);
}
GameObject reportPrefab;
int reportIndex;
public async Task<GameObject> LoadFish(int index, Transform fishParent)
{
reportIndex = index;
AquariumSlotData slotData = AM.data.slotDatas[index];
Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID);
var fishData = _tables.TbFishData.GetOrDefault(item.RedirectID);
if (reportPrefab != null)
{
Addressables.ReleaseInstance(reportPrefab);
reportPrefab = null;
}
var Prefab = await Addressables.InstantiateAsync(fishData.Fbx, fishParent).Task;
if (fishParent == null || reportIndex != index)
{
Addressables.ReleaseInstance(Prefab);
Prefab = null;
return null;
}
else if (Prefab != null)
{
reportPrefab = Prefab;
var fish = reportPrefab.GetComponent<Fish>();
fish.animator.transform.localPosition = Vector3.zero;
fish.EnableCollider();
fish.animator.Play("Swim01", 0, UnityEngine.Random.Range(0, 0.8f));
fish.animator.transform.localPosition = Vector3.zero;
reportPrefab.transform.localPosition = Vector3.zero;
reportPrefab.transform.localScale = Vector3.one * fishData.TankScale;
var TankRotation = fishData.TankRotation;
reportPrefab.transform.localRotation = Quaternion.Euler(TankRotation[0], TankRotation[1], TankRotation[2]);
if (slotData.mutants <= 0 || mutantMaterial == null)
{
return reportPrefab;
}
float eyeScale = _tables.TbFishMutant.FxAquariumScale[fishData.Quality - 1];
if (fish.LeftEye != null && fxLeftEye != null)
{
var leftEye = Instantiate(fxLeftEye);
leftEye.transform.localScale = Vector3.one * eyeScale;
leftEye.transform.parent = fish.LeftEye;
leftEye.transform.localPosition = Vector3.zero;
leftEye.transform.localRotation = Quaternion.identity;
}
if (fish.RightEye != null && fxRightEye != null)
{
var rightEye = Instantiate(fxRightEye);
rightEye.transform.localScale = Vector3.one * eyeScale;
rightEye.transform.parent = fish.RightEye;
rightEye.transform.localPosition = Vector3.zero;
rightEye.transform.localRotation = Quaternion.identity;
}
Renderer[] meshRenderer = reportPrefab.GetComponentsInChildren<Renderer>();
if (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(mutantMaterial);
material_P.SetTexture("_BaseMap", material.GetTexture("_BaseMap"));
material_P.SetTexture("_BumpMap", material.GetTexture("_BumpMap"));
materials[i] = material_P;
}
render.materials = materials;
}
}
return reportPrefab;
}
/// <summary>
/// 刷新鱼的大小
/// </summary>
/// <param name="aquariumSlotData"></param>
/// <param name="index"></param>
void SetFishScale(AquariumSlotData slotData, int index)
{
var dateTime = ZZTimeHelper.UtcNow();
DateTime startTime = slotData.FishHatchTime();
float normalH = (float)(dateTime - startTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
float progress = normalH / slotData.growthTime;
if (progress > 1)
{
progress = 1;
}
Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID);
FishData fishData = _tables.TbFishData.GetOrDefault(item.RedirectID);
float scale = fishData.AquariumMinScale + (fishData.AquariumMaxScale - fishData.AquariumMinScale) * progress;
aquariumFishController.fishManager.SetFishScale(index, scale, slotData.mutants, _tables.TbFishMutant.AquariumScale[fishData.Quality - 1]);
}
void ReleaseAquarium()
{
if (aquarium != null)
{
Addressables.ReleaseInstance(aquarium);
aquarium = null;
}
}
public override async System.Threading.Tasks.Task StopAsync()
{
if (reportPrefab != null)
{
Addressables.ReleaseInstance(reportPrefab);
reportPrefab = null;
}
if (mutantMaterial != null)
{
Addressables.Release(mutantMaterial);
mutantMaterial = null;
}
if (fxLeftEye != null)
{
Addressables.Release(fxLeftEye);
fxLeftEye = null;
}
if (fxRightEye != null)
{
Addressables.Release(fxRightEye);
fxRightEye = null;
}
eventAggregator = null;
ReleaseAquarium();
if (fishUnDownloadAlter != null)
{
foreach (var item in fishUnDownloadAlter)
{
Addressables.Release(item.Value);
}
}
disposables?.Dispose();
disposables = null;
aquariumPanel = null;
UIManager.Instance.DestroyUI(UITypes.AquariumDetectPanel);
UIManager.Instance.DestroyUI(UITypes.AquariumPanel);
GContext.container.Unregister<AquariumManager>();
GContext.container.Unregister<FishingData>();
await base.StopAsync();
}
public void OnClickFish(int index)
{
aquariumPanel.OnClickFish(index);
}
#region UI操作
public bool CanDragMove()
{
return aquariumPanel != null && aquariumPanel.CanDragMove;
}
public void FollowFishCamera(AquariumSlotData slotData, bool isEgg)
{
if (isEgg)
{
var egg = aquariumFishController.fishEggManager.GetEgg(slotData.index);
aquariumFishController.cameraManager.FollowFishCamera(egg);
}
else
{
var fish = aquariumFishController.fishManager.GetFish(slotData.index);
aquariumFishController.cameraManager.FollowFishCamera(fish);
}
}
public void StopFollowFishCamera()
{
aquariumFishController.cameraManager.StopFollowFishCamera();
}
#endregion
protected override void OnDestroy()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7bd45b1df5e498d4580209241f65c6ee
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,552 @@
using asap.core;
using System.Threading.Tasks;
using UniRx;
using UnityEngine.AddressableAssets;
using UnityEngine;
using System.Collections.Generic;
using cfg;
using System;
using game;
using GameCore;
using System.Linq;
using DG.Tweening;
using System.Collections;
public class ShooterFishAct : AGameAct
{
AquariumShooterFishManager AM;
CompositeDisposable disposables;
GameObject aquarium;
cfg.Tables _tables;
AquariumInit aquariumInit;
Material mutantMaterial;
GameObject fxLeftEye;
GameObject fxRightEye;
AquariumFishController aquariumFishController;
Dictionary<int, GameObject> fishUnDownloadAlter = new Dictionary<int, GameObject>();
OpponentItemData localOpponentItemData;
FishMovement targetMovement;
EventFishHuntingPanel eventFishHuntingPanel;
bool shoot = false;
[Header("General Settings")]
public float[] FxScale;//不同品质的鱼的特效缩放大小
Dictionary<string, GameObject> fx_hunt_prefab = new Dictionary<string, GameObject>();
[Header("Aim Settings")]
public float AimCameraMoveDelay = 0.05f;//延迟这么久开始挪动相机
public float AimCameraMoveTime = 0.4f;//相机后续挪动时间,挪到位置后
public Vector3 AimCameraMovePos;//相机挪到这个位置
public AnimationCurve AimCameraMoveCurve = AnimationCurve.Linear(0, 1, 1, 1); //时间缩放曲线
float fieldOfView = 60;
[Header("Back Settings")]
public float BackShowDelay = 0.1f;//延迟这么久开始显示弩箭
public float BackCameraMoveTime = 0.25f;//相机后续挪动时间
public float AimBlockTime = 0.25f;//相机挪回去之后,在这段时间内禁止开镜射鱼
[Header("Shoot Settings")]
public float ShootTime = 1;
public float ShootDelay = 0.2f;//延迟这么久干掉弩箭模型
public float timeStartScale = 0.5f; //开始慢镜头时间
public float timeEndScale = 1f; //结束慢镜头时间
public AnimationCurve timeScaleCurve = AnimationCurve.Linear(0, 1, 1, 1); //时间缩放曲线
public Vector3 reasonableLocation;
public Vector3 reasonableCenter;
public float reasonableMinDistance = 2;
public float reasonableMaxDistance = 5;
public float[] shootSwimSpeed = new float[2] { 1.25f, 1.75f }; //射鱼时鱼的最小速度,最大速度
[Header("Escape Settings")]
public AnimationCurve EscapeShockCurve = AnimationCurve.Linear(0, 1, 1, 1); //在这段时间里,位移一个距离的受击位移曲线
public float[] EscapeShockTime;//不同品质的鱼的受击时间
public float[] EscapeShockDistance;//不同品质的鱼的受击距离
public float EscapeDelay = 0.5f;//鱼的Hurt01动画播放时间延迟这么久箭会脱落
public float EscapeDistance = 30;
public float EscapeDuration = 2;
public float EscapeAnimSpeed = 3;//鱼逃跑时动画播放的速度
public float EscapeAnimRecoverTime = 1.5f;//鱼逃跑时动画恢复的时间
public float escapeRewardUIDelay = 1.25f;//鱼开始游走算起多长时间出现结算UI
public float ArrowEscapeTime = 2;
[Header("Capture Settings")]
public AnimationCurve CaptureShockCurve = AnimationCurve.Linear(0, 1, 1, 1); //在这段时间里,位移一个距离的受击位移曲线
public float[] CaptureShockTime;//不同品质的鱼的受击时间
public float[] CaptureShockDistance;//不同品质的鱼的受击距离
public float CaptureDelay = 1.16f;//鱼的Hurt02动画播放时间延迟这么久往回拉
public float lineDrawSpeed = 4f;//每秒往回拉的距离
public float lineDrawMinTime = 1.25f;//最少也得拉这么长时间
public float fishAnimMinSpeed = 1.5f;
public float fishAnimMaxSpeed = 3;
public float addRotation = 15;
public float addRotationPeriod = 0.75f;//拉回时,每间隔这段时间,鱼会从-addRotation到+addRotation中随机一个值然后摆动过去
public float fishToCameraDistance = 1f;//额外的距离
public float fishDisappearDelay = 0.4f;//拉回来后,鱼延迟消失的时间
public override async Task<bool> StartAsync()
{
UIManager.Instance.DestroyUI(UITypes.EventGamePlayPanel);
_tables = GContext.container.Resolve<cfg.Tables>();
aquariumInit = _tables.TbAquariumInit.DataList[0];
disposables = new CompositeDisposable();
GContext.container.Unregister<AquariumShooterFishManager>();
AM = new AquariumShooterFishManager();
GContext.container.RegisterInstance(AM);
localOpponentItemData = GContext.container.Resolve<SmallGameData>().GetBankHeistOpponent(EnemyType.Aquarium);
List<FishHuntInit> huntInits = _tables.TbFishHuntInit.DataList;
if (GContext.container.Resolve<SmallGameData>().FishHuntGameCount < huntInits.Count && GContext.container.Resolve<LeadboardData>().fishingEvent == null)
{
FishHuntInit inti = huntInits[GContext.container.Resolve<SmallGameData>().FishHuntGameCount];
var itemDatas = GContext.container.Resolve<SmallGameData>().opponentItemDatas.Where(x => x.isRobot).ToList();
//机器人数据
localOpponentItemData = itemDatas[UnityEngine.Random.Range(0, itemDatas.Count)];
GContext.container.Resolve<SmallGameData>().opponentData = localOpponentItemData;
AM.GetDataFishHuntInit(localOpponentItemData.playFabID, inti);
}
else
{
await AM.GetData(localOpponentItemData.playFabID, localOpponentItemData.isRobot, false);
if (AM.serverData == null)
{
var itemDatas = GContext.container.Resolve<SmallGameData>().opponentItemDatas.Where(x => x.isRobot).ToList();
//机器人数据
localOpponentItemData = itemDatas[UnityEngine.Random.Range(0, itemDatas.Count)];
localOpponentItemData.target_group = GContext.container.Resolve<SmallGameData>().opponentData.target_group;
GContext.container.Resolve<SmallGameData>().opponentData = localOpponentItemData;
await AM.GetData(localOpponentItemData.playFabID, localOpponentItemData.isRobot, false);
}
}
GContext.OnEvent<ChangeSmallGameTargetEvent>().Subscribe(ChangeSmallGameTargetEvent).AddTo(disposables);
// 加载场景
mutantMaterial = await Addressables.LoadAssetAsync<Material>(_tables.TbFishMutant.Material).Task;
fxLeftEye = await Addressables.LoadAssetAsync<GameObject>(_tables.TbFishMutant.FxLeftEye).Task;
fxRightEye = await Addressables.LoadAssetAsync<GameObject>(_tables.TbFishMutant.FxRightEye).Task;
await LoadFX();
await EnterMapScene();
return await base.StartAsync();
}
async Task LoadFX()
{
///fx_aquarium_hunt_shoot
///fx_aquarium_hunt_fishhitbig
///fx_aquarium_hunt_fishhitsmall
///fx_aquarium_hunt_fishhurt
///fx_aquarium_hunt_escape
///fx_aquarium_hunt_capture
GameObject fx_aquarium_hunt_shoot = await Addressables.LoadAssetAsync<GameObject>("fx_aquarium_hunt_shoot").Task;
if (fx_aquarium_hunt_shoot != null)
{
fx_hunt_prefab["fx_aquarium_hunt_shoot"] = fx_aquarium_hunt_shoot;
}
GameObject fx_aquarium_hunt_fishhitbig = await Addressables.LoadAssetAsync<GameObject>("fx_aquarium_hunt_fishhitbig").Task;
if (fx_aquarium_hunt_fishhitbig != null)
{
fx_hunt_prefab["fx_aquarium_hunt_fishhitbig"] = fx_aquarium_hunt_fishhitbig;
}
GameObject fx_aquarium_hunt_fishhitsmall = await Addressables.LoadAssetAsync<GameObject>("fx_aquarium_hunt_fishhitsmall").Task;
if (fx_aquarium_hunt_fishhitsmall != null)
{
fx_hunt_prefab["fx_aquarium_hunt_fishhitsmall"] = fx_aquarium_hunt_fishhitsmall;
}
GameObject fx_aquarium_hunt_fishhurt = await Addressables.LoadAssetAsync<GameObject>("fx_aquarium_hunt_fishhurt").Task;
if (fx_aquarium_hunt_fishhurt != null)
{
fx_hunt_prefab["fx_aquarium_hunt_fishhurt"] = fx_aquarium_hunt_fishhurt;
}
GameObject fx_aquarium_hunt_escape = await Addressables.LoadAssetAsync<GameObject>("fx_aquarium_hunt_escape").Task;
if (fx_aquarium_hunt_escape != null)
{
fx_hunt_prefab["fx_aquarium_hunt_escape"] = fx_aquarium_hunt_escape;
}
GameObject fx_aquarium_hunt_capture = await Addressables.LoadAssetAsync<GameObject>("fx_aquarium_hunt_capture").Task;
if (fx_aquarium_hunt_capture != null)
{
fx_hunt_prefab["fx_aquarium_hunt_capture"] = fx_aquarium_hunt_capture;
}
}
public async void ChangeSmallGameTargetEvent(ChangeSmallGameTargetEvent changeSmallGameTargetEvent)
{
await UIManager.Instance.ShowUI(UITypes.CloudTransitionPanel);
OpponentItemData opponentItemData = changeSmallGameTargetEvent.opponentItemData;
AquariumServerData data = await AM.GetData(opponentItemData.playFabID, opponentItemData.isRobot, !changeSmallGameTargetEvent.random);
if (data == null)
{
var itemDatas = GContext.container.Resolve<SmallGameData>().opponentItemDatas.Where(x => x.isRobot).ToList();
//机器人数据
opponentItemData = itemDatas[UnityEngine.Random.Range(0, itemDatas.Count)];
opponentItemData.target_group = GContext.container.Resolve<SmallGameData>().opponentData.target_group;
GContext.container.Resolve<SmallGameData>().opponentData = opponentItemData;
data = await AM.GetData(opponentItemData.playFabID, opponentItemData.isRobot, false);
}
await Task.Delay(500);
if (data != null)
{
changeSmallGameTargetEvent.opponentItemData = opponentItemData;
localOpponentItemData = opponentItemData;
//机器人数据
if (aquarium != null)
{
Addressables.ReleaseInstance(aquarium);
aquarium = null;
}
await EnterMapScene();
}
else
{
GContext.container.Resolve<SmallGameData>().opponentData = localOpponentItemData;
}
changeSmallGameTargetEvent.ts.SetResult(data != null);
GContext.Publish(new EndTransition());
}
async Task EnterMapScene()
{
List<AquariumSlotData> slotDatas = AM.serverData.slotDatas;
for (int i = 0; i < slotDatas.Count; i++)
{
AquariumSlotData slotData = slotDatas[i];
Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID);
if (!fishUnDownloadAlter.ContainsKey(item.Quality - 1))
{
int id = _tables.GetItemData(_tables.TbGlobalConfig.FishUnDownloadAlter[item.Quality - 1]).RedirectID;
FishData fishData = _tables.TbFishData.GetOrDefault(id);
fishUnDownloadAlter[item.Quality - 1] = await Addressables.LoadAssetAsync<GameObject>(fishData.Fbx).Task;
}
}
await LoadScene();
Debug.Log($"EnterMap OpponentData playerID {localOpponentItemData.playFabID}");
InitFish();
await Awaiters.Seconds(1);
StartTime();
ShowCrossbowLow();
}
async void ShowCrossbowLow()
{
await Awaiters.Seconds(0.5f);
GameObject panel = await UIManager.Instance.ShowUINotLoading(UITypes.EventFishHuntingPanel);
eventFishHuntingPanel = panel.GetComponent<EventFishHuntingPanel>();
eventFishHuntingPanel.shooterFishAct = this;
bool isGuide = GContext.container.Resolve<GuideDataCenter>().InspectTriggerGuide("EventFishHuntingPanel");
FishMovement guide = null;
if (isGuide && GContext.container.Resolve<GuideDataCenter>().curGroupDefine.groupName == GroupName.Raid)
{
guide = GetMutantFish();
}
aquariumFishController.cameraManager.PlayCrossbow(guide);
}
async Task LoadScene()
{
var mapData = _tables.TbMapData.DataMap[AM.MapId];
string prefabName = mapData.AquariumPrefab;
aquarium = await Addressables.InstantiateAsync(prefabName).Task;
aquariumFishController = aquarium.GetComponent<AquariumFishController>();
aquariumFishController.fishManager.MaxLoadTime = 0.5f;
}
void InitFish()
{
Debug.Log($"nextOpponent InitFish MapID {AM.serverData.mapId}");
List<AquariumSlotData> slotDatas = AM.serverData.slotDatas;
if (slotDatas == null)
{
return;
}
aquariumFishController.fishManager.fishUnDownloadAlter = fishUnDownloadAlter;
var time = ZZTimeHelper.UtcNow();
List<AquariumResultData> aquariumResultDatas = AM.serverData.aquariumResultDatas;
for (int i = 0; i < slotDatas.Count; i++)
{
AquariumSlotData slotData = slotDatas[i];
slotData.index = i;
var HatchTime = slotData.FishHatchTime();
if (HatchTime < time)
{
if (!slotData.IsResult() && !aquariumResultDatas[i].IsResult())
{
//检查是否受伤
//正常的成长时间 自然时间+加速成长-总恢复时间
float normalH = (float)(time - HatchTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
float injuryH = slotData.injuryGrowthTime;
int fishQ = slotData.fishMQ;
if (injuryH < normalH)
{
AM.serverData.aquariumHurtDatas[i].fishLQ = 0;
}
else
{
fishQ -= AM.serverData.aquariumHurtDatas[i].fishLQ;
if (fishQ <= 0)
{
fishQ = 1;
}
}
AddFish(slotData, i, fishQ);
}
}
//else
//{
// //初始化蛋
// aquariumFishController.fishEggManager.AddEgg(i, slotData.eggId);
//}
}
}
void StartTime()
{
List<AquariumSlotData> slotDatas = AM.serverData.slotDatas;
List<AquariumResultData> aquariumResultDatas = AM.serverData.aquariumResultDatas;
for (int i = 0; i < slotDatas.Count; i++)
{
if (!aquariumResultDatas[i].IsResult() && !slotDatas[i].IsResult())
{
SetFishScale(slotDatas[i], i);
}
}
}
/// <summary>
/// 加载鱼的模型
/// </summary>
/// <param name="aquariumSlotData"></param>
/// <param name="index"></param>
void AddFish(AquariumSlotData aquariumSlotData, int index, int count)
{
aquariumFishController.fishManager.AddFish(
mutantMaterial, fxLeftEye, fxRightEye,
aquariumSlotData,
count,
index);
}
FishMovement GetMutantFish()
{
List<AquariumSlotData> slotDatas = AM.serverData.slotDatas;
AquariumSlotData aquariumSlotData = null;
for (int i = 0; i < slotDatas.Count; i++)
{
aquariumSlotData = slotDatas[i];
if (aquariumSlotData.mutants > 0)
{
break;
}
}
return aquariumFishController.fishManager.GetFish(aquariumSlotData.index);
}
/// <summary>
/// 刷新鱼的大小
/// </summary>
/// <param name="aquariumSlotData"></param>
/// <param name="index"></param>
void SetFishScale(AquariumSlotData slotData, int index)
{
var dateTime = ZZTimeHelper.UtcNow();
DateTime startTime = slotData.FishHatchTime();
float normalH = (float)(dateTime - startTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
float progress = normalH / slotData.growthTime;
if (progress > 1)
{
progress = 1;
}
Item item = _tables.TbItem.GetOrDefault(slotData.fishItemID);
FishData fishData = _tables.TbFishData.GetOrDefault(item.RedirectID);
float scale = fishData.AquariumMinScale + (fishData.AquariumMaxScale - fishData.AquariumMinScale) * progress;
aquariumFishController.fishManager.SetFishScale(index, scale, slotData.mutants, _tables.TbFishMutant.AquariumScale[fishData.Quality - 1]);
}
public void OnTargetChange(FishMovement fish)
{
this.targetMovement = fish;
}
public IEnumerator AniCameraMove()
{
GContext.Publish(EShootState.Aim);
shoot = false;
aquariumFishController.cameraManager.TriggerCrossbow("Aim");
yield return new WaitForSeconds(AimCameraMoveDelay);
DOTween.Kill("FieldOfView");
aquariumFishController.cameraManager.cameraVirtual.transform.DOKill();
aquariumFishController.cameraManager.cameraVirtual.transform.DOLocalMove(AimCameraMovePos, AimCameraMoveTime)
.SetEase(AimCameraMoveCurve);
cfg.Crossbow crossBow = _tables.TbCrossbow.DataList[0];
float fov = aquariumFishController.cameraManager.cameraVirtual.m_Lens.FieldOfView;
DOTween.To(() => fov, x => fov = x, crossBow.AimFov, AimCameraMoveTime).OnUpdate(() =>
{
aquariumFishController.cameraManager.cameraVirtual.m_Lens.FieldOfView = fov;
}).SetId("FieldOfView");
yield return new WaitForSeconds(AimCameraMoveTime);
aquariumFishController.cameraManager.HideCrossbow(true);
shoot = true;
}
public IEnumerator OnBack()
{
shoot = false;
DOTween.Kill("FieldOfView");
aquariumFishController.cameraManager.cameraVirtual.transform.DOKill();
aquariumFishController.cameraManager.cameraVirtual.transform.DOLocalMove(Vector3.zero, BackCameraMoveTime);
float fov = aquariumFishController.cameraManager.cameraVirtual.m_Lens.FieldOfView;
DOTween.To(() => fov, x => fov = x, fieldOfView, AimCameraMoveTime).OnUpdate(() =>
{
aquariumFishController.cameraManager.cameraVirtual.m_Lens.FieldOfView = fov;
}).SetId("FieldOfView");
yield return new WaitForSeconds(BackShowDelay);
aquariumFishController.cameraManager.HideCrossbow(false);
GContext.Publish(EShootState.Back);
aquariumFishController.cameraManager.TriggerCrossbow("Back");
}
public FishMovement Target()
{
if (shoot)
{
bool hasTarget = targetMovement != null;
if (hasTarget)
{
aquariumFishController.cameraManager.Target();
//结算
targetMovement.fish.SetTrigger("Idle");
return targetMovement;
}
}
return null;
}
public async Task OnShoot(bool isRob)
{
aquariumFishController.cameraManager.TriggerCrossbow("Shoot");
GContext.Publish(EShootState.Shoot);
DOTween.Kill("FieldOfView");
///先操作鱼,获取终点
await Awaiters.Seconds(ShootDelay);
aquariumFishController.cameraManager.cameraVirtual.m_Lens.FieldOfView = fieldOfView;
float speed = UnityEngine.Random.Range(shootSwimSpeed[0], shootSwimSpeed[1]);
targetMovement.OnShoot(isRob, speed, ShootTime, reasonableCenter, reasonableLocation, UnityEngine.Random.Range(reasonableMinDistance, reasonableMaxDistance));
aquariumFishController.cameraManager.Shoot(FxScale, fx_hunt_prefab, isRob, ShootTime, targetMovement);
aquariumFishController.fishManager.AllEscape();
StartCoroutine(TimeScale());
aquariumFishController.fishManager.avoidance *= 10;
aquariumFishController.fishManager.cohesion = 0;
aquariumFishController.fishManager.alignment = 0;
aquariumFishController.fishManager.areaConstrain = 0;
}
IEnumerator TimeScale()
{
yield return new WaitForSeconds(timeStartScale);
targetMovement.fish.SetTrigger("Swim01");
DOTween.To(() => 0.01f, x => Time.timeScale = x, 1,
timeEndScale - timeStartScale)
.SetEase(timeScaleCurve);
yield return new WaitForSeconds(timeEndScale);
Time.timeScale = 1f;
}
public async Task OnShooted(bool isRob)
{
targetMovement.OnShooted(isRob);
if (isRob)
{
float captureShockTime = CaptureShockTime[targetMovement.slotData.aquariumFishID - 1];//不同品质的鱼的受击时间
float captureShockDistance = CaptureShockDistance[targetMovement.slotData.aquariumFishID - 1];//不同品质的鱼的受击距离
targetMovement.Shock(captureShockDistance, captureShockTime, CaptureShockCurve);
await Awaiters.Seconds(CaptureDelay);
targetMovement.Capture(fishAnimMinSpeed, fishAnimMaxSpeed, addRotation, addRotationPeriod);
float captureTime = aquariumFishController.cameraManager.Capture(fishToCameraDistance, lineDrawMinTime, lineDrawSpeed, targetMovement);
GContext.Publish(EShootState.Capture);
await Awaiters.Seconds(captureTime + fishDisappearDelay);
//aquariumFishController.cameraManager.crossbowGo.SetActive(false);
aquariumFishController.cameraManager.Captureed();
targetMovement.gameObject.SetActive(false);
}
else
{
float escapeShockTime = EscapeShockTime[targetMovement.slotData.aquariumFishID - 1];//不同品质的鱼的受击时间
float escapeShockDistance = EscapeShockDistance[targetMovement.slotData.aquariumFishID - 1];//不同品质的鱼的受击距离
targetMovement.Shock(escapeShockDistance, escapeShockTime, EscapeShockCurve);
await Awaiters.Seconds(EscapeDelay);
targetMovement.Escape(EscapeDistance, EscapeDuration);
targetMovement.SetFishSpeed(EscapeAnimSpeed, EscapeAnimRecoverTime);
aquariumFishController.cameraManager.Escape(ArrowEscapeTime);
GContext.Publish(EShootState.Escape);
await Awaiters.Seconds(escapeRewardUIDelay);
}
}
public override async System.Threading.Tasks.Task StopAsync()
{
foreach (var item in fx_hunt_prefab)
{
Addressables.Release(item.Value);
}
fx_hunt_prefab.Clear();
if (mutantMaterial != null)
{
Addressables.Release(mutantMaterial);
mutantMaterial = null;
}
if (fxLeftEye != null)
{
Addressables.Release(fxLeftEye);
fxLeftEye = null;
}
if (fxRightEye != null)
{
Addressables.Release(fxRightEye);
fxRightEye = null;
}
if (aquarium != null)
{
Addressables.ReleaseInstance(aquarium);
aquarium = null;
}
if (fishUnDownloadAlter != null)
{
foreach (var item in fishUnDownloadAlter)
{
Addressables.Release(item.Value);
}
}
eventFishHuntingPanel = null;
UIManager.Instance.DestroyUI(UITypes.EventFishHuntingPanel);
disposables?.Dispose();
disposables = null;
GContext.container.Unregister<AquariumShooterFishManager>();
await base.StopAsync();
}
protected override void OnDestroy()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 732986c1638f5fb4d8a04e8f1523c873
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 080346d6d7b97ef4aa1e27d6b2430915
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using asap.core;
using GameCore;
using System;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class AquariumBtnGift : MonoBehaviour
{
Button btn_enter;
TMP_Text text_time;
TriggerPackData triggerPackData;
TriggerPackBuyData triggerPack;
private void Awake()
{
triggerPackData = GContext.container.Resolve<TriggerPackData>();
btn_enter = GetComponent<Button>();
text_time = transform.Find("text_time").GetComponent<TMP_Text>();
var triggerPackDic = triggerPackData.GetTriggerPackList(6);
if (triggerPackDic.Count <= 0)
{
gameObject.SetActive(false);
return;
}
triggerPack = triggerPackDic[0];
TimeSpan now = triggerPackData.GetCurTriggerPackEndTime(triggerPack);
if (now.TotalSeconds < 0)
{
gameObject.SetActive(false);
return;
}
}
void OnEnable()
{
if (triggerPack != null)
{
SetEndTime();
}
}
private void Start()
{
btn_enter.onClick.AddListener(OnClick);
}
async void OnClick()
{
btn_enter.enabled = false;
await UIManager.Instance.ShowUILoad(UITypes.AquariumGiftPopupPanel);
btn_enter.enabled = true;
}
void SetEndTime()
{
DateTime curTime = ZZTimeHelper.UtcNow().UtcNowOffset();
DateTime endTime = GlobalUtils.TryParseDateTime(triggerPack.time, curTime);
TimeSpan now = endTime - curTime;
double seconds = now.TotalSeconds;
if (seconds < 1)
{
gameObject.SetActive(false);
}
else
{
this.AttachTimer((float)seconds,
() => { gameObject.SetActive(false); },
(elapsed) =>
{
if (triggerPack.index > 0)
{
gameObject.SetActive(false);
return;
}
now = endTime - ZZTimeHelper.UtcNow().UtcNowOffset();
text_time.text = ConvertTools.ConvertTime2(now.Days, now.Hours, now.Minutes, now.Seconds);
}, useRealTime: true);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0f643b7e30fa9b9418a3bf5d9a4f423c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,14 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class AquariumCardWeight : MonoBehaviour
{
public Image icon;
public TMP_Text text_level;
private void Reset()
{
icon = transform.Find("icon").GetComponent<Image>();
text_level = transform.Find("text_level").GetComponent<TMP_Text>();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d170e163d7f296945b780b5edae26151
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,149 @@
using asap.core;
using GameCore;
using System;
using System.Collections;
using UnityEngine;
using UniRx;
using TMPro;
using UnityEngine.UI;
using cfg;
using UnityEngine.AddressableAssets;
public class AquariumCloudPanel : MonoBehaviour
{
Animation ani;
IDisposable disposable;
Image image_map;
TMP_Text text_map;
TMP_Text text_level;
AquariumManagerData data;
int type = 0;
AudioClip doorvault_gear;
Sound sound_doorvault_gear;
private void Awake()
{
ani = GetComponent<Animation>();
disposable = GContext.OnEvent<EndTransition>().Subscribe(EndTransition);
image_map = transform.Find("RandomMapPanel/Item/img_map").GetComponent<Image>();
text_map = transform.Find("RandomMapPanel/result/text_map").GetComponent<TMP_Text>();
text_level = transform.Find("RandomMapPanel/result/fishcard/text_level").GetComponent<TMP_Text>();
type = FishingAquariumAct.CloudType;
StartCoroutine(OnStart());
Synchrodata();
}
void Synchrodata()
{
//从服务器拿数据
string dataStr = PlayFabMgr.Instance.GetLocalData(AquariumManager.AquariumEventDataKey);
if (!string.IsNullOrEmpty(dataStr))
{
data = Newtonsoft.Json.JsonConvert.DeserializeObject<AquariumManagerData>(dataStr);
if (data != null)
{
Tables _tables = GContext.container.Resolve<Tables>();
var mapData = _tables.TbMapData.DataMap[data.mapId];
GContext.container.Resolve<IUIService>().SetImageSprite(image_map, mapData.Bg);
text_map.text = LocalizationMgr.GetText(mapData.Name_l10n_key);
string levelLV = LocalizationMgr.GetText("UI_FishingMapPanel_101006");
int fishCardLevel = GContext.container.Resolve<PlayerFishData>().GetFishLevelByMap(data.mapId);
text_level.text = levelLV + fishCardLevel.ToString();
}
}
}
IEnumerator OnStart()
{
string cloud_in = "aquarium_cloud_in_2";
float time = 0.75f;
switch (type)
{
case 2:
cloud_in = "aquarium_cloud_in_3";
time = 1.25f;
break;
default:
break;
}
if (disposable != null)
{
ani.Play(cloud_in);
}
yield return new WaitForSeconds(time);//入场动画播完
PlayRodAudio("audio_ui_aquarium_doorvault_gear");
if (disposable != null)
{
ani.Play("aquarium_cloud_loop_2");
}
}
void StopRodAudio()
{
if (doorvault_gear)
{
Addressables.Release(doorvault_gear);
doorvault_gear = null;
}
if (sound_doorvault_gear)
{
sound_doorvault_gear.audioSource.Stop();
sound_doorvault_gear.ReturnPool();
sound_doorvault_gear = null;
}
}
async void PlayRodAudio(string audioName)
{
StopRodAudio();
doorvault_gear = await Addressables.LoadAssetAsync<AudioClip>(audioName).Task;
if (disposable == null)
{
if (doorvault_gear)
{
Addressables.Release(doorvault_gear);
doorvault_gear = null;
}
return;
}
sound_doorvault_gear = GContext.container.Resolve<ISoundService>().GetNewUISound(doorvault_gear);
sound_doorvault_gear.audioSource.Play();
sound_doorvault_gear.audioSource.loop = true;
}
public void EndTransition(EndTransition endTransition)
{
StartCoroutine(End());
StopRodAudio();
}
private void OnDisable()
{
Dispose();
}
IEnumerator End()
{
string cloud_out = "aquarium_cloud_out_2";
float time = 1.25f;
switch (type)
{
case 1:
case 5:
cloud_out = "aquarium_cloud_out_3";
time = 0.866f;
break;
default:
break;
}
image_map.gameObject.SetActive(false);
ani.Play(cloud_out);
Dispose();
yield return new WaitForSeconds(time);//退场动画播完
UIManager.Instance.DestroyUI(UITypes.AquariumCloudPanel);
}
void Dispose()
{
disposable?.Dispose();
disposable = null;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b23b723950eb39646945ef78c6ba02d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
using asap.core;
using DG.Tweening;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AquariumDetectEgg : MonoBehaviour
{
RectTransform Content;
GameObject icon_item;
int allCount = 5;
float height;
int maIndex = 2;
int curAllCount;
IUIService uIService;
private void Init()
{
uIService = GContext.container.Resolve<IUIService>();
Content = transform.Find("Viewport/Content").GetComponent<RectTransform>();
icon_item = transform.Find("Viewport/Content/Item").gameObject;
height = icon_item.GetComponent<RectTransform>().rect.height;
icon_item.SetActive(false);
}
public void SetIcon(List<string> iconNameList, string curIcon, int index)
{
Init();
curAllCount = 0;
//List<string> 得到一个新的随机顺序的列表
string str;
string curStr = curIcon;
allCount += index;
for (int i = 0; i < allCount + maIndex; i++)
{
str = iconNameList[Random.Range(0, iconNameList.Count)];
SetMapBg(str);
}
SetMapBg(curStr);
SetMapBg(iconNameList[Random.Range(0, iconNameList.Count)]);
}
void SetMapBg(string bg)
{
GameObject go = Instantiate(icon_item, Content);
Image image = go.transform.GetChild(0).GetComponent<Image>();
go.SetActive(true);
uIService.SetImageSprite(image, bg);
curAllCount++;
}
public void Play()
{
var sequence = DOTween.Sequence();
sequence.Append(Content.DOAnchorPosY(allCount * height, 0.08f * allCount).SetLoops(2, LoopType.Restart).SetEase(Ease.Linear));
//跑马灯动画
float index2 = allCount + maIndex + Random.Range(-0.5f, 0.5f);
sequence.Append(Content.DOAnchorPosY(index2 * height, 0.2f).SetEase(Ease.Linear));
sequence.Append(Content.DOAnchorPosY((allCount + maIndex) * height, 0.2f).SetEase(Ease.InSine));
sequence.Play();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e8158707274832642816f337e0982f45
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,275 @@
using asap.core;
using cfg;
using game;
using Game;
using GameCore;
using System;
using System.Collections;
using TMPro;
using UniRx;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UI;
public class AquariumDetectPanel : BasePanel
{
AquariumManager AM;
Animation anim;
Button btn_close;
Button btn_enter;
Button btn_enter_gray;
TMP_Text text_info;
TMP_Text text_time;
Button btn_event;
GameObject event_redpoint;
Button btn_slot;
TMP_Text text_num_slot;
GameObject slot_redpoint;
GameObject slot_tips;
TMP_Text text_title_tips;
TMP_Text text_title_info;
Button btn_questionmark;
AquariumRandomMapPanel randomMapPanel;
int maxSlot = 6;
DateTime refreshTime;
bool isCutTo = false;
AudioClip doorvault_gear;
Sound sound_doorvault_gear;
AudioClip searchingroll_single;
Sound sound_searchingroll_single;
string audioName;
int refreshTimeInt;
private void Awake()
{
AM = GContext.container.Resolve<AquariumManager>();
anim = GetComponent<Animation>();
btn_close = transform.Find("btn_close").GetComponent<Button>();
btn_enter = transform.Find("root_main/btn_enter/btn_green").GetComponent<Button>();
btn_enter_gray = transform.Find("root_main/btn_enter_gray/btn_green").GetComponent<Button>();
text_info = transform.Find("root_main/btn_enter_gray/text_info").GetComponent<TMP_Text>();
text_time = transform.Find("root_main/text_time").GetComponent<TMP_Text>();
btn_event = transform.Find("root_main/btn_event").GetComponent<Button>();
event_redpoint = transform.Find("root_main/btn_event/redpoint").gameObject;
btn_slot = transform.Find("root_main/btn_slot").GetComponent<Button>();
text_num_slot = transform.Find("root_main/btn_slot/text_num").GetComponent<TMP_Text>();
slot_redpoint = transform.Find("root_main/btn_slot/redpoint").gameObject;
slot_tips = transform.Find("root_main/slot_tips").gameObject;
text_title_tips = transform.Find("root_main/slot_tips/text_title").GetComponent<TMP_Text>();
text_title_info = transform.Find("root_main/slot_tips/text_info").GetComponent<TMP_Text>();
btn_questionmark = transform.Find("root_main/title/btn_questionmark").GetComponent<Button>();
randomMapPanel = transform.Find("RandomMapPanel").GetComponent<AquariumRandomMapPanel>();
event_redpoint.SetActive(false);
}
protected override void Start()
{
GContext.container.Resolve<GuideDataCenter>().InspectTriggerGuide("AquariumDetectPanel");
//randomMapPanel.gameObject.SetActive(false);
base.Start();
btn_event.onClick.AddListener(OnClickEvent);
btn_enter.onClick.AddListener(OnClickMaching);
btn_close.onClick.AddListener(OnClickClose);
btn_questionmark.onClick.AddListener(async () =>
await UIManager.Instance.ShowUI(UITypes.AquariumInfoPopupPanel));
btn_slot.onClick.AddListener(() => slot_tips.SetActive(!slot_tips.activeSelf));
int Slot = GContext.container.Resolve<PlayerData>().benefitsAquariumLimit;
text_num_slot.text = $"{Slot}/{maxSlot}";
text_title_tips.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_2", $"{Slot}/{maxSlot}");
if (Slot == maxSlot)
{
text_title_info.text = LocalizationMgr.GetText("UI_AquariumPanel_4");
}
else
{
int level = GContext.container.Resolve<PlayerData>().benefitsLevel[6];
var Benefits = GContext.container.Resolve<Tables>().TBBenefits.GetOrDefault(7);
if (Benefits == null || level + 1 >= Benefits.AccountLevel.Count)
{
Debug.LogError("No account data AquariumLimit up");
}
else
{
text_title_info.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_3", Benefits.AccountLevel[level + 1]);
}
}
var nowTime = ZZTimeHelper.UtcNow().UtcNowOffset();
refreshTime = nowTime.Date.AddDays(1);
if (nowTime.Date.DayOfYear != AM.data.refreshDay)
{
AM.data.refreshCount = 0;
AM.data.adCount = 0;
AM.data.refreshDay = nowTime.Date.DayOfYear;
}
refreshTimeInt = GContext.container.Resolve<Tables>().TbAquariumConfig.RefreshTime;
bool isRefresh = AM.data.refreshCount < refreshTimeInt;
if (!isRefresh)
{
ShowInfo();
}
btn_enter.transform.parent.gameObject.SetActive(isRefresh);
btn_enter_gray.transform.parent.gameObject.SetActive(!isRefresh);
text_time.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_44", refreshTimeInt - AM.data.refreshCount, refreshTimeInt);
}
void ShowInfo()
{
//剩余时间
TimeSpan duration = refreshTime - ZZTimeHelper.UtcNow().UtcNowOffset();
string textValue = LocalizationMgr.GetText("UI_AquariumPanel_7");
text_info.text = string.Format(textValue, ConvertTools.ConvertTime2(duration));
var timer = Observable.Interval(TimeSpan.FromSeconds(1))
.TakeWhile(seconds => seconds <= duration.TotalSeconds)
.Subscribe(seconds => text_info.text =
string.Format(textValue, ConvertTools.ConvertTime2(duration.Subtract(TimeSpan.FromSeconds(seconds))))
, Refresh)
.AddTo(disposables);
}
void Refresh()
{
AM.data.adCount = 0;
AM.data.refreshCount = 0;
AM.data.refreshDay = ZZTimeHelper.UtcNow().UtcNowOffset().Date.DayOfYear;
text_time.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_44", refreshTimeInt, refreshTimeInt);
btn_enter.transform.parent.gameObject.SetActive(true);
btn_enter_gray.transform.parent.gameObject.SetActive(false);
}
void OnClickEvent()
{
_ = UIManager.Instance.ShowUI(UITypes.EventReportPopupPanel);
}
async void GetSearchingrollSingle()
{
searchingroll_single = await Addressables.LoadAssetAsync<AudioClip>("audio_ui_aquarium_doorvault_searchingroll_single").Task;
if (searchingroll_single != null && this != null)
{
sound_searchingroll_single = GContext.container.Resolve<ISoundService>().GetNewUISound(searchingroll_single);
}
}
IDisposable enterMap;
void OnClickMaching()
{
StartCoroutine(StartClickMaching());
}
IEnumerator StartClickMaching()
{
//randomMapPanel.gameObject.SetActive(true);
anim.Play("match_map_start");
yield return new WaitForSeconds(1);
PlayRodAudio("audio_ui_fishingduel_matchingloop");
randomMapPanel.SetMap();
enterMap = FishingAquariumAct.eventAggregator.GetEvent<EnterMaped>().Subscribe(EnterMaped);
randomMapPanel.InitEgg();
FishingAquariumAct.eventAggregator.Publish(new AquariumEnterMapScene());
yield return new WaitForSeconds(3);
StopRodAudio();
GContext.Publish(new VibrationData(HapticTypes.HeavyImpact));
anim.Play("match_egg_start");
GetSearchingrollSingle();
yield return new WaitForSeconds(1);
PlayRodAudio("audio_ui_aquarium_doorvault_searchingroll_loop");
randomMapPanel.PlayEgg();
yield return new WaitForSeconds(1.5f);
StopRodAudio();
for (int i = 1; i < AM.Slot; i++)
{
yield return new WaitForSeconds(0.16f);
if (sound_searchingroll_single != null)
{
sound_searchingroll_single.audioSource.Play();
}
}
anim.Play("aquarium_cloud_in");
yield return new WaitForSeconds(3.5f);
PlayRodAudio("audio_ui_aquarium_doorvault_gear");
anim.Play("aquarium_cloud_loop");
randomMapPanel.HideMap();
yield return new WaitForSeconds(1f);
OnClose();
}
void StopRodAudio()
{
if (doorvault_gear)
{
Addressables.Release(doorvault_gear);
doorvault_gear = null;
}
if (sound_doorvault_gear)
{
sound_doorvault_gear.audioSource.Stop();
sound_doorvault_gear.ReturnPool();
sound_doorvault_gear = null;
}
}
private void OnDisable()
{
this.audioName = "";
StopRodAudio();
if (searchingroll_single)
{
Addressables.Release(searchingroll_single);
searchingroll_single = null;
}
if (sound_searchingroll_single)
{
sound_searchingroll_single.audioSource.Stop();
sound_searchingroll_single.ReturnPool();
sound_searchingroll_single = null;
}
}
async void PlayRodAudio(string audioName)
{
this.audioName = audioName;
StopRodAudio();
var local_doorvault_gear = await Addressables.LoadAssetAsync<AudioClip>(audioName).Task;
if (local_doorvault_gear == null)
{
return;
}
if (this.audioName != audioName)
{
Addressables.Release(local_doorvault_gear);
return;
}
doorvault_gear = local_doorvault_gear;
sound_doorvault_gear = GContext.container.Resolve<ISoundService>().GetNewUISound(doorvault_gear);
sound_doorvault_gear.audioSource.Play();
sound_doorvault_gear.audioSource.loop = true;
}
void EnterMaped(EnterMaped enterMaped)
{
enterMap?.Dispose();
enterMap = null;
OnClose();
}
async void OnClose()
{
if (isCutTo)
{
StopRodAudio();
anim.Play("aquarium_cloud_out");
FishingAquariumAct.eventAggregator.Publish(new AquariumEnterMapScene() { isShowUI = true });
await Awaiters.Seconds(2.0f);
UIManager.Instance.DestroyUI(UITypes.AquariumDetectPanel);
}
else
{
isCutTo = true;
}
}
void OnClickClose()
{
FishingAquariumAct.CloudType = 2;
GContext.Publish(new UnloadActToNextAct(transitionPanel: UITypes.AquariumCloudPanel, time: 1.25f));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9530c5e1797998d4e8eae671d2b7baf3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
using asap.core;
using cfg;
using GameCore;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class AquariumEggTips : MonoBehaviour, IAquariumTips
{
public Image icon;
public TMP_Text text_name;
public Image bar;
public TMP_Text text_time;
public Button btn_speedup;
public GameObject[] card_info;
AquariumSlotData slotData;
AquariumSlot aquariumSlot;
public void SetActive(bool value)
{
gameObject.SetActive(value);
}
public void SetData(AquariumSlot aquariumSlot)
{
this.aquariumSlot = aquariumSlot;
this.slotData = aquariumSlot.slotData;
for (int i = 0; i < card_info.Length; i++)
{
card_info[i].SetActive(false);
}
UpdateBar(ZZTimeHelper.UtcNow());
AquariumEgg aquariumEgg = GContext.container.Resolve<Tables>().TbAquariumEgg.GetOrDefault(slotData.eggId);
if (aquariumEgg != null)
{
text_name.text = LocalizationMgr.GetText(aquariumEgg.Name_l10n_key);
var quantity = aquariumEgg.HatchFishQuantity;
GContext.container.Resolve<IUIService>().SetImageSprite(icon, aquariumEgg.Icon);
List<int> hatchFishQuality = aquariumEgg.HatchFishQuality;
bool showNum = false;
int max = 1;
int min = hatchFishQuality[0];
if (hatchFishQuality.Count > 1)
{
showNum = true;
max = hatchFishQuality[^1];
}
int index = 0;
TMP_Text text_fish_num;
for (int i = 0; i < hatchFishQuality.Count; i++)
{
index = hatchFishQuality[i] - 1;
if (index < card_info.Length)
{
card_info[index].SetActive(true);
text_fish_num = card_info[index].transform.Find("text_fish_num").GetComponent<TMP_Text>();
if (showNum)
{
text_fish_num.text = $"{min}{max}";
}
else
{
text_fish_num.text = min.ToString();
}
}
}
}
}
public bool UpdateBar(DateTime dateTime)
{
float time = (float)(dateTime - slotData.startTime).TotalHours + slotData.accelerationHatch;
bar.fillAmount = time / slotData.hatchTime;
int timeRemaining = (int)((slotData.hatchTime - time) * 3600);
if (timeRemaining <= 0)
{
return false;
}
TimeSpan timeSpan = new TimeSpan(0, 0, timeRemaining);
text_time.text = ConvertTools.ConvertTime2(timeSpan);
return true;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 55501fec551954c42a9d89432530e7da
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,200 @@
using asap.core;
using cfg;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using System;
using GameCore;
public class AquariumFishTips : MonoBehaviour, IAquariumTips
{
public Image icon;
public Image tag_fish;
public TMP_Text text_name;
public Image bar;
public Image bar_hurt;
public TMP_Text text_time;
public GameObject recoverting;
public TMP_Text text_time2;
public GameObject killed;
public GameObject sold;
public TMP_Text text_killed;
public GameObject text_max;
public Button btn_speedup;
public Button btn_sell;
public TMP_Text text_cash;
public GameObject mutated;
public TMP_Text fishcard;
AquariumSlotData slotData;
Item item;
FishData fishData;
AquariumSlot aquariumSlot;
AquariumFish aquariumFish;
AquariumManager AM;
Tables _tables;
DateTime StartTime;
float injuryH;
float allRewardCount;
float baseRewardCount;
float WeightIncEvent;
public void SetActive(bool value)
{
gameObject.SetActive(value);
}
public void SetData(AquariumSlot aquariumSlot)
{
AM = GContext.container.Resolve<AquariumManager>();
_tables = GContext.container.Resolve<Tables>();
this.aquariumSlot = aquariumSlot;
this.slotData = aquariumSlot.slotData;
item = _tables.TbItem.GetOrDefault(slotData.fishItemID);
fishData = _tables.TbFishData.GetOrDefault(item.RedirectID);
aquariumFish = _tables.TbAquariumFish.GetOrDefault(slotData.aquariumFishID);
StartTime = slotData.FishHatchTime();
injuryH = slotData.injuryGrowthTime;
mutated.SetActive(slotData.mutants > 0);
text_name.text = LocalizationMgr.GetText(item.Name_l10n_key);
GContext.container.Resolve<IUIService>().SetImageSprite(tag_fish, "icon_fish_rate_tag_" + item.Quality);
PlayerFishData.SetFishIcon(icon, item);//鱼头像
PlayerData playerData = GContext.container.Resolve<PlayerData>();
var weights = GContext.container.Resolve<AquariumManager>().GetWeightMag();
float weight = weights[slotData.aquariumFishID - 1];
fishcard.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_40", weight.ToPercentageString());
WeightIncEvent = (1 + weight) * (1 + playerData.benefitsCashMag) * (1 + playerData.benefitsAquariumCashMag);
baseRewardCount = slotData.allCash;
allRewardCount = 0;
int fishQ = slotData.fishMQ;
for (int i = 0; i < fishQ; i++)
{
if (slotData.mutants > i)
{
allRewardCount += baseRewardCount * WeightIncEvent * (1 + aquariumFish.MutantGrowthExtraSoldReward) * (1 + aquariumFish.MutantExtraSoldReward);
}
else
{
allRewardCount += baseRewardCount * WeightIncEvent * (1 + aquariumFish.GrowthExtraSoldReward);
}
}
UpdateBar(ZZTimeHelper.UtcNow());
}
public bool UpdateBar(DateTime dateTime)
{
//正常的成长进度 自然时间+加速成长 - 全部恢复时间
float normalH = (float)(dateTime - StartTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
//受伤时的成长进度加上本次恢复时间大于正常的成长进度
bar_hurt.gameObject.SetActive(false);
text_time.gameObject.SetActive(true);
recoverting.gameObject.SetActive(false);
text_max.gameObject.SetActive(false);
btn_speedup.gameObject.SetActive(true);
btn_sell.gameObject.SetActive(false);
killed.SetActive(false);
sold.SetActive(false);
float timeProgress = 1;
if (aquariumSlot.slotState == 5)
{
bar.transform.parent.gameObject.SetActive(false);
killed.SetActive(true);
btn_speedup.gameObject.SetActive(false);
text_time.gameObject.SetActive(false);
AquariumResultData aquariumResultDatas = AM.data.aquariumResultDatas[slotData.index];
text_killed.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_42", aquariumResultDatas.displayName);
text_cash.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_26", $"{0}/{ConvertTools.GetNumberString2((int)allRewardCount)}");
return false;
}
else if (aquariumSlot.slotState == 4)
{
bar.transform.parent.gameObject.SetActive(false);
sold.SetActive(true);
btn_speedup.gameObject.SetActive(false);
text_time.gameObject.SetActive(false);
text_cash.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_26", $"{ConvertTools.GetNumberString2(slotData.cash)}/{ConvertTools.GetNumberString2((int)allRewardCount)}");
return false;
}
else
{
bar.transform.parent.gameObject.SetActive(true);
timeProgress = normalH / slotData.growthTime;
bar.fillAmount = 1;
if (injuryH > normalH)
{
text_time.gameObject.SetActive(false);
recoverting.gameObject.SetActive(true);
bar_hurt.gameObject.SetActive(true);
bar_hurt.fillAmount = (injuryH - normalH) / slotData.recoveryTime;
int timeRemaining = (int)((injuryH - normalH) * 3600);
TimeSpan timeSpan = new TimeSpan(0, 0, timeRemaining);
text_time2.text = ConvertTools.ConvertTime2(timeSpan);
if (injuryH / slotData.growthTime > 1)
{
timeProgress = 1 - ((injuryH - normalH) / slotData.growthTime);
}
bar.fillAmount = 0;
}
else if (normalH >= slotData.growthTime)
{
text_time.gameObject.SetActive(false);
text_max.gameObject.SetActive(true);
btn_speedup.gameObject.SetActive(false);
btn_sell.gameObject.SetActive(true);
timeProgress = 1;
}
else
{
bar.fillAmount = normalH / slotData.growthTime;
}
if (timeProgress < 1)
{
int timeRemaining = (int)(slotData.growthTime * (1 - timeProgress) * 3600);
TimeSpan timeSpan = new TimeSpan(0, 0, timeRemaining);
text_time.text = ConvertTools.ConvertTime2(timeSpan);
}
}
float rewardProgress = timeProgress;// normalH / slotData.growthTime;
if (rewardProgress > 1)
{
rewardProgress = 1;
}
//金币显示
int fishQ = slotData.fishMQ;
if (injuryH > normalH)
{
fishQ -= GContext.container.Resolve<AquariumManager>().data.aquariumHurtDatas[slotData.index].fishLQ;
if (fishQ <= 0)
{
fishQ = 1;
}
}
float rewardCount = 0;
for (int i = 0; i < fishQ; i++)
{
if (slotData.mutants > i)
{
rewardCount += baseRewardCount * (1 + aquariumFish.MutantExtraSoldReward) * (1 + aquariumFish.MutantGrowthExtraSoldReward * rewardProgress) * WeightIncEvent;
}
else
{
rewardCount += baseRewardCount * (1 + aquariumFish.GrowthExtraSoldReward * rewardProgress) * WeightIncEvent;
}
}
text_cash.text = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_26", $"{ConvertTools.GetNumberString2((int)(rewardCount))}/{ConvertTools.GetNumberString2((int)allRewardCount)}");
return true;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: daa217149732d6b40b4a1bfaaad0537d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,16 @@
using GameCore;
using UnityEngine;
using UnityEngine.UI;
public class AquariumInfoPopupPanel : MonoBehaviour
{
private Button btnClose;
private void Awake()
{
btnClose = transform.Find("btn_close").GetComponent<Button>();
}
void Start()
{
btnClose.onClick.AddListener(() => UIManager.Instance.DestroyUI(UITypes.AquariumInfoPopupPanel));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a72a012b9cb7fc4abffc4d9e52d0ea7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,429 @@
using asap.core;
using cfg;
using game;
using GameCore;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UniRx;
using UnityEngine.UI;
public class AquariumPanel : BasePanel
{
Button btn_close;
Button btn_event;
Button btn_progress;
Button btn_fishcard;
TMP_Text text_level;
Button btn_questionmark;
Button btn_sell;
Button btn_speedup;
Head head;
TMP_Text text_name;
TMP_Text text_title;
Button btn_close_tips;
GameObject redpoint;
AquariumManager AM;
Tables tables;
AquariumSlot[] aquariumSlot;
bool updateBar = true;
IUIService uIService;
IAquariumTips aquariumTips;
AquariumEggTips aquariumEggTips;
AquariumFishTips aquariumFishTips;
AquariumSlot curAquariumSlot;
FishingAquariumAct fishingAquariumAct;
UIDrag moveCameraPanel;
bool canDragMove = false;
public bool CanDragMove => canDragMove;
MapData mapData;
private void Awake()
{
GContext.OnEvent<GetUIAsyncEvent>().Subscribe(GetUIAsyncEvent).AddTo(disposables);
GContext.OnEvent<ChangeMapDataAsyncEvent>().Subscribe(e =>
{
UIManager.Instance.DestroyUI(UITypes.FishcardBenefitPopupPanel);
GContext.container.Resolve<PlayerData>().SetCurrentMapId(e.mapID);
OnClickClose();
e.source?.SetResult(false);
}).AddTo(disposables);
transform.SetAsFirstSibling();
reportService = GContext.container.Resolve<IReportService>();
eventReport = transform.Find("root/Event_report").GetComponent<EventReport>();
tables = GContext.container.Resolve<Tables>();
uIService = GContext.container.Resolve<IUIService>();
AM = GContext.container.Resolve<AquariumManager>();
text_name = transform.Find("root/title/bg/text_name").GetComponent<TMP_Text>();
head = transform.Find("root/title/btn_head").GetComponent<Head>();
btn_event = transform.Find("root/btn_event").GetComponent<Button>();
btn_progress = transform.Find("root/btn_progress").GetComponent<Button>();
btn_fishcard = transform.Find("root/btn_fishcard").GetComponent<Button>();
btn_close = transform.Find("btn_close").GetComponent<Button>();
btn_questionmark = transform.Find("root/title/btn_questionmark").GetComponent<Button>();
text_level = transform.Find("root/btn_fishcard/text_level").GetComponent<TMP_Text>();
aquariumSlot = transform.Find("root/partner").GetComponentsInChildren<AquariumSlot>();
text_title = transform.Find("root/title/text_title").GetComponent<TMP_Text>();
moveCameraPanel = transform.Find("moveCameraPanel").GetComponent<UIDrag>();
redpoint = transform.Find("root/btn_fishcard/redpoint").gameObject;
btn_sell = transform.Find("btn_2/btn_sell").GetComponent<Button>();
btn_speedup = transform.Find("btn_2/btn_speedup").GetComponent<Button>();
aquariumEggTips = transform.Find("egg_tips").GetComponent<AquariumEggTips>();
aquariumFishTips = transform.Find("fish_tips").GetComponent<AquariumFishTips>();
btn_close_tips = transform.Find("btn_close_tips").GetComponent<Button>();
SetMoveCameraPanel();
}
void SetMoveCameraPanel()
{
moveCameraPanel.OnPointerDownCall = () =>
{
canDragMove = true;
};
moveCameraPanel.OnPointerUpCall = () =>
{
canDragMove = false;
};
//moveCameraPanel.OnDragCall = (eventData) =>
//{
// Debug.Log(" Pointer OnDragCall");
//};
}
void GetUIAsyncEvent(GetUIAsyncEvent data)
{
if (data.uIType == UITypes.FishingMapPanel.Name && !data.show)
{
SetRed();
string levelLV = LocalizationMgr.GetText("UI_FishingMapPanel_101006");
int fishCardLevel = GContext.container.Resolve<PlayerFishData>().GetFishLevelByMap(AM.MapId);
text_level.text = levelLV + fishCardLevel.ToString();
}
}
protected override void Start()
{
var fishingData = GContext.container.Resolve<FishingData>();
fishingData.MapId = AM.MapId;
updateBar = true;
base.Start();
GContext.container.Resolve<GuideDataCenter>().InspectTriggerGuide("AquariumPanel");
aquariumEggTips.btn_speedup.onClick.AddListener(OnClickSpeedup);
aquariumFishTips.btn_speedup.onClick.AddListener(OnClickSpeedup);
btn_speedup.onClick.AddListener(OnClickSpeedup);
aquariumFishTips.btn_sell.onClick.AddListener(ShowFishSellingPopupPanel);
btn_close_tips.onClick.AddListener(CloseTips);
btn_event.onClick.AddListener(() => _ = UIManager.Instance.ShowUI(UITypes.EventReportPopupPanel));
btn_fishcard.onClick.AddListener(async () =>
await UIManager.Instance.ShowUI(UITypes.FishcardBenefitPopupPanel));
btn_sell.onClick.AddListener(ShowFishSellingPopupPanel);
btn_progress.onClick.AddListener(OnClickProgress);
btn_close.onClick.AddListener(OnClickClose);
btn_questionmark.onClick.AddListener(async () =>
await UIManager.Instance.ShowUI(UITypes.AquariumInfoPopupPanel));
text_name.text = GContext.container.Resolve<IUserService>().DisplayName;
head.SetData(GContext.container.Resolve<IUserService>().AvatarUrl);
mapData = tables.TbMapData.GetOrDefault(AM.MapId);
text_title.text = LocalizationMgr.GetText(mapData.Name_l10n_key);
string levelLV = LocalizationMgr.GetText("UI_FishingMapPanel_101006");
int fishCardLevel = GContext.container.Resolve<PlayerFishData>().GetFishLevelByMap(AM.MapId);
text_level.text = levelLV + fishCardLevel.ToString();
DateTime dateTime = ZZTimeHelper.UtcNow();
Item item;
AquariumEgg aquariumEgg;
bool isShowSell = false;
bool isShowSpeedup = false;
for (int i = 0; i < aquariumSlot.Length; i++)
{
if (i < AM.Slot)
{
AquariumSlotData slotData = AM.data.slotDatas[i];
if (slotData.startTime.AddHours(slotData.hatchTime - slotData.accelerationHatch) > dateTime)
{
aquariumEgg = tables.TbAquariumEgg.GetOrDefault(slotData.eggId);
//还没孵化
uIService.SetImageSprite(aquariumSlot[i].icon_egg, aquariumEgg.Icon);
}
item = tables.TbItem.GetOrDefault(slotData.fishItemID);
PlayerFishData.SetFishIcon(aquariumSlot[i].icon_fish, item);//鱼头像
uIService.SetImageSprite(aquariumSlot[i].icon_rate, "icon_fish_rate_tag_" + item.Quality);
aquariumSlot[i].InitSlot(i, slotData, OnClickSlot, OnFishStateChange);
if (aquariumSlot[i].slotState == 2 || aquariumSlot[i].slotState == 3)
{
isShowSell = true;
}
if (aquariumSlot[i].slotState < 3)
{
isShowSpeedup = true;
}
}
else
{
aquariumSlot[i].gameObject.SetActive(false);
}
}
btn_sell.gameObject.SetActive(isShowSell);
btn_speedup.gameObject.SetActive(isShowSpeedup);
AM.CheckInHome();
NextReport();
SetRed();
}
void SetRed()
{
bool isRedPoint = GContext.container.Resolve<PlayerFishData>().GetMapRed(mapData.FishList);
redpoint.SetActive(isRedPoint);
}
public void OnUpdate(DateTime dateTime)
{
if (!updateBar)
{
return;
}
for (int i = 0; i < AM.Slot; i++)
{
aquariumSlot[i].UpdateBar(dateTime);
}
if (aquariumTips != null && curAquariumSlot != null && curAquariumSlot.slotState < 3)
{
aquariumTips.UpdateBar(dateTime);
}
}
public void Init(FishingAquariumAct fishingAquariumAct)
{
this.fishingAquariumAct = fishingAquariumAct;
}
async void ShowFishSellingPopupPanel()
{
GameObject go = await UIManager.Instance.ShowUI(UITypes.FishSellingPopupPanel);
FishSellingPopupPanel fishSellingPopupPanel = go.GetComponent<FishSellingPopupPanel>();
fishSellingPopupPanel.Init(OnSellFish);
aquariumFishTips.gameObject.SetActive(false);
}
async void OnSellFish()
{
GameObject go = await UIManager.Instance.ShowUI(UITypes.AquariumReportPopupPanel);
AquariumReportPopupPanel aquariumReportPopupPanel = go.GetComponent<AquariumReportPopupPanel>();
aquariumReportPopupPanel.InitData(fishingAquariumAct);
OnFishStateChange();
}
/// <summary>
/// 鱼当前状态倒计时结束
/// 售卖鱼刷新
/// </summary>
void OnFishStateChange()
{
bool isShowSell = false;
bool isShowSpeedup = false;
List<int> addFish = new List<int>();
List<int> removeFish = new List<int>();
for (int i = 0; i < AM.Slot; i++)
{
if (aquariumSlot[i].slotState > 3)
{
continue;
}
int oldState = aquariumSlot[i].slotState;
aquariumSlot[i].SetState();
if (oldState != aquariumSlot[i].slotState)
{
if (oldState == 1 && (aquariumSlot[i].slotState == 2 || aquariumSlot[i].slotState == 3))
{
//添加鱼
addFish.Add(i);
}
else if (aquariumSlot[i].slotState == 4)
{
//删除鱼
removeFish.Add(i);
}
}
if (aquariumSlot[i].slotState == 2 || aquariumSlot[i].slotState == 3)
{
isShowSell = true;
}
if (aquariumSlot[i].slotState < 3)
{
isShowSpeedup = true;
}
}
btn_sell.gameObject.SetActive(isShowSell);
btn_speedup.gameObject.SetActive(isShowSpeedup);
//修改显示的鱼
if (removeFish.Count > 0 || addFish.Count > 0)
{
if (aquariumTips != null && curAquariumSlot != null)
{
bool isShow = aquariumTips.UpdateBar(ZZTimeHelper.UtcNow());
if (!isShow)
{
CloseTips();
}
}
ChangeFishEvent changeFishEvent = new ChangeFishEvent();
changeFishEvent.addFish = addFish;
changeFishEvent.removeFish = removeFish;
FishingAquariumAct.eventAggregator.Publish(changeFishEvent);
}
}
void CloseTips()
{
if (curAquariumSlot != null && aquariumTips != null)
{
curAquariumSlot.selected.SetActive(false);
aquariumTips.SetActive(false);
btn_close_tips.gameObject.SetActive(false);
curAquariumSlot = null;
aquariumTips = null;
}
fishingAquariumAct.StopFollowFishCamera();
}
public void OnClickFish(int index)
{
if (index < aquariumSlot.Length)
{
OnClickSlot(aquariumSlot[index]);
}
}
void OnClickSlot(AquariumSlot aquariumSlot)
{
if (curAquariumSlot != null && aquariumTips != null)
{
if (curAquariumSlot == aquariumSlot)
{
CloseTips();
return;
}
curAquariumSlot.selected.SetActive(false);
aquariumTips.SetActive(false);
}
curAquariumSlot = aquariumSlot;
curAquariumSlot.selected.SetActive(true);
AquariumSlotData slotData = aquariumSlot.slotData;
DateTime dateTime = ZZTimeHelper.UtcNow();
bool isEgg = false;
if (slotData.FishHatchTime() > dateTime)
{
//还没孵化
isEgg = true;
aquariumTips = aquariumEggTips;
}
else
{
//已经孵化
aquariumTips = aquariumFishTips;
}
if (curAquariumSlot.slotState < 4)
{
fishingAquariumAct.FollowFishCamera(slotData, isEgg);
}
aquariumTips.SetActive(true);
aquariumTips.SetData(curAquariumSlot);
btn_close_tips.gameObject.SetActive(true);
}
async void OnClickSpeedup()
{
DateTime dateTime = ZZTimeHelper.UtcNow();
if (aquariumTips != null && curAquariumSlot != null && curAquariumSlot.slotState < 3)
{
bool isShow = aquariumTips.UpdateBar(dateTime);
if (!isShow)
{
CloseTips();
return;
}
}
var go = await UIManager.Instance.ShowUI(UITypes.SpeedupPopupPanel);
if (go != null)
{
//判断是否置灰
bool isAd = AM.data.adCount < tables.TbAquariumConfig.AdMaxTime;
SpeedupPopupPanel speedupPopupPanel = go.GetComponent<SpeedupPopupPanel>();
string adContent = LocalizationMgr.GetFormatTextValue("UI_AquariumPanel_44", tables.TbAquariumConfig.AdMaxTime - AM.data.adCount, tables.TbAquariumConfig.AdMaxTime);
if (isAd)
{
speedupPopupPanel.SetData(OnAdsSucceed, StartSpeedUp, adContent);
}
else
{
speedupPopupPanel.SetData(null, null, adContent);
}
}
}
void StartSpeedUp(bool isGuide)
{
updateBar = false;
//加速成功
AM.Speedup(isGuide);
}
void OnAdsSucceed()
{
updateBar = true;
if (aquariumTips != null && curAquariumSlot != null && curAquariumSlot.slotState < 3)
{
bool isShow = aquariumTips.UpdateBar(ZZTimeHelper.UtcNow());
if (!isShow)
{
CloseTips();
}
}
OnFishStateChange();
}
async void OnClickProgress()
{
await UIManager.Instance.ShowUI(UITypes.PlayerGradePanel);
GContext.Publish(new HideHomePanelEvent());
GContext.Publish(new ChangeTabEvent() { index = 1 });
}
void OnClickClose()
{
FishingAquariumAct.CloudType = 4;
GContext.Publish(new UnloadActToNextAct(transitionPanel: UITypes.AquariumCloudPanel, time: 0.75f));
}
EventReport eventReport;
IReportService reportService;
bool isEnable = true;
private void OnDisable()
{
isEnable = false;
}
async void PlayEventReport(ReportData reportEvent)
{
eventReport.gameObject.SetActive(true);
eventReport.SetData(reportEvent.playFabId, reportEvent.content, reportEvent.type);
await Awaiters.Seconds(4f);
if (!isEnable)
{
return;
}
eventReport.gameObject.SetActive(false);
NextReport();
}
void NextReport()
{
var data = reportService.GetAquariumReportData();
if (data != null)
{
PlayEventReport(data);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c600010492ee4164d904cb466cc1daf6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,139 @@
using asap.core;
using cfg;
using DG.Tweening;
using GameCore;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class AquariumRandomMapPanel : MonoBehaviour
{
AquariumManager AM;
RectTransform Content;
GameObject img_map;
int allCount = 5;
float height;
int maIndex = 2;
IUIService uIService;
GameObject result;
TMP_Text text_map;
TMP_Text text_level;
AquariumDetectEgg[] aquariumDetectEggs;
Transform eggRoot;
Tables _tables;
Transform door;
private void Awake()
{
_tables = GContext.container.Resolve<Tables>();
uIService = GContext.container.Resolve<IUIService>();
AM = GContext.container.Resolve<AquariumManager>();
Content = transform.Find("Viewport/Content").GetComponent<RectTransform>();
img_map = transform.Find("Viewport/Content/Item").gameObject;
height = img_map.GetComponent<RectTransform>().rect.height;
img_map.SetActive(false);
result = transform.Find("result").gameObject;
text_map = transform.Find("result/text_map").GetComponent<TMP_Text>();
text_level = transform.Find("result/fishcard/text_level").GetComponent<TMP_Text>();
eggRoot = transform.Find("eggRoot");
aquariumDetectEggs = eggRoot.GetComponentsInChildren<AquariumDetectEgg>();
//eggRoot.gameObject.SetActive(false);
door = transform.Find("door");
}
//private void Start()
//{
// result.SetActive(false);
//}
public void SetMap()
{
PlayerData playerData = GContext.container.Resolve<PlayerData>();
AM.GetRandmMap();
var lastMapID = playerData.lastMapId;
List<MapData> mapDatas = _tables.TbMapData.DataList;
List<int> indexs = new List<int>();
for (int i = 0; i < mapDatas.Count; i++)
{
if (mapDatas[i].ID <= lastMapID)
{
indexs.Add(i);
}
else
{
break;
}
}
while (indexs.Count < allCount)
{
indexs.AddRange(indexs);
}
List<int> newIDs = new List<int>();
for (int i = 0; i < allCount; i++)
{
int mapIDIndex = indexs[Random.Range(0, indexs.Count)];
newIDs.Add(mapIDIndex);
indexs.Remove(mapIDIndex);
}
newIDs.AddRange(newIDs);
for (int i = 0; i < allCount + maIndex; i++)
{
SetMapBg(mapDatas[newIDs[i]].Bg);
}
var mapData = _tables.TbMapData.DataMap[AM.MapId];
SetMapBg(mapData.Bg);
SetMapBg(mapDatas[newIDs[0]].Bg);
text_map.text = LocalizationMgr.GetText(mapData.Name_l10n_key);
string levelLV = LocalizationMgr.GetText("UI_FishingMapPanel_101006");
int fishCardLevel = GContext.container.Resolve<PlayerFishData>().GetFishLevelByMap(AM.MapId);
text_level.text = levelLV + fishCardLevel.ToString();
var sequence = DOTween.Sequence();
sequence.Append(door.DOLocalMoveX(900, 0.5f).SetEase(Ease.Linear));
sequence.Append(Content.DOAnchorPosY(allCount * height, 0.8f).SetLoops(2, LoopType.Restart).SetEase(Ease.Linear));
//跑马灯动画
float index2 = allCount + maIndex + Random.Range(-0.5f, 0.5f);
sequence.Append(Content.DOAnchorPosY(index2 * height, 0.2f).SetEase(Ease.Linear));
sequence.Append(Content.DOAnchorPosY((allCount + maIndex) * height, 0.2f).SetEase(Ease.InSine));
sequence.Play();
}
void SetMapBg(string bg)
{
GameObject go = Instantiate(img_map, Content);
Image image = go.transform.GetChild(0).GetComponent<Image>();
go.SetActive(true);
uIService.SetImageSprite(image, bg);
}
public void InitEgg()
{
//开始随机蛋蛋
for (int i = 0; i < aquariumDetectEggs.Length; i++)
{
if (i < AM.Slot)
{
AquariumEgg aquariumEgg = _tables.TbAquariumEgg.GetOrDefault(AM.data.slotDatas[i].eggId);
aquariumDetectEggs[i].SetIcon(AM.eggNames, aquariumEgg.Icon, i);
}
else
{
aquariumDetectEggs[i].gameObject.SetActive(false);
}
}
}
public void PlayEgg()
{
//开始随机蛋蛋
for (int i = 0; i < aquariumDetectEggs.Length; i++)
{
if (i < AM.Slot)
{
AquariumEgg aquariumEgg = _tables.TbAquariumEgg.GetOrDefault(AM.data.slotDatas[i].eggId);
aquariumDetectEggs[i].Play();
}
}
}
public void HideMap()
{
Content.gameObject.SetActive(false);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 311a4753f6d60b34c9b7c383888d32e7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class AquariumReportFishItem : MonoBehaviour
{
[Header("Fish Info")]
public Transform mask_bg;
public Image fish_icon;
public Image icon_rate;
public Image icon_egg;
[Header("Cash Info")]
public GameObject fish_info;
public TMP_Text text_cash;
public TMP_Text text_fish_name;
[Header("Player Info")]
public GameObject player_info;
public TMP_Text text_player_name;
public Head text_player_head;
public int index;
private void Reset()
{
mask_bg = transform.Find("mask_bg2").GetComponent<Transform>();
fish_icon = transform.Find("mask_bg2/icon_fish").GetComponent<Image>();
icon_rate = transform.Find("mask_bg2/icon_rate").GetComponent<Image>();
icon_egg = transform.Find("mask_bg2/icon_egg").GetComponent<Image>();
fish_info = transform.Find("fish_info").gameObject;
text_cash = transform.Find("fish_info/text_cash").GetComponent<TMP_Text>();
text_fish_name = transform.Find("fish_info/text_name").GetComponent<TMP_Text>();
player_info = transform.Find("player_info").gameObject;
text_player_name = transform.Find("player_info/text_name").GetComponent<TMP_Text>();
text_player_head = transform.Find("player_info/text_name/btn_head").GetComponent<Head>();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eb99e1bb5ebd3b6499e45982aaf53e8c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,372 @@
using asap.core;
using cfg;
using DG.Tweening;
using Game;
using GameCore;
using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UniRx;
public class AquariumReportPopupPanel : MonoBehaviour
{
public Button btn_next;
public GameObject receive;
public GameObject photo;
public TMP_Text text_gold;
public TMP_Text text_energy;
public TMP_Text txt_diamond;
public TMP_Text text_num;
public GameObject[] _lights;
public float showTime = 0.3f;
public Transform reward_show;
public RawImage icon;
public Image tag_fish;
public TMP_Text text_fish_name;
public Transform fishIconRT;
public RawImage rawImage;
RenderTexture rt;
Camera rtCamera;
Transform avatarCapture;
int fieldOfView = 60;
//鱼距离相机的位置
int fishPosZ = 20;
public GameObject mutated;
List<AquariumSlotData> aquariumSlotDatas;
AquariumSlotData curData;
int curIndex;
int allCount;
int Energy;
int curDiamond;
ulong Gold;
bool isClose;
bool isClickClose;
IDisposable disposable;
private Tables _tables;
Item item;
AquariumManager AM;
Vector3 startPosition;
FishingAquariumAct aquariumAct;
Item fishItem;
bool isEnable = true;
public SpriteRenderer bg_photo;
private void Awake()
{
_tables = GContext.container.Resolve<Tables>();
item = _tables.TbItem.GetOrDefault(1002);
AM = GContext.container.Resolve<AquariumManager>();
aquariumSlotDatas = AM.sellList;
Energy = GContext.container.Resolve<PlayerData>().Energy;
Gold = GContext.container.Resolve<PlayerData>().gold;
curDiamond = GContext.container.Resolve<PlayerData>().diamond;
ShowItemCount();
text_energy.text = ConvertTools.GetNumberString2(Energy);
text_gold.text = ConvertTools.GetNumberString2(Gold);
txt_diamond.text = ConvertTools.GetNumberString2(curDiamond);
allCount = aquariumSlotDatas.Count;
avatarCapture = fishIconRT.Find("avatarCapture");
rtCamera = fishIconRT.Find("Camera").GetComponent<Camera>();
startPosition = avatarCapture.localPosition;
curIndex = 0;
disposable = GContext.OnEvent<ResAddEvent>().Subscribe(x =>
{
NumPlay(x.id);
});
}
public void InitData(FishingAquariumAct aquariumAct)
{
this.aquariumAct = aquariumAct;
SetRT();
SetData();
}
void SetRT()
{
fishIconRT.transform.position = Vector3.back * 30;
RectTransform raw = rawImage.GetComponent<RectTransform>();
rt = new RenderTexture((int)raw.rect.width, (int)raw.rect.height, 24, RenderTextureFormat.ARGB32);
rtCamera.fieldOfView = fieldOfView;
rtCamera.enabled = true;
rtCamera.targetTexture = rt;
rawImage.texture = rt;
rtCamera.Render();
}
private void Start()
{
var mapData = _tables.TbMapData.DataMap[AM.MapId];
string prefabName = mapData.AquariumPrefab;
Transform bg = photo.transform.Find($"bg_{prefabName}");
if (bg != null)
{
bg_photo.sprite = bg.GetComponent<Image>().sprite;
}
btn_next.onClick.AddListener(OnClickNext);
}
async void ShowFish()
{
GameObject fishGo = await aquariumAct.LoadFish(curData.index, avatarCapture);
if (fishGo != null)
{
var fishData = _tables.TbFishData.GetOrDefault(fishItem.RedirectID);
var TankPosition = fishData.TankPosition;
Vector3 pos = new Vector3(TankPosition[0], TankPosition[1], TankPosition[2] + fishPosZ);
Transform avatar = avatarCapture;
pos += startPosition;
avatar.localPosition = pos;
//fish.transform.localPosition = pos;
}
}
async void SetData()
{
isClose = false;
isClickClose = false;
curData = aquariumSlotDatas[curIndex];
mutated.SetActive(curData.mutants > 0);
photo.SetActive(false);
fishItem = _tables.TbItem.GetOrDefault(curData.fishItemID);
ShowFish();
photo.SetActive(true);
text_fish_name.text = LocalizationMgr.GetText(fishItem.Name_l10n_key);
GContext.container.Resolve<IUIService>().SetImageSprite(tag_fish, "icon_fish_rate_tag_" + fishItem.Quality);
int audioName = curIndex % 4 + 1;
GContext.Publish(new EventUISound($"audio_ui_getreward_{audioName}"));
float showCount = curData.allCash;
ItemShow itemShow = GContext.container.Resolve<Tables>().TbItemShow.GetOrDefault(1002);
int light_index = 1;
if (itemShow != null)
{
light_index = 0;
showCount = (showCount / GContext.container.Resolve<PlayerItemData>().ExtraCoinMag());
for (int i = itemShow.Count.Count - 1; i >= 0; i--)
{
if (showCount > itemShow.Count[i])
{
light_index = i + 1;
break;
}
}
}
if (light_index >= _lights.Length)
{
light_index = _lights.Length - 1;
}
for (int i = 0; i < _lights.Length; i++)
{
_lights[i].SetActive(i == light_index);
}
curIndex++;
receive.SetActive(false);
receive.SetActive(true);
var progress = 0f;
//text_num.text = ConvertTools.GetNumberString2(curData.cash);
int cash = curData.cash;
DOTween.Kill("AddCash");
await Awaiters.Seconds(showTime);
DOTween.To(() => progress, x => progress = x, 1f, 0.8f).OnUpdate(() =>
{
text_num.text = ConvertTools.GetNumberString2((int)(cash * progress));
}).SetId("AddCash");
await Awaiters.Seconds(0.5f);
await ParticleAttractor(showCount);
isClose = true;
if (isClickClose)
{
Close();
}
}
void NumPlay(int id)
{
if (id != 1002)
{
return;
}
GoldAddAnim(curData.cash);
}
void GoldAddAnim(float add)
{
DOTween.Kill("report_text_gold");
text_gold.text = ConvertTools.GetNumberString2(Gold);
float progress = 0;
ulong glod = Gold;
DOTween.To(() => progress, x => progress = x, 1, 0.4f).OnUpdate(() =>
{
Gold = glod + (ulong)(add * progress);
text_gold.text = ConvertTools.GetNumberString2(Gold);
}).SetDelay(0.5f).SetId("report_text_gold");
}
void ShowItemCount()
{
if (aquariumSlotDatas != null)
{
for (int i = 0; i < aquariumSlotDatas.Count; i++)
{
ulong curGold = (ulong)aquariumSlotDatas[i].cash;
if (Gold > curGold)
{
Gold -= curGold;
}
}
}
}
void Close()
{
isClickClose = false;
isClose = false;
receive.SetActive(false);
UIManager.Instance.DestroyUI(UITypes.AquariumReportPopupPanel);
if (AM.data.isHome)
{
FishingAquariumAct.eventAggregator.Publish(new AquariumEnterMapScene());
}
}
void OnClickNext()
{
if (curIndex >= allCount)
{
receive.SetActive(false);
if (isClose)
{
Close();
}
else
{
isClickClose = true;
}
return;
}
SetData();
}
public async System.Threading.Tasks.Task ParticleAttractor(float showCount)
{
//1001 1002 另外一种配法
//ItemShow itemShow = _tables.TbItemShow.GetOrDefault(item.ID);
//string fxName = itemShow.Fx[0];
//for (int i = itemShow.Count.Count - 1; i >= 0; i--)
//{
// if (showCount > itemShow.Count[i])
// {
// fxName = itemShow.Fx[i + 1];
// break;
// }
//}
string fxName = "fx_ui_reward_common_money_01";// item.Fx;
if (fishItem.Quality > 3)
{
fxName = "fx_ui_reward_common_money_02";
}
Transform fxP = reward_show.Find(fxName);
if (fxP == null)
{
GContext.Publish(new ResAddEvent(item.ID, item.Type, item.SubType));
return;
}
GameObject fx = Instantiate(fxP.gameObject, reward_show);
ParticleSystem particleSystem = fx.transform.Find("Scale/quan03").GetComponent<ParticleSystem>();
if (particleSystem != null)
{
reward_show.gameObject.SetActive(true);
//fx.transform.position = transform.position;
ParticleAttractorData particleAttractorData = new ParticleAttractorData()
{
Type = item.Type,
SubType = item.SubType,
Priority = -1,
};
GContext.Publish(particleAttractorData);
if (particleAttractorData.Priority > -1 && particleAttractorData.uIParticleAttractorCenter != null)
{
var particleRenderer = particleSystem.GetComponent<ParticleSystemRenderer>();
var sprite = icon.texture;
var uIParticleAttractorCenter = particleAttractorData.uIParticleAttractorCenter;
//多个粒子飞向同一个target时,隐藏前一个粒子
var particleAttractor = uIParticleAttractorCenter.GetUIParticleAttractor();
particleAttractor?.Clear();
particleAttractor.particleSystem = null;
//particleAttractor.enabled = false;
Texture texture = sprite;// await GContext.container.Resolve<IUIService>().GetTexture(item.Icon, "RewardPopupPanel");
if (!isEnable)
{
return;
}
//_TextureSample0
particleRenderer.material.SetTexture("_TextureSample0", texture);
//particleRenderer.material.SetTextureScale("_TextureSample0", new Vector2(sprite.textureRect.width / texture.width, sprite.textureRect.height / texture.height));
//particleRenderer.material.SetTextureOffset("_TextureSample0", new Vector2(sprite.textureRect.x / texture.width, sprite.textureRect.y / texture.height));
particleSystem.Clear();
var main = particleSystem.main;
int maxCount = main.maxParticles;
if (showCount < maxCount)
{
int addCount = (int)showCount;
main.maxParticles = addCount;
//var emission = particleSystem.emission;
//emission.rateOverTime = 0;
//emission.SetBursts(new ParticleSystem.Burst[] { new ParticleSystem.Burst(0.0f, addCount) });
}
fx.SetActive(true);
if (particleAttractor != null)
{
particleAttractor.particleSystem = particleSystem;
particleAttractor.enabled = true;
}
await Awaiters.Seconds(0.2f);
if (!isEnable)
{
return;
}
GContext.Publish(new ResAddEvent(item.ID, item.Type, item.SubType));
await Awaiters.Seconds(1.8f);
if (!isEnable)
{
return;
}
if (particleAttractor != null && particleAttractor.particleSystem == particleSystem)
{
particleAttractor.Clear();
particleAttractor.enabled = false;
particleAttractor = null;
}
}
}
Destroy(fx);
return;
}
private void OnDisable()
{
isEnable = false;
disposable?.Dispose();
disposable = null;
rtCamera.targetTexture = null;
if (rt != null)
{
rt.Release();
Destroy(rt);
rt = null;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 677c3f4971f9f104e88f80a951ef4b22
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,78 @@
using asap.core;
using cfg;
using GameCore;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class AquariumReportPopupPanelOld : MonoBehaviour
{
Button btn_confirm;
TMP_Text text_num;
AquariumManager AM;
GameObject fishItemPrefab;
Transform fish_info_root;
Tables tables;
private void Awake()
{
tables = GContext.container.Resolve<Tables>();
AM = GContext.container.Resolve<AquariumManager>();
text_num = transform.Find("root/bg_reward/text_num").GetComponent<TMP_Text>();
btn_confirm = transform.Find("root/btn_confirm/btn_green").GetComponent<Button>();
fish_info_root = transform.Find("root/fish_info1");
fishItemPrefab = transform.Find("root/fish_info1/fish").gameObject;
}
private void Start()
{
btn_confirm.onClick.AddListener(OnClickConfirm);
int allCash = 0;
AquariumReportFishItem fishItem = null;
Item item = null;
MapData mapData = tables.TbMapData.GetOrDefault(AM.data.mapId);
IUIService uiService = GContext.container.Resolve<IUIService>();
List<AquariumResultData> aquariumReportDatas = AM.data.aquariumResultDatas;
for (int i = 0; i < AM.data.slot; i++)
{
fishItem = Instantiate(fishItemPrefab, fish_info_root).GetComponent<AquariumReportFishItem>();
fishItem.gameObject.SetActive(true);
fishItem.index = i;
AquariumResultData aquariumSettlementData = aquariumReportDatas[i];
AquariumSlotData slotData = AM.data.slotDatas[i];
item = tables.TbItem.GetOrDefault(slotData.fishItemID);
PlayerFishData.SetFishIcon(fishItem.fish_icon, item);//鱼头像
uiService.SetImageSprite(fishItem.icon_rate, "icon_fish_rate_tag_" + item.Quality);
var bgbg = fishItem.mask_bg.Find(mapData.AquariumBg);
bgbg.gameObject.SetActive(true);
AquariumEgg aquariumEgg = GContext.container.Resolve<Tables>().TbAquariumEgg.GetOrDefault(slotData.eggId);
if (aquariumEgg != null)
{
uiService.SetImageSprite(fishItem.icon_egg, aquariumEgg.Icon);
}
fishItem.fish_info.SetActive(slotData.cash > 0);
fishItem.player_info.SetActive(slotData.cash <= 0);
if (slotData.cash > 0)
{
fishItem.text_fish_name.text = LocalizationMgr.GetText(item.Name_l10n_key);
fishItem.text_cash.text = ConvertTools.GetNumberString2(slotData.cash);
allCash += slotData.cash;
}
else if (slotData.cash <= 0)
{
fishItem.text_player_name.text = aquariumSettlementData.displayName;
fishItem.text_player_head.SetData(aquariumSettlementData.avatar);
}
}
text_num.text = ConvertTools.GetNumberString2(allCash);
}
void OnClickConfirm()
{
FishingAquariumAct.eventAggregator.Publish(new AquariumEnterMapScene());
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6c52c227bae65bc45884f488664a7156
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,255 @@
using asap.core;
using DG.Tweening;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AquariumSlot : MonoBehaviour
{
public Button btn_click;
public Image icon_egg;
public GameObject mask_fish;
public Image icon_fish;
public Image icon_rate;
public GameObject selected;
public GameObject done;
public GameObject icon_hurt;
public GameObject icon_killed;
public GameObject icon_sold;
public GameObject redpoint;
public AquariumSlotData slotData;
public Image bar;
public Image bar_hurt;
Action<AquariumSlot> onClick;
Action onFishStateChange;
public int index;
/// <summary>
/// 1 == egg 2 == fish 3 == done 4 == sell 5 == lose
/// </summary>
[HideInInspector]
public int slotState = 0;
AquariumManager AM;
//private void Reset()
//{
// btn_click = GetComponent<Button>();
// icon_egg = transform.Find("icon_egg").GetComponent<Image>();
// mask_fish = transform.Find("mask_fish").gameObject;
// icon_fish = transform.Find("mask_fish/icon_fish").GetComponent<Image>();
// icon_rate = transform.Find("mask_fish/icon_rate").GetComponent<Image>();
// selected = transform.Find("selected").gameObject;
// done = transform.Find("mask_fish/done").gameObject;
// icon_hurt = transform.Find("icon_hurt").gameObject;
// icon_killed = transform.Find("icon_killed").gameObject;
// icon_sold = transform.Find("icon_sold").gameObject;
// redpoint = transform.Find("redpoint").gameObject;
// bar = transform.Find("bg_bar/bar").GetComponent<Image>();
// bar_hurt = transform.Find("bg_bar/bar_hurt").GetComponent<Image>();
//}
private void Awake()
{
redpoint.SetActive(false);
btn_click.onClick.AddListener(OnClick);
}
void OnClick()
{
//if (slotState == 4)
//{
// return;
//}
onClick?.Invoke(this);
}
public void InitSlot(int index, AquariumSlotData slotData, Action<AquariumSlot> onClick, Action onFishStateChange)
{
AM = GContext.container.Resolve<AquariumManager>();
this.index = index;
this.slotData = slotData;
this.onClick = onClick;
this.onFishStateChange = onFishStateChange;
SetState();
InitBar();
}
public void SetState()
{
DateTime dateTime = ZZTimeHelper.UtcNow();
var HatchTime = slotData.FishHatchTime();
var FishGrowthTime = slotData.FishGrowthTime();
bool isHatch = HatchTime < dateTime;
TimeSpan offsetTime = new TimeSpan();
bool isUpdate = false;
done.gameObject.SetActive(false);
icon_hurt.gameObject.SetActive(false);
bar_hurt.gameObject.SetActive(false);
icon_killed.gameObject.SetActive(false);
bar.gameObject.SetActive(true);
redpoint.SetActive(false);
if (isHatch)
{
//鱼鱼
slotState = 2;
icon_egg.gameObject.SetActive(false);
mask_fish.gameObject.SetActive(true);
bool growth = FishGrowthTime < dateTime;
List<AquariumResultData> aquariumReportDatas = AM.data.aquariumResultDatas;
//售卖或者丢失
if (slotData.IsResult())
{
slotState = 4;
//btn_click.enabled = false;
done.gameObject.SetActive(true);
icon_sold.gameObject.SetActive(true);
bar.gameObject.SetActive(false);
}
else if (aquariumReportDatas[slotData.index].IsResult())
{
slotState = 5;
icon_killed.gameObject.SetActive(true);
done.gameObject.SetActive(true);
bar.gameObject.SetActive(false);
}
else
{
//检查是否受伤
//正常的成长时间 自然时间+加速成长-总恢复时间
float normalH = (float)(dateTime - HatchTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
float injuryH = slotData.injuryGrowthTime;
//受伤时的成长进度大于正常的成长进度=还没恢复
isUpdate = true;
if (injuryH > normalH)
{
bar.gameObject.SetActive(false);
bar_hurt.gameObject.SetActive(true);
icon_hurt.gameObject.SetActive(true);
offsetTime = dateTime.AddHours(injuryH - normalH) - dateTime;
}
else if (growth)
{
//成熟并且没有受伤
slotState = 3;
isUpdate = false;
redpoint.SetActive(true);
}
else
{
bar_hurt.gameObject.SetActive(false);
icon_hurt.gameObject.SetActive(false);
offsetTime = FishGrowthTime - dateTime;
}
}
}
else
{
isUpdate = true;
offsetTime = HatchTime - dateTime;
//蛋蛋
slotState = 1;
icon_egg.gameObject.SetActive(true);
mask_fish.gameObject.SetActive(false);
done.gameObject.SetActive(false);
}
if (isUpdate)
{
StartCoroutine(UpdateTime((float)offsetTime.TotalSeconds));
}
}
void InitBar()
{
if (slotState == 5)
{
bar.fillAmount = 0;
return;
}
if (slotState == 4)
{
bar.fillAmount = 0;
return;
}
DateTime dateTime = ZZTimeHelper.UtcNow();
if (slotState == 1)
{
float time = (float)(dateTime - slotData.startTime).TotalHours + slotData.accelerationHatch;
bar.fillAmount = time / slotData.hatchTime;
return;
}
var StartTime = slotData.FishHatchTime();
//正常的成长进度 自然时间+加速成长 - 全部恢复时间
float normalH = (float)(dateTime - StartTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
//受伤时的成长进度
float injuryH = slotData.injuryGrowthTime;
//受伤时的成长进度大于正常的成长进度
float timeProgress = 1;
if (injuryH > normalH)
{
bar_hurt.fillAmount = (injuryH - normalH) / slotData.growthTime;
timeProgress = 0;// injuryH / slotData.growthTime;
}
else if (normalH < slotData.growthTime)
{
timeProgress = normalH / slotData.growthTime;
}
bar.fillAmount = timeProgress;
}
public void UpdateBar(DateTime dateTime)
{
if (slotState == 5)
{
bar.fillAmount = 0;
return;
}
if (slotState == 4)
{
//bar.DOFillAmount(1, 0.9f);
bar.fillAmount = 0;
return;
}
if (slotState == 1)
{
float time = (float)(dateTime - slotData.startTime).TotalHours + slotData.accelerationHatch;
var fillAmount = time / slotData.hatchTime;
bar.DOFillAmount(fillAmount, 0.9f);
return;
}
var StartTime = slotData.FishHatchTime();
//正常的成长进度 自然时间+加速成长 - 全部恢复时间
float normalH = (float)(dateTime - StartTime).TotalHours + slotData.accelerationGrowth - slotData.allRecoveryTime;
//受伤时的成长进度
float injuryH = slotData.injuryGrowthTime;
//受伤时的成长进度大于正常的成长进度
float timeProgress = 1;
if (injuryH > normalH)
{
var fillAmount = (injuryH - normalH) / slotData.recoveryTime;
bar_hurt.DOFillAmount(fillAmount, 0.9f);
//timeProgress = injuryH / slotData.growthTime;
bar.fillAmount = 0;
}
else if (normalH < slotData.growthTime)
{
timeProgress = normalH / slotData.growthTime;
bar.DOFillAmount(timeProgress, 0.9f);
}
else
{
bar.DOFillAmount(timeProgress, 0.9f);
}
}
IEnumerator UpdateTime(float s)
{
yield return new WaitForSeconds(s);
//发送事件,状态修改
onFishStateChange?.Invoke();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4fbf14b1ce2402a4981f9ff90a46787d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,93 @@
using asap.core;
using game;
using GameCore;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AquariumUpdatePopupPanel : MonoBehaviour
{
Transform map;
RewardItemNew[] rewards;
Button btn_sure;
bool isShowBox;
private void Awake()
{
btn_sure = transform.Find("root/bg/btn_sure/btn_green").GetComponent<Button>();
map = transform.Find("root/bg/rewards");
rewards = map.GetComponentsInChildren<RewardItemNew>();
}
private void Start()
{
OpenBox();
btn_sure.onClick.AddListener(OnBtnSure);
}
void OnBtnSure()
{
UIManager.Instance.DestroyUI(UITypes.AquariumUpdatePopupPanel);
}
void OpenBox()
{
var _dataProvider = GContext.container.Resolve<FishingBoxDataProvier>();
Dictionary<int, int> FishingBoxs = _dataProvider.Data.FishingBoxs;
isShowBox = false;
int index = 0;
foreach (var box in FishingBoxs)
{
var boxCount = box.Value;
if (boxCount > 0)
{
int id = box.Key;
isShowBox = true;
rewards[index].SetData(new ItemData(id, boxCount));
}
rewards[index].gameObject.SetActive(boxCount > 0);
index++;
if (index >= 5)
{
break;
}
}
map.gameObject.SetActive(isShowBox);
}
private void OnDisable()
{
if (isShowBox)
{
var _dataProvider = GContext.container.Resolve<FishingBoxDataProvier>();
Dictionary<int, int> FishingBoxs = _dataProvider.Data.FishingBoxs;
var FishingNewBoxs = _dataProvider.Data.FishingNewBoxs;
int index = 0;
foreach (var box in FishingBoxs)
{
var boxCount = box.Value;
if (boxCount > 0)
{
int id = box.Key;
if (FishingNewBoxs.ContainsKey(id))
{
FishingNewBoxs[id] += boxCount;
}
else
{
FishingNewBoxs.Add(id, boxCount);
}
}
index++;
if (index >= 5)
{
break;
}
}
_dataProvider.Data.FishingBoxs.Clear();
_dataProvider.Data.Save();
GContext.Publish(new ShowData(null, RewardType.FishBoxOpen, 1));
}
GContext.Publish(new FaceUICloseEvent());
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 93eaf9df0cfde5046bbc6894e930afbd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

Some files were not shown because too many files have changed in this diff Show More