Denne opplæringen er forskjellig fra mine tidligere opplæringsprogrammer, da denne er orientert mot spillstopp og spillprototyping, spesielt kortspill. Vi skal lage en 2D-kortkortdekk i Unity uten å bruke noen art-rent med kode.
Et spillekort dekk har totalt 52 kort med 13 kort hver av 4 forskjellige symboler. For å opprette en som bruker kode, må vi lage disse 4 symbolene, den avrundede rektangulære basen for kortet og designet på baksiden av kortet.
Designet på baksiden av kortet kan være et abstrakt mønster, og det er mange måter å lage en på. Vi skal skape et enkelt fliseremønster som da vil bli flislagt for å skape designet. Vi har ingen spesiell design for A-, K-, Q- og J-kortene.
Før vi begynner, må jeg nevne at det er enklere løsninger der ute som vi kan bruke til å lage et kortkort. Noen av disse er listet opp nedenfor.
Font-basert løsning er den raskeste og enkleste en hvis du vil gjøre raske prototyper.
Det første trinnet er å lære å lage en Texture2D
bruker kode som deretter kan brukes til å lage en Sprite
i enhet. Følgende kode viser opprettelsen av en 256x256 blank tekstur.
Texture2D texture = ny Texture2D (256, 256, TextureFormat.ARGB4444, false); texture.filterMode = FilterMode.Trilinear; texture.wrapMode = TextureWrapMode.Clamp; texture.Apply ();
Tanken er å tegne alle designene på tekstur før vi bruker Søke om
metode. Vi kan tegne design på teksturpiksel ved piksel ved hjelp av SetPixel
metode, som vist nedenfor.
texture.SetPixel (x, y, Color.white);
For eksempel, hvis vi ønsket å fylle ut hele tekstur med en farge, kunne vi bruke en metode som dette.
privat tomrom PaintRectangle (Texture2D tekstur, Rect rectBounds, Color farge) for (int i = (int) rectBounds.x; jegNår vi har en
Texture2D
opprettet, kan vi bruke den til å lage enSprite
å bli vist på skjermen.Sprite sprite = Sprite.Create (tekstur, ny Rect (0.0f, 0.0f, texture.width, texture.height), ny Vector2 (0.5f, 0.5f), 1);Den kompliserte delen i alt dette er etableringen av de nødvendige designene på tekstur.
4. Opprette hjerteformen
Når det gjelder opprettelsen av hjerteformen, er det mange forskjellige tilnærminger som vi kan bruke, blant annet noen kompliserte likninger, samt enkel blanding av former. Vi vil bruke blandingen av former som vist nedenfor, spesielt den med trekanten.
Som du har observert, kan vi bruke to sirkler og et kvadrat eller en trekant for å lage den grunnleggende hjerteformen. Dette betyr at det ville savne de ekstra vakre kurvene, men passer perfekt til vår hensikt.
Maling en sirkel
La oss pusse opp på noen likninger for å male en sirkel. For en sirkel med senter ved opprinnelse og radius
r
, ligningen for punktet(X, y)
på sirkelen erx
2
+ y
2
= r
2
. Nå hvis senterets senter er på(H, k)
da blir ligningen(X-h)
2
+ (Y-k)
2
= r
2
. Så hvis vi har et firkantet begrensende boks rektangel så kan vi løpe gjennom alle punktene i rektangelet og bestemme hvilke punkter som kommer inn i sirkelen, og hvilke som ikke gjør det. Vi kan enkelt lage vårPaintCircle
metode basert på denne forståelsen, som vist nedenfor.privat tomrom PaintCircle (Texture2D tekstur, floatradius, Vector2 midPoint, Fargefarge) Rect circleBounds = new Rect (); circleBounds.x = Mathf.Clamp (midPoint.x- (radius), 0, oppløsning); circleBounds.y = Mathf.Clamp (midPoint.y- (radius), 0, oppløsning); circleBounds.width = Mathf.Clamp (2 * radius, 0, oppløsning); circleBounds.height = Mathf.Clamp (2 * radius, 0, oppløsning); flyte iValue; for (int i = (int) circleBounds.x; jegmidPoint.x-iValue && i Når vi har
PaintCircle
metode, kan vi fortsette å skape vår hjerteform som vist nedenfor.void PaintHearts (Texture2D tekstur) // 2 sirkler på topp floatradius = oppløsning * 0.26f; Vector2 mid = ny Vector2 (radius, oppløsning-radius); PaintCircle (tekstur, radius, mid, Color.red); midt = ny Vector2 (oppløsning-radius, oppløsning-radius); PaintCircle (tekstur, radius, mid, Color.red); // trekant nederst flytebredde = oppløsning * 0,58f; int endJ = (int) (oppløsning * 0,65f); int startJ = (int) (oppløsning * 0.1f); float delta = (bredde / endJ); float midI = oppløsning * 0.5f; for (int i = 0; i(MIDI (delta * (j-startJ))) && i<(midI+(delta*(j-startJ)))) texture.SetPixel(i, j, Color.red); Variabelen
Vedtak
er bredden og høyden på tekstur.5. Opprette diamantformen
Vi drøfter to måter å tegne diamantformen på.
Maling en enkel diamant
Den enkleste er å utvide koden som brukes til trekanten og legge til en omvendt trekant på toppen for å skape den nødvendige formen, som vist nedenfor.
void PaintDiamond (Texture2D tekstur) float width = resolution * 0.35f; for (int i = 0; imidJ) j = oppløsning-j; if (i> (MIDI (delta * j)) && i<(midI+(delta*j))) isValid=true; else if(i>(MIDI (delta * j)) && i<(midI+(delta*j))) isValid=true; return isValid; PaintDiamond(texture); Maling en buet diamant
Den andre er å bruke en annen ligning for å skape en bedre, svingete versjon av vår diamantform. Vi skal bruke denne til å lage fliseleggesignen på baksiden av kortet vårt. Ligningen for en sirkel kommer fra den opprinnelige ligningen av en ellipse, som er
(X / a)
2
+ (Y / b)
2
= r
2
.Denne ligningen er den samme som for sirkelen når variablene
en
ogb
er begge1
. Ellipse likningen kan da utvides til en superellipse likning for lignende former bare ved å endre kraften,(X / a)
n
+ (Y / b)
n
= r
n
. Så nårn
er2
vi har ellipse, og for andre verdier avn
Vi vil ha forskjellige former, hvorav den ene er vår diamant. Vi kan bruke tilnærmingen som brukes til å komme fram tilPaintCircle
metode for å komme fram til vårt nyePaintDiamond
metode.privat tomrom PaintDiamond (Texture2D tekstur, Rect rectBounds, Vector2 midPoint, Color farge, float n = 0.8f) float iValue; int a = (int) (rectBounds.width / 2); int b = (int) (rectBounds.height / 2); flyte nRoot = 1 / n; float delta; float partialOne; rectBounds.width = Mathf.Clamp (rectBounds.x + rectBounds.width, 0, oppløsning); rectBounds.height = Mathf.Clamp (rectBounds.y + rectBounds.height, 0, oppløsning); rectBounds.x = Mathf.Clamp (rectBounds.x, 0, oppløsning); rectBounds.y = Mathf.Clamp (rectBounds.y, 0, oppløsning); for (int i = (int) rectBounds.x; jegmidPoint.x-iValue && i Maling en avrundet rektangel
Den samme ligningen kan brukes til å lage vår avrundede rektangulære kortbaseform ved å variere verdien av
n
.privat tomrom PaintRoundedRectangle (Texture2D tekstur) for (int i = 0; imid.x-iValue && i Maling av flislegging
Bruk dette
PaintDiamond
Metode, vi kan tegne fem diamanter for å lage teglestrukturen for designet på baksiden av kortet vårt.Koden for tegning av flisekonstruksjonen er som nedenfor.
privat tomrom PaintTilingDesign (Texture2D tekstur, int tileResolution) Vector2 mid = new Vector2 (tileResolution / 2, tileResolution / 2); float size = 0.6f * tileResolution; PaintDiamond (tekstur, ny Rect (mid.x-size / 2, mid.y-size / 2, størrelse, størrelse), midt, Color.red); midt = nytt Vector2 (0,0); PaintDiamond (tekstur, ny Rect (mid.x-size / 2, mid.y-size / 2, størrelse, størrelse), midt, Color.red); midt = ny Vector2 (fliseravløsning, 0); PaintDiamond (tekstur, ny Rect (mid.x-size / 2, mid.y-size / 2, størrelse, størrelse), midt, Color.red); midt = ny Vector2 (fliser, resolusjon, flisløsning); PaintDiamond (tekstur, ny Rect (mid.x-size / 2, mid.y-size / 2, størrelse, størrelse), midt, Color.red); midt = ny Vector2 (0, fliser resolusjon); PaintDiamond (tekstur, ny Rect (mid.x-size / 2, mid.y-size / 2, størrelse, størrelse), midt, Color.red);6. Opprette Spadesformen
Spadesformen er bare den vertikale flippen av vår hjerteform sammen med en grunnform. Denne grunnformen vil være den samme for klubbenes form også. Den nedenstående figuren illustrerer hvordan vi kan bruke to sirkler for å lage denne grunnformen.
De
PaintSpades
Metoden vil være som vist nedenfor.void PaintSpades (Texture2D tekstur) // 2 sirkler på midtflatradius = oppløsning * 0.26f; Vector2 mid = ny Vector2 (radius, oppløsning-2,2f * radius); PaintCircle (tekstur, radius, mid, Color.black); midt = ny Vector2 (oppløsning-radius, oppløsning-2,2f * radius); PaintCircle (tekstur, radius, mid, Color.black); // trekant ved topp floatbredde = oppløsning * 0,49f; int startJ = (int) (oppløsning * 0,52f); float delta = (bredde / (oppløsning-startJ)); float midI = oppløsning * 0.5f; int alteredJ; radius = oppløsning * 0.5f; flyte midJ = oppløsning * 0,42f; flyte iValue; for (int i = 0; i(MIDI (delta * alteredJ)) && i<(midI+(delta*alteredJ))) texture.SetPixel(i, j, Color.black); //bottom stalk for (int k=0;k mid.x + iValue) mid = ny Vector2 (oppløsning, midJ); iValue = (Mathf.Sqrt (radius * radius - ((k-mid.y) * (k-mid.y)))); // + mid.x; hvis jeg 7. Opprette Clubs Shape
På dette punktet er jeg sikker på at du kan finne ut hvor lett det har blitt å lage klubbens form. Alt vi trenger er to sirkler og grunnformen vi opprettet for spaderformen.
De
PaintClubs
Metoden vil være som vist nedenfor.void PaintClubs (Texture2D tekstur) int radius = (int) (oppløsning * 0.24f); // 3 sirkler Vector2 mid = ny Vector2 (oppløsning * 0.5f, oppløsning-radius); PaintCircle (tekstur, radius, mid, Color.black); midt = ny Vector2 (oppløsning * 0.25f, oppløsning- (2,5f * radius)); PaintCircle (tekstur, radius, mid, Color.black); midt = ny Vector2 (oppløsning * 0.75f, oppløsning- (2,5f * radius)); PaintCircle (tekstur, radius, mid, Color.black); // base stalkradius = (int) (oppløsning * 0,5f); flyte midY = oppløsning * 0.42f; int stalkHeightJ = (int) (oppløsning * 0,65f); flyte iValue; for (int i = 0; imid.x + iValue) mid = ny Vector2 (oppløsning * 1.035f, midY); iValue = (Mathf.Sqrt (radius * radius - ((j-mid.y) * (j-mid.y)))); // + mid.x; hvis jeg 8. Pakking av teksturer
Hvis du undersøker enhetens kildefiler for dette prosjektet, finner du en
TextureManager
klasse som gjør alt tungt løft. Når vi har skapt alle nødvendige teksturer,TextureManager
klassen brukerPackTextures
metode for å kombinere dem til en enkelt tekstur, og dermed redusere antall trekksamtaler som kreves når vi bruker disse figurene.Rect [] packedAssets = packedTexture.PackTextures (allGraphics, 1);Bruker
packedAssets
array, kan vi hente grensebokser av individuelle teksturer fra hovedtekststrukturen som heterpackedTexture
.offentlig Rect GetTextureRectByName (streng teksturnavn) textureName = textureName.ToLower (); int textureIndex; Rect textureRect = ny Rect (0,0,0,0); hvis (textureDict.TryGetValue (textureName, out textureIndex)) textureRect = ConvertUVToTextureCoordinates (packedAssets [textureIndex]); else Debug.Log ("ingen slik tekstur" + teksturnavn); returnere textureRect; Private Rect ConvertUVToTextureCoordinates (Rect rect) returner ny Rect (rect.x * packedTexture.width, rect.y * packedTexture.height, rect.width * packedTexture.width, rect.height * packedTexture.height);Konklusjon
Med alle nødvendige komponenter opprettet, kan vi fortsette å lage kortkortet vårt, da det bare handler om å legge ut formene riktig. Vi kan enten bruke Unity UI til komposittkort eller vi kan lage kortene som individuelle teksturer. Du kan utforske prøvekoden for å forstå hvordan jeg har brukt den første metoden for å lage kortoppsett.
Vi kan følge den samme metoden for å skape noen form for dynamisk kunst på kjøretid i Unity. Å lage kunst ved kjøretid er en ytelse-sulten operasjon, men det må bare gjøres en gang hvis vi lagrer og gjenbruk disse teksturer effektivt. Ved å pakke de dynamisk opprettede eiendommene til en enkelt tekstur, får vi også fordelene ved å bruke et teksturatlas.
Nå som vi har vår kortkort dekk, gi meg beskjed om hvilke spill du planlegger å lage med den.