Nauka C# i problemy z nauką


#21

Dla mnie decyzja o napisaniu czegoś z palca albo użyciu biblioteki to nie jest łatwa decyzja.
Jak ktoś nie ogarnia i łapie każdą nową technologię i każdą bibliotekę po nazwach funkcji nie rozumiejąc co to robi i do czego służy to jest po prostu nieprofesjonalny.

Dla takich ludzi jest stanowisko juniora i taką osobę trzeba pilnować żeby czegoś nie rozwaliła, czy to własnym kodem czy bibliotecznym - bez różnicy.

Jak dla mnie to właśnie większe projekty mają prę MB w d*** bo się dołoży parę złotówek na większy serwer a nie ma czasu tego poprawiać. Oczywiście są sytuacje gdzie wielkość ma znaczenie… typu limit MB na pakę mobilną. (apka do podcastów sprawiła że musiałem kupić nowy telefon bo ciągnie kilka GB podcastów do preloadu…) Ale naprawdę rzadko kiedy parę MB na bibliotekę ma istotne znaczenie projektowe.

Wycieki pamięci to inna sprawa, ale sensowne użycie biblioteki zakłada sprawdzenie czy biblioteka jest choc troche popularna. Jeśli ktoś tego używa to może jednak nie cieknie albo trzeba podnieść wersje do poprawionej. I jednak ten open source jest modny więc jak jest open source i cieknie to można pobrać kod, poprawić wyciek i używać własnego brancha. Tylko właśnie pod opiekę trafiła masa niepotrzebnego kodu to może lepiej w takiej sytuacji przepisać na kod z palca albo zmienić bibliotekę. To nie są proste decyzje.

Za to dociąganie losowego niepotrzebnego syfu ma duże znacznie projektowe bo jest bałagan i taki kod robi mnóstwo losowych problemów. Głównie przy migracji czegoś faktycznie użytecznego do wyższej wersji albo migracji na inna platformę gdzie ten crap okazuje się nie portowalny.

Tak czy siak cała dyskusja jest kompletnie nie na temat bo nowa osoba musi się najpierw nauczyć robić cokolwiek żeby działo jakkolwiek.
A potem nauczyć robić to sensownej jakości.

Nie widzę sensu zalewać kogoś kto wałsnie prubuje ogarnąć swój pierwszy język informacjami o horror stroies ze źle prowadzonych projektów.

Zwłaszcza że tutaj d*** dał senior, który powinien projektu pilnować.
A nie losowy kontraktor co zrobił jak umiał, a umiał nie najlepiej i wyszło słabo…

Zwłaszcza że od licencji to trzeba prawnika a nie programisty…
Ja miałem kurs na studiach i mi wyjaśnili co oznacza
GPL - licencja “hipisów” co chcą żeby cały kod był wolny, nie używać komercyjnie bo propaguje się na cały soft
Niestety większość licencji jest po prawniczemu i ciężko ogarnąć o co chodzi.
Sam użyłem gorszej biblioteki bo lepsza miała nie dość że płatną licencję to jeszcze nie wiem nawet jak ją rozliczyć w chmurze na serverless gdzie terminy użyte w licencji nie miały żadnego sensu.
A z nugeta obie ściąga się tak samo jednym kliknięceim.

Dalej nie wiem jak niby początkujący ma ogarniać licencje żeby Januszsoft nie stracił milionów jak nie ogarnia prowadzenia swojej własnej działalności i nie zatrudnił sensownego deva do nadzoru projektu.

Btw naruszenie licencji to jest chyba grzywna ok 3 krotności adekwatnej opłaty licencyjnej, a nie armagedon. (No chyba że GPL bo to trzeba usunąć i przepisać, albo wysłać cały własny kod klientom którzy maja apkę.) Coś takiego kojarzę z kursu. Ale takie rzeczy to z prawnikami a nie z developerami… w sumie nie wiem jak wygląda prawdziwy proces o naruszenie licencji GPL. Ktoś z tego projektu GPL musiałby zaskarżyć że jest używany. Kto tam jest stroną i jak to ma wyglądać…
Ma ktoś jakiegoś linka?

Dalej nie wiem co to ma do nauki programowania… trochę mocny offtop.


#22

ale dyskusja :D, przydała by się nagroda złotej łopaty dla nowego kolegi :D,


#23

Właśnie chciałem sobie podyskutować i mało aktywnych wątków to została mi nekromancja :confused:

warsztat.gd też raczej mało żywe

jest jakieś nowe community koło amatorskiego gamedevu?
jakieś facebooki? discordy? slacki? inne dziwa?


#24

gamedev to nie instagramowe ploteczki gdzie każdy jest specjalistą i wszystko wie i o wszystkim pisze, tutaj raczej wypowiadają się osoby które mają problemy bądź szukają pracy/zespołu, ale jak chcesz podyskutować to mam kilka problemów :D,
tworzę prosty generator terenu oparty o marchingcubes i
1- shader który zrobiłem tworzy takie brzydkie coś

(czerwony zolty to dwa różne materiały powinno generować prosty pasek a wychodzi co wychodzi.
dane do teksturowania pochodzą z UV każdy z wierzchołków trójkąta posiada odpowiednio współrzędne (1,0,0),(0,1,0),(0,0,1) do nich są przypisane tekstury
jak się pozbyć tego zaznaczonego na niebiesko ?
2- chciałbym dodać LOD do terenu ale problem stanowi połączenie siatek mesh :l
3- pathfinding (planuje kopiować/ tworzyć siatkę mesh w locie przypisaną do chunk’a), ale nie wiem czy to się sprawdzi
4- mam już wstępnie przyszykowany model poruszania się ale ma jedną wadę, nie przewiduje przemieszczenia się tylko działa reaktywnie (np collider postaci jest przesunięty po czym zostaje sprawdzone czy na nowej pozycji się nie ześlizgnie w dól jeśli tak to się ślizga :/)


#25

AD 1
pokombinowałbym z jakimiś debugowymi tekturami żeby lepiej zwizualizować gdzie jeszcze są artefakty i jakiego typu
Bo tu jest jedno przejście czerwony - żółty a pewnie jest więcej artefaktów tej transformacji,
a zakładam że powinna być ciągła i takie artefakty inna tekstura powinna pokazać
np płynne przejście po odcieniach szarości nałożyć i zobaczyć jak tam się zachowa shader.
Konkretnie shaderów nie pisałem ale ogólne issues z kodem mogę coś znaleźć.
Jak najprostsze środowisko do replikacji buga + kod mogą pomóc zdiagnozować problem
Da się twój shader wrzucić np na https://www.shadertoy.com/ tak żeby można było się nim pobawić?

AD 2
Hmm marching cubes brzmi dość elastycznie.
Co do nieciągłości na granicach nie wystarczy dokleić węzłów bardziej szczegółowej siatki do węzłów i krawędzi siatki mniej szczegółowej na złączeniu? W sensie wygenerować współrzędne na obu częściach. A potem skleić krawędź na wspólnej prostej rzutując bardziej szczegółowe na mniej szczegółową łamaną po osi w góra<->dół. Jak siatki się zgadzają to nie parzyste po prostu skopiują mniej szczegółową siatkę a parzyste będą średnią sąsiadów. Czy czegoś nie rozumiem…

AD 3 Pathfiding się lubi bugować dramatycznie bez dodatkowej magii z dynamicznym generowaniem. Jak teren jest statyczny w grze lepiej byłoby wygenerować geometrię kolizji offline i ją tam po prostu wstawić. Jak ma się zmieniać teren w trakcie gry to gorzej ale też raczej bym to próbował jakoś obejść prostszym sposobem. Zwłaszcza że ogólny marching cubes to potrafi naprawdę porąbane funkcje wizualizować, a zakładam że funkcje do terenu to jednak góry doły i jedna płaszczyzna. Jak to ma poprawnie obsługiwać jaskinie, przewieszenia itp. to brzmi ciężko. Jak masz prostą funkcję wysokość (x,z) = y to nawet nie trzeba specjalnie silnika fizycznego tylko ustawić obiekt na wysokości y.
A pathfinding musi przede wszystkim jakoś wygenerować sobie graf możliwych ścieżek, tu nawet nie wiem jaki rodzaj terenu powinien być uznany za niemożliwy do przejścia… nachylenia stoków czy inne kryterium?

AD 4
Jak masz funkcje typu f(x,z) = y i nie udało się offline wygenerować jakiejś normalnej geometrii na której można puścić silnik fizyczny
to poruszałbym się tylko w osiach x,z i ustawiał na odpowiednią wysokość żeby nie spaść pod ziemię, jedyny problem to to żeby nie zasuwać za bardzo pod górkę i odpowiednio przyspieszać spadając. Ale to brzmi na coś co można dochaczyć kilkoma testami typu
if (y_start - y_end > dt * maxGoUpPerSecond) dont_move = true;
if (y_start - y_end < dt * maxFallPerSecond) inAir = true;
Plus pewnie trace Kolizją gracza czy nie włazi na coś interaktywnego/ze statyczną geometrią
Sporo zależy od docelowego gameplayu i innych elementów.
Np jak chcesz tam np rzucać piłkę na silniku fizycznym to jednak trzeba będzie wygenerować geometrię kolizji. A jak już masz geometrię kolizji to pewnie można jej też użyć dla gracz itp.
Ale zależy od gameplayu.


#26

Odpisałem Ci na slacku warsztatu :slight_smile:

discordy: Polski serwer indiegamedev Discord

facebooki też są, ale nie jestem w stanie polecić bo unikam tego pożeracza czasu :smiley:


#27

nie napisałem chyba wcześniej więc pisze teraz robię na unity 2020
shader zrobiony w shadergraph :confused: problem jest przy próbkowaniu współrzędnych UV na rodzaj materiału, z teksturami wygląda tak (pochyłe elementy są rozmazane bo korzystam z triplaner’a a dla uproszczenia na ten moment jest tylko jedna tekstura)


tak wygląda wierzchołek z maską

czerwoną linią zaznaczyłem jak jest odcinana maska a aby pozbyć się artefaktów powinna być łukiem ?

  1. brzmi elastycznie :smiley: bo takie jest, w moim przypadku mam 14 unikalnych kombinacji siatki mesh łącznie 256 kombinacji idąc dalej i chcąc wygenerować to ręcznie będę miał od groma łączeń siatek low high (zakładam że tak przynajmniej 256256 (nawet nie tyle bo zakładając skale 2:1 bedzie 4256*256), nie dodam tego ręcznie trzeba zrobić to automatycznie tylko jak ;l

  2. tak wyglada kod
    https://pastebin.pl/view/c14a7f30
    i jak pisałem działa REAKTYWNIE, dopiero po przemieszczeniu przez silnik fizyki unity są sprawdzane obliczenia, a aby to działało poprawnie musiałbym najpierw wykonać sprawdzenie po czym dopiero przemieszczenie/ bądz jeśli postać chce iść za bardzo pod górkę to go zatrzymać/ pchać wzdłuż przeszkody


#28

Może jakiś inny temat założyć bo to z nauką C# ma już zupełnie nic wspólnego

AD 1
Ta zielono niebieska wizualizacja fajnie pokazuje issue.
Jaki jest input do tego shadera?
Bo mam problem ze zrozumieniem jaki jest input i jaki ma być efekt


Na tym konkretnym bugu wydaje się że powinno pójść przejście po krawędzi A
Ale to działa tylko dla mieszania 2 tekstur… jeśli tam mogą byc 3 różne tekstury na każdym z wierzchołków to trochę nie wiem jak miałby wyglądać ten trójkąt wewnątrz ABC już nawet nie mówiac o implementacji… brzmi jakby tam były potrzebne jekieś dodatkowe parametry które pozwolą określić którędy idą podziały na poszczególne tekstury wewnątrz samego trójkąta, bo najbliższy z wagami to wyjdą jakieś takie latawce…

AD 2
jeśli dobrze rozumie to masz jakiegoś grida i generujesz te trójkąty czymś w stylu
for each (grid_Part)
{
for (int x = gridx0; x <= gridx1; x+= gridLODdensity)
{
for (int y = gridy0; y <= gridy1; y+= gridLODdensity)
vertexPosition = f(x,y,z?);
}
}
Trzeba wziać te wierzchołki wygenerowane na złączeniach czyli z tym samym x = gridx0;
i “skleić” z tymi wygenerowanymi dla kawałka obok z tym samym x = gridx0;

Jak już masz je np w jakiejś tablicy to potem skleić funkcją z logiką z pseudokodem typu:

List Glue (List edge1, List edge2, vector3 edgeDir)
{
var newEdge = new List();
if (edge1.Size < edge2.Size ) {var tmp = edge1; edge1 = edge2; edge2 = tmp;}
// edge1.Size jest teraz zawsze “gęstszą” siatką, doklejam edge 1 do edge 2
var glueIdx = 0;
foreach (var v in edge1)
{
var vDist = v.Dot(dir); // odległość wzdłuż ośki
if ( vDist > edge2[glueIdx].Dot(dir)){
++glueIdx;
}
var prev = edge2[glueIdx].Dot(dir);
var next = edge2[glueIdx+1].Dot(dir);
var alpha = (vDist - prev)/(next-prev);
newEdge.Add(Lerp(edge2[glueIdx],edge2[glueIdx+1], alpha ));
}
return newEdge;
}

Tylko tam trzeba to dobrze napisać żeby przekazać do Glue odpowiednie krawędzie i podmienić wierzchołki tej gęstszej siatki. I zakłądam że to generujesz jednak po gridzie 2d generując wysokość,
tak że na danej płaszczyżnie łączącej kawałki LOD po obu stronach jest łamana tylko z inną rozdzielczoscią. A nie zupełnie dowolną geometrię w 3d, bo wtedy to faktycznie nie skleisz jak jeden sześcian ma kawałek jaskini, a drugi w ogóle nie generuje tam trójkątów bo za niski LOD to takim prostym sposobem nie pójdzie…

AD3
Ok z tego co widzę robisz normalnego Raycasta sferą w dół i sprawdzasz w co trafiłeś i pod jakim kątem
(PS tego asin to lepiej nie liczyć w każdej klatce, tylko przeliczyć sobie kont na sinus na starcie i porównywać z y normalki, generalnie kąty w stopniach to w obliczeniach 3d raczej rzadko występują, łatwiej policzyć sinus/cosinus tego kąta i potem porównywać z rzutem na daną ośkę

zamiast magnitude przy raycast był w dół to chyba lepiej sprawdzić samą oś y,
zwłaszcza że losowe przesunięcie w płaszczyźnie x,z jak sfera zachaczy o coś obok środka nie powinno wpływać na to czy postać stoi czy lata)

Jak dla mnie to wygląda ok.
Sprawdzasz jaki jest teren w danej klatce, czy jest pod górkę, ustawiasz prędkość, przemieszczasz postać zgodnie z nową prędkością.
Dodałbym Ruch w osi Y w dół na koniec, niezależnie od osi x/z, żeby doklejać postać do ziemi.
To trochę zależy jak się konkretnie zachowuje fizyka przy różnych ruchach.
Ale potencjalnie ruch może mieć 3 fazy kiedy _lastFrameOnGround:
-> podnieść troche do góry (żeby wchodzić na małe przeszkody)
-> przesunąć w pląszczyźnie x,z
-> opuścić w dół o trochę więcej niż podniesiono, żeby dokleić do ziemi jeśli postać schodzi w dół po zboczu
I po tych 3 Move zrobiłbym trace gdzie teraz stoję i czy nie powinienem sfixować prędkości.
Tylko to bardziej na silniku który blokuje sie przy każdej przeszkodzie,
nie wiem jak zachowuje się
this.character.Move(move);
czy trochę się ślizga w górę i czy dociąga do podłogi

Przy sensownym FPSie i niskich prędkościach off by 1 frame nie powinno robić wielkiej różnicy.
Jak FPS jest niski albo prędkości duże trzeba w jednej klatce zrobić więcej iteracji pętli fizycznej tak żeby te odległości były sensowniejsze i żeby to reagowało jakoś sensowniej.


#29

a no nie jest to temat na to