Platformer level management
This commit is contained in:
1 parent
72070901ec
commit
1aceea1b79
94 files changed
+3656
-197
No files matched your search
@@ -1,4 +1,8 @@
|
||||
using System;
|
||||
using Code.Infrastructure.Audio;
|
||||
using Code.Infrastructure.Configs;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Reflex.Attributes;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Code.Example.Platformer.Entity.Enemies
|
||||
@@ -11,11 +15,42 @@ namespace Code.Example.Platformer.Entity.Enemies
|
||||
|
||||
private float _acceleration = 3f;
|
||||
|
||||
[SerializeField] private EntityHealth health;
|
||||
|
||||
[Inject] private IAudioService _audioService;
|
||||
private void Start()
|
||||
{
|
||||
health.OnEntityDamage = OnEntityDamage;
|
||||
health.OnEntityDeath = OnEntityDeath;
|
||||
}
|
||||
|
||||
private void OnEntityDeath()
|
||||
{
|
||||
animator.SetBool(Died, true);
|
||||
animator.SetTrigger(OnDeath);
|
||||
Die().Forget();
|
||||
}
|
||||
|
||||
private async UniTaskVoid Die()
|
||||
{
|
||||
await UniTask.WaitForSeconds(1);
|
||||
_audioService.PlayOneShot(AudioNames.Platformer, 3 );
|
||||
Destroy(gameObject);
|
||||
}
|
||||
private void OnEntityDamage(int obj)
|
||||
{
|
||||
_audioService.PlayOneShot(AudioNames.Platformer, 2);
|
||||
UnityEngine.Debug.Log(gameObject.name + " damaged");
|
||||
animator.SetTrigger(OnHit);
|
||||
}
|
||||
|
||||
protected override void Move()
|
||||
{
|
||||
if (health.IsDead) return;
|
||||
if (_target)
|
||||
{
|
||||
_directionRight = ((_target.position - transform.position)).x > float.Epsilon;
|
||||
TryAttack();
|
||||
_directionRight = (_target.position - transform.position).x > float.Epsilon;
|
||||
UnityEngine.Debug.DrawLine(transform.position, (transform.position + (_target.position - transform.position)), Color.salmon);
|
||||
|
||||
CheckupDirection();
|
||||
@@ -30,7 +65,7 @@ namespace Code.Example.Platformer.Entity.Enemies
|
||||
rigidbody2D.linearVelocityX = _directionRight ? 0.5f : -0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void HandleFlipX() => spriteRenderer.flipX = rigidbody2D.linearVelocity.x > -0.01f;
|
||||
|
||||
private void CheckupDirection()
|
||||
@@ -45,9 +80,15 @@ namespace Code.Example.Platformer.Entity.Enemies
|
||||
LayerMasks.Masks[LayerMaskType.PlatformerGround]))
|
||||
_directionRight = true;
|
||||
}
|
||||
|
||||
private void TryAttack()
|
||||
{
|
||||
if ((transform.position - _target.position).magnitude < attackThreshold) _target.GetComponent<EntityHealth>().GiveDamage(1);
|
||||
}
|
||||
|
||||
private Transform _target;
|
||||
|
||||
private float attackThreshold = 0.5f;
|
||||
|
||||
public void GotTarget(Transform target)
|
||||
{
|
||||
_target = target;
|
||||
|
||||
@@ -5,26 +5,42 @@ namespace Code.Example.Platformer.Entity
|
||||
{
|
||||
public abstract class Entity : MonoBehaviour
|
||||
{
|
||||
private static readonly int VelocityY = Animator.StringToHash("VelocityY");
|
||||
private static readonly int VelocityX = Animator.StringToHash("VelocityX");
|
||||
private static readonly int OnGround = Animator.StringToHash("OnGround");
|
||||
protected static readonly int VelocityY = Animator.StringToHash("VelocityY");
|
||||
protected static readonly int VelocityX = Animator.StringToHash("VelocityX");
|
||||
protected static readonly int OnGround = Animator.StringToHash("OnGround");
|
||||
protected static readonly int OnHit = Animator.StringToHash("OnHit");
|
||||
protected static readonly int OnDeath = Animator.StringToHash("OnDeath");
|
||||
protected static readonly int Died = Animator.StringToHash("Died");
|
||||
|
||||
[SerializeField] protected Rigidbody2D rigidbody2D;
|
||||
[SerializeField] protected Animator animator;
|
||||
[SerializeField] protected SpriteRenderer spriteRenderer;
|
||||
[SerializeField] private Vector2 groundPoint;
|
||||
|
||||
private PlatformerEntityData _data;
|
||||
|
||||
private PlatformerEntityData _data; // TODO
|
||||
protected bool isFreezed;
|
||||
protected bool onGround;
|
||||
public void SetData(PlatformerEntityData data)
|
||||
{
|
||||
_data = data;
|
||||
}
|
||||
|
||||
protected bool onGround;
|
||||
public void Freeze()
|
||||
{
|
||||
rigidbody2D.bodyType = RigidbodyType2D.Kinematic;
|
||||
isFreezed = true;
|
||||
}
|
||||
public void UnFreeze()
|
||||
{
|
||||
rigidbody2D.bodyType = RigidbodyType2D.Dynamic;
|
||||
isFreezed = false;
|
||||
}
|
||||
|
||||
|
||||
protected virtual void Update()
|
||||
{
|
||||
if(isFreezed) return;
|
||||
|
||||
animator.SetFloat(VelocityX, rigidbody2D.linearVelocityX);
|
||||
animator.SetFloat(VelocityY, rigidbody2D.linearVelocityY);
|
||||
}
|
||||
@@ -33,6 +49,8 @@ namespace Code.Example.Platformer.Entity
|
||||
|
||||
protected virtual void FixedUpdate()
|
||||
{
|
||||
if(isFreezed) return;
|
||||
|
||||
onGround = CheckGround();
|
||||
animator.SetBool(OnGround, onGround);
|
||||
|
||||
@@ -48,8 +66,5 @@ namespace Code.Example.Platformer.Entity
|
||||
}
|
||||
|
||||
protected abstract void Move();
|
||||
|
||||
public virtual void OnGetDamage(){}
|
||||
public virtual void OnDeath(){}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using Code.Infrastructure.EventBus;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Reflex.Attributes;
|
||||
using UnityEngine;
|
||||
|
||||
@@ -8,19 +10,47 @@ namespace Code.Example.Platformer.Entity
|
||||
{
|
||||
private int _health;
|
||||
private int _maxHealth;
|
||||
public void SetMaxHealth(int maxHealth) => _maxHealth = maxHealth;
|
||||
private float _damageThreshold;
|
||||
|
||||
public void Setup(int maxHealth, float damageThreshold)
|
||||
{
|
||||
_maxHealth = maxHealth;
|
||||
_health = maxHealth;
|
||||
_damageThreshold = damageThreshold;
|
||||
}
|
||||
|
||||
public bool IsDead { get; private set; }
|
||||
private bool _isDamageable = true;
|
||||
|
||||
[Inject] private EventBus _eventBus;
|
||||
[SerializeField] private Entity entity;
|
||||
|
||||
[Inject] private EventBus _eventBus;
|
||||
|
||||
public Action<int> OnEntityHeal;
|
||||
public Action<int> OnEntityDamage;
|
||||
public Action OnEntityDeath;
|
||||
|
||||
private async UniTaskVoid WaitThreshold()
|
||||
{
|
||||
await UniTask.WaitForSeconds(_damageThreshold);
|
||||
_isDamageable = true;
|
||||
}
|
||||
public void GiveDamage(int damage)
|
||||
{
|
||||
if (!_isDamageable) return;
|
||||
|
||||
_health -= damage;
|
||||
|
||||
if(_health <= 0) IsDead = true;
|
||||
_isDamageable = false;
|
||||
OnEntityDamage?.Invoke(_health);
|
||||
|
||||
if(_health <= 0)
|
||||
{
|
||||
IsDead = true;
|
||||
OnEntityDeath?.Invoke();
|
||||
}
|
||||
|
||||
_eventBus.RaiseEvent<IEntityDamagedHandler>(x=> x.EntityDamaged(gameObject, damage, IsDead));
|
||||
|
||||
WaitThreshold().Forget();
|
||||
}
|
||||
|
||||
public void Heal(int heal)
|
||||
@@ -29,6 +59,8 @@ namespace Code.Example.Platformer.Entity
|
||||
if (_health + heal > _maxHealth) _health = _maxHealth;
|
||||
else _health += heal;
|
||||
|
||||
OnEntityHeal?.Invoke(_health);
|
||||
|
||||
_eventBus.RaiseEvent<IEntityHealedHandler>(x=> x.EntityHealed(gameObject, heal));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,9 +4,12 @@ using System.Linq;
|
||||
using Code.Infrastructure.Configs;
|
||||
using Code.Infrastructure.EventBus;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Reflex.Core;
|
||||
using Reflex.Injectors;
|
||||
using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Code.Example.Platformer.Entity
|
||||
{
|
||||
@@ -15,7 +18,7 @@ namespace Code.Example.Platformer.Entity
|
||||
UniTaskVoid WarmEnemy(PlatformerEntityType enemyType);
|
||||
void ReleaseEnemy(PlatformerEntityType racerType);
|
||||
|
||||
UniTaskVoid SpawnEnemy(
|
||||
void SpawnEnemy(
|
||||
PlatformerEntityType enemyType,
|
||||
Vector3 position);
|
||||
}
|
||||
@@ -67,10 +70,6 @@ namespace Code.Example.Platformer.Entity
|
||||
await _enemyPrefabsHandle[enemyType].ToUniTask();
|
||||
|
||||
var entity = _enemyPrefabsHandle[enemyType].Result.GetComponent<Entity>();
|
||||
entity.SetData(_enemyConfigs[enemyType].EntityData);
|
||||
|
||||
var health = _enemyPrefabsHandle[enemyType].Result.GetComponent<EntityHealth>();
|
||||
health.SetMaxHealth(_enemyConfigs[enemyType].EntityData.maxHealth);
|
||||
|
||||
_eventBus.RaiseEvent<IPlatformerEnemyLoadedHandle>(x => x.PlatformerEnemyLoaded(enemyType, entity));
|
||||
}
|
||||
@@ -81,13 +80,21 @@ namespace Code.Example.Platformer.Entity
|
||||
_enemyPrefabsHandle.Remove(racerType);
|
||||
}
|
||||
|
||||
public async UniTaskVoid SpawnEnemy(
|
||||
public void SpawnEnemy(
|
||||
PlatformerEntityType enemyType,
|
||||
Vector3 position)
|
||||
{
|
||||
if (enemyType == PlatformerEntityType.Player) return;
|
||||
|
||||
await Addressables.InstantiateAsync(_enemyConfigs[enemyType].prefabReference, position, Quaternion.identity);
|
||||
var gameObject = Object.Instantiate(_enemyPrefabsHandle[enemyType].Result, position, Quaternion.identity);
|
||||
|
||||
var entity = gameObject.GetComponent<Entity>();
|
||||
entity.SetData(_enemyConfigs[enemyType].EntityData);
|
||||
|
||||
var health = gameObject.GetComponent<EntityHealth>();
|
||||
health.Setup(_enemyConfigs[enemyType].EntityData.maxHealth, _enemyConfigs[enemyType].EntityData.damageRecieveThreshold);
|
||||
|
||||
GameObjectInjector.InjectObject(gameObject, Container.RootContainer);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using Code.Infrastructure.Generators;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace Code.Example.Platformer.Entity
|
||||
{
|
||||
@@ -14,6 +15,7 @@ namespace Code.Example.Platformer.Entity
|
||||
public int damage;
|
||||
public PlatformerEntityType type;
|
||||
public int maxHealth;
|
||||
public float damageRecieveThreshold;
|
||||
}
|
||||
|
||||
public enum PlatformerEntityType
|
||||
|
||||
@@ -10,15 +10,16 @@ using UnityEngine;
|
||||
using UnityEngine.AddressableAssets;
|
||||
using UnityEngine.ResourceManagement.AsyncOperations;
|
||||
using UnityEngine.SceneManagement;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace Code.Example.Platformer.Entity
|
||||
{
|
||||
public interface IPlatformerPlayerFactory
|
||||
{
|
||||
UniTaskVoid LoadPlayer();
|
||||
UniTaskVoid WarmPlayer();
|
||||
void ReleasePlayer();
|
||||
|
||||
UniTaskVoid SpawnPlayer(Vector3 position);
|
||||
void SpawnPlayer(Vector3 position);
|
||||
}
|
||||
|
||||
public class PlatformerPlayerFactory : IPlatformerPlayerFactory, IDisposable
|
||||
@@ -50,7 +51,7 @@ namespace Code.Example.Platformer.Entity
|
||||
_eventBus.RaiseEvent<IPlatformerPlayerFactoryInitializedHandle>(x => x.PlatformerPlayerFactoryInitialized());
|
||||
}
|
||||
|
||||
public async UniTaskVoid LoadPlayer()
|
||||
public async UniTaskVoid WarmPlayer()
|
||||
{
|
||||
if (_playerPrefabHandle.IsValid())
|
||||
{
|
||||
@@ -63,8 +64,6 @@ namespace Code.Example.Platformer.Entity
|
||||
_playerPrefabHandle = Addressables.LoadAssetAsync<GameObject>(_playerConfig.prefabReference);
|
||||
|
||||
await _playerPrefabHandle.ToUniTask();
|
||||
var racer = _playerPrefabHandle.Result.GetComponent<Entity>();
|
||||
racer.SetData(_playerConfig.EntityData);
|
||||
|
||||
_eventBus.RaiseEvent<IPlatformerPlayerLoadedHandle>(x => x.PlatformerPlayerLoaded());
|
||||
}
|
||||
@@ -74,11 +73,20 @@ namespace Code.Example.Platformer.Entity
|
||||
_playerPrefabHandle.Release();
|
||||
}
|
||||
|
||||
public async UniTaskVoid SpawnPlayer(Vector3 position)
|
||||
public void SpawnPlayer(Vector3 position)
|
||||
{
|
||||
var player = await Addressables.InstantiateAsync(_playerConfig.prefabReference, position, Quaternion.identity).ToUniTask();
|
||||
var player = Object.Instantiate(_playerPrefabHandle.Result, position, Quaternion.identity);
|
||||
|
||||
var racer = player.GetComponent<Entity>();
|
||||
racer.SetData(_playerConfig.EntityData);
|
||||
|
||||
var health = player.GetComponent<EntityHealth>();
|
||||
health.Setup(_playerConfig.EntityData.maxHealth, _playerConfig.EntityData.damageRecieveThreshold);
|
||||
|
||||
GameObjectInjector.InjectObject(player, Container.RootContainer); // TODO САМОЕ НЕСТАБИЛЬНОЕ ДЕРЬМО ВО ВСЕЛЕННОЙ КОНТЕЙНЕР ДОЛЖЕН БЫТЬ КОНТЕКСТНЫМ
|
||||
_eventBus.RaiseEvent<IPlatformerPlayerSpawnedHandle>(x => x.PlatformerPlayerSpawned(player.GetComponent<Entity>()));
|
||||
|
||||
_eventBus.RaiseEvent<IPlatformerPlayerSpawnedHandle>(
|
||||
x => x.PlatformerPlayerSpawned(player.GetComponent<Entity>()));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Code.Infrastructure.Audio;
|
||||
using Code.Infrastructure.Camera;
|
||||
using Code.Infrastructure.Configs;
|
||||
@@ -32,6 +33,11 @@ namespace Code.Example.Platformer.Entity
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if(!health.IsDead) UnbindControls();
|
||||
}
|
||||
|
||||
private void UnbindControls()
|
||||
{
|
||||
_inputService.UnbindActionPerformed((int)ActionMappings.Platformer, (int)PlatformerActions.Move,
|
||||
MovementPerformed);
|
||||
@@ -65,6 +71,8 @@ namespace Code.Example.Platformer.Entity
|
||||
rigidbody2D.AddForceY(100f);
|
||||
|
||||
_acceleration = 1f;
|
||||
|
||||
_audioService.PlayOneShot(AudioNames.Platformer, 6);
|
||||
}
|
||||
|
||||
[SerializeField] private Vector2 attackOffset;
|
||||
@@ -75,7 +83,7 @@ namespace Code.Example.Platformer.Entity
|
||||
//
|
||||
|
||||
//
|
||||
_audioService.PlayOneShot(AudioNames.UISounds, 1);
|
||||
_audioService.PlayOneShot(AudioNames.Platformer, 1);
|
||||
animator.SetBool(OnAttack, true);
|
||||
}
|
||||
|
||||
@@ -89,7 +97,6 @@ namespace Code.Example.Platformer.Entity
|
||||
foreach (var damaged in damagedOnes)
|
||||
{
|
||||
damaged.gameObject.GetComponent<EntityHealth>().GiveDamage(1);
|
||||
_audioService.PlayOneShot(AudioNames.UISounds, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,5 +112,28 @@ namespace Code.Example.Platformer.Entity
|
||||
}
|
||||
|
||||
public void AttackEnd() => animator.SetBool(OnAttack, false);
|
||||
|
||||
[SerializeField] private EntityHealth health;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
health.OnEntityDeath = OnEntityDeath;
|
||||
health.OnEntityDamage = OnEntityDamage;
|
||||
}
|
||||
|
||||
private void OnEntityDamage(int obj)
|
||||
{
|
||||
UnityEngine.Debug.Log("Player damaged");
|
||||
}
|
||||
|
||||
private void OnEntityDeath()
|
||||
{
|
||||
_moveDirection = Vector2.zero;
|
||||
|
||||
animator.SetBool(Died, true);
|
||||
|
||||
UnbindControls();
|
||||
// Destroy(gameObject, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user