This commit is contained in:
2024-10-16 00:03:41 +08:00
commit 897058435c
5033 changed files with 1009728 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6f44d1eccbd24d9bb534eff45185e56e
timeCreated: 1675317961

View File

@@ -0,0 +1,142 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditor.Build.Reporting;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace BuildEditor
{
public class BuildTools
{
// [MenuItem("Build/自动化构建ab包")]
private static void BuildAssetBundle(bool isTest)
{
}
#if UNITY_ANDROID
[MenuItem("Build/Build Taptap (需要先打ab包)")]
public static void BuildTaptap()
{
GameGlobalConfig.Instance.Channel = GameChannel.Taptap;
BuildStandalonePlayer(BuildOptions.ShowBuiltPlayer);
}
[MenuItem("Build/Build 快爆 (需要先打ab包)")]
public static void BuildKuaibao()
{
GameGlobalConfig.Instance.Channel = GameChannel.Kuaibao;
BuildStandalonePlayer(BuildOptions.ShowBuiltPlayer);
}
[MenuItem("Build/Build 摸摸鱼 (需要先打ab包)")]
public static void BuildMomoyu()
{
GameGlobalConfig.Instance.Channel = GameChannel.Momoyu;
BuildStandalonePlayer(BuildOptions.ShowBuiltPlayer);
}
[MenuItem("Build/一键打包 测试包 自动build ab包")]
public static void BuildTest()
{
BuildAssetBundle(true);
GameGlobalConfig.Instance.Channel = GameChannel.Private;
BuildStandalonePlayer(BuildOptions.ShowBuiltPlayer);
}
[MenuItem("Build/构建所有渠道包 (自动build ab包)")]
public static void BuildAll ()
{
BuildAssetBundle(false);
GameGlobalConfig.Instance.Channel = GameChannel.Taptap;
BuildStandalonePlayer();
GameGlobalConfig.Instance.Channel = GameChannel.Kuaibao;
BuildStandalonePlayer();
GameGlobalConfig.Instance.Channel = GameChannel.Momoyu;
BuildStandalonePlayer(BuildOptions.ShowBuiltPlayer);
}
#endif
public static void BuildStandalonePlayer(BuildOptions buildOptions = BuildOptions.None)
{
#if !UNITY_IOS
CheckKeyPwd();
#endif
var outputPath =
Path.Combine(Environment.CurrentDirectory,
"Build/" + Application.version); //EditorUtility.SaveFolderPanel("Choose Location of the Built Game", "", "");
if (outputPath.Length == 0)
return;
var levels = new List<string>();
for (int i = 0; i < SceneManager.sceneCount; i++)
{
var sceneAt = SceneManager.GetSceneAt(i);
if (sceneAt.IsValid())
{
levels.Add(sceneAt.path);
}
}
if (levels.Count == 0)
{
Debug.Log("Nothing to build.");
return;
}
var targetName = "/" + Application.identifier +
$"_{GameGlobalConfig.Instance.Channel}_{Application.version}.apk";
#if GM
targetName = targetName.Replace(".apk", "[GM].apk");
#endif
if (targetName == null)
return;
#if UNITY_5_4 || UNITY_5_3 || UNITY_5_2 || UNITY_5_1 || UNITY_5_0
BuildOptions option = EditorUserBuildSettings.development ? BuildOptions.Development : BuildOptions.None;
BuildPipeline.BuildPlayer(levels, path + targetName, EditorUserBuildSettings.activeBuildTarget, option);
#else
var buildPlayerOptions = new BuildPlayerOptions
{
scenes = levels.ToArray(),
locationPathName = outputPath + targetName,
target = EditorUserBuildSettings.activeBuildTarget,
options = EditorUserBuildSettings.development
? BuildOptions.Development
: buildOptions
// : BuildOptions.AutoRunPlayer
};
var buildPlayer = BuildPipeline.BuildPlayer(buildPlayerOptions);
BuildSummary summary = buildPlayer.summary;
if (summary.result == BuildResult.Succeeded)
{
Debug.Log("构建应用成功: " + summary.totalSize / (1024 * 1024.0f * 10) + " mb");
Debug.Log("构建应用地址: " + summary.outputPath);
}
if (summary.result == BuildResult.Failed)
{
Debug.Log("构建应用失败");
}
#endif
}
[MenuItem("Build/Check KeyPwd")]
public static void CheckKeyPwd()
{
if (string.IsNullOrEmpty(PlayerSettings.keystorePass))
{
PlayerSettings.keystorePass = "123456";
PlayerSettings.keyaliasPass = "123456";
}
}
[MenuItem("Build/打开持久化存储目录")]
private static void ViewDataPath()
{
EditorUtility.OpenWithDefaultApp(Application.persistentDataPath);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 56af7c6b7d3643caa7be9ff9eef17fbb
timeCreated: 1675317962

View File

@@ -0,0 +1,28 @@
#if UNITY_EDITOR
using System;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
public class MsvcStdextWorkaround : IPreprocessBuildWithReport
{
const string kWorkaroundFlag = "/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS";
public int callbackOrder => 0;
public void OnPreprocessBuild(BuildReport report)
{
var clEnv = Environment.GetEnvironmentVariable("_CL_");
if (string.IsNullOrEmpty(clEnv))
{
Environment.SetEnvironmentVariable("_CL_", kWorkaroundFlag);
}
else if (!clEnv.Contains(kWorkaroundFlag))
{
clEnv += " " + kWorkaroundFlag;
Environment.SetEnvironmentVariable("_CL_", clEnv);
}
}
}
#endif // UNITY_EDITOR

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dde1f974eccb4e17bd3e13704162c4cd
timeCreated: 1675421696

3
Assets/Scripts/Game.meta Normal file
View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c361469f1ccd4021a897fcdfab37157b
timeCreated: 1687791732

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 84344f6921334139804e2bf9eec56d8e
timeCreated: 1687791817

View File

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

View File

@@ -0,0 +1,109 @@
using System;
using System.RandomPool;
using Coffee.UIExtensions;
using Game.Data;
using Sirenix.OdinInspector;
using UnityEngine;
namespace Game.Component
{
[Serializable]
public class CardEffectNode : MonoBehaviour
{
public enum EffectAnimState
{
Close = 0, //卡牌背面状态
StartShow, //点击翻开
Opened //完成翻转
}
[SerializeField] private bool HasUIParticle;
[SerializeField, HideIf ("HasUIParticle")]
private ParticleSystem Effect;
[SerializeField, ShowIf ("HasUIParticle")]
private UIParticle UiEffect;
[SerializeField] private EffectAnimState State;
[SerializeField] private CardQuality Quality;
[SerializeField] private bool IsSoleQuality; //是否唯一展示
[SerializeField] private bool IsCloseActive; //是否在不满足指定State状态下主动关闭当前特效的GameObject.Active状态
[SerializeField] private bool OverlyColor;
[SerializeField, ShowIf ("OverlyColor")]
private Color[] QualityColors;
private GameObject EffectObject => this.HasUIParticle ? this.UiEffect.gameObject : this.Effect.gameObject;
public void CheckNode (EffectAnimState state , CardQuality quality)
{
if (state == this.State)
{
if (this.OverlyColor)
{
if (this.HasUIParticle)
{
this.UiEffect.color = this.QualityColors[(int)quality];
}
else
{
var effectMain = this.Effect.main;
effectMain.startColor = new ParticleSystem.MinMaxGradient (this.QualityColors[(int)quality]);
}
}
if (!this.IsSoleQuality && (int)quality >= (int)this.Quality)
{
SetActive (true);
return;
}
if (this.IsSoleQuality && quality == this.Quality)
{
SetActive (true);
return;
}
}
if (this.IsCloseActive)
{
SetActive (false);
}
}
private void SetActive (bool isActive)
{
if (isActive)
{
this.EffectObject.gameObject.SetActive (true);
if (this.HasUIParticle)
{
this.UiEffect.Stop ();
this.UiEffect.Play ();
}
else
{
this.Effect.Stop();
this.Effect.Simulate (0 , false , true);
// this.Effect.Play (false);
}
}
else
{
this.EffectObject.gameObject.SetActive (false);
}
}
public void ResetNode ()
{
var effectGameObject = this.EffectObject;
if (effectGameObject.activeSelf)
{
effectGameObject.SetActive (false);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9e073f35f6834fc7a977ea9b3cd2615a
timeCreated: 1690553292

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.RandomPool;
using System.Utils;
using Framework.Timer;
using Game.Data;
using UnityEngine;
namespace Game.Component
{
public class CardEffectShower : DoubleCardEntity
{
private static readonly Dictionary<CardQuality , Color> _COLORS = new Dictionary<CardQuality, Color>
{
{CardQuality.N , new Color (0.86f, 0.91f, 1f)},
{CardQuality.R , new Color (0.23f, 0.65f, 1f)},
{CardQuality.SR , new Color (0.73f, 0.31f, 1f)},
{CardQuality.SSR , new Color (1f, 0.47f, 0.07f)},
{CardQuality.UR , new Color (1f, 0.95f, 0f)},
{CardQuality.SP , new Color (1f, 0.26f, 0.3f)},
};
[SerializeField] private List<CardEffectNode> _effectNodes;
[SerializeField] private float _openDelay;
[SerializeField] private float _openDuration;
[SerializeField] private MultiGraphicControl _graphicControl;
private TimeHandler _timeHandler;
private CardQuality _quality;
private Action _callback;
public void Init (CardQuality quality , Transform cameraTransform)
{
ResetNode ();
this.Init (cameraTransform , -1);
this._quality = quality;
}
public void ClickOpen (Action action)
{
this._callback = action;
if (this._timeHandler != null && this._timeHandler.IsPlaying)
{
return;
}
CheckEffectNode (CardEffectNode.EffectAnimState.StartShow);
this._timeHandler = GameUpdateMgr.Instance.CreateTimer (this._openDelay , () =>
{
this.ToFore (this._openDuration , ShowCardComplete);
});
}
public void NotAnimOpen (Action action)
{
this._callback = action;
this.ToFore (0 , ShowCardComplete);
}
public void ClickClose ()
{
ResetNode ();
this.ToBreak (0);
}
private void ShowCardComplete ()
{
this._graphicControl.gameObject.SetActive (true);
this._graphicControl.SetColor (_COLORS[this._quality]);
CheckEffectNode (CardEffectNode.EffectAnimState.Opened);
this._callback?.Invoke ();
}
private void CheckEffectNode (CardEffectNode.EffectAnimState state)
{
foreach (var effectNode in this._effectNodes)
{
effectNode.CheckNode (state , this._quality);
}
}
private void ResetNode ()
{
foreach (var effectNode in this._effectNodes)
{
effectNode.ResetNode ();
}
this._graphicControl.gameObject.SetActive (false);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a1e39e9117364e04984f04aa5f32a808
timeCreated: 1690548997

View File

@@ -0,0 +1,10 @@
using UnityEngine;
namespace Game.Component
{
public abstract class CardShower : MonoBehaviour
{
public abstract void ShowCard ();
public abstract void HideCard ();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 80f005ef790e41d9acb6753c32d49d6b
timeCreated: 1690511851

View File

@@ -0,0 +1,129 @@
using System;
using Framework.Timer;
using Framework.Utils;
using UnityEngine;
namespace Game.Component
{
/// <summary>
/// 双面卡牌容器
/// </summary>
public class DoubleCardEntity : MonoBehaviour
{
[SerializeField] private Transform _entity; //容器
[SerializeField] private CardShower _foreCard; //正面卡牌
[SerializeField] private CardShower _breakCard; //背面卡牌
private Transform _camera;
private TimeHandler _animHandler;
private int _curCardState;
private int _targetCardState;
private Action _callback;
private bool _hasFore => Vector3.Dot (this._camera.forward , this._entity.forward) < 0;
public bool IsOpen => this._targetCardState == 1;
public CardShower ForeCard => this._foreCard;
public CardShower BreakCard => this._breakCard;
private int CurCardState
{
get => this._curCardState;
set
{
if (value != this._curCardState)
{
this._curCardState = value;
if (value == -1)
{
this._breakCard.ShowCard ();
this._foreCard.HideCard ();
}
else if (value == 0)
{
this._breakCard.HideCard ();
this._foreCard.HideCard ();
}
else if (value == 1)
{
this._breakCard.HideCard ();
this._foreCard.ShowCard ();
}
}
}
}
public void Init (Transform cameraTransform , int defaultState = 0)
{
this._camera = cameraTransform;
this._curCardState = -2;
SetTargetCard (defaultState, 0 , null);
}
public void ToFore (float duration , Action callback = null)
{
SetTargetCard (1 , duration , callback);
}
public void ToBreak (float duration, Action callback = null)
{
SetTargetCard (-1 , duration , callback);
}
private void SetTargetCard (int target, float duration , Action callback)
{
if (this.CurCardState == target && (this._animHandler == null || this._animHandler.IsDone))
{
callback?.Invoke ();
return;
}
this._animHandler?.Kill ();
this._callback = callback;
this._targetCardState = target;
this._animHandler = GameUpdateMgr.Instance.CreateTimer (duration , UpdateCardComplete , UpdateCard);
}
private void UpdateCardComplete ()
{
var targetEuler = this._targetCardState == 1 ? 0 : 180;
this._entity.eulerAngles = new Vector3 (0 , targetEuler , 0);
CheckCard ();
this._callback?.Invoke ();
}
private void UpdateCard (float progress)
{
var targetEuler = -180;
progress = this._targetCardState == 1 ? 1 - progress : progress;
var euler = targetEuler * progress;
this._entity.eulerAngles = new Vector3 (0 , euler , 0);
CheckCard ();
}
public void CheckCard ()
{
if (this._hasFore)
{
//背面
this.CurCardState = -1;
}
else
{
//正面
this.CurCardState = 1;
}
}
public void ResetData ()
{
this._animHandler?.Kill ();
this._curCardState = -2;
this._targetCardState = 0;
this._callback = null;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 540970c3a9534747af243d3e250a9e14
timeCreated: 1690510273

View File

@@ -0,0 +1,26 @@
using UnityEngine;
using UnityEngine.Events;
namespace Game.Component
{
public class NoneCardShower : CardShower
{
[SerializeField] private UnityEvent onCardShow;
[SerializeField] private UnityEvent onCardHide;
public override void ShowCard ()
{
this.gameObject.SetActive (true);
this.onCardShow?.Invoke ();
}
public override void HideCard ()
{
this.gameObject.SetActive (false);
this.onCardHide?.Invoke ();
}
public UnityEvent OnCardShow => this.onCardShow;
public UnityEvent OnCardHide => this.onCardHide;
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 89d9ca0ad1244f4fa5b3e50eecd50247
timeCreated: 1690511924

View File

@@ -0,0 +1,232 @@
using System;
using Framework.Timer;
using Pathfinding;
using UnityEngine;
using XFFSM;
namespace Game.Component
{
public class EnemyEntity : MonoBehaviour
{
[Serializable]
public class FsmData
{
public bool HasAttack;
public bool HasSafeArea;
public bool HasRunaway;
public bool HasActive = true;
}
[SerializeField] protected FSMController _fsmController;
[SerializeField] protected AILerp _aiLerp;
[Header ("最大活动区域")] public Vector2 ActiveArea = new Vector2 (10 , 5);
[Header ("随机巡逻区域")] public Vector2 WalkArea = new Vector2 (5 , 5);
[Header ("攻击检测半径")] public float TriggerDistance = -1f;
[Header ("追逐检测半径")] public float FollowDistance = -1f;
[Header ("攻击最小持续时间")] public float AttackStateDuration = 5f; //攻击状态最小持续时间
[Header ("仇恨丢失冷却时间")] public float AttackCDDuration = 2f;
[Header ("单位移动速度")] public float MoveSpeed = 3;
private FsmData _fsmData;
private float _curAttackingTime;
private float _curAttackCDTime;
//出生点
[HideInInspector] public Vector2 CreatePos;
#if UNITY_EDITOR
public bool IsDebugDraw = true;
private void OnDrawGizmos ()
{
this._aiLerp.speed = this.MoveSpeed;
if (!IsDebugDraw)
{
return;
}
var enemyTransform = this.transform.position;
//基于CreatePos为中心点绘制一个矩形,宽高为ActiveArea 用于表示此单位的活动区域
if (!UnityEditor.EditorApplication.isPlaying)
{
this.CreatePos = enemyTransform;
}
if (this.ActiveArea.y != 0 && this.ActiveArea.x != 0)
{
UnityEditor.Handles.color = new Color (0f, 1f, 0f, 0.5f);
UnityEditor.Handles.DrawSolidRectangleWithOutline (
new Rect (CreatePos.x - ActiveArea.x / 2, CreatePos.y - ActiveArea.y / 2, ActiveArea.x, ActiveArea.y),
new Color (0f, 1f, 0f, 0.25f),
Color.black);
// 在圆顶部绘制文本“活动范围”
UnityEditor.Handles.Label (CreatePos + new Vector2 (0f, ActiveArea.y / 2), "活动范围");
}
if ( this.WalkArea.y != 0 && this.WalkArea.x != 0)
{
UnityEditor.Handles.color = new Color (0f, 0f, 1f, 0.5f);
UnityEditor.Handles.DrawSolidRectangleWithOutline (
new Rect (CreatePos.x - this.WalkArea.x / 2, CreatePos.y - WalkArea.y / 2, WalkArea.x, WalkArea.y), new Color (0f, 0f, 1f, 0.25f),
Color.black);
// 在圆顶部绘制文本“巡逻范围”
UnityEditor.Handles.Label (CreatePos + new Vector2 (0f, WalkArea.y / 2), "巡逻范围");
}
if (TriggerDistance > 0)
{
//绘制一个半径为TriggerDistance的圆形
UnityEditor.Handles.color = new Color (1f, 0f, 0f, 0.5f);
UnityEditor.Handles.DrawSolidDisc (enemyTransform, Vector3.back, TriggerDistance);
//在圆顶部绘制文本“攻击范围”
UnityEditor.Handles.Label (enemyTransform + new Vector3 (0f, TriggerDistance, 0f), "攻击范围");
}
if (this.FollowDistance > 0 && this._curAttackingTime > 0)
{
//绘制一个半径为FollowDistance的圆形
UnityEditor.Handles.color = new Color (0.62f, 0f, 1f, 0.25f);
UnityEditor.Handles.DrawSolidDisc (enemyTransform, Vector3.back, FollowDistance);
//在圆顶部绘制文本“追逐范围”
UnityEditor.Handles.Label (enemyTransform + new Vector3 (0f, FollowDistance, 0f), "追逐范围");
}
if (UnityEditor.EditorApplication.isPlaying && this._fsmController.Initialized)
{
var currentStateInfo = this._fsmController.GetCurrentStateInfo (0);
//绘制文本
var text = "行动状态: " + currentStateInfo.data.DisplayName;
UnityEditor.Handles.Label (enemyTransform, text);
}
}
#endif
public AILerp AiLerp => this._aiLerp;
public bool HasAttack => this._curAttackingTime > 0;
public bool HasSafeArea
{
get
{
//检测当前位置是否在活动范围内, 如果不在活动范围内直接返回false
if (transform.position.x < this.CreatePos.x - this.ActiveArea.x / 2 ||
transform.position.x > this.CreatePos.x + this.ActiveArea.x / 2 ||
transform.position.y < this.CreatePos.y - this.ActiveArea.y / 2 ||
transform.position.y > this.CreatePos.y + this.ActiveArea.y / 2)
{
return false;
}
return true;
}
}
public bool HasRunaway { get; private set; } = false;
private void ResetState ()
{
_curAttackingTime = 0;
_curAttackCDTime = 0;
this._aiLerp.speed = this.MoveSpeed;
}
private void OnDisable ()
{
GameUpdateMgr.Instance.RemoveUpdater (DoUpdate);
}
private void OnEnable ()
{
if (!this._fsmController.Initialized)
{
Init ();
}
GameUpdateMgr.Instance.AddUpdater (DoUpdate);
ResetState ();
}
private void DoUpdate ()
{
if (_curAttackingTime > 0)
{
this._curAttackingTime -= Time.deltaTime;
if (this._curAttackingTime <= 0)
{
EndAttack ();
}
}
if (this._curAttackCDTime > 0)
{
_curAttackCDTime -= Time.deltaTime;
}
AttackCheck ();
CheckUpdateFsmData ();
}
private void AttackCheck ()
{
//处于攻击cd时不作攻击检测
if (_curAttackCDTime > 0)
{
return;
}
var hasAttack = false;
if (this._curAttackingTime > 0)
{
//追逐中使用追逐半径检测
hasAttack = this.FollowDistance < 0 ||
Vector2.Distance ( MapContent.Instance.PlayerPosition , this.transform.position) < this.FollowDistance;
}
else
{
hasAttack = this.TriggerDistance < 0 ||
Vector2.Distance ( MapContent.Instance.PlayerPosition , this.transform.position) < this.TriggerDistance;
}
if (hasAttack)
{
this._curAttackingTime = this.AttackStateDuration;
}
}
public void EndAttack ()
{
this._curAttackingTime = 0;
this._curAttackCDTime = this.AttackCDDuration;
}
public void CheckUpdateFsmData (bool isUpdate = false)
{
isUpdate |= _fsmData.HasAttack != this.HasAttack;
isUpdate |= _fsmData.HasSafeArea != this.HasSafeArea;
isUpdate |= _fsmData.HasRunaway != this.HasRunaway;
this._fsmData.HasAttack = HasAttack;
this._fsmData.HasSafeArea = HasSafeArea;
this._fsmData.HasRunaway = HasRunaway;
if (isUpdate)
{
this._fsmController.SetBool ("hasAttack", this._fsmData.HasAttack);
this._fsmController.SetBool ("hasSafeArea", this._fsmData.HasSafeArea);
this._fsmController.SetBool ("hasRunaway", this._fsmData.HasRunaway);
}
}
private void Init ()
{
this._fsmData = new FsmData ()
{
HasActive = true
};
this.CreatePos = this.transform.position;
this._fsmController.Init (this);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fcb26e39de124f6eae1eef8b8b70cc34
timeCreated: 1728978904

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4078f52ab0a5408ca396d8253e706e2e
timeCreated: 1728986866

View File

@@ -0,0 +1,20 @@
using UnityEngine;
using XFFSM;
namespace Game.Component.EnemyFSM_AI
{
public abstract class EnemyFSMState : FSMState
{
protected EnemyEntity Entity;
public override void OnCreate ()
{
this.Entity = (EnemyEntity)this.userData;
}
public void SetAiTarget (Vector2 targetPos)
{
this.Entity.AiLerp.destination = targetPos;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b1f10345745046a6b4ca1ccc5951d343
timeCreated: 1728987048

View File

@@ -0,0 +1,14 @@
namespace Game.Component.EnemyFSM_AI
{
public class Follow : EnemyFSMState
{
public override void OnEnter ()
{
}
public override void OnUpdate ()
{
this.SetAiTarget (MapContent.Instance.PlayerPosition);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: cbe864c917a64ccab3b6b115595248b7
timeCreated: 1728987822

View File

@@ -0,0 +1,17 @@
using XFFSM;
namespace Game.Component.EnemyFSM_AI
{
public class Idea : EnemyFSMState
{
public override void OnEnter ()
{
if (!this.Entity.HasSafeArea)
{
this.Entity.EndAttack ();
}
//角色进入idea状态时 重置状态
this.SetAiTarget (this.Entity.CreatePos);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3e32e90cfcf94a799c192bd48694869c
timeCreated: 1728986882

View File

@@ -0,0 +1,34 @@
using Unity.VisualScripting;
using UnityEngine;
namespace Game.Component.EnemyFSM_AI
{
public class RandomWalk : EnemyFSMState
{
private Vector2 target;
public override void OnEnter ()
{
this.target = this.CreateRandomPos ();
this.SetAiTarget (this.target);
}
public override void OnUpdate ()
{
if (Vector2.Distance (this.Entity.transform.position, this.target) < 0.5f)
{
this.target = this.CreateRandomPos ();
this.SetAiTarget (this.target);
}
}
private Vector2 CreateRandomPos ()
{
var point = this.Entity.CreatePos;
var area = this.Entity.WalkArea.Abs ();
//随机生成一个位置
var x = Random.Range(point.x - area.x / 2, point.x + area.x / 2);
var y = Random.Range(point.y - area.y / 2, point.y + area.y / 2);
return new Vector2(x, y);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f30cf9a1f060477888024e0f40a3bc3e
timeCreated: 1728987901

View File

@@ -0,0 +1,9 @@
using XFFSM;
namespace Game.Component.EnemyFSM_AI
{
public class Sleep : EnemyFSMState
{
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4468144f266a4902a696efa225b1ee3b
timeCreated: 1728986951

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2e47461a718542f6b02fee90bc8b8460
timeCreated: 1701243102

View File

@@ -0,0 +1,38 @@
using System;
using Framework.Utils.Extend;
using UnityEngine;
namespace Game.Component
{
public class GyroscopeEulerController : MonoBehaviour
{
[SerializeField] private Vector3 _minGravity;
[SerializeField] private Vector3 _maxGravity;
[SerializeField] private float _offset;
private Vector3 _curGravity;
private Vector3 _baseRotation;
private Vector3 _baseGravity;
void OnEnable ()
{
this._baseRotation = this.transform.localEulerAngles;
this._baseGravity = GyroscopeMgr.Instance.Gyroscope.gravity;
GyroscopeMgr.Instance.AddUpdater (DoUpdate);
}
void DoUpdate (Vector3 gravity)
{
var gyroGravity = gravity - this._baseGravity;
this._curGravity
= Vector3.Slerp (this._curGravity , (gyroGravity * this._offset).Clamp (this._minGravity , this._maxGravity) , 0.25f);
this.transform.localEulerAngles = this._baseRotation + new Vector3 (this._curGravity.y , -this._curGravity.x , 0);
}
private void OnDisable ()
{
GyroscopeMgr.Instance.RemoveUpdater (DoUpdate);
}
}
}

View File

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

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using Framework.Timer;
using Framework.Utils.SingletonTemplate;
using UnityEngine;
namespace Game.Component
{
public class GyroscopeMgr : MgrMonoBase<GyroscopeMgr>
{
public Gyroscope Gyroscope => Input.gyro;
protected override void InitMgr ()
{
this._UpdateList = new List<Action<Vector3>> ();
}
private void OnEnable ()
{
GameUpdateMgr.Instance.AddUpdater (DoUpdate);
}
private void OnDisable ()
{
this._UpdateList?.Clear ();
GameUpdateMgr.Instance.RemoveUpdater (DoUpdate);
}
private void CheckEnable ()
{
if (this._UpdateList is { Count: > 0 } && !Input.gyro.enabled)
{
Input.gyro.enabled = true;
Input.gyro.updateInterval = 0.1f;
return;
}
if (this._UpdateList!.Count == 0 && Input.gyro.enabled)
{
Input.gyro.enabled = false;
return;
}
}
private List<Action<Vector3>> _UpdateList;
private void _InvokeUpdate(List<Action<Vector3>> list)
{
if (list == null)
{
return;
}
for (int i = list.Count - 1; i >= 0; i--)
{
//在遍历时可能会出现外部操作list导致Count改变
if (i >= list.Count)
continue;
if (list[i] == null)
{
list.RemoveAt(i);
}
else
{
list[i].Invoke(Input.gyro.gravity);
}
}
}
private void DoUpdate() => this._InvokeUpdate(this._UpdateList);
public void AddUpdater(Action<Vector3> updater)
{
this._UpdateList.Add(updater);
CheckEnable ();
}
public void RemoveUpdater(Action<Vector3> updater)
{
this._UpdateList.Remove(updater);
CheckEnable ();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fda42c789e884142ae13551ed0f3398f
timeCreated: 1701243139

View File

@@ -0,0 +1,66 @@
using System;
using Framework.Utils.Extend;
using Sirenix.OdinInspector;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Serialization;
namespace Game.Component
{
public class GyroscopePositionController : MonoBehaviour
{
[SerializeField] private Vector3 _minGravity;
[SerializeField] private Vector3 _maxGravity;
[SerializeField] private float _gravityOffset;
[SerializeField, Range (0, 1)] private float _offset = 0.2f;
[SerializeField] private bool _isFlip;
[SerializeField] private bool _isDelay;
[SerializeField, ShowIf ("_isDelay")] private float _delayTime = 0.75f;
private Vector3 _curGravity;
private Vector3 _basePosition;
private Vector3 _baseGravity;
private bool _isUnlock;
void OnEnable ()
{
if (this._isDelay)
{
this._isUnlock = false;
this.Invoke ("RefreshBasePosition" , this._delayTime);
}
else
{
RefreshBasePosition ();
}
GyroscopeMgr.Instance.AddUpdater (DoUpdate);
}
private void RefreshBasePosition ()
{
this._basePosition = this.transform.localPosition;
this._baseGravity = GyroscopeMgr.Instance.Gyroscope.gravity;
this._isUnlock = true;
}
void DoUpdate (Vector3 gravity)
{
if (!this._isUnlock)
{
return;
}
var gyroGravity = (gravity - this._baseGravity) * (this._isFlip ? -1 : 1);
this._curGravity
= Vector3.Slerp (this._curGravity , (gyroGravity * this._gravityOffset).Clamp (this._minGravity , this._maxGravity) , 0.25f);
this.transform.localPosition = math.lerp (this.transform.localPosition ,
this._basePosition + new Vector3 (this._curGravity.x , this._curGravity.y , 0) , this._offset);
}
private void OnDisable ()
{
GyroscopeMgr.Instance.RemoveUpdater (DoUpdate);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a1b0ecafcaa14218a3df5c926d8bfef8
timeCreated: 1696584635

View File

@@ -0,0 +1,26 @@
using System;
using UnityEngine;
namespace Game.Component
{
public class MapContent : MonoBehaviour
{
public PlayerEntity PlayerEntity;
//玩家位置
public Vector2 PlayerPosition { private set; get; }
//全局特殊单例
public static MapContent Instance;
private void Awake ()
{
//全局特殊单例
Instance = this;
}
private void Update ()
{
this.PlayerPosition = PlayerEntity.transform.position;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 774a99fa7c1a4245b2e1d4e0d101a5bb
timeCreated: 1728998540

View File

@@ -0,0 +1,65 @@
using System.Collections;
using UnityEngine;
namespace Game.Component
{
public class ObjectShake : MonoBehaviour
{
[SerializeField] private ObjectShake LinkObjectShake;
private bool startShake = false; //camera是否开始震动
private float seconds = 0f; //震动持续秒数
private bool started = false; //是否已经开始震动
private float quake = 0.2f; //震动系数
[SerializeField] private float quakeOffset = 1;
private Vector3 startPOS; //camera的起始位置
// Use this for initialization
void OnEnable()
{
this.startPOS = transform.localPosition;
}
// Update is called once per frame
void LateUpdate()
{
if (startShake)
{
transform.localPosition = this.startPOS + Random.insideUnitSphere * (this.quake * this.quakeOffset);
}
if (started)
{
StartCoroutine(WaitForSecond(seconds));
started = false;
}
}
/// <summary>
/// 外部调用控制camera震动
/// </summary>
/// <param name="duration">震动时间</param>
/// <param name="scale">震动幅度</param>
public void ShakeFor(float duration, float scale)
{
// if (startShake)
// return;
seconds = duration;
started = true;
startShake = true;
quake = scale;
if (!ReferenceEquals (this.LinkObjectShake , null))
{
this.LinkObjectShake.ShakeFor (duration , scale);
}
}
IEnumerator WaitForSecond(float a)
{
// camPOS = transform.position;
yield return new WaitForSeconds(a);
startShake = false;
transform.localPosition = this.startPOS;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 193ff27fbb0a4a46accda0b5758b9ae1
timeCreated: 1703074717

View File

@@ -0,0 +1,14 @@
using UnityEngine;
namespace Game.Component
{
public class PlayerEntity : MonoBehaviour
{
public float speed = 10;
public void OnMove (Vector2 vector)
{
this.transform.Translate (vector * speed * Time.deltaTime);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dfce19dfebea46149e6c38028733afb0
timeCreated: 1728904022

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: dc9953bf48964825ac0d8e85c98e90e4
timeCreated: 1719889198

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9212289873f344c7a0b36456b34dc904
timeCreated: 1717139296

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 88ce5b8843a1472fba360ff54e4ee9e0
timeCreated: 1717140387

View File

@@ -0,0 +1,9 @@
namespace Game.Data.BaseData
{
public enum Quality
{
Human = 0, // 人级
Earth, // 地级
Heaven // 天级
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5cbec106dcd446c3bed46e7c59f36210
timeCreated: 1717149166

View File

@@ -0,0 +1,49 @@
using Framework.Save;
namespace Game.Data
{
public class RoomGlobalData : SinglePersistentData<RoomGlobalData>
{
public static RoomGlobalData Create (bool isLoad = false)
{
var data = new RoomGlobalData ();
if (isLoad)
{
if (data.Load ())
{
return data;
}
}
return data;
}
public void SaveData ()
{
this.Save ();
}
public void OverlyCoin (int overlyCoin , bool hasEcho = false)
{
if (RoomManager.Instance.CurrentGameState == GameState.FightGame && hasEcho)
{
}
}
public void GameEnd ()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 09ff2e86e3074cb8a13c756f7cd38b15
timeCreated: 1717146874

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 93d134b69a1b42d0ae319bfe3b3bec6f
timeCreated: 1717407876

View File

@@ -0,0 +1,10 @@
using System;
using System.Collections.Generic;
using Framework.Utils.Extend;
using UniFramework.Event;
using UnityEngine;
namespace Game.EventDefine
{
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ba62c151770040a98e38fb54a9a2acf4
timeCreated: 1718704279

View File

@@ -0,0 +1,100 @@
using System.Collections.Generic;
using UniFramework.Event;
using UnityEngine;
namespace Game.EventDefine
{
public static class GameEventDefine
{
/// <summary>
/// 变化金币
/// </summary>
public class OverlyCoin : IEventMessage
{
public bool hasEcho;
public int overlyCoin;
public static void SendMessage (int overlyCoin , bool echo = false) => UniEvent.SendMessage (new OverlyCoin ()
{
hasEcho = echo,
overlyCoin = overlyCoin
});
}
/// <summary>
/// 改变游戏状态
/// </summary>
public class ChangeGameFsm : IEventMessage
{
public GameState State { get; private set; }
public object[] Args { get; private set; }
private ChangeGameFsm ()
{
}
public static void SendMessage (GameState state , params object[] args)
{
var changeGameFsm = new ChangeGameFsm { State = state , Args = args };
UniEvent.SendMessage (changeGameFsm);
}
}
public class ShowTextHub : IEventMessage
{
public string text;
public RectTransform rectTransform;
public Vector2 extDistance;
public Vector3 Position
{
//将rectTransform的对应方向点转换为世界坐标
get
{
var pos = rectTransform.position;
return pos + new Vector3 (this.extDistance.x , this.extDistance.y , 0);
}
}
private ShowTextHub ()
{
}
public static void SendMessage (string text , RectTransform rectTransform , Vector2 extDistance = default)
{
var showTextHub = new ShowTextHub
{
text = text,
rectTransform = rectTransform,
extDistance = extDistance
};
UniEvent.SendMessage (showTextHub);
}
}
public class ShowTipBox : IEventMessage
{
public string tipText;
public string content;
public RectTransform box;
public Vector2 extDistance;
private ShowTipBox ()
{
}
public static void SendMessage (string tipText , string content, RectTransform box, Vector2 extDistance = default)
{
var showTipBox = new ShowTipBox
{
tipText = tipText,
content = content,
box = box,
extDistance = extDistance
};
UniEvent.SendMessage (showTipBox);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ede6a977037247babeec816154782c47
timeCreated: 1717470954

View File

@@ -0,0 +1,17 @@
using UniFramework.Event;
namespace Game.EventDefine
{
public static class GlobalEventDefine
{
/// <summary>
/// 刷新视图
/// </summary>
public class RefreshView : IEventMessage
{
private RefreshView () { }
public static void SendMessage() => UniEvent.SendMessage (new RefreshView ());
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0ef26903fac54c9a99d32cc922cd694a
timeCreated: 1717407918

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 002a4a6bafcb4fb183c49337def83d0e
timeCreated: 1717040215

View File

@@ -0,0 +1,15 @@
using Framework.FSMLite;
namespace Game.FsmNode
{
public class GameContinue : StateMachine<GameState>
{
protected override void OnEnter (params object[] args)
{
}
protected override void OnExit ()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: c50e36cd17c243bdb4863a03bb1503e8
timeCreated: 1717040446

View File

@@ -0,0 +1,26 @@
using System;
using Framework.Audio;
using Framework.FSMLite;
using Framework.UI;
using Views;
namespace Game.FsmNode
{
public class GameExit : StateMachine<GameState>
{
protected override void OnEnter (params object[] args)
{
AudioManager.Instance.StopPlayers(AudioType.BGM , 0.5f);
OnExitGame ();
}
private void OnExitGame ()
{
RoomManager.Instance._OnExitGame ();
}
protected override void OnExit ()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8690c4c7ce6c4420999456130c48b071
timeCreated: 1717040582

View File

@@ -0,0 +1,22 @@
using System;
using Framework.Audio;
using Framework.FSMLite;
using Framework.UI;
using Views;
namespace Game.FsmNode
{
public class GameField : StateMachine<GameState>
{
protected override void OnEnter (params object[] args)
{
AudioManager.Instance.PlaySoundEffect(SeAudio.OverGame_Fail);
}
protected override void OnExit ()
{
UIManager.Instance.CloseViewWithGroup (this.GetType ().FullName);
UIManager.Instance.CloseViewWithGroup (GameFight.GroupName);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5abf45a637134ff6929b6e021f3a931c
timeCreated: 1717040566

View File

@@ -0,0 +1,33 @@
using System;
using System.Guide;
using Framework.Audio;
using Framework.FSMLite;
using Framework.UI;
using Game.Data;
using UnityEngine;
using Views;
namespace Game.FsmNode
{
public class GameFight : StateMachine<GameState>
{
// 基础战斗引导
// ReSharper disable once MemberCanBePrivate.Global
public const string FightGuideTable = "FightGuide";
// ReSharper disable once MemberCanBePrivate.Global
public const string GodEyeGuideTable = "GodEyeGuide";
public static string GroupName = typeof(GameFight).FullName;
protected override async void OnEnter (params object[] args)
{
AudioManager.Instance.PlayBGM (BgmAudio.FightingBgm);
var globalData = RoomManager.Instance.RoomGlobalData;
}
protected override void OnExit ()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 193bce9c5df54fa383a51f9d91811aec
timeCreated: 1717040507

View File

@@ -0,0 +1,22 @@
using Framework.FSMLite;
using Framework.UI;
using Game.Data;
using Views;
namespace Game.FsmNode
{
public class GameInit : StateMachine<GameState>
{
protected override void OnEnter (params object[] args)
{
//初始化数据层
var data = RoomGlobalData.Create (false);
RoomManager.Instance.RoomGlobalData = data;
}
protected override void OnExit ()
{
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 77b5c9fdf4b241fcb0be94d0ba945395
timeCreated: 1717040382

View File

@@ -0,0 +1,27 @@
using System;
using Framework.Audio;
using Framework.FSMLite;
using Framework.UI;
using Game.EventDefine;
using IcecreamView;
using UnityEngine;
using Views;
namespace Game.FsmNode
{
public class GamePart : StateMachine<GameState>
{
private int _lastPartLayer = -1;
private int _lastLevelIndex = -1;
protected override void OnEnter (params object[] args)
{
AudioManager.Instance.PlayBGM(BgmAudio.NormalBgm , 0.65f);
}
protected override void OnExit ()
{
UIManager.Instance.CloseViewWithGroup (this.GetType ().FullName);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 33084e8a307b49648b468d7ae4123115
timeCreated: 1717040492

View File

@@ -0,0 +1,37 @@
using System;
using Framework.Audio;
using Framework.FSMLite;
using Framework.UI;
using Game.EventDefine;
using Game.Manager;
using Views;
namespace Game.FsmNode
{
public class GameRelax : StateMachine<GameState>
{
protected override async void OnEnter (params object[] args)
{
AudioManager.Instance.PlayBGM(BgmAudio.NormalBgm , 0.65f);
//如果是从游戏关卡选择中返回休息,不刷新商店
var isRefreshShop = this.stateMachineRunner.LastState != GameState.PartGame;
if (isRefreshShop)
{
RefreshShop ();
}
}
private void RefreshShop ()
{
if (this.stateMachineRunner.LastState != GameState.PartGame)
{
}
}
protected override void OnExit ()
{
UIManager.Instance.CloseViewWithGroup (this.GetType ().FullName);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 72a83c4ee54e44ea8fd35c8f522ad3b7
timeCreated: 1717040477

View File

@@ -0,0 +1,18 @@
using Framework.FSMLite;
using Framework.UI;
namespace Game.FsmNode
{
public class GameRevert : StateMachine<GameState>
{
protected override void OnEnter (params object[] args)
{
this.stateMachineRunner.OpenState (GameState.RelaxGame);
}
protected override void OnExit ()
{
UIManager.Instance.CloseViewWithGroup (this.GetType ().FullName);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 4002bf2ef5c64e33b794d0f10fbc7d5c
timeCreated: 1717040526

View File

@@ -0,0 +1,28 @@
using System;
using Framework.Audio;
using Framework.FSMLite;
using Framework.UI;
using Game.Data;
using Game.EventDefine;
using Views;
namespace Game.FsmNode
{
public class GameStart : StateMachine<GameState>
{
protected override async void OnEnter (params object[] args)
{
AudioManager.Instance.PlayBGM(BgmAudio.NormalBgm , 0.65f);
GameEventDefine.ChangeGameFsm.SendMessage (GameState.PartGame , true);
UIManager.Instance.CloseLoading (null);
if (Account.Instance.AccountGameData.InitCardIds.Count > 0)
{
}
}
protected override void OnExit ()
{
UIManager.Instance.CloseViewWithGroup (this.GetType ().FullName);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 33e64d21260b43a8a2ff0b9650c92e7a
timeCreated: 1717040404

View File

@@ -0,0 +1,31 @@
using System;
using System.RandomPool;
using FJson.Core;
using Framework.Audio;
using Framework.FSMLite;
using Framework.Timer;
using Framework.UI;
using Game.Component;
using Game.Data;
using Game.EventDefine;
using IcecreamView;
using Unity.Mathematics;
using Views;
namespace Game.FsmNode
{
public class GameSuccess : StateMachine<GameState>
{
protected override async void OnEnter (params object[] args)
{
AudioManager.Instance.PlaySoundEffect (SeAudio.OverGame_Success);
}
protected override void OnExit ()
{
UIManager.Instance.CloseViewWithGroup (this.GetType ().FullName);
UIManager.Instance.CloseViewWithGroup (GameFight.GroupName);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d166d288650f436da8df73a42ca861fb
timeCreated: 1717040546

View File

@@ -0,0 +1,21 @@
namespace Game
{
public static class GameEventCode
{
#region
public const int PropTip = 10000; //通用提示, string 提示内容
public const int Prop2Tip = 10003; //通用提示, string 提示内容
public const int AddGold = 10004; //获得金币 int 金币数量
#endregion
public const int Update_View = 100000; //更新显示层
public const int Update_Price = 100001; //更新货币显示层
public const int ResetGameView = 100002; //重置刷新信号
public const int OnScreenFlicker = 200005; //屏幕闪烁 int 闪烁次数
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5245a35d949842da9e28d691f711531c
timeCreated: 1690253736

View File

@@ -0,0 +1,25 @@
using System.StateSystem.State;
using Framework.FSMLite;
using Game.FsmNode;
using StateSystem.State;
namespace Game
{
public class GameFsm : StateMachineRunner<GameState>
{
public override void OnInit()
{
AppendState<GameInit>(GameState.InitGame);
AppendState<GameStart>(GameState.StartGame);
AppendState<GameContinue>(GameState.ContinueGame);
AppendState<GameRelax>(GameState.RelaxGame);
AppendState<GamePart>(GameState.PartGame);
AppendState<GameFight>(GameState.FightGame);
AppendState<GameRevert>(GameState.RevertGame);
AppendState<GameSuccess>(GameState.SuccessGame);
AppendState<GameField>(GameState.FieldGame);
AppendState<GameExit>(GameState.ExitGame);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 398b6670c7d54fd897d241f8ec93f465
timeCreated: 1717040244

View File

@@ -0,0 +1,16 @@
namespace Game
{
public enum GameState
{
InitGame = 0,
StartGame,
ContinueGame,
RelaxGame,
PartGame,
FightGame,
RevertGame,
SuccessGame,
FieldGame,
ExitGame,
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 04dfdc4031004e8ab895aad21f53ccb7
timeCreated: 1695495729

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e58b8d9cff264643b02c1ddc0626115e
timeCreated: 1717400756

View File

@@ -0,0 +1,83 @@
using System;
using System.Collections;
using System.Collections.Generic;
using FJson;
using FJson.Core;
using Framework.Utils.SingletonTemplate;
using Game.Data.BaseData;
using UnityEngine;
namespace Game.Manager
{
public class PackageManager : MgrBase<PackageManager>
{
private Dictionary<int, RofWeaponCardRow> _weaponCardCache;
private Dictionary<int , RofEchoCardRow> _echoCardCache;
private Dictionary<int , RofMaskCardRow> _maskCardCache;
private Dictionary<int , RofExchangeCardRow> _exchangeCardCache;
private Dictionary<int , RofReplenishCardRow> _replenishCardCache;
private Dictionary<int, RofSecretCardRow> _secretCardCache;
private Dictionary<int, Quality> _cardQualityCache;
protected override void OnCreateMge ()
{
this._weaponCardCache = new Dictionary<int, RofWeaponCardRow> ();
this._echoCardCache = new Dictionary<int, RofEchoCardRow> ();
this._maskCardCache = new Dictionary<int, RofMaskCardRow> ();
this._exchangeCardCache = new Dictionary<int, RofExchangeCardRow> ();
this._replenishCardCache = new Dictionary<int, RofReplenishCardRow> ();
this._secretCardCache = new Dictionary<int, RofSecretCardRow> ();
this._cardQualityCache = new Dictionary<int, Quality> ();
RofManagerConfig.Instance.WeaponCardTable.GetAllRow ().ForEach (row =>
{
this._weaponCardCache.Add (row.ID, row);
this._cardQualityCache.Add (row.ID, (Quality)row.quality);
});
RofManagerConfig.Instance.EchoCardTable.GetAllRow ().ForEach (row =>
{
this._echoCardCache.Add (row.ID, row);
this._cardQualityCache.Add (row.ID, (Quality)row.quality);
});
RofManagerConfig.Instance.MaskCardTable.GetAllRow ().ForEach (row =>
{
this._maskCardCache.Add (row.ID, row);
this._cardQualityCache.Add (row.ID, (Quality)row.quality);
});
RofManagerConfig.Instance.ExchangeCardTable.GetAllRow ().ForEach (row =>
{
this._exchangeCardCache.Add (row.ID, row);
this._cardQualityCache.Add (row.ID, (Quality)row.quality);
});
RofManagerConfig.Instance.ReplenishCardTable.GetAllRow ().ForEach (row =>
{
this._replenishCardCache.Add (row.ID, row);
this._cardQualityCache.Add (row.ID, (Quality)row.quality);
});
RofManagerConfig.Instance.SecretCardTable.GetAllRow ().ForEach (row =>
{
this._secretCardCache.Add (row.ID, row);
this._cardQualityCache.Add (row.ID, (Quality)row.quality);
});
}
public Quality GetCardQuality (int cardId)
{
return this._cardQualityCache.GetValueOrDefault (cardId);
}
public Vector2 GetRangeEcho (int cardId)
{
if (this._echoCardCache.TryGetValue (cardId, out var rofEchoCardRow))
{
var readActionParser = ActionParser.CreateAction (null , rofEchoCardRow.maskId);
return new Vector2 ((int)readActionParser.ActionArgs[0] , (int)readActionParser.ActionArgs[1]);
}
return new Vector2 (-1, -1);
}
public RofEchoCardRow GetEchoRof (int node)
{
return this._echoCardCache.GetValueOrDefault (node);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 660bff782e2f4348a2a705cabc4d5e79
timeCreated: 1717400783

View File

@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using Framework.Asset;
using Framework.Utils.SingletonTemplate;
using Game.Data.BaseData;
using UnityEngine;
namespace Game.Manager
{
public class SpriteLoaderMgr : MgrBase<SpriteLoaderMgr>
{
private const string WeaponSpritePath = "AutoSource/WeaponSprite/";
private const string BossSpritePath = "AutoSource/BossSprite/";
protected override void OnCreateMge ()
{
}
private Dictionary<string , Sprite> _weaponSpriteDic = new Dictionary<string , Sprite> ();
private Dictionary<string , Sprite> _weaponEffectSpriteDic = new Dictionary<string , Sprite> ();
private Dictionary<string , Sprite> _bossSpriteDic = new Dictionary<string , Sprite> ();
public void Clear ()
{
this._weaponSpriteDic.Clear ();
this._weaponEffectSpriteDic.Clear ();
this._bossSpriteDic.Clear ();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3a815d7cced74822ada8a3d129a8fd01
timeCreated: 1720148380

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 98b1633a4b534339aaa79313a4c292cf
timeCreated: 1697645822

View File

@@ -0,0 +1,71 @@
using System.Collections.Generic;
using Framework.GamePool;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.UI;
namespace Game.OtherComponent
{
public class HpSlider : MonoBehaviour
{
[SerializeField] private Image _prefab;
[SerializeField] private Sprite _activeImg;
[SerializeField] private Sprite _unActiveImg;
[SerializeField] private float _minValue = 0;
[SerializeField] private float _maxValue = 100;
private float _value;
public int RateUnit = 10;
public float MinValue => this._minValue;
public float MaxValue => this._maxValue;
public float Value => this._value;
public float Progress => (this._value - this._minValue ) / (this._maxValue - this._minValue);
private List<Image> _images = new List<Image> ();
private int ObjMaxValue => (int)math.ceil ((this._maxValue * 1.0f / this.RateUnit));
private int ObjActiveValue => (int)math.ceil ((this.Progress * 1.0f * this.ObjMaxValue));
public void SetMinMax (float minValue, float maxValue, float value)
{
this._minValue = minValue;
this._maxValue = maxValue;
SetValue (value);
}
public void SetValue (float value)
{
this._value = ValueMono (value);
RefreshSlider ();
}
private int ValueMono (float value)
{
return (int)math.clamp (value + 0.5f , this._minValue , this._maxValue);
}
private void RefreshSlider ()
{
if (this._prefab.gameObject.activeSelf)
{
this._prefab.gameObject.SetActive (false);
}
var amount = math.max (this._images.Count , this.ObjMaxValue);
for (int i = 1; i <= amount; i++)
{
if (this._images.Count < i)
{
var image = Instantiate (this._prefab , this.transform);
this._images.Add (image);
}
var obj = this._images[i - 1];
obj.gameObject.SetActive (i <= this.ObjMaxValue);
obj.sprite = i <= this.ObjActiveValue ? this._activeImg : this._unActiveImg;
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d894ba957d924a4a871bcf0ec9b64107
timeCreated: 1701248007

View File

@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.ScriptListener;
using Cysharp.Threading.Tasks;
using FJson;
using Framework.Audio;
using Framework.GamePool.manager;
using Framework.Timer;
using Framework.UI;
using Framework.Utils.SingletonTemplate;
using Game.Data;
using Game.EventDefine;
using IcecreamView;
using StateSystem;
using UniFramework.Event;
using UnityEngine;
using Views;
namespace Game
{
public enum VibratorScale
{
Small = 1,
Normal = 2,
Big = 4,
SuperBig = 6,
Max = 8
}
public class RoomManager : MgrBase<RoomManager>
{
private EventGroup _eventGroup;
private GameFsm _gameFsm;
private RoomGlobalData _roomGlobalData;
public bool HasGaming { get; private set; }
public bool HasLock { get ; private set; }
public GameState CurrentGameState => this._gameFsm.CurrentState;
public RoomGlobalData RoomGlobalData
{
get => _roomGlobalData;
set => _roomGlobalData = value;
}
public void JoinGame (params object[] args)
{
this._gameFsm = new GameFsm ();
this._gameFsm.Active (GameState.InitGame , args);
GameUpdateMgr.Instance.AddUpdater (DoUpdate);
this.BindEvent ();
this._gameFsm.OpenState (GameState.StartGame);
}
internal void _OnExitGame ()
{
UnBindEvent ();
this._gameFsm.Kill ();
GameUpdateMgr.Instance.RemoveUpdater (DoUpdate);
GameStateManager.Instance.OpenState (System.StateSystem.GameGlobalState.GameHome);
}
private void DoUpdate ()
{
#if UNITY_EDITOR
if (Input.GetKeyDown (KeyCode.F1))
{
}
#endif
if (HasGaming)
{
}
}
protected override void OnCreateMge ()
{
// _eventBindHandler = new EventBindHandler (this);
_eventGroup = new EventGroup ();
}
protected override bool InstanceHook ()
{
return GameStateManager.Instance.CurrentState == System.StateSystem.GameGlobalState.GameRoom;
}
/// <summary>
/// 锁定操作
/// </summary>
public void Lock ()
{
this.HasLock = true;
}
/// <summary>
/// 解除锁定操作
/// </summary>
public void UnLock ()
{
this.HasLock = false;
}
#region
private void BindEvent ()
{
this._eventGroup.AddListener<GameEventDefine.ChangeGameFsm> (ChangeGameFsm);
this._eventGroup.AddListener<GameEventDefine.OverlyCoin> (OverlyCoin);
}
private void ChangeGameFsm (IEventMessage eventMessage)
{
GameEventDefine.ChangeGameFsm message = eventMessage as GameEventDefine.ChangeGameFsm;
this._gameFsm.OpenState (message.State , message.Args);
}
private void OverlyCoin (IEventMessage obj)
{
if (obj is GameEventDefine.OverlyCoin message)
{
AudioManager.Instance.PlaySoundEffect (SeAudio.Gaming_GetCoin);
this.RoomGlobalData.OverlyCoin (message.overlyCoin , message.hasEcho);
GlobalEventDefine.RefreshView.SendMessage ();
}
}
private void UnBindEvent ()
{
this._eventGroup.RemoveAllListener ();
}
#endregion
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2d9082a2239d412e8eac3e59af1e2ab4
timeCreated: 1695490817

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a2ed7d200da84e44a536695c94812b69
timeCreated: 1690168117

View File

@@ -0,0 +1,81 @@
using System;
using UnityEngine;
using UnityEngine.Events;
namespace Game.Component
{
/// <summary>
/// 摇一摇组件
/// </summary>
public class AccelerationListener : MonoBehaviour
{
private float _lastAcceleration;
//波动阈值
private const float ACCELERATION_THRESHOLD = 0.75f;
//是否启用摇晃时手机震动反馈
public bool isVibrator = true;
//摇一摇事件摇晃次数,达到阈值后触发回调
public int ActiveCount = 1;
public UnityAction AccelerationComplete;
public UnityAction SingeAcceleration;
// private bool _isAcccelerating = false;
private int CurActiveCount = 0;
private float _listennerCD;
private float _shakeCD;
private void Update()
{
if (this._listennerCD > 0)
{
this._listennerCD -= Time.deltaTime;
if (this._listennerCD <= 0)
{
ResetData();
}
}
if (this._shakeCD > 0)
{
this._shakeCD -= Time.deltaTime;
}
var accelerationX = Math.Abs(Input.acceleration.x);
if (this._shakeCD <= 0 && accelerationX - this._lastAcceleration >= ACCELERATION_THRESHOLD)
{
this._shakeCD = 0.15f;
Acccelerating();
}
this._lastAcceleration = accelerationX;
}
private void ResetData()
{
this._listennerCD = 0;
CurActiveCount = 0;
}
private void Acccelerating()
{
if (isVibrator)
{
VibratorImp.Instance.StartVibrator(100);
}
this.SingeAcceleration?.Invoke();
this.CurActiveCount += 1;
this._listennerCD = 0.5f;
if (CurActiveCount >= ActiveCount)
{
ResetData();
this.AccelerationComplete?.Invoke();
}
}
}
}

View File

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

View File

@@ -0,0 +1,90 @@
using System.IO;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Serialization;
public class GameVersionConfig : ScriptableObject
{
public int ClientBuildID;
}
public class GameGlobalConfig : GameVersionConfig
{
#region Instance Logic
private static GameGlobalConfig instance;
public static GameGlobalConfig Instance
{
get
{
#if UNITY_EDITOR
if (UnityEditor.EditorApplication.isPlaying == false)
{
instance = null;
}
#endif
if (instance == null)
{
#if UNITY_EDITOR
if (!File.Exists("Assets/Resources/GameSettings.asset"))
{
instance = CreateInstance<GameGlobalConfig>();
// 自定义资源保存路径
string path = "Assets/Resources";
//如果项目总不包含该路径,创建一个
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
UnityEditor.AssetDatabase.CreateAsset(instance, path + "/GameSettings.asset");
UnityEditor.AssetDatabase.Refresh();
}
if (instance != null)
{
Resources.UnloadAsset(instance);
}
instance = Resources.Load<GameGlobalConfig>("GameSettings");
#else
instance = Resources.Load<GameGlobalConfig>("GameSettings");
#endif
}
return instance;
}
}
#endregion
[Header("游戏渠道")]public GameChannel Channel;
[BoxGroup("AssetBundle Info"),Header("拟真模式")] public bool IsNativeAssets;
[BoxGroup("AssetBundle Info"),Header("是否强制资源检查更新")] public bool IsMandatory;
[BoxGroup("AssetBundle Info"),Header("是否在启动时自动检查热更新")] public bool IsCheckNetAsset;
[BoxGroup("AssetBundle Info"),Header("热更新检查地址")] public string AssetRemotePath;
[BoxGroup("Taptap Info")] public string TapClientId;
[BoxGroup("Taptap Info")] public string TapToken;
[BoxGroup("Taptap Info")] public string TapUrl;
[BoxGroup("Taptap Info")] public string TapAppUrl;
[BoxGroup("游戏通用配置"), Header("每日最大广告上限")]public int EveryDayAdLimit = 99;
[BoxGroup("游戏通用配置"), Header("每日最大体力广告上限")]public int EveryDayPowerAdLimit = 2;
[BoxGroup("游戏通用配置"), Header("体力广告恢复CD上限 (分)")]public int PowerAdCD = 60;
}
public enum GameChannel
{
Private = 0,
Taptap,
Kuaibao,
Momoyu,
Ios,
Ohayoo,
Douyin,
Weixin
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0c92bb51b8bf4e04b124711be4c5f180
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