清理各个 Component 里的判断以及调用规范

This commit is contained in:
2026-09-14 18:35:02 +08:00
parent 5fbeec2476
commit 17ee268416
30 changed files with 769 additions and 1326 deletions
Binary file not shown.
@@ -1,12 +1,15 @@
[ [
{ {
"weaponCapacity": 6, "weaponCapacity": 6,
"propMaxCount": -1,
"weaponRecycleRate": 300, "weaponRecycleRate": 300,
"shopGoodsCount": 4, "shopGoodsCount": 4,
"shopPriceRandomPercent": 50, "shopPriceRandomPercent": 50,
"shopMinPrice": 0, "shopMinPrice": 0,
"propMaxCount": -1,
"levelUpRefreshPriceBase": 2, "levelUpRefreshPriceBase": 2,
"levelUpRewardCount": 4 "levelUpRewardCount": 4,
"enemyGroupName": "Enemy",
"spawnEnemyMaxCount": 5000,
"spawnDistanceFromPlayer": 20000
} }
] ]
@@ -1,580 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SepCore.Event;
using SepCore.Definition;
using SepCore.Entity;
using SepCore.Components;
using SepCore.CustomUtility;
using SepCore.Simulation;
using SepCore.EnemyManager;
using SepCore.Procedure;
using UnityEngine;
using UnityGameFramework.Runtime;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
public class RuntimeDebugPanelComponent : MonoBehaviour
{
private const float MinSpawnRate = 0.1f;
private const float CornerTapWindow = 0.6f;
private const int RequiredCornerTapCount = 3;
private const int DebugHealAmount = 200;
[Header("Window Content")] [SerializeField]
private bool _showBuffSection = true;
[SerializeField] private bool _showBattleOverview = true;
[SerializeField] private bool _showCollisionStats = true;
[SerializeField] private bool _showSpawnControls = true;
[SerializeField] private bool _showBattleDurationControls = true;
[SerializeField] private bool _showPlayerWeaponControls = true;
[SerializeField] private bool _showPlayerHealthControls = true;
[SerializeField] private bool _showTips = true;
private Rect _windowRect;
private Vector2 _panelScroll;
private GUISkin _panelSkin;
private bool _isPanelVisible;
private int _windowId;
private string _searchText = string.Empty;
private int _selectedIndex;
private int _addCount = 1;
private Vector2 _buffScroll;
private float _spawnRateScaleInput = 1f;
private float _extendDurationSeconds = 30f;
private IReadOnlyList<PropConfig> _allProps;
private IReadOnlyList<PropConfig> _filteredProps;
private string[] _displayNames = Array.Empty<string>();
private int _cornerTapCount;
private float _lastCornerTapTime = -10f;
private bool _lockPlayerHealthToMax;
private void Awake()
{
_windowId = GetInstanceID();
}
private void Update()
{
if (IsTogglePressed())
{
_isPanelVisible = !_isPanelVisible;
}
HandleCornerTapGesture();
if (_lockPlayerHealthToMax)
{
KeepPlayerHealthAtMax();
}
}
private void OnGUI()
{
GUISkin previousSkin = GUI.skin;
Matrix4x4 previousMatrix = GUI.matrix;
if (_panelSkin == null)
{
_panelSkin = Instantiate(previousSkin);
_panelSkin.label.fontSize = 18;
_panelSkin.label.wordWrap = true;
_panelSkin.button.fontSize = 18;
_panelSkin.button.padding = new RectOffset(12, 12, 10, 10);
_panelSkin.button.fixedHeight = 44f;
_panelSkin.textField.fontSize = 20;
_panelSkin.textField.fixedHeight = 44f;
_panelSkin.textField.padding = new RectOffset(10, 10, 10, 10);
_panelSkin.window.padding = new RectOffset(16, 16, 12, 16);
_panelSkin.verticalScrollbar.fixedWidth = 28f;
_panelSkin.verticalScrollbarThumb.fixedWidth = 28f;
}
Rect safeArea = Screen.safeArea;
float scale = Mathf.Max(0.1f, Mathf.Min(safeArea.width, safeArea.height) / 480f);
Rect bounds = new Rect(0f, 0f, safeArea.width / scale, safeArea.height / scale);
try
{
GUI.skin = _panelSkin;
GUI.matrix = Matrix4x4.TRS(
new Vector3(safeArea.x, Screen.height - safeArea.yMax, 0f),
Quaternion.identity, new Vector3(scale, scale, 1f));
DrawToggleButton(bounds);
if (!_isPanelVisible) return;
float width = Mathf.Min(460f, bounds.width - 24f);
_windowRect = new Rect(bounds.width - width - 12f, 72f, width,
Mathf.Min(760f, bounds.height - 84f));
GUI.Window(_windowId, _windowRect, DrawWindow, string.Empty);
}
finally
{
GUI.matrix = previousMatrix;
GUI.skin = previousSkin;
}
}
private void OnDestroy()
{
if (_panelSkin != null) Destroy(_panelSkin);
}
private void DrawToggleButton(Rect bounds)
{
const float width = 120f;
const float height = 48f;
Rect buttonRect = new Rect(bounds.width - width - 12f, 12f, width, height);
if (GUI.Button(buttonRect, "DEBUG"))
{
_isPanelVisible = !_isPanelVisible;
}
}
private void DrawWindow(int windowId)
{
if (_showBuffSection)
{
EnsurePropList();
}
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("Runtime Debug", GUILayout.ExpandWidth(true));
if (GUILayout.Button("Close", GUILayout.Width(90f))) _isPanelVisible = false;
GUILayout.EndHorizontal();
GUILayout.Space(8f);
_panelScroll = GUILayout.BeginScrollView(_panelScroll, false, true);
bool hasPreviousSection = false;
if (_showBuffSection)
{
DrawBuffSection();
hasPreviousSection = true;
}
if (HasVisibleBattleSection())
{
if (hasPreviousSection)
{
GUILayout.Space(8f);
GUILayout.Label(string.Empty, GUI.skin.horizontalSlider);
GUILayout.Space(8f);
}
DrawBattleSection();
hasPreviousSection = true;
}
if (_showTips)
{
if (hasPreviousSection)
{
GUILayout.Space(8f);
}
GUILayout.Label("Tips: press F8 or tap top-left corner 3 times to toggle.");
}
GUILayout.EndScrollView();
GUILayout.EndVertical();
}
private void DrawBuffSection()
{
GUILayout.Label("Buff Debug");
GUILayout.BeginHorizontal();
GUILayout.Label("Search", GUILayout.Width(78f));
_searchText = GUILayout.TextField(_searchText);
if (GUILayout.Button("Refresh", GUILayout.Width(100f)))
{
EnsurePropList(true);
}
GUILayout.EndHorizontal();
ApplyFilter(_searchText);
if (_displayNames.Length == 0)
{
GUILayout.Label("No Buff data. Enter battle and try again.");
return;
}
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _displayNames.Length - 1);
_buffScroll = GUILayout.BeginScrollView(_buffScroll, GUILayout.Height(120f));
_selectedIndex = GUILayout.SelectionGrid(_selectedIndex, _displayNames, 1);
GUILayout.EndScrollView();
PropConfig selectedProp = GetSelectedProp();
if (selectedProp == null) return;
GUILayout.Label($"Selected: {selectedProp.Name} ({selectedProp.Rarity})");
GUILayout.Label(ItemDescUtility.CreatePropDescription(selectedProp.Modifiers), GUILayout.Height(40f));
GUILayout.BeginHorizontal();
GUILayout.Label("Count", GUILayout.Width(78f));
string addCountText = GUILayout.TextField(_addCount.ToString(), GUILayout.Width(88f));
if (!int.TryParse(addCountText, out _addCount)) _addCount = 1;
_addCount = Mathf.Clamp(_addCount, 1, 99);
if (GUILayout.Button("Add Buff To Player", GUILayout.Height(44f)))
{
AddSelectedBuffToPlayer(selectedProp, _addCount);
}
GUILayout.EndHorizontal();
}
private void DrawBattleSection()
{
GUILayout.Label("Battle Debug");
ProcedureGame procedure = GameEntry.Procedure.CurrentProcedure as ProcedureGame;
EnemyManagerComponent enemyManager = GameEntry.EnemyManager;
Player player = FindPlayer();
HealthComponent playerHealth = player != null ? player.GetComponent<HealthComponent>() : null;
if (enemyManager == null)
{
GUILayout.Label("EnemyManager unavailable.");
return;
}
if (procedure == null)
{
GUILayout.Label("ProcedureGame unavailable.");
return;
}
if (_showBattleOverview)
{
GUILayout.Label($"Spawn Rate: {enemyManager.SpawnRateScale:F2}");
GUILayout.Label(
$"Battle Time: {enemyManager.ElapsedBattleTime:F1}s / {enemyManager.BattleDuration:F1}s");
GUILayout.Label($"Enemy Count: {enemyManager.CurrentEnemyCount}");
}
SimulationWorld simulationWorld = GameEntry.SimulationWorld;
if (_showCollisionStats && simulationWorld != null)
{
GUILayout.Space(4f);
GUILayout.Label(
$"Collision Queries: total {simulationWorld.LastCollisionQueryCount} (Projectile {simulationWorld.LastProjectileCollisionQueryCount} / Area {simulationWorld.LastAreaCollisionQueryCount})");
GUILayout.Label(
$"Collision Candidates: total {simulationWorld.LastCollisionCandidateCount} (Projectile {simulationWorld.LastProjectileCollisionCandidateCount} / Area {simulationWorld.LastAreaCollisionCandidateCount})");
GUILayout.Label(
$"Area Resolve: hits {simulationWorld.LastResolvedAreaHitCount}");
GUILayout.Label(
$"Broad Phase: cell {simulationWorld.LastCollisionCellSize:F2}, hasEnemyTargets {(simulationWorld.LastCollisionHasEnemyTargets ? "Yes" : "No")}");
if (simulationWorld.LastCollisionCandidateCount != 0)
{
Log.Info($"LastCollisionCandidateCount:{simulationWorld.LastCollisionCandidateCount}");
}
if (simulationWorld.LastResolvedAreaHitCount != 0)
{
Log.Info($"LastResolvedAreaHitCount:{simulationWorld.LastResolvedAreaHitCount}");
}
}
if (_showSpawnControls)
{
GUILayout.Space(12f);
GUILayout.Label("Enemy Spawn Rate");
GUILayout.BeginHorizontal();
GUILayout.Label("Rate", GUILayout.Width(78f));
string rateText = GUILayout.TextField(_spawnRateScaleInput.ToString("F2"), GUILayout.Width(88f));
if (float.TryParse(rateText, out float parsedRate))
{
_spawnRateScaleInput = Mathf.Clamp(parsedRate, MinSpawnRate, 50f);
}
if (GUILayout.Button("Apply", GUILayout.Width(100f)))
{
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button("x0.5"))
{
_spawnRateScaleInput = Mathf.Max(MinSpawnRate, enemyManager.SpawnRateScale * 0.5f);
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
if (GUILayout.Button("x2"))
{
_spawnRateScaleInput = enemyManager.SpawnRateScale * 2f;
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
GUILayout.EndHorizontal();
}
if (_showBattleDurationControls)
{
GUILayout.Space(12f);
GUILayout.Label("Battle Duration");
GUILayout.BeginHorizontal();
GUILayout.Label("Add Sec", GUILayout.Width(78f));
string durationText = GUILayout.TextField(_extendDurationSeconds.ToString("F0"), GUILayout.Width(88f));
if (float.TryParse(durationText, out float parsedDuration))
{
_extendDurationSeconds = Mathf.Clamp(parsedDuration, 1f, 3600f);
}
if (GUILayout.Button("Extend Battle", GUILayout.Height(44f)))
{
if (procedure.CurrentGameState is GameStateBattle gameState)
{
gameState.AddBattleDuration(_extendDurationSeconds);
}
}
GUILayout.EndHorizontal();
}
if (_showPlayerWeaponControls)
{
GUILayout.Space(12f);
GUILayout.Label(
$"Player Weapon: {(player == null ? "Player not found" : (player.WeaponEnabled ? "Enabled" : "Disabled"))}");
GUILayout.BeginHorizontal();
GUI.enabled = player != null;
if (GUILayout.Button("Disable Weapons", GUILayout.Height(44f)))
{
player.SetWeaponEnabled(false);
}
if (GUILayout.Button("Enable Weapons", GUILayout.Height(44f)))
{
player.SetWeaponEnabled(true);
}
GUI.enabled = true;
GUILayout.EndHorizontal();
}
if (_showPlayerHealthControls)
{
GUILayout.Space(4f);
GUILayout.Label(
$"Player HP: {(playerHealth == null ? "Unavailable" : $"{playerHealth.CurrentHealth}/{playerHealth.MaxHealth}")}");
GUILayout.BeginHorizontal();
GUI.enabled = playerHealth != null;
if (GUILayout.Button($"+{DebugHealAmount} HP", GUILayout.Height(44f)))
{
AddPlayerHealth(playerHealth, DebugHealAmount);
}
if (GUILayout.Button(_lockPlayerHealthToMax ? "GodMode: ON" : "GodMode: OFF", GUILayout.Height(44f)))
{
_lockPlayerHealthToMax = !_lockPlayerHealthToMax;
if (_lockPlayerHealthToMax)
{
RestorePlayerHealthToMax(playerHealth);
}
}
GUI.enabled = true;
GUILayout.EndHorizontal();
}
}
private bool HasVisibleBattleSection()
{
return _showBattleOverview ||
_showCollisionStats ||
_showSpawnControls ||
_showBattleDurationControls ||
_showPlayerWeaponControls ||
_showPlayerHealthControls;
}
private void EnsurePropList(bool force = false)
{
if (!force && _allProps != null && _allProps.Count > 0) return;
if (GameEntry.Luban == null)
{
_allProps = Array.Empty<PropConfig>();
_displayNames = Array.Empty<string>();
return;
}
_allProps = GameEntry.Luban.GetTable<PropConfig>();
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, Mathf.Max(0, _allProps.Count - 1));
ApplyFilter(_searchText);
}
private void ApplyFilter(string keyword)
{
if (_allProps == null || _allProps.Count == 0)
{
_displayNames = Array.Empty<string>();
return;
}
if (string.IsNullOrWhiteSpace(keyword))
{
_filteredProps = _allProps;
}
else
{
string search = keyword.Trim();
_filteredProps = _allProps.Where(p =>
p != null &&
(p.Name?.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0 ||
p.Id.ToString().Contains(search))).ToArray();
}
_displayNames = _filteredProps.Select(p => $"[{p.Id}] {p.Name} ({p.Rarity})").ToArray();
if (_displayNames.Length == 0) _selectedIndex = 0;
else _selectedIndex = Mathf.Clamp(_selectedIndex, 0, _displayNames.Length - 1);
}
private PropConfig GetSelectedProp()
{
if (_filteredProps == null || _filteredProps.Count == 0) return null;
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _filteredProps.Count - 1);
return _filteredProps[_selectedIndex];
}
private static Player FindPlayer()
{
return UnityEngine.Object.FindObjectOfType<Player>();
}
private void KeepPlayerHealthAtMax()
{
Player player = FindPlayer();
if (player == null) return;
HealthComponent playerHealth = player.GetComponent<HealthComponent>();
if (playerHealth == null) return;
RestorePlayerHealthToMax(playerHealth);
}
private static void AddPlayerHealth(HealthComponent playerHealth, int amount)
{
if (playerHealth == null || amount <= 0) return;
if (playerHealth.CurrentHealth <= 0) return;
int maxHealth = playerHealth.MaxHealth;
if (maxHealth <= 0) return;
int nextHealth = Mathf.Clamp(playerHealth.CurrentHealth + amount, 0, maxHealth);
if (nextHealth == playerHealth.CurrentHealth) return;
playerHealth.CurrentHealth = nextHealth;
PublishPlayerHealthChanged(playerHealth);
}
private static void RestorePlayerHealthToMax(HealthComponent playerHealth)
{
if (playerHealth == null) return;
if (playerHealth.CurrentHealth <= 0) return;
int maxHealth = playerHealth.MaxHealth;
if (maxHealth <= 0 || playerHealth.CurrentHealth >= maxHealth) return;
playerHealth.CurrentHealth = maxHealth;
PublishPlayerHealthChanged(playerHealth);
}
private static void PublishPlayerHealthChanged(HealthComponent playerHealth)
{
if (playerHealth == null || GameEntry.Event == null) return;
GameEntry.Event.Fire(null,
PlayerHealthChangeEventArgs.Create(0, playerHealth.CurrentHealth, playerHealth.MaxHealth));
}
private static void AddSelectedBuffToPlayer(PropConfig prop, int count)
{
Player player = FindPlayer();
if (player == null || prop == null || prop.Modifiers == null) return;
int applyCount = Mathf.Clamp(count, 1, 99);
for (int i = 0; i < applyCount; i++)
{
player.AddProp(new PropItem(prop));
}
}
private void HandleCornerTapGesture()
{
if (!TryGetTouchReleased(out Vector2 touchPosition)) return;
if (touchPosition.x > 80f || touchPosition.y < Screen.height - 80f) return;
float now = Time.unscaledTime;
if (now - _lastCornerTapTime > CornerTapWindow)
{
_cornerTapCount = 0;
}
_lastCornerTapTime = now;
_cornerTapCount++;
if (_cornerTapCount >= RequiredCornerTapCount)
{
_cornerTapCount = 0;
_isPanelVisible = !_isPanelVisible;
}
}
private static bool IsTogglePressed()
{
#if ENABLE_INPUT_SYSTEM
Keyboard keyboard = Keyboard.current;
if (keyboard == null) return false;
return keyboard.backquoteKey.wasPressedThisFrame || keyboard.f8Key.wasPressedThisFrame;
#else
return Input.GetKeyDown(KeyCode.BackQuote) || Input.GetKeyDown(KeyCode.F8);
#endif
}
private static bool TryGetTouchReleased(out Vector2 touchPosition)
{
#if ENABLE_INPUT_SYSTEM
Touchscreen touchscreen = Touchscreen.current;
if (touchscreen == null)
{
touchPosition = default;
return false;
}
var touch = touchscreen.primaryTouch;
if (!touch.press.wasReleasedThisFrame)
{
touchPosition = default;
return false;
}
touchPosition = touch.position.ReadValue();
return true;
#else
if (Input.touchCount <= 0)
{
touchPosition = default;
return false;
}
Touch touch = Input.GetTouch(0);
if (touch.phase != TouchPhase.Ended)
{
touchPosition = default;
return false;
}
touchPosition = touch.position;
return true;
#endif
}
}
@@ -17,13 +17,16 @@ public sealed partial class GlobalConfig : Luban.BeanBase
public GlobalConfig(ByteBuf _buf) public GlobalConfig(ByteBuf _buf)
{ {
WeaponCapacity = _buf.ReadInt(); WeaponCapacity = _buf.ReadInt();
PropMaxCount = _buf.ReadInt();
WeaponRecycleRate = _buf.ReadInt(); WeaponRecycleRate = _buf.ReadInt();
ShopGoodsCount = _buf.ReadInt(); ShopGoodsCount = _buf.ReadInt();
ShopPriceRandomPercent = _buf.ReadInt(); ShopPriceRandomPercent = _buf.ReadInt();
ShopMinPrice = _buf.ReadInt(); ShopMinPrice = _buf.ReadInt();
PropMaxCount = _buf.ReadInt();
LevelUpRefreshPriceBase = _buf.ReadInt(); LevelUpRefreshPriceBase = _buf.ReadInt();
LevelUpRewardCount = _buf.ReadInt(); LevelUpRewardCount = _buf.ReadInt();
EnemyGroupName = _buf.ReadString();
SpawnEnemyMaxCount = _buf.ReadInt();
SpawnDistanceFromPlayer = _buf.ReadInt();
} }
public static GlobalConfig DeserializeGlobalConfig(ByteBuf _buf) public static GlobalConfig DeserializeGlobalConfig(ByteBuf _buf)
@@ -36,6 +39,10 @@ public sealed partial class GlobalConfig : Luban.BeanBase
/// </summary> /// </summary>
public readonly int WeaponCapacity; public readonly int WeaponCapacity;
/// <summary> /// <summary>
/// 最大持有道具数量
/// </summary>
public readonly int PropMaxCount;
/// <summary>
/// 武器回收价比例 /// 武器回收价比例
/// </summary> /// </summary>
public readonly int WeaponRecycleRate; public readonly int WeaponRecycleRate;
@@ -52,10 +59,6 @@ public sealed partial class GlobalConfig : Luban.BeanBase
/// </summary> /// </summary>
public readonly int ShopMinPrice; public readonly int ShopMinPrice;
/// <summary> /// <summary>
/// 最大持有道具数量
/// </summary>
public readonly int PropMaxCount;
/// <summary>
/// 升级奖励刷新基本价格 /// 升级奖励刷新基本价格
/// </summary> /// </summary>
public readonly int LevelUpRefreshPriceBase; public readonly int LevelUpRefreshPriceBase;
@@ -63,6 +66,18 @@ public sealed partial class GlobalConfig : Luban.BeanBase
/// 升级奖励候选数 /// 升级奖励候选数
/// </summary> /// </summary>
public readonly int LevelUpRewardCount; public readonly int LevelUpRewardCount;
/// <summary>
/// 敌人对象池名
/// </summary>
public readonly string EnemyGroupName;
/// <summary>
/// 最大敌人数量
/// </summary>
public readonly int SpawnEnemyMaxCount;
/// <summary>
/// 敌人生成距离
/// </summary>
public readonly int SpawnDistanceFromPlayer;
public const int __ID__ = -958250779; public const int __ID__ = -958250779;
public override int GetTypeId() => __ID__; public override int GetTypeId() => __ID__;
@@ -77,19 +92,25 @@ public sealed partial class GlobalConfig : Luban.BeanBase
} }
public override string ToString() public override string ToString()
{ {
return "{ " return "{ "
+ "weaponCapacity:" + WeaponCapacity + "," + "weaponCapacity:" + WeaponCapacity + ","
+ "propMaxCount:" + PropMaxCount + ","
+ "weaponRecycleRate:" + WeaponRecycleRate + "," + "weaponRecycleRate:" + WeaponRecycleRate + ","
+ "shopGoodsCount:" + ShopGoodsCount + "," + "shopGoodsCount:" + ShopGoodsCount + ","
+ "shopPriceRandomPercent:" + ShopPriceRandomPercent + "," + "shopPriceRandomPercent:" + ShopPriceRandomPercent + ","
+ "shopMinPrice:" + ShopMinPrice + "," + "shopMinPrice:" + ShopMinPrice + ","
+ "propMaxCount:" + PropMaxCount + ","
+ "levelUpRefreshPriceBase:" + LevelUpRefreshPriceBase + "," + "levelUpRefreshPriceBase:" + LevelUpRefreshPriceBase + ","
+ "levelUpRewardCount:" + LevelUpRewardCount + "," + "levelUpRewardCount:" + LevelUpRewardCount + ","
+ "enemyGroupName:" + EnemyGroupName + ","
+ "spawnEnemyMaxCount:" + SpawnEnemyMaxCount + ","
+ "spawnDistanceFromPlayer:" + SpawnDistanceFromPlayer + ","
+ "}"; + "}";
} }
} }
@@ -35,6 +35,10 @@ public partial class TbGlobalConfig
/// </summary> /// </summary>
public int WeaponCapacity => _data.WeaponCapacity; public int WeaponCapacity => _data.WeaponCapacity;
/// <summary> /// <summary>
/// 最大持有道具数量
/// </summary>
public int PropMaxCount => _data.PropMaxCount;
/// <summary>
/// 武器回收价比例 /// 武器回收价比例
/// </summary> /// </summary>
public int WeaponRecycleRate => _data.WeaponRecycleRate; public int WeaponRecycleRate => _data.WeaponRecycleRate;
@@ -51,10 +55,6 @@ public partial class TbGlobalConfig
/// </summary> /// </summary>
public int ShopMinPrice => _data.ShopMinPrice; public int ShopMinPrice => _data.ShopMinPrice;
/// <summary> /// <summary>
/// 最大持有道具数量
/// </summary>
public int PropMaxCount => _data.PropMaxCount;
/// <summary>
/// 升级奖励刷新基本价格 /// 升级奖励刷新基本价格
/// </summary> /// </summary>
public int LevelUpRefreshPriceBase => _data.LevelUpRefreshPriceBase; public int LevelUpRefreshPriceBase => _data.LevelUpRefreshPriceBase;
@@ -62,6 +62,18 @@ public partial class TbGlobalConfig
/// 升级奖励候选数 /// 升级奖励候选数
/// </summary> /// </summary>
public int LevelUpRewardCount => _data.LevelUpRewardCount; public int LevelUpRewardCount => _data.LevelUpRewardCount;
/// <summary>
/// 敌人对象池名
/// </summary>
public string EnemyGroupName => _data.EnemyGroupName;
/// <summary>
/// 最大敌人数量
/// </summary>
public int SpawnEnemyMaxCount => _data.SpawnEnemyMaxCount;
/// <summary>
/// 敌人生成距离
/// </summary>
public int SpawnDistanceFromPlayer => _data.SpawnDistanceFromPlayer;
public void ResolveRef(Tables tables) public void ResolveRef(Tables tables)
{ {
@@ -0,0 +1,561 @@
using System;
using System.Collections.Generic;
using System.Linq;
using SepCore.Event;
using SepCore.Definition;
using SepCore.Entity;
using SepCore.Components;
using SepCore.CustomUtility;
using SepCore.Simulation;
using SepCore.EnemyManager;
using SepCore.Procedure;
using UnityEngine;
using UnityGameFramework.Runtime;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
namespace SepCore.DebugPanel
{
public class RuntimeDebugPanelComponent : MonoBehaviour
{
private const float MinSpawnRate = 0.1f;
private const float CornerTapWindow = 0.6f;
private const int RequiredCornerTapCount = 3;
private const int DebugHealAmount = 200;
[Header("Window Content")]
[SerializeField] private bool _showBuffSection = true;
[SerializeField] private bool _showBattleOverview = true;
[SerializeField] private bool _showCollisionStats = true;
[SerializeField] private bool _showSpawnControls = true;
[SerializeField] private bool _showBattleDurationControls = true;
[SerializeField] private bool _showPlayerWeaponControls = true;
[SerializeField] private bool _showPlayerHealthControls = true;
[SerializeField] private bool _showTips = true;
private Rect _windowRect;
private Vector2 _panelScroll;
private GUISkin _panelSkin;
private bool _isPanelVisible;
private int _windowId;
private string _searchText = string.Empty;
private int _selectedIndex;
private int _addCount = 1;
private Vector2 _buffScroll;
private float _spawnRateScaleInput = 1f;
private float _extendDurationSeconds = 30f;
private IReadOnlyList<PropConfig> _allProps;
private IReadOnlyList<PropConfig> _filteredProps;
private string[] _displayNames = Array.Empty<string>();
private int _cornerTapCount;
private float _lastCornerTapTime = -10f;
private bool _lockPlayerHealthToMax;
private void Awake()
{
_windowId = GetInstanceID();
}
private void Update()
{
if (IsTogglePressed())
{
_isPanelVisible = !_isPanelVisible;
}
HandleCornerTapGesture();
if (_lockPlayerHealthToMax)
{
KeepPlayerHealthAtMax();
}
}
private void OnGUI()
{
GUISkin previousSkin = GUI.skin;
Matrix4x4 previousMatrix = GUI.matrix;
if (_panelSkin == null)
{
_panelSkin = Instantiate(previousSkin);
_panelSkin.label.fontSize = 18;
_panelSkin.label.wordWrap = true;
_panelSkin.button.fontSize = 18;
_panelSkin.button.padding = new RectOffset(12, 12, 10, 10);
_panelSkin.button.fixedHeight = 44f;
_panelSkin.textField.fontSize = 20;
_panelSkin.textField.fixedHeight = 44f;
_panelSkin.textField.padding = new RectOffset(10, 10, 10, 10);
_panelSkin.window.padding = new RectOffset(16, 16, 12, 16);
_panelSkin.verticalScrollbar.fixedWidth = 28f;
_panelSkin.verticalScrollbarThumb.fixedWidth = 28f;
}
Rect safeArea = Screen.safeArea;
float scale = Mathf.Max(0.1f, Mathf.Min(safeArea.width, safeArea.height) / 480f);
Rect bounds = new Rect(0f, 0f, safeArea.width / scale, safeArea.height / scale);
try
{
GUI.skin = _panelSkin;
GUI.matrix = Matrix4x4.TRS(
new Vector3(safeArea.x, Screen.height - safeArea.yMax, 0f),
Quaternion.identity, new Vector3(scale, scale, 1f));
DrawToggleButton(bounds);
if (!_isPanelVisible) return;
float width = Mathf.Min(460f, bounds.width - 24f);
_windowRect = new Rect(bounds.width - width - 12f, 72f, width,
Mathf.Min(760f, bounds.height - 84f));
GUI.Window(_windowId, _windowRect, DrawWindow, string.Empty);
}
finally
{
GUI.matrix = previousMatrix;
GUI.skin = previousSkin;
}
}
private void OnDestroy()
{
if (_panelSkin != null) Destroy(_panelSkin);
}
private void DrawToggleButton(Rect bounds)
{
const float width = 120f;
const float height = 48f;
Rect buttonRect = new Rect(bounds.width - width - 12f, 12f, width, height);
if (GUI.Button(buttonRect, "DEBUG"))
{
_isPanelVisible = !_isPanelVisible;
}
}
private void DrawWindow(int windowId)
{
if (_showBuffSection)
{
EnsurePropList();
}
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("Runtime Debug", GUILayout.ExpandWidth(true));
if (GUILayout.Button("Close", GUILayout.Width(90f))) _isPanelVisible = false;
GUILayout.EndHorizontal();
GUILayout.Space(8f);
_panelScroll = GUILayout.BeginScrollView(_panelScroll, false, true);
bool hasPreviousSection = false;
if (_showBuffSection)
{
DrawBuffSection();
hasPreviousSection = true;
}
if (HasVisibleBattleSection())
{
if (hasPreviousSection)
{
GUILayout.Space(8f);
GUILayout.Label(string.Empty, GUI.skin.horizontalSlider);
GUILayout.Space(8f);
}
DrawBattleSection();
hasPreviousSection = true;
}
if (_showTips)
{
if (hasPreviousSection)
{
GUILayout.Space(8f);
}
GUILayout.Label("Tips: press F8 or tap top-left corner 3 times to toggle.");
}
GUILayout.EndScrollView();
GUILayout.EndVertical();
}
private void DrawBuffSection()
{
GUILayout.Label("Buff Debug");
GUILayout.BeginHorizontal();
GUILayout.Label("Search", GUILayout.Width(78f));
_searchText = GUILayout.TextField(_searchText);
if (GUILayout.Button("Refresh", GUILayout.Width(100f)))
{
EnsurePropList(true);
}
GUILayout.EndHorizontal();
ApplyFilter(_searchText);
if (_displayNames.Length == 0)
{
GUILayout.Label("No Buff data. Enter battle and try again.");
return;
}
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _displayNames.Length - 1);
_buffScroll = GUILayout.BeginScrollView(_buffScroll, GUILayout.Height(120f));
_selectedIndex = GUILayout.SelectionGrid(_selectedIndex, _displayNames, 1);
GUILayout.EndScrollView();
PropConfig selectedProp = GetSelectedProp();
if (selectedProp == null) return;
GUILayout.Label($"Selected: {selectedProp.Name} ({selectedProp.Rarity})");
GUILayout.Label(ItemDescUtility.CreatePropDescription(selectedProp.Modifiers), GUILayout.Height(40f));
GUILayout.BeginHorizontal();
GUILayout.Label("Count", GUILayout.Width(78f));
string addCountText = GUILayout.TextField(_addCount.ToString(), GUILayout.Width(88f));
if (!int.TryParse(addCountText, out _addCount)) _addCount = 1;
_addCount = Mathf.Clamp(_addCount, 1, 99);
if (GUILayout.Button("Add Buff To Player", GUILayout.Height(44f)))
{
AddSelectedBuffToPlayer(selectedProp, _addCount);
}
GUILayout.EndHorizontal();
}
private void DrawBattleSection()
{
GUILayout.Label("Battle Debug");
ProcedureGame procedure = GameEntry.Procedure.CurrentProcedure as ProcedureGame;
Player player = FindPlayer();
HealthComponent playerHealth = player != null ? player.GetComponent<HealthComponent>() : null;
if (procedure == null)
{
GUILayout.Label("ProcedureGame unavailable.");
return;
}
EnemyManagerComponent enemyManager = GameEntry.EnemyManager;
if (_showBattleOverview)
{
GUILayout.Label($"Spawn Rate: {enemyManager.SpawnRateScale:F2}");
GUILayout.Label(
$"Battle Time: {enemyManager.ElapsedBattleTime:F1}s / {enemyManager.BattleDuration:F1}s");
GUILayout.Label($"Enemy Count: {enemyManager.CurrentEnemyCount}");
}
if (_showCollisionStats)
{
SimulationWorld simulationWorld = GameEntry.SimulationWorld;
GUILayout.Space(4f);
GUILayout.Label(
$"Collision Queries: total {simulationWorld.LastCollisionQueryCount} (Projectile {simulationWorld.LastProjectileCollisionQueryCount} / Area {simulationWorld.LastAreaCollisionQueryCount})");
GUILayout.Label(
$"Collision Candidates: total {simulationWorld.LastCollisionCandidateCount} (Projectile {simulationWorld.LastProjectileCollisionCandidateCount} / Area {simulationWorld.LastAreaCollisionCandidateCount})");
GUILayout.Label(
$"Area Resolve: hits {simulationWorld.LastResolvedAreaHitCount}");
GUILayout.Label(
$"Broad Phase: cell {simulationWorld.LastCollisionCellSize:F2}, hasEnemyTargets {(simulationWorld.LastCollisionHasEnemyTargets ? "Yes" : "No")}");
}
if (_showSpawnControls)
{
GUILayout.Space(12f);
GUILayout.Label("Enemy Spawn Rate");
GUILayout.BeginHorizontal();
GUILayout.Label("Rate", GUILayout.Width(78f));
string rateText = GUILayout.TextField(_spawnRateScaleInput.ToString("F2"), GUILayout.Width(88f));
if (float.TryParse(rateText, out float parsedRate))
{
_spawnRateScaleInput = Mathf.Clamp(parsedRate, MinSpawnRate, 50f);
}
if (GUILayout.Button("Apply", GUILayout.Width(100f)))
{
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button("x0.5"))
{
_spawnRateScaleInput = Mathf.Max(MinSpawnRate, enemyManager.SpawnRateScale * 0.5f);
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
if (GUILayout.Button("x2"))
{
_spawnRateScaleInput = enemyManager.SpawnRateScale * 2f;
enemyManager.SetSpawnRateScale(_spawnRateScaleInput);
}
GUILayout.EndHorizontal();
}
if (_showBattleDurationControls)
{
GUILayout.Space(12f);
GUILayout.Label("Battle Duration");
GUILayout.BeginHorizontal();
GUILayout.Label("Add Sec", GUILayout.Width(78f));
string durationText = GUILayout.TextField(_extendDurationSeconds.ToString("F0"), GUILayout.Width(88f));
if (float.TryParse(durationText, out float parsedDuration))
{
_extendDurationSeconds = Mathf.Clamp(parsedDuration, 1f, 3600f);
}
if (GUILayout.Button("Extend Battle", GUILayout.Height(44f)))
{
if (procedure.CurrentGameState is GameStateBattle gameState)
{
gameState.AddBattleDuration(_extendDurationSeconds);
}
}
GUILayout.EndHorizontal();
}
if (_showPlayerWeaponControls)
{
GUILayout.Space(12f);
GUILayout.Label(
$"Player Weapon: {(player == null ? "Player not found" : (player.WeaponEnabled ? "Enabled" : "Disabled"))}");
GUILayout.BeginHorizontal();
GUI.enabled = player != null;
if (GUILayout.Button("Disable Weapons", GUILayout.Height(44f)))
{
player.SetWeaponEnabled(false);
}
if (GUILayout.Button("Enable Weapons", GUILayout.Height(44f)))
{
player.SetWeaponEnabled(true);
}
GUI.enabled = true;
GUILayout.EndHorizontal();
}
if (_showPlayerHealthControls)
{
GUILayout.Space(4f);
GUILayout.Label(
$"Player HP: {(playerHealth == null ? "Unavailable" : $"{playerHealth.CurrentHealth}/{playerHealth.MaxHealth}")}");
GUILayout.BeginHorizontal();
GUI.enabled = playerHealth != null;
if (GUILayout.Button($"+{DebugHealAmount} HP", GUILayout.Height(44f)))
{
AddPlayerHealth(playerHealth, DebugHealAmount);
}
if (GUILayout.Button(_lockPlayerHealthToMax ? "GodMode: ON" : "GodMode: OFF", GUILayout.Height(44f)))
{
_lockPlayerHealthToMax = !_lockPlayerHealthToMax;
if (_lockPlayerHealthToMax)
{
RestorePlayerHealthToMax(playerHealth);
}
}
GUI.enabled = true;
GUILayout.EndHorizontal();
}
}
private bool HasVisibleBattleSection()
{
return _showBattleOverview ||
_showCollisionStats ||
_showSpawnControls ||
_showBattleDurationControls ||
_showPlayerWeaponControls ||
_showPlayerHealthControls;
}
private void EnsurePropList(bool force = false)
{
if (!force && _allProps != null && _allProps.Count > 0) return;
if (!GameEntry.Luban.IsReady)
{
_allProps = Array.Empty<PropConfig>();
_displayNames = Array.Empty<string>();
return;
}
_allProps = GameEntry.Luban.GetTable<PropConfig>();
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, Mathf.Max(0, _allProps.Count - 1));
ApplyFilter(_searchText);
}
private void ApplyFilter(string keyword)
{
if (_allProps == null || _allProps.Count == 0)
{
_displayNames = Array.Empty<string>();
return;
}
if (string.IsNullOrWhiteSpace(keyword))
{
_filteredProps = _allProps;
}
else
{
string search = keyword.Trim();
_filteredProps = _allProps.Where(p =>
p.Name.IndexOf(search, StringComparison.OrdinalIgnoreCase) >= 0 ||
p.Id.ToString().Contains(search)).ToArray();
}
_displayNames = _filteredProps.Select(p => $"[{p.Id}] {p.Name} ({p.Rarity})").ToArray();
if (_displayNames.Length == 0) _selectedIndex = 0;
else _selectedIndex = Mathf.Clamp(_selectedIndex, 0, _displayNames.Length - 1);
}
private PropConfig GetSelectedProp()
{
if (_filteredProps == null || _filteredProps.Count == 0) return null;
_selectedIndex = Mathf.Clamp(_selectedIndex, 0, _filteredProps.Count - 1);
return _filteredProps[_selectedIndex];
}
private static Player FindPlayer()
{
return UnityEngine.Object.FindObjectOfType<Player>();
}
private void KeepPlayerHealthAtMax()
{
Player player = FindPlayer();
if (player == null) return;
HealthComponent playerHealth = player.GetComponent<HealthComponent>();
RestorePlayerHealthToMax(playerHealth);
}
private static void AddPlayerHealth(HealthComponent playerHealth, int amount)
{
if (amount <= 0) return;
if (playerHealth.CurrentHealth <= 0) return;
int maxHealth = playerHealth.MaxHealth;
if (maxHealth <= 0) return;
int nextHealth = Mathf.Clamp(playerHealth.CurrentHealth + amount, 0, maxHealth);
if (nextHealth == playerHealth.CurrentHealth) return;
playerHealth.CurrentHealth = nextHealth;
PublishPlayerHealthChanged(playerHealth);
}
private static void RestorePlayerHealthToMax(HealthComponent playerHealth)
{
if (playerHealth.CurrentHealth <= 0) return;
int maxHealth = playerHealth.MaxHealth;
if (maxHealth <= 0 || playerHealth.CurrentHealth >= maxHealth) return;
playerHealth.CurrentHealth = maxHealth;
PublishPlayerHealthChanged(playerHealth);
}
private static void PublishPlayerHealthChanged(HealthComponent playerHealth)
{
GameEntry.Event.Fire(null,
PlayerHealthChangeEventArgs.Create(0, playerHealth.CurrentHealth, playerHealth.MaxHealth));
}
private static void AddSelectedBuffToPlayer(PropConfig prop, int count)
{
Player player = FindPlayer();
if (player == null) return;
int applyCount = Mathf.Clamp(count, 1, 99);
for (int i = 0; i < applyCount; i++)
{
player.AddProp(new PropItem(prop));
}
}
private void HandleCornerTapGesture()
{
if (!TryGetTouchReleased(out Vector2 touchPosition)) return;
if (touchPosition.x > 80f || touchPosition.y < Screen.height - 80f) return;
float now = Time.unscaledTime;
if (now - _lastCornerTapTime > CornerTapWindow)
{
_cornerTapCount = 0;
}
_lastCornerTapTime = now;
_cornerTapCount++;
if (_cornerTapCount >= RequiredCornerTapCount)
{
_cornerTapCount = 0;
_isPanelVisible = !_isPanelVisible;
}
}
private static bool IsTogglePressed()
{
#if ENABLE_INPUT_SYSTEM
Keyboard keyboard = Keyboard.current;
if (keyboard == null) return false;
return keyboard.backquoteKey.wasPressedThisFrame || keyboard.f8Key.wasPressedThisFrame;
#else
return Input.GetKeyDown(KeyCode.BackQuote) || Input.GetKeyDown(KeyCode.F8);
#endif
}
private static bool TryGetTouchReleased(out Vector2 touchPosition)
{
#if ENABLE_INPUT_SYSTEM
Touchscreen touchscreen = Touchscreen.current;
if (touchscreen == null)
{
touchPosition = default;
return false;
}
var touch = touchscreen.primaryTouch;
if (!touch.press.wasReleasedThisFrame)
{
touchPosition = default;
return false;
}
touchPosition = touch.position.ReadValue();
return true;
#else
if (Input.touchCount <= 0)
{
touchPosition = default;
return false;
}
Touch touch = Input.GetTouch(0);
if (touch.phase != TouchPhase.Ended)
{
touchPosition = default;
return false;
}
touchPosition = touch.position;
return true;
#endif
}
}
}
@@ -49,7 +49,7 @@ namespace SepCore.Procedure
_levelTimerHandle = GameEntry.Timer.ScheduleOnce(levelConfig.Duration, OnLevelTimeUp, this); _levelTimerHandle = GameEntry.Timer.ScheduleOnce(levelConfig.Duration, OnLevelTimeUp, this);
_enemyManager.OnInit(levelConfig, Player); _enemyManager.OnInit(levelConfig, Player);
if (Player != null) Player.Enable = true; Player.Enable = true;
if (Application.isMobilePlatform) if (Application.isMobilePlatform)
{ {
@@ -61,12 +61,8 @@ namespace SepCore.Procedure
{ {
_enemyManager.OnUpdate(elapseSeconds, realElapseSeconds); _enemyManager.OnUpdate(elapseSeconds, realElapseSeconds);
SimulationWorld simulationWorld = GameEntry.SimulationWorld; Vector3 playerPosition = Player.CachedTransform.position;
if (simulationWorld != null) GameEntry.SimulationWorld.Tick(new SimulationTickContext(elapseSeconds, realElapseSeconds, playerPosition));
{
Vector3 playerPosition = Player != null ? Player.CachedTransform.position : Vector3.zero;
simulationWorld.Tick(new SimulationTickContext(elapseSeconds, realElapseSeconds, playerPosition));
}
int timeLeft = Mathf.Max(0, (int)GameEntry.Timer.GetRemainingTime(_levelTimerHandle)); int timeLeft = Mathf.Max(0, (int)GameEntry.Timer.GetRemainingTime(_levelTimerHandle));
GameEntry.Event.Fire(this, LevelProcessEventArgs.Create(timeLeft)); GameEntry.Event.Fire(this, LevelProcessEventArgs.Create(timeLeft));
@@ -8,7 +8,8 @@
"GUID:47a82ffa13c291447ab895cd0bc251cd", "GUID:47a82ffa13c291447ab895cd0bc251cd",
"GUID:436e23dbdc31e7d4fb5c3f804548b2df", "GUID:436e23dbdc31e7d4fb5c3f804548b2df",
"GUID:0e1d182005e0ae647ab3fa40f5492dbb", "GUID:0e1d182005e0ae647ab3fa40f5492dbb",
"GUID:3bb549212964b4192b427888ac9382e7" "GUID:3bb549212964b4192b427888ac9382e7",
"GUID:75469ad4d38634e559750d17036d5f7c"
], ],
"includePlatforms": [], "includePlatforms": [],
"excludePlatforms": [], "excludePlatforms": [],
@@ -167,7 +167,7 @@ namespace SepCore.AsyncTask
return entityComponent.ShowEntityAsync( return entityComponent.ShowEntityAsync(
data.Id, enemyType, AssetUtility.GetEntityAsset(entityConfig.PrefabPath), "Enemy", data.Id, enemyType, AssetUtility.GetEntityAsset(entityConfig.PrefabPath), "Enemy",
Constant.AssetPriority.EnemyAsset, data, timeout, cancellationToken) Constant.AssetPriority.EnemyAsset, data, timeout, cancellationToken)
.ContinueWith(entity => entity?.Logic as EnemyBase); .ContinueWith(entity => entity.Logic as EnemyBase);
} }
/// <summary> /// <summary>
@@ -184,7 +184,7 @@ namespace SepCore.AsyncTask
return entityComponent.ShowEntityAsync( return entityComponent.ShowEntityAsync(
data.Id, weaponType, AssetUtility.GetEntityAsset(entityConfig.PrefabPath), "Weapon", data.Id, weaponType, AssetUtility.GetEntityAsset(entityConfig.PrefabPath), "Weapon",
Constant.AssetPriority.WeaponAsset, data, timeout, cancellationToken) Constant.AssetPriority.WeaponAsset, data, timeout, cancellationToken)
.ContinueWith(entity => entity?.Logic as WeaponBase); .ContinueWith(entity => entity.Logic as WeaponBase);
} }
/// <summary> /// <summary>
@@ -1,6 +1,5 @@
using UnityEngine; using UnityEngine;
using UnityGameFramework.Runtime; using UnityGameFramework.Runtime;
using Object = UnityEngine.Object;
namespace SepCore.CameraModule namespace SepCore.CameraModule
{ {
@@ -11,178 +10,52 @@ namespace SepCore.CameraModule
[DisallowMultipleComponent] [DisallowMultipleComponent]
public class CameraModuleComponent : GameFrameworkComponent public class CameraModuleComponent : GameFrameworkComponent
{ {
[SerializeField] private CinemachineCameraController _cinemachineController; [SerializeField] private CinemachineCameraController _cinemachineController = null;
[SerializeField] private bool _autoSearchController = true;
[SerializeField] private bool _logMissingControllerWarnings = true;
private ICameraController _controller;
private bool _hasLoggedMissingController;
public ICameraController Controller
{
get
{
ResolveController(false);
return IsControllerValid(_controller) ? _controller : null;
}
}
public bool HasController => Controller != null;
public Transform Target => Controller?.Target;
public CameraEffectSettings CurrentSettings => Controller?.CurrentSettings ?? CameraEffectSettings.Default;
protected override void Awake()
{
base.Awake();
ResolveController(false);
}
public void RegisterController(ICameraController controller)
{
if (!IsControllerValid(controller))
{
Log.Warning("CameraModuleComponent.RegisterController() controller is invalid.");
return;
}
_controller = controller;
_hasLoggedMissingController = false;
if (controller is CinemachineCameraController cinemachineController)
{
_cinemachineController = cinemachineController;
}
}
public void UnregisterController(ICameraController controller)
{
if (controller != null && !ReferenceEquals(_controller, controller))
{
return;
}
_controller = null;
_cinemachineController = null;
}
public void SetTarget(Transform target) public void SetTarget(Transform target)
{ {
if (!EnsureController()) if (!EnsureController()) return;
{
return;
}
_controller.SetTarget(target); _cinemachineController.SetTarget(target);
} }
public void ApplySettings(CameraEffectSettings settings) public void ApplySettings(CameraEffectSettings settings)
{ {
if (!EnsureController()) if (!EnsureController()) return;
{
return;
}
_controller.ApplySettings(settings); _cinemachineController.ApplySettings(settings);
} }
public void EnableEffect(CameraEffectType effect) public void EnableEffect(CameraEffectType effect)
{ {
if (!EnsureController()) if (!EnsureController()) return;
{
return;
}
_controller.EnableEffect(effect); _cinemachineController.EnableEffect(effect);
} }
public void DisableEffect(CameraEffectType effect) public void DisableEffect(CameraEffectType effect)
{ {
if (!EnsureController()) if (!EnsureController()) return;
{
return;
}
_controller.DisableEffect(effect); _cinemachineController.DisableEffect(effect);
} }
public bool IsEffectEnabled(CameraEffectType effect) public bool IsEffectEnabled(CameraEffectType effect)
{ {
return EnsureController() && _controller.IsEffectEnabled(effect); if (!EnsureController()) return false;
return _cinemachineController.IsEffectEnabled(effect);
} }
private bool EnsureController() private bool EnsureController()
{ {
ResolveController(_logMissingControllerWarnings);
return IsControllerValid(_controller);
}
private void ResolveController(bool logWarning)
{
if (IsControllerValid(_controller))
{
return;
}
if (_cinemachineController != null) if (_cinemachineController != null)
{ {
_controller = _cinemachineController; return true;
_hasLoggedMissingController = false;
return;
} }
if (!_autoSearchController) Log.Error("CameraModuleComponent requires a CinemachineCameraController. Assign one in Inspector.");
{ return false;
LogMissingController(logWarning);
return;
}
_cinemachineController = GetComponentInChildren<CinemachineCameraController>(true);
if (_cinemachineController == null)
{
#if UNITY_2023_1_OR_NEWER
_cinemachineController = FindFirstObjectByType<CinemachineCameraController>(FindObjectsInactive.Include);
#else
_cinemachineController = FindObjectOfType<CinemachineCameraController>(true);
#endif
}
if (_cinemachineController != null)
{
_controller = _cinemachineController;
_hasLoggedMissingController = false;
return;
}
LogMissingController(logWarning);
}
private void LogMissingController(bool logWarning)
{
if (!logWarning || _hasLoggedMissingController)
{
return;
}
_hasLoggedMissingController = true;
Log.Warning(
"CameraModuleComponent requires a CinemachineCameraController. " +
"Assign one in Inspector or place one in the loaded scene.");
}
private static bool IsControllerValid(ICameraController controller)
{
if (controller == null)
{
return false;
}
if (controller is Object unityObject && unityObject == null)
{
return false;
}
return true;
} }
} }
} }
@@ -11,11 +11,11 @@ namespace SepCore.DamageText
[SerializeField] private string _poolName = "DamageTextItem"; [SerializeField] private string _poolName = "DamageTextItem";
[SerializeField] private RectTransform _instanceRoot; [SerializeField] private RectTransform _instanceRoot = null;
[SerializeField] private Canvas _canvas; [SerializeField] private Canvas _canvas = null;
[SerializeField] private GameObject _damageTextItemPrefab; [SerializeField] private GameObject _damageTextItemPrefab = null;
private IObjectPool<DamageTextItemObject> _damageTextItemPool; private IObjectPool<DamageTextItemObject> _damageTextItemPool;
@@ -30,11 +30,9 @@ namespace SepCore.DamageText
public void ShowDamage(Vector3 worldPosition, int damage) public void ShowDamage(Vector3 worldPosition, int damage)
{ {
if (damage <= 0 || _damageTextItemPool == null || _canvas == null) return; if (damage <= 0) return;
DamageTextItem item = CreateDamageTextItem(); DamageTextItem item = CreateDamageTextItem();
if (item == null) return;
item.Show(worldPosition, damage, _canvas, OnItemComplete); item.Show(worldPosition, damage, _canvas, OnItemComplete);
_activeDamageTextItems.Add(item); _activeDamageTextItems.Add(item);
} }
@@ -62,7 +60,6 @@ namespace SepCore.DamageText
private void OnItemComplete(DamageTextItem item) private void OnItemComplete(DamageTextItem item)
{ {
if (item == null) return;
item.ResetItem(); item.ResetItem();
_activeDamageTextItems.Remove(item); _activeDamageTextItems.Remove(item);
_damageTextItemPool.Unspawn(item); _damageTextItemPool.Unspawn(item);
@@ -72,7 +69,6 @@ namespace SepCore.DamageText
{ {
_activeDamageTextItems.Clear(); _activeDamageTextItems.Clear();
_damageTextItemPool.Release(); _damageTextItemPool.Release();
_damageTextItemPool = null;
} }
} }
} }
@@ -13,26 +13,17 @@ namespace SepCore.DamageText
private const float FadeDuration = 0.35f; private const float FadeDuration = 0.35f;
private static readonly Color NormalColor = new Color(1f, 0.32f, 0.23f, 1f); private static readonly Color NormalColor = new Color(1f, 0.32f, 0.23f, 1f);
[SerializeField] private RectTransform _cachedTransform; [SerializeField] private RectTransform _cachedTransform = null;
[SerializeField] private CanvasGroup _canvasGroup; [SerializeField] private CanvasGroup _canvasGroup = null;
[SerializeField] private TMP_Text _text; [SerializeField] private TMP_Text _text = null;
private Sequence _sequence; private Sequence _sequence;
private Action<DamageTextItem> _onComplete; private Action<DamageTextItem> _onComplete;
private void Awake()
{
if (_cachedTransform == null) _cachedTransform = GetComponent<RectTransform>();
if (_canvasGroup == null) _canvasGroup = GetComponent<CanvasGroup>();
if (_text == null) _text = GetComponent<TMP_Text>();
}
public void Show(Vector3 worldPosition, int damage, Canvas canvas, Action<DamageTextItem> onComplete) public void Show(Vector3 worldPosition, int damage, Canvas canvas, Action<DamageTextItem> onComplete)
{ {
if (canvas == null || GameEntry.Scene.MainCamera == null) return;
_onComplete = onComplete; _onComplete = onComplete;
gameObject.SetActive(true); gameObject.SetActive(true);
KillSequence(); KillSequence();
@@ -53,7 +44,7 @@ namespace SepCore.DamageText
.SetEase(Ease.OutQuad)); .SetEase(Ease.OutQuad));
_sequence.Join(_cachedTransform.DOPunchScale(new Vector3(0.15f, 0.15f, 0f), 0.18f, 6, 0.75f)); _sequence.Join(_cachedTransform.DOPunchScale(new Vector3(0.15f, 0.15f, 0f), 0.18f, 6, 0.75f));
_sequence.Join(_canvasGroup.DOFade(0f, FadeDuration).SetDelay(FadeDelay)); _sequence.Join(_canvasGroup.DOFade(0f, FadeDuration).SetDelay(FadeDelay));
_sequence.OnComplete(() => _onComplete?.Invoke(this)); _sequence.OnComplete(() => _onComplete(this));
} }
public void ResetItem() public void ResetItem()
@@ -73,6 +64,7 @@ namespace SepCore.DamageText
private void KillSequence() private void KillSequence()
{ {
if (_sequence == null) return; if (_sequence == null) return;
_sequence.Kill(); _sequence.Kill();
_sequence = null; _sequence = null;
} }
@@ -13,7 +13,7 @@ namespace SepCore.EnemyManager
{ {
public class EnemyManagerComponent : GameFrameworkComponent public class EnemyManagerComponent : GameFrameworkComponent
{ {
private const string EnemyGroupName = "Enemy"; private string EnemyGroupName => GameEntry.Luban.Global.EnemyGroupName;
private EntityComponent _entity; private EntityComponent _entity;
private EnemyRegistry _enemyRegistry; private EnemyRegistry _enemyRegistry;
@@ -21,8 +21,8 @@ namespace SepCore.EnemyManager
public IReadOnlyCollection<EntityBase> Enemies => _enemyRegistry.Enemies; public IReadOnlyCollection<EntityBase> Enemies => _enemyRegistry.Enemies;
[SerializeField] private int _spawnEnemyMaxCount = 5000; private int _spawnEnemyMaxCount;
[SerializeField] private int _spawnDistanceFromPlayer = 20; private int _spawnDistanceFromPlayer;
private int _currentSpawnEnemyId; private int _currentSpawnEnemyId;
private int _currentLevel; private int _currentLevel;
@@ -61,12 +61,8 @@ namespace SepCore.EnemyManager
GameEntry.Event.Unsubscribe(HideEntityCompleteEventArgs.EventId, OnHideEntityComplete); GameEntry.Event.Unsubscribe(HideEntityCompleteEventArgs.EventId, OnHideEntityComplete);
GameEntry.Event.Unsubscribe(ShowEntitySuccessEventArgs.EventId, OnShowEntitySuccess); GameEntry.Event.Unsubscribe(ShowEntitySuccessEventArgs.EventId, OnShowEntitySuccess);
_spawnCts?.Dispose(); _spawnCts.Dispose();
_spawnCts = null; _spawnScheduler.Reset();
_enemyRegistry = null;
_spawnScheduler?.Reset();
_spawnScheduler = null;
_entity = null;
} }
public void OnInit(LevelConfig level, Player player) public void OnInit(LevelConfig level, Player player)
@@ -78,7 +74,8 @@ namespace SepCore.EnemyManager
} }
_isStopped = false; _isStopped = false;
_spawnEnemyMaxCount = GameEntry.Luban.Global.SpawnEnemyMaxCount;
_spawnDistanceFromPlayer = GameEntry.Luban.Global.SpawnDistanceFromPlayer / 1000;
_player = player.CachedTransform; _player = player.CachedTransform;
_spawnPositionStrategy = new RandomCircleSpawnStrategy(_spawnDistanceFromPlayer); _spawnPositionStrategy = new RandomCircleSpawnStrategy(_spawnDistanceFromPlayer);
@@ -138,7 +135,7 @@ namespace SepCore.EnemyManager
var ct = _spawnCts.Token; var ct = _spawnCts.Token;
var (isCanceled, enemy) = var (isCanceled, enemy) =
await _entity.ShowEnemyAsync(enemyData, cancellationToken: ct).SuppressCancellationThrow(); await _entity.ShowEnemyAsync(enemyData, cancellationToken: ct).SuppressCancellationThrow();
if (isCanceled || ct.IsCancellationRequested || enemy == null || !enemy.Available) if (isCanceled || ct.IsCancellationRequested)
{ {
// 取消通常发生在 OnReset 期间,此时实体往往尚未出生,enemy 为 null 无法 hide。 // 取消通常发生在 OnReset 期间,此时实体往往尚未出生,enemy 为 null 无法 hide。
// 真正的兜底在 OnShowEntitySuccess:停战后出生的敌人会被立即 hide。 // 真正的兜底在 OnShowEntitySuccess:停战后出生的敌人会被立即 hide。
@@ -150,6 +147,19 @@ namespace SepCore.EnemyManager
return; return;
} }
if (enemy == null)
{
Log.Error("Can not spawn enemy '{0}' with entity id '{1}': entity logic is invalid.", enemyType,
entityId);
return;
}
// 未取消但实体已不可用,说明 OnShowEntitySuccess 已在停战窗口兜底 hide。
if (!enemy.Available)
{
return;
}
// await 恢复时若已停战,说明这是漏网的在途敌人,立即 hide,不注册。 // await 恢复时若已停战,说明这是漏网的在途敌人,立即 hide,不注册。
if (_isStopped) if (_isStopped)
{ {
@@ -157,11 +167,7 @@ namespace SepCore.EnemyManager
return; return;
} }
if (_player != null) enemy.SetTarget(_player);
{
enemy.SetTarget(_player);
}
_enemyRegistry.Register(enemy); _enemyRegistry.Register(enemy);
} }
@@ -20,22 +20,12 @@ namespace SepCore.HPBar
private void Start() private void Start()
{ {
if (_hpBarInstanceRoot == null)
{
Log.Error("You must set HP bar instance root first.");
return;
}
_cachedCanvas = _hpBarInstanceRoot.GetComponent<Canvas>(); _cachedCanvas = _hpBarInstanceRoot.GetComponent<Canvas>();
_hpBarItemObjectPool = _hpBarItemObjectPool =
GameEntry.ObjectPool.CreateSingleSpawnObjectPool<HPBarItemObject>("HPBarItem", _instancePoolCapacity); GameEntry.ObjectPool.CreateSingleSpawnObjectPool<HPBarItemObject>("HPBarItem", _instancePoolCapacity);
_activeHPBarItems = new List<HPBarItem>(); _activeHPBarItems = new List<HPBarItem>();
} }
private void OnDestroy()
{
}
private void Update() private void Update()
{ {
for (int i = _activeHPBarItems.Count - 1; i >= 0; i--) for (int i = _activeHPBarItems.Count - 1; i >= 0; i--)
@@ -54,14 +44,14 @@ namespace SepCore.HPBar
{ {
if (entity == null) if (entity == null)
{ {
Log.Warning("Entity is invalid."); Log.Error("Entity is invalid.");
return; return;
} }
HPBarItem hpBarItem = GetActiveHPBarItem(entity); HPBarItem hpBarItem = GetActiveHPBarItem(entity);
if (hpBarItem == null) if (hpBarItem == null)
{ {
hpBarItem = CreateHPBarItem(entity); hpBarItem = CreateHPBarItem();
_activeHPBarItems.Add(hpBarItem); _activeHPBarItems.Add(hpBarItem);
} }
@@ -77,11 +67,6 @@ namespace SepCore.HPBar
private HPBarItem GetActiveHPBarItem(EntityBase entity) private HPBarItem GetActiveHPBarItem(EntityBase entity)
{ {
if (entity == null)
{
return null;
}
for (int i = 0; i < _activeHPBarItems.Count; i++) for (int i = 0; i < _activeHPBarItems.Count; i++)
{ {
if (_activeHPBarItems[i].Owner == entity) if (_activeHPBarItems[i].Owner == entity)
@@ -93,7 +78,7 @@ namespace SepCore.HPBar
return null; return null;
} }
private HPBarItem CreateHPBarItem(EntityBase entity) private HPBarItem CreateHPBarItem()
{ {
HPBarItem hpBarItem = null; HPBarItem hpBarItem = null;
HPBarItemObject hpBarItemObject = _hpBarItemObjectPool.Spawn(); HPBarItemObject hpBarItemObject = _hpBarItemObjectPool.Spawn();
@@ -104,7 +89,7 @@ namespace SepCore.HPBar
else else
{ {
hpBarItem = Instantiate(_hpBarItemTemplate); hpBarItem = Instantiate(_hpBarItemTemplate);
Transform transform = hpBarItem.GetComponent<Transform>(); Transform transform = hpBarItem.transform;
transform.SetParent(_hpBarInstanceRoot); transform.SetParent(_hpBarInstanceRoot);
transform.localScale = Vector3.one; transform.localScale = Vector3.one;
_hpBarItemObjectPool.Register(HPBarItemObject.Create(hpBarItem), true); _hpBarItemObjectPool.Register(HPBarItemObject.Create(hpBarItem), true);
@@ -14,13 +14,13 @@ namespace SepCore.HPBar
private const float KeepSeconds = 0.4f; private const float KeepSeconds = 0.4f;
private const float FadeOutSeconds = 0.3f; private const float FadeOutSeconds = 0.3f;
[FormerlySerializedAs("m_HPBar")] [SerializeField] private Slider _hPBar = null; [FormerlySerializedAs("m_HPBar")] [SerializeField] private Slider _hpBar = null;
private Canvas _parentCanvas = null; private Canvas _parentCanvas = null;
private RectTransform _cachedTransform = null; private RectTransform _cachedTransform = null;
private CanvasGroup _cachedCanvasGroup = null; private CanvasGroup _cachedCanvasGroup = null;
private EntityBase _owner = null; private EntityBase _owner = null;
private int m_OwnerId = 0; private int _ownerId = 0;
public EntityBase Owner => _owner; public EntityBase Owner => _owner;
@@ -38,11 +38,11 @@ namespace SepCore.HPBar
StopAllCoroutines(); StopAllCoroutines();
_cachedCanvasGroup.alpha = 1f; _cachedCanvasGroup.alpha = 1f;
if (_owner != owner || m_OwnerId != owner.Id) if (_owner != owner || _ownerId != owner.Id)
{ {
_hPBar.value = fromHPRatio; _hpBar.value = fromHPRatio;
_owner = owner; _owner = owner;
m_OwnerId = owner.Id; _ownerId = owner.Id;
} }
Refresh(); Refresh();
@@ -57,7 +57,7 @@ namespace SepCore.HPBar
return false; return false;
} }
if (_owner != null && Owner.Available && Owner.Id == m_OwnerId) if (_owner != null && Owner.Available && Owner.Id == _ownerId)
{ {
Vector3 worldPosition = _owner.CachedTransform.position + Vector3.forward; Vector3 worldPosition = _owner.CachedTransform.position + Vector3.forward;
Vector3 screenPosition = GameEntry.Scene.MainCamera.WorldToScreenPoint(worldPosition); Vector3 screenPosition = GameEntry.Scene.MainCamera.WorldToScreenPoint(worldPosition);
@@ -78,7 +78,7 @@ namespace SepCore.HPBar
{ {
StopAllCoroutines(); StopAllCoroutines();
_cachedCanvasGroup.alpha = 1f; _cachedCanvasGroup.alpha = 1f;
_hPBar.value = 1f; _hpBar.value = 1f;
_owner = null; _owner = null;
gameObject.SetActive(false); gameObject.SetActive(false);
} }
@@ -86,23 +86,12 @@ namespace SepCore.HPBar
private void Awake() private void Awake()
{ {
_cachedTransform = GetComponent<RectTransform>(); _cachedTransform = GetComponent<RectTransform>();
if (_cachedTransform == null)
{
Log.Error("RectTransform is invalid.");
return;
}
_cachedCanvasGroup = GetComponent<CanvasGroup>(); _cachedCanvasGroup = GetComponent<CanvasGroup>();
if (_cachedCanvasGroup == null)
{
Log.Error("CanvasGroup is invalid.");
return;
}
} }
private IEnumerator HPBarCo(float value, float animationDuration, float keepDuration, float fadeOutDuration) private IEnumerator HPBarCo(float value, float animationDuration, float keepDuration, float fadeOutDuration)
{ {
yield return _hPBar.SmoothValue(value, animationDuration); yield return _hpBar.SmoothValue(value, animationDuration);
yield return new WaitForSeconds(keepDuration); yield return new WaitForSeconds(keepDuration);
yield return _cachedCanvasGroup.FadeToAlpha(0f, fadeOutDuration); yield return _cachedCanvasGroup.FadeToAlpha(0f, fadeOutDuration);
} }
@@ -114,7 +114,7 @@ namespace SepCore.UIRouter
private void RegisterSerializedBindings() private void RegisterSerializedBindings()
{ {
if (_controllerBindings == null || _controllerBindings.Count == 0) if (_controllerBindings.Count == 0)
{ {
return; return;
} }
@@ -122,28 +122,36 @@ namespace SepCore.UIRouter
HashSet<UIFormType> seen = new(); HashSet<UIFormType> seen = new();
foreach (ControllerBinding binding in _controllerBindings) foreach (ControllerBinding binding in _controllerBindings)
{ {
if (binding == null || binding.UIFormType == UIFormType.Undefined || bool hasFormType = binding.UIFormType != UIFormType.Undefined;
string.IsNullOrWhiteSpace(binding.ControllerTypeName)) bool hasControllerTypeName = !string.IsNullOrWhiteSpace(binding.ControllerTypeName);
if (!hasFormType && !hasControllerTypeName)
{ {
continue; continue;
} }
if (!hasFormType || !hasControllerTypeName)
{
Log.Error("UIRouter binding is incomplete: UIFormType '{0}', controller type name '{1}'.",
binding.UIFormType.ToString(), binding.ControllerTypeName);
continue;
}
if (!seen.Add(binding.UIFormType)) if (!seen.Add(binding.UIFormType))
{ {
Log.Warning("UIRouter duplicate binding for '{0}', later one overrides earlier one.", Log.Error("UIRouter duplicate binding for '{0}', later one overrides earlier one.",
binding.UIFormType.ToString()); binding.UIFormType.ToString());
} }
Type controllerType = Type.GetType(binding.ControllerTypeName); Type controllerType = Type.GetType(binding.ControllerTypeName);
if (controllerType == null) if (controllerType == null)
{ {
Log.Warning("UIRouter binding type not found: {0}", binding.ControllerTypeName); Log.Error("UIRouter binding type not found: {0}", binding.ControllerTypeName);
continue; continue;
} }
if (!typeof(IUIController).IsAssignableFrom(controllerType)) if (!typeof(IUIController).IsAssignableFrom(controllerType))
{ {
Log.Warning("UIRouter binding type '{0}' does not implement IUIFormController.", Log.Error("UIRouter binding type '{0}' does not implement IUIController.",
binding.ControllerTypeName); binding.ControllerTypeName);
continue; continue;
} }
@@ -77,12 +77,9 @@ public abstract class EnemyBase : TargetableObject
CachedTransform.localScale = Vector3.one * Mathf.Max(0.1f, data.Scale); CachedTransform.localScale = Vector3.one * Mathf.Max(0.1f, data.Scale);
var renderer = GetComponentInChildren<Renderer>(); var renderer = GetComponentInChildren<Renderer>();
if (renderer != null) var block = new MaterialPropertyBlock();
{ block.SetColor("_BaseColor", data.Color);
var block = new MaterialPropertyBlock(); renderer.SetPropertyBlock(block);
block.SetColor("_BaseColor", data.Color);
renderer.SetPropertyBlock(block);
}
} }
} }
@@ -27,7 +27,7 @@ namespace SepCore.CustomUtility
WeaponType.Axe => new WeaponSlashData(entityId, config, ownerId, ownerCamp), WeaponType.Axe => new WeaponSlashData(entityId, config, ownerId, ownerCamp),
WeaponType.Lightning => new WeaponLightningData(entityId, config, ownerId, ownerCamp), WeaponType.Lightning => new WeaponLightningData(entityId, config, ownerId, ownerCamp),
WeaponType.Lance => new WeaponLanceData(entityId, config, ownerId, ownerCamp), WeaponType.Lance => new WeaponLanceData(entityId, config, ownerId, ownerCamp),
_ => throw new NotImplementedException() _ => throw new NotImplementedException($"Unsupported weapon type '{weaponType}'.")
}; };
} }
+5 -436
View File
@@ -338,30 +338,6 @@ MonoBehaviour:
m_PointerBehavior: 0 m_PointerBehavior: 0
m_CursorLockBehavior: 0 m_CursorLockBehavior: 0
m_ScrollDeltaPerTick: 6 m_ScrollDeltaPerTick: 6
--- !u!114 &142428270 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 6269556444878685483, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 2efdcd06cdaa830448f76b22ea7c98fb, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &142428271 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 400612800417406683, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1001 &343730742 --- !u!1001 &343730742
PrefabInstance: PrefabInstance:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -841,30 +817,6 @@ MonoBehaviour:
_showPlayerWeaponControls: 1 _showPlayerWeaponControls: 1
_showPlayerHealthControls: 1 _showPlayerHealthControls: 1
_showTips: 0 _showTips: 0
--- !u!114 &491542084 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 6053195524865570449, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a5079836f95c2a44b96fa331487ebb70, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &491542086 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 227536339921118688, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &513208572 --- !u!1 &513208572
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -960,9 +912,10 @@ MonoBehaviour:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_instancePoolCapacity: 256 _instancePoolCapacity: 256
_poolName: DamageTextItem _poolName: DamageTextItem
_instanceRoot: {fileID: 0} _instanceRoot: {fileID: 31248797}
_canvas: {fileID: 0} _canvas: {fileID: 31248799}
_damageTextItemPrefab: {fileID: 0} _damageTextItemPrefab: {fileID: 8729657611800212236, guid: 308577c72eb4cd14ca676aeee62b0ea5,
type: 3}
--- !u!1 &553656361 --- !u!1 &553656361
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -993,8 +946,7 @@ RectTransform:
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0} m_LocalScale: {x: 0, y: 0, z: 0}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: m_Children: []
- {fileID: 1280276267}
m_Father: {fileID: 432952642} m_Father: {fileID: 432952642}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
@@ -1065,54 +1017,6 @@ Canvas:
m_SortingLayerID: 0 m_SortingLayerID: 0
m_SortingOrder: 0 m_SortingOrder: 0
m_TargetDisplay: 0 m_TargetDisplay: 0
--- !u!114 &640014055 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 103163210424128144, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &640014059 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 8559108892240801629, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &652305783 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 6102478747521363808, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &652305787 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 3868237545351061730, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!850595691 &819759088 --- !u!850595691 &819759088
LightingSettings: LightingSettings:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1223,8 +1127,6 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_cinemachineController: {fileID: 2103467908} _cinemachineController: {fileID: 2103467908}
_autoSearchController: 0
_logMissingControllerWarnings: 1
--- !u!1 &1245211030 --- !u!1 &1245211030
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1275,337 +1177,6 @@ MonoBehaviour:
_loadBindingOverridesOnInit: 1 _loadBindingOverridesOnInit: 1
_saveBindingOverridesOnDestroy: 0 _saveBindingOverridesOnDestroy: 0
_bindingOverrideSettingKey: SepCore.InputModule.BindingOverrides _bindingOverrideSettingKey: SepCore.InputModule.BindingOverrides
--- !u!114 &1258981242 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 7330401870143477410, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: f4688fdb7df04437aeb418b961361dc5, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1258981246 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 249520213934040151, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1001 &1280276266
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 553656362}
m_Modifications:
- target: {fileID: 395929355422612576, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_Name
value: ItemTooltipForm
objectReference: {fileID: 0}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.size
value: 8
objectReference: {fileID: 0}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.data[0]
value:
objectReference: {fileID: 1280276276}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.data[1]
value:
objectReference: {fileID: 1280276273}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.data[2]
value:
objectReference: {fileID: 640014059}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.data[3]
value:
objectReference: {fileID: 1258981246}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.data[4]
value:
objectReference: {fileID: 652305787}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.data[5]
value:
objectReference: {fileID: 1352570666}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.data[6]
value:
objectReference: {fileID: 142428271}
- target: {fileID: 2236042990348165862, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: serializationItems.Array.data[7]
value:
objectReference: {fileID: 491542086}
- target: {fileID: 4303509830935515119, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: _view
value:
objectReference: {fileID: 1280276275}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_Pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_Pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_AnchorMax.x
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalRotation.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalRotation.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents:
- targetCorrespondingSourceObject: {fileID: 395929355422612576, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
insertIndex: -1
addedObject: {fileID: 1280276275}
- targetCorrespondingSourceObject: {fileID: 625540161254782982, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
insertIndex: -1
addedObject: {fileID: 1280276276}
m_SourcePrefab: {fileID: 100100000, guid: 20e5dc75d1c3fe74bb841127a036d69d, type: 3}
--- !u!224 &1280276267 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 6368625289863409235, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1280276268 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 7488000213460330546, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 578fa91d15f54e74a95ccce338d0a772, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!224 &1280276269 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 7543853000780573685, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
--- !u!1 &1280276270 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 625540161254782982, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1280276271 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 1280310065211852598, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1280276270}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &1280276272 stripped
GameObject:
m_CorrespondingSourceObject: {fileID: 395929355422612576, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1280276273 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 8926258706962002499, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!222 &1280276274 stripped
CanvasRenderer:
m_CorrespondingSourceObject: {fileID: 3996340794476105959, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
--- !u!114 &1280276275
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1280276272}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4d9524b70efb9c840a84baed8b0c12d0, type: 3}
m_Name:
m_EditorClassIdentifier:
iconArea: {fileID: 1280276268}
titleText: {fileID: 640014055}
typeText: {fileID: 1258981242}
infoText: {fileID: 652305783}
recycleButton: {fileID: 1352570662}
textFormatText: {fileID: 142428270}
cancelButton: {fileID: 491542084}
--- !u!114 &1280276276
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 1280276270}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
componentReferences:
- component: {fileID: 1280276269}
generateReference: 1
variableName: contentRectTransform
- component: {fileID: 1280276274}
generateReference: 0
variableName: contentCanvasRenderer
- component: {fileID: 1280276271}
generateReference: 0
variableName: contentImage
--- !u!114 &1352570662 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 7966632555814587605, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: a5079836f95c2a44b96fa331487ebb70, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &1352570666 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 5617935853479120081, guid: 20e5dc75d1c3fe74bb841127a036d69d,
type: 3}
m_PrefabInstance: {fileID: 1280276266}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: fbaa237e23f7d4d3f85f73e0acd7eaec, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1 &1454214586 --- !u!1 &1454214586
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -1984,8 +1555,6 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 8d840df1b53db744cb522b82426f2cd5, type: 3} m_Script: {fileID: 11500000, guid: 8d840df1b53db744cb522b82426f2cd5, type: 3}
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
_spawnEnemyMaxCount: 5000
_spawnDistanceFromPlayer: 20
--- !u!1 &2050832066 --- !u!1 &2050832066
GameObject: GameObject:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -30,7 +30,6 @@ namespace SepCore.InputModule.Runtime
private SettingComponent _settingComponent = null; private SettingComponent _settingComponent = null;
private bool _isInitialized = false; private bool _isInitialized = false;
private bool _onInitCalled = false; private bool _onInitCalled = false;
private bool _ownsRuntimeActions = false;
private InputActionRebindingExtensions.RebindingOperation _activeRebindOperation; private InputActionRebindingExtensions.RebindingOperation _activeRebindOperation;
private bool _rebindCanceledByUser; private bool _rebindCanceledByUser;
private IInputPromptMap _promptMap; private IInputPromptMap _promptMap;
@@ -75,11 +74,6 @@ namespace SepCore.InputModule.Runtime
} }
} }
protected override void Awake()
{
base.Awake();
}
private void OnEnable() private void OnEnable()
{ {
if (_isInitialized) if (_isInitialized)
@@ -112,29 +106,21 @@ namespace SepCore.InputModule.Runtime
UnsubscribeFromGlobalDeviceTracking(); UnsubscribeFromGlobalDeviceTracking();
UnsubscribeFromActions(); UnsubscribeFromActions();
if (_ownsRuntimeActions && _runtimeActions != null) if (Application.isPlaying)
{ {
if (Application.isPlaying) Destroy(_runtimeActions);
{ }
Destroy(_runtimeActions); else
} {
else DestroyImmediate(_runtimeActions);
{
DestroyImmediate(_runtimeActions);
}
} }
_runtimeActions = null;
_actionMaps.Clear();
_listeners.Clear();
_isInitialized = false;
_onInitCalled = false;
} }
public void RegisterListener(InputActionId actionId, Action<InputCommand> listener) public void RegisterListener(InputActionId actionId, Action<InputCommand> listener)
{ {
if (listener == null) if (listener == null)
{ {
Log.Error("InputModuleComponent.RegisterListener() listener is invalid.");
return; return;
} }
@@ -160,7 +146,7 @@ namespace SepCore.InputModule.Runtime
if (_listeners.TryGetValue(command.ActionId, out Action<InputCommand> listener)) if (_listeners.TryGetValue(command.ActionId, out Action<InputCommand> listener))
{ {
listener?.Invoke(command); listener.Invoke(command);
} }
} }
@@ -343,11 +329,14 @@ namespace SepCore.InputModule.Runtime
EnsureInitialized(); EnsureInitialized();
if (!TryGetAction(contextId, actionId, out InputAction action)) if (!TryGetAction(contextId, actionId, out InputAction action))
{ {
Log.Error("InputModuleComponent.ResetBindingToDefault() action '{0}' is not found in context '{1}'.",
actionId, contextId);
return; return;
} }
if (bindingIndex < 0 || bindingIndex >= action.bindings.Count) if (bindingIndex < 0 || bindingIndex >= action.bindings.Count)
{ {
Log.Error("InputModuleComponent.ResetBindingToDefault() binding index '{0}' is invalid.", bindingIndex);
return; return;
} }
@@ -364,6 +353,8 @@ namespace SepCore.InputModule.Runtime
EnsureInitialized(); EnsureInitialized();
if (!TryGetAction(contextId, actionId, out InputAction action)) if (!TryGetAction(contextId, actionId, out InputAction action))
{ {
Log.Error("InputModuleComponent.ResetActionToDefaults() action '{0}' is not found in context '{1}'.",
actionId, contextId);
return; return;
} }
@@ -392,11 +383,7 @@ namespace SepCore.InputModule.Runtime
string overridesJson = _runtimeActions.SaveBindingOverridesAsJson(); string overridesJson = _runtimeActions.SaveBindingOverridesAsJson();
string storedData = BindingOverridePersistence.Serialize(overridesJson); string storedData = BindingOverridePersistence.Serialize(overridesJson);
SettingComponent settingComponent = GetSettingComponent(); GetSettingComponent().SetString(_bindingOverrideSettingKey, storedData);
if (settingComponent != null)
{
settingComponent.SetString(_bindingOverrideSettingKey, storedData);
}
return new InputBindingSnapshot(overridesJson); return new InputBindingSnapshot(overridesJson);
} }
@@ -409,13 +396,8 @@ namespace SepCore.InputModule.Runtime
private void LoadBindingOverridesCore() private void LoadBindingOverridesCore()
{ {
if (_runtimeActions == null)
{
return;
}
SettingComponent settingComponent = GetSettingComponent(); SettingComponent settingComponent = GetSettingComponent();
if (settingComponent == null || !settingComponent.HasSetting(_bindingOverrideSettingKey)) if (!settingComponent.HasSetting(_bindingOverrideSettingKey))
{ {
return; return;
} }
@@ -423,6 +405,7 @@ namespace SepCore.InputModule.Runtime
string storedData = settingComponent.GetString(_bindingOverrideSettingKey); string storedData = settingComponent.GetString(_bindingOverrideSettingKey);
if (!BindingOverridePersistence.TryDeserialize(storedData, out string overridesJson)) if (!BindingOverridePersistence.TryDeserialize(storedData, out string overridesJson))
{ {
Log.Error("InputModuleComponent failed to deserialize stored binding overrides.");
return; return;
} }
@@ -455,7 +438,6 @@ namespace SepCore.InputModule.Runtime
_runtimeActions = _inputActionsAsset != null _runtimeActions = _inputActionsAsset != null
? Instantiate(_inputActionsAsset) ? Instantiate(_inputActionsAsset)
: InputModuleDefaultActions.Create(); : InputModuleDefaultActions.Create();
_ownsRuntimeActions = true;
CacheActionMaps(); CacheActionMaps();
SubscribeToActions(); SubscribeToActions();
@@ -470,7 +452,7 @@ namespace SepCore.InputModule.Runtime
int mapCount = _actionMaps.Count; int mapCount = _actionMaps.Count;
if (mapCount == 0) if (mapCount == 0)
{ {
Log.Warning("[InputModule] Initialized but no action maps were cached. Check that action map names match InputContextId enum values."); Log.Error("[InputModule] Initialized but no action maps were cached. Check that action map names match InputContextId enum values.");
} }
else else
{ {
@@ -504,7 +486,7 @@ namespace SepCore.InputModule.Runtime
} }
else else
{ {
Log.Warning("[InputModule] ActionMap '{0}' does not match any InputContextId and will be ignored.", map.name); Log.Error("[InputModule] ActionMap '{0}' does not match any InputContextId and will be ignored.", map.name);
} }
} }
} }
@@ -521,11 +503,6 @@ namespace SepCore.InputModule.Runtime
private void UnsubscribeFromActions() private void UnsubscribeFromActions()
{ {
if (_runtimeActions == null)
{
return;
}
foreach (InputAction action in _runtimeActions) foreach (InputAction action in _runtimeActions)
{ {
action.started -= OnActionTriggered; action.started -= OnActionTriggered;
@@ -559,11 +536,6 @@ namespace SepCore.InputModule.Runtime
// context is active at any time, preventing overlapping bindings from stacked maps. // context is active at any time, preventing overlapping bindings from stacked maps.
private void ApplyContextState() private void ApplyContextState()
{ {
if (_runtimeActions == null)
{
return;
}
_runtimeActions.Disable(); _runtimeActions.Disable();
if (_actionMaps.TryGetValue(InputContextId.Global, out InputActionMap globalMap)) if (_actionMaps.TryGetValue(InputContextId.Global, out InputActionMap globalMap))
@@ -600,7 +572,7 @@ namespace SepCore.InputModule.Runtime
if (_listeners.TryGetValue(actionId, out Action<InputCommand> listener)) if (_listeners.TryGetValue(actionId, out Action<InputCommand> listener))
{ {
listener?.Invoke(command); listener.Invoke(command);
} }
} }
@@ -725,7 +697,7 @@ namespace SepCore.InputModule.Runtime
continue; continue;
} }
if (string.Equals(binding.effectivePath, newPath, System.StringComparison.OrdinalIgnoreCase)) if (string.Equals(binding.effectivePath, newPath, StringComparison.OrdinalIgnoreCase))
{ {
return true; return true;
} }
@@ -16,7 +16,7 @@ namespace SepCore.InputModule.Tests
public void SetUp() public void SetUp()
{ {
_gameObject = new GameObject("InputModuleTest"); _gameObject = new GameObject("InputModuleTest");
_component = _gameObject.AddComponent<InputModuleComponent>(); _component = InputModuleTestFactory.CreateComponent(_gameObject);
} }
[TearDown] [TearDown]
@@ -17,7 +17,7 @@ namespace SepCore.InputModule.Tests
public void SetUp() public void SetUp()
{ {
_gameObject = new GameObject("InputModuleEventTest"); _gameObject = new GameObject("InputModuleEventTest");
_component = _gameObject.AddComponent<InputModuleComponent>(); _component = InputModuleTestFactory.CreateComponent(_gameObject);
_component.OnInit(); _component.OnInit();
} }
@@ -185,6 +185,9 @@ namespace SepCore.InputModule.Tests
public void RegisterListener_NullCallback_DoesNotThrow() public void RegisterListener_NullCallback_DoesNotThrow()
{ {
Assert.DoesNotThrow(() => _component.RegisterListener(InputActionId.Pause, null)); Assert.DoesNotThrow(() => _component.RegisterListener(InputActionId.Pause, null));
Dictionary<InputActionId, Action<InputCommand>> listeners = GetPrivateListenersDictionary();
Assert.That(listeners.ContainsKey(InputActionId.Pause), Is.False);
} }
[Test] [Test]
@@ -17,7 +17,7 @@ namespace SepCore.InputModule.Tests
{ {
base.Setup(); base.Setup();
_gameObject = new GameObject("InputModuleRebindTest"); _gameObject = new GameObject("InputModuleRebindTest");
_component = _gameObject.AddComponent<InputModuleComponent>(); _component = InputModuleTestFactory.CreateComponent(_gameObject);
_component.OnInit(); _component.OnInit();
} }
@@ -202,7 +202,8 @@ namespace SepCore.InputModule.Tests
InputAction confirmAction = _component.RuntimeActions.FindAction($"{nameof(InputContextId.UI)}/{nameof(InputActionId.Confirm)}"); InputAction confirmAction = _component.RuntimeActions.FindAction($"{nameof(InputContextId.UI)}/{nameof(InputActionId.Confirm)}");
confirmAction.ApplyBindingOverride(0, "<Keyboard>/space"); confirmAction.ApplyBindingOverride(0, "<Keyboard>/space");
InputBindingSnapshot snapshot = _component.SaveBindingOverrides(); string overridesJson = _component.RuntimeActions.SaveBindingOverridesAsJson();
InputBindingSnapshot snapshot = new InputBindingSnapshot(overridesJson);
_component.ResetAllBindingsToDefaults(); _component.ResetAllBindingsToDefaults();
Assert.That(confirmAction.bindings[0].overridePath, Is.Null); Assert.That(confirmAction.bindings[0].overridePath, Is.Null);
@@ -17,7 +17,7 @@ namespace SepCore.InputModule.Tests
public void SetUp() public void SetUp()
{ {
_gameObject = new GameObject("InputModuleDebuggerReflectionTest"); _gameObject = new GameObject("InputModuleDebuggerReflectionTest");
_component = _gameObject.AddComponent<InputModuleComponent>(); _component = InputModuleTestFactory.CreateComponent(_gameObject);
} }
[TearDown] [TearDown]
@@ -0,0 +1,18 @@
using System.Reflection;
using SepCore.InputModule.Runtime;
using UnityEngine;
namespace SepCore.InputModule.Tests
{
internal static class InputModuleTestFactory
{
public static InputModuleComponent CreateComponent(GameObject gameObject)
{
InputModuleComponent component = gameObject.AddComponent<InputModuleComponent>();
typeof(InputModuleComponent)
.GetField("_loadBindingOverridesOnInit", BindingFlags.Instance | BindingFlags.NonPublic)
.SetValue(component, false);
return component;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1e4066e709bd03646a983938f9b9b525
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -57,6 +57,7 @@ namespace SepCore.Timer
if (timerTask.RepeatCount == 0) if (timerTask.RepeatCount == 0)
{ {
Log.Error("Timer task repeat count is zero.");
return TimerHandle.Invalid; return TimerHandle.Invalid;
} }
@@ -139,6 +140,7 @@ namespace SepCore.Timer
{ {
if (owner == null) if (owner == null)
{ {
Log.Error("Timer task owner is invalid.");
return 0; return 0;
} }
@@ -248,6 +250,12 @@ namespace SepCore.Timer
} }
float safeInterval = Mathf.Max(0f, newInterval); float safeInterval = Mathf.Max(0f, newInterval);
if (taskInfo.IsRepeating && safeInterval <= 0f)
{
Log.Error("Timer task interval must be greater than zero for repeated tasks.");
return false;
}
if (adjustRemainingTime && taskInfo.Interval > 0f && safeInterval > 0f) if (adjustRemainingTime && taskInfo.Interval > 0f && safeInterval > 0f)
{ {
float ratio = safeInterval / taskInfo.Interval; float ratio = safeInterval / taskInfo.Interval;
@@ -443,11 +451,6 @@ namespace SepCore.Timer
_isUpdating = true; _isUpdating = true;
for (int i = taskCount - 1; i >= 0; i--) for (int i = taskCount - 1; i >= 0; i--)
{ {
if (i >= _timerTasks.Count)
{
continue;
}
TimerTaskInfo taskInfo = _timerTasks[i]; TimerTaskInfo taskInfo = _timerTasks[i];
if (taskInfo.IsCancelled || taskInfo.IsPaused) if (taskInfo.IsCancelled || taskInfo.IsPaused)
{ {
@@ -539,6 +542,7 @@ namespace SepCore.Timer
RemainingTime = delay; RemainingTime = delay;
Interval = interval; Interval = interval;
RemainingRepeatCount = repeatCount; RemainingRepeatCount = repeatCount;
IsRepeating = repeatCount != 1;
TimeMode = timeMode; TimeMode = timeMode;
Owner = owner; Owner = owner;
Callback = callback; Callback = callback;
@@ -569,6 +573,11 @@ namespace SepCore.Timer
set; set;
} }
public bool IsRepeating
{
get;
}
public TimerTimeMode TimeMode public TimerTimeMode TimeMode
{ {
get; get;
Binary file not shown.