• úvod
  • témata
  • události
  • tržiště
  • diskuze
  • nástěnka
  • přihlásit
    registrace
    ztracené heslo?
    BYDKUNITY 3D
    JAACOB
    JAACOB --- ---
    SLASH: Zvlastni - na prvni pohled v tom kodu nevidim problem. Jeste me napada, jestli to nemuze byt nejaky bordel s recyklaci tweenu - vim, ze s tim jeden kolega kdysi zapasil a konfiguroval jinak appku. Zkus mrknout na dokumentaci initu a zkus upravit parametry a pouzit ten safe mode nebo vypnout recyklaci - jestli problem nahodou neni tam..?
    DOTween - Documentation
    http://dotween.demigiant.com/documentation.php?api=DOTween.Init
    JAACOB
    JAACOB --- ---
    PATRIKSIMA: Spravne je to tak, ze kdyz hrac nema stisknuty input strelby, tak proste cekas, az stisknutej bude. Jakmile se detekuje, ze jako jo, tak vystrelis a ulozis si nejakej TimeoutDoDalsihoVystrelu - coz je realne cas podle kadence zbrane. Pak v kazdem updatu, pokud je TimeoutDoDalsihoVystrelu > 0, tak od nej odectes time.deltaTime (cas framu). Az v okamziku, kdy je <= 0, tak muzes vystrelit znovu. Ale nenastavis ho znova na celou hodnotu, jen k aktualni hodnote tu novou prictes. Takze kdyz po odectu byla hodnota zaporna, tak to je "kompenzace" za to, zes mel vystrelit uz tech par milisekund zpet. Chtel jsem poslat link na unity, ale to je zmatene a jeste blbe... :)
    Kod by mel vypadat napr. takhle nejak:

    private float fireDelta = 100f; // kadence
    private float timeToShoot = 0f; // timeout do dalsiho vystrelu

    private void Update()
    {
        if (timeToShoot > 0) timeToShoot -= time.deltaTime;

        if (Input.GetButton("Fire1") && timeToShoot <=0)
        {
           Shoot(); // spawn projektilu, animace - whatever
           timeTiShoot += fireDelta; // proste deltu prictem, neresetujem! Takze ten zaporny cas, o ktery jsme prisli delkou framu mame kompenzovany...
        }

        if (timeToShoot < 0) timeToShoot = 0; // ale aby se "nenabijel" firerate kdyz nestrilis nebo neco, tak tady cas resetujem na 0...
    }
    SLASH
    SLASH --- ---
    JAACOB: Est raz diki za rady, prepisal som to tak ze je tam pouzita ta coroutine a seqvencia : https://pastebin.com/3FcwatHx

    funguje to celkom dobre, ale teraz tam vznikol taky bug...

    Pokial sa pouzije funkcionality Hint (cize to tlacitko vpravo dole, ktore ukaze uzivatelovy ktory objekt ma najst) a toto zavola na Hunt.cs funkciu showHintAnimation() co je v podstate taky jednoduchy yoyo color tween, a potom user klikne na ten objekt a spusti showFoundAnimation().. ten posledny fade tween sa nevykona, tym padom sa ani OnComplete nevykona ktore by malo znicit ten gameObject takze ostane ta minca visiet na scene .. a uz samozrejme nie je klikatelna. Nestava sa to ale vzdy, niekedy to funguje OK aj napriek tomu ze je minca kliknuta pocas tej hint animacie.

    Napadlo ma dat tam timeline insert s callbackom na znicenie objektu, namiesto zavesit no na OnComplete?
    Alebo co by si navrhol za riesenie?

    Tu je preview, stalo sa to hned na zaciatku..
    hunt
    http://www.youtube.com/watch?v=UlRHYyr-MAs
    JAACOB
    JAACOB --- ---
    K tomu jak se jednoduse da udelat slusnej fuckup v timingu tu mam jednu perlicku z praxe - v byvale praci pri hrani nasi strilecky jsem proste citil, ze FPS ovlivnuje rychlost strelby zbrane. Zacal jsem se vrtat v kodu a zjistil, ze je to napsane uplne blbe. Mezi vystrelama se cekalo na timeout podle kadence zbrane, vystrelilo se a pak se cekalo zase stejnej timeout. To je ale blbe. Zkusim nacrtnout:

    ╚══════╝ Pozadovany realny interval mezi vystrely

    Realny framerate (N = nevystrel, V = vystrel)
    N────N────N────N────N

    Optimalni chovani strelby - v kazdem framu vyhodnocujes, jestli od presneho casu posledniho vystrelu uz muzes strilet znova:

    V────N────V────V────N────V────V────V─...
    ╚══════╩══════╩══════╩══════╩══════╩═...

    Situace, kde kontrolujes, jestli uz muzes v danem framu vystrelit a kdyz jo, tak restartujes timeout:

    V────N────V────N────V────N────V────N...
    ╚══════╝    ╚══════╝    ╚══════╝    ╚═════...

    To je ale blbe! (a takhle podle me funguje i ten InvokeRepeating). Tady je videt, ze i na 8 framech s vysokou kadenci jsi schopnej u spatneho pristupu okrast hrace o 2 vystrely...to je velkej pruser! :)
    TOBE by se pak klidne mohlo stat, ze ti podle FPS ty invoke-repeating/frame count fajrovani eventu muze klidne vychazet uplne na random o +- pul vteriny, takze se jednou ten fade zvladne, jindy ne...
    JAACOB
    JAACOB --- ---
    SLASH: dej spis pak vedet jak jsi dopadl. Jestli pomohl ten unbind kliku nebo aspon ten prepis na sekvenci. Osobne si myslim, zes tam mel primarne spis rozkople casovani a zalezelo na tom, jak ti zrovna vysly ty invoky. Nevim totiz kdo presne a kdy vlastne vola ten destroy. Ale jestli je to neco, co je hookle na tu tvoji Action onItemClicked, tak by to tu akci melo zavolat v optimalnim svete, kde frametime je nekonecne maly za 0.375 vteriny - prakticky o polovinu driv, nez se nejaky fade vubec zacne resit. Realne to ale bude treba i 2x delsi cas asi.

    Uprimne nejsem expert na realne fungovani InvokeRepeating, ale dal bych si na nej velkeho majzla hned z nekolika duvodu. Jednak je prasarna spoustet metody jejich string nazvem. Uz kvuli tomu je jasne, ze tam bude figurovat nejaka hnusna a uplne zbytecne narocna reflexe. Za druhe - kdyz budes nekde ve VS dohledavat reference, dostanes leda prd, protoze se na tu metodu technicky nikdo neodkazuje. Co vede k dalsimu problemu - lehce kvuli chybe muzes nekde zapomenout invoke vypnout (nebo se upsat v nazvu metody) a zadelavas si na problem. Refactoring rename je taky v prdeli - na Invoky se zapomene. A nakonec - a to je fakt jen muj dohad - ale rekl bych, ze kdyz das invoke repeating na tak malej interval, tak ze on proste jenom bude cekat na timeout, pak zavola metodu a pak nastavi zase uplne stejnej timeout. Jenomze kdyz nebudes pocitat "preteceni" delky framu (coz si myslim, ze InvokeRepeating resit nebude), tak se ti proste na zaklade FPS budou brutalne lisit doby, za ktere to tech 50 timeoutlych ticku udela.

    Navic jeste - kdyz mas neco timeoutovane v tak malych casoych dimenzich, je to FPS bound a bude se mega lisit timing tech tweenu a volani callbacku. Dovysvetlim:

    Pokud ti hra renderuje v 60FPS, mel bys mit time.deltatime mezi framama nejakych 16.6ms, kdyz hra jede 30FPS, tak je deltatime cca 33ms. Rozdil u 50 framu je dvojnasobny cas. Proto bys nemel pocitat framy, ale absolutni cas, kdy neco naplanujes, protoze v prvnim pripade to bude trvat 25*16ms = 0.4s, v druhem pripade 25*33ms = 0.82 sekundy...
    SLASH
    SLASH --- ---
    JAACOB: wow, diki moc, je tam zopar uzitocnych typov!

    Sekvencie ma zatial nenapadlo moc pouzivat zdalo sa mi ze by to zbytocne koplikovalo veci,
    aj ked som uz predtym pouzival Timeline animations s balika GSAP pre AS3/JS...

    Ale dam tomu sancu, ako vravis, ma to aj vyhody...

    Ten koplikovany destroy tam bolo kvoli tomu ze pouzivam extenziu UIParticles ktora sa musi odpalit samostatne predtym nez sa zavola Destroy na gameobject... Inac to tam vyhodi Error / Runtime Exception :(

    Ten BetterImage je sucastou tohto balika: https://assetstore.unity.com/packages/tools/gui/better-ui-79031

    Su tam celkom dobre vychytavky pre UI komponenty, napriklad na tom Image si mozes navilit material ktorym potom ovladas Brightness / Hue / Saturation, co ti dovoluje robit zaujimave efekty.
    Asi najviac z toho pouzivam funkcionality "Keep border aspect ratio" ktora ti zaisti rovnemerne skalovanie borders obrazkov.
    JAACOB
    JAACOB --- ---
    SLASH: fju to je teda divokej zapis! Pri kliku startujes dva solo tweeny, dalsi rizeni pres invoke repeating, trocha casovani, trocha pricitani...jako bonus nevim co je BetterImage a jestli do toho nemuze nejak vrtat anebo jestli treba nahodou tyhle objekdy nejak neprepouzivas / necachujes (doufam teda, ze ne).

    Par veci:
    - nemas zabezpeceny, ze kdyz na item kliknes jednou, tak ze uz nekliknes podruhe (jestli to ma byt nejaka "finalize" animace, tak v tom minimalne odregistruj click handler, nebo checkni, jestli uz neanimujes nahodou a dalsi klik zahod.

    - u tweenu - kdyz kombinujes nekolik efektu v poradi, pouzivej radeji DOTween.Sequence(), kde nahazes nekolik tweenu za sebou pomoci .Append() anebo na libovolne misto pomoci .Insert(). Jako bonus - kdyz z bezpecnostnich duvodu tweeny treba v Destroy killujes nebo dokoncujes, budes resit jen jednu sekvenci, ne pet ruznych samostatnych tweeneru pro jeden item...

    - v tom destroy jak likvidujes postupne komponenty jednoho gameobjektu - je to potreba? To je nejaky particle system referencovany nekde jinde na jinem gameobjektu a ridi se vymazanim tehle komponenty? Muzu se plest, ale ze zapisu mi pripada, ze proste v destroy resis nejake smazani gameobjektu, co ma na sobe efektiky a podobne - ze nechces vlastne jen selektivne promazavat komponenty, ale smazat cely gameobjekt. Tak to neres. Proste nekde zavolej Destroy(hunt.gameObject) a on proste vystreli cely gameobjekt se vsema podvesenyma komponentama a podobne..

    - to rizeni animace a delegace kliku na nekolika mistech pomoci ruznych casovani a navic jeste pomoci Invoke/InvokeRepeating je cesta do pekel. Kdyz uz musis, pouzij aspon coroutiny - pokud by se tweeny neprolinaly, da se normalne yieldovat jeden tween za druhym:

    yield return punchScaleTween.WaitForCompletion();
    yield return coin.DOFade(0, .4f).SetEase(Ease.OutQuad);

    - anebo to v tomhle pripade, kde se ty tweeny prolinaji a podobne - nech teda odridit celou flow tou tween sekvenci. Zvlada i volat callbacky bud kdykoli v prubehu sekvence nebo se da hooknout na konec sekvence, takze mas jistotu, ze to bude posledni vec. Navic se pri destroyi da volat .Complete(true) misto .Kill(), aby vsechny zavazane callbacky zavolal. U toho obcas pouzivam fintu, ze na .OnComplete() rferenci na tween/sekvenci smazu, takze v nejakem destroy vim, jestli jeste jede nebo ne a podle toho cistim.

    Takze za me - bych tech par veci (naslepo - nerucim za 100% funkcnost) prepsal aspon zhruba takhle (mrkni hlavne na kod kolem showFoundAnimation, rotation a destroy): https://pastebin.com/12J8SUAd
    SLASH
    SLASH --- ---
    Pouzivate tu niekto DOT tween?

    Mam taky problem, ten kod dole je pre objekt ktory ked sa klikne prehra sa casticova animacia a tiez scale animacia a potom to ma fade out. Vsetko funguje pomerne dobre, az na to ze obcas sa stava ze mi ten object ne fadne out. proste len tak ostane visiet z full opacity az kym sa neznici cez ten nacasovany destroy. Ked ale komentnem out co je v OnDestroy handlery, tak to funguje ok...

    netusite v tom by to mohlo byt?

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using DG.Tweening;
    using Sirenix.OdinInspector;
    using TheraBytes.BetterUi;
    using UnityEngine;
    using UnityEngine.Serialization;
    using UnityEngine.UI;
    using UnityEngine.UI.Extensions;
    
    public class Hunt : MonoBehaviour
    {
        [PreviewField] [SerializeField] private List<Sprite> availableSprites;
        [SerializeField] private List<Sprite> frames;
        [SerializeField] private Button btn;
        [SerializeField] private RectTransform huntRT;
        [SerializeField] private BetterImage coin;
        [SerializeField] private ParticleSystem sparkles_ps;
        [SerializeField] private ParticleSystem glow_ps;
    
        [NonSerialized] public Action<Hunt> onItemClicked;
        [NonSerialized] public Vector2 pos;
        private Tween fadeTween;
        private int nextFrame;
        private int totalFrames;
        private Color col;
        private ParticleSystem.MainModule mainPs;
        private Tweener punchScaleTween;
    
        void Start()
        {
            btn.onClick.AddListener(showFoundAnimation);
    
            totalFrames = frames.Count;
    
            var rnd = GuessItemsPanel.rnd;
            var rndInt = rnd.Next(0, availableSprites.Count);
            var randomSprite = availableSprites[rndInt];
            coin.sprite = randomSprite;
            nextFrame = int.Parse(randomSprite.name);
    
            var wid = Screen.width;
            var webWid = wid * .1f;
    
            //resize
            huntRT.sizeDelta = new Vector2(webWid, webWid);
    
            //first color
            var randomAlpha = rnd.Next(25, 65);
            col = Color.white;
            col.a = randomAlpha / 100f;
            coin.color = col;
    
            //second color
            randomAlpha = rnd.Next(30, 60);
            col = Color.white;
            col.a = randomAlpha / 100f;
            coin.SecondColor = col;
    
            //Particle Setup
            //resize the radius and startsizes
            var containWid = huntRT.rect.width;
    
            //set aprticle radius
            mainPs = sparkles_ps.main;
            var shape = sparkles_ps.shape;
            shape.radius = containWid * .5f;
    
            //set particle size
            mainPs.startSize = new ParticleSystem.MinMaxCurve(containWid * .2f, containWid * .5f); //10 - 50 ?      
            glow_ps.startSize = wid * .25f;
    
            pos = transform.position;
        }
    
        private void showFoundAnimation()
        {
            nextFrame = 0;
    
            //change alpha to 1
            col.a = 1;
            coin.ColoringMode = ColorMode.Color;
            coin.color = col;
    
            //start 3d rotation
            InvokeRepeating(nameof(rotate3D), 0, .015f);
    
            sparkles_ps.Simulate(0);
            sparkles_ps.Play();
    
            glow_ps.Simulate(0);
            glow_ps.Play();
    
            int vibrato = 4;
            float duration = 1.2f;
            float elasticity = 0.2f;
            int maxFrames = 50;
            Vector3 targetScale = new Vector3(1.2f, 1.2f, 1.2f);
    
            punchScaleTween = huntRT.DOPunchScale(targetScale, duration, vibrato, elasticity);
            fadeTween = coin.DOFade(0, .4f).SetEase(Ease.OutQuad).SetDelay(0.8f);
        }
    
    
        private void rotate3D()
        {
            coin.sprite = frames[(nextFrame) % totalFrames];
            nextFrame++;
            if (nextFrame == 25) onItemClicked?.Invoke(this);
            if (nextFrame == 50) CancelInvoke(nameof(rotate3D));
        }   
        
    
        private void OnDestroy()
        {
            
            if (sparkles_ps)
            {
                sparkles_ps.Clear();
                Destroy(sparkles_ps.GetComponent<UIParticleSystem>());
                Destroy(sparkles_ps);
            } 
            
            if (glow_ps)
            {
                glow_ps.Clear();
                Destroy(glow_ps.GetComponent<UIParticleSystem>());
                Destroy(glow_ps);
            }
            
            CancelInvoke(nameof(rotate3D));
            fadeTween?.Kill();
            punchScaleTween?.Kill();
            btn.onClick.RemoveListener(showFoundAnimation);
        }
    }
    
    
    SHIGORBIRDMAN
    SHIGORBIRDMAN --- ---
    btw "Aspon nieco jednoduche co rozozna oblohu stromy , travu a pod..." jeste pred deseti lety bych se takovemu dotazu smal nahlas ;)
    SHIGORBIRDMAN
    SHIGORBIRDMAN --- ---
    SLASH: jako moc neverim, ze by existovala nejaka knihovna primo v c#, mozna tak nejaky wrapper... (byt s burstem by mohla byt zajimava implementace i primo v "c#".).

    Kdysi davno jsem si chvilku hral s vuforia, to je afaik uprednostnovana AR knihovna pri unity, ale nemam zdani v jakem je to ted stavu....
    SLASH
    SLASH --- ---
    Skusali ste niekto v Unity semanticke rozoznavanie objektov v obrazku ( Object Class Image Segmentation / Semantic Image Segmentation) ?
    Hladam nejaku kniznucu v C# ktora by sa dala na toto implementovat. Aspon nieco jednoduche co rozozna oblohu stromy , travu a pod...
    MAIMONIDES
    MAIMONIDES --- ---
    JAACOB: Dost dobrý!
    JAACOB
    JAACOB --- ---
    Space Support by Jaacob
    https://jaacob.itch.io/space-support

    Tentokrát jsme pro Ludum splácli ve třech jednoduchou endless survival hříčku ve vesmíru. Jste přepravní dron uprostřed meteorické bouře, která nabírá na obrátkách. Vaším úkolem je zásobování vesmírných stanic. Každá stanice něco vyrábí a průběžně něco potřebuje. Po čase chybějící suroviny začínají stanici poškozovat. Jde o to udržet co nejdéle při životě jak sebe sama, tak všechny stanice. HQ opravuje škody drona a v intervalech generuje důležité upgrady.
    SHIGORBIRDMAN
    SHIGORBIRDMAN --- ---
    Madscape (LD46) by Shigor
    https://shigor.itch.io/madscape-ld46

    Karantenni Ludum Dare game jam - MADSCAPE - tentokrat relativne jednoducha strategicko/logicka hricka. Puvodne to melo byt dost jine, ale na bezmyslenkovite trapeni mozkovych zavitu to docela funguje. (Startovni mapa jde vyhrat za par minut, velke muzou byt na hodinu dve... a nektere mozna vyhrat nepujdou, aspon ne za vsechny hrace / ve vsech modech).
    WEBGL i odkaz na PC verzi. Mozna se dokonce dokopu k udelani mobilni verze.
    SHIGORBIRDMAN
    SHIGORBIRDMAN --- ---
    (s ngui jsem ted malem musel zase po letech delat, ale nez delat archeovypravu, navic do kodu, ktery jsem nedelal, radsi jsem s diky odmitl... hackovat ho na keypad controller se mi fakt nechtelo, tim spis ze cast ui by se musela uplne predelat, aby to slo pouzit)
    SHIGORBIRDMAN
    SHIGORBIRDMAN --- ---
    MONKEYFIGHTER: tak to uplne stary bylo uplne k nicemu. imgui, ktery je dodnes v editoru, bylo proste vykonove totalne nepouzitelny... kdyz jsem pred lety poprve udelal build na prvni ipad a zkusil to a s prekvapenim zjistil, ze mam asi 3 framy za sekundu a 80% bere jednoduchy debugovy ui, tak jsem se dost vydesil :)
    MONKEYFIGHTER
    MONKEYFIGHTER --- ---
    SHIGORBIRDMAN: Jono, to stary ui sem chvili zazil a uz tam sme radsi pouzivali nGui(to delal tusim ten typ co jim pomahal s tim soucasnym?) takze jak odiky bohu aspon za to co tam je ted urcite.

    Jinak on v tom videu tvrdi ze to UI bude jeden drawcall vzdy coz mi vhledem k tomu ze to cpes vlastnima assetama kteray se na jeden atlas casto nevejdou pokud mas vic UI trochu smrdi... no nevim zkusim si v tom nejaky slozitejsi UI posladat a podivam se co to ve skutecnosti dela treba na mobilu)
    SHIGORBIRDMAN
    SHIGORBIRDMAN --- ---
    jeden draw call mozna dosahnou (pokud to je vubec mozne, cili atlasovane textury), ale bojim se, ze dynamicke zmeny budou vykonove jeste brutalnejsi peklo nez u soucasneho ui, kde muzes aspon optimalizovat rucne a pouzivat pooly atd...
    (ja to puvodne chapal ze to ma byt, KONECNE, nahrada editoroveho ui, ktere ma sice vyhodu extra rychleho masteni nejakych zakladnich tlacitek, ale vykon je osklivy)
    SHIGORBIRDMAN
    SHIGORBIRDMAN --- ---
    MONKEYFIGHTER: dalo by se, ale ta 3rd party byla vyslovene "namrdame to tam aby to bylo jako "moderni" ui v xml popisu a prolinkujeme to sem a tam a...
    A bohuzel u unity bych se fakt bal, ze to bude, minimalne zpocatku, hruzny bastl. Unity a UI bylo dycinky peklo. To soucasne se... celkem da. Ale to bylo na principu, ze koupili autora jednoho z nejpouzivanejsich 3rd party (ngui) a delali to s nim, v ramci moznosti celkem dobre.
    (a hlavne dali ven sources, takze vsechny ty posery ktere dokazali spachat pri upadtech, ktere delaly dost total breaking veci, se daly spravit / zmodifikovat pro use cases, se kterymi vubec nepocitali (jako treba virtualni kurzory)
    MONKEYFIGHTER
    MONKEYFIGHTER --- ---
    SHIGORBIRDMAN: jasne no, to je muj nejvetsi otaznik asi, kdyz rikaji ze bude cely UI jeden drawcall tak me zajima co bude stat ten jeden drawcall vygenerovat.

    ale zas si rikam ze by predelali kompletne cely UI od zakladu a udelali z toho nejaku pazravou vec v momente kdy performance je jedna z veci co dostavaj nejvic sezrat a evidentne se snazej s tim neco pomalu ale jiste udelat?

    U 3rd party xml based UI se nedivim ze to bylo v prdeli protoze takovouhle 3d party vec imho neudelas bez brutalniho overheadu?
    Kliknutím sem můžete změnit nastavení reklam