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:
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:
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:
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
:
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:
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 143x (2.49 kB)
Aplikace je včetně zdrojových kódů v jazyce C# .NET