IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - 3D střílečka v Unity - Otáčení kamery pomocí myši

V minulé lekci, 3D střílečka v Unity - Terén a pohyb hráče, jsme si naprogramovali terén a pohyb hráče po něm.

V dnešním Unity 3D tutoriálu si do našeho projektu 3D střílečky naprogramujeme otáčení kamery při pohybu myši. Napíšeme si skript pro pohyb kamery.

Tvorba skriptu

Podobně jak jsme již tvořili skript na pohyb hráče si nyní vytvoříme skript pro kameru. Ze všeho nejdříve klikneme v okénku Hiearchy na Main Camera. Poté klikneme na tlačítko Add Component:

Tvorba 3D her v Unity

Vyplníme název skriptu CameraMove a klikneme na new script. V zobrazovaném poli s názvem name se nám ukáže text, který jsme napsali, tedy CameraMove. Klikneme na tlačítko Create and Add. Tímto způsobem jsme si vytvořili skript, tentokrát na kameře. Naše scéna teď vypadá takto:

Tvorba 3D her v Unity

Na obrázku je náš skript označený červeně. Dvakrát na něj klikneme a upravíme jeho kód.

Úprava kódu skriptu CameraMove

Po kliknutí se nám zase vygenerovala třída, tentokrát s názvem CameraMove podle našeho názvu skriptu. Do třídy CameraMove si vložíme proměnné a napíšeme metodu Update().

Proměnné

Nejprve si tedy vložíme tyto proměnné:

  • osa_x - proměnná k ukládání hodnoty myši na ose x,
  • osa_y - proměnná k ukládání hodnoty myši na ose y,
  • player - proměnná s hráčem, kterou inicializujeme později.
  • mousesensitivi = 12 - hodnota, kterou násobíme získanou hodnotu na osách za účelem úpravy výsledku posunu po ose hráče nebo kamery

Kód je následující:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraMove : MonoBehaviour
{

    float osa_x;
    float osa_y;
    public GameObject player;
    float mousesensitivi = 12;

    ...
}

Modifikátor přístupu public zajistí viditelnost proměnné player z Unity editoru, kde ji také potom nastavíme na hráče. Místo modifikátoru public bychom mohli použít [SerializeField] tj. [SerializeField] GameObject player; Obdobně bychom to mohli použít i pro proměnnou mousesensitivi.

Metoda Update()

Nejprve si do metody napíšeme tento kód:

osa_x -= Input.GetAxis("Mouse Y") * mousesensitivi;
osa_y += Input.GetAxis("Mouse X") * mousesensitivi;

Zde se nám odečítá/přičítá hodnota myši na dané ose od naší hodnoty proměnné, která je při spuštění hry nulová. Hodnotu myší získáváme pomocí metody GetAxis(), které předáme text "Mouse " s identifikací osy. Získaná data jsou jen číslo, o kolik se myš po osách posunula, ne její pozice. Další hodnota by se už rovnala nule, protože už se pozice myši dál nemění, myš stojí na místě.

Hodnotu osy x myši odečítáme, protože při pohybu objektu kamery nahoru ubíráme hodnoty. Hodnotu osy y myši přičítáme, protože při otáčení vpravo po ose y objektu se hodnoty zvětšují.

Otáčení hlavy hráče

Nyní si na okamžik nastavíme modifikátor přístupu proměnné osa_x na public. Poté otáčejme hráčem a odečítejme hodnoty. Vidíme, že právě hodnoty 335 a 420 odpovídají reálnému otáčení hlavy. Modifikátor public odstraníme a do metody Update() přidáme našemu pokusu odpovídající kód:

osa_x = Mathf.Clamp(osa_x, 335, 420);

Kdybychom hodnoty neomezili, mohl by hráč otáčet krkem dokola o 360° :).

Na omezení rotace jsme použili metodu Clamp() s těmito parametry:

  • vstupní hodnota (v našem případě osa_x),
  • minimum, jaký může být výsledek metody,
  • maximum výsledku metody.

Metoda nám jednoduše hodnotu ořízne, pokud se nevejde do zvolených mezí, a vrátí nám ji jako float. Pokud se vejde, jen ji vrátí.

Transformace objektů

Následuje otáčení kamery a hráče, transformovat potřebujeme oba tyto objekty:

transform.localEulerAngles = new Vector3(osa_x, 0,0);
player.transform.localEulerAngles = new Vector3(0, osa_y, 0);

Vlastnost transform nám umožňuje transformovat objekt, na kterém je skript přichycen, tedy např. otočit. Vlastnost localEulerAngles je to, co vidíme v editoru pod záložkou transform, v řádku rotation. Určujeme tedy rotaci objektu, nastavíme jakou hodnotu mají mít jednotlivé osy. Hodnotu rotace udáváme ve formátu Vector3 se třemi hodnotami, jedna hodnota pro každou osu.

Hodnotu pro rotaci osou Y zadáváme hráči a ne kameře. Hodnotu pro rotaci osou X zadáváme pak kameře a ne hráči. Proč? Hráč se má na rozdíl od kamery točit jen dokola. Kdybychom umožnili otáčení hráče okolo osy X, hráč by se nadnášel, protože bychom předek kapsle posunuli víc k zemi a spodek kapsle nadzvedli. Je to vidět na následujících obrázcích:

Tvorba 3D her v Unity
Tvorba 3D her v Unity
Tvorba 3D her v Unity
Tvorba 3D her v Unity

Na závěr tvorby metody Update() si uveďme celý její kód:

...
public class CameraMove : MonoBehaviour
{

    ...

    void Update()
    {
        osa_x -= Input.GetAxis("Mouse Y") * mousesensitivi;
        osa_y += Input.GetAxis("Mouse X") * mousesensitivi;

        osa_x = Mathf.Clamp(osa_x, 335, 420);

        transform.localEulerAngles = new Vector3(osa_x, 0,0);
        player.transform.localEulerAngles = new Vector3(0, osa_y, 0);
    }
}

Inicializace proměnné player

Ještě musíme udělat několik věcí, než bude vše zcela funkční. Ze všeho nejdříve musíme určit, co je naše proměnná player. Náš skript ví jen to, že je viditelná z Unity editoru a má jí měnit hodnotu rotace při pohybu myší. Skript CameraMove neví, kdo nebo co je hráč. To hned napravíme :-)

Po uložení skriptu CameraMove se nám v Unity editoru objevil rámeček s nápisem None (Game Object) v záložce Camera Move (script). Před rámečkem je nápis Player. Tento rámeček je naše proměnná Player:

Tvorba 3D her v Unity

Pokud nevidíme proměnnou player v Unity Editoru, je možné že jsme neuložili skript CameraMove.

Pro definici proměnné stačí kliknout na část rámečku s kroužkem, kde uprostřed něho je tečka:

Tvorba 3D her v Unity

Po kliknutí se nám zobrazí seznam všech objektů, které máme v naší scéně a zároveň mohou být považovány za proměnné. Vybereme objekt Capsule.

Alternativně můžeme v Hierarchii najet myší na objekt, který chceme mít v proměnné Player a podržením pravého tlačítka myši ho chytneme a přesuneme do proměnné Player. Tím se nám nastaví proměnná Player na objekt, který jsme vybrali.

Díky tomu, že jsme v našem programu s názvem CameraMove přidali před proměnnou player modifikátor přístupu public jsme docílili viditelnost proměnné v editoru. Mohli jsme tak nastavit proměnné jiný objekt, než je objekt, na kterém je náš skript přichycen.

Zatím jsme se tedy naučili dvě možnosti, jak definovat objekt ve skriptu:

  • pracovat přímo s objektem, na kterém je skript, např. přes vlastnost transform,
  • pro objekt ve skriptu si definovat pro proměnnou modifikátor přístupu public, a tím si pak v editoru umožnit ji definovat.

Příliš velké množství proměnných, které jsou public neboli pro nás viditelné, mohou znatelně vytížit počítač, na kterém program běží. 

Testování

Skript je hotov. Po spuštění hry se nám stane, že když pohneme myší, tak se naše kamera otočí a s tím i náš pohled. Všimněme si, že když někam namíříme a stiskneme klávesu W, hráč se pohybuje, ale ne ve směru, kam se díváme. Aby se nám hráč pohyboval ve směru pohledu, musíme upravit náš předchozí skript Move pro pohyb.

Úprava skriptu Move

Musíme nastavit, aby síla, která se vždy přidá při stisknutí klávesy směru chůze, např. W, působila v úhlu, kam je v daném okamžiku kamera nasměrována.

To zajistíme metodou AddRelativeForce(), která přidá sílu ve směru, kterým je objekt natočen. Tato metoda přidá sílu v aktuálním směru osy X, Y nebo Z a ne ve směru osy, která se uložila do paměti po spuštění hry.

Otevřeme si skript Move. V metodě Update()nahradíme volání metody AddForce() voláním metody AddRelativeForce():

...

public class Move : MonoBehaviour
{
    ...

    void Update()
    {
        if (Input.GetKey(KeyCode.D))
        {
            rb.AddRelativeForce(new Vector3(5, 0, 0));
        }
        if (Input.GetKey(KeyCode.A))
        {
            rb.AddRelativeForce(new Vector3(-5, 0, 0));
        }
        if (Input.GetKey(KeyCode.W))
        {
            rb.AddRelativeForce(new Vector3(0, 0, 5));
        }
        if (Input.GetKey(KeyCode.S))
        {
            rb.AddRelativeForce(new Vector3(0, 0, -5));
        }
    }
}

Nyní, po uložení skriptu Move a spuštění hry, bude ovládání pohledu pomocí myši a pohyb ve směru kamery funkční.

V příští lekci, 3D střílečka v Unity - Práce s Asset Store a model zbraně, se naučíme importovat balíčky z obchodu Unity Asset Store a pracovat s nimi. Do hry přidáme model zbraně.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 118x (2.49 kB)
Aplikace je včetně zdrojových kódů v jazyce C# .NET

 

Předchozí článek
3D střílečka v Unity - Terén a pohyb hráče
Všechny články v sekci
Tvorba 3D her v Unity
Přeskočit článek
(nedoporučujeme)
3D střílečka v Unity - Práce s Asset Store a model zbraně
Článek pro vás napsal Tomáš Brabec
Avatar
Uživatelské hodnocení:
70 hlasů
Hodně zdaru programátoři všeho druhu,doufám ,že nikdy nezažijete nudu.
Aktivity