maint: added livewatch asset
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fe50439153774769a917b9ef7c3444ed
|
||||
timeCreated: 1726052848
|
||||
@@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class EconomyConfig : ScriptableObject
|
||||
{
|
||||
public Dictionary<MobType, int> MobKillRewards
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_mobRewardsDict != null)
|
||||
return _mobRewardsDict;
|
||||
|
||||
_mobRewardsDict = new Dictionary<MobType, int>();
|
||||
foreach (var mobKillReward in _mobKillRewards)
|
||||
{
|
||||
_mobRewardsDict.Add(mobKillReward.Type, mobKillReward.GoldReward);
|
||||
}
|
||||
|
||||
return _mobRewardsDict;
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<TowerType, int> TowerBuildCosts
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_towerCostsDict != null)
|
||||
return _towerCostsDict;
|
||||
|
||||
_towerCostsDict = new Dictionary<TowerType, int>();
|
||||
foreach (var towerBuildCost in _towerCosts)
|
||||
{
|
||||
_towerCostsDict.Add(towerBuildCost.Type, towerBuildCost.GoldCost);
|
||||
}
|
||||
|
||||
return _towerCostsDict;
|
||||
}
|
||||
}
|
||||
|
||||
public Dictionary<TowerType, int> TowerSellPrices
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_towerSellPricesDict != null)
|
||||
return _towerSellPricesDict;
|
||||
|
||||
_towerSellPricesDict = new Dictionary<TowerType, int>();
|
||||
foreach (var towerBuildCost in _towerCosts)
|
||||
{
|
||||
_towerSellPricesDict.Add(towerBuildCost.Type, towerBuildCost.GoldSellPrice);
|
||||
}
|
||||
|
||||
return _towerSellPricesDict;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private MobRewardSetup[] _mobKillRewards;
|
||||
[SerializeField] private TowerCostSetup[] _towerCosts;
|
||||
|
||||
private Dictionary<MobType, int> _mobRewardsDict;
|
||||
private Dictionary<TowerType, int> _towerCostsDict;
|
||||
private Dictionary<TowerType, int> _towerSellPricesDict;
|
||||
|
||||
[Serializable]
|
||||
private class MobRewardSetup
|
||||
{
|
||||
public MobType Type;
|
||||
public int GoldReward;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class TowerCostSetup
|
||||
{
|
||||
public TowerType Type;
|
||||
public int GoldCost;
|
||||
public int GoldSellPrice;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 555126785c4f49a58db7735195a9ca5c
|
||||
timeCreated: 1726052861
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Configs/EconomyConfig.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class LevelConfig : ScriptableObject
|
||||
{
|
||||
public int MaxHealth = 20;
|
||||
public int StartGold = 100;
|
||||
public List<MobWave> Waves = new();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MobWave
|
||||
{
|
||||
public List<MobSpawn> Spawns = new();
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class MobSpawn
|
||||
{
|
||||
public float Delay;
|
||||
public int MobCount;
|
||||
public MobMain MobPrefab;
|
||||
public float SpawnDelayBetween = 0.1f;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5acaf173387b48bba941b9b4d523a82e
|
||||
timeCreated: 1725791173
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Configs/LevelConfig.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class EnergyManager : MonoBehaviour
|
||||
{
|
||||
public event Action EnergyChanged;
|
||||
|
||||
public int CurrentEnergy
|
||||
{
|
||||
get => _energy;
|
||||
set
|
||||
{
|
||||
if (_energy == value)
|
||||
return;
|
||||
|
||||
_energy = value;
|
||||
EnergyChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private int _energy;
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Watch.GetOrAdd("Energy", () => CurrentEnergy)
|
||||
.SetSortOrder(TD_WatchSortOrder.Energy);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_levelScene.MobManager.MobDiedByHp += OnMobDiedByHp;
|
||||
}
|
||||
|
||||
public void ResetEnergy()
|
||||
{
|
||||
CurrentEnergy = _levelScene.LevelConfig.StartGold;
|
||||
}
|
||||
|
||||
private void OnMobDiedByHp(MobMain mob)
|
||||
{
|
||||
var reward = _levelScene.EconomyConfig.MobKillRewards[mob.Type];
|
||||
CurrentEnergy += reward;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 356869e3279748738aee19e4491c4c56
|
||||
timeCreated: 1725817574
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/EnergyManager.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class GameSpeedManager : MonoBehaviour
|
||||
{
|
||||
public event Action SpeedChanged;
|
||||
|
||||
public SpeedMode CurrentSpeed
|
||||
{
|
||||
get => _currentSpeed;
|
||||
protected set
|
||||
{
|
||||
if (_currentSpeed == value)
|
||||
return;
|
||||
|
||||
_currentSpeed = value;
|
||||
SpeedChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private SpeedMode _currentSpeed;
|
||||
|
||||
public void SetDefaultSpeed()
|
||||
{
|
||||
SetGameSpeed(SpeedMode.x1);
|
||||
}
|
||||
|
||||
public void SetGameSpeed(SpeedMode mode)
|
||||
{
|
||||
Time.timeScale = mode switch
|
||||
{
|
||||
SpeedMode.x1 => 1,
|
||||
SpeedMode.x2 => 2,
|
||||
SpeedMode.x4 => 4,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(mode), mode, null)
|
||||
};
|
||||
|
||||
CurrentSpeed = mode;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SpeedMode
|
||||
{
|
||||
x1,
|
||||
x2,
|
||||
x4
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 808c7e6ae676460ebcff47f63cd0863a
|
||||
timeCreated: 1726311529
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/GameSpeedManager.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class HealthManager : MonoBehaviour
|
||||
{
|
||||
public event Action HealthChanged;
|
||||
|
||||
public int CurrentHealth
|
||||
{
|
||||
get => _health;
|
||||
set
|
||||
{
|
||||
if (_health == value)
|
||||
return;
|
||||
|
||||
_health = value;
|
||||
HealthChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
public int MaxHealth => _levelScene.LevelConfig.MaxHealth;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
private int _health;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Watch.GetOrAdd("Health", () => CurrentHealth)
|
||||
.SetSortOrder(TD_WatchSortOrder.Health);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_levelScene.MobManager.MobReachedFinish += OnMobReachedFinish;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_levelScene.MobManager.MobReachedFinish -= OnMobReachedFinish;
|
||||
}
|
||||
|
||||
public void ResetHealth()
|
||||
{
|
||||
CurrentHealth = MaxHealth;
|
||||
}
|
||||
|
||||
private void OnMobReachedFinish(MobMain mob)
|
||||
{
|
||||
CurrentHealth = Mathf.Clamp(CurrentHealth - 1, 0, MaxHealth);
|
||||
HealthChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00c9be1057164002990d550ddbe0bb6d
|
||||
timeCreated: 1725811243
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/HealthManager.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,33 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class LevelInitialTowerSpawner : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private List<TowerSpawnSetup> _towers;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
public void SpawnAllTowers()
|
||||
{
|
||||
foreach (var towerSpawn in _towers)
|
||||
{
|
||||
_levelScene.TowerBuildManager.BuildTower(towerSpawn.Slot, towerSpawn.Type, false);
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class TowerSpawnSetup
|
||||
{
|
||||
public TowerBuildSlot Slot;
|
||||
public TowerType Type;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e02acdc164ea4da29f2d7515d985ef07
|
||||
timeCreated: 1726310399
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/LevelInitialTowerSpawner.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class LevelScene : MonoBehaviour
|
||||
{
|
||||
public PoolManager PoolManager;
|
||||
public GameSpeedManager SpeedManager;
|
||||
public MobManager MobManager;
|
||||
public HealthManager HealthManager;
|
||||
public WaveManager WaveManager;
|
||||
public EnergyManager EnergyManager;
|
||||
public TowerManager TowerManager;
|
||||
public TowerBuildManager TowerBuildManager;
|
||||
public LevelInitialTowerSpawner InitialTowerSpawner;
|
||||
public LevelStateManager LevelStateManager;
|
||||
|
||||
public LevelConfig LevelConfig;
|
||||
public EconomyConfig EconomyConfig;
|
||||
public MobTriggerZone FinishTriggerZone;
|
||||
public List<Transform> Waypoints;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae3bf07677c6d72439b069ddc0da2380
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/LevelScene.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,112 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class LevelStateManager : MonoBehaviour
|
||||
{
|
||||
public event Action StateChanged;
|
||||
|
||||
public LevelStateType CurrentState
|
||||
{
|
||||
get => _currentState;
|
||||
set
|
||||
{
|
||||
if (_currentState == value)
|
||||
return;
|
||||
|
||||
_currentState = value;
|
||||
StateChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private LevelStateType _currentState;
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private Dictionary<LevelStateType, string> _stateNamesCache = new();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
StartLevel();
|
||||
|
||||
// Cache is needed to avoid GC from .ToString() every frame
|
||||
foreach (var stateEnum in Enum.GetValues(typeof(LevelStateType)))
|
||||
_stateNamesCache.Add((LevelStateType)stateEnum, stateEnum.ToString());
|
||||
|
||||
Watch.GetOrAdd("State", () => _stateNamesCache[CurrentState])
|
||||
.SetSortOrder(TD_WatchSortOrder.State);
|
||||
}
|
||||
|
||||
public void StartLevel()
|
||||
{
|
||||
if (CurrentState == LevelStateType.Playing)
|
||||
return;
|
||||
|
||||
CurrentState = LevelStateType.Waiting;
|
||||
|
||||
_levelScene.SpeedManager.SetDefaultSpeed();
|
||||
_levelScene.HealthManager.ResetHealth();
|
||||
_levelScene.EnergyManager.ResetEnergy();
|
||||
_levelScene.WaveManager.ResetWaves();
|
||||
_levelScene.TowerBuildManager.DestroyAllTowers();
|
||||
_levelScene.InitialTowerSpawner.SpawnAllTowers();
|
||||
|
||||
_levelScene.HealthManager.HealthChanged += OnHealthChanged;
|
||||
_levelScene.WaveManager.WaveStarted += OnWaveStarted;
|
||||
_levelScene.WaveManager.WaveFinished += OnWaveFinished;
|
||||
}
|
||||
|
||||
public void FinishLevel(bool isWin)
|
||||
{
|
||||
if (CurrentState is LevelStateType.Win or LevelStateType.Lose)
|
||||
return;
|
||||
|
||||
CurrentState = isWin ? LevelStateType.Win : LevelStateType.Lose;
|
||||
|
||||
_levelScene.TowerManager.DisableTowers();
|
||||
_levelScene.MobManager.DespawnMobsAll();
|
||||
_levelScene.WaveManager.FinishWave();
|
||||
|
||||
_levelScene.HealthManager.HealthChanged -= OnHealthChanged;
|
||||
_levelScene.WaveManager.WaveStarted -= OnWaveStarted;
|
||||
_levelScene.WaveManager.WaveFinished -= OnWaveFinished;
|
||||
}
|
||||
|
||||
private void OnHealthChanged()
|
||||
{
|
||||
if (_levelScene.HealthManager.CurrentHealth > 0)
|
||||
return;
|
||||
|
||||
FinishLevel(false);
|
||||
}
|
||||
|
||||
private void OnWaveStarted()
|
||||
{
|
||||
CurrentState = LevelStateType.Playing;
|
||||
|
||||
_levelScene.TowerManager.EnabledTowers();
|
||||
}
|
||||
|
||||
private void OnWaveFinished()
|
||||
{
|
||||
_levelScene.TowerManager.DisableTowers();
|
||||
_levelScene.MobManager.DespawnMobsAll();
|
||||
|
||||
if (_levelScene.WaveManager.CurrentWave >= _levelScene.WaveManager.MaxWave)
|
||||
{
|
||||
FinishLevel(true);
|
||||
return;
|
||||
}
|
||||
|
||||
_levelScene.WaveManager.SetNextWave();
|
||||
CurrentState = LevelStateType.Waiting;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6509b3e884d74eb698c4c2f82bc401cd
|
||||
timeCreated: 1725799543
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/LevelStateManager.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public enum LevelStateType
|
||||
{
|
||||
Waiting,
|
||||
Playing,
|
||||
Win,
|
||||
Lose
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97acdd860a8145bbab35cef358fd42d3
|
||||
timeCreated: 1725818409
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/LevelStateType.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ce3fb6d5e454192ba8f552525ef26b9
|
||||
timeCreated: 1725791017
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class MobHealth : MonoBehaviour
|
||||
{
|
||||
public Action HealthChanged;
|
||||
|
||||
public int CurrentHealth
|
||||
{
|
||||
get => _currentHealth;
|
||||
set
|
||||
{
|
||||
if (_currentHealth == value)
|
||||
return;
|
||||
|
||||
_currentHealth = value;
|
||||
HealthChanged?.Invoke();
|
||||
|
||||
if (_currentHealth <= 0)
|
||||
_deathCallback?.Invoke();
|
||||
}
|
||||
}
|
||||
public int MaxHealth => maxHealth;
|
||||
|
||||
[SerializeField] private int maxHealth;
|
||||
private int _currentHealth;
|
||||
private Action _deathCallback;
|
||||
|
||||
public void ResetHealth()
|
||||
{
|
||||
CurrentHealth = MaxHealth;
|
||||
}
|
||||
|
||||
public void TakeDamage(int damage)
|
||||
{
|
||||
CurrentHealth = Mathf.Clamp(CurrentHealth - damage, 0, MaxHealth);
|
||||
}
|
||||
|
||||
public void SetOnDeath(Action deathCallback)
|
||||
{
|
||||
_deathCallback = deathCallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc0bc970ef50473ab4dd1d71ec6d3213
|
||||
timeCreated: 1725985325
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Mob/MobHealth.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class MobHealthBar : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private MobMain mob;
|
||||
[SerializeField] private Transform bar;
|
||||
|
||||
private Camera _mainCamera;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_mainCamera = Camera.main;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
mob.Health.HealthChanged += RefreshBar;
|
||||
RefreshBar();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
mob.Health.HealthChanged -= RefreshBar;
|
||||
}
|
||||
|
||||
private void LateUpdate()
|
||||
{
|
||||
transform.rotation = _mainCamera.transform.rotation;
|
||||
}
|
||||
|
||||
private void RefreshBar()
|
||||
{
|
||||
var progress = (float)mob.Health.CurrentHealth / mob.Health.MaxHealth;
|
||||
bar.localScale = new Vector3(progress, bar.localScale.y, bar.localScale.z);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c8c4923e295d4d9986ac6214a28db302
|
||||
timeCreated: 1725985707
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Mob/MobHealthBar.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,71 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class MobMain : MonoBehaviour
|
||||
{
|
||||
public string Id { get; private set; }
|
||||
public MobType Type => _type;
|
||||
public bool IsAlive { get; private set; }
|
||||
public int CurrentHealth => Health.CurrentHealth;
|
||||
public float SpawnTime { get; private set; }
|
||||
public MobWaypointMover WaypointMover => _waypointMover;
|
||||
public MobHealth Health => _health;
|
||||
|
||||
[SerializeField] private MobType _type;
|
||||
[SerializeField] private MobWaypointMover _waypointMover;
|
||||
[SerializeField] private MobHealth _health;
|
||||
[SerializeField] private GameObject _deathFxPrefab;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
|
||||
public void Spawn(string id, LevelScene level)
|
||||
{
|
||||
Id = id;
|
||||
IsAlive = true;
|
||||
SpawnTime = Time.time;
|
||||
|
||||
_levelScene = level;
|
||||
_waypointMover.StartMoving(level.Waypoints);
|
||||
_health.ResetHealth();
|
||||
|
||||
var mobWatch = Watch.GetOrAdd<Any>("Mobs").GetOrAdd<Any>(Id);
|
||||
Watch.Push(mobWatch.GetOrAdd<string>("Type"), Type.ToString());
|
||||
mobWatch.GetOrAdd("Health", () => CurrentHealth);
|
||||
}
|
||||
|
||||
public void Despawn(bool showDeathFx = false, float delay = 0f)
|
||||
{
|
||||
if (!IsAlive)
|
||||
return;
|
||||
|
||||
IsAlive = false;
|
||||
_waypointMover.StopMoving();
|
||||
|
||||
StopAllCoroutines();
|
||||
|
||||
if (delay <= 0f)
|
||||
Destroy(showDeathFx);
|
||||
else
|
||||
StartCoroutine(DelayedDestroying(showDeathFx, delay));
|
||||
}
|
||||
|
||||
private IEnumerator DelayedDestroying(bool showDeathFx, float delay)
|
||||
{
|
||||
yield return new WaitForSeconds(delay);
|
||||
Destroy(showDeathFx);
|
||||
}
|
||||
|
||||
private void Destroy(bool showDeathFx)
|
||||
{
|
||||
_levelScene.PoolManager.Push(gameObject);
|
||||
|
||||
if (showDeathFx)
|
||||
{
|
||||
var deathFx = _levelScene.PoolManager.Get(_deathFxPrefab);
|
||||
deathFx.transform.position = transform.position + Vector3.up;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2554fbc067f54ad08dbf5f7be16a1f23
|
||||
timeCreated: 1725791025
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Mob/MobMain.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public enum MobType
|
||||
{
|
||||
Small,
|
||||
Medium,
|
||||
Big
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 132d1aa57e044b64a4962b10d8fa4d65
|
||||
timeCreated: 1726052963
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Mob/MobType.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class MobWaypointMover : MonoBehaviour
|
||||
{
|
||||
public float Speed;
|
||||
public float RotationSpeed = 5f;
|
||||
public float TravelledDist { get; private set; }
|
||||
|
||||
private const float ArriveThreshold = 0.01f;
|
||||
|
||||
private int _currentPointIndex;
|
||||
private bool _isMoving;
|
||||
private List<Transform> _waypoints;
|
||||
|
||||
private Transform nextPoint => _waypoints[_currentPointIndex];
|
||||
private Vector2 currentPosition => new Vector2(transform.position.x, transform.position.z);
|
||||
private Vector2 pointPosition => new Vector2(nextPoint.position.x, nextPoint.position.z);
|
||||
|
||||
public void StartMoving(List<Transform> waypoints)
|
||||
{
|
||||
_isMoving = true;
|
||||
_currentPointIndex = 0;
|
||||
_waypoints = waypoints;
|
||||
TravelledDist = 0;
|
||||
}
|
||||
|
||||
public void StopMoving()
|
||||
{
|
||||
_isMoving = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isMoving)
|
||||
return;
|
||||
|
||||
UpdateTargetPoint();
|
||||
UpdatePosition();
|
||||
UpdateRotation();
|
||||
}
|
||||
|
||||
private void UpdateTargetPoint()
|
||||
{
|
||||
var sqrDist = (currentPosition - pointPosition).sqrMagnitude;
|
||||
|
||||
if (sqrDist <= ArriveThreshold * ArriveThreshold)
|
||||
_currentPointIndex = Mathf.Clamp(_currentPointIndex + 1, 0, _waypoints.Count - 1);
|
||||
}
|
||||
|
||||
private void UpdatePosition()
|
||||
{
|
||||
var vector = pointPosition - currentPosition;
|
||||
var distLeft = (pointPosition - currentPosition).magnitude;
|
||||
|
||||
if (distLeft < ArriveThreshold)
|
||||
return;
|
||||
|
||||
var direction = vector / distLeft;
|
||||
var moveDelta = Mathf.Clamp(Speed * Time.deltaTime, 0, distLeft);
|
||||
var vectorMoveDelta = moveDelta * new Vector3(direction.x, 0, direction.y);
|
||||
|
||||
transform.position += vectorMoveDelta;
|
||||
TravelledDist += moveDelta;
|
||||
}
|
||||
|
||||
private void UpdateRotation()
|
||||
{
|
||||
var vector = pointPosition - currentPosition;
|
||||
var distLeft = (pointPosition - currentPosition).magnitude;
|
||||
|
||||
if (distLeft < ArriveThreshold)
|
||||
return;
|
||||
|
||||
var directionCurrent = new Vector2(transform.forward.x, transform.forward.z);
|
||||
var directionTarget = vector;
|
||||
var directionNew = Vector2.Lerp(directionCurrent, directionTarget, Time.unscaledDeltaTime * RotationSpeed);
|
||||
|
||||
transform.forward = new Vector3(directionNew.x, 0, directionNew.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: af506fca87704f09b836f009d20f8f89
|
||||
timeCreated: 1725791044
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Mob/MobWaypointMover.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class MobManager : MonoBehaviour
|
||||
{
|
||||
public event Action<MobMain> MobDiedByHp;
|
||||
public event Action<MobMain> MobReachedFinish;
|
||||
public List<MobMain> Mobs { get; } = new();
|
||||
|
||||
private const float mobFinishDestroyDelay = 0.25f;
|
||||
private LevelScene _levelScene;
|
||||
private int _spawnedMobCount;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_levelScene.WaveManager.WaveStarted += OnWaveStarted;
|
||||
_levelScene.FinishTriggerZone.OnMobEntered += OnMobTriggeredFinished;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_levelScene.WaveManager.WaveStarted -= OnWaveStarted;
|
||||
_levelScene.FinishTriggerZone.OnMobEntered -= OnMobTriggeredFinished;
|
||||
}
|
||||
|
||||
public void DespawnMobsAll()
|
||||
{
|
||||
foreach (var mob in Mobs.ToList())
|
||||
DespawnMob(mob);
|
||||
|
||||
Mobs.Clear();
|
||||
}
|
||||
|
||||
private void OnWaveStarted()
|
||||
{
|
||||
_spawnedMobCount = 0;
|
||||
}
|
||||
|
||||
private void OnMobTriggeredFinished(MobMain mob)
|
||||
{
|
||||
MobReachedFinish?.Invoke(mob);
|
||||
DespawnMob(mob, false, mobFinishDestroyDelay);
|
||||
|
||||
Watch.Push("MobLog", $"{mob.Id} reached base")
|
||||
.SetSortOrder(TD_WatchSortOrder.MobLog);
|
||||
}
|
||||
|
||||
public MobMain SpawnMob(MobMain prefab)
|
||||
{
|
||||
var mobObj = _levelScene.PoolManager.Get(prefab.gameObject);
|
||||
var mob = mobObj.GetComponent<MobMain>();
|
||||
|
||||
mob.transform.SetParent(transform);
|
||||
mob.transform.position = _levelScene.Waypoints[0].position;
|
||||
|
||||
var mobId = $"Mob_{++_spawnedMobCount}";
|
||||
mob.Spawn(mobId, _levelScene);
|
||||
mob.Health.SetOnDeath(() =>
|
||||
{
|
||||
MobDiedByHp?.Invoke(mob);
|
||||
DespawnMob(mob, true);
|
||||
});
|
||||
Mobs.Add(mob);
|
||||
|
||||
Watch.Push("MobLog", $"{mob.Id} spawned")
|
||||
.SetSortOrder(TD_WatchSortOrder.MobLog);
|
||||
|
||||
return mob;
|
||||
}
|
||||
|
||||
public void DespawnMob(MobMain mob, bool deathFx = false, float delay = 0f)
|
||||
{
|
||||
Mobs.Remove(mob);
|
||||
mob.Despawn(deathFx, delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 240b5da4a1bb461dbc0f45725edce9c2
|
||||
timeCreated: 1725791080
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/MobManager.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class MobTriggerZone : MonoBehaviour
|
||||
{
|
||||
public event Action<MobMain> OnMobEntered;
|
||||
|
||||
[SerializeField] private ParticleSystem _attackFx;
|
||||
|
||||
private void OnTriggerEnter(Collider other)
|
||||
{
|
||||
var mob = other.GetComponentInParent<MobMain>();
|
||||
|
||||
if (mob == null)
|
||||
return;
|
||||
|
||||
OnMobEntered?.Invoke(mob);
|
||||
_attackFx.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3156c2e028794a3a81a780de15656cb3
|
||||
timeCreated: 1725805559
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/MobTriggerZone.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,42 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Pool;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class PoolManager : MonoBehaviour
|
||||
{
|
||||
private Dictionary<GameObject, Stack<GameObject>> _prefabToPools = new();
|
||||
private Dictionary<GameObject, Stack<GameObject>> _objectToPools = new();
|
||||
|
||||
public GameObject Get(GameObject prefab)
|
||||
{
|
||||
var pool = GetPool(prefab);
|
||||
var pooledObject = pool.Count > 0 ? pool.Pop() : Instantiate(prefab);
|
||||
_objectToPools[pooledObject] = pool;
|
||||
|
||||
pooledObject.SetActive(true);
|
||||
return pooledObject;
|
||||
}
|
||||
|
||||
public void Push(GameObject pooledObject)
|
||||
{
|
||||
var pool = _objectToPools[pooledObject];
|
||||
pool.Push(pooledObject);
|
||||
|
||||
pooledObject.SetActive(false);
|
||||
pooledObject.transform.SetParent(transform);
|
||||
}
|
||||
|
||||
private Stack<GameObject> GetPool(GameObject prefab)
|
||||
{
|
||||
if (_prefabToPools.TryGetValue(prefab, out var pool))
|
||||
return pool;
|
||||
|
||||
pool = new Stack<GameObject>();
|
||||
_prefabToPools.Add(prefab, pool);
|
||||
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 302c469964b746ffbd1488b942dae2c0
|
||||
timeCreated: 1725798402
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/PoolManager.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,45 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class ReturnToPoolTimer : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private bool useUnscaledTime = false;
|
||||
[SerializeField] private float delaySeconds = 3;
|
||||
|
||||
private PoolManager poolManager;
|
||||
private float currentTimer;
|
||||
private bool isTimerTicking;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
poolManager = FindObjectOfType<PoolManager>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
isTimerTicking = true;
|
||||
currentTimer = delaySeconds;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
isTimerTicking = false;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!isTimerTicking)
|
||||
return;
|
||||
|
||||
currentTimer -= useUnscaledTime ? Time.unscaledDeltaTime : Time.deltaTime;
|
||||
|
||||
if (currentTimer <= 0)
|
||||
{
|
||||
isTimerTicking = false;
|
||||
poolManager.Push(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2eddfea6dfcf423eb70475a0a9f9bf64
|
||||
timeCreated: 1729244736
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/ReturnToPoolTimer.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 589da07f7f0c48fd991821a2deabecdb
|
||||
timeCreated: 1726052413
|
||||
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
[Serializable]
|
||||
public abstract class BasePopupUI : MonoBehaviour
|
||||
{
|
||||
public bool IsOpened { get; private set; }
|
||||
|
||||
[SerializeField] protected bool _closeByClickOutside = true;
|
||||
[SerializeField] protected bool _lookAtCamera = true;
|
||||
[SerializeField] protected GameObject _panel;
|
||||
|
||||
protected LevelScene _levelScene;
|
||||
private Camera _mainCamera;
|
||||
private bool _skipNextClick;
|
||||
private HashSet<GameObject> _clickableChilds;
|
||||
|
||||
protected virtual void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
_clickableChilds = GetComponentsInChildren<Selectable>().Select(s => s.gameObject).ToHashSet();
|
||||
_mainCamera = Camera.main;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (_lookAtCamera)
|
||||
{
|
||||
transform.rotation = _mainCamera.transform.rotation;
|
||||
}
|
||||
|
||||
OnCreated();
|
||||
}
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if (IsOpened
|
||||
&& _closeByClickOutside
|
||||
&& Input.GetMouseButtonDown(0)
|
||||
&& !_clickableChilds.Contains(EventSystem.current.currentSelectedGameObject))
|
||||
{
|
||||
if (_skipNextClick)
|
||||
_skipNextClick = false;
|
||||
else
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void OnCreated()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnOpened()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
protected virtual void OnClosed()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
if (IsOpened)
|
||||
return;
|
||||
|
||||
IsOpened = true;
|
||||
|
||||
_skipNextClick = true;
|
||||
_panel.SetActive(true);
|
||||
|
||||
OnOpened();
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (!IsOpened)
|
||||
return;
|
||||
|
||||
OnClosed();
|
||||
|
||||
IsOpened = false;
|
||||
_panel.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 635ac69aa74b473d9f0928567300d9ef
|
||||
timeCreated: 1726055771
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Slot/BasePopupUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class ClickableObject : MonoBehaviour
|
||||
{
|
||||
public event Action Clicked;
|
||||
|
||||
private void OnMouseDown()
|
||||
{
|
||||
Clicked?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1819d6599d204b50994dfa6aa395d2e8
|
||||
timeCreated: 1726054870
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Slot/ClickableObject.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class TowerBuildSlot : MonoBehaviour
|
||||
{
|
||||
public event Action OccupationChanged;
|
||||
|
||||
public bool IsOccupied
|
||||
{
|
||||
get => _isOccupied;
|
||||
protected set
|
||||
{
|
||||
if (_isOccupied == value)
|
||||
return;
|
||||
|
||||
_isOccupied = value;
|
||||
OccupationChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
public int Id { get; private set; }
|
||||
public TowerBase Tower { get; protected set; }
|
||||
public Vector3 BuildLocation => transform.position;
|
||||
|
||||
[SerializeField] private GameObject _emptyStateObj;
|
||||
private WatchReference<Any> slotWatch;
|
||||
|
||||
public void Init(int id)
|
||||
{
|
||||
Id = id;
|
||||
slotWatch = Watch.GetOrAdd<Any>("TowerSlots").GetOrAdd<Any>(Id.ToString());
|
||||
slotWatch.GetOrAdd("IsOccupied", () => IsOccupied);
|
||||
}
|
||||
|
||||
public void Occupy(TowerBase tower)
|
||||
{
|
||||
Tower = tower;
|
||||
IsOccupied = true;
|
||||
|
||||
_emptyStateObj.SetActive(false);
|
||||
Watch.Push(slotWatch.GetOrAdd<string>("TowerId"), tower.Id);
|
||||
}
|
||||
|
||||
public void Empty()
|
||||
{
|
||||
IsOccupied = false;
|
||||
Tower = null;
|
||||
|
||||
_emptyStateObj.SetActive(true);
|
||||
slotWatch.GetOrAdd<string>("TowerId").PushEmptyValue();
|
||||
}
|
||||
|
||||
private bool _isOccupied;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fd36162806e5e204ba7176b2cb055a6d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Slot/TowerBuildSlot.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class TowerBuildSlotUIHandler : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TowerBuildSlot _targetSlot;
|
||||
[SerializeField] private ClickableObject _slotClickable;
|
||||
[SerializeField] private TowerSlotBuildPopupUI _buildUI;
|
||||
[SerializeField] private TowerSlotDestroyPopupUI _destroyUI;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_buildUI.TargetSlot = _targetSlot;
|
||||
_destroyUI.TargetSlot = _targetSlot;
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_slotClickable.Clicked += OnSlotClicked;
|
||||
_targetSlot.OccupationChanged += OnSlotOccupied;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_slotClickable.Clicked -= OnSlotClicked;
|
||||
_targetSlot.OccupationChanged -= OnSlotOccupied;
|
||||
}
|
||||
|
||||
private void OnSlotClicked()
|
||||
{
|
||||
if (_targetSlot.IsOccupied)
|
||||
{
|
||||
_destroyUI.Open();
|
||||
}
|
||||
else
|
||||
{
|
||||
_buildUI.Open();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSlotOccupied()
|
||||
{
|
||||
if (_targetSlot.IsOccupied)
|
||||
{
|
||||
_buildUI.Close();
|
||||
}
|
||||
else
|
||||
{
|
||||
_destroyUI.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b85b55a53a2a41e48622aa7404a32e00
|
||||
timeCreated: 1726052468
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Slot/TowerBuildSlotUIHandler.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class TowerSlotBuildPopupUI : BasePopupUI
|
||||
{
|
||||
[SerializeField] private List<BuildButton> _buildButtons = new();
|
||||
|
||||
public TowerBuildSlot TargetSlot { get; set; }
|
||||
|
||||
protected override void OnOpened()
|
||||
{
|
||||
base.OnOpened();
|
||||
|
||||
_levelScene.EnergyManager.EnergyChanged += OnEnergyChanged;
|
||||
|
||||
foreach (var buildButton in _buildButtons)
|
||||
{
|
||||
RefreshButton(buildButton);
|
||||
buildButton.Button.onClick.AddListener(() => OnButtonClicked(buildButton));
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnClosed()
|
||||
{
|
||||
base.OnClosed();
|
||||
|
||||
_levelScene.EnergyManager.EnergyChanged -= OnEnergyChanged;
|
||||
|
||||
foreach (var buildButton in _buildButtons)
|
||||
{
|
||||
buildButton.Button.onClick.RemoveAllListeners();
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshButton(BuildButton buildButton)
|
||||
{
|
||||
var price = _levelScene.EconomyConfig.TowerBuildCosts[buildButton.Type];
|
||||
var playerEnergy = _levelScene.EnergyManager.CurrentEnergy;
|
||||
|
||||
buildButton.Button.interactable = playerEnergy >= price;
|
||||
buildButton.Text.text = $"{buildButton.Type}{Environment.NewLine}COST: -{price}".ToUpper();
|
||||
}
|
||||
|
||||
private void OnEnergyChanged()
|
||||
{
|
||||
foreach (var buildButton in _buildButtons)
|
||||
RefreshButton(buildButton);
|
||||
}
|
||||
|
||||
private void OnButtonClicked(BuildButton buildButton)
|
||||
{
|
||||
_levelScene.TowerBuildManager.BuildTower(TargetSlot, buildButton.Type);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class BuildButton
|
||||
{
|
||||
[FormerlySerializedAs("Tower")] public TowerType Type;
|
||||
public Button Button;
|
||||
public Text Text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 015356ff48f342a0803b25a5ee3d9318
|
||||
timeCreated: 1726059535
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Slot/TowerSlotBuildPopupUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class TowerSlotDestroyPopupUI : BasePopupUI
|
||||
{
|
||||
public TowerBuildSlot TargetSlot { get; set; }
|
||||
|
||||
[SerializeField] private Button sellButton;
|
||||
[SerializeField] private Text sellPriceText;
|
||||
|
||||
protected override void OnOpened()
|
||||
{
|
||||
base.OnOpened();
|
||||
|
||||
var sellPrice = _levelScene.EconomyConfig.TowerSellPrices[TargetSlot.Tower.Type];
|
||||
sellPriceText.text = $"Destroy{Environment.NewLine}+{sellPrice}".ToUpper();
|
||||
|
||||
sellButton.onClick.AddListener(OnSellClicked);
|
||||
}
|
||||
|
||||
protected override void OnClosed()
|
||||
{
|
||||
base.OnClosed();
|
||||
|
||||
sellButton.onClick.RemoveListener(OnSellClicked);
|
||||
}
|
||||
|
||||
private void OnSellClicked()
|
||||
{
|
||||
_levelScene.TowerBuildManager.DestroyTower(TargetSlot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 34b0bb117c064e3695b94aff839b0726
|
||||
timeCreated: 1726059585
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Slot/TowerSlotDestroyPopupUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc1a6b10ff22a7b4186d82b63e52669e
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,33 @@
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class LaserEffect : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float _duration = 0.05f;
|
||||
[SerializeField] private GameObject _laserBeam;
|
||||
|
||||
public void Play(Vector3 target)
|
||||
{
|
||||
target += Vector3.up * 0.5f;
|
||||
|
||||
var dist = (target - transform.position).magnitude;
|
||||
transform.LookAt(target);
|
||||
_laserBeam.transform.localScale = new Vector3(
|
||||
_laserBeam.transform.localScale.x,
|
||||
_laserBeam.transform.localScale.y,
|
||||
dist/2f);
|
||||
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(ShowAndHide());
|
||||
}
|
||||
|
||||
private IEnumerator ShowAndHide()
|
||||
{
|
||||
_laserBeam.SetActive(true);
|
||||
yield return new WaitForSeconds(_duration);
|
||||
_laserBeam.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fc9b506708f84dc285684ec1f66a4793
|
||||
timeCreated: 1726323107
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Tower/LaserEffect.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,111 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class LaserTower : TowerBase
|
||||
{
|
||||
public override TowerType Type => TowerType.Laser;
|
||||
|
||||
[SerializeField] private float _cooldown = 0.5f;
|
||||
[SerializeField] private int _damage = 5;
|
||||
[SerializeField] private float _radius = 4f;
|
||||
[SerializeField] private Transform _turretPivot;
|
||||
[SerializeField] private ParticleSystem _laserEffect;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
private bool _isActive;
|
||||
private float _lastFireTime;
|
||||
private float _lastTargetUpdateTime;
|
||||
private Vector2 ourPos => new Vector2(transform.position.x, transform.position.z);
|
||||
private MobMain _previousTarget;
|
||||
|
||||
private const float targetFindCooldown = 0.05f;
|
||||
private const float rotationSpeed = 5;
|
||||
|
||||
public override void Enable(LevelScene levelScene)
|
||||
{
|
||||
_isActive = true;
|
||||
_lastFireTime = Time.time;
|
||||
_levelScene = levelScene;
|
||||
}
|
||||
|
||||
public override void Disable()
|
||||
{
|
||||
_isActive = false;
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
Gizmos.DrawWireSphere(transform.position, _radius);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isActive)
|
||||
return;
|
||||
|
||||
UpdateRotation();
|
||||
|
||||
if (Time.time < _lastFireTime + _cooldown)
|
||||
return;
|
||||
|
||||
_lastFireTime = Time.time;
|
||||
Fire();
|
||||
}
|
||||
|
||||
private void UpdateRotation()
|
||||
{
|
||||
if (Time.time > _lastTargetUpdateTime + targetFindCooldown)
|
||||
_previousTarget = FindNearestTarget();
|
||||
|
||||
if (_previousTarget == null || !_previousTarget.IsAlive)
|
||||
return;
|
||||
|
||||
var targetDirection = _previousTarget.transform.position - _turretPivot.position;
|
||||
var directionNew = Vector3.Slerp(_turretPivot.forward, targetDirection, Time.unscaledDeltaTime * rotationSpeed);
|
||||
_turretPivot.forward = directionNew;
|
||||
}
|
||||
|
||||
private MobMain FindNearestTarget()
|
||||
{
|
||||
MobMain targetMob = null;
|
||||
|
||||
foreach (var mob in _levelScene.MobManager.Mobs)
|
||||
{
|
||||
var mobPos = new Vector2(mob.transform.position.x, mob.transform.position.z);
|
||||
var sqrDist = (mobPos - ourPos).sqrMagnitude;
|
||||
|
||||
if (sqrDist > _radius * _radius)
|
||||
continue;
|
||||
|
||||
if (targetMob == null || mob.WaypointMover.TravelledDist > targetMob.WaypointMover.TravelledDist)
|
||||
{
|
||||
targetMob = mob;
|
||||
}
|
||||
}
|
||||
|
||||
return targetMob;
|
||||
}
|
||||
|
||||
private void Fire()
|
||||
{
|
||||
var targetMob = FindNearestTarget();
|
||||
|
||||
if (targetMob != null)
|
||||
{
|
||||
if (targetMob.Health.CurrentHealth <= _damage)
|
||||
Watch.Push("MobLog", $"{targetMob.Id} killed by {Id}")
|
||||
.SetSortOrder(TD_WatchSortOrder.MobLog)
|
||||
;
|
||||
|
||||
_turretPivot.forward = targetMob.transform.position - _turretPivot.position;
|
||||
_laserEffect.transform.LookAt(targetMob.transform.position);
|
||||
_laserEffect.Play();
|
||||
|
||||
targetMob.Health.TakeDamage(_damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 163f0a04a378463a841d7ad2758ad6ad
|
||||
timeCreated: 1726318386
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Tower/LaserTower.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class ShockwaveTower : TowerBase
|
||||
{
|
||||
public override TowerType Type => TowerType.Shockwave;
|
||||
|
||||
[SerializeField] private float _cooldown = 1f;
|
||||
[SerializeField] private int _damage = 20;
|
||||
[SerializeField] private float _radius = 3f;
|
||||
[SerializeField] private ParticleSystem _waveEffect;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
private bool _isActive;
|
||||
private float _lastFireTime;
|
||||
private Vector2 ourPos => new Vector2(transform.position.x, transform.position.z);
|
||||
private List<MobMain> _pendingDamageMobs = new();
|
||||
|
||||
public override void Enable(LevelScene levelScene)
|
||||
{
|
||||
_isActive = true;
|
||||
_lastFireTime = Time.time;
|
||||
_levelScene = levelScene;
|
||||
}
|
||||
|
||||
public override void Disable()
|
||||
{
|
||||
_isActive = false;
|
||||
}
|
||||
|
||||
private void OnDrawGizmos()
|
||||
{
|
||||
Gizmos.DrawWireSphere(transform.position, _radius);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!_isActive)
|
||||
return;
|
||||
|
||||
if (Time.time < _lastFireTime + _cooldown)
|
||||
return;
|
||||
|
||||
_lastFireTime = Time.time;
|
||||
Fire();
|
||||
}
|
||||
|
||||
private void Fire()
|
||||
{
|
||||
_pendingDamageMobs.Clear();
|
||||
|
||||
foreach (var mob in _levelScene.MobManager.Mobs)
|
||||
{
|
||||
var mobPos = new Vector2(mob.transform.position.x, mob.transform.position.z);
|
||||
var sqrDist = (mobPos - ourPos).sqrMagnitude;
|
||||
|
||||
if (sqrDist > _radius * _radius)
|
||||
continue;
|
||||
|
||||
_pendingDamageMobs.Add(mob);
|
||||
}
|
||||
|
||||
foreach (var mob in _pendingDamageMobs)
|
||||
{
|
||||
if (mob.Health.CurrentHealth <= _damage)
|
||||
{
|
||||
Watch.Push("MobLog", $"{mob.Id} killed by {Id}")
|
||||
.SetSortOrder(TD_WatchSortOrder.MobLog)
|
||||
;
|
||||
}
|
||||
|
||||
mob.Health.TakeDamage(_damage);
|
||||
}
|
||||
|
||||
_waveEffect.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59b5965df77a462a9425484fb3d9f8f9
|
||||
timeCreated: 1725990226
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Tower/ShockwaveTower.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,12 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public abstract class TowerBase : MonoBehaviour
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public abstract TowerType Type { get; }
|
||||
public abstract void Enable(LevelScene levelScene);
|
||||
public abstract void Disable();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e0632d72869458bbc6ea2eb55f19201
|
||||
timeCreated: 1725990613
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Tower/TowerBase.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public enum TowerType
|
||||
{
|
||||
Shockwave,
|
||||
Laser
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9c13752bd084cdb978f2a51ce953371
|
||||
timeCreated: 1726052989
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Tower/TowerType.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class WaveEffect : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float _growDuration = 0.1f;
|
||||
[SerializeField] private float _stayDuration = 0.1f;
|
||||
[SerializeField] private Transform _wave;
|
||||
|
||||
private float _radius;
|
||||
private Coroutine _effectRoutine;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
SetSizeRaw(0);
|
||||
}
|
||||
|
||||
public void SetRadius(float radius)
|
||||
{
|
||||
_radius = radius;
|
||||
}
|
||||
|
||||
public void Play()
|
||||
{
|
||||
SetSizeRaw(0);
|
||||
|
||||
if (_effectRoutine != null)
|
||||
StopCoroutine(_effectRoutine);
|
||||
|
||||
_effectRoutine = StartCoroutine(EffectPlaying());
|
||||
}
|
||||
|
||||
private IEnumerator EffectPlaying()
|
||||
{
|
||||
SetSizeRaw(0);
|
||||
|
||||
var timer = _growDuration;
|
||||
|
||||
while (timer >= 0)
|
||||
{
|
||||
timer -= Time.deltaTime;
|
||||
|
||||
var progress = 1 - timer / _growDuration;
|
||||
SetSizeRaw(_radius * progress);
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
yield return new WaitForSeconds(_stayDuration);
|
||||
|
||||
SetSizeRaw(0);
|
||||
}
|
||||
|
||||
private void SetSizeRaw(float value)
|
||||
{
|
||||
_wave.localScale = value * Vector3.one;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fad3a9a7a9ac406ab0618ee81f7d420f
|
||||
timeCreated: 1725993754
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/Tower/WaveEffect.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Ingvar.LiveWatch.TowerDefenceDemo;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class TowerBuildManager : MonoBehaviour
|
||||
{
|
||||
public List<TowerBuildSlot> Slots => _slots;
|
||||
|
||||
[SerializeField] private Transform _towersParent;
|
||||
[SerializeField] private List<TowerBuildSlot> _slots;
|
||||
[SerializeField] private List<TowerPrefab> _towerPrefabs;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
|
||||
var slotId = 0;
|
||||
foreach (var slot in _slots)
|
||||
slot.Init(slotId++);
|
||||
|
||||
Watch.GetOrAdd<string>("BuildLog")
|
||||
.SetSortOrder(TD_WatchSortOrder.TowerBuildLog);
|
||||
}
|
||||
|
||||
|
||||
public void DestroyAllTowers()
|
||||
{
|
||||
foreach (var slot in Slots)
|
||||
{
|
||||
if (!slot.IsOccupied)
|
||||
continue;
|
||||
|
||||
DestroyTower(slot, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void BuildTower(TowerBuildSlot slot, TowerType type, bool useGold = true)
|
||||
{
|
||||
var prefab = _towerPrefabs.First(p => p.Type == type).Prefab;
|
||||
var towerObj = _levelScene.PoolManager.Get(prefab.gameObject);
|
||||
var tower = towerObj.GetComponent<TowerBase>();
|
||||
|
||||
towerObj.transform.SetParent(_towersParent);
|
||||
towerObj.transform.position = slot.BuildLocation;
|
||||
|
||||
_levelScene.TowerManager.AddTower(tower);
|
||||
slot.Occupy(tower);
|
||||
|
||||
Watch.Push("BuildLog", $"Built {tower.Id} at {slot.Id} slot");
|
||||
if (useGold)
|
||||
{
|
||||
var price = _levelScene.EconomyConfig.TowerBuildCosts[type];
|
||||
_levelScene.EnergyManager.CurrentEnergy -= price;
|
||||
}
|
||||
}
|
||||
|
||||
public void DestroyTower(TowerBuildSlot slot, bool useGold = true)
|
||||
{
|
||||
var tower = slot.Tower;
|
||||
Watch.Push("BuildLog", $"Destroyed {slot.Tower.Id} at {slot.Id}");
|
||||
|
||||
_levelScene.TowerManager.RemoveTower(tower);
|
||||
_levelScene.PoolManager.Push(tower.gameObject);
|
||||
slot.Empty();
|
||||
|
||||
if (useGold)
|
||||
{
|
||||
var price = _levelScene.EconomyConfig.TowerSellPrices[tower.Type];
|
||||
_levelScene.EnergyManager.CurrentEnergy += price;
|
||||
}
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class TowerPrefab
|
||||
{
|
||||
public TowerType Type;
|
||||
public TowerBase Prefab;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: efcc9dd285e44b55b526b2a8b87ebdd9
|
||||
timeCreated: 1726052278
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/TowerBuildManager.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class TowerManager : MonoBehaviour
|
||||
{
|
||||
private Dictionary<string, TowerBase> _towers = new();
|
||||
|
||||
private LevelScene _levelScene;
|
||||
private int _spawnedTowersCount;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
|
||||
public void EnabledTowers()
|
||||
{
|
||||
foreach (var tower in _towers.Values)
|
||||
{
|
||||
tower.Enable(_levelScene);
|
||||
}
|
||||
}
|
||||
|
||||
public void DisableTowers()
|
||||
{
|
||||
foreach (var tower in _towers.Values)
|
||||
{
|
||||
tower.Disable();
|
||||
}
|
||||
}
|
||||
|
||||
public void AddTower(TowerBase tower)
|
||||
{
|
||||
tower.Id = $"{tower.Type}_{++_spawnedTowersCount}";
|
||||
_towers.Add(tower.Id, tower);
|
||||
|
||||
if (_levelScene.LevelStateManager.CurrentState == LevelStateType.Playing)
|
||||
tower.Enable(_levelScene);
|
||||
}
|
||||
|
||||
public void RemoveTower(TowerBase tower)
|
||||
{
|
||||
_towers.Remove(tower.Id);
|
||||
|
||||
if (_levelScene.LevelStateManager.CurrentState == LevelStateType.Playing)
|
||||
tower.Disable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3dcaf7048f434c0c98737db4920b3740
|
||||
timeCreated: 1725991927
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/TowerManager.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0d32e44f88e4dbe97033609e73885af
|
||||
timeCreated: 1725809354
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo.UI
|
||||
{
|
||||
public class EnergyPanelUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float _animationExtraScale = 0.2f;
|
||||
[SerializeField] private float _animationScaleDuration = 0.2f;
|
||||
[SerializeField] private Text _energyText;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_levelScene.EnergyManager.EnergyChanged += OnEnergyChanged;
|
||||
RefreshEnergy(false);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_levelScene.EnergyManager.EnergyChanged -= OnEnergyChanged;
|
||||
}
|
||||
|
||||
private void OnEnergyChanged()
|
||||
{
|
||||
RefreshEnergy();
|
||||
}
|
||||
|
||||
private void RefreshEnergy(bool animate = true)
|
||||
{
|
||||
_energyText.text = $"{_levelScene.EnergyManager.CurrentEnergy}";
|
||||
|
||||
if (animate)
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(AnimateChange());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator AnimateChange()
|
||||
{
|
||||
_energyText.transform.localScale = Vector3.one;
|
||||
|
||||
var zoomOutTime = 0f;
|
||||
while (zoomOutTime <= _animationScaleDuration)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
zoomOutTime += Time.deltaTime;
|
||||
var progress = Mathf.Clamp01(Mathf.InverseLerp(0, _animationScaleDuration, zoomOutTime));
|
||||
_energyText.transform.localScale = (1 + progress * _animationExtraScale) * Vector3.one;
|
||||
}
|
||||
|
||||
var zoomInTime = 0f;
|
||||
while (zoomInTime <= _animationScaleDuration)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
zoomInTime += Time.deltaTime;
|
||||
var progress = Mathf.Clamp01(Mathf.InverseLerp(0, _animationScaleDuration, zoomInTime));
|
||||
_energyText.transform.localScale = (1 + _animationExtraScale - progress * _animationExtraScale) * Vector3.one;
|
||||
}
|
||||
|
||||
_energyText.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9797888ece1d48379a82c2d289de9991
|
||||
timeCreated: 1725995747
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/UI/EnergyPanelUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,73 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo.UI
|
||||
{
|
||||
public class HealthPanelUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float animationExtraScale = 0.2f;
|
||||
[SerializeField] private float animationScaleDuration = 0.2f;
|
||||
[SerializeField] private Text healthText;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_levelScene.HealthManager.HealthChanged += OnHealthChanged;
|
||||
RefreshHealth(false);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_levelScene.HealthManager.HealthChanged -= OnHealthChanged;
|
||||
}
|
||||
|
||||
private void OnHealthChanged()
|
||||
{
|
||||
RefreshHealth();
|
||||
}
|
||||
|
||||
private void RefreshHealth(bool animate = true)
|
||||
{
|
||||
healthText.text = $"{_levelScene.HealthManager.CurrentHealth}";
|
||||
|
||||
if (animate)
|
||||
{
|
||||
StopAllCoroutines();
|
||||
StartCoroutine(AnimateChange());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator AnimateChange()
|
||||
{
|
||||
healthText.transform.localScale = Vector3.one;
|
||||
|
||||
var zoomOutTime = 0f;
|
||||
while (zoomOutTime <= animationScaleDuration)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
zoomOutTime += Time.deltaTime;
|
||||
var progress = Mathf.Clamp01(Mathf.InverseLerp(0, animationScaleDuration, zoomOutTime));
|
||||
healthText.transform.localScale = (1 + progress * animationExtraScale) * Vector3.one;
|
||||
}
|
||||
|
||||
var zoomInTime = 0f;
|
||||
while (zoomInTime <= animationScaleDuration)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
zoomInTime += Time.deltaTime;
|
||||
var progress = Mathf.Clamp01(Mathf.InverseLerp(0, animationScaleDuration, zoomInTime));
|
||||
healthText.transform.localScale = (1 + animationExtraScale - progress * animationExtraScale) * Vector3.one;
|
||||
}
|
||||
|
||||
healthText.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0185bc50567c4c2fb9c6a083dba272c0
|
||||
timeCreated: 1725809360
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/UI/HealthPanelUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo.UI
|
||||
{
|
||||
public class LevelFinishPanelUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private CanvasGroup panelBase;
|
||||
[SerializeField] private Text statusText;
|
||||
[SerializeField] private Button restartButton;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
restartButton.onClick.AddListener(OnRestartButtonClicked);
|
||||
_levelScene.LevelStateManager.StateChanged += LevelStateManagerOnStateChanged;
|
||||
|
||||
SetShown(false);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
restartButton.onClick.RemoveListener(OnRestartButtonClicked);
|
||||
_levelScene.LevelStateManager.StateChanged -= LevelStateManagerOnStateChanged;
|
||||
}
|
||||
|
||||
private void LevelStateManagerOnStateChanged()
|
||||
{
|
||||
if (_levelScene.LevelStateManager.CurrentState is not LevelStateType.Win and not LevelStateType.Lose)
|
||||
return;
|
||||
|
||||
SetShown(true);
|
||||
|
||||
statusText.text = _levelScene.LevelStateManager.CurrentState == LevelStateType.Win
|
||||
? "YOU WON"
|
||||
: "YOU LOST";
|
||||
}
|
||||
|
||||
private void OnRestartButtonClicked()
|
||||
{
|
||||
SetShown(false);
|
||||
_levelScene.LevelStateManager.StartLevel();
|
||||
}
|
||||
|
||||
private void SetShown(bool isOn)
|
||||
{
|
||||
panelBase.alpha = isOn ? 1 : 0;
|
||||
panelBase.blocksRaycasts = isOn;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fa255261a4664bb8b36eb5d6d0bfc246
|
||||
timeCreated: 1725821124
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/UI/LevelFinishPanelUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo.UI
|
||||
{
|
||||
public class SpeedPanelUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private List<SpeedToggle> _speedToggles;
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_levelScene.SpeedManager.SpeedChanged += RefreshToggles;
|
||||
|
||||
foreach (var speedToggle in _speedToggles)
|
||||
speedToggle.Toggle.onValueChanged.AddListener((isOn) => OnToggleChanged(speedToggle, isOn));
|
||||
|
||||
RefreshToggles();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_levelScene.SpeedManager.SpeedChanged -= RefreshToggles;
|
||||
|
||||
foreach (var speedToggle in _speedToggles)
|
||||
speedToggle.Toggle.onValueChanged.RemoveAllListeners();
|
||||
}
|
||||
|
||||
private void RefreshToggles()
|
||||
{
|
||||
foreach (var speedToggle in _speedToggles)
|
||||
speedToggle.Toggle.SetIsOnWithoutNotify(speedToggle.Speed == _levelScene.SpeedManager.CurrentSpeed);
|
||||
}
|
||||
|
||||
private void OnToggleChanged(SpeedToggle speedToggle, bool isOn)
|
||||
{
|
||||
if (!isOn)
|
||||
return;
|
||||
|
||||
_levelScene.SpeedManager.SetGameSpeed(speedToggle.Speed);
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class SpeedToggle
|
||||
{
|
||||
public Toggle Toggle;
|
||||
public SpeedMode Speed;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 566f30cbabcd4731b0879f05b6ac7e3e
|
||||
timeCreated: 1726312021
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/UI/SpeedPanelUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo.UI
|
||||
{
|
||||
public class WaveButtonUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Button playWaveButton;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_levelScene.LevelStateManager.StateChanged += RefreshButton;
|
||||
playWaveButton.onClick.AddListener(OnPlayButtonClicked);
|
||||
|
||||
RefreshButton();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_levelScene.LevelStateManager.StateChanged -= RefreshButton;
|
||||
playWaveButton.onClick.RemoveListener(OnPlayButtonClicked);
|
||||
}
|
||||
|
||||
private void RefreshButton()
|
||||
{
|
||||
playWaveButton.interactable = _levelScene.LevelStateManager.CurrentState == LevelStateType.Waiting;
|
||||
}
|
||||
|
||||
private void OnPlayButtonClicked()
|
||||
{
|
||||
_levelScene.WaveManager.StartWave();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 25bd98f41f9b4d7eb3cb2459efb29153
|
||||
timeCreated: 1725819869
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/UI/WaveButtonUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo.UI
|
||||
{
|
||||
public class WavePanelUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private Text waveText;
|
||||
|
||||
private LevelScene _levelScene;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
_levelScene.WaveManager.WaveChanged += RefreshWave;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
_levelScene.WaveManager.WaveChanged -= RefreshWave;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
RefreshWave();
|
||||
}
|
||||
|
||||
private void RefreshWave()
|
||||
{
|
||||
waveText.text = $"WAVE: {_levelScene.WaveManager.CurrentWave+1}/{_levelScene.WaveManager.MaxWave+1}";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 917360a2cc324e4bb5304ceb3a8d028e
|
||||
timeCreated: 1725811761
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/UI/WavePanelUI.cs
|
||||
uploadId: 770587
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Ingvar.LiveWatch.TowerDefenceDemo
|
||||
{
|
||||
public class WaveManager : MonoBehaviour
|
||||
{
|
||||
public event Action WaveStarted;
|
||||
public event Action WaveFinished;
|
||||
public event Action WaveChanged;
|
||||
|
||||
public bool IsActiveWave { get; private set; }
|
||||
public int CurrentWave
|
||||
{
|
||||
get => _wave;
|
||||
set
|
||||
{
|
||||
if (_wave == value)
|
||||
return;
|
||||
|
||||
_wave = value;
|
||||
WaveChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
public int MaxWave => _levelScene.LevelConfig.Waves.Count - 1;
|
||||
public int CurrentSpawn { get; private set; }
|
||||
|
||||
private LevelScene _levelScene;
|
||||
private int _wave;
|
||||
private Coroutine _waveRoutine;
|
||||
private List<MobWave> waves => _levelScene.LevelConfig.Waves;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
_levelScene = FindObjectOfType<LevelScene>();
|
||||
}
|
||||
|
||||
|
||||
public void ResetWaves()
|
||||
{
|
||||
CurrentWave = 0;
|
||||
}
|
||||
|
||||
public void SetNextWave()
|
||||
{
|
||||
CurrentWave = Mathf.Clamp(CurrentWave + 1, 0, MaxWave);
|
||||
}
|
||||
|
||||
public void StartWave()
|
||||
{
|
||||
IsActiveWave = true;
|
||||
_waveRoutine = StartCoroutine(WaveProcessing(waves[CurrentWave]));
|
||||
WaveStarted?.Invoke();
|
||||
}
|
||||
|
||||
public void FinishWave()
|
||||
{
|
||||
if (_waveRoutine != null)
|
||||
StopCoroutine(_waveRoutine);
|
||||
|
||||
IsActiveWave = false;
|
||||
WaveFinished?.Invoke();
|
||||
}
|
||||
|
||||
private IEnumerator WaveProcessing(MobWave wave)
|
||||
{
|
||||
CurrentSpawn = 0;
|
||||
|
||||
foreach (var spawn in wave.Spawns)
|
||||
{
|
||||
yield return new WaitForSeconds(spawn.Delay);
|
||||
|
||||
for (var i = 0; i < spawn.MobCount; i++)
|
||||
{
|
||||
_levelScene.MobManager.SpawnMob(spawn.MobPrefab);
|
||||
yield return new WaitForSeconds(spawn.SpawnDelayBetween);
|
||||
}
|
||||
|
||||
CurrentSpawn++;
|
||||
}
|
||||
|
||||
yield return new WaitWhile(() => _levelScene.MobManager.Mobs.Count > 0);
|
||||
FinishWave();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7295529eb2a40b28cb726a23b6b6d35
|
||||
timeCreated: 1725810836
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 324001
|
||||
packageName: LiveWatch Lite | Debug with full history of changes
|
||||
packageVersion: 1.0.1
|
||||
assetPath: Assets/LiveWatchLite/TowerDefenceDemo/Scripts/WaveManager.cs
|
||||
uploadId: 770587
|
||||
Reference in New Issue
Block a user