This shows you the differences between two versions of the page.
pjv:laboratoare:2024:a02 [2024/10/21 11:56] andrei.lapusteanu Added events documentation |
pjv:laboratoare:2024:a02 [2024/10/23 08:45] (current) maria_anca.balutoiu [Sisteme de evenimente] |
||
---|---|---|---|
Line 47: | Line 47: | ||
* Inamicii realizeaza actiuni random | * Inamicii realizeaza actiuni random | ||
- | Pentru simplitate, toate interactiunile se pot realiza prin butoane de comanda. | + | Pentru simplitate, toate interactiunile se pot realiza prin butoane de comanda, dar este necesar sa folositi un sistem de evenimente pentru decuplarea responsabilitatilor (la alegere). |
Bonusuri: | Bonusuri: | ||
Line 75: | Line 75: | ||
=== Gestiune harta === | === Gestiune harta === | ||
+ | |||
+ | Desi se poate gestiona o harta turn based si fara un sistem grid, cele mai adesea se folosesc sisteme grid de tip matrice sau hexagonal, ca si in imaginile exemplificate mai sus. | ||
+ | |||
+ | Daca in cazul unui sistem de tip matrice reprezentarea in memorie este simpla, folosind direct o matrice, in cazul unui sistem hexagonal, lucrurile sunt ceva mai complicate. | ||
+ | |||
+ | Cateva resurse in acest sens: | ||
+ | * [[https://www.redblobgames.com/grids/parts/]] | ||
=== Gestiune personaje === | === Gestiune personaje === | ||
+ | |||
+ | Pentru gestiunea personajelor sunt importante 3 elemente: | ||
+ | * gestiunea pe harta: miscare, constrangeri, efecte, pozitionare, pathfinding etc | ||
+ | * gestiunea prin interfata grafica: abilitati, skilltree, actiuni etc | ||
+ | * gestiunea in memorie | ||
+ | |||
+ | |||
+ | Intrucat sunt foarte multe elemente de gestionat, recomandarea este sa se incerce o decuplare a acestor componente, din punct de vedere logic. | ||
+ | |||
+ | Pentru selectia personajelor cel mai adesea se folosesc RayCast-uri. | ||
+ | Pentru selectie multipla (mai multe personaje/unitati odata) o varianta poate fi: | ||
+ | * Obține raycast a poziției în care jucătorul a început să tragă | ||
+ | * Obțineți raycast a poziției în care jucătorul a terminat de tras | ||
+ | * Din aceste două Vector3 puteți construi un cub 3D. | ||
+ | * Tratați-l ca pe un plan 2D (adică ignorați înălțimea cubului); | ||
+ | * Pentru fiecare unitate: dacă unitatea se află în planul 2D, selectați-o. | ||
=== Gestiune comenzi === | === Gestiune comenzi === | ||
Line 111: | Line 134: | ||
Clasa CommandInvoker este apoi responsabilă pentru executarea și anularea comenzilor. În plus față de metodele ExecuteCommand și UndoCommand, are o stivă de anulare pentru a păstra secvența de obiecte de comandă. | Clasa CommandInvoker este apoi responsabilă pentru executarea și anularea comenzilor. În plus față de metodele ExecuteCommand și UndoCommand, are o stivă de anulare pentru a păstra secvența de obiecte de comandă. | ||
+ | |||
+ | O opțiune simplă pentru a schimba poziția jucătorului este crearea unui PlayerMover. | ||
+ | |||
+ | Pentru a face acest lucru, va trebui să treceți un Vector3 în metoda Mutare pentru a ghida jucătorul de-a lungul celor patru direcții ale busolei. De asemenea, puteți utiliza un raycast pentru a detecta pereții în LayerMask corespunzătoare. Desigur, implementarea a ceea ce doriți să aplicați command pattern este separată de modelul în sine. | ||
+ | |||
+ | |||
+ | |||
+ | Pentru a urma command pattern, capturați metoda de mutare a PlayerMover ca obiect. În loc să apelați direct Move, creați o nouă clasă, MoveCommand, care implementează interfața ICommand. | ||
+ | |||
+ | <code c#> | ||
+ | public class MoveCommand : ICommand | ||
+ | { | ||
+ | PlayerMover playerMover; | ||
+ | Vector3 movement; | ||
+ | public MoveCommand(PlayerMover player, Vector3 moveVector) | ||
+ | { | ||
+ | this.playerMover = player; | ||
+ | this.movement = moveVector; | ||
+ | } | ||
+ | public void Execute() | ||
+ | { | ||
+ | playerMover.Move(movement); | ||
+ | } | ||
+ | public void Undo() | ||
+ | { | ||
+ | playerMover.Move(-movement); | ||
+ | } | ||
+ | } | ||
+ | </code> | ||
+ | |||
+ | Indiferent de logică pe care doriți să o realizați, intră aici, așa că invocați Move cu vectorul de mișcare. | ||
+ | |||
+ | De asemenea, ICommand are nevoie de o metodă Undo pentru a restabili scena la starea anterioară. În acest caz, logica Undo scade vectorul de mișcare, împingând în esență jucătorul în direcția opusă. | ||
+ | |||
+ | MoveCommand stochează toți parametrii necesari pentru a-i executa. Setați-le cu un constructor. În acest caz, salvați componenta PlayerMover corespunzătoare și vectorul de mișcare. | ||
+ | |||
+ | Odată ce creați obiectul de comandă și salvați parametrii necesari acestuia, utilizați metodele statice ExecuteCommand și UndoCommand ale CommandInvoker pentru a transmite MoveCommand. Aceasta rulează Execute sau Undo din MoveCommand și urmărește obiectul de comandă din stiva de anulare. | ||
+ | |||
+ | InputManager nu apelează direct metoda PlayerMover's Move. În schimb, adăugați o metodă suplimentară, RunMoveCommand, pentru a crea o nouă MoveCommand și a o trimite către CommandInvoker. | ||
+ | |||
+ | Apoi, configurați diferitele evenimente onClick ale butoanelor UI pentru a apela RunPlayerCommand cu cei patru vectori de mișcare. | ||
+ | |||
+ | Mai multe detalii si exemple aici: [[https://unity.com/how-to/use-command-pattern-flexible-and-extensible-game-systems]] | ||
==== Sisteme de evenimente ==== | ==== Sisteme de evenimente ==== | ||
Line 182: | Line 248: | ||
| | ||
// Unsubscribe from the event (stop listening). | // Unsubscribe from the event (stop listening). | ||
- | private void OnDisable() => player.OnPlayerHealthChanged += HandlePlayerHealthChanged; | + | private void OnDisable() => player.OnPlayerHealthChanged -= HandlePlayerHealthChanged; |
// Method which is called on event invocation | // Method which is called on event invocation | ||
Line 251: | Line 317: | ||
fileName = "PlayerEventSO", | fileName = "PlayerEventSO", | ||
menuName = "Player/PlayerEventSO")] | menuName = "Player/PlayerEventSO")] | ||
- | public class PlayerEventSO : MonoBehaviour | + | public class PlayerEventSO : ScriptableObject |
{ | { | ||
// Unity event. | // Unity event. |