# Guide: Kollisioner ## Introduktion För att hantera kollisioner i Unity vill vi använda en metod som heter `OnCollisionEnter`. Det är precis som `Start` och `Update` en metod som anropas av Unity vid speciella tillfällen. `OnCollisionEnter` körs när objektet nuddar ett annat objekt. För att metoden ska triggas krävs följande saker för objekten som kolliderar: * båda objekten har en collider * minst ett av objekten har en rigidbody * skriptet med `OnCollisionEnter` sitter på ett av objekten Vi kan testa att det fungerar genom att i `OnCollisionEnter` metoden skriva en kodrad som skriver ut något till konsolen. Det gör vi genom `Debug.Log()` vilket ungefär motsvara `Console.WriteLine()` som vi använde när vi jobbade med konsol-applikationer. ```csharp void OnCollisionEnter(Collision collision){ Debug.Log("Vi träffade något!") } ``` ## Exempel: skjuta fiender Något vi ofta vill göra är att anropa metoder i andra skript när vi kolliderar med saker. För att illustrera detta kan vi ta ett exempel: ett skott-objekt som kolliderar med ett fiende-objekt. Vid kollisionen ska skottet försvinna, och fienden ta skada. För att bygga detta kan vi gå igenom följande steg: 1. Skapa skottobjekt med skript, collider och rigidbody 2. Skapa fiendeobjekt med skript och collider 3. Hantera kollisionen i skott-skriptet 4. Anropa en metod i fiendet skriptet för att "ta skada" ### 1 - skapa skottobjektet På skottobjektet behöver vi tre saker: 1. collider 2. rigidbody 3. `Bullet`-skript En collider brukar finnas från början när vi skapar ett 3D objekt. Vi lägger till en Rigidbody via "add component"-knappen, samt ett nytt skript som vi döper till något vettigt, till exempel `Bullet`. ![Skärmbild 2023-12-12 130459](https://hackmd.io/_uploads/SkEYnTB8a.png) I bullet skriptet vill vi göra saker som skottet att röra på sig (kolla guide: rigidbody), men det vi ska fokusera på är kollsioner. Vi lägger till `OnCollisionEnter(Collision collision)` till skriptet: ```csharp public class Bullet : MonoBehaviour{ void Start(){ } void Update(){ } void OnCollisionEnter(Collision collision){ Debug.Log("Vi träffade något!") } } ``` ### 2 - skapa fiendeobjektet På vårt fiendeobjekt räcker det att det finns en collider, samt ett eget skript som får heta till exempel `Enemy`. Det skriptet ska ansvara för att hålla koll på antal liv fienden har kvar, och ta bort fienden om den får slut på liv. För detta gör vi två saker: * skapar en variabel som representerar antal liv * skapa en metod med namn `TakeDamage` som minskar antal liv och tar bort objektet om antal liv är lika med noll ```csharp public class Enemy : MonoBehaviour { int hp = 3; public void TakeDamage() { hp -= 1; if (hp == 0) { Destroy(gameObject); } } } ``` `Destroy()` tar bort det objekt man skriver inom parenteserna. `gameObject` är en variabel som hänvisar till det GameObject som skriptet sitter på. ### 3 - hantera kollision I `OnCollisionEnter` i `Bullet`-skriptet vill vi göra två saker: 1) ta bort skott-objektet och 2) anropa `TakeDamage` i `Enemy`-skriptet. Den första löser vi med att anropa `Destroy`. I `Bullet`: ```csharp void OnCollisionEnter(Collision collision){ Destroy(gameObject); } ``` ### 4 - anropa `TakeDamage` från `Bullet` Vi vill också anropa `TakeDamage` när kollisionen sker. Det kan vi göra på följande sätt ```csharp void OnCollisionEnter(Collision collision){ Destroy(gameObject); // Ta bort skottet GameObject enemyObject = collision.gameObject; Enemy enemyComponent = enemyObject.GetComponent<Enemy>(); if(enemyComponent != null){ enemyComponent.TakeDamage(); } } ``` Först får vi alltså tag på själva fiende-objektet med koden `collision.gameObject`. I den här metoden är `collision` en variabel som innehåller information om själva kollisionen, bland annat objektet vi kolliderade med. På det objektet kan vi anropa `GetComponent<Enemy>`. Då får vi tillgång till `Enemy` skriptet och kan anropa metoder som finns där. `GetComponent<Enemy>` kommer bara returnera en komponent om det faktiskt finns en på objektet vi kolliderade med. Annars kommer variabeln `enemyComponent` vara `null`, så vi lägger även till en if-sats för att kolla detta.