Zdravím, tvorím vlastnú strategickú hru v Unity na štýl Travian, DK atď. kde som sa dostal do menšieho problému so skriptom. Hra obsahuje produkcie surovín za hodinu kde som využil Time.deltaTime a všetko funguje ako má, lenže ak hráč vypne aplikáciu produkcie sa tým pádom zastavia čo nie je vôbec dobre...
Je to moja prvá hra a som prekvapený ako ďaleko som sa s ňou dostal lenže tento problém neviem vyriešiť. Premýšľal som že využijem aktuálny čas a nejako to prepojím s produkciami ale vôbec sa neviem pohnúť. Vedel by niekto niečo?
Unity3D - C# script
Unity3D - C# script
Spoiler: ukázať
Re: Unity3D - C# script
S Unity som uz dlhsie nerobil, ale skusim. Predpokladam, ze robis offline desktop aplikaciu v ktorej ak bezi hra, bezi aj produkcia. Dalej ak tomu rozumiem, tak kazdu hodinu pripisujes iste mnozstvo surovin a deltu pouzivas na zistenie, ci ta hodina ubehla. To je zaroven tvoj problem, lebo chces aby produkcia bezala aj vtedy, ak hra nie. Ak som to dobre pochopil, tak ma napada toto:
Predpokladam, ze mas implementovanu nejaku Save Game funkcionalitu, tak? Uloz si timestamp, potom pri load-e vypocitaj diff timestamp-u voci aktualnemu casu a z toho si doratas produkciu za danu dobu. Ak mas definovane ze 1 hod/ +x suroviny y, tak je to simple, deltu v tomto pripade nepotrebujes. Z diff-u tiez vies zistit, kolko ti zostava do skoncenia nasledujucej hodiny a dalej produkciu ratas od daneho casu.
Predpokladam, ze mas implementovanu nejaku Save Game funkcionalitu, tak? Uloz si timestamp, potom pri load-e vypocitaj diff timestamp-u voci aktualnemu casu a z toho si doratas produkciu za danu dobu. Ak mas definovane ze 1 hod/ +x suroviny y, tak je to simple, deltu v tomto pripade nepotrebujes. Z diff-u tiez vies zistit, kolko ti zostava do skoncenia nasledujucej hodiny a dalej produkciu ratas od daneho casu.
PC -> Topping DX7 Pro+ -> Meze 109 PRO / Microlab B77
Re: Unity3D - C# script
S Unity nerobím, ale tak vo všeobecnosti:
Travian beží nonstop online na serveri takže tam takéto problémy nie sú, počíta to server ktorý beží nonstop. To je jedna z možností ako to riešiť, prevádzkovať nonstop online server na ktorý sa budú hráči pripájať a ktorý to bude sledovať, teda ak je cieľom aj nejaká online zložka.
Čo sa offline týka materik ti pekne odpovedal, ale zostáva otázka jednoduchého cheatovania zmenou aktuálneho času v PC, a ošetrenia čo robiť ak timestamp v save je väčší ako aktuálny, čo sa môže stať v prípade posunu času dozadu (z akéhokoľvek dôvodu - predchádzajúci cheat na suroviny posunom času dopredu a teraz nastavil späť pôvodný čas, pôvodne mal zlý čas/dátum v PC a nastavil správny, posun letný/zimný čas...). V podstate máš niekoľko možností, suroviny sa odpočítajú a možno pôjdu do mínusu lebo rozdiel je záporný, suroviny sa pripočítajú lebo počítaš absolútnu hodnotu rozdielu timestampov alebo to ošetríš tak že v tomto prípade sa suroviny nezmenia alebo vypíšeš nejakú hlášku s upozornením...
Travian beží nonstop online na serveri takže tam takéto problémy nie sú, počíta to server ktorý beží nonstop. To je jedna z možností ako to riešiť, prevádzkovať nonstop online server na ktorý sa budú hráči pripájať a ktorý to bude sledovať, teda ak je cieľom aj nejaká online zložka.
Čo sa offline týka materik ti pekne odpovedal, ale zostáva otázka jednoduchého cheatovania zmenou aktuálneho času v PC, a ošetrenia čo robiť ak timestamp v save je väčší ako aktuálny, čo sa môže stať v prípade posunu času dozadu (z akéhokoľvek dôvodu - predchádzajúci cheat na suroviny posunom času dopredu a teraz nastavil späť pôvodný čas, pôvodne mal zlý čas/dátum v PC a nastavil správny, posun letný/zimný čas...). V podstate máš niekoľko možností, suroviny sa odpočítajú a možno pôjdu do mínusu lebo rozdiel je záporný, suroviny sa pripočítajú lebo počítaš absolútnu hodnotu rozdielu timestampov alebo to ošetríš tak že v tomto prípade sa suroviny nezmenia alebo vypíšeš nejakú hlášku s upozornením...
Spoiler: ukázať
Re: Unity3D - C# script
@wingo: Dobry point so zmenou casu, mozno by to vedel vyriesit call na nejaku free API-nu a ukladat UTC cas, miesto pouzita systemoveho casu. Hned vsak vidim problem, ze co robit, ked si offline?
PC -> Topping DX7 Pro+ -> Meze 109 PRO / Microlab B77
Re: Unity3D - C# script
Nad tým cheatom pomocou zmeny času som práve premýšľal lebo som to používal v každej hre kde to išlo. Tak budem to musieť vývoj pauznuť a začať zisťovať ako to spraviť pomocou nejakého servera alebo multiplayer-a ktorý ponúka unity. Neviem o tom v podstate nič takže teraz mám čo robiť kým si to naštudujem ... Ak to zvládnem tak pomocou servera hneď načítam serverový čas a podľa toho času sa budu vypočítavať aj produkcie či odpočítavať časy upgradovania budov.
Spoiler: ukázať
Re: Unity3D - C# script
Ak ti ide len o čas nemusíš mať vlastný server ani riešiť žiadny multiplayer ak ho nechceš implementovať, ako spomenul materik môžeš využiť nejaký free server s aktuálnym časom. Existuje kopec public NTP serverov, len ako z nich zisťovať aktuálny čas cez NTP protokol si musíš zistiť ty, predpokladám že nejaký vzorový skript nájdeš
V prípade nedostupnosti servera jednoducho môže hra vypísať že funguje iba keď si online a basta. Hlavne toto rieš iba pri save a loade (a NewGame) a nedopytuj online aktuálny čas každú sekundu, ten deltatime už máš poriešený
V prípade nedostupnosti servera jednoducho môže hra vypísať že funguje iba keď si online a basta. Hlavne toto rieš iba pri save a loade (a NewGame) a nedopytuj online aktuálny čas každú sekundu, ten deltatime už máš poriešený
Spoiler: ukázať
Re: Unity3D - C# script
Tu mas free API, kde dostanes UTC cas. Skus si najprv toto, lahsie ako kodit vlastny server.
A tu mas tutorial ako spravit connection na WEB API.
A tu mas tutorial ako spravit connection na WEB API.
PC -> Topping DX7 Pro+ -> Meze 109 PRO / Microlab B77
Re: Unity3D - C# script
Asi som si to premyslel a bude to offline hra bez netu. Síce som si pozrel všetko čo ste mi radili ale tak pracujem na tej hre sám a nejdem si to zbytočne komplikovať lebo by som tu hru ani nedokončil, tak si dám račej jednoduchší cieľ s tým že to časom aj dokončím a hlavne sa pri tom viac toho naučím.
Takže asi to spravím tak, že vytvorím vlastný herný dátum ačas kde hra sa bude začínať napr. v roku 2030 a vtedy sa čas spustí. Produkcie budu podľa herného času takže zmena systémového času nebude môcť byť využitá ako cheat a ak hráč nebude v hre tak ani samotná hra nebude bežať. Takže ako klasické stratégie na PC. Tým by som aj donútil hráčov aby trávili viac času v hre. Multiplayer tam ani neplánujem pridávať maximálne nejakú štatistiku aby sa mohli hráči obehovať v počte bodov.
Čo sa týka toho herného času tak si to predstavujem nejak tak, že si zadefinujem začiatok hry pomocou:
DateTime GameTime = new DateTime(2030, 1, 1, 10, 00, 00);
... a potom ho nejako spustím no ešte som neprišiel na to ako... možno využiť niečo ako deltaTime:
FuelTime.AddSeconds((+1) * Time.deltaTime);
...len že to mi nefungovalo
Takže asi to spravím tak, že vytvorím vlastný herný dátum ačas kde hra sa bude začínať napr. v roku 2030 a vtedy sa čas spustí. Produkcie budu podľa herného času takže zmena systémového času nebude môcť byť využitá ako cheat a ak hráč nebude v hre tak ani samotná hra nebude bežať. Takže ako klasické stratégie na PC. Tým by som aj donútil hráčov aby trávili viac času v hre. Multiplayer tam ani neplánujem pridávať maximálne nejakú štatistiku aby sa mohli hráči obehovať v počte bodov.
Čo sa týka toho herného času tak si to predstavujem nejak tak, že si zadefinujem začiatok hry pomocou:
DateTime GameTime = new DateTime(2030, 1, 1, 10, 00, 00);
... a potom ho nejako spustím no ešte som neprišiel na to ako... možno využiť niečo ako deltaTime:
FuelTime.AddSeconds((+1) * Time.deltaTime);
...len že to mi nefungovalo
Spoiler: ukázať
Re: Unity3D - C# script
Trochu nechapem tvojmu Game Design-u. Nakolko si sa rozhodol odstranit off-line produkciu, teda ked hra nebezi, tak co chces osetrovat pouzitim specialneho casu?
Ak mas produkcie definovane v nejakom konfiguraku ako casovy udaj (napr. 60000ms), tak je uplne jedno, co si user robi so systemovym casom. Ty si vzdy rataj prejdeny cas na zaklade delty a ukladaj si cas, ktory stihol ubehnut predtym, ako user ulozil hru.
Nieco take:
Hre je tak uplne jedno, ci je systemovy cas 20 rokov pozadu, alebo 30 v buducnosti.
Ak mas produkcie definovane v nejakom konfiguraku ako casovy udaj (napr. 60000ms), tak je uplne jedno, co si user robi so systemovym casom. Ty si vzdy rataj prejdeny cas na zaklade delty a ukladaj si cas, ktory stihol ubehnut predtym, ako user ulozil hru.
Nieco take:
Kód: Vybrať všetko
60000ms passed => addResources()
45352ms passed && event.saveGame => saveGame(45352) // public boolean saveGame(float timeThatPassed) { ... }
LOAD:
if (!!timeThatPassed) {
deltaStart = timeThatPassed;
} else {
deltaStart = 0;
}
PC -> Topping DX7 Pro+ -> Meze 109 PRO / Microlab B77