#archived-code-advanced

1 messages · Page 1 of 1 (latest)

undone coral
#

even if you ensured that the await occurs on the main thread using await UniTask.SwitchToMainThread(), this statement await ... will permit the main thread to do other work while it waits for the result of the task (i.e., the meaning of the keyword await). however, if this is a network stream, WriteAsync returns immediately or returns an error at the time it is called.

#

i think everything else people are telling you is noise

#

and not relevant

#

or wrong

#

i am avoiding the use of the word blocking

#

it is a confusing word for a lot of people

wet sail
#

hi, can someone explain to me how do fixedUpdate and Update run on the same thread ? how is this possible since they are 2 different parallel loops ?

undone coral
#

since pistoleta is using unitask, there aren't any difficulties getting a task to run on the correct thread

#

if you need events, use UniRx

final steeple
#

I'm talking about when you're waiting synchronously on an asynchronous operation

wet sail
undone coral
#

if you want to see the real player loop, you can step through PlayerLoop.GetCurrentPlayerLoop() in the debugger.

undone coral
#

that is all it does

#

nothing more

#

the velocities, masses and positions are shipped off to physx, a library in the unity executable, which runs it all and gives it back to unity. unity decides whether or not to run another fixed update (and therefore physics timestep) if the rendering is so slow that you have not passed enough physics time relative to game time

#

@wet sail does that make sense?

wet sail
#

yea

#

but im asking how do they make it so that fixed update executes before update ?

undone coral
#

fixed update receives an amount of time Time.fixedDeltaTime, but that is not the same as wall clock time

undone coral
wet sail
#

yeah but wont monobehaviour.FixedUpdate(); freeze the thread ?

#

before monobehaviour.Update(); is called ?

undone coral
#

you've implemented fixed update

#

right?

#

like you've made a callback in a script called FixedUpdate

#

right?

#

have you ever done anything in a fixed update that "freezes the thread"?

wet sail
#

i know but im talking about the unity internals

#

how did they make the fixed update loop ?

undone coral
#

fixedupdate doesn't do anything

#

Physics.Simulate does

#

you can even call physics.simulate

wet sail
#

so basically fixed update is inside "update" ?

undone coral
#

no

#

is update being called inside of fixed update in my example above?

#

it's for loops (hence the "loop" in player loop)

wet sail
#

basically yes

undone coral
#

it's not

wet sail
#

if not then wouldnt the while delay the update() too ?

austere jewel
#

Update happens after FixedUpdate, so yes if FixedUpdate runs Update is delayed by it

undone coral
#

you are correct

#

it delays it in wall clock time

#

i'm going to delete my last thing because it's only going to confuse you more

#

it delays it in terms of wall clock time. Time.deltaTime, Time.time... are illusions

austere jewel
#

Time is pretend, and your code can be fed any time value and the simulation can be advanced at any rate.
FixedUpdate is just a loop that occurs before update and advances fixed time, simulating as many steps as needed in that frame. If not enough time has passed to run a simulation it won't run. If lots of time has passed it can loop many times. Simulation doesn't actually occur when fixedTime equals time, it's just advanced at fixedDeltaTime and kept at the same pace as Update

wet sail
#

alright im still confused a bit, one sec

#

alright so lets say this is our fixedUpdate

#
public void FixedUpdate(Action<float> Step)
        {

            int frameMilliseconds = _fpsCap < 0 ? 0 : 1000 / _fpsCap;
            Stopwatch stopwatch = new Stopwatch();

            int overTime = 0;
            float delta = 0;

            while (!_quit)
            {
                stopwatch.Restart();

                delta = (frameMilliseconds + overTime) * 0.001f;

                Step(delta);

                stopwatch.Stop();
                int stepTime = (int)stopwatch.ElapsedMilliseconds;

                if (stepTime <= frameMilliseconds)
                {
                    Thread.Sleep(frameMilliseconds - stepTime);
                    overTime = 0;
                }
                else
                {
                    overTime = stepTime - frameMilliseconds;
                }
            }
        }

#

where do update gets called then ??

undone coral
#

lol

#

it will be called after all the fixed updates are called

#

exactly like in my example

#

i wrote the snippet verbatim!

#

you see where update is called

#

i made it even easier for you to read

wet sail
#

your snippet says :
while // blocks thread for 60fps
update // called after the thread is blocked for 60fps

undone coral
#

that's right

wet sail
#

but thats not what happen

undone coral
#

that is exactly what happens

wet sail
#

update runs faster

undone coral
#

what i wrote in the script

#

EnoughPhysicsTimeHasPassed can be true

wet sail
#

how does update runs faster / slower ?

undone coral
#

that's how, and the body of the while loop is skipped

#

so it sounds what you're really confused by is EnoughPhysicsTimeHasPassed

#

and CalculatePhysicsTimestep()

#

does that sound right?

wet sail
#

EnoughPhysicsTimeHasPassed is what ?

#

60fps ?

undone coral
#

no it's a bool

wet sail
#

yeah i mean when its true ?

undone coral
#

the documentation explains how it works

#

you don't want your physics simulation to be too far behind or too far ahead

#

if your physics has been evaluated up to 1.2s of game time, and you've finished 1s of game time, and your physics timestep is 0.2s, EnoughPhysicsTimeHasPassed will be true.

#

is that helpful?

#

sometimes, when starting a new frame, for the first time EnoughPhysicsTimeHasPassed is true, so fixed update is not called at all that frame

#

and physics is not simulated that frame

#

does that make sense?

#

the snippet i showed is executed every frame

wet sail
#

so physics simulation is inside frame loop ?

#

and so is fixed update ?

undone coral
#

it is exactly where i wrote it yes

wet sail
#

but isnt update the frame loop ?

undone coral
#

no

#

Update is a method

#

if you're asking what it is for real

#

it's a method that gets called in a loop at the "right time"

#

its purpose is to give you a chance to change transforms and other render-impacting code in an ergonomic way

wet sail
#

so the delta of update isnt difference between 2 frames ?

#

FrameLoop = { Update + FixedUpdate } right ?

#

FrameLoop has a delta

#

itself

undone coral
#

what you are calling FrameLoop consists of everything in the array PlayerLoop.GetDefaultPlayerLoop()

#

it should be clear to you what it's real name is 🙂

#

Update and FixedUpdate are callbacks

#

they are called by objects in the array returned in PlayerLoop.GetDefaultPlayerLoop()

#

listen i don't know why unity doesn't document this!

#

player loop didn't exist until recently

#

since 2015 or whenever they wrote that execution order thing

#

because reality is super confusing

#

everything that the document says is true

#

so i think i have answered your question

#

i think you are confused by "sometimes, when starting a new frame, for the first time EnoughPhysicsTimeHasPassed is true, so fixed update is not called at all that frame"

#

if you have advanced your physics simulation enough, you don't simulate physics

#

the consequence is fixedupdate is never called during a frame

#

that seems to be what you are hung up on

#

you also thought that making fixedupdate take longer means physics simulated for a longer timestep

#

it doesn't

#

Physics.Simulate(timestep) doesn't refer to a timestep in wall clock time

#

it refers to a time step in game logic time

#

is that helpful?

wet sail
#

yea

#

what is wall clock

undone coral
#

fixedupdate doesn't have anything to do with simulating physics

#

Physics.simulate is not called inside fixedupdate

#

so there's no physics simulation happening there, right?

#

you see in my snippet where it is called

undone coral
#

the time written on the clock on your wall

wet sail
#

alright

undone coral
#

colloquially people call fixedupdate the "physics" but it's not

wet sail
#

i got the physics simulation part

#

but there's still sth bothering me

#

what is deltaTime ?

#

is it playerLoop delta ?

undone coral
#

what can i do. game developers also do not name period and frequency correctly

wet sail
#

tbh unity should have named it OnBeforePhysicsLoop

#

for example

undone coral
#

look at the thing i've been telling you to

#

a bajillion times

#

you can see what all the loops are called

#

and there's something like that

calm ocean
#

Is it better to call EventSystem.current or find the event system with tag, assuming my scene only has one event system

undone coral
#

it is an array with like 27 elements in it on HDRP

undone coral
calm ocean
#

Using it for SetSelectedGameObject

undone coral
# wet sail is it playerLoop delta ?

more or less yes. consider that if your game is in the background and is not rendering, wall clock time passes but Time.deltaTime will still give the right answer

wet sail
#

so IRL the physics.Simulate isnt called at a fixed time right ? cuz what guarantees the PhysicsTimePassed that flags the EnoughPhysicsTimeHasPassed to be precise ?

undone coral
#

however, that calculation doesn't get called every time you call Time.deltaTime

#

it is done before the calls to update

#

Time.deltaTime gets a float out of a field. it doesn't compute anything

#

hmm

#

i'm worried i just confused you more

undone coral
wet sail
#

no i got it

undone coral
#

or how this relates to your application

undone coral
wet sail
#

im trying to re-implement the Monobehavior methods for fun

wet sail
#

to undesrtand it more

undone coral
#

got it

#

well

#

you should be looking at PlayerLoop then

#

you can also look at the profiler

#

you'll see every object in PlayerLoop make an appearance on the main thread in profiler

#

when you're viewing the timeline

austere jewel
#

it's just incremented at a fixed rate. As long as the latest one has occurred that you expected before Update happens so you have the right visuals, when it's called doesn't matter.

undone coral
#

or to understand it

#

good luck out there

wet sail
#

i see

#

thank you guys

undone coral
#

if you're using stopwatch you're doing something wrong

wet sail
#

wut

undone coral
#

i'm deleting the message where i said what time.delta time was

#

yeah

#

i think that's the takeaway

#

in all of player loop, there is exactly one place where "stopwatch" is used, and that's if and only if you finished the frame faster than the speed implied by Application.targetFrameRate and vsync

#

you will look at the profiler and eventually comprehend that stopwatch is not used anywhere in reality

#

so if you're using it to implement Time.deltaTime, you haven't done it right

#

for example, if your game renders only 1 frame per second because it's so busy, but your application.targetFrameRate is 60, Time.deltaTime will still be something, but neither 1/60th nor 1.0

austere jewel
undone coral
#

and what it's actually measuring

wet sail
#

this change everything

undone coral
#

sorry

#

i fixed that

#

it wasn't true

wet sail
#

alright hahahahaha

undone coral
#

you don't know what it's measuring is the problem

#

it's estimating how long until you will render

#

so that by the end of Update and the start of OnBeforeRender, the right amount of movement has occured

wet sail
#

yea

undone coral
#

if you are using it for something like modifying a transform

#

anyway i gotta go

wet sail
#

yea thanks for help

distant pivot
flint geyser
#

How does Dependency Inversion Principle not violate SRP? We will also have to take over responsibility of satisfying abstraction... Also using DIP implies having circular references between assemblies

long ivy
#

There isn't a short answer. Why do you think it violates SRP? And circular references suggests you have things tightly coupled still, which is exactly what you're trying to avoid with DI

tough knoll
#

A breakdown of the update loop and how deltaTime is calculated

wet sail
#

yea vertx linked that

flint geyser
# long ivy There isn't a short answer. Why do you think it violates SRP? And circular refer...

I saw an example with a class which parsed some logs in various formats to the needed one and pushed it to a database. As example of DIP there was created an interface with the method of parsing which further would be implemented by different log classes
Here I see how log classes also contain responsibility of providing parsing implementation and also depend on the interface supposedly located in the same assembly as the class which will call parse method on logs

long ivy
#

that suggests the interface is probably in the wrong assembly

#

or that this should not have been split into multiple assemblies

flint geyser
# long ivy that suggests the interface is probably in the wrong assembly

Man I don't know... I'm only trying to learn it so I don't know what's wrong what's not here. But I see that log scripts would not only have their basic responsibility but also responsibility of implementing parse interface and that there's going to be some reference mess. Please tell me where I am wrong if I am

long ivy
#

don't think of SRP as things the implementation does, but of domains that it touches. Does it make sense for a script that parses a log to implement a parsing interface? Sure, no SRP violation. But if it does anything with a database, now you have a problem. So you extract the database portion into its own bit, hide the parser behind an interface so database doesn't have a hard dependency on it, and database now has a dependency on an interface. Which is not its problem, satisfying that is up to the caller. And so these dependencies all get pushed upwards until you encounter a composition root

flint geyser
# long ivy don't think of SRP as things the implementation does, but of domains that it tou...

Actually, it's the other bit a feel bad about. The one where class which is simply supposed to represent an unprocessed unparsed log file and yet it is forced to implement a parsing interface and that leads to having 2 responsibilities (more than 1 which violates SRP). (I've already pointed at it twice and haven't got an answer, am I not asking correctly or not understanding the answer????)

long ivy
#

Maybe I misunderstood you originally. Yes that is a SRP violation. Why does the class that does parsing know anything about a file at all? If you iterate it out:
ThingWhichParsesAndIsAlsoAFile
ThingWhichParsesFiles -> File
Then you can see ThingWhichParsesFiles still knows way too many details. Hide it in an interface:
ThingWhichParsesFiles -> IFile
Then you can wonder, wait what other thing could file be? And hopefully leads to to realize that there's a code smell still, ThingWhichParsesFiles doesn't really care about where the data comes from:
ThingWhichParsesStreams -> IDataStream
now IDataStream can be a file, or a chunk of memory, or a database. ThingWhichParses streams parses data from some source. Everything is nice and neat

#

-> means dependency btw, in case its unclear

flint geyser
long ivy
#

why is it forced to implement a parsing interface? If it's an unprocessed, unparsed log file, it is data and doesn't have behavior

flint geyser
#

Right

long ivy
#

split it into LogFileParser and LogFile to start with. It sounds like ThingWhichParsesAndIsAlsoAFile, and if your question is why didn't they do that, it's because where to draw the lines can be subjective. My experience with DI/Solid/IoC in Unity is: don't. This makes more sense for enterprise-type applications that need unit testing and will be supported for years

flint geyser
long ivy
#

do your two concrete parsers share enough implementation details to have a common base class like that?

flint geyser
#

Not necessarily

#

If there are more types of log files then most probably there won't be a single parameter shared among them

#

So most probably abstract class is useless

long ivy
#

I'd delete it then, and the parsers can implement the interface directly

flint geyser
long ivy
#

depends on how crazy you want to go with SOLID. Technically speaking, both of your log files can be hidden behind an interface like I mentioned before. Right now you have a hard dependency for both of your parsers

flint geyser
long ivy
#

you think a file providing data violates SRP? Why? That's right in file's domain, no?

flint geyser
long ivy
#

Don't think of it in terms of what it does. Think in terms of what domains it works with. A file interacts directly with the disk, so saving and loading data from disk can be things it can do without causing an issue. But if it has to format the data too, now it's interacting with the disk AND providing a view on that data. So the question is, are those two responsibilities closely related enough that they make sense to be in the same class, or should that logic be extracted out?

flint geyser
long ivy
#

examples of what exactly? I'm not sure how to answer. Maybe it's easier to think of different people in control of different parts of your program. The accountant decides how the calculations are done, gfx designers decide how the ui looks, etc. Then when you look at a class, you decide which person should control it. If it's more than one, you have a SRP violation

flint geyser
flint geyser
#

I guess I'll try to read Clean Code instead of wandering the web and asking here

abstract basalt
#

I always liked "The Practice of Programming" myself

undone coral
#

line of business and backend engineers get hung up on organizational practices. that stuff, like dependency injection, is negative ROI for most video games

#

one reason is the best game innovation is done by 1 person

#

if you architect your game to be worked on by 10 people it has already failed

#

you don't have a $400m budget like Riot does to clone games. there, Big Code makes sense

#

one of my favorite interns got the job because he wrote a funny joke in a comment

#

that said, 10 years later and he's still a garbage engineer. does that matter for things being made in Unity? no

flint geyser
#

just topic from an article

undone coral
#

anyway you're at level 2 of the expanding brain meme of game engineering

#

as you gain levels you'll see what @long ivy said to you:

My experience with DI/Solid/IoC in Unity is: don't."

undone coral
flint geyser
#

well I think at my level I should mostly stick to these non-unity practices and only then advance to unity-specific ones

jovial totem
#

How can I read data outputted from a blend tree? Like, the position of various bones, and stuff, from an animator component, instead of applying to a skinned mesh.

untold moth
#

Ok, how do I debug something like this? ><
My terrain-blend-edge detection algorithm seems to invert on the X axis. Or it's the data that fed into it, because the algorithm does not do anything like that...🤔

granite viper
#

I have no idea what I'm looking at

proper ginkgo
#

Not sure if this the place to post this but..

Been looking around and could not find much info on this, maybe you guys can help. I am attempting to make a very simple card builder in Unity. I want to be able to take some png's from a file and essentially layer them on top of an image or something and then put them together and export it out to a normal PNG making a card. Something like this http://www.hearthcards.net/. This is used to make hearthstone cards with set png's.
Is there a way to make something like this in unity, and allow for the exporting of a PNG card file?

Here you can make custom Hearthstone cards.
I know this is a website, but is something like this possible in Unity?

untold moth
#

The plane is a a procedurally generated "2d terrain" blending between different textures based on a heightmap. And the white lines are just debug gizmos to test the "edge detection" algorithm, that's supposed to get areas where there's a transition between 2 terrain types.
But yeah, I didn't really expect anyone to react, so I didn't provide much info, hahah...

untold moth
#

Figured that out if anybody cares. Since I define terrain data at virtual vertices, not "tiles"(a quad of 4 vertices), when using the "terrain resolution"(basically tiles count per axis), I was actually offsetting the position on the X axis each iteration(row), so it looked like it was inverted. But it was actually skewed. Sampling the points at the correct indices y * (res+1) + x instead of y * res + x, I got the correct result.

#

Now it looks more like an avocado

novel plinth
#

like any gamengines out there, there are learning curves in Unity as well..

Most users hated it when they're told learn the c# language 1st, but that's the truth whether you like it or not. There's some shortcuts, like buying a premade templates on Assets store, but trust me, to get your dream game come true, you'll still need to learn c# especially in Unity

flint sage
#

It really depends on what you want to do, if you want to become a programmer then learning C# separately is the best way, you can still learn C# and Unity at the same time however you should be aware that it'll teach you bad practices and it'll take significant effort to unlearn those.
If you just want to create a game and don't care that it is hacked together, feel free to do whatever you want in whatever order

novel plinth
#

All those folks learned c# via Unity got some serious inheritance problems 🧐

regal olive
untold moth
regal olive
#

Yoooo

#

It’s so smooth

#

Good job dude 💪

untold moth
#

There are still a lot of edge cases where it does not look great😮‍💨

regal olive
#

Still

#

Very cool

gaunt spoke
#

What do you think of "Interfaces should be adjectives. Abstract classes should be nouns." If I have to create an abstraction of a file for example, I'll ask myself if it is a behavior or a thing ? Then, I'll either create a File abstract class or a IParsable interface, what's your take ?

quiet bolt
#

I’m curious about the abstract vs interface thing too. Actually ngl i thought interfaces were more closer to Actions/Events but thats prolly me

regal olive
#

I like interfaces more lol

#

I mean each thing had it’s own use

quiet bolt
#

I’ve never had any uses for interfaces except for IDamageable lol

novel plinth
#

not really

compact ingot
novel plinth
#

tho since c# 8 interfaces can do body implementation as well, but still

compact ingot
#

interfaces (in unity) only make sense if your project is built in a way that you do not rely on builtin editor features much, for the system that uses the interfaces. Basically making interfaces work for you (in regards to improving maintainability) is to use a lot of custom inspectors

quiet bolt
#

Actually this makes sense

#

A car and a box are not related at all, but both can be damaged

#

Yea as you can see i can only use damageable as an example lol

compact ingot
#

Adjective = Interfaces describes an attribute that a thing has independent of what it is derived from… it’s exactly what you described

#

not using abstract makes it impossible to reference your shared base type in the editor

#

testing is not a good enough reason to avoid them in most cases

#

Seems to me like a bunch of boilerplate just to make tests work

#

but if you do that to do some sort of composition/aspect oriented programming I’d agree that’s a good thing

#

Fair enough

#

Suppose you work in long term projects mostly?

#

ic

#

I think testing (TDD) is only a financially sound decision if the project runs longer than 3 man(person)-months

#

Can appreciate that sentiment 🙂

#

it’s nice to have tests, not so nice to write and maintain them

#

Depends a lot on the test strategy. Writing tests during prototyping is useless, and it’s hard to go into slow-mode dev with tests after that, especially if there is no discipline about rewriting everything if a spec changes

distant island
#

Does anyone know of any good machine learning modeling software?

regal olive
distant island
#

I'm trying to set up several markov equations in software format. I'm just trying to find the best way of doing this.

compact ingot
#

What does that have to do with democratization? Afaik TDD was hyped a decade ago, got popular as a buzzword but reality showed that it’s only a sound investment if it fits the product’s lifecycle

#

There are a lot of strategies you can take towards testing

#

Dogmatic TDD for everything is just foolish

#

Also you can do a lot in the actual code to test and communicate assumptions/contracts

#

It’s always a good idea to have them, but you need to judge their value against their cost. Only if you do that does it become an argument. In theory they are always good.

#

therefore in longer projects their value increases

#

in short projects you start with double or triple the cost over manual testing, assertions and a few simple integration tests

#

But testing games is inherently hard, no tooling can ever fix that

flint sage
fallen magnet
undone coral
undone coral
undone coral
gaunt spoke
keen cloud
#

if i called a method from inside a task will the method also be run through that task

woeful warren
#

Does anyone know how the map generation works in Vampire Survivors?

#

i'm trying to create a similar thing

#

I tried making a tilemap that has 4 empty objects inside of it (in each corner of the tilemap), calculating the distance between the player and each of these objects and then generating tilemaps in different locations, e.g. above the current tilemap, to the right of the current tilemap and in the top-right of the current tilemap

#

but firstly, it generates duplicate tilemaps, and second (though, I think this may solve the first problem), I dont know what to do after I place the tilemaps in the correct position. What do I do with the old tilemap?

undone coral
#

if the method does a bunch of work in C# code that is like, a big for loop, and thus it takes a long time to complete - as opposed to waiting for a web request or waiting to write a file or some kind of IO/specially handled thing - the thread running the task will be blocked. if the task is being run by the main thread, the main thread will be blocked

compact ingot
quiet bolt
#

Even IPickupable is also good

#

Anything that uses CompareTag can replaced with an interface

keen cloud
chrome coral
#

hey there! this is the first time i'm working with Pooling, and i'm struggling to replicate a certain behavior

#

essentially, instead of Instantiating bullet holes and then destroying them after X seconds, i want them to never disappear

#

but after reaching a certain amount of total bullet holes in the pool, the oldest bullet hole is recycled instead of a new one being Instantiated

#

all Pooling tutorials i have found only use the first behavior (so destroying them after X amount of time) so i don't really see the point

undone coral
undone coral
#

set the lifetime to Mathf.PositiveInfinity

#

and resize the pool

undone coral
#

which is to say, components already are traits, in the way that interfaces are traits

#

and people like to reinvent components

keen cloud
quiet bolt
# undone coral the way compare tag is used, you don't even need an interface. you can do ```cs...

I meant more like if many objects share the same sort of method but different functionality, e.g with IPickuable. Instead of checking if you picked up a Medkit or a Speedboost and then getting their respective script, you can just check if the object you collided with has an IPickuable interface in it and call some sort of a Pickup() method

Same for IDamageable. Instead of checking if it hit a player or a crate or something, just check for the identifier and call its method

That’s my initial thought atleast. Basically if you got many different objects that does similar things, it’d be better to just use one identifier instead of comparing many tags

jovial totem
undone coral
#

and attach it to medkit and speedboost prefabs

#

You can use a UnityEvent onPickedUp and wire it up to your Heals component or your AddsSpeed component's respective methods when you build the prefab

gaunt spoke
undone coral
#

this way you could make .eg. a single Heals component and add it to an item, an area of the map with a trigger, a monster, etc.

#

the prefab component model is pretty much purpose built for creating platformer levels and monsters

tough knoll
#

Or maybe the context in which they are useful for a game

gaunt spoke
quiet bolt
#

^^

tough knoll
#

It's just bloat for no reason

undone coral
#

it's unavoidable

#

you will have to put the code somewhere

tough knoll
#

an example of where interfaces are just no nonsense imo: I have a bunch of different object types driven by completely different physics code. Players, pickups, projectiles, props... they all need to be pushable, but they all have different unrelated methods of calculating forces/collisions

#

So just make a IPushable interface

undone coral
#

i offer that since there are many things that can be picked up that aren't items in platformers

tough knoll
#

Yea

undone coral
#

for example, quests, corpses, etc.

tough knoll
#

True

#

but there are more general cases where the interface makes more sense

undone coral
#

it really depends on what kind of game you're making

tough knoll
#

There's just less stuff to track with the interface

undone coral
#

the reason unity has the component model is because it's sort of what flash had

#

they didn't htink about this

tough knoll
#

You implement the GetsPushed() function in your component directly, don't have to play with references

undone coral
#

but flash had it because shockwave had it, and shockwave has it because for designers it helps them be creative

#

by composing their little pieces that the engineers made

tough knoll
#

For getting a reference to the interface I have a reference table

#

You just do collider.GetPushable() and it's done.

undone coral
#

so in terms of making a good game... ia dvocate for making lots of little components, because the psychic experience of clicking aroudnt he inspector and searching by text for things you want to put together helps you create innovative new monters, items, etc in your platformer

undone coral
tough knoll
#

It's < 20 lines

undone coral
#

and i've had this conversation with people before here - yes,l you always need to write code to achieve things

#

it's unavoidable

#

people have long arguments about where to put taht code

#

and i bet you your 20 lines look really arcane and obscure

tough knoll
#

With the component approach you still have to implement each case individually in the component that drives the behaviour

#

In fact you may as well use an interface for that part!

quiet bolt
#

Atp it’s pretty much prefrence on how you do it 💀

undone coral
#

you have to write code to achieve things

tough knoll
#
            if( collider == null ) return null;
            return m_References.GetOrCreateValue(collider).thing;
        }
        public static void SetThing( this Collider collider, MorosThing thing ) {
            if( collider == null ) return;
            if( thing == null ) {
                MorosReferences r;
                if( m_References.TryGetValue( collider, out r ) ) {
                    r.thing = null;
                    if( r.IsEmpty() )
                        m_References.Remove( collider );
                }
            } else m_References.GetOrCreateValue(collider).thing = thing;
        }```
#

really is the simplest thing in the universe

#

Plus if you're looking at this from a team perspective, the "designers" don't need to know about any of this

undone coral
#

this is a lot of work for GetComponent<X>() != null

#

unity already does this idea

tough knoll
#

The work in your case happens in a different area

undone coral
#

in the least obscure area, in 1 line

#

you still need a line for SetThing()

#

you still need to be aware of these

#

GetThing and SetThing

#

you haven't strictly reduced the burden of what components and interfaces are

tough knoll
#

You have to maintain references between the components and the IsPushable component, then you need to implement all the behaviour for the individual objects in IsPushable component. It has to know of all the object types in your project and find/maintain references to them

undone coral
#

it is a matter of opinion if you've increased the burden (intellectual or otherwise)

#

in my opinion you have

tough knoll
#

The behaviour for the pushing should be the responsability of the underlying object, not the compatibility layer : S

undone coral
#

you have to do that

#

you have to do that no matter what

#

no matter how you do things

#

somewhere, you will have to write code

tough knoll
#

If I write a new object type and someone else does as well I have a merge conflict with IsPushable component now.

undone coral
#

that makes the special behavior of something being pushed

tough knoll
#

If you use an interface, its implemented in the underlying component. No merge conflict, no problems.

undone coral
#

i don't think having an IsPushable component is a good idea

#

i don't think checking the types of things is either

tough knoll
#

Maximize merge conflict, minimize productivity B-)

undone coral
#

i wouldn't implement it the way you did

#

anyway

#

i guess my point is that you are welcome to use interfaces to recreate the unity component system

#

they really are duals of one another

#

anything you can do in one, you can do in the other, and vice versa

#

that's like, how they are conceived, at a theoretic level

#

that's all i'm trying to illuminate

#

FindObjectsOfType is your "reference table"

#

if you look carefully you will see these things are duals

tough knoll
#

That's true

undone coral
#

it's okay

tough knoll
#

but that's not the part that's better. The improvement is that you minimize the points where the code is touching. The behaviour is implemented in different classes, and in the class where it's most relevant and where all the information is available

#

Having the Pushable component have custom logic to handle every object type in your game is gonna turn into spaghet the more people are working on it and the more object types you have

#

If you don't use this method and instead you have it refer to a virtual function called on the destination object then it's basically identical to an interface with the added downside of forcing inheritance

#

You're handwaving this away like "so what merge conflicts, shit happens" xD. It's silly

compact ingot
#

People who don't understand your custom system are inclined to ignore it and implement their own way/workaround, maybe they are just unaware how it really works and next to the 100 important things they need to know to get stuff done, it might just get used in the wrong way or you spend a lot of time explaining the why and how to them

tough knoll
#

My custom system is irrelevant to the use of interfaces

#

It is just one example of an implementation of it.

#

I was trying to provide a concrete case

compact ingot
#

the more basic and commonplace the patterns in a project are the more likely it is that people in the team will use them correctly

tough knoll
#

that's true

#

But like

#

here's an example:

compact ingot
#

i'm saying what pangloss is saying

#

just from a different angle

tough knoll
#

Add a Pushable component, the pushable component looks for a component on the object and casts it to an interface

#

There you go, now you're using the Unity component system and you have all the advantages of abstracting the behaviour out.

#

The reference table thing has nothing to do with my point, that's just how I did it because it results in less spaghetti in my particular case

compact ingot
#

I'd do that when there is an apparent need to abstract behaviour, not before though

tough knoll
#

yea!

#

Ofc.

#

100%

compact ingot
#

so with all things, engineer more when there is an apparent need to do it, but don't start with XML

tough knoll
#

But on a big project where there are lots of ways to interact with stuff (IDamageable, IPushable, IPickupable, IUseable...) it's obviously extremely useful

compact ingot
#

i'd say interfaces would be more suitable to abstracting larger modules than "IDamageable"

tough knoll
#

I don't want to have to stop working on my crate pushing code to resolve a merge conflict because someone just added a beach ball and it responds to pushing with different physics code, and now I (or we both) have to edit the player physics code to have different pushing behaviour.

#

This will manifest with literally two people

compact ingot
#

this sounds more like an architectural problem

tough knoll
#

It is

#

but interfaces are like, a simple solution to it

compact ingot
#

you don't solve architecture problems with language constructs

undone coral
#

even ICinemachineCamera is implemented only 3 times

#

and once you see how, it'll be clear that it is a convenience

#

and that's a very complex and low-bug unity library

compact ingot
#

tbh, i tend to create interfaces all the time, only for them to be eventually replaced by that singular implementation

undone coral
#

that's useful

#

lots of people i know do that

compact ingot
#

seems to help me think

#

like the component-click/search you mentioned

undone coral
#

yeah and i wish more people would just

#

do the things that help them think

#

as opposed to worrying about like, what happens when 10 people start working on this codebase, which never happens

proper ginkgo
undone coral
#

also another reason i advocate for unirx & unitask so much - it frees your mind for how to think

#

and why i think people advocate for seemingly low ROI things, like learning haskell - it's about helping you think

undone coral
#

critically, it is impossible to procastinate using UniRx. what are you going to do... make more triggers? cygames guy has made them all

#

however... making glorious type hierarchies... very easy to procrastinate doing that

#

tradeoffs to everything

compact ingot
#

there is a "glorious type hierarchy phase" to a programmers maturing as a developer 😄

undone coral
regal olive
upbeat path
chrome needle
#

I'm trying to keep my script on gameobjects with a list of all my scriptableobjects that are in my project. That's easy to get but I need some way to update it as a scriptableobject is created. OnValidate works mostly...it doesn't trigger when one is created. Is there a way that when one is created to update my scripts with the new scriptableobject? This is in Editortime not Runtime.

tough knoll
obtuse remnant
chrome needle
tough knoll
#

How about Reset?

#

Seems to work for me

chrome needle
#

Hmm. I'll look into that.

tough knoll
#

On the scriptableobject at least, it's called when it's created

obtuse remnant
gentle topaz
#

might need to change the type name to UnfinishedTechDemo instead of Game

#

then it would basically be my implementation as well

brazen hamlet
#
    IEnumerator DatabaseDownload()
    {
        
        WWW www = new WWW(webURL + publicCode + "/pipe/0/10"); //Gets top 10
        yield return www;

        if (string.IsNullOrEmpty(www.error))
        {
            OrganizeInfo(www.text);
            myDisplay.SetScoresToMenu(scoreList);
        }
        else print("Error uploading" + www.error);
    }``` 

guys, my WWW have that green underline, so i put [system.Obsolete] and that green underline is gone so now there's no issue. But i have to ask, it is ok right? because the tutorials didnt ask me to put system.obsolete.
upbeat path
old swallow
#

Hello, I want to make a render texture in runtime (runs once per scene) with the exact pixel size of a rawimage that draws it to the UI, but I cant find anything about about getting the screen resolution of the rawimage.

flint geyser
#

(dotted line is flow of control and the red one is dependency pointer)
I can't understand... the book (clear architecture) says that the source code dependency between MLl and the interface I points in the opposite direction compared to the flow of control but they (arrows) are not opposite, are they?

oak lotus
#

The green one is moving down the tree, the red one is moving up?

#

It's definitely not the same direction

flint geyser
#

But they do not look opposite to me either

oak lotus
#

The book is not saying that they are opposite, it's saying they point in opposite directions

#

One is pointing up the tree, the other is pointing down the tree

timber flame
#

Would you like to separate runtime data from logic?
For example, in strategy games, there are runtime data like population, resources, etc. They are updated at runtime while playing. A class which contains just data and another class to manipulate runtime data.
Also what do you prefer to name them?
RuntimeResourceData/ResourceDynamics and ResourceManagement (logic) for example?

oak lotus
flint geyser
oak lotus
#

Supposedly, an arrow would be a line pointing from some point A to some point B. The opposite of that would be B -> A. The direction is merely a part of what makes an arrow an arrow 🤷

flint geyser
#

doesn't make sense for me eitherway

turbid arch
#

Heya! I'm trying to create animation clips based on some imported json, I can create rotation and position curves just fine however when I try the scale curves (docs says they should work) they don't show up in my clips. ```cs
if (script.positions) {
var pos = item.localPosition;
var x_curve = AnimationCurve.Linear(0, pos.x, 1, pos.x);
var y_curve = AnimationCurve.Linear(0, pos.y, 1, pos.y);
var z_curve = AnimationCurve.Linear(0, pos.z, 1, pos.z);
clip.SetCurve(path, typeof(Transform), "localPosition.x", x_curve);
clip.SetCurve(path, typeof(Transform), "localPosition.y", y_curve);
clip.SetCurve(path, typeof(Transform), "localPosition.z", z_curve);
children[i].position = resets_position[i];
}

if (script.scales) {
var scl = item.localScale;
Debug.Log(scl);
var x_curve = AnimationCurve.Linear(0, scl.x, 1, scl.x);
var y_curve = AnimationCurve.Linear(0, scl.y, 1, scl.y);
var z_curve = AnimationCurve.Linear(0, scl.z, 1, scl.z);
clip.SetCurve(path, typeof(Transform), "localScale.x", x_curve);
clip.SetCurve(path, typeof(Transform), "localScale.y", y_curve);
clip.SetCurve(path, typeof(Transform), "localScale.z", z_curve);
children[i].localScale = resets_scale[i];
}
}```

glad scroll
#

Hello, i made this player controller script https://pastebin.com/LZ139Mps. When I move my mouse it seems to be working properly, but when I put my mouse to a specific spot on my desk, and look at a specific object in the game, then move my mouse around really fast and return it to the original spot, the player doesnt look at the object anymore, although I returned the mouse to the exact same spot it was in before. So it seems that the game isnt picking up the exact mouse movements. Is there any way to fix this issue?

twilit chasm
glad scroll
#

Many people get that wrong

thin mesa
twilit chasm
#

Doesnt help that they do it in the documentation examples. 😮

glad scroll
#

By the way, I tested other games and they all have the same problem. Not as noticable as in my game though

thin mesa
thin mesa
glad scroll
#

Okay nothing to do with this problem but i changed GetAxis("Mouse X") to GetAxisRaw. Now its completely weird mouse movement. Why? I thought GetAxis just applies some kind of smoothing?

twilit chasm
#

I have a question as well: How would you convert data so it can be shared between different clients? If the game features a level editor/creator that exports all data to JSON, what is the next step so I can send that data to my friend so he can play my level? What is the keyword I should google? I guess you could upload it to your server and create a url, but are there other options available?

thin mesa
glad scroll
#

Oh okay I see

thin mesa
# twilit chasm I have a question as well: How would you convert data so it can be shared betwee...

this would probably depend on how you intend to handle networking in the first place. like are these levels that are stored locally on the player's machine and only shared when in a multiplayer lobby or whatever? if so, just send the json data from the host (or client that owns the data) to the other player(s) over the network and store it locally on their machine. or your idea could work where it is sent to some server and downloaded via a GET request. probably better off asking in #archived-networking though

rugged radish
#

hey guys
how do I correctly dispose of persistent NativeArrays that supposed to live until a scene change or application exit ?
when I dispose them in OnDestroy / OnApplicationQuit of the behavior that holds the reference it says that arrays are already disposed
if I don't, it says that arrays were not disposed

novel wing
rugged radish
upbeat path
rugged radish
dim zephyr
#

Does anyone has code/worked on attraction-repulsion model that can share with me?

icy aspen
green ether
#

I'm currently making a multi-player game where I use a singleton for the game manager to access an array that every player will be reading and writing to, which is ok.

However, I need a way for the bombs every player drops to access the stats of the player so they can act accordingly (power, and maxammo count, and probably others in the future). I realize that using a singleton to access something like player stats would be potentially problematic down the line. Do you have advice as to how to structure this in a way that is multi-player proof?

Sorry, I'm a bit new, and I haven't looked too much into how the implementation of multi-player would go, I just have a feeling that using a singleton for something like this potentially a bad idea. Thanks.

gray pulsar
sly grove
#

You could also use a Dictionary to map bombs to the player that owns them

twilit chasm
# green ether I'm currently making a multi-player game where I use a singleton for the game ma...

Are you aware of this talk? I would use a ScriptableObject for your problem. You store each players values in its own ScriptableObject that is referenced by the bombs.
https://youtu.be/raQ3iHhE_Kk

Scriptable Objects are an immensely powerful yet often underutilized feature of Unity. Learn how to get the most out of this versatile data structure and build more extensible systems and data patterns. In this talk, Schell Games shares specific examples of how they have used the Scriptable Object for everything from a hierarchical state machine...

▶ Play video
rugged radish
#

documentation says it's not a good idea to access static data from jobs, does it mean literally anything that uses the static keyword ? even things like a read only dictionary in a static class ?
I'm using one instead of a long switch expression, wonder if it's ok or maybe it will cause some hard to track stability issues in the future

sly grove
#

Native collections only typically

rugged radish
devout hare
#

Not a code issue, much less an advanced code issue

#

but put the project somewhere else other than the desktop

humble onyx
#

and not spaces in the project path

undone coral
#

the simplest thing is to always access things like stats via an argument that signifies which player is being accessed (e.g. "player index 0")

undone coral
regal olive
#

I am getting this error: There is no argument given that corresponds to the required formal parameter 'checkPlayer' of 'Combat.RpcOnReceivedDamaged(int, DamageType, bool)' trying to call this command victimCombat.RpcOnReceivedDamaged(damageDealt, damageType);

#

[ClientRpc]
public void RpcOnReceivedDamaged(int amount, DamageType damageType, bool checkPlayer)

#

how do I add checkPlayer? I tried Player, player, checkPlayer. nothing worked

thin mesa
regal olive
#

Its advanced for me :( how do I supply that argument?

#

I tried player, checkplayer, and Player

thin mesa
#

go back to #💻┃code-beginner and check the pins. there are beginner courses in there, those courses will teach you how to include arguments when you call a method

regal olive
#

Ok tyvm

tough knoll
#

I tested it just to be sure

#

Left hand is GetAxis, right hand is GetAxisRaw

thin mesa
#

well then i have no fucking clue why GetAxisRaw gave different results than GetAxis 🤷‍♂️

tough knoll
#

I thought that GetAxis applied smoothing, but right now it seems to do nothing different

#

But definitely GetAxisRaw does not lock the mouse input to -1/0/1

thin mesa
#

GetAxis does not apply smoothing to mouse input

tough knoll
#

Yea

#

Seems to be exactly the same

#

Definitely though GetAxisRaw does not clamp input to -1/0/1

#

That's the one that I use in my actual FPS game and I'm pretty sure you would be able to tell if it did!

#

I haven't personally noticed any mouse accel in Unity

#

Do you have enhance pointer precision on? And sensitivity in windows settings set to 6th notch @glad scroll

#

seems that way yes

tough knoll
# green ether I'm currently making a multi-player game where I use a singleton for the game ma...

I'm not sure how you might want to answer this question if you're not sure yet how your multiplayer implementation will work. You're basically asking if a design pattern of which you haven't yet explored the consequences will work with another unknown design pattern you haven't decided on. Use what makes you comfortable. I can't think of any general reasons why a singleton would somehow prevent you from having multiple players, local or in networking. If you don't intend to be running more than one game at a time then having the game manager be a singleton sounds reasonable, no?

#

Just use what makes you comfortable for now. When you have more information about what you want to do you'll be able to make more informed decisions

silver schooner
#

With occlusion culling, is it possible to tell Unity to sample from another point besides the camera transform?

I'm working on a game where the player can shrink, and occlusion culling culls stuff it's not supposed to if you're too close to the ground on sloped surfaces. I've tried adjusting the size of the volumes, but that leads to the occlusion culling then not culling things it should, and the computation time and data size balloons.

I can't simply scale my world up, as that creates way too many issues with things like reflection probe volumes and other stuff not scaling with it.

So what I'd like to do is tell the occlusion culling to sample from a certain distance above the player when they are small, because down to around 10cm tall it works fine, but I'm trying to get down to 1.5cm.

sly grove
silver schooner
silver schooner
#

That seems like a channel where advanced questions go to die. "Non-programming questions and stuff that doesn't fit elsewhere"?

somber tendon
silver schooner
#

Generally, when the backface test is enabled (i.e. when backface threshold is something smaller than 100), Umbra will do a better job near occluders, because it is able to detect the insides of occluders, and correspondingly dilate all valid locations slightly towards them, so that you’ll get correct results even if you go arbitrarily close to an occluder. So if you cannot prevent your camera from going very close (or even slightly inside) an occluder, the first thing you may wish to try is to set backface threshold to something smaller than 100. This will help with dilation and may fix the issue.

If tweaking backface threshold does not help, or if your camera goes very deep inside an occluder, the only thing left to do is to simply remove the occluder flag from the object.

#

I wouldn't have even thought to try lowering backface test. That seems like it could only make the problem worse. Of course, lowering smallest hole also seems like it should not have fixed the issue with my culling since my problem was not enough objects were being culled, but when I found this blog and learned the system works on voxels I realized that it was probably discarding my interior walls as occluders.

#

And setting my ramp to not occlude also seems like a viable solution if that doesn't work.

#

Though I have so many sloped surfaces maybe that isn't viable.

somber tendon
#

this seems like a hack, but how about when you are small, disable occlusion culling and reduce visibility range (if needed, just incase frame rate drop)?

silver schooner
#

I don't even know if disabling occlusion culling is possible. Well, not without traversing every object in the scene and turning it off. But even if it is, the framerate drop would be too great. And reducing the visibility distance would probably not work well. My sky for example is not a standard skybox because the mirror system I'm using it requires it to be geometry. So that would end up being culled and I'm not sure how I'd stop that. But also I would have to reduce the distance so much it would cull very visible large distant objects. It would just be so easy to fix this if I could just tell the occlusion culling system to sample from a different point 0.1 meter above the player when small, it would work without issue 99.9% of the time.

#

Well it is possible to disable it per camera, so that's easy enough but still, massive fps drops if I do that, so not a good solution.

#

I wonder if it would be possible to move the camera before the culling phase, then move it back in the render phase. But I don't know how well that would play with VR. I had an issue with a menu camera updating choppy when I tried to make it follow my main camera with a constraint.

regal olive
#

Someone else already said it

tough knoll
#

The builtin occlusion culling system is mostly blackboxed though. There's no way to really hack into it that I know of and I've looked into it a few times. This sounds like a case where you should be building your own system

#

Reducing the voxel size to that scale is probably a terrible idea btw, it's going to make your pvs data hueg. But it might work, no idea what impact that's going to have on the CPU afterwards though. You can maybe check if it is indeed the static component of the occlusion system that's causing objects to disappear or if it's dynamic occlusion. Those two systems are seperate and I don't really know how dynamic occlusion is handled but I've had some problems before where dynamic occlusion was causing objects that should have clearly been in view to disappear when inside very tight spaces, like a vent or something

silver schooner
# tough knoll You can try using a smaller voxel size for your occlusion. As in, a voxel size t...

I'm currently using a smallest occluder of 1 and a smallest hole of 0.05. I've found that reducing either of these leads to very long bake times, and large data sizes, but those I could live with. The real problem is that those seem to be the only settings that actually work well. I have a house with relatively thin walls, like most houses have. And for the longest time I could not figure out why nothing was being occluded inside the house. It wasn't until I found those blog posts from 2013 explaining that the culling system voxelizes everything rather than using polygons to determine visibility, that I realized what was happening was likely that voxels overlapping those walls were partially inside the rooms of the house, and so they were discarded as occluders. I then tried smaller values for smallest hole, which I had previously assumed could only cause MORE objects to be hidden if it was too large, and lo and behold it started working as expected.

But here's the thing... I found the sweet spot was 0.05 for the smallest occluder, and that for some reason, if I went smaller than that, even though there's clearly walls blocking the player's view from outside and there's no gaps in the structure, certainly none which are larger than a millimeter, I started seeing objects inside the house that should not be visible showing up. So if I were to go lower, while it might stop parts of the house from disappearing it would also negate the point of occlusion culling because it wouldn't occlude half the stuff.

tough knoll
#

I mean

#

So the way it works is it reduces the world into a bunch of bounding volumes and pre-calculates which objects are visible from which volumes, right

#

The voxel approach is kind of obvious for that

#

It's not the best system ever and it's definitely not fool proof, if you need more accurate occlusion you really have to use some kind of custom system. There's someone out there that wrote a Unreal style GPU occlusion culling system, I think it's on the asset store. If you have no interest in figuring out how it works on a technical level I'd say just try that one. It probably won't have the same problems as the Unity one.

silver schooner
#

Yeah, and that may be the route I take, since it seems like there is no way to offset the location from which its sampling that would have been the simplest solution.

#

But it annoys me that the docs were so unclear about the voxel thing. "smallest hole you can see through" does not inform you the world is being voxelized and they say nothing about thin walls being missed if that value isn't small enough. I'd never have thought they were converting stuff to voxels to determine visibility and every time I've asked about why the system wasn't working nobody seemed to have any ideas. Hell, the devs of Budget Cuts even commented on having to delay the game to roll their own culling system because the Unity system did not work well enough. Makes me wonder if they just had the same problem I did not understanding how the culling data was being built because aside from my issue with it not working well for teeny tiny players, it works pretty darn well, with those specific settings I chose, for interior environments with thin walls.

silver schooner
#

I'm happy to report that changing the backface threshold seems to have resolved the issue! I do get a few more objects than I expect to be culled not being culled in the house, but it's maybe like 5% more which I can live with. I set the threshold to 50%. I could perhaps set it lower or higher, but I haven't tested those yet. Perhaps a higher value would cull more objects in the house. That would be the opposite of my expectations, but since 100 worked slightly better than 50 is, while simultaneously not working best because it culled more stuff than it should in some cases in spite of that supposing to be the most conservative setting, well... Everything I expect about how this culling system seems to work the opposite, so I guess the only way to be sure is to test.

glad scroll
icy aspen
#

hello everyone i have a question, I want to save the player position without updating it. However if I do this in the code below, the startPosition constantly updates because it always the same as the player position. However I want to save the player position once and not update it. I placed this code in a void that gets called when a key is pressed on the keyboard.

public Vector3 startPosition;
... 
startPosition = transform.position;
devout hare
icy aspen
#

ok

icy aspen
#

@devout hare do u know a solution

hallow cove
#

so I'm always getting this error now for some reason:
NotSupportedException: The invoked member is not supported in a dynamic module.

#
        {
            Type[] types = assembly.GetExportedTypes();

            foreach (Type type in types)
            {
                if (type == typeof(Debug))
                {
                    GetMethods(type, GetIconFromType(type), 2);
                }
            }
        }```
#

and if I change it to a for loop it works, but then when I reopen the project it gives the same error

#

and I have to keep going back and forth

#

The error happens because you are trying to get the location of an in-memory assembly (the ones you have created on the fly) and those assemblies aren't located anywhere.

#

but I do get the assemblies here:
List<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();

#

if it compiles the scripts, then it works

#

how can I fix this?

hallow cove
stuck onyx
#
 await UniTask.WaitForEndOfFrame();
 Texture.ReadPixels(......) ``` shouldn't WaitForEndOfFrame tell unity to readPixels in the drawing frame?
#

Im getting 'ReadPixels was called from system frame buffer, while not inside drawing frame'

#

though on editor the 'waitForEndFrame' seems to work, on device it doesnt

hallow cove
#

ok so I fixed my issue by detecting when the project is first opened, and running this:
UnityEditor.Compilation.CompilationPipeline.RequestScriptCompilation();

novel plinth
#

oh.. shoot...

#

you did that already.. then I've no idea

real blaze
#

I know they're great, but in Unity it's really better to stick with Coroutine for Unity stuff

regal olive
#
    void StepThroughEnum<T>(ref int indexer) where T : struct, IConvertible
    {
        if (!typeof(T).IsEnum) 
        {
            throw new ArgumentException("T must be an enumerated type");
        }
        indexer++;
        string[] names = Enum.GetNames(typeof(T));
        T[] enums = (T[])Enum.GetValues(typeof(T));
        Debug.Log(enums.Length);
        if (indexer >= enums.Length)
        {
            indexer = 0;
        }
        int testIndex = 0;
        foreach (var name in names)
        {
            Console.WriteLine("names:" + name);
        }
        foreach (T item in enums)
        {
            Console.WriteLine("enum:" + testIndex);
            Console.WriteLine(item);
            testIndex++;
        }
        Debug.Log("end enum step");
    }```
#

Does anyone know why this doesnt work?
i get for example "8" as length but the foreach loops both of them just dont log anything

#

no errors, and the last debug.log also executes..

#

Here an easier to read code:

#
void StepThroughEnum<T>() where T : struct, IConvertible{
    T[] enums = (T[])Enum.GetValues(typeof(T));
    Debug.Log(enums.Length); // for example returned 8
    foreach (T item in enums)
    {
        Console.WriteLine("enum:"); // this doesnt show in the console
        Console.WriteLine(item); // neither does this
    }
    Debug.Log("end enum step"); // This shows up in the console
}```
flat marsh
#

put a breakpoint and inspect the value of your array

devout hare
#

Why are you mixing Debug.Log and Console.WriteLine?

#

Console.WriteLine doesn't print to the Unity console AFAIK

regal olive
#

idk

#

that was probably the issue anyway 🙄

#

thx hehe..

#

Yea it was.... very stupid mistake..

undone coral
#

you can use a custom pass to retrieve the display frame buffer. otherwise you will have to render to texture

#

look at the timeline view in hierarchy while exploring the output of PlayerLoop.GetCurrentPlayerLoop() in a debugger to fully understand where WaitForEndOfFrame and such occur

undone coral
#

unfortunately WaitForEndOfFrame is waiting until the end of the CPU rendering work in scriptable render pipeline. it does not wait for the GPU work

undone coral
#

there are a bajillion ways to get the thing you need. the best is to do Camera.render

stuck onyx
#

thanks for answering

#

the context is the following... i have a sript that
1.Renders
3.Creates a texture based on the renderTexture assigned to a specific cam
4.Saves the texture in disc

undone coral
#

okay

stuck onyx
#

the camera the script captures and renders its a secondary one, not the one the player is seeing

undone coral
#

is it essential that the second camera's output be as up to date as possible?

#

does it matter?

stuck onyx
#

mmm no, i trigger it 1 second or 2 later of a modification being done in that area

#

its like a satellite view of a city builder

#

so when player modifies something in area x, i move that cam there, render just a portion... etc etc...

#

to create a mosaic of 16 textures

#

that would be the satellite view

#

1 way of doing it is completely syncronous... i do this is sometimes, when the player 'enters' that view

#

but in order for this process to take less time

#

i take portions while theyre playing

#

so yeah, i dont need to have it fully up to date since player wont see it until he enters that secondary view

#

I dont know If i answered your question

#

this is what the script does exactly
1 create rendertexture
2 assign rendertexture to secondary cam
3 enable secondary cam
4 render secondary cam
5 disable secondary cam
6 convert renderTexture to texture (here i use the ReadPixels)
7 Save texture in disc
8 Destroy texture

#

this is done and the player doesnt even realize that it has happened, just a few ms for each step, but when I call ReadPixels the message ''ReadPixels was called from system frame buffer...' appears. The thing is when i added WaitForEndOFFrame this was fixed for editor, but on device still happens

undone coral
#

oh yeah

#

so

#

don't get mad, but you know you can reference a render texture in a material right?

#

that'show your'e supposed to do this

#

it shouldn't touch the CPU at all

#

if this is for saving to disk

#

to make like a preview

#

use async gpu readback

#

which i believe will be supported on all your devices

#

otherwise, use graphics.blit instead of readpixels

stuck onyx
#

yeah but its 16 textures of 1024, then this textures would be all allocated in RAM all the time

#

what im trying to do is to capture 1/16 of the map and having textures in disc, out of ram, so whenever the user wants to see them, then i load them in a material

#

and if i do it like this is so the process can be done while the user is playing and doesnt realize, if i do it like you said, takes lot of time capture what we want and show it

#

plus the usage of the ram

undone coral
#

it really depends how out of date it can be

undone coral
#

the best thing to do would be to have a single texture

stuck onyx
#

its 4096x4096... but im giving it a try

undone coral
#

a single small texture

#

it's on a mobile device right?

stuck onyx
#

yes

#

we just care about >3GB ram devices though

undone coral
#

you can use jobs to create the images

#

that is probably the best approach

#

you would save them as bitmaps onto disk

#

targa or whatever unity can load on all mobile devices at runtime

stuck onyx
#

i was gonna try the renderTexture approach you mentioned but with 16 porttions and profile memory

undone coral
#

i wouldn't do it on the cpu thread

#

well you can move the camera's view every frame

#

so across 16 frames image your 16 different tiles

#

you would still need 16 render textures

stuck onyx
#

yes

#

thats it

undone coral
#

also it's possible that pixelRect will let you draw to a psecific portion of the render texture

#

you sort of want the inverse of pixel rect but that doesn't exist

#

you can't specify 16 render textures for 1 camera in unity

stuck onyx
#

but this time i would do it syncronously because i would do it during the trransition of one mode to the other (theres a fading effect)

undone coral
#

i mean

#

i don't really know

#

i guess you'll find out

stuck onyx
#

yeah, i think i remember it was

#

thats why i had to do this

undone coral
#

the reason it's slow is because it touches the cpu

#

and modern graphics are pipelined

#

you never want a dependency in the main thread on something that comes out of the end of the "gfx" thread (meaning the gpu)

#

that's what async gpu readback is for

#

to let you keep pipelining

stuck onyx
#

let me get a hold of this...

#

right now this is heavy because im relying on CPU

#

is it correct?

undone coral
#

it's heavy because you are waiting on graphics

#

you are doing no work

#

you'll see it in the profiler

#

it's also what that error message is really trying to say

#

it's trying to say "you are interacting with the modern graphics pipeline incorrectly"

#

once you look at your profiler in timeline view

#

and look at the main thread, the render thread and the gpu rows

#

you'll realize how this works

stuck onyx
#

async gpu readback , you mentioned this would help me

undone coral
#

because it is a way to express to unity that "the next frame does not depend on the work i am doing right now"

#

unity doesn't know if it does or does not

#

it's "wait for end of frame" right? but graphics might not be done by the time your frame is ended. meaning the picture that the gpu is rendering isn't finished rendering at the end of the frame

stuck onyx
#

so its kinda... a thread you launch to gpu?

undone coral
#

"but how?" because graphics are pipelined

#

are you using URP?

stuck onyx
#

nono

#

built in

undone coral
#

graphics are pipelined in all of them

#

i was just wondering

stuck onyx
#

does that mean i cant use gpu readback?

#

or still can

undone coral
#

you can

stuck onyx
#

okay this iis gonna be harder than already was

undone coral
#

async gpu readback means schedule this piece of code to run when the resource i'm rendering to has actually finished rendering. don't wait for the result this frame

#

ReadPixels explicitly waits for the rendering to complete

#

do you see what's interesting there? because until you ReadPixels

stuck onyx
#

so i just need to use the async gpu readback on that operation?

undone coral
#

unity knows you don't need the texture on the main thread

stuck onyx
#

okay, that was clear

#

shit

undone coral
#

that's sort of what the error was saying

#

the error is horrible

#

if you just want to show the camera's output in your scene, put the render texture on a material

#

if you need to save it to disk

#

one is to use async gpu readback

#

which you're right is not supported on some low end devices

stuck onyx
#

i wanted both

undone coral
#

another is to use jobs

#

ah

stuck onyx
#

so i kinda have cached

undone coral
#

yeah you can do both

stuck onyx
#

the different areas

undone coral
#

well... reading the texture from disk is always synchronous so it will lose more than you gain

stuck onyx
#

because the player usually doesnt modify more than 2 areas at the same time

undone coral
#

this is a unity limitation

#

i'm not sure if it's still a problem someone who has done this more recently will know

stuck onyx
#

yeah but thats not too much of a problem, since i saved the texture without encode

#

the saving and reading is... 2 ms

#

maybe 3

undone coral
#

that's actually a colossal amount of time lol

stuck onyx
#

as i saiid... when i change 'mode'

undone coral
#

also for something that you don't really need to wait for

stuck onyx
#

theres a transition, im kinda free to use some time there

undone coral
#

okay

stuck onyx
#

hmmm

#

im trying to sort my thoughts

undone coral
#

yeah this stuff is really tricky

stuck onyx
#

i appreciate a lot the time you took explaining to me

#

thanks a lot

undone coral
#

yeah it also helps me looking up things too

#

i am also learning

#

basically the idea is you have a texture that only exists in the GPU's world, the render texture

stuck onyx
#

reading the unity docs about asyncGPUReadback

undone coral
#

on a mobile device, it's unified memory. however, i don't believe ther'es a way to ask unity to "demote" a render texture to a regular texture

#

it's possible that asyncgpureadback can do that for you

#

i also don't believe you can mark a render texture as read-only after it's been drawn to. after all, the camera will be writing to it next frame

#

this means that, overall, you have a pretty problematic situation

#

you will have to copy in order to cache something to disk from the gpu, if you are also rendering to that same piece of memory later

#

you can create a pool of render textures

stuck onyx
#

16 rendertextures

undone coral
#

you would need a pool of Nx16 render textures

#

or use exclusively async gpu readback and create a copy (i.e. ReadPixels)

#

it actually must already give you a copy

#

yeah it does

#

async gpu readback gives you a copy

stuck onyx
#

but

#

you give a texture to asyncgpureadbackRequest

#

is it the empty one or?

undone coral
#

a texture is just "a view into a gpu resource, potentially unintialized"

#

async gpu readback will initialize it for you

stuck onyx
#

resource to read the data from.... ah i guess thats thew render texture what you give to the asyncGPU

undone coral
#

yes

#

so internally async gpu readback does

#
var source = renderTexture.GetNativeTexturePointer();
var destination = destinationTexture.GetNativeTexturePointer();
CurrentGPUCommandBuffer.afterRenderCommands.CopyFromToWithCallback(source, destination, AsyncGpuReadbackCallback);
stuck onyx
#

bilit means copy in graphics?

undone coral
#

yeah

stuck onyx
#

okay im gonna give a try to this

undone coral
#

the idea is that the gpu command buffer, it's like a Task that is run on the "gfx" thread

#

and you're adding more stuff to run at the end of the task

#

does that make sense?

#

and "gfx" tasks are ALWAYS DoGfxTask().Forget() 🙂

#

it's always UniTask.Void.

stuck onyx
#

yes, and before this i was doing it in the CPU

undone coral
#

yes

#

you were await DoGfxTask()

stuck onyx
#

but then... shoulnt unity have a more straightforward way to do this kind of stuff?

undone coral
#

it is unknowable how someone will use the texture

#

some people use the textures for gameplay

stuck onyx
#

i mean.... i understand this now you explained but... everybody using ReadPixels will be wasting resources if doesnt know this

#

ah

#

ah of course, the main difference here is as you said... i was waiting for something i was not even going to use

#

shit this took me on a wrong day

undone coral
#

lol

stuck onyx
#

😅

undone coral
#

yes everybody using readpixels is wasting resources

#

i agree

#

unless it is important for the business logic of your game

#

almost everyone will want to reference the render texture in their material

stuck onyx
#

ill try to improve this shit and let you know how it goes

undone coral
#

or use async gpu readback to do work on a rendered frame in unity

#

if you need to do work on a rendered frame that is exclusively graphics, usually it's best to use a custom pass / full screen shader

#

if you need some hybrid of all of them, you can use jobs*

stuck onyx
#

buff... im not ready for that shit, im the only programmer in the project and i have my hands full

undone coral
#

jobs that use managed types are not compiled with burst. so for example the job that splits the rendered texture into 16 pieces would be a burst-compiled job, then the 16 jobs that save those buffers to files would be a not-burst compiled job

#

and the dependency chain for jobs is explicit. what that means is you can expressly state if you need the output of a job on the main thread for gameplay purposes

#

the way you do that is INCREDIBLY ARCANE because i believe like many things in unity (i'm looking at you UGUI) it was written by ESL people, which as an ESL person i do not mean disrespectfully at all

#

i am saying that to just illustrate that jobs are helpful, and the way its APIs are named is bad, but they are the right APIs

#

burst compiled = fast

stuck onyx
#

yeah yeah im grateful for it

#

but if im not wrong... in order to work with jobs i need to pass raw data to the job, cant use textures or unityEngine stuff right?

undone coral
#

you would use uni task for saving to files, btw, since it would be blocked by file io which is already pipelined elsewhere

stuck onyx
#

sorry im not into it at all so know little about it

#

but writeAllbytes is async

#

sorry

#

im using

#

stream.WriteAsync

rugged radish
#

speaking of Job limitations
for some reason I assumed you're not supposed to access unity's APIs from them, but just randomly tried using Debug.Draw and it worked just fine
did I assume wrong ? would like to get a clear list of do and don't for jobs, so far I only know about unmanaged memory and native containers

#

my understanding for job system was - just do a lot of parallel math and data manipulation

#

but seems like you can do more with them ?

undone coral
#

you can only burst compile and therefore accelerate jobs authored within specific constraints

#

if you ignore those constraints random bad things will happen

undone coral
stuck onyx
#

oh yeah i found that not long ago! gonna take a look

undone coral
#

observe read pixels is not used!!

rugged radish
undone coral
#

all these api calls set up a "job" (not in the sense jobs) with a dependncy graph to be sent to the GPU

#

i.e. a command buffer

undone coral
#

and i've NEVER authored a job

rugged radish
#

I see, so I should research every single thing before moving it inside a job

stuck onyx
haughty niche
#

any1 knows if this is upToDate
if no, then whats the new version called

shadow seal
#

Networking

#

Always has been

rugged radish
#

can you have a mesh with multiple submeshes all using the same material ? can't find anything that would suggest that possibility in the docs.
alternatively, if I add the same material multiple times over, so that each submesh has one, will that save draw calls at all ? (I'm looking into implementing a mesh combiner to optimize rendering performance and to reduce gameobject count)
from the looks of it, seems like you're supposed to merge all the submeshes, and then, if the combined mesh needs to be modified - reassemble the whole mesh again with modified data. is my assumption correct ?

haughty niche
#

okay so that did work thanks

rugged radish
#

my initial idea was to combine meshes into a single mesh so that each submesh would have its own submesh index, which I wanted to use to try and set an empty triangle list for that particular submesh

haughty niche
#

"isLocalPlayer" used to work

#

what is it now?

#

if any1 knows

undone coral
shadow seal
# haughty niche

Only in NetworkBehaviour classes, and you should not be using UNet at all

undone coral
#

if you are using HDRP, gpu instancing is the only way in practice to avoid 1 draw call per object. hdrp you'll see has a huge number of draw calls

haughty niche
shadow seal
#

Replaced by Netcode for GameObjects

undone coral
#

why? because hdrp supports lots of realtime shadows is my understanding

haughty niche
#

im not fluent

undone coral
#

@rugged radish so it can be really scene specific

shadow seal
undone coral
#

if you want to reduce draw calls in hdrp, the highest yield thing you can do is manage your lighting & shadows really tightly

haughty niche
#

so how

#

do i do my networking xd

undone coral
#

then gpu instancing

#

because every hdrp material basically has "shadow map" as a hidden parameter

#

and you can see how the same mesh and the same material can have different shadow maps depending on where it is in the scene

shadow seal
rugged radish
undone coral
#

it can even foil gpu instancing is i guess my point

undone coral
#

that's also why shadow atlas size is important

haughty niche
#

im wathcing a guide that uses mirror

#

cuz i dont know how this networking stuff works

shadow seal
#

Well you need to be using Mirror not using UnityEngine.Networking

undone coral
#

it lets you do 1 shadow texture for everything and kill draw calls

#

there's a lot of details here

haughty niche
#

thanks!

undone coral
#

what kind of scene is it @rugged radish ?

haughty niche
#

what

#

which one

#

mirror or mirro

undone coral
#

i'm jk

shadow seal
#

Mirror obviously

undone coral
#

it's mirror

haughty niche
#

mirror.(antyhing)

#

or just mirror

undone coral
#

you're at the start of a very long journey @haughty niche

shadow seal
#

Just Mirror

undone coral
#

maybe start with a Photon sample

haughty niche
#

okay thank you!

undone coral
#

they're really good

#

try to find a photon sample that is similar to your game

rugged radish
haughty niche
#

so here i am XD

#

trying my dear life

#

to make a shooter

#

im not fluent nor do i understand programming at all

#

but i have a map and working controls for a player

#

just need to get the networking down

shadow seal
#

You're in for a bad time

rugged radish
#

it's a bird eye view, camera is high above the ground and looks down

haughty niche
#

and im set (for now)

rugged radish
#

and I can't just paint trees like foliage, they do behave like game objects, player will often remove them

haughty niche
#

still does not work

haughty niche
#

do you know

#

what i am supposed to type

#

instead

undone coral
#

it looked like a forestry simulator

haughty niche
#

doctor do you know?

rugged radish
#

yeah, it's a lot even in a single world fragment

undone coral
#

so it's probably too late for this

#

but the best thing to do is to have a LOD=0 tree that is identical everywhere, that is used for gpu instancing

#

for some LODs 0...N you use the same handful of tree models and materials. if they are only illuminated by the 1 directional light in real time, they will be correctly instanced (by LOD)

#

the thing that is "different" about each tree can either be baked into the whole tree (so gpu instancing "draw call" per unique tree) or you can split it off into different pieces

shadow seal
undone coral
#

where LOD 0...N is invisible, and N...max_lod is the unique elements

haughty niche
#

im sorry if i sound stupid hahha

shadow seal
#

You are in for a horrific time

haughty niche
#

well im doing this for my friend so i want to try

undone coral
#

some things that will blow up efficiencies gained by gpu instancing -> trees that can cast shadows on other trees

haughty niche
#

im gonna give up when i cant to more

undone coral
#

think about how that would work

haughty niche
#

but im going as far as i can

shadow seal
#

Well my advice is to learn C# first

haughty niche
#

yes

#

well i do know some java

#

at leats

shadow seal
#

It's a start

haughty niche
#

ik how methods, classes, loops etc

#

work

undone coral
#

someone who is really a rendering expert can say if that happens or not

haughty niche
#

but yes where would i put

#

NetworkBehaviour class

#

in the script

shadow seal
haughty niche
#

insted of mono?

undone coral
#

@rugged radish what rendering pipeline do you use?

#

i am only really familiar with HDRP

rugged radish
#

damn, I know very little about GPU instancing, just glanced over a summary, so I need to reread that again to see if it's applicable to my situation

haughty niche
rugged radish
undone coral
#

GPU instancing is extremely efficient

#

it's preposterously efficient

haughty niche
#

where should i put the thing that you wrote to me?

shadow seal
# haughty niche what

It's not a hard concept to grasp, you don't know C# and you are trying to implement multiplayer, not a good combo

undone coral
#

i think if you want to see any of the effects of your choices, first you have to measure without shadows

haughty niche
#

i got it to work

#

i swaped mono out

#

thank you!

undone coral
#

@rugged radish shadows basically complicates everything

rugged radish
undone coral
#

i believe hdrp actually correctly gpu instances in 1 pass to generate the shadow atlas, then renders with it later in another pass

#

so that's fine

#

if it's one directional light you will not have problems with gpu instancing

#

i remember your screenshots

#

you should definitely be using gpu instancing

#

to force the trees to be rendered using gpu instancing

stuck onyx
#

@undone coral i kinda made it work on the first attempt!

rugged radish
#

Yeah, reading the docs rn, I do have some requirements.
I think I turned away from GPU instancing because I assumed it's not a good fit for interactive elements
but maybe I just assumed wrong

stuck onyx
undone coral
#

does that make sense?

stuck onyx
#

i know is dirty now but... well at least captured the portion as it was supposed to

undone coral
# stuck onyx

yes you probably want to put writeallbytes on a unitask thread

#

and then you're gucci

#

and do using _buffer so that you correctly handle io exceptions like running out of space

#

or iunvalid permissions

stuck onyx
#

now i dont need a texture anymore, except whenever i want to load this on the material

undone coral
#

(you should probably panic for those anyway)

stuck onyx
#

oh yeah

undone coral
#

it's unavoidable

#

you don't have to change the scripts to be aware of LODs

stuck onyx
#

shit im so happy, ill let you know how the global process goes and send you the script if you want

rugged radish
#

LODs aren't really a problem, it's all programmer art anyway

#

throwaways

undone coral
#

it's just the technique to control what has to look unique versus can be a generic tree

#

there are 1,100 of them visible and gpu instancing made it run extremely efficiently

rugged radish
#

nice stuff btw
didn't know you could do something like that, have normal lods and a special instanced lod on the same model

stuck onyx
#

@undone coral so basically what we do here is send the task we were doing with the cpu before with readpixels to the GPU? is this correct?

undone coral
#

hold on let me show you a screenshot

stuck onyx
#

sure

undone coral
#

^do you see how "redner thread" does work that overlaps with "main thread"?

#

and that render thread's work is really a long time?