Add new meta files and interfaces for project structure

This commit is contained in:
2025-07-11 21:46:14 +02:00
commit 43c1730ed5
3230 changed files with 1428743 additions and 0 deletions

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

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3c731f00fecb494083d0a60ed8c7450d
timeCreated: 1752254721

View File

@@ -0,0 +1,11 @@
using Sirenix.OdinInspector;
using Sirenix.Serialization;
using UnityEngine;
namespace Data
{
public class Character : MonoBehaviour
{
[OdinSerialize, InlineProperty] public CharacterAttributes attributes = new();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 44b572240c4243c9954bd19967bfeb64
timeCreated: 1752255110

View File

@@ -0,0 +1,266 @@
using System;
using Sirenix.OdinInspector;
using Sirenix.Serialization;
namespace Data
{
[Serializable]
public class CharacterAttributes
{
[OdinSerialize] public float health = 100f;
[OdinSerialize] public float maxHealth = 100f;
[OdinSerialize] public float moveSpeed = 5f;
[OdinSerialize] public float luck = 0f;
[OdinSerialize] public float armor = 0f;
[OdinSerialize, PropertyTooltip("This is damage multiplier")]
public float damage = 1f;
[OdinSerialize, PropertyTooltip("This is damage multiplier for ranged attacks")]
public float rangedDamage = 1f;
[OdinSerialize, PropertyTooltip("This is damage multiplier for melee attacks")]
public float meleeDamage = 1f;
[OdinSerialize] public float attackRange = 16f;
[OdinSerialize] public float attackSpeed = 1f;
public event Action<float> OnHealthChanged;
public event Action<float> OnMaxHealthChanged;
public event Action<float> OnMoveSpeedChanged;
public event Action<float> OnLuckChanged;
public event Action<float> OnArmorChanged;
public event Action<float> OnDamageChanged;
public event Action<float> OnRangedDamageChanged;
public event Action<float> OnMeleeDamageChanged;
public event Action<float> OnAttackRangeChanged;
public event Action<float> OnAttackSpeedChanged;
public float Health
{
get => health;
private set
{
if (Math.Abs(health - value) < float.Epsilon) return;
health = value;
OnHealthChanged?.Invoke(health);
}
}
public float MaxHealth
{
get => maxHealth;
private set
{
if (Math.Abs(maxHealth - value) < float.Epsilon) return;
maxHealth = value;
OnMaxHealthChanged?.Invoke(maxHealth);
}
}
public float MoveSpeed
{
get => moveSpeed;
private set
{
if (Math.Abs(moveSpeed - value) < float.Epsilon) return;
moveSpeed = value;
OnMoveSpeedChanged?.Invoke(moveSpeed);
}
}
public float Luck
{
get => luck;
private set
{
if (Math.Abs(luck - value) < float.Epsilon) return;
luck = value;
OnLuckChanged?.Invoke(luck);
}
}
public float Armor
{
get => armor;
private set
{
if (Math.Abs(armor - value) < float.Epsilon) return;
armor = value;
OnArmorChanged?.Invoke(armor);
}
}
public float Damage
{
get => damage;
private set
{
if (Math.Abs(damage - value) < float.Epsilon) return;
damage = value;
OnDamageChanged?.Invoke(damage);
}
}
public float RangedDamage
{
get => rangedDamage;
private set
{
if (Math.Abs(rangedDamage - value) < float.Epsilon) return;
rangedDamage = value;
OnRangedDamageChanged?.Invoke(rangedDamage);
}
}
public float MeleeDamage
{
get => meleeDamage;
private set
{
if (Math.Abs(meleeDamage - value) < float.Epsilon) return;
meleeDamage = value;
OnMeleeDamageChanged?.Invoke(meleeDamage);
}
}
public float AttackRange
{
get => attackRange;
private set
{
if (Math.Abs(attackRange - value) < float.Epsilon) return;
attackRange = value;
OnAttackRangeChanged?.Invoke(attackRange);
}
}
public float AttackSpeed
{
get => attackSpeed;
private set
{
if (Math.Abs(attackSpeed - value) < float.Epsilon) return;
attackSpeed = value;
OnAttackSpeedChanged?.Invoke(attackSpeed);
}
}
public void SetHealth(float value)
{
Health = Math.Clamp(value, 0, MaxHealth);
}
public void SetMaxHealth(float value)
{
MaxHealth = Math.Max(value, 0);
if (Health > MaxHealth)
{
Health = MaxHealth;
}
}
public void SetMoveSpeed(float value)
{
MoveSpeed = Math.Max(value, 0);
}
public void SetLuck(float value)
{
Luck = Math.Max(value, 0);
}
public void SetArmor(float value)
{
Armor = Math.Max(value, 0);
}
public void SetDamage(float value)
{
Damage = Math.Max(value, 0);
}
public void SetRangedDamage(float value)
{
RangedDamage = Math.Max(value, 0);
}
public void SetMeleeDamage(float value)
{
MeleeDamage = Math.Max(value, 0);
}
public void SetAttackRange(float value)
{
AttackRange = Math.Max(value, 0);
}
public void SetAttackSpeed(float value)
{
AttackSpeed = Math.Max(value, 0);
}
public void ModifyHealth(float delta)
{
SetHealth(Health + delta);
}
public void ModifyMaxHealth(float delta)
{
SetMaxHealth(MaxHealth + delta);
}
public void ModifyMoveSpeed(float delta)
{
SetMoveSpeed(MoveSpeed + delta);
}
public void ModifyLuck(float delta)
{
SetLuck(Luck + delta);
}
public void ModifyArmor(float delta)
{
SetArmor(Armor + delta);
}
public void ModifyDamage(float delta)
{
SetDamage(Damage + delta);
}
public void ModifyRangedDamage(float delta)
{
SetRangedDamage(RangedDamage + delta);
}
public void ModifyMeleeDamage(float delta)
{
SetMeleeDamage(MeleeDamage + delta);
}
public void ModifyAttackRange(float delta)
{
SetAttackRange(AttackRange + delta);
}
public void ModifyAttackSpeed(float delta)
{
SetAttackSpeed(AttackSpeed + delta);
}
public void Reset()
{
Health = MaxHealth = 100f;
MoveSpeed = 5f;
Luck = 0f;
Armor = 0f;
Damage = 1f;
RangedDamage = 1f;
MeleeDamage = 1f;
AttackRange = 16f;
AttackSpeed = 1f;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ec34b2d212ec4a40aa3f6365010831d2
timeCreated: 1752254981

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 29e980f0c2ed42388d7cce531df73f64
timeCreated: 1752257139

View File

@@ -0,0 +1,19 @@
using UnityEngine;
namespace Interfaces
{
public interface IDamageInflector
{
float Damage { get; }
GameObject Owner { get; }
DamageType Type { get; }
}
public enum DamageType
{
Melee,
Ranged,
Magic,
True
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a30deabf1e4846b88b50d344a066d3b9
timeCreated: 1752258571

View File

@@ -0,0 +1,9 @@
using Data;
namespace Interfaces
{
public interface IDamageInflectorSetup
{
void Setup(Character attacker);
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9f328cdb5cd3428aaac6120198e94b7f
timeCreated: 1752259405

View File

@@ -0,0 +1,7 @@
namespace Interfaces
{
public interface IDeathBehavior
{
void Die();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 396e339b82ed49f8b4714bb5b5590ebe
timeCreated: 1752258524

View File

@@ -0,0 +1,7 @@
namespace Interfaces
{
public interface IWeapon
{
void Fire();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1bf1e96a05924a4ebada9d3e9b32473b
timeCreated: 1752258710

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 80054e1d536ad7a388c5fd2612c9e5a3

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 24a41a699fc246ceae6ebc1bc88d5b85
timeCreated: 1752255158

View File

@@ -0,0 +1,34 @@
using System;
using KBCore.Refs;
using UnityEngine;
using UnityEngine.InputSystem;
namespace Systems
{
public class Aiming : MonoBehaviour
{
[SerializeField, Scene] private Camera mainCamera;
private void Reset()
{
if (!mainCamera)
{
mainCamera = Camera.main;
}
}
private void Update()
{
if (!mainCamera) return;
var mousePosition = Mouse.current.position.ReadValue();
var worldPosition = mainCamera.ScreenToWorldPoint(mousePosition);
worldPosition.z = transform.position.z;
var direction = (worldPosition - transform.position).normalized;
var angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0,0, angle);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: d8f62cd9ff7b4fcfa29d4c7fca486944
timeCreated: 1752262081

View File

@@ -0,0 +1,36 @@
using Data;
using Interfaces;
using KBCore.Refs;
using UnityEngine;
namespace Systems
{
public class DeathHandler : MonoBehaviour
{
[Self, SerializeField] private Character character;
[Self, SerializeField] private InterfaceRef<IDeathBehavior> deathBehavior;
private void OnEnable()
{
character.attributes.OnHealthChanged += OnHealthChanged;
}
private void OnDisable()
{
character.attributes.OnHealthChanged -= OnHealthChanged;
}
private void OnHealthChanged(float newHealth)
{
if (newHealth <= 0f)
{
Die();
}
}
private void Die()
{
deathBehavior.Value.Die();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5fa2924c6ed8486bbfa95c439bf9e421
timeCreated: 1752260559

View File

@@ -0,0 +1,24 @@
using System;
using Data;
using KBCore.Refs;
using UnityEngine;
namespace Systems
{
public class Health : MonoBehaviour
{
[Self, SerializeField] private Character character;
[SerializeField] private float initialHealth = 100f;
private void Start()
{
character.attributes.SetHealth(initialHealth);
}
public void TakeDamage(float damage)
{
var effectiveDamage = Math.Max(damage - character.attributes.Armor, 1);
character.attributes.ModifyHealth(-effectiveDamage);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 9139aea24fd54a5eb0f5fc1556478cb6
timeCreated: 1752257112

View File

@@ -0,0 +1,50 @@
using System;
using Data;
using KBCore.Refs;
using UnityEngine;
using UnityEngine.InputSystem;
namespace Systems
{
public class Movement : MonoBehaviour
{
private InputSystem_Actions controls;
private Vector2 movementInput;
[Self, SerializeField] private Character character;
[Self, SerializeField] private Rigidbody2D rb;
private void OnEnable()
{
controls ??= new InputSystem_Actions();
controls.Enable();
controls.Player.Move.performed += OnMovePerformed;
controls.Player.Move.canceled += ctx => movementInput = Vector2.zero;
}
private void OnMovePerformed(InputAction.CallbackContext obj)
{
movementInput = obj.ReadValue<Vector2>();
}
private void OnDisable()
{
controls.Disable();
controls.Player.Move.performed -= OnMovePerformed;
}
private void FixedUpdate()
{
ApplyMovement();
}
private void ApplyMovement()
{
if (!rb) return;
var velocity = new Vector2(movementInput.x, movementInput.y).normalized * character.attributes.MoveSpeed;
rb.linearVelocity = velocity;
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3c35f16c2a9546a2b4911f4da933efa0
timeCreated: 1752255167

View File

@@ -0,0 +1,14 @@
using Interfaces;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Systems
{
public class PlayerDeathBehavior : MonoBehaviour, IDeathBehavior
{
public void Die()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b46c8a98e30a405eb2d287515609ecda
timeCreated: 1752258510

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6acebadd6c0546d6bd75d7879efd28cb
timeCreated: 1752259203

View File

@@ -0,0 +1,19 @@
using Interfaces;
using UnityEngine;
namespace Weapons
{
public class AutoWeapon : Weapon, IWeapon
{
[SerializeField] private GameObject projectilePrefab;
[SerializeField] private Transform firePoint;
public override void Fire()
{
var projectile = Instantiate(projectilePrefab, firePoint.position, firePoint.rotation);
projectile.TryGetComponent<IDamageInflectorSetup>(out var inflector);
inflector?.Setup(character);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: fd9cdb55272f45ab9c60a948a56e01f5
timeCreated: 1752259218

View File

@@ -0,0 +1,27 @@
using System;
using Data;
using Interfaces;
using Systems;
using UnityEngine;
namespace Weapons
{
public class MeleeAttack : Weapon, IWeapon
{
[SerializeField] private float range = 1f;
[SerializeField] private LayerMask targetMask;
public override void Fire()
{
var hits = Physics2D.OverlapCircleAll(transform.position, range, targetMask);
foreach (var hit in hits)
{
hit.TryGetComponent<Health>(out var health);
if (hit.gameObject == character.gameObject) continue;
var damage = character.attributes.Damage * character.attributes.MeleeDamage;
health.TakeDamage(damage);
}
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: e4ff53f671604189b15fac28115b2b70
timeCreated: 1752259665

View File

@@ -0,0 +1,47 @@
using System;
using Data;
using Interfaces;
using KBCore.Refs;
using Systems;
using UnityEngine;
namespace Weapons
{
public class Projectile : MonoBehaviour, IDamageInflector, IDamageInflectorSetup
{
[Self, SerializeField] private Rigidbody2D rb;
[SerializeField] private float speed = 10f;
[SerializeField] private float lifeTime = 5f;
public float Damage { get; private set; }
public GameObject Owner { get; private set; }
public DamageType Type => DamageType.Ranged;
public void Setup(Character attacker)
{
Damage = attacker.attributes.Damage * attacker.attributes.RangedDamage;
Owner = attacker.gameObject;
}
private void Start()
{
Destroy(gameObject, lifeTime);
}
private void FixedUpdate()
{
var direction = transform.up.normalized;
var movement = direction * (speed * Time.fixedDeltaTime);
rb.MovePosition(rb.position + (Vector2)movement);
}
private void OnTriggerEnter2D(Collider2D other)
{
other.TryGetComponent<Health>(out var health);
if (other.gameObject == Owner) return;
health.TakeDamage(Damage);
Destroy(gameObject);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2d5fcee922b049d1b9db7b49711ce562
timeCreated: 1752259511

View File

@@ -0,0 +1,27 @@
using System;
using Data;
using Interfaces;
using UnityEngine;
namespace Weapons
{
public abstract class Weapon : MonoBehaviour, IWeapon
{
private float timer;
[SerializeField] private float cooldown = 1f;
[SerializeField] protected Character character;
private void Update()
{
timer -= Time.deltaTime;
if (!(timer <= 0f)) return;
Fire();
timer = 1f / character.attributes.AttackSpeed;
}
public abstract void Fire();
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a504bad3918744d7bbbf3065678bb96a
timeCreated: 1752259779