#archived-code-advanced

1 messages ยท Page 119 of 1

misty glade
#

(not like an SSD or anything)

#

"won't fix" ...

echo coral
#

sounds like they arent sure if its a regression of an old bug or not ๐Ÿค”

misty glade
#

i'm reading through the [very long] forum post to see

#

hundreds of posts

abstract hill
#

Hi all, I am working on a project where I am generating procedural terrain and storing said terrain data in cells (think along the lines of Minecraft's generation), Right now I am creating these cells and storing the data in chunk objects (class objects). Since i am now trying to optimise this I want to move to structs so I can utilise native arrays.

My main goal with this though is to avoid unnecisary recreation of structs, such that I need to modify a single value during the generation phase of these chunks I would then need to overwrite the original copy with the new version with updated values.

I have been looking in to access these with pointers and unsafe code, below UnsafeUtility seems to allow me to get a reference to the original version from within the nativeArray:

ref CellColumnData cellColumnData = ref UnsafeUtility.ArrayElementAsRef<CellColumnData>(chunkColumn.cellColumnDataArray.GetUnsafePtr(), columnIndex);

I would like to be able to do something simular with NativeHashMaps, as I am storing the chunk data right now in a Dictionary<int3, Chunk>. Converting the Chunk to a struct would be fine but I can't seem to find anything that isn't AI generated rubbish on actually being able to access the original copy of these structs as references.

What is the "correct" way of actually doing this? I was considering directly assigning memory using Marshal, but reading online that Burst doesn't apparently work with memory like that?

Any help with this would be appreciated.

echo coral
#

but what is Dictionary<int3>, is that the 3d pos for the chunk?

abstract hill
#

Yeah, unity mathematics has int3's, basically vector3Ints that are meant to be lightweight.

echo coral
#

dw im aware of the mathmatics lib and burst

compact ingot
abstract hill
compact ingot
#

it is very likely that without doing everything exactly right, you wonโ€™t gain anything

echo coral
abstract hill
#

Yeah thats the crux of the problem, I am trying to get the code sorted to then work with Burst in ParralellJobs. So I need native arrays Dx

compact ingot
#

You fist need to understand how jobs/burst improve performance

#

cause there is a lot of overhead involved when using both and you need to understand how to get a net positive result

abstract hill
compact ingot
#

well, without specifics not much can be said

abstract hill
#

I have already transitioned a chunk of the code to using jobs, and have got significant perfornamce increases. its just specific regions that need to be fixed now (optimisation pass, and setting up rendering groups). However as I said since all the data is being stored in classes, it can't easily move this data to execute on a job without a significant copy paste job from the class to native arrays.

Ideally I would have a single true copy of the data that is read only sent to the jobs, but can be accessed and modified outside of them.

#

I guess, if specfics are confusing things, my question boils down to. How would I store structs in a dictionary like way, so that I can both access them by reference and use them with the Job system without needing to copy data.

echo coral
#

I dont think this is possible because the dictionary could move the contents at any time (thus making a struct ref invalid)

abstract folio
abstract hill
abstract folio
#

(never used Job's so shot in the dark) oh well ๐Ÿ˜ฆ

abstract hill
#

Am I even correct in thinking that the job system doesn't like pointers to structs? I read this earlier when I was thinking of instead parcing a NativeHashSet of NativeHashSet<int3, Chunk*> where chunk is created using Marshal's malloc?

#

As that would mean the original copy is kept untouched, but dupicating / copying the pointer doesn't really matter at that point.

abstract folio
#

is the issue that your classes ->srtucts are large, and have lots of members (bytes)?

#

if so, perhaps you could convert one class to multiple structs- so when you need to change something, only a small amount of data needs to be copied around?

abstract hill
#

Not to large, but not small either. A single Chunk / ChunkColumn stores tempuary data for world generation (needed by neighbour chunks too), the chunk column holds smaller structs for each cell column across x, z. Which the Chunk holds an enum on each cell, which is (4096) cells in total per chunk.

#

So even though their isn't a huge amount of data in these things, if I can avoid unnecisary copying that would be ideal. especialy if I am just updating a boolean or such.

echo coral
#

Well to put data into and out of a burst job it will always be copied

abstract hill
#

For the jobs thats fine, I more mean in the general use case of the program

#

Jobs wise, i am treating all data as read only

echo coral
#

So was the problem not copying in the job when accessing this shared int3 -> Chunk map?

abstract hill
#

No no, the problem is that I want to store my chunk data in a nativeHashMap, so that I can pass it into the job system,
However, I also want to access and modify the values in my normal c# code, (like populating cells and checking for visibility in the optimisation pass). So I would like to modify the original reference to the structs while still having them in a format that can be passed to the job system

abstract folio
echo coral
#

Well to be supported the map value has to be an actual struct or other supported type

abstract hill
#

that would only work unfortantly with linear chunk indexes. Since I am using 3D chunk coordinates I would not know the position of the given index.

abstract folio
echo coral
#

im a tad confused following this tbh. Is a chunk 2d?

abstract hill
#

I'm not sure what you mean.

echo coral
#

When i can i always do a single dimension array for 2d grids of a known size (and ofc can be extended to 3d)

abstract hill
#

Chunk is 3D, its a 16 * 16 * 16 object that holds data for 4096 cells, which spans an infinate grid.

#

This is why it needs to be stored in a hashmap / dictionary as their is no upper cap

echo coral
#

And are chunks placed in 3d or 2d?

abstract hill
#

What do you mean?

echo coral
#

Is it like minecraft where chunks exist in a 2D grid is my main question basically

abstract folio
#

I don't see why that matters for this issue, can you explain why you ask? @echo coral

abstract hill
#

Game logic is 3D, but yeah mainly the question is about storing the data in a way that can access the structs by reference in a burst supported format

echo coral
#

From what i understood they want to be able to access many chunks by ref but ofc using a map/dictionary prevents this
But if you could also group many chunks into a fixed sized collection you can work on the bigger group by references.

abstract hill
#

(Ignore the terrible visuals, this is just basic rendering atm)

#

It seems strange to me that their isn't just a way to access the raw pointer to the structs memory while its in a native hash map

echo coral
#

Usually its because of relocation

abstract hill
#

Wouldn't the pointer also be relocated though?

echo coral
#

managed class references do this but in native code its not a thing

#

If you have a pointer to memory there is no guarantee after that what it points to still exists.

abstract hill
#

Even if its generated using UnsafeUtility.Malloc or Marshal?

echo coral
#

That will because you are managing the memory

#

If you malloc then ofc it will be safe to use until you free it

abstract hill
#

But malloc isn't burst compatible?

#

Hmm, actually

#

"Persistent allocations should work within Burst"

#

So much conflicting info xD

#

I may just give this a try then, generate the structs using Unsafe's malloc and then pass in the NativeHashMap as a mapping of int3's to pointers. If it doesn't work I may come back xD

echo coral
#

this in theory works but ofc depending on where the Chunks are now allocated you loose the benefit of contiguous allocation

abstract hill
#

contiguous allocations? Like fast lookups as they would sit next to each other in memory?

abstract folio
worldly pecan
#

Actually, if you limit the amount of chunks to a square region around the viewer, you can use a perfect hash system and store the chunks in-place.

public static int HashCoord(int2 CCoord){
    //perform a true mathematical modulous with the chunk coord
    int2 hashCoord = ((CCoord % numChunksAxis) + numChunksAxis) % numChunksAxis;
    //Linearly encode the remainder
    int hash = hashCoord.x * numChunksAxis + hashCoord.y;
    return hash;
}

This hash function can produce a perfectly unique index within the hashmap as long as two chunks are greater than numChunksAxis apart

echo coral
#

Yea as that will give a speed improvement if there would be lots of memory access to elements close to each other

worldly pecan
abstract hill
#

Thank you all btw!

echo coral
#

Yea having a larger fixed size block of many chunks will make it easier to handle. Hope you get something working as you want

scenic charm
#

Hello! I've started using the ui toolkit and the localization package together and I'm wondering about the update logic when binding LocalizedString.

As an example, if I bind a Label element through the UI builder to a simple field in a data source class. As such:

public LocalizedString Text;```

I've observed that setting the `LocalizeString` itself and setting the `LocalizationSettings.SelectedLocale` both trigger the binding. Now, i'm not sure if the binding mode `OnSourceChanged` is working just as intended or if the binding is checked every frame and that's why both of these scenarios work.

I've looked around on how I could debug this but I don't seem to have found any way to hook onto a binding trigger.
bronze glen
lean lotus
#

this is from code general, got recommendation to post this here cuz it is a little bit advanced so here it is

hello, i have been following a tutorial on procedural planets which i almost completed, and i have been trying to add a level of detail system (LOD) but im having issues with chunk generation, the verts and triangles are getting distorted when the chunks are generated and dont know why i get this problem, have been working on it for hours and im really starting to get frustrated, here is the code: https://scriptbin.xyz/kobupojini.cs

Use Scriptbin to share your code with others quickly and easily.

upbeat path
#

!code

thorn flintBOT
lean lotus
#

ty, didnt know that

upbeat path
#

So if you've been 'working on this for hours' why is there absolutely no evidence of debugging in your code?

lean lotus
#

cuz i deleted the debug logs

upbeat path
#

so how do you expect us to help you?

lean lotus
lean lotus
upbeat path
#

we cannot run your code so it's up to you to provide data we can work with

#

which means Debug.Logs and Console screenshots

lean lotus
#

ok, i will give you that

lean lotus
# lean lotus this is from code general, got recommendation to post this here cuz it is a litt...

here are 3 screenshots, by the way, in the code, the ConstructTree method is what generates the chunks(LOD), and the ConstructMesh method makes the planet with all its features, inside ConstructTree i have a variable that calls CalculateVerticesAndTrianglesOfChunk method, which is called until the chunk data with its triangles and vertices is calculated which means the level of detail of the planet.

i know the problem is somewhere between the code in ConstructTree method, because that is where LOD is calculated, there i specify a parentChunk that generates the children, there are 2 lists, which are vertices and triangles, they first get the data of the mesh that has been made with ConstructMesh, then after the calculations of the LOD have been done, i store that data inside those variables and convert them to arrays and recalculate the normals as the final part, and as you can see in the screenshot, i get those distortions, and i dont know what part of the calculation or data management is bad here

thin vine
#

I've been able to achieve the result I want by editing the Lighting.hlsl file in Packages/Universal RP/ShaderLibrary/ but I'd prefer to turn it into a Render Feature so that it's better integrated. I made this graphic to illustrate my currently janky process.

mental escarp
#

Hi, I've been trying to convert my json to the RectTransform, and I got it for the most part.
However, there is a huge issue.
If I combine 2 anchor types(e.g. X uses position+size whilst Y uses stretching) it breaks.
This is the function that's supposed to handle the data loaded from json.
What might seem odd at first is repeated if checks for the offset types.
This is intentional and I've done it because I use this to set the regular position, and from my understanding, it also overrides offset values, not just relative ones.
At first, I thought this was the issue, and therefore, I made the change I just mentioned above, however, it still doesn't work.
What happens now is if one of the axes uses the offset(different anchors), it overrides the relative(same anchors) position of the other axis.
I am honestly out of ideas and don't know what to do, any help is appreciated.
Thanks in advance and please @ me when replying, I am off to sleep now so odds are I won't see the message otherwise.

tired fog
#

Is there any kind of event or method called tied to switching the display in GameView?

#

For some reason my game crashes when I change display twice. Like from 1 to 2, no problem, from 2 to 1 crash

#

I have a custom GPU rendering system that Im working on that I think could be the cause, so I want to ensure I handle those switch display cases accordingly, but I have no clue what's being called that could cause the crash

#

It seems that im calling Graphics.RenderMeshIndirect but they are not actually used until the camera is in the gameView. Aka, they are being scheduled but not called. So when I switch display, all the draw calls I called are suddenly drawn which crashes my unity

mental escarp
misty glade
#

yeah, ToJson() and FromJson()

#

all of that stuff is well and good, but it might not be everything you'll need to recreate a recttransform

lament salmon
#

Components can't be properly serialized with JsonUtility

#

Or does it save some meaningful data?

misty glade
#

components can't? it says specifically in the docs that any MB can

lament salmon
#

At least you can't deserialize them with FromJson

#

Oh okay yeah:

However, when deserializing JSON into subclasses of MonoBehaviour or ScriptableObject, you must use the FromJsonOverwrite method.

#

TIL!

mental escarp
misty glade
#

i mean, that's true too ๐Ÿ™‚

#

i haven't tried to actually serialize a RT using unity's method - but depending on what you're trying to do, i'd probably create my own POCO for "location" on the screen, and the just instantiate a prefab with the values i care about put into it.. instead of trying to make a one size fits all RT serializer

echo coral
misty glade
#

there's a lot of stuff in RT under the hood, and i don't know what all of it is (I don't think I'm necessarily supposed to)

mental escarp
#

either rt structure and code are weird or I am seriously lacking braincells(prob the second one)

gloomy palm
#

is there someone with knowledge in vertex manipulation that can tell me why the vertices aren't where they should be even though they are in the inspector

#

I'll show screenshots of whatever you may need to see

gloomy palm
#

it seems to be stretched from the getgo, this is where the first vertices should be but they're clearly not

long ivy
#

"aren't where they should be" isn't very descriptive, but from the naming of your vars there's a problem there already because mesh vertices are defined in local space. Are your GOs holding these all at (0,0,0) with identity scale and rotation?

gloomy palm
#

the parent object is at 0,0,0 with identity scale and rotation, so is the prefab. The object itself is not at that location, but it does have identity scale and rotation and the position of said object is in the middle between the two points of where the vertices should be manipulated to.

How do I define the vertices in global space?

untold moth
gloomy palm
#

It does not after creation, so that'd be fine by me

gloomy palm
#

that fixed it, thanks!

worldly pecan
#

Hey guys, has anyone ever implemented the transvoxel algorithm before? I'm trying to do it on a shader but I've noticed that the LUT's given by the github linked on https://transvoxel.org/ doesn't match the obvious way of finding the LUT's index. There's this following diagram in the paper, figure 4.16.

6---------7---------8
|         |         |
|         |         |    
|         |         |
3---------4---------5
|         |         |
|         |         |
|         |         |
0---------1---------2

So if for example nodes 0, 1, 2, 3, 4, 5 are underground and 6, 7, 8, are not, The LUT index should be, 0x3F or 63 whereby the first 5 bits are set. However when I look at the "transitionVertexData" table on https://github.com/EricLengyel/Transvoxel/blob/main/Transvoxel.cpp, I find that the 63rd entry has vertices that don't reflect the isosurface at all. My best guess is that the look-up index isn't determined with the same diagram, but I can't seem to find any reference to how it's found anywhere.

#

Just looking to see if anyone's done it off these LUTs and knows what's going on here

worldly pecan
#

I found the issue, apparently Eric Lengyel when writing the LUT made the corner order follow an archimedes spiral when finding the look-up index.

6---------5---------4
|         |         |
|         |         |    
|         |         |
7---------8---------3
|         |         |
|         |         |
|         |         |
0---------1---------2

This is in spite of the corner index the LUT references being in a different order. He just never noted that down anywhere, causing me a few days of agony. Hopefully he amends this or someone puts a post about that.

#

Honestly there's no reason I can think of of why the index is formulated following an archimedes spiral. Low-key I think he just did this to mess me up

bleak citrus
#

huh, yeah, it's not like this is a massive dataset that needs a clever traversal order

#

that technique looks neat!

compact ingot
#

Maybe it helps with expanding/contracting the indices to a 2 by 2 grid by dividing/multiplying by 2

wooden silo
#

Hello, I'm trying to make a Native Plugin for a feature that is only available in C++ but I'm having issues with .h files not being packaged with the .dll. How can I solve this issue?

echo coral
wooden silo
#

I was able to solve it, the .cpp and .h source files were being included in the unity build process

#

regardless @echo coral thanks for coming to my aid

echo coral
#

ah right yea that usually works reliably when you put the src files in project ๐Ÿ‘

sonic hinge
#

Hi ๐Ÿ™‚ I'm programming a sim/tycoon game where procedural stuff is being generated by the player. Let's say the player builds walls.

I keep an underlying data structure of wall placement which gets updated anytime there is addition or removal. I'm wondering how to properly decouple logic from my data structure and MonoBehaviour.

I either need to update the Mono class (mesh, collider, etc) from my data structure or the other way (update data structure from Mono class).

What's the advised way of representing this 2-way relationship?

  • Centralization with a dictionary? Like assigning a same id to both the instance data-side speaking and in Mono class
  • Class fields? But I wouldn't like having a direct ref to my game object inside my data structure
  • Other Unity pattern shenanigan that I may be unaware of?...
dusty wigeon
sonic hinge
#

Currently I'd have a WallBehaviour (Mono component) and Wall (which is from my data structure)

dusty wigeon
sonic hinge
# dusty wigeon Why do you want to seperate them ?

I feel like a separation of concerns would be relevant, as MonoBehaviour exposes stuff to the engine (mesh, physics, etc). 'Wall' class is a plain-old struct. I'd like to see my 'WallNetwork' interacts with Mono classes as little as possible.

dusty wigeon
#

If the idea is that the Wall could exists without a WallMonobehaviour, you can either use events or nullcheck before accessing the monobehaviour.

#

If you truly wants to increase the complexity simply to be cleaner (for no beneficit), you can use an interface to obfuscate the relation between wall and its monobehaviour.

sonic hinge
#

It's not much about ownership because each 'WallBehaviour' will be associated with a 'Wall' whatsoever. It's more about considering traversals, algorithms on the data. I don't feel like using MonoBehaviour classes for that is a good bet

#

but I may be wrong and overengineered it, of course it would decouple logic, but it will give more sense to it

#

I also try to decouple data from Mono if I ever need to feed data to a job, later on

echo coral
#

if wall is a class then why not have the monobehaviour reference that and not hold data itself? If its a struct then as suggested, use events and some manager to sync updates

sonic hinge
#

Yup thatโ€™s already the case, except that Mono-related stuff is keptโ€ฆ in Mono class ;)

#

My concern was more about cleanly keeping track of Mono from data, and reverse

compact ingot
# sonic hinge My concern was more about cleanly keeping track of Mono from data, and reverse

There is often nothing to gain from having a non-mono representation of a world object. Usually it only makes sense when the structure of the backing data is significantly different or memory has been exhausted. Performance benefits are not usually unlocked by having a poco dual. You also often find that the lifecycle that mono gives you will have to be recreated in the poco and sync between both is a frequent source of bugs.

#

if you want to have a clean/efficient representation, use entities, donโ€™t reinvent game objects just because you canโ€™t โ€˜newโ€™ monobehaviours.

midnight violet
dusty wigeon
dusty wigeon
sonic hinge
dusty wigeon
#

You need to ask yourself why are you doing it. Doing something simply for it to be aligned with best practice is usually an error. Mostly because those practices are not created with Game Development in mind.

sonic hinge
dusty wigeon
sonic hinge
#

Reading through discussions on forums it sounded like MonoBehaviour is the root of all evil lol

#

A project surely benefits from limiting them as much as possible though, I prefer to use them only where ultimately necessary ๐Ÿ˜

#

(Primarily concerning lifecycle functions)

midnight violet
#

MonoBehaviour is tied to visuals in my head. I try to do everything in there, that is not processing data but rather position stuff and so on and needs to rely on the unity execution order. Data driven objects are just classes and only singleton managers and staff alike will inherit from monobehaviour to be accessible in the editor and observe data fetched.

coral citrus
#

#archived-code-general message
heya, does anyone here have a brain for camera matrix math that could help me out? I'm almost positive the issue here is with having my camera tilted down at a 30* X rotation, but I am absolutely lost as far as how I can fix that

midnight violet
#

crossposting wont speed this up

coral citrus
#

apologies, I wasn't sure if camera matrices were a shader thing or not

midnight violet
#

but you posted a coding channel link ๐Ÿ˜„ So you did post it on two coding channels and not even #archived-shaders ๐Ÿ˜„ OR? ๐Ÿคฃ

coral citrus
#

I originally posted the problem there, but someone answered my original question about why it was happening and I realized it's a camera matrix issue

#

so I posted the link to reference the original question with my added info from the answer

#

since I figured camera matrices were less of a general thing

midnight violet
#

Okay, just hard to follow that over 3 channels ๐Ÿ˜‰

coral citrus
#

np, that's why I included the message link to the original question

midnight violet
#

So you say, z axis is your problem?

compact ingot
# midnight violet MonoBehaviour is tied to visuals in my head. I try to do everything in there, th...

I think many share this association but it is far too limiting. Rendering is really just a small part of all the common problems that a game object solves. Many of those are only evident late in projects of an appropriate scope and when the team hasnโ€™t gone off-roading and lost in the poco woods. That said there are endless opportunities to build systems adjacent to game objects that do not need or benefit from MonoBehaviour. Itโ€™s just that usually, going โ€˜all inโ€™ is trouble.

midnight violet
midnight violet
bleak citrus
coral citrus
#

hmm, right, that makes sense. but there has to be some sort of equation to allow it to accommodate for that difference right? with the exception of 90* of course, though in that case it can't jitter since Z movement at a flat angle would be static in that case

#

I did find this but it didn't work in my case, and is a bit messy

pale salmon
#

Hey guys, basically, I have a vertex on a mesh, for that vertex I want to return a vector3 which would represent the up direction for that point on the mesh, how should I go about doing this?

sly grove
pale salmon
#

No I just have a mesh and on that mesh I need to get the up direction for a vertex

sly grove
#

In general if you have a Mesh object in Unity you can get the surface normals in the .normals property on the Mesh

#

so if it's vertex v, then the "up direction" for that vertex is Vector3 normal = myMesh.normals[v];

pale salmon
sly grove
#

Assuming by "up direction" you actually mean "normal"

#

Just note that every time you do myMesh.normals it copies the entire array, so you should do it very rarely and reuse the array if possible

pale salmon
sly grove
#

yes those are called normal vectors

#

and that's exactly what I'm pointing you to

pale salmon
#

Yup gonna try it with that thanks

#

I was never particularly good remembering math terms so I didnt know "normals" was the thing to look for but hearing it now makes some supressed math class memories come back

brisk olive
#

does anyone know what can be causing this

#

whenever im playing my main game scene in development mode im getting this

#

tried 3 unity version still its the same

#

unity 6000.0.33,29,20f1

echo coral
brisk olive
#

how to do that?

echo coral
#

use android logcat and pray you kept your symbol files from this build

#

you essentially configure the path to the symbol files, open the stacktrace utility window and paste in the stack and decode it

brisk olive
#

is this it?

#

i configured symbol paths like this

#

if i put the symbols symbol path at top i get this

#

@echo coral

#

any idea?

echo coral
#

huh the il2cpp one didnt work, did you copy that one too?
looks like some internal unity api though

brisk olive
#

it is il2cpp symbol

upbeat path
brisk olive
#

but why is this happening only in development mode

#

its working fine in release build

#

i was making development build to profile my game

#

there is some performance issue

#

and out of the blue it starting crashing when i go to this scene in development build

#

last time when memory profiler was working i went to that commit as well

#

but still its crashing

echo coral
#

a null pointer deref is not the same

brisk olive
#

i even went back to the unity version i had used to profile at that time

#

its the same

#

crashing

#

there are 3 scene in my game - menuscene , practice scene , main game

#

menuscene loads fine

#

even practice scene

#

when i go to main game

#

it crashes

upbeat path
#

please type in full sentences you are not a 3 y/o

brisk olive
#

and this is happening only in development build

echo coral
#

ideally id like to see the last 3 stack lines decoded

brisk olive
#

i can make a build again if theres any steps to be followed

echo coral
#

I usually expect libunity and libil2cpp to decode

brisk olive
#

i was doing this

echo coral
#

did you actually put files there? go check

#

i put a manual path cus we use a build slave for builds

brisk olive
#

yup there are files there

echo coral
#

build a dev build again to a custom path and after copy over all 3 .so files

echo coral
#

wherever you configured

brisk olive
#

i only see 2 .sofiles

echo coral
#

i dunno if it needs to be configured to make the il2cpp one. I presume this is arm64 and also using il2cpp for scripting?

brisk olive
#

ok i found where the exact .so files were for my build.It was in Bee folder

echo coral
#

can you show all of the ones that got decoded properly...

#

best you can do here is figure out if this is your code somehow breaking, unity code or some library

brisk olive
#

you mean this?

echo coral
#

kinda yea. They the green we have is all from libunity so its some internal unity bug

#

next step is to search and hopefully find a pre existing bug report. else update to latest patch ver and try again. If still broken then report it yourself.

brisk olive
#

@echo coral thank you so much i solved it

#

i was calling garbage collector manually

#

i removed all of it

#

and now its working

#

thanks for pointing in right direction

#

i was hopeless

echo coral
#

you never normally need to do that but it shouldn't crash your game ๐Ÿค”

#

glad its solved though! decoding crashes is the best first step to find out the cause!

brisk olive
#

i was calling garbage collector too many times maybe that was causing it

#

and it was crashing in low end devices

echo coral
#

99% of the time you should not call it manually like ever

brisk olive
#

ok

#

i had a serious memory leak issue

#

so i was calling it in scene change

brave gorge
brisk olive
#

NO

#

then used addressable

#

then removed hard references in scripts

brave gorge
#

your game was crashing crashing cause you were manually calling the gc then some other code was trying to access a reference that was deallocated

brisk olive
#

i did that gc call thing in my initial phase of optimization .I read it somewhere

#

anyway now i know it's a bad thing

#
Resources.UnloadUnusedAssets();
System.GC.Collect();```
#

i was calling these both

#

Resources.UnloadUnusedAsset should do the work right?

#

i will remove GC.collect from everywhere

final steeple
#

UnloadUnusedAssets calls GC.Collect itself yeah

brisk olive
final steeple
#

(Well, to be more specific, it doesn't call GC.Collect but internally it activates the GC so it does the same thing)

echo coral
#

GC shouldn't ever delete objects still referenced so this is a bug

#

When you call it manually you are just making it happen sooner

#

Ofc if you used unsafe then this could happen perhaps but I presume not

austere jewel
#

If the Unity Object isn't referenced by a static or Scene then Resources.UnloadUnusedAssets will remove the object even though it could be referenced on the stack

#

(which is mentioned in the docs; it's a pretty easy thing to overlook when it's called interally via non-additive scene loading though)

echo coral
#

The managed object for it should still exist but I would expect the engine to account for someone trying to use an asset that was destroyed safely

austere jewel
#

If you've set the optimisation level to not throw exceptions for null reference exceptions then it will crash

echo coral
#

Can you change this for android? Doesn't seem smart to change anyhow

austere jewel
#

In one of my projects in the past, a 3rd-party porter introduced a build config that set NREs to crash, took a while to figure out what was going on

#

I think there's a setting that disables it project-wide, not just with attributes. It was a long time ago though so I can't remember

echo coral
stuck plinth
worldly pecan
#

Classic example of who needs saftey checks if our code is perfect

untold moth
#

There's not much point in implicit safety checks in release build anyway. It's not like you want the user to debug it.

echo coral
#

its better to have an exception (that can be logged somewhere) instead of the game crashing. Id be hesitant to disable this except in a few specific places.

stuck plinth
#

if you have spare CPU to throw at it, leave it on for sure then! that's not always the case though

midnight violet
#

When in debug mode, you can log, when not, you gotta fallback to something thats working for the user to know, whats going on

#

He does not know, an error occurred specific to your code, but know, something has to "try again" and revert to the last stable state to retry (unless your code is just wrong and will always return null ๐Ÿ˜„ )

echo coral
#

when i say log i mean to some service where you can see it such as firebase or unity cloud

ashen yoke
#

I discovered you can use a Tuple (vector3,vector3) as a dictionary key, presumably because it hashes it to make an id... but can I make it so that which ever order 2 values are passed in the key will be the same? AI suggests using magnitude to order them before passing as a key, I suppose if squared mag. might not be too big performance hit but still...

#

would have to be magnitude with axis adjustments though else 0,1,0 is same as 1,0,0 in order

#

hashcode for order I guess...

jolly token
#

Hash will be different, and even if you get same hash the equality is different

ashen yoke
jolly token
#

Well then use any stable order

#

You can just order with X then if equals order with Y, so on

ashen yoke
jolly token
#

Not GetHashCode

#

Thatโ€™s not stable ordering

ashen yoke
#

well I am not sure what is for Vector3, this is the real question...

ashen yoke
#

thanks

lost shoal
#

Hey, I have a little problem in project. It causes Unity to crash, and not like any kind of log crash where when unity crashes popups that beatiful window discribes if you want to send report to Unity and here are your logs if you wanna check what happend. It just crashes Unity completly, process stops to respond (Similary to the StackOverflow exception), but there is no any high processor usage in Task Manager. It happens randomly in different part of the game and in different actions taken. Do you have any idea how could I debug this mess?

stuck plinth
lost shoal
#

Visual Studio Debugger?

stuck plinth
#

whatever debugger you use should work

lost shoal
#

Okay what shoud I look for?

stuck plinth
#

if you press pause, see if it's inside a loop?

#

maybe there's a while loop with a condition that's always true

#

that would freeze in the way you described

midnight violet
#

up

lost shoal
#

But where I need to place break points?

#

Cause other wise i have bo fire Debug in VS and crashes Unity, but I dont see anything in VS

#

Okay

#

Okay

#

I catched it

#

Thanks guys

hasty tinsel
#

one of my biggest problems with the arkham games is that they were never 100% open world, like botw is. basically, the arkham games didn't let rooms be loaded in in the same "scene" as the main world, and i wanted to ask if anyone has any advice or resources that i can look into for making my game open world while still, yknow, not requiring 100% memory usage, lol.

compact vault
#

i dont think that's a coding question

hasty tinsel
#

๐Ÿ’”

compact vault
#

although, its pretty simple from what i understand. just dont load anything that's far away.

hasty tinsel
#

see, what does that means exactly?

compact vault
#

LOD should handle the rendering (not sure if that's automatic or not, i haven't used it in a while)

hasty tinsel
#

setactive false, or..????

compact vault
#

there's a lot of different things that would be in the "open-world"

hasty tinsel
#

true...

#

so like, what does load actually mean?

#

get something ready to be used in the memory?

compact vault
#

for most cases, probably just disable any scripts that aren't going to be near the player

hasty tinsel
#

makes sense

#

just make a big ass box collider

compact vault
#

a pretty common example is the super mario games. enemies aren't loaded until the player gets close enough to them. they're also unloaded once the player is far enough

hasty tinsel
#

LOD seems to work the way i should need it to work, so that feature of rendering is built in then โ‰๏ธ

compact vault
#

i've never actually had to use it myself. i dont typically work with art assets much. someone else might have to answer that (or you can google it)

hasty tinsel
#

what about shaders?

compact vault
#

also handled by LOD

hasty tinsel
#

wtf

#

its all built in ๐Ÿ˜ญ

#

i aint even gotta do anything

#

well ill make sure but

#

thank you :)

compact vault
bleak citrus
#

LODGroups turn different renderers on and off

#

Note that this has nothing to do with the LOD property that you can define for a shader

#

You can use it to limit which shader is allowed to run at all

#

I've never done that

bleak citrus
compact vault
dapper willow
#

does any of you guys have information about Tower Defense games?

echo coral
#

Wrong channel?

lost stag
#

is there any good way to make something like [SerializeInEditor] or maybe [InspectInEditor]? (technically I could write a custom inspector, but it tends to be a pain to just vis a few variables, and annoying to make those variables act like the default behavior) I often find I want to be able to inspect the state of certain runtime values in the inspector and thus make certain fields at least temporarily public or [SerializeField], but don't really want the fields to be serialized outside of play mode and definitely want to avoid including them in a build. I was looking at the decompilation of [SerializeField] but it looks like its basically just a marker for some native code so it doesn't look like I can do something with that. I could technically #if UNITY_EDITOR but that gets messy and I then also have to be careful to put any code in an #if UNITY_EDITOR block rather than just getting defaults which occasionally doesn't get caught until a build so its also not ideal. Thoughts?

stuck plinth
#

if you don't want to add a whole package i believe NA is open source so you can see how it works

lost stag
#

thanks! also, lol the odin store page videos doesn't work, the videos require third party cookies or something, and I'm leery about something with a non perpetual license but NA seems promising ... now to trying and get my team onboard

bleak citrus
#

What you want is a custom editor

echo coral
#

I use naughty attributes a lot its great (though can slow down the inspector if used a lot)

bleak citrus
#

NaughtyAttributes creates a custom editor for all MonoBehaviours (and i presume for all ScriptableObjects), iirc

#

which does mean it can clash with more specific custom editors

lost stag
#

@bleak citrus I could write a custom editor but its kinda a pain when I literally just want to inspect a few variables quickly, the point of my question was a simple way to do it for one off cases that is less horrible than just adding [SerializeField]

echo coral
#

you can extend theirs to keep both but if you go the custom editor route you can draw the default and add extra stuff

bleak citrus
lost stag
#

honestly even something like unreal's readonly would be nice to vis intermediate calculations and such that you don't want people trying to modify

compact ingot
bleak citrus
#

oh god, don't remind me

#

private fields are still serialized

#

(which can actually footgun you)

cold breach
#

Is Physics2DRaycaster bugged in unity 6? I'm getting no feedback on any 2D polygon collider events, no matter what I try.

sly grove
#

Which collider events do you mean?

vapid jackal
#

There are a few places out there on the web that all employ a similar type of solution to this. Dunno why Unity doesn't make it a standard engine feature. I use it all the time.

#

Oops I guess that's not exactly what you're asking for... but in any case, its a way to show the values in the Inspector without having them editable in the Inspector.

sly grove
cold breach
sly grove
cold breach
#

This is programming advance, not programming beginner.

sly grove
#

And as advanced programmers we check everything thoroughly

#

because we know we still make mistakes.

cold breach
#
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.EventSystems;

public class Mask : MonoBehaviour, , IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerMoveHandler
{
    [Header("Mask Settings")] public MaskType maskType;
    [ShowIf("maskType", MaskType.Body)] public BodyMaskPart bodyMaskPart;
    [ShowIf("maskType", MaskType.Head)] public HeadMaskPart headMaskPart;
    [ShowIf("maskType", MaskType.Outfit)] public OutfitMaskPart outfitMaskPart;

    [Header("References")] public MaskController2D maskController2D;

    public void Subscribe(MaskController2D maskController)
    {
        maskController2D = maskController;
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log("Click Detected");
        if (GameControlManager.Instance.announceMaskHit && !GameControlManager.Instance.isInteractionDisabled)
            //Announce and link to gameobject
            Debug.Log("Mask hit: " + gameObject.name, gameObject);
    }

    public void OnPointerMove(PointerEventData eventData)
    {
         Debug.Log("Move Detected");
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        Debug.Log("Enter Detected");
    }

    public void OnPointerExit(PointerEventData eventData)
    {
        Debug.Log("Exit Detected");
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        if (GameControlManager.Instance.announceMaskHit && !GameControlManager.Instance.isInteractionDisabled)
            //Announce and link to gameobject
            Debug.Log("Mask hit: " + gameObject.name, gameObject);
    }
}
cold breach
sly grove
#

do all the objects in question have the appropriate layers?

cold breach
#

Aye.

#

I've spent about an hour going through every forum post I could find. Everything was already correctly setup.

sly grove
#

it;s also possible a UI element is blocking things and eating the events

#

Try disabling everything except the object in question and the event system basically

#

and the camera

cold breach
#

I tested with all UI elements disabled.

sly grove
#

or in a clean scene

cold breach
#

I also tested with everything but the cam, sprite layers I wanted to poke, and camera.

#

Absolutely nothing.

cold breach
#

One moment.

#

I'll get this setup on a timer.

sly grove
#

Double check the INput Module settings as well

#

and that there aren't errors in the console, of course

#

(covering all the bases)

cold breach
#

No errors, input has been working fine.

thin mesa
#

have you tested with more primitive colliders like a box collider or circle collider to rule out the issue being the collider?

cold breach
#

And it just starts working after recompiling. Despite not changing anything in that script, and putting it on a seperate one.

#

Thanks for the help guys, I think unity decided to have slow day today though ๐Ÿ™‚

ashen yoke
#

Hi I have a lot of issues with a package using async Tasks. I need a Task to tell a Monobehaviour something is done (callback/Action), but it being a Task it can run off the main thread. I need to notify from the main thread - I mean all the tasks could just run on the main thread but what is the point of Tasks then instead of say coroutines? I find it an odd mix with Unity

scenic forge
#

Task continues on main thread =/= the task has to run on main thread.

ashen yoke
odd turret
#

ideally you would only use those kinds of Tasks if you actually want it to run off the main thread, like in a web request or long running background processing

#

if you want a substitue for coroutines you should look into UniTask

scenic forge
#

That's kind of odd of a situation, are you saying you have a task that's running on non main thread, and during its execution it needs to do something on main thread? So it needs to "do some work in current thread -> do some work in main thread -> do some more work in current thread"?

#

At that point I don't see why not just split it into 3.

#

If you are using UniTask, there are UniTask.SwitchToMainThread and UniTask.SwitchToThreadPool; if you are using Awaitable, there are Awaitable.MainThreadAsync and Awaitable.BackgroundThreadAsync.

ashen yoke
#

It is not my code really but a package - no UniTask - which can end up off the main thread, not sure why or if it is meant to. I simply wanted to have an Action when things were complete. I do question this packages use of Tasks

scenic forge
#

If it's someone else's code, how do you end up needing to switch to main thread in the middle of it?

ashen yoke
#

because it is very customisable

#

Anyway I guess can force this to run on main thread

odd turret
#

you can also create your own main thread dispatcher (or grab some implementations online) and route the stuff to the main thread

echo coral
ashen yoke
#

Perhaps I can combine UniTask

echo coral
#

Oh then im not sure what the problem really is

#
await DoThing();
await UniTask.SwitchToMainThread();
//use unity api safely
ashen yoke
#

yeah thats nice

old swallow
#

Is it possible to load a second scene, but keep the first one from not lagging? Anything I am trying doesn't seem to work ๐Ÿ˜ฆ

I basically have a static scene, where the user can rotate around it with the camera.
A second scene, where a separate camera just makes pictures of the static environment. Every 5 second there is a different second static environment in the second scene. This scene is never in actual view of the user, just meant to save images somehwere in the distance.

#

All I can come up with is a second .exe, but it's not really desirable

dusty wigeon
old swallow
#

It's a bit hard to describe it ๐Ÿค” The scenes are not really intensive.

Hmm, imagine if you have a scene of a 3d model, static one. A fish let's say. The user can control the camera and rotate around it. Then there is a second scene which also just has a 3d model of a static giraffe for example in the far distance so the user doesn't see it. Where it just makes pictures from different angles. Every 5 seconds a new scene is added with a different animal. Basically I just need the user to not have the 1-2s lag spike when rotating the camera on the first scene.

#
    public void LoadMainGameScene()
    {
        isLoadingVesselScene = true;
        try
        {
            AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("VesselScene", LoadSceneMode.Additive);
            StartCoroutine(LoadScreenShotSceneEvery5Seconds());
        }
        catch (Exception e)
        {
            throw;
        }
    }

    private IEnumerator LoadScreenShotSceneEvery5Seconds()
    {
        while (true)
        {
            yield return new WaitForSeconds(5);

            AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("ScreenShotScene", LoadSceneMode.Additive);

            asyncLoad.allowSceneActivation = false;

            while (asyncLoad.progress < 0.9f)
            {
                // This helps spread out the loading over multiple frames
                yield return null;
            }

            asyncLoad.allowSceneActivation = true;

            while (!asyncLoad.isDone)
                yield return null;

            SceneManager.UnloadSceneAsync("ScreenShotScene");
        }
    }```
upbeat path
#

!code

thorn flintBOT
upbeat path
#

use a paste site for large blocks

sly grove
#

Maybe you're doing IO on the main thread for example? (Saving the screenshots)

ashen yoke
echo coral
stuck plinth
#

you could try turning down the loading thread priority too but that won't help much if your performance problem is coming from the frame it gets activated

old swallow
lofty falcon
#

What is the difference between GraphicsBuffer and ComputeBuffer?

dusty wigeon
# old swallow It's a bit hard to describe it ๐Ÿค” The scenes are not really intensive. Hmm, im...

Your "scene" does not really seem to be heavy. I have done the exact same thing recently with "Hunting Trophy". Instead of loading a scene, I'm simply instancing a gameobject. Obviously, the resources (Mesh, Texture, etc.) are already loaded.

What I suggest you do, is if you do not need a complex 3D environment, but simply a prefab is to not use a scene. Finally, if yo do need a 3D scene, reduce as much as you can component and other scripts as it is mostly the Awake/Start function of each script that is costly. Also, I'm doing "screenshot" (Creating a texture with the information currently displayed) on the Switch, I do not think it the screenshot itself is CPU intensive, but saving it which can be done on an additional thread.

I use ScreenCapture.CaptureScreenshotIntoRenderTexture for the function.

sage radish
# lofty falcon What is the difference between `GraphicsBuffer` and `ComputeBuffer`?

GraphicsBuffer is a newer API to create buffers of all kinds on the GPU. ComputeBuffer is an older version, introduced when compute shaders were first implemented in Unity and only supports some buffer types, notably doesn't support vertex and index buffers.

There's no reason to use ComputeBuffer over GraphicsBuffer and I assume it will eventually be deprecated.

thin vine
tired fog
#

Can jobs be scheduled asynchronously? I have a problem ahere I schedule so many jobs that the game stutters

scenic forge
#

Are you sure the cause is the scheduling of jobs rather than something else (eg creation/completion of jobs)?

sacred dawn
#

A weird bug is happening when loading tile maps from JSON
It works most of the time but sometimes it decides to not work
I inspected the json nothing wrong there
I inspected the code execution order and its as it should be
but it for some reason loads onli one map and puts it on the wrong layer (so the contend for the background tile map loads on a different one)
But if I generate all the maps again and save them they load just fine and it works fine the entire day
but next day its broken again (am using newtonsoft json package)
if someone is willing to help me I'll send the code for more context
thanks in advance

tired fog
scenic forge
#

If you are not sure, always profile and understand what exactly the problem is, rather than throwing random solutions at the wall and praying.

#

That goes for any performance related questions.

tired fog
#

Yeah of course, that's why I'm asking of theres any way to reduce job scheduling times, like asynchronously. I need to check again if job creation had any big impact since i don't remember, but the main thing was scheduling

primal badge
#

hi, can anyone help me with my idea?
I want to render character's shadow, then move the character's bone, then render character, but I'm having problems and would like to get an advice

scenic forge
#

You are just guessing that's the issue and asking for solution assuming that must be the problem.

tired fog
#

But that's not the point at all tho, i appreciate the concern about doing it right, but I'm not asking that

tired fog
untold moth
#

It's not like we underestimate you, we just want to have the full context.

#

Otherwise it's just poking in the dark.

#

Because, jobs scheduling itself doesn't sound like something that would be heavy. Normally, it's not.

scenic forge
#

Wasn't trying to be rude but sure I could've worded it better, it's just that you have provided basically no context for people to help.

#

From my understanding as well, job scheduling shouldn't be a performance bottleneck either, so it's very likely to be many other things:

  • Maybe your new MyJob(...) is the part that's slow.
  • Maybe the reason new MyJob(...) is slow is because you are creating/copying data every time instead of some kind of caching.
  • Maybe you have jobs that operate on an array of data and instead of scheduling a parallel job/one job that loops through the entire array, you are scheduling one job for each element.
  • Maybe it's work done after job completion that's slow.
  • Maybe ...
    It's not realistic for people to help by listing out all the possible problems and solutions. Profiler data can help, code can help, but we have nothing.
echo coral
#

Without context we cant do more than a google search could

timber shadow
#

Does anyone know what API is used if you want to have an icon in the editor down in the area where unity's icon/button for release/debug mode is?

#

Or if anyone has another idea for a good way to present a status display of an editor tool, I'd be interested.

#

This is a tool which runs in the background.

#

I'd like something visible if it has something to inform the user of without spamming them with popups.

timber shadow
#

Cheers

tired fog
north matrix
#

what's the best way to implement states, buff and debuff like electrified state in a 2d game ? Ideas? Please...

dusty wigeon
#

You can just create a "Buff" or "Modifier" class

north matrix
dusty wigeon
# north matrix Thanks man

If you want more information, you will need to elaborate more. It might seem stupid what I just said, but there is many person that do create such classes resulting in cluttered codes.

undone coral
#

you can increase the resolution of shadows to make them "sharper"

undone coral
#

what do you want your behavior to be?

thin vine
#

this is only at 2k resolution but is crisp

#

I achieved it by rounding the shadow attenuation function in one of URP's shader function files, but I wanted to know if I could do this in the Render Graph instead

undone coral
#

i mean it's a wavy line

thin vine
#

eh, I like it

#

also looks better at lower shadow resolution

#

compared to it being blobby

#

but yeah, I just wanted to use the Render Graph to do this rather than manually edititng the package file since it would be a bit cleaner imo

#

but I haven't been able to figure out if I can do that

echo coral
#

why isnt this a feature in urp normally ๐Ÿค”

undone coral
#

shadows are kind of complicated

worldly pecan
#

do you have soft shadows turned on?

echo coral
#

if you have it disabled in the urp settings it doesnt work but wont tell you (or may be built in i forget)

untold moth
thin vine
#

ty for the clarification

thin vine
untold moth
thin vine
#

it effectively just applies a threshold to the shadow attenuation

#

via rounding

#

I do wonder though, is there a way to disable bilinear filtering for shadows? because even with soft shadows off thereโ€™s still some slight โ€˜softnessโ€™

#

and it could be nice to have pixelated shadows

untold moth
thin vine
#

you only really notice it at lower shadow resolutions

#

but it would be nice if you could toggle it for retro-esk graphics

hearty shoal
#

Heya, I had a code architecture question. People always talk about seperating your logic from your visuals. I usually do this by using the Observer pattern (to trigger animations for example). The problem I'm running into is animations. For example, in our turn based game, unit A might attack unit B. In my logic, this is executed immediately. I'd have a listener on the health to update the health bar.

But what if I only want the health bar to update after the animation is done? Or what if I want to stop the player from doing actions during the animation?
I know one could use animation events, and have the animation event lock player input, but then my logic and animations are tied together.

How do you guys deal with this in your projects?

lost sequoia
#

Is it even possible to make a screenshot Script that doesen't cause a 2 seconds long lag?

(Trying IEnumerator and IJob-structs, did not solved it either)

worldly crater
#

Hello, I had a curious thought. If we use Scriptable objects for lets say "health" . For a single player game, can a user modify health Scriptable Object in runtime and become "god' ? I am thinking in terms of fraud detection.

stuck plinth
worldly crater
random dust
#

It would help if you shared your current approach

odd turret
#

I'm trying to make them all cancellable, so at any point the player can trigger a new action and then the game should resume from the most recent logic state

midnight violet
midnight violet
gaunt crystal
hearty shoal
midnight violet
#

Of course you could also just let the attacker send an event and the receiver send an event and rely on that, but overcomplicating things can lead to unnecessary systems too. If you rely on visuals because something is animating dynamically, you have to link it somehow. First of all, what brought you to the "do not link visuals to logic" conclusion? Maybe its a misinterpretation thats confusing you? Just trying to get on the same page here ๐Ÿ˜„

hearty shoal
#

To clarify, I do link visuals to logic lots of times, I'm mainly trying to broaden my horizons a little bit on how to improve my code in the future.

Lets say I want to start unit testing. Having pure C# classes that can run this code makes this a lot easier. If I link my animation to my attack code, I now have to provide an animation when testing

#

I know it's possible with things like play mode tests, but I'm just looking to see if there's any other options

midnight violet
#

That would take my animation sample into account. So instead of passing the animation, you just delay the execution for a set time, in your case, playmode => animationlength or unit test => default float in your method params

hearty shoal
#

Ye, I suppose just a set timer is a good solution

#

And then even scaling the animation based on that

#

Is that how a lot of this kinda stuff is handled in a MVC approach?

midnight violet
#

Sounds like. I guess some more studied people can help more in this case, as I have no master degree in development or whatever. But from what I read about MVC and guess also doing myself in some cases, it sounds like the approach you are aiming for.

hearty shoal
#

Maybe another example as well, the thing we're actually working on atm:

We're working on a VR game. In that game, we have a machine that crafts things. To craft something, you first have to pull a lever, this plays a "close door" animation, then a button appears. When you press that, an animation is played. After that animation, the item is crafted and given to the player.

There's a lot of things that rely on animations to finish. I guess if you wanted to decouple the animations, you'd make the machine a state machine, that the animation looks at

#

With timers for every state

midnight violet
#

Yeh, this is a great example to talk about. So you cant really put your flow of animated interaction to the data. The only thing your data will give your little craft machine would be the item to craft, in this case, right? There is no other connection besides, you decide what to craft, interact with that machine and you get back your crafted item. For me, I only see two data points connected between visual and database, and that is your machine starting and completing. To decouple this even more, you could just send a "CraftTask" to the machine and inside your state controller, you wait for your tasks to be completed.

hearty shoal
#

Ye, indeed

#

This is what sucks working with only 2 programmers (and the other guy is a junior), I wanna grow as a programmer, but sometimes it's easier to do that when you see other approaches in other projects

midnight violet
#

I myself did this for an app where you have like conveyor belts and different users can access at the same time and filter out products from that belt. All users send a request to the controller script which then distributes the requests to the belts. All passing around the request, so everyone has one source of truth to rely on

hearty shoal
# midnight violet I myself did this for an app where you have like conveyor belts and different us...

That makes me think of another case, maybe you'll have some input on this. We worked on networked turn based game in the past with Photon. There you have a server set the health of a unit, and the player receives the callback when the health is changed by the server.

How do you deal with delaying stuff there? I suppose you could have an attack command, that you sync to the clients. Server just waits the attack time, clients do the animation when they receive it. When the time elapses on the server, it sets the health, which hands the callback to the clients

midnight violet
#

You could also think the other way around. What if the server already updated the health for everyone, but the animation will just fire the visual update of the health bar after finishing? If its round based, you do not have to safe check, that something relies on that healthbar like user decisions and what not.

hearty shoal
#

Hm, that's what we ended up doing

#

The problem we ran into is if there are other things that heal the unit for example

#

You have to make sure that also executes that logic

midnight violet
#

But thats totally up to your system, not best practice in that case. Do you want realtime attack and healing, then first come first serve for the server to get the requests (or timestamp based). But if you are doing turn based, you are having a low frequent row of requests which can easily be handled.

hearty shoal
#

I'm not sure what you mean by that

#

Maybe to clarify on what I mean (and ours is fully turn based): We have an animation event in the Attack animation that says "UpdateHealthBar".
We added a building at a certain point that heals the unit, which had a different animation. Because it didn't have that UpdateHealthBar call, well, it didnt update

#

I guess you could go around that by just updating the health bar after any unit animation though

midnight violet
#

So are attack and healing happening at the same time?

hearty shoal
#

no

midnight violet
#

Okay, i do not really get your health building then. When does it decide to heal or how is it connected to the UpdateHealthBar

hearty shoal
#

Your point was that you could look at the animations the other way around. The server sets the health already, and the client fires a visual update after the attack animation.

This means that you're not hooking into the callback that the health changes from the server, to update the health bar, but instead that something else is responsible for doing that, right?

#

In this case, the attack animation

midnight violet
#

Oh, now I got what you mean. Got your point now

hearty shoal
#

Or was that not what you were saying?

midnight violet
#

You are right about the issue, that your healthbar would only react to the unit. But if your unit gets healing, it will be the same as attack. It plays its attack animation and at the end, update healthbar, right?

hearty shoal
#

Well, for example, in our game, the healing happens when you move on a tile

#

So there's no attack animation

#

But ye, its a matter of adding that then to the move animation I suppose

midnight violet
#

Now you are linking it directly again with the move animation ๐Ÿ˜‰

hearty shoal
#

But aren't you linking it with the attack animation too?

midnight violet
#

so your player moves to a platform, either the player/unit or the platform will now detect it and send its behaviour, something like HealUnit(Unit unit, float amount) to the server

hearty shoal
#

Indeed

#

Server then does all the checks, and probably says "Increase health by 10"

#

oh wait

#

I see what you're saying

#

You're saying, client does animation first, then only sends a call to the server?

scenic forge
#

Only skimming through the conversation, I'd like to say that it's often helpful to separate the true value from the visual representation of the value. Eg when you are losing health, the true health value is decreased immediately, while the health bar receives the event of "health changed" and plays an animation of tweening from old health to new health or whatever.

midnight violet
hearty shoal
#

Sorry, I know I'm being a bit dumb here, but in the case of row, when you say the unit decides when to show it visually, that is linked to the animation, no? Or there you would also just say "UpdateHealthBar in 5 seconds"

#

I understand the 2 health values part

midnight violet
hearty shoal
#

Ye, so for example, if you have a UnitAnimator, you can queue animations on it, at the end of any animation, it calls UpdateHealthBar

#

And then it syncs the shown health value, with the server's health value

#

Or an animation event

midnight violet
#

Exactly

hearty shoal
#

Alrighty

#

It took a bit

#

But we got there

midnight violet
#

Theorizing code structure without writing down anything is always a hassle

hearty shoal
#

Ye. I love reading books on it, but I always wanna see some actual practical examples

#

And I've always worked at small studios, where I'm the only coder, or there's someone very junior. I haven't much been in a team where I have a senior with loads more experience

#

To learn shit like this

#

But I appreciate your time ๐Ÿ™

#

I'm gonna go eat lunch now

midnight violet
#

Enjoy your lunch and I can tell you, I was freelancing for 13 years and learned this on the go, its a lot about reading and just writing code, failing and so on. I am far off from students about what coding principles are there and what not, but still got my things together and learned while working and sacrificing a lot of time ๐Ÿ˜„ Just keep going and I always live by the standard "There is almost nothing, I cant do or at least try to learn and master it", and so far, it worked out. ๐Ÿ˜„

hearty shoal
#

Using Addressables for example, my god. That shit is not easy to retroactively add

echo coral
#

changing non async code to async is a pain to start but its a good change.
I much prefer it over coroutines now.

worldly crater
#

why so ?

echo coral
#

async code doesn't require a monobehaviour to be executed and things like UniTask make it easy to just await an addressable asset load and other async things in unity

dusty wigeon
undone coral
# hearty shoal That makes me think of another case, maybe you'll have some input on this. We wo...

many games, not just turn based, all eventually look like virtual machines. if you are savvy, you can still achieve this all in ordinary, pure C# where your game stack looks like a c# stack. this is almost what ECS is.

the depth you need to deal with this problem depends how complex the game is.

specifically for turn based, if your game is resolved in the server, you end up with a marble diagram of reactive messages that look like this


net
msgs ooo
     |
obsv o                o             o
     |                |             |
sel  |                |             |
many o--->o-->o----->xo-->o--->o-->xo-->...

in the select many statement, you enumerate through all the "handlers" of an event & state update in order "with async" or "as a coroutine" i.e., you are waiting for animations to finish until you process the next network message.

undone coral
#

it's the same thing

#

succinctly and correctly writing the code to get a "route handler" behavior for game events and state changes? hard, but it's like 20 lines.

#

one point of view is that people think all this stuff is decoupled and really it's very tightly coupled. if you look at a web application, the way your route handlers interact with each other is all declared in one place. very, very tightly coupled. and the way you declare routes, pass user authorization information, return responses, etc. is always very opinionated.

dusty wigeon
undone coral
# dusty wigeon At the end, where the length/duration comes from ?
GameMessages()
 // Process each message, determining its duration
 // The initial message is null
 .Select(message => Observable
 .FromCoroutine<ServerToClientMessage>((observer, cancellation) => ProcessMessage(message, messageHandlers, observer)))
  .Concat()
  // code anywhere can now observe the game state
  // correctly "delayed" by animations or whatever
  .Multicast(m_Messages)
  .Connect();
private IEnumerator ProcessMessage(ServerToClientMessage message, MessageHandler[] messageHandlers,
    IObserver<ServerToClientMessage> observer)
{
    var messageContext = new MessageContext(...);
    foreach (var messageHandler in messageHandlers)
    {
        var processor = messageHandler.Handle(messageContext);
        // workaround for https://forum.unity.com/threads/yielding-a-nested-ienumerator-waits-a-frame-even-on-break.772352/
        while (processor.MoveNext())
        {
            yield return processor.Current;
        }
    }
    observer.OnNext(message);
    observer.OnCompleted();
}
#

or await messageHandler.Handle(...)

#

so the duration comes from however long it takes to process a handler

#

handlers can see if a message has been "handled"

#

just like route handlers in a web framework

#

same semantics

#

at least if you're familiar with stuff like vertx or even express

#

it's the same thing

dusty wigeon
undone coral
#

in a networked turn based game, everything has been resolved. you get "GameMessages()" immediately

#

the delay comes from .Concat

dusty wigeon
undone coral
#

comment out Select and Concat

#

nothing in the UI would ever observe GameMessages. maybe i should have written it up as NetworkMessages

#

i see this kind of thing a bajillion times. people try to animate in a decoupled way

#

it's impossible

#

you can still author all of your animations elsewhere, as in this example

#

this is from my card game

#

you don't even have to declare the relationship between the animations in the same place

#

you just have to write 5 lines of code to ensure that the animations are called in an order and with Task or Coroutine semantics

#

it's a very neat trick

dusty wigeon
#

Yeah, hence why I said you either depends on your animation (directly or indirectly) or have your animation respect a duration you set elsewhere.

undone coral
#

hmm. there's no duration set elsewhere.

#

you don't need to know the duration ahead of time

#

big difference

dusty wigeon
undone coral
#

in that example. the duration comes from how long it takes to 'execute' the code. it's a coroutine, so that could be infinite, or zero.
example of showing a little hearthstone damage number popup on cards:

/// <summary>
/// Shows a damage view.
/// </summary>
public sealed class DamageHandler : ValueEventHandler
{
    [SerializeField] private float m_Duration = 1.1f;
    public override IEnumerator Handle(MessageContext messageContext)
    {
        if (messageContext.message.Event?.EventType == GameEventTypeMessage.Types.GameEventType.PreDamage)
        {
            messageContext.HandledBy(this);
            yield break;
        }
        if (messageContext.message.Event?.EventType != GameEventTypeMessage.Types.GameEventType.Damage)
        {
            var shouldWait = bufferedEvents.Count > 0;
            ProcessBuffer();
            if (shouldWait)
            {
                yield return new WaitForSeconds(m_Duration);
            }
            yield break;
        }
        var evt = messageContext.message.Event;
        Buffer(evt);
        messageContext.HandledBy(this);
    }
}
undone coral
#

it doesn't need to happen

#

it could wait, or not wait, or do nothing

#

it's up to you

#

it's exactly the same as a web framework

dusty wigeon
undone coral
#

almost named all the same things

dusty wigeon
#

Which would be the more hard to maintains but more decoupled way of doing things.

undone coral
#

i did want to show you this because it uses the word duration

#

but there's a big difference here

#

you could choose to not "yield return"

#

you can do whatever you want

#

you can make a change to an animation in the inspector, and everything just works, but the network code, it doesn't need to look inside the animations to know how long they last

#

animations just happen, or not.

#

the trick is in turning animation code into observables, and concatting them. the point is to use system.reactivex / unirx to make a bug free "route handler"

echo coral
#

I feel like "events" should all get handled together and any required animation changes should happen after somewhere else

undone coral
#

because otherwise it's kind of clunky to "delay" game state elsewhere

#

i mean take it from someone who has written this in a robust way

#

we've looked at this a million different ways

undone coral
#

that's kind of the magic

#

people reinvent all of system.reactive to do something like this

echo coral
#

oh i presumed this was network messages not internal event messaging to react to it

undone coral
#

they end up with a whole implementation of system.reactive spread out across their game

echo coral
#

then i dunno ๐Ÿคทโ€โ™‚๏ธ

#

continue ur argument

undone coral
#

the network messages arrive immediately

#

let's say. 100 of them.

#

okay. lots of people struggle with, i want to program some of my ui to be traditionally reactive, like a website

#

and other parts, i want animations

#

so how do i "delay" the "messages"

#

you know, messages, game state, whatever. it's all the same thing

#

it's about the developer experience. how do you write something which can show like, the number of hitpoints on a unit without being aware of animations, but also author a damage explosion animation that correctly "delays" the hitpoints going down in the thing that visualizing the hitpoints

#
you take your network messages, and you never show them to anyone directly
your network messages are processed one by one, checking to see which animations are interested in them
run the animations. it's up to the animations how long they last, or if they should take any time at all, or whatever.
after all the animations are done, update some value, we can call this the local view of the state, that things that need delays but would prefer to not be aware of delays would subscribe to. in fact this is the only view of the game state the UI needs 99% of the time.
#

this much is clear. everybody wants this. the question is how to implement it succinctly

#

MOST people spread out an ad hoc implementation of system.reactive across many places

#

and so it FEELS like this is way more complicated than it actually is, because they don't know about system.reactive / unirx and the problems it solves

#

the IDEA isn't super simple but it's simple enough

hearty shoal
#

I need to look more into reactive. I'm not very familiar with the way it works

undone coral
#

so the pseudocode in the code block. i mean you read that. you think, "i should have a for loop." NO.

hearty shoal
#

But the way you explain it, it does seem to handle exactly what I'm talking about

undone coral
#

that is implementing system.reactive!

#

@echo coral am i making sense now?

#

the trick here is NOT the idea of how to correctly delay for animations

#

or whatever

#

the trick is to know not to ad hoc implement system.reactive

#

for years people were like "eww unirx"

#

and now that it's "blessed system.reactive" maybe it will be better

dusty wigeon
#

You either set a duration somewhere and utilize that or you use the duration from the animation directly. In both "your method" and "what is used", if the animation is deleted the game does not work any more, in what I suggest it still works. Obviously it requires more work and you should not really do it in my opinion.

undone coral
#

it's up to you

#

everything i'm sharing is from a real game. you want to delete damagehandler component from the game object? great. everything sitll works

#

but you are overthinking this

#

i think it's a lot to wrap your mind around because it is so, so succinct

#

what is "concat"? what is it doing there?

#

what is turning a coroutine into an "observable"?

#

why are the game messages being passed down through this, and then back into something called m_Messages?

#

these are the questions. that's how you implement all of this with brevity and correctly

#

i mean the real game. the animations are developed one at a time. there are so many of them.

#

that's the whole point of this architecture

#

i had to stare at a lot of marble charts to understand this all

#

dismissing it as an "abstraction" is the worst possible thing you could do

#

worst takeaway

#

it's not an abstraction, it's the opposite. Concat, FromCoroutine and SelectMany is the implementation not the abstraction!

#

just because something FEELS abstract doesn't mean it IS

dusty wigeon
#

Mate, stop.

You clearly do not understand what I am saying and you are not trying either.

End of the discussion.

hearty shoal
#

Hm, I'm just wondering if I got it right.

I'm gonna put it into the example of a monobehaviour, I wouldn't implement it this way, but I just wanna know if I got the basic principle right.

Would this be the equivelant of having a monobehaviour Unit
When it executes a method, lets say attack, it searches for all the IAttackHandlers child objects, and awaits the "HandleAttack" method?

Very simply put (and probably oversimplifying)

undone coral
#

but listen. there's a reason the cygames guy, who also makes a card, game, and i, use the same thing

undone coral
#

it's up to you. it depends how your game is architected

hearty shoal
#

Like, I'm just trying to understand the basic principle a bit

#

Of what you're saying

undone coral
#

do you want to execute the game logic and the animation in the same place?

#

well. have you ever developed a website?

hearty shoal
#

Nope

#

As I say, I'm not familiar with reactive

undone coral
#

i think what you are describing is decoupling things in a way that is spreading out system.reactive in an ad hoc way

hearty shoal
#

I understand its probably much more than what I explained, I'm just trying to pull it to an anology which is closer to my usual workflow

undone coral
#

it's kind of the point i'm trying to make. there are a million right ways to do this, but there are only a few best ways

hearty shoal
#

I understand that what you were saying earlier was much more global

undone coral
#

so really you start with: where do you want to define these things:

struct GameState {...}
struct AttackArgs {Unit source; Unit target; int damage;}
static void Attack(GameState currentState, AttackArgs args)
static async void AnimateAttack(GameState currentState, AttackArgs args)
#

attack could look like

static async void Attack(GameState currentState, AttackArgs args) {
  currentState.units[args.target].hp -= args.damage;
  // check if the target has died
  if ...

  await AnimateAttack(...);
}

#

and then, they don't make it static

#
class Unit : MonoBehaviour {
 public async void Attack(GameState currentState, AttackArgs args) {
   currentState.units[args.target].hp -= args.damage;
   // check if the target has died
   if ...
 
   await AnimateAttack(...);
 }
}
#

@hearty shoal okay, you see how this works? i mean this is correct

#

but do you see. it's up to you where you want to define and call those things

hearty shoal
#

Yup

undone coral
#

you can see how, if attack can change currentState at any time, then you have to do a ton of work to update UI in the right places

#

etc. etc.

#

if you mix things like this, you can have something that is correct, but it will be very hard to write it correctly all the time

#

even if it's easy to understand

hearty shoal
#

yes, this is what I was trying to avoid, indeed

undone coral
#

so what i am advocating for is to put these things in kind of idiosyncratic places, but the net result is that things become way easier to author

#

you have no choice but to try to understand system.reactive / unirx

#

if you want to do things that way

#

most people eventually arrive at defining Attack and AnimateAttack in different places. you have to, in order to have a networked game for example

#

but from there. it's a huge struggle to not reinvent half of system.reactive poorly

#

nearly everyone chooses to do that

#

in some cases, on top of reinventing system.reactive they also reinvent ECS

#

@hearty shoal are you trying to make a networked turn based game?

#

i know the stuff i am writing sounds like crank gobbledygook, it certainly has that energy

hearty shoal
#

Honestly, for simplicity sake, lets say no. Like, this is a problem I run into a lot, the thing you show of having the await AnimateAttack in the attack. I was mainly looking for alternatives for these kinds of issues

#

I'm not looking for an actual solution, more to broaden my horizons, to explore different methodologies. Like, we're gonna stick with what we have in our current project regardless, but it's more something I want to learn for future projects

undone coral
#

you just don't know that you are doing that

#

except "Any sufficiently complicated Unity game contains an ad hoc, informally specified, bug-ridden, slow implementation of half of System.Reactive"

#

does that make sense?

#

so you kind of already know the best methodology. it's the one in the pseudocode. you already know what you want

#

and you are sort of already doing it. it comes down to whether or not you want to stubbornly refuse to adopt some libraries, sometimes, because "dependencies"

#

it's usually that

#

like going to your team and adding a "dependency"

#

that's the problem

#

@hearty shoal "hey guys, let's add this dependency" --> everyone yells at you

hearty shoal
#

Tbf, it's not being stuborn or anything, it's more ignorance at the moment

undone coral
#

lol

#

well you're going and asking about it

#

the opposite of ignorance ๐Ÿ™‚

hearty shoal
#

I'm open to learn, ye, but I am ignorant of what it is atm

#

I didnt mean that as a put down :p

undone coral
#

i know i know

hearty shoal
#

I'm defo gonna read up on it, I was mainly a little confused at what you said in the very beginning, with the message handlers and what not. I was curious, very high level, how that worked

undone coral
#

it's just tough. i think this is why many of the games with the most opinionated engineering have such small teams. it's got little to do with right or wrong per se. but the average person gets stuck at the door with "dependencies" before deciding if something is a good way to do something

undone coral
#

because that's what the idea is borrowed from

#

there are like 100x as many website server backends as turn based games so people have thought very deeply about how that should work

hearty shoal
#

Ye, I imagine often in websites you also have to await an animation to finish, before showing something

undone coral
#

yeah. all the time. and then in the backend, well writing to a database takes a "long time"

#

there's a lot of wrangling stuff that is async and evented

#

and how to express all of that

hearty shoal
#

But thats why I tried to put it a bit into a more monobehaviour perspective, just to wrap my head around it

#

Because at the start, you mentioned messages and all that, just curious, very abstractly, how it works

undone coral
#

well in my implementation, there is no Unit MonoBehavior

hearty shoal
#

No, of course, of course

undone coral
#

and the AttackHandler monobehavior is AddComponent to some random root object, just once

#

which is the same as declaring your routes in a website backend

#

once you see how website backends are authored, this is instantly more clear

#

messages are just "people visiting your website"

#

sometimes you care about that being handled in order. like if it were a banking website, and everyone was depositing and withdrawing from the same few accounts for example.

#

so that's what this is all for

#

you don't want some people to wait to see their correct account balances, but you do want animations on the client.

#

how do you do all of this? that's where the ideas come from

hearty shoal
#

But high level, without monobehaviours. You have some sort of Unit script, correct?
And I'm guessing that Unit sends a message "I want to attack"?

#

Then it looks for any handlers that want to react to the attack. You await all of those to finish (In order, or not)

#

I understand this may be a gross oversimplification, I'm just trying to wrap my head around what it looks like a bit

undone coral
#

there's no unit script sending messages

#

there's one entrypoint for taking user actions

hearty shoal
#

k, so there's a script, UserActions

undone coral
#

and anything on the battlefield (imagine hearthstone) can emit actions the user can take

#

yes

hearty shoal
#

There you enqueue a "AttackAction"

#

Where you pass a unit, maybe the damage, etc?

undone coral
hearty shoal
#

I'll have a look

undone coral
#

there's also xmage that is implemented in a similar way, but for magic the gathering

hearty shoal
#

But you enqueue this AttackAction. Then it looks for any handlers to deal with that action. And it awaits those handlers?

undone coral
#

from the server's point of view, everything is just executed. attackaction has some method on it, it runs, and that kicks off all the game logic, there's no waiting

as the game logic is executed, events are raised. these are just structs that snapshot the game state and have some extra info. so dealing damage, but all the other things that could happen in a card game like hearthstone or magic

something gathers up these structs and sends them to the client

the client receives them all immediately. one by one, the client looks at the struct and finds MonoBehaviors called Handlers that are interested in the struct, and await handler.Handle(theStruct)

#

all the animations are authored in Handlers

hearty shoal
#

Ye, so you might have an AnimationHandler, and a PlaySoundHandler

undone coral
#

this way they all happen in order. since the Handle is awaited, all the durations can be dealt with without knowing how long it actually takes

#

yes

#

and since it's async, you can choose to wait or not inside the method

hearty shoal
#

Client receives the AttackAction

undone coral
#

client gets all the events all at once

#

in microseconds

#

because that's how long it takes to evaluate teh player's choice on the server

#

all at once, but in order.

#

so it has a full snapshot of the journey of the game

#

up to the point that a player needs to make a choice

hearty shoal
#

Can you clarify what you mean there? Events here being the actions?

undone coral
#

client receives a list of possible actions, like attackaction, end turn action, whatever. then it tells the server, i want action index 0

hearty shoal
#

Ye, sure

undone coral
hearty shoal
#

I see, so for example, player sends attack action to server

#

Server translates that into: Oh, so that's damage to the unit, and then it ends the player turn. So client receives event: Damage unit, end turn

#

based on those events, client looks for related handlers, and awaits them?

undone coral
#

yes

#

that is exactly what happens lol

hearty shoal
#

I'm guessing there's also an attack event?

#

For things like animations of the actual attack

undone coral
#

yes, and that gets animated into one unit smashing into another

hearty shoal
#

So client receives "Attack Event", looks for handlers:

"PlayAnimationHandler", "PlaySoundHandler", it awaits both of those

#

Once its done awaiting those, it moves on to the Damage Unit event

#

awaits stuff there

#

(if you want it to wait for each other)

undone coral
#

yes

#

BUT the thing that is written on the unit that says how much HP it has

#

it finds the unit in teh game state and subscribes to changes in its hp

#

the "game state" that it subscribed to is updated "after" "every handler"

#

it never sees the instantaneous stream of events

#

so there's a bajillion places in the UI where things would be clunky to express as handlers.

hearty shoal
#

Ye, thats fair

undone coral
#

so yes. that's it. that's the whole idea

hearty shoal
#

But I wonder, how does it handle things like updating the health after an animation?

#

If its not handled by handlers

undone coral
#

you can do that in your for loop

#

if you wanted to

#

you could do this.healthChanged(...) in your for loop, and things can healthChanged += it

hearty shoal
#

The for loop of taking in the events? What for loop?

undone coral
#
foreach (var event in events) {
 foreach (var handler in handlers) {
   await handler.Handle(event);
   this.gameState = event.newGameState;
   this.gameStateChanged();
   switch (event.type) {
    case DAMAGE:
     this.unitHealthChanged(event);
     break;
    case ...
   }
 }
} 
#

yeah

#

you can do this

hearty shoal
#

I see

undone coral
#

okay. so now we're fleshing out all of the code to do this, you see that it's not so simple, this implementation

#

you certainly CAN do it. but it's reinventing UniRx / System.Reactive ๐Ÿ™‚

hearty shoal
#

But those are libraries that implement this paradigm, right

undone coral
#

uh they just deal with all the problems this can solve

#

correctly

#

you know that drake meme

#

he's saying "no no" to system.reactive
and he's nodding yes to "doing this all yourself crappily"

#

because people use hating dependencies as a coping mechanism for how hard programming is

#

and hard programming means you don't make your game

#

you can write "event bus" into the discord search

#

and see for yourself. people love writing event busses

hearty shoal
#

Well, I do think there's value in writing it yourself to understand how it works

#

Well, I appreciate you taking the time to explain this all

stray umbra
#

hello i have this huge climbing system script and i have some bugs can anyone help me?

thorn flintBOT
stray umbra
upper cape
#

what is your opinion to the best Method to create a dash ability

regal lava
#

The method that moves my character in a direction at a speed

humble loom
#

switching on enum values is a big code smell for me. instead of iterating over so much stuff agnostically and checking every type every time, queue them in a dictionary of lists using the enum as a key

bronze imp
scenic forge
#

The dictionary approach cannot enforce exhaustiveness. Not in C# anyways, in languages with a more powerful type system like TS, you can.

regal lava
#

wait what TS being a more powerful type system than C#?

scenic forge
#

Way more powerful, TS type system is Turing complete.

bronze imp
#

they certainly get fancier with them

#

the problem is at some point it has to become js

regal lava
#

Building off js I wouldn't expect* the exact opposite to happen

bronze imp
#

so you don't get the crazy runtime type magic that C# does

random dust
#

Typescript's type system is sooooooo good

#

You can use generics to modify the state of whole objects. Like Required<T> removes all nullabillity on objects. Imagine that

scenic forge
#

The type system doesn't have to be constrained by runtime, in fact the JS runtime being "typeless" actually allows you to do a lot of interesting patterns in TS, that is otherwise impossible to do in C# without sacrificing type safety/having to resort to source generators to get type safety back.

bronze imp
#

I'm not knocking it for that. I understand that the type system being constrained by runtime safety makes it less feature-complete -- that's a given haha

bronze imp
#

when you start to toe the metaprogramming line is when you really start to miss the runtime stuff (or at least, I do) -- even little things like reified generics are hard to part with ๐Ÿ˜ฆ

scenic forge
#

RTTI vs type erasure is definitely an interesting language design choice, both have pros and cons.

bronze imp
#

For sure, I definitely feel like from a "correctness" standpoint, you'd lean towards erasing type information.

If your entire codebase is fully and meaningfully specified, you don't ever NEED that runtime type information. There's always a better way to do it.

scenic forge
#

Reified generic for example, in C#:

T Create<T>() where T : new()
{
    return new T();
}

Can be roughly thought of as Create(Type t), but the problem is that there isn't a way in the type system to express "that function returns whatever an instance of Type t"
In TS, there is a way to express that in the type system:

function create<T>(cls: new () => T): T {
    return new cls()
}

In general, languages that use type erasure go with the approach of "passing runtime objects, and use the powerful type system to infer types."

#

Even in this example, one of the unfortunate effect is that C# only has where T : new(), so it cannot express something like "T is a class that can be constructed with a string parameter" whereas that is possible in TS via:

function create<T>(cls: new (arg: string) => T): T {
    return new cls('hello world')
}
#

The same has to be written in C# using a factory method wrapping (arg) => new MyClass(arg).

bronze imp
#

Yeah, for sure. i prefer a healthy balance between both tbh

#

Sometimes you need to interact with systems that come from a less refined type system than yours. Maybe it's serialization, or a poorly typed library, or even just legacy code.

That's when I start to really miss the cheats we get from rtti

scenic forge
#

Yeah you just need to be flexible and make use of the strong points of the language you are using. C# source generator is great and makes up for the situations where the type system is not powerful enough, TS type system is powerful and makes up for situations where you do need runtime type information.

bronze imp
#

Have you used Hack at all? I think they struck a really good balance there.

#

Honestly anytime I code in anything else I just wish it was more like it haha

#

But it kinda does a little of both. There's really complete refinement available at static analysis (less so than TS, ofc). But then it also keeps parts of that at runtime

#

So you're given some of the goodies from each side

scenic forge
#

I'm comfortable working with both C# and TS that they together covers pretty much all use cases (bar embedded) that it's hard for me to get into a new language. Not for the lack of trying, but I pretty much just forget whatever new language after a while because there's never a chance to use them ๐Ÿ˜…

bronze imp
#

Yeah yeah I totally feel that. That's how I feel about rust actually, it looks really cool, I'd really like to play with it. But I'd just never get to do more than that with it

crisp pebble
#

Quick explorative question: i'm looking into how to further optimize my procedural terrain rendering. I'm currently computing my vertex heights on the CPU (using jobs+burst this is lightning fast on a Ryzen 3700X 8 core, and even negligible on an 8th gen intel 6 core), but then I'm also constructing a whole bunch of actual meshes based on the heights, all on the CPU. I'm probably going to keep my noise calculation on the CPU but I figure if I can just send those heights to the GPU in a buffer and render them all using some instancing command, I can save a ton of bandwidth (1 float vs 3 floats, and I can probably even use halfs for it considering my height data is in the range 0.0 to 6.0, so that's a 6x memory reduction) and move a whole lot of super parallelizable execution to the GPU. I think I should be able to use Graphics.RenderPrimitivesInstanced() (API) for this, because it gives access to a vertex index but I'm not sure if it's possible to get like full control over the data on the GPU, like chunk position offset or other data that can be global for a specific draw call. One thing I've never looked into Custom Render Passes, but I figure this would be the most logical place to put rendering code (I'm doing other instanced rendering in this project in a MonoBehaviour.Update call). So my question is: for this use case, can it be beneficial to render things like terrain 'meshes' in a Custom render pass?

humble loom
#

Ive been exposed to javascript just by virtue of being cheap and not wanting to pay to make a portfolio site lol. That and gives me an excuse to practice css which is gonna help with ui toolkit

upbeat path
humble loom
upbeat path
humble loom
#

You dont know the meme of "mom can i get X?"
Mom: we have X at home
Then it shows a picture of a really shitty version of said thing

#

I love explaining jokes it makes them so much more funny lol

upbeat path
#

I don't do memes, way to old for that childish shit

humble loom
#

amazin

#

I think I finally set up an input system that I'm happy with btw. pretty hyped. So unity's new input, using c# events and generating a c# class for the input controls, instantiate it in a singleton and bind it to static event containers. End result is really simple event binding

private void Awake()
{
    _mainCamera = Camera.main;
    InputEvent.Ui.Click += OnClick;
    InputEvent.Ui.Point += OnPoint;
}

private void OnDestroy()
{
    InputEvent.Ui.Click -= OnClick;
    InputEvent.Ui.Point -= OnPoint;
}
#

https://paste.myst.rs/jlvvjioc if anyones interested in the full implementation. just used the default action map for now but will inevitably be tweaked im sure

sly grove
humble loom
#

I feel you. I don't like needing people to access the singleton though necessarily, and there's like low low chance of race conditions accessing it directly, whereas having static events that the singleton binds to when its ready is like super idiot proof. and the event containers are just to make it tidy

#

and i'm making my first proper game in DOTS so im big idiot mode right now lol

#

something i realized about DOTS though is that it's like insanely unit testable so i'm really going hard with the testing

#

something i started doing recently btw - I got really used to having like friend class usage in my c++ projects and I wondered why C# doesn't use it until i realized it kinda does

#

with explicit interface implementation. narrows usage of a class only to things that know of it as that interface, like obviously any interface has those defined members, but if you have an explicit interface implementation, those members are hidden from things that don't reference it as that interface

#

stranger can't boop my dog cause he don't know him that way

#

thought that was really neat. gonna be using that a lot more

#

so you can do really cute stuff like have highly mutable types but the interface to manipulate them is sealed to the module

jaunty creek
#

Using a phone as a golf club
I am using Input.gyro.attitude. Looking at the gif, the golf club is swinging in a circle around the player at an angle. From the gyro attitude, I need a way to get the degrees per second that the phone is rotating.

I am thinking that I need a way to get the circle of best fit.

Additionally, I need to know if the last frame of input before the ball is hit is under or over the best fitting circle, as well as its distance to the circle. That way I know how much the ball is gonna curve left or right

Any help or direction will be greatly appreciated

humble loom
#

you're gonna have to buy a lot of new phones if you're hitting balls with them

jaunty creek
humble loom
#

so you need more than just attitude right? i assume you're holding the phone like a club?

jaunty creek
#

Yes

humble loom
#

its tough too cause you gotta account for wrist movement, even if your accounting is that you don't care lol

jaunty creek
#

I assume I can use the attitude to calculate the speed of rotation

humble loom
#

not if they flick their wrists you can't

jaunty creek
#

Maybe the accelerometer is what I should use

humble loom
#

yeah i think so

#

accelerometer will let you track its actual delta position per frame and you can reverse engineer a circle which will let you calculate arc seconds

drifting solstice
#

that's called dead reckoning and it's not particularly accurate at this scale

jaunty creek
humble loom
#

so you want tangential speed AT point of impact OF the imaginary club head which is a fixed offset from the phones positive Y axis or something like that

drifting solstice
#

honestly i think the best solution would be to have some kind of attachment mimicking the shape of a golf club to get the inertia and moment right, and it'd also help prevent accidentally flicking the wrist
kinda like wii tennis attachments, just a foam tennis racket to get the feel right

but that's probably not practical

#

i think you'd have to choose what you want to focus on
the rotation aspect, or the hitting aspect
for the former, you'd primarily check rotation
for the latter, you'd primarily check acceleration
accounting for both seems like a pain with diminishing returns

#

actually wii does have golf
maybe that could have some insights

humble loom
#
Quaternion rotation = Input.gyro.attitude;
Vector3 clubOffset = new Vector3(0, -ClubLength, 0);
Vector3 clubPosition = transform.position + (rotation * clubOffset);
Vector3 acceleration = Input.acceleration;
float speed = acceleration.magnitude * Time.deltaTime;
float angularSpeed = Input.gyro.rotationRate.magnitude;
float tangentialVelocity = ClubLength * angularSpeed;
#

i think? you could do this in update, cache the tangential velocity and apply it as explosive force to the ball on impact

#

the real question i guess is how much does aiming matter? or are you more looking for just like effective form and motion

#

also i think that should be localposition where i'm calculating the offset there but you get the gist

drifting solstice
#

wii sports golf only used a linear accelerometer, no gyroscope

humble loom
#

they probably just do simple speed calculations and clever movement restrictions and checks to see if the gesture is somewhat correct

#

like "is y trending up"

drifting solstice
#

iirc you could just flick and it'd have the same effect as a full swing if you got the strength right (presumably just checking tangential speed at impact, like you mentioned)

humble loom
#

and then they just output the accelerometers deltaZ to the player hand

#

yeah that's why i wouldn't use rotation by itself it's super exploitable

#

@jaunty creek what you could do is create a small gesture test suite where you can iterate on those parameters. define like a GolfSwingGesture, then you can boot up the unity test and just practice swinging and see if the light goes green when you expect it to

#

if you wanna be real fancy you can machine learning the heck out of it lol. sit in front of your computer all day swinging your phone for a week and then it's like alright bet i know what a golf swing is. Then you just check IsGolfSwingGesturePerformed() ? ApplyForceToBall();

drifting solstice
#

you would also have to do negative samples

upbeat path
tired fog
#

My bad, I thought I was in shaders lol

bleak citrus
#

You just replace every instance of Foo.Instance

#

(that's one hell of a load-bearing "just" ๐Ÿ˜‰ )

compact ingot
jaunty creek
#

@humble loom & @drifting solstice Thank you both for the suggestions. I'll try fiddling around with a few different ideas and pick the one that seems to work the best. I will not try the machine learning thing though ๐Ÿ˜…

jaunty creek
drifting solstice
jaunty creek
#

That sounds about right

drifting solstice
#

2000 here being small because of the sheer amount of variation possible

jaunty creek
#

Geez

#

I'm not doing that

drifting solstice
#

for a decent & reliable sample, it'd probably be a few month's worth of manhours lol

jaunty creek
#

Ahah. I like the math way better ๐Ÿ˜†

#

Wait, one swing/sec for 2000 seconds?

#

That's about half an hour

#

I could do an hour or two ๐Ÿ˜

#

But math is still cooler ๐Ÿ˜Ž

serene jetty
#

does anyone know the absolute fastest way to bake a collision mesh? in physx or unity physics

regal lava
#

VFX graph has a nice SDF tool but no clue if you can use it outside of its intended usage

long ivy
drifting solstice
brisk spear
#

is there any quick '() => ' syntax to make an enumerator

echo coral
#

if the return type of the delegate was IEnumerator that could maybe work?

brisk spear
echo coral
#

yay easy fix

brisk spear
#

is there anyway for me to reference a script asset directly in the inspector

echo coral
brisk spear
echo coral
#

not the script asset file

brisk spear
#

ye and im trying to see if i can reference a script asset and execute

echo coral
#

you just cant

#

it needs to be an instance on a game object. If its a scriptableobject then it needs to be an instance of one too.

drifting solstice
brisk spear
drifting solstice
#

you can but it's not very useful

#

you can reference it but you can't really do anything with it from there

echo coral
#

@brisk spear what do you hope to do and perhaps we can think of an alternative

drifting solstice
brisk spear
#

i know i can make one time scriptable object as delegate so now im just trying to push further

lament salmon
#

MonoScript isn't even available in a build

echo coral
brisk spear
#

just experimentation thats all