Стан Атаки
public class AttackState : State
{
string attackStateName;
bool isAttacking;
Animator animator;
Transform transform;
float range;
int damage;
LayerMask playerLayer;
public AttackState(Transform t, Animator animator, LayerMask playerLayer, string attackStateName, int damage, float range = 2.1f)
{
this.animator = animator;
this.attackStateName = attackStateName;
this.range = range;
transform = t;
this.damage = damage;
this.playerLayer = playerLayer;
}
public override void StartState()
{
isStateFinished = false;
animator.SetBool(attackStateName, true);
isAttacking = false;
}
public override void EndState()
{
animator.SetBool(attackStateName, false);
}
public override void UpdateState(float deltaTime)
{
Attack();
}
public override void StartAction()
{
isAttacking = true;
}
public override void FinishMovement()
{
isAttacking = false;
}
void Attack()
{
if (!isAttacking) return;
RaycastHit2D rayCastHit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, range, playerLayer);
if (rayCastHit)
{
if (rayCastHit.transform.TryGetComponent(out IGetAttacked getAttacked))
{
getAttacked.GetAttacked(damage);
isAttacking = false;
}
}
}
}
Пояснення до класу AttackState
Клас AttackState
— це специфічний стан, який відповідає за поведінку атаки ворога. Цей клас наслідує від класу State
і містить методи для запуску, оновлення та завершення стану атаки, а також для обробки самої дії атаки.
Визначення класу та змінні-члени
Визначення класу:
public class AttackState : State
;
Цей клас наслідує від класу State
, тобто повинен реалізовувати абстрактні методи, визначені у State
.
Змінні-члени:
string attackStateName;
Назва стану атаки, що використовується в аніматорі.
bool isAttacking;
Прапорець, який вказує, чи ворог зараз атакує.
Animator animator;
Керує анімаціями.
Transform transform;
Трансформ ворога, використовується для позиціонування та рейкастингу.
float range;
Дальність атаки.
int damage;
Шкода, що завдається атакою.
LayerMask playerLayer;
Маска шару, яка використовується для ідентифікації гравця.
Конструктор
Конструктор ініціалізує AttackState
необхідними компонентами: Transform
для позиціонування, Animator
для анімацій, маскою шару для ідентифікації гравця, назвою стану атаки, значенням шкоди та радіусом атаки. Він встановлює ці значення у відповідні змінні-члени.
Метод StartState
Цей метод встановлює isStateFinished
у значення false
, запускає анімацію атаки, встановлюючи відповідний булевий параметр в аніматорі у true
, та скидає прапорець isAttacking
у false
.
Метод EndState
Цей метод зупиняє анімацію атаки, встановлюючи відповідний булевий параметр в аніматорі у false
.
Метод UpdateState
Цей метод викликається кожного кадру та запускає метод Attack
для виконання дії атаки.
Метод StartAction
Цей метод встановлює isAttacking
у значення true
, що вказує на початок дії атаки.
Метод FinishMovement
Цей метод встановлює isAttacking
у значення false
, що вказує на завершення дії атаки.
Метод атаки
Цей метод виконує дію атаки. Якщо isAttacking
дорівнює true
, виконується кидок променя у напрямку, в якому дивиться ворог. Якщо промінь потрапляє в об'єкт на шарі playerLayer
, викликається метод GetAttacked
на цьому об'єкті, завдаючи шкоди та завершуючи дію атаки.
Чому реалізовано саме так
-
Контроль над поведінкою атаки: Прапорець
isAttacking
забезпечує точний контроль над моментом виконання атаки, роблячи поведінку більш чутливою до ігрових подій; -
Динамічне виконання атаки: Завдяки постійному оновленню стану атаки ворога,
AttackState
дозволяє ворогу точно та динамічно атакувати гравця; -
Інтеграція анімації: Використання параметрів аніматора гарантує, що анімації ворога правильно синхронізовані з його атаками, забезпечуючи плавний і реалістичний ігровий досвід.
Як це працює в контексті
Вхід у стан атаки: Коли ворог переходить у AttackState
, викликається метод StartState
, який запускає анімацію атаки та скидає прапорець isAttacking
.
Під час атаки: Метод UpdateState
викликається кожен кадр. Він викликає метод Attack
, щоб перевірити, чи потрібно виконати атаку.
Початок атаки: Метод StartAction
встановлює isAttacking
у true
, дозволяючи методу Attack
виконати дію атаки.
Виконання атаки: Метод Attack
виконує кидок променя для виявлення гравця та завдає шкоди, якщо гравець потрапляє під атаку.
Завершення атаки: Метод FinishMovement
встановлює isAttacking
у false
, зупиняючи дію атаки.
Вихід зі стану атаки: Коли ворог залишає AttackState
, викликається метод EndState
, який зупиняє анімацію атаки.
Завдяки такій структурі AttackState
ворог може виконувати чутливі та динамічні атаки на гравця з плавними переходами між анімаціями та станами.
Перехід на близьку відстань:
closeTransition = new Transition(() =>
{
return (ThresholdDistance >= Mathf.Abs(transform.position.x - player.position.x));
}, new StatePourcentage(attack2, 50f), new StatePourcentage(attack1, 50f));
stateManager.AddStateTransition(idle, closeTransition);
stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(dashState, finishRunning);
stateManager.AddStateTransition(runState, finishRunning);
stateManager.AddStateTransition(attack2, toIdleTransition);
stateManager.AddStateTransition(attack1, toIdleTransition);
closeTransition:
Цей перехід перевіряє, чи знаходиться гравець на певній горизонтальній відстані (ThresholdDistance
) від ворога.
Якщо умова виконується, відбувається випадковий перехід до attack1
або attack2
з однаковою ймовірністю (по 50%);
Приклад коду:
```csharp
closeTransition = new Transition(() =>
{
return (ThresholdDistance >= Mathf.Abs(transform.position.x - player.position.x));
}, new StatePourcentage(attack2, 50f), new StatePourcentage(attack1, 50f));
```
Додавання closeTransition до стану Idle:
stateManager.AddStateTransition(idle, closeTransition);
Цей рядок додає closeTransition
до стану idle
, дозволяючи машині станів перевіряти цю умову, коли ворог перебуває у стані очікування.
Чому ми зробили саме так
Система переходів дозволяє ворогу переходити в стан атаки залежно від близькості гравця, що підвищує залученість. Ймовірнісний підхід до вибору між різними атаками додає непередбачуваності, збільшуючи складність і цікавість гри.
Як це працює в контексті
Стан спокою:
Поки ворог перебуває у стані idle
, він постійно перевіряє, чи знаходиться гравець у межах ThresholdDistance
, використовуючи closeTransition
.
Якщо гравець достатньо близько, спрацьовує closeTransition
, і ворог переходить у стан attack1
або attack2
.
Стан атаки:
Потрапивши у стан attack1
або attack2
, ворог виконує атаку.
Після завершення атаки існуючий toIdleTransition
повертає ворога у стан idle
, щоб знову перевіряти умову closeTransition
.
Додаючи цей closeTransition
, ми забезпечуємо більш динамічну та непередбачувану взаємодію ворога з гравцем, коли гравець знаходиться на близькій відстані. Це покращує ігровий процес, роблячи поведінку ворога більш чутливою та захопливою.
Дякуємо за ваш відгук!
Запитати АІ
Запитати АІ
Запитайте про що завгодно або спробуйте одне із запропонованих запитань, щоб почати наш чат
Awesome!
Completion rate improved to 3.33
Стан Атаки
Свайпніть щоб показати меню
public class AttackState : State
{
string attackStateName;
bool isAttacking;
Animator animator;
Transform transform;
float range;
int damage;
LayerMask playerLayer;
public AttackState(Transform t, Animator animator, LayerMask playerLayer, string attackStateName, int damage, float range = 2.1f)
{
this.animator = animator;
this.attackStateName = attackStateName;
this.range = range;
transform = t;
this.damage = damage;
this.playerLayer = playerLayer;
}
public override void StartState()
{
isStateFinished = false;
animator.SetBool(attackStateName, true);
isAttacking = false;
}
public override void EndState()
{
animator.SetBool(attackStateName, false);
}
public override void UpdateState(float deltaTime)
{
Attack();
}
public override void StartAction()
{
isAttacking = true;
}
public override void FinishMovement()
{
isAttacking = false;
}
void Attack()
{
if (!isAttacking) return;
RaycastHit2D rayCastHit = Physics2D.Raycast(transform.position, Vector2.right * transform.localScale.x, range, playerLayer);
if (rayCastHit)
{
if (rayCastHit.transform.TryGetComponent(out IGetAttacked getAttacked))
{
getAttacked.GetAttacked(damage);
isAttacking = false;
}
}
}
}
Пояснення до класу AttackState
Клас AttackState
— це специфічний стан, який відповідає за поведінку атаки ворога. Цей клас наслідує від класу State
і містить методи для запуску, оновлення та завершення стану атаки, а також для обробки самої дії атаки.
Визначення класу та змінні-члени
Визначення класу:
public class AttackState : State
;
Цей клас наслідує від класу State
, тобто повинен реалізовувати абстрактні методи, визначені у State
.
Змінні-члени:
string attackStateName;
Назва стану атаки, що використовується в аніматорі.
bool isAttacking;
Прапорець, який вказує, чи ворог зараз атакує.
Animator animator;
Керує анімаціями.
Transform transform;
Трансформ ворога, використовується для позиціонування та рейкастингу.
float range;
Дальність атаки.
int damage;
Шкода, що завдається атакою.
LayerMask playerLayer;
Маска шару, яка використовується для ідентифікації гравця.
Конструктор
Конструктор ініціалізує AttackState
необхідними компонентами: Transform
для позиціонування, Animator
для анімацій, маскою шару для ідентифікації гравця, назвою стану атаки, значенням шкоди та радіусом атаки. Він встановлює ці значення у відповідні змінні-члени.
Метод StartState
Цей метод встановлює isStateFinished
у значення false
, запускає анімацію атаки, встановлюючи відповідний булевий параметр в аніматорі у true
, та скидає прапорець isAttacking
у false
.
Метод EndState
Цей метод зупиняє анімацію атаки, встановлюючи відповідний булевий параметр в аніматорі у false
.
Метод UpdateState
Цей метод викликається кожного кадру та запускає метод Attack
для виконання дії атаки.
Метод StartAction
Цей метод встановлює isAttacking
у значення true
, що вказує на початок дії атаки.
Метод FinishMovement
Цей метод встановлює isAttacking
у значення false
, що вказує на завершення дії атаки.
Метод атаки
Цей метод виконує дію атаки. Якщо isAttacking
дорівнює true
, виконується кидок променя у напрямку, в якому дивиться ворог. Якщо промінь потрапляє в об'єкт на шарі playerLayer
, викликається метод GetAttacked
на цьому об'єкті, завдаючи шкоди та завершуючи дію атаки.
Чому реалізовано саме так
-
Контроль над поведінкою атаки: Прапорець
isAttacking
забезпечує точний контроль над моментом виконання атаки, роблячи поведінку більш чутливою до ігрових подій; -
Динамічне виконання атаки: Завдяки постійному оновленню стану атаки ворога,
AttackState
дозволяє ворогу точно та динамічно атакувати гравця; -
Інтеграція анімації: Використання параметрів аніматора гарантує, що анімації ворога правильно синхронізовані з його атаками, забезпечуючи плавний і реалістичний ігровий досвід.
Як це працює в контексті
Вхід у стан атаки: Коли ворог переходить у AttackState
, викликається метод StartState
, який запускає анімацію атаки та скидає прапорець isAttacking
.
Під час атаки: Метод UpdateState
викликається кожен кадр. Він викликає метод Attack
, щоб перевірити, чи потрібно виконати атаку.
Початок атаки: Метод StartAction
встановлює isAttacking
у true
, дозволяючи методу Attack
виконати дію атаки.
Виконання атаки: Метод Attack
виконує кидок променя для виявлення гравця та завдає шкоди, якщо гравець потрапляє під атаку.
Завершення атаки: Метод FinishMovement
встановлює isAttacking
у false
, зупиняючи дію атаки.
Вихід зі стану атаки: Коли ворог залишає AttackState
, викликається метод EndState
, який зупиняє анімацію атаки.
Завдяки такій структурі AttackState
ворог може виконувати чутливі та динамічні атаки на гравця з плавними переходами між анімаціями та станами.
Перехід на близьку відстань:
closeTransition = new Transition(() =>
{
return (ThresholdDistance >= Mathf.Abs(transform.position.x - player.position.x));
}, new StatePourcentage(attack2, 50f), new StatePourcentage(attack1, 50f));
stateManager.AddStateTransition(idle, closeTransition);
stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(dashState, finishRunning);
stateManager.AddStateTransition(runState, finishRunning);
stateManager.AddStateTransition(attack2, toIdleTransition);
stateManager.AddStateTransition(attack1, toIdleTransition);
closeTransition:
Цей перехід перевіряє, чи знаходиться гравець на певній горизонтальній відстані (ThresholdDistance
) від ворога.
Якщо умова виконується, відбувається випадковий перехід до attack1
або attack2
з однаковою ймовірністю (по 50%);
Приклад коду:
```csharp
closeTransition = new Transition(() =>
{
return (ThresholdDistance >= Mathf.Abs(transform.position.x - player.position.x));
}, new StatePourcentage(attack2, 50f), new StatePourcentage(attack1, 50f));
```
Додавання closeTransition до стану Idle:
stateManager.AddStateTransition(idle, closeTransition);
Цей рядок додає closeTransition
до стану idle
, дозволяючи машині станів перевіряти цю умову, коли ворог перебуває у стані очікування.
Чому ми зробили саме так
Система переходів дозволяє ворогу переходити в стан атаки залежно від близькості гравця, що підвищує залученість. Ймовірнісний підхід до вибору між різними атаками додає непередбачуваності, збільшуючи складність і цікавість гри.
Як це працює в контексті
Стан спокою:
Поки ворог перебуває у стані idle
, він постійно перевіряє, чи знаходиться гравець у межах ThresholdDistance
, використовуючи closeTransition
.
Якщо гравець достатньо близько, спрацьовує closeTransition
, і ворог переходить у стан attack1
або attack2
.
Стан атаки:
Потрапивши у стан attack1
або attack2
, ворог виконує атаку.
Після завершення атаки існуючий toIdleTransition
повертає ворога у стан idle
, щоб знову перевіряти умову closeTransition
.
Додаючи цей closeTransition
, ми забезпечуємо більш динамічну та непередбачувану взаємодію ворога з гравцем, коли гравець знаходиться на близькій відстані. Це покращує ігровий процес, роблячи поведінку ворога більш чутливою та захопливою.
Дякуємо за ваш відгук!