Adds knight on horse and its animations #8

Merged
Garutako merged 16 commits from art/knightOnHorse into main 2025-07-14 22:58:23 +00:00
7 changed files with 99 additions and 59 deletions
Showing only changes of commit 2a2f3bf040 - Show all commits

View File

@ -67,7 +67,7 @@ AnimatorStateTransition:
m_TransitionDuration: 0.25 m_TransitionDuration: 0.25
m_TransitionOffset: 0 m_TransitionOffset: 0
m_ExitTime: 0.875 m_ExitTime: 0.875
m_HasExitTime: 1 m_HasExitTime: 0
m_HasFixedDuration: 1 m_HasFixedDuration: 1
m_InterruptionSource: 0 m_InterruptionSource: 0
m_OrderedInterruption: 1 m_OrderedInterruption: 1

View File

@ -1235,7 +1235,7 @@ Transform:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 3062706309015911873} m_GameObject: {fileID: 3062706309015911873}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: 2.52, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
@ -1255,7 +1255,7 @@ BoxCollider2D:
m_IsTrigger: 1 m_IsTrigger: 1
m_UsedByEffector: 0 m_UsedByEffector: 0
m_UsedByComposite: 0 m_UsedByComposite: 0
m_Offset: {x: 1.7083191, y: 0} m_Offset: {x: -0.1805121, y: 0}
m_SpriteTilingProperty: m_SpriteTilingProperty:
border: {x: 0, y: 0, z: 0, w: 0} border: {x: 0, y: 0, z: 0, w: 0}
pivot: {x: 0, y: 0} pivot: {x: 0, y: 0}
@ -1266,7 +1266,7 @@ BoxCollider2D:
adaptiveTiling: 0 adaptiveTiling: 0
m_AutoTiling: 0 m_AutoTiling: 0
serializedVersion: 2 serializedVersion: 2
m_Size: {x: 0.5, y: 0.5} m_Size: {x: 0.6224893, y: 0.5}
m_EdgeRadius: 0 m_EdgeRadius: 0
--- !u!114 &5850107427616902080 --- !u!114 &5850107427616902080
MonoBehaviour: MonoBehaviour:
@ -2776,7 +2776,7 @@ Transform:
m_PrefabAsset: {fileID: 0} m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 9048754633958631738} m_GameObject: {fileID: 9048754633958631738}
m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalPosition: {x: -0.33, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1} m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0 m_ConstrainProportionsScale: 0
m_Children: [] m_Children: []
@ -2796,7 +2796,7 @@ BoxCollider2D:
m_IsTrigger: 1 m_IsTrigger: 1
m_UsedByEffector: 0 m_UsedByEffector: 0
m_UsedByComposite: 0 m_UsedByComposite: 0
m_Offset: {x: 1, y: 0} m_Offset: {x: 1.33, y: 0}
m_SpriteTilingProperty: m_SpriteTilingProperty:
border: {x: 0, y: 0, z: 0, w: 0} border: {x: 0, y: 0, z: 0, w: 0}
pivot: {x: 0, y: 0} pivot: {x: 0, y: 0}

View File

@ -19,9 +19,10 @@ public class Rider : Ally
[SerializeField] [SerializeField]
private GameObject _root; private GameObject _root;
private Detection _chargeDetectionScript;
private Root _rootScript; private Root _rootScript;
private Detection _detectionScript;
private int _originalAttackDamage;
private Vector3 _originalPos; private Vector3 _originalPos;
private Vector2 _movementVector = Vector2.zero; private Vector2 _movementVector = Vector2.zero;
private bool _isCharging; private bool _isCharging;
@ -32,33 +33,37 @@ public class Rider : Ally
{ {
base.Start(); base.Start();
_chargeDetectionScript = _chargeDetection.GetComponent<Detection>();
_rootScript = _root.GetComponent<Root>(); _rootScript = _root.GetComponent<Root>();
_detectionScript = _detection.GetComponent<Detection>();
_originalAttackDamage = _chargeAttackDamage;
_originalPos = transform.position; _originalPos = transform.position;
_isCharging = true;
_timeSinceLastCharge = _chargeCooldown + 1;
} }
public override void Update() public override void Update()
{ {
// check for charge cooldown // check for charge cooldown
if (_timeSinceLastCharge > _chargeCooldown) if (_timeSinceLastCharge > _chargeCooldown && !_isCharging)
{ {
SweepAttack();
_isCharging = true; _isCharging = true;
Animation.ToggleChargeAnim(true);
} }
if (_isCharging) if (_isCharging)
{ {
SweepAttack();
// toggle charge detection // toggle charge detection
_detection.SetActive(false);
_chargeDetection.SetActive(true); _chargeDetection.SetActive(true);
// movement // movement
_movementVector.x = Time.deltaTime * Speed; _movementVector.x = Time.deltaTime * Speed;
transform.position += (Vector3)_movementVector; transform.position += (Vector3)_movementVector;
Debug.Log(IsEnemyDetected);
// attack // attack
if (IsEnemyDetected && !_opponentsHit.Contains(Enemy)) if (IsEnemyDetected && !_opponentsHit.Contains(Enemy))
{ {
@ -76,11 +81,14 @@ public class Rider : Ally
_isCharging = false; _isCharging = false;
_timeSinceLastCharge = 0; _timeSinceLastCharge = 0;
_opponentsHit.Clear(); _opponentsHit.Clear();
// detection state // detection state
IsEnemyDetected = false; IsEnemyDetected = false;
Enemy = null; Enemy = null;
// toggle animation
Animation.ToggleChargeAnim(false);
// toggle detection // toggle detection
_detection.SetActive(true); _detection.SetActive(true);
_chargeDetection.SetActive(false); _chargeDetection.SetActive(false);
@ -96,21 +104,39 @@ public class Rider : Ally
} }
} }
void AttackEnemyRiding() // attacks all enemies already in the default detection box at start of the charge.
// charge uses a different detection due to Enemy being the oldest opponent to enter the hitbox.
// therefore enemies would only get hit when the previous Enemy exits, which is at the handle instead of the tip`.
// to cover for the enemies behind the charge detection which is at the tip, we hit them all as the charge starts
private void SweepAttack()
{ {
Debug.Log("Attack Riding"); foreach (Entity entity in _detectionScript.DetectedEntities)
_rootScript.AttackWithCustomDamage(_chargeAttackDamage); {
Enemy = entity;
AttackEnemyRiding();
}
if (_detectionScript.DetectedEntities.Count > 0)
{
_detection.SetActive(false);
}
}
private void AttackEnemyRiding()
{
AttackDamage = _chargeAttackDamage;
_rootScript.Attack();
_opponentsHit.Add(Enemy); _opponentsHit.Add(Enemy);
} }
void AttackEnemy() private void AttackEnemy()
{ {
//Attack Cooldown //Attack Cooldown
if (AttackSpeedWait > AttackInterval) if (AttackSpeedWait > AttackInterval)
{ {
AttackDamage = _originalAttackDamage;
Animation.PlayAttackAnim(); Animation.PlayAttackAnim();
AttackSpeedWait = 0f; AttackSpeedWait = 0f;
} }

View File

@ -4,12 +4,13 @@ using UnityEngine;
public class AnimationEntity : MonoBehaviour public class AnimationEntity : MonoBehaviour
{ {
enum EntityAnimationState enum EntityAnimationState
{ {
Idle = 0, Idle = 0,
Walking = 1, Walking = 1,
Attacking = 2, Attacking = 2,
Dying = 3 Dying = 3,
Charging = 4
} }
private EntityAnimationState entityState; private EntityAnimationState entityState;
@ -17,15 +18,15 @@ public class AnimationEntity : MonoBehaviour
private bool _doSomething = false; private bool _doSomething = false;
private bool _isDead = false; private bool _isDead = false;
private bool _isWalking = false; private bool _isWalking = false;
void Start() void Start()
{ {
AttackSpeedMultiplier = 10; AttackSpeedMultiplier = 10;
SpeedMultiplier = 10; SpeedMultiplier = 10;
_animatorEntity = GetComponentInChildren<Animator>(); _animatorEntity = GetComponentInChildren<Animator>();
} }
void Update() void Update()
{ {
if (!_animatorEntity) return; if (!_animatorEntity) return;
if (_doSomething && _animatorEntity.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1f) if (_doSomething && _animatorEntity.GetCurrentAnimatorStateInfo(0).normalizedTime >= 1f)
@ -47,18 +48,20 @@ public class AnimationEntity : MonoBehaviour
}; };
} }
public void PlayIdleAnim() public void PlayIdleAnim()
{ {
if(!_isDead) { if (!_isDead)
{
_animatorEntity.speed = 1; _animatorEntity.speed = 1;
_animatorEntity.Play("idle", 0, 0f); _animatorEntity.Play("idle", 0, 0f);
entityState = EntityAnimationState.Idle; entityState = EntityAnimationState.Idle;
} }
} }
public void PlayWalkAnim() public void PlayWalkAnim()
{ {
if(!_isDead) { if (!_isDead)
{
_animatorEntity.speed = SpeedMultiplier; _animatorEntity.speed = SpeedMultiplier;
_animatorEntity.Play("walk", 0, 0f); _animatorEntity.Play("walk", 0, 0f);
entityState = EntityAnimationState.Walking; entityState = EntityAnimationState.Walking;
@ -66,9 +69,10 @@ public class AnimationEntity : MonoBehaviour
} }
} }
public void PlayAttackAnim() public void PlayAttackAnim()
{ {
if(!_isDead && _animatorEntity != null) { if (!_isDead && _animatorEntity != null)
{
_animatorEntity.speed = AttackSpeedMultiplier; _animatorEntity.speed = AttackSpeedMultiplier;
_animatorEntity.Play("attack", 0, 0f); _animatorEntity.Play("attack", 0, 0f);
entityState = EntityAnimationState.Attacking; entityState = EntityAnimationState.Attacking;
@ -76,7 +80,24 @@ public class AnimationEntity : MonoBehaviour
} }
} }
public void PlayDieAnim() public void ToggleChargeAnim(bool isCharging)
{
if (!_isDead && _animatorEntity != null)
{
_animatorEntity.speed = AttackSpeedMultiplier;
_animatorEntity.SetBool("Charging", isCharging);
if (isCharging)
{
entityState = EntityAnimationState.Charging;
}
else
{
PlayIdleAnim();
}
}
}
public void PlayDieAnim()
{ {
// Not every entity needs an animator // Not every entity needs an animator
if (_animatorEntity != null) if (_animatorEntity != null)
@ -84,7 +105,7 @@ public class AnimationEntity : MonoBehaviour
_animatorEntity.speed = 1; _animatorEntity.speed = 1;
_animatorEntity.Play("die", 0, 0f); _animatorEntity.Play("die", 0, 0f);
} }
entityState = EntityAnimationState.Dying; entityState = EntityAnimationState.Dying;
_doSomething = true; _doSomething = true;
_isDead = true; _isDead = true;

View File

@ -178,4 +178,5 @@ public class Detection : MonoBehaviour
return rect; return rect;
} }
} }
public List<Entity> DetectedEntities { get { return detectedEntities; } }
} }

View File

@ -20,7 +20,7 @@ public abstract class Entity : LevelObject
private float _attack_speed_wait = 0f; private float _attack_speed_wait = 0f;
private AnimationEntity _animation; private AnimationEntity _animation;
private Shader _shaderGUItext; private Shader _shaderGUItext;
private Shader _shaderSpritesDefault; private Shader _shaderSpritesDefault;
private SpriteRenderer[] _spriteRenderers; private SpriteRenderer[] _spriteRenderers;
private AudioPlayerComponent _audioPlayerComponent; private AudioPlayerComponent _audioPlayerComponent;
@ -45,41 +45,41 @@ public abstract class Entity : LevelObject
_lifeBar.gameObject.SetActive(_lifeBar.value <= 0.99f); _lifeBar.gameObject.SetActive(_lifeBar.value <= 0.99f);
} }
//Start the animation of death and the fading of the entity //Start the animation of death and the fading of the entity
public virtual void Death() public virtual void Death()
{ {
_animation.PlayDieAnim(); _animation.PlayDieAnim();
Invoke("Dying", 0.1f); Invoke("Dying", 0.1f);
} }
//Recursive method that fade the dying entity //Recursive method that fade the dying entity
private void Dying() private void Dying()
{ {
foreach (SpriteRenderer renderer in _spriteRenderers) foreach (SpriteRenderer renderer in _spriteRenderers)
{ {
Color currentColor = renderer.color; Color currentColor = renderer.color;
currentColor.a = currentColor.a - 0.1f; currentColor.a = currentColor.a - 0.1f;
renderer.color = currentColor; renderer.color = currentColor;
} }
if(_spriteRenderers[0].color.a > 0f) if (_spriteRenderers[0].color.a > 0f)
{ {
Invoke("Dying", 0.1f); Invoke("Dying", 0.1f);
} }
else else
{ {
Destroy(gameObject); Destroy(gameObject);
} }
} }
//When hit : get damage and start a flash of light //When hit : get damage and start a flash of light
public void Hit(int damage) public void Hit(int damage)
{ {
_hp-=damage; _hp -= damage;
_lifeBar.value = _hp / (float)_maxHp; _lifeBar.value = _hp / (float)_maxHp;
_shaderGUItext = Shader.Find("GUI/Text Shader"); _shaderGUItext = Shader.Find("GUI/Text Shader");
_shaderSpritesDefault = Shader.Find("Sprites/Default"); _shaderSpritesDefault = Shader.Find("Sprites/Default");
foreach (SpriteRenderer renderer in _spriteRenderers) foreach (SpriteRenderer renderer in _spriteRenderers)
@ -90,7 +90,7 @@ public abstract class Entity : LevelObject
} }
//End the flash of light from the method above //End the flash of light from the method above
private void ReturnNormalColor() private void ReturnNormalColor()
{ {
foreach (SpriteRenderer renderer in _spriteRenderers) foreach (SpriteRenderer renderer in _spriteRenderers)
{ {
@ -98,15 +98,15 @@ public abstract class Entity : LevelObject
} }
} }
public void Move() public void Move()
{ {
if(!_animation.IsWalking) if (!_animation.IsWalking)
{ {
_animation.PlayWalkAnim(); _animation.PlayWalkAnim();
} }
} }
public void PlaySound(string soundName, float volumeMultiplier = 1f, float overrideVolume = -1f) public void PlaySound(string soundName, float volumeMultiplier = 1f, float overrideVolume = -1f)
{ {
_audioPlayerComponent.PlaySound(soundName, volumeMultiplier, overrideVolume); _audioPlayerComponent.PlaySound(soundName, volumeMultiplier, overrideVolume);
} }
@ -123,7 +123,11 @@ public abstract class Entity : LevelObject
public float Speed => _speed * SpeedMultiplier; public float Speed => _speed * SpeedMultiplier;
public int AttackDamage => (int)(_attack_damage * DamageMultiplier); public int AttackDamage
{
get { return (int)(_attack_damage * DamageMultiplier); }
set { _attack_damage = value; }
}
public float AttackInterval => _attack_interval / AttackSpeedMultiplier; public float AttackInterval => _attack_interval / AttackSpeedMultiplier;

View File

@ -24,18 +24,6 @@ public class Root : MonoBehaviour
} }
} }
public void AttackWithCustomDamage(int damage)
{
if (_entity == null || _entity.Enemy == null) return;
_entity.Enemy.Hit(damage);
if (_entity.Enemy.Hp <= 0)
{
_entity.Enemy.Death();
_entity.IsEnemyDetected = false;
}
}
public void ShotProjectile() public void ShotProjectile()
{ {
Rigidbody2D _rigidbodyAlly; Rigidbody2D _rigidbodyAlly;