#archived-code-advanced
1 messages · Page 124 of 1
Me neither
I think he wants to simulate rotation that you can do with rotate around transformation function
Yes that would be an orbit
but physically
It is a math problem. This would be the same if it were kinematic.
that sounds like a really difficult mathmatical challenge
I really don't think it is and I'm just not very good at math
Except that if you want to work within the confines of the physics engine it's a physics problem.
Look it really depends on how "real" you need this to be
you said you want it to be "physical" but what does that actually mean
I posted about the issue earlier today to no response.
So this code takes the object I'm holding and manipulates the rb to follow it. The issue is with the rotational force. Since the grip may be offset from the center, any rotation dislocates it from the grip before being corrected by the position. This causes a wobbly feel to the objects.
Here is a frame-by-frame of the issue.
Vector3 targetPosition = Hand.position;
Quaternion targetRotation = Hand.rotation;
Vector3 grabOffset = grabPoint.position - rb.worldCenterOfMass;
Vector3 targetGrabWorldPos = targetPosition + transform.rotation * extraPos;
Vector3 linearVelocityForCOM = (targetGrabWorldPos - grabOffset - rb.position) / Time.fixedDeltaTime;
rb.linearVelocity = linearVelocityForCOM;
Quaternion rotDiff = targetRotation * Quaternion.Euler(extraRot) * Quaternion.Inverse(grabPoint.rotation);
if (rotDiff.w < 0) { rotDiff = new Quaternion(-rotDiff.x, -rotDiff.y, -rotDiff.z, -rotDiff.w); }
rotDiff.ToAngleAxis(out float angle, out Vector3 axis);
angle = Mathf.Min(angle, 180f);
Vector3 angularVelocity = axis.normalized * (angle * Mathf.Deg2Rad / Time.fixedDeltaTime);
rb.angularVelocity = angularVelocity;```
what are the requirements
I think u r asking what torque and force you need yo add to rotate around a virtual axis physically. That sounds like s really difficult calculation to me. or maybe there is a function that does that
This really is quite simple. I am overcomplicating my explanation
this disconnect here? bad
See how the code rotates the object about the center, and not the controller?
can you attach the object to your controller with a hinge joint
this was kinda bgugy like it freezes the cursor too long for some reason
A boneworks-like system of joints and all is far out of scope. I would rather keep this simple.
I actually just finished removing it from my project
So maybe now my little diagram is more clear. What I need to do, is position the object in a way that from any rotation of the hand, I can rotate the object so that it snaps the handle into place
I just don't know how to math that. Been trying for the past hour.
This is the handle, by the way
I cannot imagine what you're trying to describe but maybe others can help you
I'm not exactly sure I'm following this either. I'm not sure what you mean by "handle" here
I think you need to draw with painter program rather than keep trying to describe it with words
A cube is poor at visually communicating. Let me make a comparison video
At the very least, I hope the issue is clear. This is what is currently happening.
that "handle" is where the box should meet the hand, the grab point
Think like the grip of a gun
I'm still not following
so there's some fixed grab point on the object and you want the object to... track the motion of the VR controller?
If so this is just a matter of calculating the desired position and rotation of the object and then depending on your definition of "physical" you need to set the velocity/angularvelocity to get to that point in one frame OR use Rigidbody.Move
you should have just said you want your VR controller to grab a physical object lol
Here is the real problem. See how the handle likes to disconnect from the controller a lot?
It is because it is matching the rotation of the controller, before correcting the position
It is rotating about the center of the gun, and not the hand
I think that's a glitch that can be caused by many factors that it's probably impossible for us to decipher unless we see the codes
No. I know exactly what the problem is. I broke it down frame by frame in those three images I sent.
Frame 1, "gun" is straight
Frame 2, controller jerks to the left, the gun matches the rotation of the controller
Frame 3, the difference in position is corrected
right - there's a delay
Yes
That's inevitable
What?
if you want to use physics anyway
what you could do is have a non-phyiscal "ghost" object that directly follows the controller
basically a child object
and then have an invisible physics object that syncs when the physice engine gets around to running
ohh I thought the jerky motion was the issue, I thought thats what u were saying.... yeah either I am slow or ur wordings confuse me lol
but the physics engine is generally going to be running "behind" the visuals since it runs at a typically lower framerate
(50hz by default)
if you decrease your fixed timestep does it get a little better?
also if you disable interpolation does it get a little better?
Clearly not, seeing the dozens of games that get around this issue. And no, I know at least one of them does not use joints. It uses rigidbodies and positioning, as I am.
See?
I see a delay there
A delay in the movement, not rotation. The rotation is perfect.
The positional delay is caused by the smoothing. It is acceptable.
I disagree I see the same delay in both
the games that do not have a delay are probably not using physics but just directly updating the guns position and rotation? I think?
there has to be some sort of a delay if its physics
Did you see the video?
H3VR operates on a 50 hz timestep
you know you can move your physical objects without using physics and still make it collide naturally like you see in the video
If it's just 1 frame delay, you'd probably not even notice it.
what rigidbody interpolation mode are you using btw?
Interpolation
Do I have to pull out a task manager and do a frame by frame comparison, like I did with my game, and show you that the controller stays firmly on the grip with rotations? I know for a fact that the transform is not on the grip here either.
I have played this game, and have seen my game. The difference is night and day. I know precisely what the problem is, I know what causes it, I came to this channel to ask for some vector math help that would let me position and object a certain way. I would really appreciate it if you helped me with that.
I am too dumb to help you. good luck. maybe someone can
Wait what in tarnation are you actually doing here?
rotDiff = new Quaternion(-rotDiff.x, -rotDiff.y, -rotDiff.z, -rotDiff.w);```
Did you mean to do Quaternion.Inverse()?
The machine suggested this.
what is extraRot?
Something that would let me add recoil
I would basically expect:
Quaternion currentGunRotation = rb.rotation;
Quaternion diff = targetRotation * Quaternion.Inverse(currentGunRotation);
Vector3 angularVelocity = diff.eulerAngles * Mathf.Deg2Rad / Time.fixedDeltaTime;
rb.angularVelocity = angularVelocity;```
That's probably the right way
I have no idea if new Quaternion(-rotDiff.x, -rotDiff.y, -rotDiff.z, -rotDiff.w); does anything useful but I suspect... not
As a rule I don't mess with the internals of Quaternions
Though I guess it seems like it's probably doing something close to right...
Vector3 targetPosition = Hand.position + (Hand.rotation * grabPoint.localPosition);
Quaternion targetRotation = Hand.rotation;
if (!doSnapping) {
targetPosition += Hand.rotation * grabPoint.localPosition;
targetRotation *= Quaternion.Inverse(root.rotation) * grabPoint.rotation;
}
if (Interactor.other.held != null && Interactor.other.held is GrabInteractable s && s.transform.root == transform.root) {
Vector3 handsDirection = (s.Hand.position - Hand.position);
targetRotation = Quaternion.LookRotation(handsDirection, Vector3.up);
}
rb.linearVelocity = (targetPosition + transform.rotation * extraPos - grabPoint.position) / Time.fixedDeltaTime;
Quaternion diff = targetRotation * Quaternion.Inverse(transform.rotation);
diff.ToAngleAxis(out float angle, out Vector3 axis);
rb.angularVelocity = axis * (angle * Mathf.Deg2Rad) / Time.fixedDeltaTime;```
I settled on this. No idea what grok what spitting out earlier but this seems to be fine.
The issue remains though
I'm gonna try to explain it again
So the handle of the object is off-center, it is somewhere usually behind it. This code I have matches the position of the object to make the handle (grabPoint) stick to the controller, and to match the rotation of the controller
It works, but a problem arises when you rotate the controller. Since angularVelocity rotates about the center, and the handle is off-center, it creates a disconnect between the handle and the controller, before quickly being fixed by the positioning code.
The result is a slight visual wobble. It may not seem like much but it is very noticeable.
Your problem is probably that you're accounting for the position at the current rotation not at the target rotation.
there's also: targetPosition + transform.rotation
the Transform rotation may be slightly off due to interpolation vs the Rigidbody rotation
Not probably. That is exactly the problem.
The solution is to make the positioning code account for the rotation of the controller.
I don't know how to do that.
make a bigger chunks.... that's your LOD
I do think cs Hand.position + (Hand.rotation * grabPoint.localPosition); should be basically correct but that's assuming the gun isn't scaled at all
is there scaling in the gun's hierarchy?
making smaller chunks into bigger chunks, those are your lods, thats what I meant. yes it'd work on your voxel too
nanite is what slowing down most UE games. it's a cool tech for big budget high-end games, but not for decent-ish hardware
we're not missing out the tech, even in unity 😏
For various reasons, I need a UV lookup table that is, in itself, a texture. That is, each pixel of the texture encodes a particular UV value of a different texture. The reasons I need this are complex and dumb. Is there a standard way to do this? Or should I just wing an encoding algorithm
We'd probably need to hear these various dumb and complex reasons
I usually do stuff like that in a compute shader
My boss is insisting on having a flood fill for our water asset. That is, if a section of the dynamic content is a 'bowl', the water will only fill whats in the bowl and wont 'spill' into other dips in the terrain. We already have a height map of the terrain, so I decided to go with a Flood Fill algorithm to determine what 'should' be filled
Given that this needs to update in real time, im opting for a compute shader approach, and am planning on implementing the Jumping Floods Algorithm, which involves coloring 'invalid' pixels a particular color that is associated with its seed
As such, I need to be able to take a color and work back to its original position, so I can determine which of the two colors is 'closer' to the current pixel
Its going to be horrible and inefficient but thats life
My current plan is to do something like float4 EncodePoint(uint2 uv) { return float4((0.5 * uv.x) / Resolution, (0.5 * uv.x) / Resolution, 0, 0); } for encoding and the inverse for decoding
But I want to check if theres a less odd way of doing the encoding
Are you sure that uint2 value is actually a UV? Seems like a pixel coordinate to me
Its a pixel coordinate, but at the end of the day, its a lookup to a source color
I guess encoding pixel coordinates into a color would be more correct
I don't follow everything (not really familiar with JFA algorithm) but you can also use integer textures with compute shaders, FYI.
I can have a input texture in the format of uint3?
like RWTexture2D<uint3> FloodTexture;?
That feels....wrong?
Hotdamn, your right
I usually use integer textures for ID lookups like this.
how do you integrate elevation in that flooding algorithm?
I already have an algorithm that divides the height map into values above and below the cutoff point.
I take the output of that and encode the pixel coords into the texture where these 'above ground' points are. I then input the seed point where the water originates in
Finally, I plan on running JFA ~9 times to build a vernoi diagram of the various fill areas, giving me an area thats flood filled
so you have water-sources that fill the terrain up to a given level, respecting any boundaries created by higher elevations that enclose it?
Yup
Just said terrain isnt a UnityTerrain, and is a depth image of dynamic GIS data
So I cant really use any existing tools to solve this
a DEM is just a heightmap
doesn't matter what format it comes in, you can always project it into a format an existing tool understands
(not saying that you should use unity terrains)
For sure, Im talking things like an existing UnityTerrain or mesh collider
Im actually already doing that by turning it into a depth texture that I use several compute shaders to position non critical elements altitude with
So we dont have to mess with calculting altitudes for things that dont matter, they just appear on the surface
I'm just pulling my hair out over this, as I need to build some flood simulation PoC when its completely out of my area of expertise. I specialize in graphics, not simulations
it doesn't sound like a simulation yet, you aren't iteratively simulating water flow to find your "pools"
Im not sure what I should do on that front. I know enough to know I dont know enough about fluid simulations to build one.
well, one bit of info you probably also know is that making a volumetric flow simulation is way too computationally intensive
but deriving a flow simulation from a stateless flood fill is probably also not gonna be the most promising path.
For sure. This is not a task I'm doing willingly
you could theoretically encode a shallow flow map (just a few meters below a given water level) and iteratively update water flow down those vectors, the flow map would be able to "push up" water level when a sample point is filled by neighbours and to "push down" when drained. (just an idea) --> this should eventually converge into a stable state.
Hmm. Ill have to give it a think
The GPU implementation is a nightmare and I dont think likely to succeed in a way thats decent
to do it on a GPU performantly the whole idea needs to be inherently parallelizable
i think a flow-map is that, since it only needs to investigate neighbours/chunks on one pass, and maybe chunk bounds or convolutions in a post-pass
I can see that working. I already have a custom burst job system I built for the project, it shouldnt be too bad to code up a very simple flow function and grow the job by chunks
Queue it up so every few frames it runs a single chunk of the simulation, leading to a very gradual filling of the water data
yes. i think one key aspect is keeping the data the algo operates on very local to the point the output is written to in each loop/step.
can you hint me how I should LOD a voxel chunk?
Can you increase LOD group numbers?
if I have a voxel chunk to be 101x101x101 and omit the every 2nd element then it would be 51x51x51
then repeat the process 26x26x26... then if I repeat the process hmmm
If I have 100^3 and box sample it then it would be 98^3 then 96^3 then 96^3 and so on
I can reduce it down to 4^3
so that would be LOTS of LOD models
is there a way to take screenshots in unity without any lag i tried AsyncGPUReadback but it isnt Async or something?
What did you try exactly?
i want to try to take a screen shot of my game and save it in a folder as a png for a texture 2D to support saveslots
but everytime i take the screenshot i get a lagspike
I mean the code you tried with asyncgpureadback
If you are calling WaitAllRequests or something then yeah it will block the main thread
async doesn't mean its automatically executed on another thread. its executing on the main thread but a bit later
aa alright? but can i wait on another thread or something?
the gpu read was done to not block the main thread but then the callback is then executed on the main thread
aa but why is taking a screenshot such a hideous process if you dont want lag i tried readpixel already i tried the other capture functions
have you checked the profiler to see what is causing the lag you are seeing?
I dont think .Apply is needed here. It just sends the data back to the GPU
You may also be able to just encode the pixels as png directly:
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/ImageConversion.EncodeArrayToPNG.html
and maybe unity will let you use this on another thread? tbh i dont know
Yeah good idea to eliminate the middleman Texture2D if possible
It says thread safe in the doc!
yea, ideally you can take the result, encode and save on another thread to prevent any hitching
yay!
very good call i will try it
nah skip the texture2d
well give both a go but minimising work on the main unity thread will yield the results you want
Rob just linked that 😄
aa sorry rob
Oh - native you say
may be better if you will do this a lot (to avoid gc) but native or non it should be better
yeah i saw that indeed
so i did the conversion to UNorm but still there is lag and i dont get how? i did everything without the texture 2D step
In case you missed it, that Encode method is thread-safe. So you can do it on a background thread
Can maybe write the file from the background thread too
aa seriously yeah i missed that
yea so next step is to use something like Task.Run() or a unity c# job to encode to png and write to disk.
though you cannot use native array to png on another threads it seems so change that too
classic unity move, mess up an api is some funny way
SO close it doesnt save now
change it to the non native version then try again
it should have logged an exception in the console. If not attach a debugger and check what its doing
also remove asset database refresh cus that should not be there and cannot be called on other threads (probably)
and ofc that is not usable outside of the editor
no ofcourse was there for trying ahha
the exception is being swallowed because you're calling Task.Run without awaiting the result, so the exception (from accessing Unity methods off the main thread) is getting stored in a task you're not doing anything with
Request is the non-async version, there's RequestAsync which returns an Awaitable if you want to write it using async code
public void OnHoldFixed() {
Vector3 targetPosition = Hand.position;
Quaternion targetRotation = Hand.rotation;
rb.linearVelocity = (targetPosition - grabPoint.position) / Time.fixedDeltaTime;
Quaternion diff = targetRotation * Quaternion.Inverse(transform.rotation);
diff.ToAngleAxis(out float angle, out Vector3 axis);
rb.angularVelocity = axis * (angle * Mathf.Deg2Rad) / Time.fixedDeltaTime;
}```
Please
Using a joint would solve this constraint problem
So it wouldn't rotate around the center of mass, but around the anchor instead
Joints are near incompatible with networking. It has to be an on the fly solution.
Modifying the centerOfMass of the item rigidbody might be worth trying too
Set it near the controller
Just an idea.
This works... but comes with the obvious issues of putting the CoM nowhere near where the CoM should be
The front tends to look very jittery, I don't know how much damping input could help with that when the center of mass is so far away
As a last resort, though, I will use it
I really didn't think this would be so difficult. Just a modifier to the position code that would put the item in a position where the rotation code would perfectly put the handle on the controller
I wouldn't expect networked physics to be easy either
Well you dismissed the joint option because of networking
Another thing to try is to use AddForceAtPosition at the tip of the item
Eh... Not sure about that actually
Yeah no
I just don't understand how they managed this\
There are no joints involved here
It could be completely custom physics 🤷♂️
Well, not completely custom, but using physics queries to check for collisions
That way you have complete control over its position and rotation
I don't believe that. System is like 8 years old.
So what?
Unity physics haven't changed much in 8 years
How do you know they aren't using joints though?
Joints don't freak out if you know what you are doing and adjust them correctly
You are making a lot of weird assumptions
Looks like it's trying to match the controller's forward and reacts to environment. What stops you from simply trying to rotate the rb to match the rotation of the controller? It'll still respond to collisions and be depenetrated as you seem to want
..Why not?
It is clearly using free-floating positioning like I am. A joint would bend over backwards to keep the handle on the controller.
I can even see the exact same effect in my game if I rotate it around the corner.
This is the problem
You want me to open up the modding toolkit and show you that the player rig doesn't have joints on it?
A configurable joint does not do that if you configure it properly
Why are you being so combative? Until now your only argument was "it doesn't freak out like a joint does"
I know that this game does not use joints.
Okay, so instead of angular velocity, what if you set the rotation manually? rotate towards based on a max delta to avoid skipping through your thinnest walls
it'll still collide
I thought about it, wouldn't that skip over physics?
not if you use the rb methods to set rotation
just gotta be careful to step it rather than instantly assign, because then quick movements will end up going through walls
I thought it would be simpler just to solve this via positioning. All that needs to be done, really, is to put the object in a position where rotating it will match the handle to the controller. Just some math I don't know how to do.
No?
By rotating it, you mean by manually setting the angular velocity?
to cover the rotation delta for the step?
Setting the angular velocity, along with the linear velocity to account for it. Because right now only the former is happening. Like a RotateAround function with a rigidbody.
Isn't this the closest you got to the goal?
What does the issue look like if you can send a vid? And what code did you use
^On second thought, this could work, if you add a force to both the tip and the anchor, towards the target tip and target anchor pos
The center of mass fix works fine for the most part, actually. I simply set the CoM to the grab point and back when its dropped.
If possible, i would like to go about this without modifying the center of mass, due to the physics side-effects that would come from that. Right now it is the most promising solution.
So, thank you. I'm just continuing to ask because I'm certain there is a way to do this positionally.
@torpid knot Does this make sense?
In other words, try with positional forces only, not torque
(This should probably be in #⚛️┃physics so sorry to anyone who comes here expecting some Zenject questions or whatever)
I see, yeah.
Any force that's not on the center of mass should result in a rotation
I'm decompiling H3VR right now to see if I can figure out how they do it or something
@torpid knot I think you could compute what the position would be after applying the rotation, and then bake that in your linear velocity assignment so that the displacement is covered in the same frame than the rotation, so you don't end up with frames where it looks like it's disconnected
so compute new position after pretend rotation. tweak velocity to cover current delta + delta induced from the rotation around the COM, and then tweak angular velocity to match orientation
@lament salmon Would you look at that, it uses free-floating rigidbody positioning
...
I'm gonna dig into it a little bit more and figure this out
I never said it didn't work like that, I was questioning how you were so sure
Sorry if I came off as rude. I was sure of it from the start, I have been playing this game for a long time.
Better remove that message btw. Decompilation is against the server rules
Oh this is the wrong channel mb, let me go to lighting
Weird question. If I point a disabled camera at an insanely highly poly object and make it manually capture every second, would that just create a massive lag spike every second, or is there a way I can make Unity handle it in a smart way (or does Unity do that automatically).
Just a hypothetical, but I was just wondering.
No
You can technically do asynchronous capture but not sure if Unity supports that. @sly grove might be more insightful
As far as I know capturing the data alone before sending it to GPU should be enough to cause a spike… and that’s what I’m sure Unity supports, but caching a state and loading asynchronously, not sure.
But honestly insanely high poly assets are a meme.
Well it's a hypothetical that demonstrates the point.
There's no magic that will make slow rendering not be slow
What I'm moreso looking at is a camera that captures 24fps, but another (main) camera capturing way more than that. Could the 24fps camera possibly cause microstutters.
sure
Unfortunate. Will look into this stuff more.
I'm doing premature optimizations and overengineering 👋
public static bool IsMethodEmpty(this MethodInfo method) {
if (method.GetMethodBody() is not MethodBody body) { return true; }
byte[] il = body.GetILAsByteArray();
bool isEmpty = (il.Length == 1 && il[0] == 0x2A); // 0x2A
if (!isEmpty && il.Length == 2 && il[0] == 0x00 && il[1] == 0x2A) { isEmpty = true; } // 0x00 0x2A
return isEmpty;
}
Would this method also be reliable on consoles?
If that relies on intermediate language, then probably not, as consoles only support il2cpp builds.
Can't grasp the magic lol. Will the byte array not even be available? Or just messed up? Ugh.
Yeah, it would probably fail to compile
Did you try building an il2cpp build on windows?
Not really. This is currently so low level it'd be a pain to create runtime debugging info for it on build 😅
Although it's fine. I can cache the states before building and ship it as a serialized dictionary in a ScriptableObject 👍
Even if it does compile, most of it would probably return null or other invalid data.
I want to comit die. Does anyone actually understand how fluid simulations actually work? Like, I understand the theory, but im not sure how I would go about implementing it as a unity burst job
Fluid simulations are like PhD thesis level things. Not exactly something someone will quickly communicate to you over discord.
I am well aware
This is more of a cry for help than me looking for practical advice
Product sold a fluid simulation to a customer without clearing it with the dev team. Yay.
My current plan is to define an area where the simulation occurs, calculate the height map for it, and implement something like the Jos Stam fluid simulation over the unity job system
However I dont know how practical that is, or even possible. I know I dont know enough to quantify the risks of this approach. So if anyone has any experience in this field and is willing to chat for 5 min to help me avoid classic pitfalls, I would be forever greatful
I presume re-selling an off-the-shelf fluid sim is off the table? (IDK the legal ramifications of that)
Legal is one problem. Another is that the way we calculate our heightmaps is based off of real time GIS data mixed with unknown user data. This means any solution that involves prebaking (All we investigated) will not function
Basicly, the user can input their own 3D models and see how water will interact with them. We dont know the models ahead of time, or even at launch time. They're loaded as GLTFs, which means any processing would have to be done while the play session is live
Its a god damn nightmare and my boss is like 'dont worry, youv done the impossible before, youll do it this time too'
prety sure Obi fluid handles thngs without prebaking? But IDK
Ill definitly look into that one. We tried the ARTnGAME one, but it was a complete mess and unusable
Ah, Obi fluids says its not for our usecase in a giant disclamer at the top. Disapointing :<
Seeing how cities flood for search and rescue preparedness
Yeah. Im a graphics engineer.
Why do I feel like Unity isn't even correct for that lol
You would be 100% correct
sounds like something you need a supercomputer for
and very, very high quality GIS data
Fortunatly, we have the high quality GIS data. We built an entire GIS system in unity using a Burst Job System I created
or at least a large scale distributed system
Works really well too
I would think a particle/fluid sim of that size is just too much data for any single node to process (other than a supercomputer)
I think you don't really need realtime simulation for this. Unity should be fine
but man you're in for a treat...
Tell me about it
Assuming you're going with particle-level, maybe just calculate/cache forces + changes and propagate them forward.
... then tell customers to leave it rendering overnight and watch it in the morning lol.
lamo
make the simulation take as long as real floods and market it as a feature
My current plan is a voxel based approach, where we do something kinda like what Dwarf Fortress does
or something
idk
Out of curiousity what kind of models would be getting put into this?
Standard 3D Tiles mostly
Along with a DEM as a baseline
(DIgital Elevation Model)
i feel offended i totally googled that before you sent it 😛
I build a height map extractor for 3DTiles and digital twins that we use to properly calculate elevation for our tool, so we have a decent enough height map for use with this simulation
Its already a texture, so its already voxelized.
@fresh tangle do you have to use burst for this? Offloading the whole thing to GPU sounds optimal.
And it's nice that you have the whole GPU just for the simulation (coz of specialized product)
I mean, I could use a compute shader, and its likely more efficient, but I dont know the algorithms well enough to know if its properly parallizable for this
The good thing with forces is that they apply one at a time lol. Meaning parallelization will work.
True, I might be able to just use a compute shader for each step of the simulation, with a small delay for a GPU readback for the finalized data
By "one at a time" I mean each frame there'll only be ONE set of forces applied -- each particle only needs to care about neighboring particles.
Although making a physics engine in the GPU is a treat by itself 😄
Yeah, that could work. I always enjoy writing shaders and compute shaders. Best part of the job tbh
I loved writing the height map extractor we use for the 3DTiles. I use a depth render and a compute shader to extract real altitudes from it
One of these days I need to improve it so that it doesnt tear when you move the map. Its on my backburner
Sebastian Lague's recent video on fluid isn't runtime friendly nor nearly at the scale you'd be looking for but might be a good watch if you haven't for inspo and some of the sources he cites
Theres some neat stuff there, should help out a lot
this is the main paper Im working from: http://graphics.cs.cmu.edu/nsp/course/15-464/Fall09/papers/StamFluidforGames.pdf
OF COURSE KENJIRO HAS DONE THIS
That guy. Insane.
that guy is a shader genius
Crest Ocean 5 shallow water module implements a performant realtime flow simulation that you may find interesting. It’s optimized for shallow surface flow, not arbitrary 3D convolutions though.
the luck in me seeing this is real, i thought id need to buuld something from scratch, and this is using almost exactly the setup i need, this is going to save me a lot of time.
well, atleast generally speaking, ill have to rework it into something more generic, but its good to have a reference
Is there a way to control the lifetime of C# objects in native code when using il2cpp regarding the garbage collector?
I know Unity uses Boehm GC but can that be interfaced anyhow? Is the native il2cpp API documented in any way anywhere? Or am I supposed to use some other API?
what are you trying to achieve?
I have native code that references C# objects, but the objects they reference get deleted because my references aren't beeing seen by the garbage collector. I need to make it aware of those references somehow.
can't you pin them?
is this maybe a job for GCHandle? https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.gchandle?view=net-9.0
it's been a while since i had to use it but iirc it works fine in Unity
So I do this when I start referencing audioSource:c++ GCHandle audioSourceGc = FFI gcCreateHandle(/*object=*/audioSource, /*pinned=*/true); And then later:c++ FFI gcDeleteHandle(/*handle=*/audioSourceGc); Before I stop referencing audioSource Correct?
FFI because I am going through an FFI interface, ignore that.
Yes, that works! Thanks a lot!!
you just need to do body.GetILAsByteArray().Length > 2
I forget, 2 or 1 for it to be empty. It will work, Unity is doing the same under the hood for their virtual methods
note, its turtle slow
you need to pin it with fixed .. note you must in unsafe context
public unsafe void Stuff()
{
fixed(var ptr = &myStuff)
{
//DO YOUR STUFF
}
}
Oh, no, found a way to do it on the native side... so it's all unsafe either way since C++: #archived-code-advanced message
Looking at the FFI library I am using FFI gcCreateHandle -> il2cpp_gchandle_new and FFI gcDeleteHandle -> il2cpp_gchandle_free.
Your solution wouldn't work either way since I need to persist the reference across multiple frames.
But thanks
yeah one way to do it is with gchandle if you want to pin it for a longer time
you're on the right path there 👍
// Collect some meshes...
ObjectHandle mesh = call<"UnityEngine.MeshCollider$$get_sharedMesh", ObjectHandle>(/*this=*/meshCollider);
i->gcHandles[mesh] = FFI gcCreateHandle(/*object=*/mesh, /*pinned=*/true);
i->meshes.push_back(mesh);
```Then later:```c++
for (auto [object, gcHandle] : i->gcHandles)
FFI gcDeleteHandle(gcHandle);
i->gcHandles.clear();
i->meshes.clear();
```This is what I am currently doing. Do you think it's alright to not keep a GC handle on `meshCollider` since the function that uses it only uses it until it returns?
kinda weird you're using gchandle on the native side, but if it works... then it works ig 😃
This needs to work without real intervention from the C# side sooo.... yeah I kind of have to
correct, Unity uses the most ancient GC in the world called Boehm 😄
Boehm Demer Weiser or something was the full name lol
Boehm–Demers–Weiser garbage collector
Hello!
Is it the expected behaviour of the Playables API's Director ClearGenericBinding/SetGenericBinding that is only works if you're looking at it in the inspector?
I can setBinding/ClearBinding in code very easily, and I can see on the Timeline window that it works as expected. However it does nothing in practice.
Until I select the director in the inspector, and if I unfold this little section here called "bindings", then everything works as expected ingame (the bindings I make/break are reflected instantly). If I retract this little section, or if I deselect the director, then no binding changes go through
Does that mean I'm using the API wrong?
On the Unity documentation I don't see any mention that anything more than calling ClearGenericBinding / SetGenericBinding should be done. Should I call some other function after that, like "Apply", "Update", "Validate" ?
I've looked at the DirectorEditor.cs script to see how the Custom editor was made here, by Unity, and see if maybe I was missing something that this inspector would inadvertently "repair" - but I found nothing. What is the expected behaviour here?
ive set bindings at runtime but not experienced this myself
You’re claiming it’ll also work for IL2CPP builds?
I mean you should try it on your end regardless 😄
Well I spent like 15 minutes making a cache so I can cache all the information I need pre-build 😛
Whereas making something that could display this kind of debug information in IL2CPP build would be non-trivial.
no it's a performance optimization regarding component initialization:
public abstract class Component {
public Component() {
if (!GetType().IsMethodEmpty(nameof(PreLoadInitialize))) { World.instance?.initializer?.QueuePreInitialization(PreLoadInitialize); }
if (!GetType().IsMethodEmpty(nameof(PostLoadInitialize))) { World.instance?.initializer?.QueuePostInitialization(PostLoadInitialize); }
}
}
why you want to check stuff if they're empty or not, i mean you're the architect here? thought its for an asset you want to sell
overengineered and ugly atm 😄 but pretty nice performance boost to avoid calling empty methods
no it's for an under-development simulation game
yeah, but if you've lots of them they will be dangling around for the lifetime of your game
reflections cant be GC'd/cleared in unity, unity will silently cache them too behind your back
and those reflection caches will live as long your game is running regardless you're using it or not
I don't really understand what you're trying to say 😛 I made a simple (Type, string) --> bool map.
public static class EmptyMethodHelper {
static Dictionary<(Type type, string methodName), bool> scannedMethodsCache = new();
//[RuntimeInitializeOnLoadMethod]
//static void Init() {
// scannedMethodsCache = Resources.Load<ReflectionCache>("ReflectionCache").EmptyMethodCache;
//}
public static bool IsMethodEmpty(this Type type, string methodName) {
var tuple = (type, methodName);
if (!scannedMethodsCache.TryGetValue(tuple, out var isEmpty)) {
var method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
isEmpty = IsMethodEmpty(method);
scannedMethodsCache.Add(tuple, isEmpty);
//UnityEngine.Debug.Log($"{type.Name}.{methodName}() -- isEmpty = {isEmpty}");
}
return isEmpty;
}
public static bool IsMethodEmpty(this MethodInfo method) {
if (method.GetMethodBody() is not MethodBody body) { return true; }
byte[] il = body.GetILAsByteArray();
bool isEmpty = (il.Length == 1 && il[0] == 0x2A); // 0x2A
if (!isEmpty && il.Length == 2 && il[0] == 0x00 && il[1] == 0x2A) { isEmpty = true; } // 0x00 0x2A
return isEmpty;
}
}
the Init method is to be enabled for builds -- but will optimize more for builds anyway.
this seems a lot like something you could do in a source generator or il processor!
or if you're being lazy... just abuse the persistent listeners
was having a little extra time yesterday xD Thought it'd be nice to NOT queue initialization of components that don't really require initialization
you think source generator or il processor could be of assistance here?
so, in order to avoid calling a potentially empty method ... you do all this extra work to see if the method is empty? I'd put money on it costing you more performance to see if the method is empty than just calling an empty method
+1 that
i think with either option it'd be fairly easy to detect empty methods without needing to fetch the IL at runtime
it's essentially just a dictionary indexing after the initial caching on a per type basis
also it's not just calling the empty method that costly -- it's queuing to the initializer lol. It's performing some extra work under the hood
but even an empty method call is more costly than a simple Right.. it isn't..if (scannedMethodsCache[(type, method)])
I bet it isn't
scannedMethodsCache[(type, method)] is a method call, isn't it?
you're calling a method that calls a method that calls a method that calls two more methods ... to see if you should call a method. It makes no sense, even ignoring the actual work that's happening
right, I see your point now
I'm running into a weird issue with addressables where only after building, loading a particular addressable by keys gives me 21 duplicates of the same addressable (i.e. when I load resource locations for an asset which should be uniquely identified, i receive 21 of the same asset location).
Has anyone come across this issue before?
upon inspection, it seems that the loaded locations include addressables used inside the prefab
btw #📦┃addressables
dictionary lookups are 1-2 orders of magnitude more expensive then a method call, even if it is a virtual call
empty normal calls evaporate (assuming the jit inlines it)
yes yes, I only benchmarked with the whole initialization lifecycle. Still negligible and "overengineering" but there's a difference.
initializer queues to lists, combines delegates, etc, so wasn't accurate to say it's just "calling the method"
is PreLoadInitalize an abstract/virtual method on Component?
it's a virtual method that may or may not be overriden yes
whole goal is to provide nice post-serialization initializations (similar to Unity's Awake and Start)
/// <summary> Called on each Component right after it's deserialized or instantiated, so it can self-initialize. </summary>
/// <remarks> <b>DO NOT</b> assume values of other objects are already initialized here. </remarks>
protected virtual void PreLoadInitialize() { }
/// <summary> Called on each Component after everything is loaded. </summary>
/// <remarks> You can expect that all other objects are already self-initialized. </remarks>
protected virtual void PostLoadInitialize() { }
why are they red in discord but look nice in preview lol...
this might not work for your specific case
but why not just loop through your list of components and call initialize on all of em?
like, even if they have empty methods?
yes
well it works but calls bunch of empty methods -- was just having some extra time and just felt like going off the task list ^^
rather than creating a bound delegate for every object
my brain rotten game dev brain goes: ooga booga heap allocation
ah well I didn't couple the Initializer with Components specifically.. but might be worthwhile
Is there a single Unity incremental source generator sample?
Its been a nightmare getting source generation to work
For CICD purposes, what happens if you call EditorUtility methods while running in headless mode (cmd line like Unity -batchmode -executeMethod BuildMyAwesomeGame.BuildAndroid -nographics)
It looks like.. silent success-failure? ie, no exceptions, no logging, no hiccups - just zip right through those lines of code?
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/EditorUtility.OpenFolderPanel.html is what I'm looking at specifically
It also suppresses pop-up windows that require human interaction (such as the Save Scene window)
So yeah sounds like that’s expected
Do you have Unity specific requirement?
It shouldn’t be too different from regular IG
empty methods most likely will be gone once compiled.
the only time checking a method body overriden or not being useful is when you're doing mods
Unless im mistaken it wouldn't make much sense for mods either
would either be abstract/virtual or an event
I am trying to incoorpreate some high level note taking features to my game (just being able to select text line by line and editing) ,I have been doing research for a while but I am kinda lost on how to approach it.
Do you think it makes more sense to just use UI toolkit in runtime to make it?
or does make sense to make a web app and embedd it on unity ?
or maybe trying to make it directly in UGUI by making every line a different textfield (sounds bad)
I am open to trying different approaches if you have any, and thank you in advance
How is your existing ui made? Use that framework. Why select/edit individual lines of text, does this have a gameplay purpose? Seems cumbersome. Multiple input fields is not in itself bad, but if you plan to make a text editor where you draw lines as individual input fields, that’s bad in any framework. In any case, embedding a web app is the worst idea of the 3.
That being said, making a good text editor, with all the expected behaviour, is the most surprisingly complex thing you can do in UI. Assuming a commponplace interpretation of what you said: If you can, you should stick to using a multiline input field per 'note' that provides a basic text editor and extend that as needed. UIToolkit and UGUI can both handle that easily. Another option would be to open an "edit panel" when clicking on a note. This panel would hold a single input field and load/edit/save the to-be-edited note.
makes sense that if no window exists that some stuff like opening a file picker fails. for build automation we dont use nographics though 🤔
I am using UGUI as usual, currently just using multiline input field is enough to prototype but it is important for me to have high level note taking features at one point in production
and I figured out it would be quite complex, so I am trying to make the calculation on wheter it is worth it to actually do that, or try to focus something else on the game
also thanks a lot for the answer,
what is "high level note taking feature" here means ?
I’ve written incremental source generators outside of unity, but when brought into unity it doesn’t seem to be able to reference user code with it.
I am using RegisterSourceOutput and not RegisterImplementationSourceOutput
Are you using Microsoft.CodeAnalysis.CSharp 4.1.0 and added RoslynAnalyzer label?
Oh maybe they bumped version up for Unity 6, but anyways version needs to be supported and needs asset label
Good to add some C# test project to see if it is sourcegen issue or Unity integration issue
Yeah it's specific versions iirc 4.3.0 works in 2022 and newer at least
We were having issues, so we tried every version before 4.9 or something
Most of the time unity just silently fails, so you might think it works but it doesn't
I am not sure what I am doing wrong
Minecraft renders max 1536 blocks long without fancy tricks
I am rendering 500 blocks long and choking up like crazy
https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Graphics.RenderMeshIndirect.html
Should I use Graphics.RenderMeshIndirect
I do combine same faces
I have lots of gameobject
Also why am I still rendering millions of triangle when I am looking at the ground
It looks like Unity does frustum culling but it doesn't do occlusion culling
RenderMeshIndirect doesn't perform any frustum culling, except for the whole thing based on the world bounding box you provide. Unity doesn't know where these meshes will end up, since you're never providing it with that information.
I do call mesh.RecalculateBounds(); mesh.RecalculateTangents();
So you are not currently using RenderMeshIndirect?
Do you generate it once and then just store it and render it?
Are they all behind? Did you forget about overdraw?
Are you comparing the same scene/world?
so why is it happening? shouldn't it be not rendered since I do not see them?
yes
when I look away from all the mass
I get high fps
when I look at directions where the blokcs are
I die
I mean my frame rate dies
so I know overdraw is happneing behind these blocks
12 M triangles
is this normal?
Without you doing anything to mitigate it then it will be overdraw. Use the frame debugger to verify
things you would expect from a note taking app, like having image embedding, having different font sizes, formatting (bold/italic/highligh)
That won't help for sure but use it to see how there is overdraw as you step through the frame.
I set shadow max distance to 10
it doesn't help
I am not sure what is helpful info to me
as you move it along the steps, the game view will change to show the "progress" of the frame
so I noticed that reducing the max shadow distance from 500 to 10
Reduce 18M -> 5.7M triangle
I can see lots of triangle being drawn if I amp up the shadow distance
Yea, it will draw triangles again for shadow projection so the smaller the shadow area the better
still I am rendering 8M when I am looking at the flat ground close to my face
and I dont think frame debugger is telling me why
it wont but you can use it to see all the mesh draw calls. If they all get batched it may be harder to see.
Try using the urp rendering debugger overdraw thingy https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@13.1/manual/features/rendering-debugger.html#rendering
Per-block: Minecraft only renders the faces of blocks that are next to air or other partial blocks, effectively hiding faces that are covered by other blocks.
Per-chunk: The game only renders chunks (16x16x16 sections of the world) if they are visible to the player, a process more properly termed occlusion culling. ```
Are you not culling the inner faces/blocks?
I only render the exterior
parts contacting the air
Hmm then if you check the profiler can you see if say batching is taking ages?
r u suggesting perhaps that CPU <-> GPU bus might be taking too long?
that makes sense?
right?
Im not sure how you are drawing the meshes but if a shit ton of varying meshes need to be sent then that is gonna be shit vs say a few small meshes that can be instanced
its shit tons of varying meshes yes
I extraced exterior then optimized each of them, giving them each unique prob
but I am not sure, isn't that what Minecraft is doing anyway?
Then that could be a contributing factor.
Tbh i dont know but im sure its been explained by many people
Wouldnt you just send the mesh to the GPU once
Even though the scene statistics is a bad source for debugging performance, it's saying up to 20k batches so you are drawing a lot there despite the camera only showing a handful of meshes
And sync changes only when the player digs (if it has such feature)
I presume so yes but gpu instancing is still better as it can draw many instances in 1 call
i was wondering this too, wouldnt these be culled already due to being outside the cam frustum? I wonder if those stats are influenced by the scene view...
do I gpu instance the entire map of 1500 x 1500 x 1500 cube world?
i admit i dont know the answer but id imagine having a set of core shapes and instancing with those
DrawProcedural is one option too. You can draw a bunch of tris or quads with it
You're chunking it right? Minecraft does like 32x32 16x16
my rendering chunk is 20^3
And one materials where you're using the UV coordinates to change what texture is displayed
one material
I cannot just render the entire world in a single call
memory cannot hold that many draw calls at once
well say you have 1 call per "chunk" that would still improve things somewhat. 19k batches is still sus though
I do 1 call per chunk yes
20^3 cube
the meshes are optimized
static batching perhaps?
Static batching is a draw call batching method that combines meshes that don’t move to reduce draw calls. It transforms the combined meshes into world space and builds one shared vertex and index buffer for them. Then Unity performs a single draw call that uses this combined mesh
to draw all objects in the batch at once. Static batching
can significantly reduce the number of draw calls.
Static batching is more efficient than dynamic batching
because static batching doesn’t transform vertices on the CPU. For more information about the performance implications for static batching, see Performance implications.```
static batching isn't really used with URP
hybrid batching in general is being phased out
SRP batcher or GPU instancing
I can only imagine the chunking isn't working and you're just rendering everything when looking at a single chunk
Try getting a chunk in front and behind the camera and see if you're still rendering everything
I presume also in the frame debugger you can see the tri count in the drawn batches to figure out if they are bigger than expected?
Ah, frustum culling doesn't cull even if blocked so yeah it would render chunks behind it so you need to set up some occlusion culling. If you want a quick solution right now, just reduce the far clipping plane* ;p
- fog ez
If they are not batched into very big pieces then they would get culled better but overdraw with pieces still in the frustum will still happen
I am guessing they get batched into large chunks and many intersect with the frustum in some way so are sent to draw 🤔
im not fully sure how the SRP batcher does things so may be wrong
1500x1500x1500 is pretty freaking gigantic. I'd double check if the clipping PLANE isn't uncapped
I am realizing that it is CPU
GPU is chilling
GPU is just like
nah bruh I am chill
is there a way to check waht's causing this CPU stress?
Scripting is taking so much cpu usage I think?
you need to go down the stack and see what it is. I presume its render pipeline drawing and/or batching stuff
yeah I agree
I decided to not fill up the mesh
just RenderFilter with 0 verticies mesh
just lots of them as I need to render the world
I get 3 fps
so I am realizing
the issue is having LOTS OF unique meshes
and CPU using draw calls
Just checking, did you have all those objects selected when getting 3fps
no
Deep profiling will also make everything run slow
Did you look at the profiler's hierarchy view to see what is happening?
I disabled deep profile
I am getting, without selecting gameobjects
30~50
fps
which is better than 11 or 3
but still unacceptable I guess
so I guess the biggest challenge is reducing the bus trip between CPU and GPU
What are you sending to the GPU every frame?
there are thousands of meshes
But they have copies of them on the GPU side. You don't "send" them every frame
Unless you do?
Depends on your RP and what type of batching
And if they have no mesh assigned, then it won't render anything right?
You have been pointed to Frame debugger which shows you each draw call
And you didn't inspect the profiler results properly yet, from what I can see
I dont think it tells me much useful info tbh
I did benefit from
shadow map
my shadow rendering distance was too long so that eveything was being restred on my depth buffer
it is useful, you can fold out and see all draw calls and what its doing and see its affect on the frame in the game view
like you did earlier, you saw the shadow drawing was doing a lot too and made a change
yeah it did help me with the shadow...
Id be interested to see what batches its making and the tri count /size
in the frame debugger?
there were 4 batches
2nd batch
3rd batch
4th batch
they all look normal tbh
I am a bit confused because in the scene it says it has 1870 batches
but I guess they were combined?
Perhaps the effort of making the batches is the whole problem? I wonder if you can disable batching for some meshes and see what changes
that makes sense
the stupid batch creation process, what should be making things faster might be making this slower
how do I disable this batching
it's not static
i could be wrong but i cant see your profiler
The statistic window hasnt been changed since built-in and the batches is always misleading, but if you've say hundreds of thousands of batches then you know something is wrong
but SRP batcher will batch a lot more than it usually says
Probably even less accurate with GPU instance
I don't think there is such thing
disable batching
I don't know
I dont know what's wrong
all I know is that, if I disable gameobjects it performs better
I think the problem is that I am making too many MeshFilter
maybe I just use that GPU instancing or something
I'd try playing with the clipping plane if you havent and see if that fixes anything
and yes, you should only have a single filter per chunk usually
except that is lowered world size for faster testing
myabe I shoud use LOD for a distance chunk
lets not forget
@fresh tangle Forgot to say yesterday -- would be kind if u threw a ping when you complete it!
I'm not expecting "ready code" but hearing about your experience (e.g. what you learned works/doesn't) would be nice.
yeah I dont think it is GPU issue at all
so all those meshes.... all this time...... they're not instanced? 😮💨
if thats the case, the perf you're experiencing is 100 % real 😃
I mean each of them is unique as I greedy meshed their faces but I guess that was just shooting myself in the foot
created thosuands of empty meshfilter
I get like 60 FPS
you can have different properties for all of them if you want even if they're instanced.
8 batches 8 tris, so it's not triangle or batch issue at all
yeah I guess I instantiate "dirt square face" or "rock square face"
at where the cube's faces need to be
it feels salty to go all the way to greedy meshing my faces only to realize I was shooting myself in the foot
Hi everyone!
I'm working on an optimized mesh destruction system for a procedural 2D planet, where every quad can be individually destroyed.
At first, I was editing vertex positions and colors using arrays with mesh.vertices and mesh.colors, which worked fine. However, the issue was that every time I edited just a few vertices, the entire mesh was being reassigned, leading to unnecessary performance overhead.
To optimize this, I decided to update vertex data directly on the GPU using SetVertexBufferData(). The colors update correctly, but the vertex positions don't change as expected. First planet image is the bufferdata and the other was with arrays working fine
Any tips on why this might be happening? Could Unity be optimizing or reordering the vertex buffer in a way I'm not considering?
does anyone know what Minecraft does with received world data (voxels?) Right now I am saving all the world data I received from server and eatting my memories. But don't I need these data to render and interact with the world?
Server like multiplayer? Everything is done by seeded values, so unless chunks are changed beyond the seeded generated value then you're just telling the peers to renders a radius around them using that seeded value.
how much memory is a single "block" in your case?
64 bytes
each player has ability to throw atomic bombs in my game
also there is a voxel tree seed that grows voxels like a tree everywhere
most blocks (think dirt, stone) only really need to store what it looks like
you can have block ids and compact it down into 2 bytes or 4 bytes for block
for more complex things you can instead store an index into something else which has the actual data
ive tried 4.1 and 4.3, with RoslynAnalyzer and also tried other labels and combinations of them
i think its a unity integration issue
ive used the source generator fine outside of unity
- opening the unity generated sln is able to see everything correctly
you've applied the correct asset label and you are certain that it isn't throwing an exception?
no exception
the code is being generated
so if the code is being generated, what is the issue?
every block doesn't need it's own material and rgba value, they/something managing them just needs to associate them with a shared material and rbga value
eg. minecraft's dirt blocks don't "have" a dirt texture, minecraft just figured out which texture to use based on the block type
Yeah, so basically you render based on that seeded value, but if the server recognizes that a chunk was changed then that must be serialized and passed onto the player
in a script file:
class UserWritenClass;
source generator output:
class C
{
// The name "UserWrittenClass" doesn't exist in the current context
public static void M(UserWrittenClass c) { }
}
what I wanted to say was, seeding doesn't work due to the game aiming to just totally aniihiliate and reconstruct during gameplay
Does Minecraft really bother with the seed things with clients?
i dont think so
I can't imagine it not. How would you serialize all that data otherwise
you've used an assembly definition to contain your source generator to just the assembly with your own code in it, right? because otherwise it will be applied to all assemblies which should be fairly obvious depending on the actual error message in your console
i can make a mc world filled with random blocks and it still loads fine
see literally any multiplayer server where most blocks are modified
if there is Air and Rock in 100^3 chunk, you only need
4 bytes x 2 => 8 bits for id denoting + 2 * 100^3 bits
that is
250,001 bytes
how it works is with block ids
1 -> dirt
2 -> stone
3 -> grass, so on and so forth
things like chests that need extra data are block entities and are stored separately
it's seeded unless modified, im not sure if that's on a block or chunk basis
I mean it's possible, but seems a hefty amount of data being serialized per peer and those servers can get pretty large
I mean minecraft saves be big
bandwidth is pretty cheap nowadays
Clients fast forwarding years of world changes by NPC entities 😛
250,001 is 1.907356262 Megabit
0.00200000799978288001 giga bit
so if the world was simple, saving 100^3 costs 0.002 Gigabit
1 / 0.002 = 500, so you could save 500 of 100^3 chunks using 1 Gigabit
that might be it
well it depends entirely on the actual error message and what assembly that error is in
specific error is
Frent.Generator\Frent.Generator.ComponentUpdateTypeRegistryGenerator\FrentComponentRegistry.g.cs(6,27): error CS0246: The type or namespace name 'RootWorld' could not be found (are you missing a using directive or an assembly reference?)
1 Gigabyte of Ram can store 4,000 of 100^3 cubes
cube root of 4000 is 15.8
15.8 * 100 cubes = 1580 cubes sight range
in Minecraft, max render distance is about 100 chunks
a chunk is 16, so 100 render distance is equal to 1600
with one giga bytes of ram u could have max render distance if u used pallete
Right now I use 120 GB of memory to render like 500 blocks worth of render distance
my Minecraft clone is trash
hmm
im looking up how assembly references work and it seems by default there is only one assembly?
so that wouldnt be the issue
at no point did i say anything about an assembly reference. i was referring to using an asmdef to limit the source generator's scope. https://docs.unity3d.com/6000.0/Documentation/Manual/analyzer-scope-and-diagnostics.html
holy crap i cannot read
if the issue is not a scope issue, then it just sounds like you're using a type that is contained within a namespace but not also either specifying the fully qualified name or adding the correct using directive in the generated code
the class is in the global namespace
i think you are right, that it is a scope issue
from what i can tell the source generator is generating a file for an already compiled assembly?
thank you so much for your time
is someone familiar with deploying builds to Epic Games store using BuildPatchTool? i have some tough issues i cant manage to fix
upload never finishes even after 9hrs and i literally tried everything with no luck, plz help
Hello everyone,
i am trying to update the session and set it to private so the players that try to join after it is set to private can't join and they create a new session of there own.
But for some reason it sets the session to be not private soon after it is private or a new player is trying to connect.
public async Task CreateSession()
{
if(activeSession != null)
{
activeSession = null;
}
var sessionOptions = new SessionOptions()
{
Name = sessionName,
MaxPlayers = maxPlayers,
}.WithDistributedAuthorityNetwork();
activeSession = await MultiplayerService.Instance.CreateOrJoinSessionAsync(sessionName, sessionOptions);
hostSession = activeSession as IHostSession;
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
HideSession();
}
}
public void HideSession()
{
if (hostSession == null) return;
hostSession.IsLocked = true;
hostSession.IsPrivate = true;
print("Lobby Privated & Locked!");
}```
I'm a little unclear how addressables bundles are looked up in the client. I've read through the documentation but there must be some nugget of info I'm missing. For context, I'm building some CICD scripts and I'd like to separate the addressable/bundle build and deploy (to google cloud) workflow from the build and deploy android/ios and deploy (to firebase and testflight) workflow. If a dev does a bugfix, we shouldn't need to rebuild the addressables and upload - they'll just be the same. Conversely, if someone updates some art, we shouldn't need to recompile the app and upload it.
My understanding is that there.s a catalog_xxxx.json and .hash that gets created with the .. build (of the app), and packaged with the addressable bundle? I have this file (along with all my bundles) but I don't know how the app knows what .json/.hash file to get from the CDN..
What am I missing?
this is one bundle from a build - also, i'm not sure why there's a bunch of different hashes and jsons in it?
If remote catalog is enabled it will check each game launch if the catalog has changed and it will download the new one. it also means the catalog version cannot change if you want this to update old builds.
I did this by keeping the catalog version as 1 and versioning with game version in the URL
instead of that automatic date one?
(and yeah, we're using remote catalogs)
so i'm assuming that the app's current setup:
this would prevent me from using separate workflows for building bundles and the app (as they'll have different timestamps)
Yea if you don't override the ver to be constant it won't work with separate jobs unless you commit the data bin and do a update build (which I did not)
That's why I versioned this all in the path itself
k.. and I think that using my own version here is gonna be preferable anyway, because if I understand this correctly, the client is going to request the remote catalog each and every time the app inits to see if it needs any bundles, and if so where they're located
so I could do some sort of schema like catalog_{ENVIRONMENT}_{APPLICATION_VERSION}.json and I won't even really need to worry too much about it
like, i could do code builds (since the app version wouldn't be incrementing) and only need an addressable build if the code build mucked with some content (rare, for this project)
I did it in the path in the profiles and not in the catalog ver
but then don't you get a full bundle build every time? (versus the delta)
or, wait, I guess that's fine too - the version assets would all be in the same directory. That actually might be preferable since our google bucket is currently just a mess.. hundreds of files
We would have /dev/XX and prod/0.0.0
k.. i like that (the versioning in the path).. we have separate buckets for environments so we don't need to comingle them, but maybe there's some advantages there
Up to you I guess. Had a manually changed num for dev builds. It's a pain to do it this way but addressables didn't think about this properly
I don't like this work needed if you don't keep the damn content bin around
the content bin..?
the uh.. addressables_content_state.bin thing?
maybe i'm not understanding how unity caches the addressables.. i just assumed the outputted bundles (and catalog json/hash) were sufficient.. Do I have to create (and keep) these bin files around between builds?
Nah I think it's useful only to "update" existing builds a bit better and keep the catalog ver the same as before?
I never kept it in any way
can you set the scripting backend when running unity in headless mode? I'm .. thinking there's a bug with building addressables that people are finding a workaround with changing the compiler to mono, but i don't want to set this for normal builds
(this error message and stack trace is super unhelpful)
Unable to build with the current settings.. check the build settings. Check what?!? 😐
Fixed it, had to [manually] call EditorUserBuildSettings.SwitchActiveBuildTarget() in the build otherwise it just pood.
is headless this important? my works jenkins doesnt use it
oh here
What's up with so much Empty Heap Space?
Unity is only using less than 1 GB
I call GC.Collect madly and yet these memories don't get freed
whats the issue? editor captures are kinda shitty so make a dev build to check instead.
Ok
my editor was eatting up too much memory like 100 GB memory
I am running a build now
My game located 10,000 MB
that's 10 GB of memory right?
did it show that in task manager?
yes
ive had issues before where it goes crazy with memory usage (once with a fbx import)
but if managed looks okay its probably fine
I don't know aht u mean by if managed
The entire world should be 250000000 bits
that should be 0.03125 gigabyte
so I feel like managed looks bad as well
i guess have an inspect and see whats up. dont forget the rest of the game 😆
unity stuff also will be managed. not sure where native containers get shown though
I just remember this is an issue I encountered before
if you create a huge dictionary or list in your function
your memory grows so large and it doesn't go away even when the function ends
search for the rest of the period your game is at this ballooned memory state. just occupying so much space for nothing
well thats just how it works, the list/dict was allocated but at somepoint it will get GC'd and freed
for how long should the game run for these unnecessary memories to be released
because they seem like not being released at all
even after an hour
If not then they are still referenced
they're really not referenced though 😦 you can even replicate this behaviour
well either you found a bug with the mono/unity GC or you are mistaken
99% you are mistaken
you sure its not a class field on some monobehaviour? used in a delegate somewhere?
yea perhaps its captured by a delegate subscribed to some event?
Actions? events? lambdas too
anyway have a think, i highly doubt this is a gc but see what you can find
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
@echo coral you can literally replicate this result
your memory will not be released even after the thread is terminated or when the unity editor stops running the scene
is there #bug or #glitch #malfunction
the thread wont stop when you stop playing and the managed memory state is not reset untill you play or recompile
The thread should stop when stopToken.IsCancellationRequested
and that's when you stop playing
I believe
and 'managed memory state is not reset untill you play or recompile'
that part is correct yes but a thread you did not stop will not end magically
if I press Space bar then it sets the bool to false
and I do get msg
UnityEngine.Debug:Log (object)
UnityTest/<>c__DisplayClass1_0:<Start>b__0 () (at Assets/UnityTest.cs:30)
System.Threading.ThreadHelper:ThreadStart ()
is that not enough to stop the thread?
r u saying even after the thread reached end of its instruction it keeps running?
no no, if it ends it ends and i see no reason for this not to be gc'd
wdym
managed memory state is not reset untill you play or recompile
does it mean each time I use new List<> or new Dictionary, I am terminally hindering my game for that session?
if you started a thread and did not stop it after stopping play mode, it will still be running until a recompile or you play again
that makes sense
so this test code shoud not cause giant memory occupation right?
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Id think it will build up quickly but after the loop ends and the thread completes it will be gc'd after a short bit
exactly what I think
but it doesnt
If u r at at your desktop I hope you run that code yourself
it really doesn't free your memory at all
!bug
🪲 To make bug reporting as quickly as possible, we made a bug reporting application for you. When running Unity choose Help->Report a Bug in the menu, or you can access it directly through the executable in the directory where Unity is installed. It will also launch automatically if you experience a crash.
📝 If your bug report is to do with Documentation, either an error, typo, or omission, you can report it by scrolling to the bottom of the page where you found the issue and click ‘Report a problem on this page’!
💡If your report is to do with a new feature idea, you can check the Unity Product Roadmaps page to see if your idea has already been planned.
For more complete instructions on how to report bugs, access: https://unity3d.com/unity/qa/bug-reporting
OK I sent the bug report
meanwhile I would really appreciate if anyone can duplicate this bug
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
I think this behaviour might be Unity not releasing already allocated sections of memory to reuse in the future
All i can think of is that unity has some ref to the thread somewhere as i know domain reload wait for all threads to end
My guess is that Uniyt is not freeing these memory because it thinks I am gona need this much memory again
well its not "unity" but the mono gc or the alt incremental gc
The time it takes to increase occupied space is lesseened each time I occupy more memory space in the new scene run
so it means I think, it is re-suing those already occupied memory spaces for my current session
perhaps in managed land its actually freed but somehow mono is not reducing managed mem space
I'm doing research right now it seems like it's really not releasing the memory back to the OS
It might reserve the allocated heap, indeed. You can try this in the build and see if the issue happens.
Also, you should use the memory profiler, as I mentioned many many times before...
I did
And what did you see?
I thought I posted here no? one sec
there are so much EMPTY HEAP SPACE
I think Unity and Unity builds just eats up memory and doesnt spit it back even after it no longer needs
it does seem like a problem for it to hang on to such a dumb amount of mem 🤔
Ah, I found it
id presume in a build its different to the editor
build was same but let me try one more time
The memory it would keep would depend on total available memory on the system I think
i had it go up like 2/4GB and it kept it, i have 32gb ram
That's a bit weird.🤔 Maybe try a non development build
i really want anyone to test this code to duplicate the result
I did a bit ago in editor and it kept the memory too
ohhh yes
so u did see it right?
sorry my English is not my first language
i miss sometimes
This may be intentional: https://docs.unity3d.com/2021.2/Documentation/Manual/performance-managed-memory.html
"Unity doesn’t release the memory allocated to the managed heap when it expands regularly; instead, it retains the expanded heap, even if a large section of it is empty. This is to prevent the need to re-expand the heap if further large allocations occur."
yeah and also I think it somehow not even that beneficial... if I try to allocate a long consistent chunk of memory, sometimes he throws me then I'm out of memory because probably he cannot find consecutive memory chunk within what it already allocated
Yea that does sound like a real problem if it cant even use that large heap again
I need long chunk of a memory. and whenever it cannot find long chunk of a memory in what it already allocated, it it's a more memories from the OS
inb4 the response is "use native collections!"
I'd profile the memory around the time it happens and see if it does or doesn't use the reserved heap.
native collections?
I think it does and doesn't sometimes
I judge this based on the memory consumption
https://docs.unity3d.com/Packages/com.unity.collections@2.5/manual/collections-overview.html
collections where its all manually allocated and disposed of so no gc!
sometimes it go up sometimes it doesn't
you mean I use.... uh... cant think of what its called
the ones that I need to manually manage and free right? (unsafe memory management way)
I think that might be the way to go to be honest
id try em yea, i didnt realise there was this problem with how the heap was handled. Who wants 8+GB of empty space doing fuck all
coreclr save us!
Yeah I want like 8000000 bits long consecutive chunk of memory (and I want like 4000 of them)
I don't think it's finding it
yeah
so I dont know how its doing but a list is an array but list of list is not big chunk
so I guess there are long chunks of memory of each list every where
and its not finding efficient place for long list
and I guess things get scattered even massier
so in the end when I need, lets say, 1GB long memory, it cannot find me 1GB long memory when its occupying 90GB free memory
I literally have 100GB memory and my game eats up all of it
and it wants more
because I guess it cannot find a place for long memory chunk section
Maybe rethink your approach then. It's not like users are gonna have anywhere close to 100GB of memory.
the problem is that I'm not using that much memory
I just use long chunk of memory and Unity keeps asking OS to find one cuz it cant find one itself
You are confusing the state of the heap Vs it's size. It should all be free and usable if gc'd. The clr host is what's helping the managed heap big
and then it doesn't release the memory back to the OS
Could also be actual stuff in use is dotted around the large heap but I do think it would move stuff.
I get the...no memory error though
Yea clearly there are many things compounding the problem
yup
Use native collections and hopefully it will all get fixed
I think they should help me yeah
I know exactly the section where the large memory chunks are required
I can manually manage that section
I think you should use a native array as suggested. Allocate one with the max size you think you would ever need for everything. Then just modify the elements to your needs.
aye agreed
Yep then dispose when done (especially if you set it to persistent)
Arrays and lists in C# are not like arrays in C/C++. They are not contiguous in memory, so their members may be stored in fragmented memory. A native array will act like a C style array, though.
The managed heap can grow but not shrink. It's expensive to allocate memory from the OS compared to reusing already requested memory, so the managed heap never frees the memory in case it needs to get used again. It's similar to preallocated heaps in other engines; grab all the memory up front and then have a custom alloc and memory manager to keep allocations quick.
There are some games that allocate a bunch of memory for no reason at boot to make sure the managed heap doesn't need to grow during gameplay to prevent any performance hiccups, so there are good reasons for not letting it shrink.
Yeah I want like 8000000 bits long consecutive chunk of memory (and I want like 4000 of them)
A native array for that much memory (about 950 mb) and managing it yourself is almost definitely the right way to handle that number of buffers, especially if they are going to be volatile in memory.
Pretty sure C# arrays are contingent in memory. They're just allocated on the heap. Obviously, if it's an array of objects(basically references), the object data itself is gonna be somewhere else, but the reference addresses in the array should still be contingent. Same goes for arrays of primitive types.
ah, that's correct, my mistake.
Is any one know what import do I need for ECS customized shader to support Dots rendering? I can not find any information on the official documentation?
If there is any page on the official page link and someone please share? Also, I can't find the section on the Unlit shader from URP import for the ECS compatible, is it just me?
I'm sure that's not a bug.. what might happens here is that your object might being promoted as LOH (LargeObjectHeap).... OR the opposite, meaning they're not large enough to be able to put GC under pressure so the gc would not happen
just for learning purposes, try this :
- MyMainList.Clear()
- then GC.Collect()
- Profile it
note gc.collect is a bad practive most of the time, in this case it's just for testing
void Paint(int pixelX, int pixelY)
{
for (int i = 0; i < colors.Length; i++)
{
colors[i] = paintColor;
}
paintedTexture.SetPixels(pixelX, pixelY, brushRadius, brushRadius, colors);
paintedTexture.Apply();
Graphics.Blit(paintedTexture, renderTexture);
meshRenderer.material.SetTexture("_PaintMask", renderTexture);
}
So I'm painting mask to blend over a mainTex which I append to with each stroke, but I'm having trouble figuring out how to "erase" color added to this texture. I've tried zeroing out the pixel color but I still seem to get a different colored pixels compared to not being set so I'm a little confused on that. #Edit: guess I didn't notice but it seems that the pixels dont instantiate zero'd out, yet the default value blended in so well with my actual mainTex
Using RGB24/32 if that matters. Maybe I'll play around with different formats.
I'm trying to create a first person perspective script, to assemble the first person mode, of a paper doll, that allows the character to pick up an item by pressing a keyboard key, and altering the graphic art of the first person, to a holy yellow shirt, I have all the graphics, and the game play already, but the script I made, does not change the first person mode to a yellow shirt, does anybody know how to solve this?
not all arrays in c# allocated on the heap, InlineArrays can be a struct
Not a code question.
sorry I couldn't find the correct channel..
#archived-lighting #archived-urp (if using URP) or #💻┃unity-talk
I'm sure what you want is Span<T>
this is free pretty much
Span<TValue> span = stackalloc TValue[length];
@last hornet Don't crosspost.
sadly it can't get out of scope and unfort Unity doesn't support [UnscopedRef] yet, but you can still pass them around as ReadOnlySpan<T> @patent bear
just a side note, don't span + stackalloc on string operations, if the string is super long it will OOM
yea in any lang having a large char[] on the stack wont fly for long
Hello, I need some assistance with an issue I am having with rotation and movement. I would like to have my character move relitive to the rotation of it. Then once it reaches the correct position or close to the correct position it will stop moving and set the position correctly if it's off by some amount. The issue I am mainly having is if I rotate the object one way it works correctly but If I rotate it to the oposition position then it does not work correctly this is the code I am using simplified.
If anyone could help I would appreshiate it!
private Vector3 TargetPos()
{
var targetPosition = stateMachine.transform.position + (stateMachine.transform.rotation * Vector3.forward);
return targetPosition;
}
private void CheckMovePositionForward(float deltaTime)
{
var currentPosition = stateMachine.transform.position.z;
if (isMoving && currentPosition > TargetPos().z)
{
Debug.Log("Call 2: Moving Forward");
//Animate Movement
}
else
{
//Stops Animate Movement
isMoving = false;
}
}
Edit:
Fixed the isseue instead of just comparing the z pos I now just compare both vectors using
Vector3.Distance(); this returns the correct value needed replacing this
if (isMoving && currentPosition > TargetPos().z)
With this:
if (Vector3.Distance(currentPosition, TargetPos()) > Threshold)
it makes sense you can't get it out of scope, it would be illegal memory access out of scope, unless you mean passing it into some function
also have you tried with -langversion:preview, still doesn't work? I can't use preview because it breaks some packages for me, and I know that ref fields are not supported in 10 but I'm not sure if preview has them
as far as I understand preview should enable some C# 11 features but I think ref fields also need runtime support so likely won't work
normally you say what specifically the error is and give more info...
copy warning text including the stack and send here
Could not save compressapidata because PlayFabSettings could not be found.
UnityEngine.Debug:LogWarning (object)
PlayFab.PfEditor.PlayFabEditorDataService/PlayFab_SharedSettingsProxy:Set<bool> (string,bool) (at Assets/PlayFabEditorExtensions/Editor/Scripts/Utils/PlayFabEditorDataService.cs:68)
PlayFab.PfEditor.PlayFabEditorDataService/PlayFab_SharedSettingsProxy:set_CompressApiData (bool) (at Assets/PlayFabEditorExtensions/Editor/Scripts/Utils/PlayFabEditorDataService.cs:22)
PlayFab.PfEditor.PlayFabEditorSettings:DrawPfSharedSettingsOptions (single) (at Assets/PlayFabEditorExtensions/Editor/Scripts/Panels/PlayFabEditorSettings.cs:305)
PlayFab.PfEditor.PlayFabEditorSettings:DrawStandardSettingsSubPanel () (at Assets/PlayFabEditorExtensions/Editor/Scripts/Panels/PlayFabEditorSettings.cs:255)
PlayFab.PfEditor.PlayFabEditorSettings:DrawSettingsPanel () (at Assets/PlayFabEditorExtensions/Editor/Scripts/Panels/PlayFabEditorSettings.cs:119)
PlayFab.PfEditor.PlayFabEditor:OnGuiInternal () (at Assets/PlayFabEditorExtensions/Editor/PlayFabEditor.cs:128)
PlayFab.PfEditor.PlayFabEditor:HideRepaintErrors (System.Action) (at Assets/PlayFabEditorExtensions/Editor/PlayFabEditor.cs:172)
PlayFab.PfEditor.PlayFabEditor:OnGUI () (at Assets/PlayFabEditorExtensions/Editor/PlayFabEditor.cs:104)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)
cool now go to PlayFabEditorDataService.cs:68 and you should realise what the problem is!
tl:dr Read the error/warning next time
im guessing stuff was not loaded into that dictionary thus its not "setting" what you want
i presume this is from a lib and not your code
its for a game of mine
👍
@regal olive go check the playfab docs as you probably are missing some settings object or initial setup. If you are having trouble interpreting this warning then post in #💻┃code-beginner in future.
I've been trying to make the jumping action for my player to work all day, for some reasons it doesn't detect the ground even though it's already on the ground. The player uses capsule collider, while the ground uses mesh collider... Please help
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
anyone here familiar with compute shaders, can I get some assistance regarding thread groups/counts? - https://discussions.unity.com/t/figuring-out-the-correct-thread-group-count-sizes-for-realtime-spherical-harmonics/1616290 - here is the unity discussion thread full with more details
just FYI, it is against server rules to discuss modding. gotta ask for help in the game's modding community or bepinex community
Sorry, my bad
I feel like this is just a race conditions issue.
Is it possible that you have several GPU threads writing to the same buffer index? Having 1 thread in a group might mitigate it, since they would possibly be using higher level caches compared to threads in the same group.
it is, but the thing is I'm not to sure how to split up this workload properly in a way where I get what I need
the end result is I need 9 sets of float3 coefficents, which require iterating over every specific tile on said texture
You could use some kind of atomic read/write operations to avoid race conditions. Or maybe use some kind of shader barrier. Though that's gonna also slow down the shader quite a bit. To be honest, writing to the same memory withing one draw call/dispatch is not something fitting GPU.
Hi, is there a good solution for reducing JIT spikes when the application is running? We would ideally not swap to IL2CPP. Some JIT spikes are 7-11ms the first time the functions are hit. As an arcade game, this is noticeable during gameplay. We tried a system we found online that was supposed to cause each function to compile on startup, but it didn't seem to work. Any ideas appreciated!
Do you know specifically the major causes? Is it genrics? il2cpp does not support runtime JIT generics from what i remember hence this not being an issue.
No, not generics... just seems to be pretty standard C#.
can you find a code example using the profiler?
Yeah, we have some of them caught in the profiler, but as far as we can tell, there's nothing special about them... just the way that C# framework works.
Gotcha. Im doing some research and came accross this blog post: https://www.liranchen.com/2010/08/forcing-jit-compilation-during-runtime.html
A stack overflow answer proposes using this: https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.runtimehelpers.preparemethod?view=net-9.0
https://stackoverflow.com/questions/751186/forcing-the-net-jit-compiler-to-generate-the-most-optimized-code-during-applica
this suggests its related to virtual methods
Okay, I'll pass them onto my colleaugue who looked at this previously. He may have found some of those links already. Thanks. We'll keep digging in. Would be great to remove the spikes somehow.
goodluck. hopefully something works
Ah, so Mono doesn't implement the Prepare Method call, so that solution doesn't currently work. This must be what we tried before.
tis the problem with shitty old mono...
since il2cpp exists as an option i guess there isn't much pressure for unity to do much about this on the mono side, is there a reason il2cpp isn't suitable for you?
mono wont be improved as the plan is to go to core clr
We lacked confidence that it wouldn't break stuff - seem comments about it not being "complete". No perceived performance gain from using IL2CPP over Mono etc. If we have to revisit this decision we can I guess.