#archived-code-advanced
1 messages · Page 50 of 1
My declaration looks similiarcs public sealed class NightVision : CustomPostProcessVolumeComponent, IPostProcessComponent { public ColorParameter tint = new ColorParameter(new Color(0.25f, 1f, 0.5f), true, true, false);
And I can control the parameters just fine
Even though the material is null, you can update the properties?
And they take effect?
@karmic surge Ive used this library in the past. Works very well. https://github.com/keijiro/KlakSpout
Yes. This makes my colors go wild:
if (nightVisionVolume.sharedProfile.TryGet(out NightVision nightVision))
{
nightVision.tint.Override(UnityEngine.Random.ColorHSV());
...
Interesting, I wonder if there is some strange magic going on with volume components... let me try
Well, that's the correct way of changing properties on your PP component
Just forget about the material, it's private for a reason in the default HDRP post process
Thank you, I am looking at it at the moment, this might save me a ton of work.
tho, there is a chance I can use ONNX model inside unity and ditch the entire python application (hopefully!)
Thank you for that. It's just very strange to me that it would work this way, but thanks!
Is there a way to write a script that replaces a Type name in code to some other name? That Type can be referenced in multiple scripts. Would i have to scan through every .cs file to replace it or is there a smarter way?
Every IDE has a rename feature
use it
He need to rename multiple source files
Here's the rename feature in Rider
i need it for an editor tool where the user can create and rename some types.
essentially i want to replicate that refactor -> rename feature
Unless you're doing code generation I don't understand what you're trying to do
i am doing that
Just change the name you are generating
but the user of my tool might have written some code that depends on the previous type. his code would break if id just "overwrite" my own file
Is that a huge problem? What is this tool supposed to be?
Its a tool to create an AI without any code. Essentially a gamedesigner could create AI all by himself. A coder might then use some of the AIs internal data to write his own Debugger or something. This Debugger would then break if the designer decides to rename stuff
Id really like to reduce the errors that could happen through a lack of communication
I mean I'm thinking about something like the input system's Input Action Assets.
If you use the generated code and rename your input actions, your code will break too.
It's not a big deal
I also get really nervous around an editor script that's going to modify my source code
modifying its own generated scripts is fine - but messing with user code? That's a little... odd
no its not messing with usercode. but the user could decide to mess with it. to extend tooling or get very specific data out of the AI. The AI is essentially a closed pipeline with Userdata as input and a decision as output. but it generates intermediate values that could be useful to some users. each of those intermediate steps is identified by a Type that is generated and named like a scriptable object the user is defining in the editor. So now if the user renames the Scriptable Object the type in code is not correct anymore. maybe i should just let it break
On a side note: currently my system allows for the coder to rename anything as he sees fit because codegen would never overwrite it. which might also be nice to have. the fact that ScriptableObject and generated Type name will not be easily connected to each other just bothers me.
oh i forgot to mention that that generated type is referenced in other generated files... without that "refactor name" feature id need to codegen everything from scratch after a rename. until now i can do everything incrementally.
im probably ovethinking this though.
Regenerating from scratch is much simpler
i guess so. i wanted to rethink my incremental approach anyways. currently im generating way too many single files. if id combine them in a few big ones its probably for the best. Nice Sourcecontrol workflows might be at risk though
Problem with AI is that it will get changed a lot and also by multiple people compared to say inputs.
Maybe consider refactoring the way the code works to be more data-driven with fewer classes
That's obviously really broad and hand-wavy
Because I don't know any details here
yeah its the most reasonable thing to suggest first anyways 😄
the issue is that im using DOTS and that has some very specific requirements regarding that
I think what you describe is best handled by some sort of runtime you build which interprets and executes user‘s ai. So you’d treat a users ai as data (as far as your code is concerned) and not as code that shares a compiler with your framework. The most flexible way to build AI is with a lisp, where code is data.
yes totally agree with you on that. Users AI is actually already just data defined in a ScriptableObject graph which could easily be interpreted in a generic way without any Codegen needed. my problem again is DOTS and the kinda incomplete API. To Query for Components i need to define entityqueries with specific known Types. so to get the Data into my "runtime" (which then again is generic) i need types...
(sry for delayed responses im not at home rn)
Given a NativeArray can I somehow make a NativeReference point at an index in that array?
I have a job that outputs a NativeArray<T> of results, but another job uses NativeReference<T> so I want to give it a ref to Array[0];
Hey sorry to ping you again. But since you seemed to have good info. Is it possible that not having the world camera assigned to the canvas may have caused this issues?
In reproducing the error, I noticed it only fires when the cursor is unlocked and the mouse is on screen. It stops once I get out of range and the other player is destroyed, which means the canvas is destroyed.
The only thing I struggle with is the unreliability of making the error happen and calling it closed.
This is the stacktrace in the editor for reference.
MissingReferenceException: The object of type 'TextMeshPro' has been destroyed but you are still trying to access it.
Your script should either check if it is null or you should not destroy the object.
UnityEngine.Component.GetComponent[T] () (at <c6b52566f59b49fc861a7812a1ea2f6b>:0)
UnityEngine.UI.Graphic.get_canvasRenderer () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Graphic.cs:444)
UnityEngine.UI.GraphicRaycaster.Raycast (UnityEngine.Canvas canvas, UnityEngine.Camera eventCamera, UnityEngine.Vector2 pointerPosition, System.Collections.Generic.IList`1[T] foundGraphics, System.Collections.Generic.List`1[T] results) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/GraphicRaycaster.cs:335)
UnityEngine.UI.GraphicRaycaster.Raycast (UnityEngine.EventSystems.PointerEventData eventData, System.Collections.Generic.List`1[T] resultAppendList) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/GraphicRaycaster.cs:236)
UnityEngine.EventSystems.EventSystem.RaycastAll (UnityEngine.EventSystems.PointerEventData eventData, System.Collections.Generic.List`1[T] raycastResults) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:263)
UnityEngine.EventSystems.PointerInputModule.GetMousePointerEventData (System.Int32 id) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/InputModules/PointerInputModule.cs:295)
UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent (System.Int32 id) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/InputModules/StandaloneInputModule.cs:540)
UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/InputModules/StandaloneInputModule.cs:526)
UnityEngine.EventSystems.StandaloneInputModule.Process () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/InputModules/StandaloneInputModule.cs:280)
UnityEngine.EventSystems.EventSystem.Update () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)
I don't think the lack of camera is relevant(if anything it might make it more difficult to reproduce). Assuming that's the same issue that you had before, I guess it's timing dependent. Specifically, the timing of the object destruction.
Sounds like a reasonable requirement and should be technically possible, but I don't see any options in the NativeReference API to not allocate new memory. It doesn't have an unsafe utility method for creating one from existing data like NativeArray does. I don't think it's intentional, just forgotten.
The only workarounds I can think of would be to use Reflection to change the internal pointer (you could also use the asmref trick to get access to the internal pointer without Reflection)
So I confirmed it is not happening when the object is destroyed. It is still on screen. So its not canvas destruction.
It seems to throw when raycasting against a TMP though. Are you sure you want text to receive pointer events?
Depends on which text it is. If it is on the player canvas then no. But I have other text setup as buttons/links
It's not great practice to have the text receive raycasts. Better have a background image that does that.
Okay. I think I figured out how to reproduce it. And I got a slightly different error.
MissingComponentException: There is no 'CanvasRenderer' attached to the "Float Number(Clone)" game object, but a script is trying to access it.
You probably need to add a CanvasRenderer to the game object "Float Number(Clone)". Or your script needs to check if the component is attached before using it.
UnityEngine.UI.GraphicRaycaster.Raycast (UnityEngine.Canvas canvas, UnityEngine.Camera eventCamera, UnityEngine.Vector2 pointerPosition, System.Collections.Generic.IList`1[T] foundGraphics, System.Collections.Generic.List`1[T] results) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/GraphicRaycaster.cs:335)
UnityEngine.UI.GraphicRaycaster.Raycast (UnityEngine.EventSystems.PointerEventData eventData, System.Collections.Generic.List`1[T] resultAppendList) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/GraphicRaycaster.cs:236)
UnityEngine.EventSystems.EventSystem.RaycastAll (UnityEngine.EventSystems.PointerEventData eventData, System.Collections.Generic.List`1[T] raycastResults) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:263)
UnityEngine.EventSystems.PointerInputModule.GetMousePointerEventData (System.Int32 id) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/InputModules/PointerInputModule.cs:295)
UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent (System.Int32 id) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/InputModules/StandaloneInputModule.cs:540)
UnityEngine.EventSystems.StandaloneInputModule.ProcessMouseEvent () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/InputModules/StandaloneInputModule.cs:526)
UnityEngine.EventSystems.StandaloneInputModule.Process () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/InputModules/StandaloneInputModule.cs:280)
UnityEngine.EventSystems.EventSystem.Update () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)
So i think it is the float text prefab
When I click on the where the canvas is on the player
Hmm... Is it a canvas without a canvas renderer?🤔
Or a ui object outside of a canvas?
Oh
Yeah. The text floats up
It would be outside of the bounds of the player cavnas
No, I mean outside like not parented to a canvas
No it is parented.
And the canvas has a canvas renderer?
Probably rollign with the asmdef trick 🙂 Thanks!
Well, it probably needs one. It's weird that it even renders without it.🤔
Yeah. I mean it is the world object version of text mesh pro
The non ui version you mean?
Yeah
Then it doesn't need to be on the canvas afaik. Perhaps that's the issue.
Not sure but i've got some testing to do. Thanks for your help.
what are you trying to do?
Fix the issue in the trace stack above. Something to do with the event system and a world space canvas
i mean, what is the bigger picture here
are these little UIs floating out in world space? what is the gameplay?
it's telling you what the error is. it sounds like you have prefabs that you have built incorrectly and you are instantiating them into hierarchy where it doesn't make sense to have them
In reproducing the error, I noticed it only fires when the cursor is unlocked and the mouse is on screen. It stops once I get out of range and the other player is destroyed, which means the canvas is destroyed.
this is all a red herring
it sounds like there are a lot of flaws.
the existence of a "Billboard" script is really concerning
sort of. you can look at keijiro's examples and ffmpegpipe.
without doing
Inter-process communication.
i don't think you mean this
hmm... it sounds like you have a lot of issues with this codebase, and based on this snippet, you have a lot of stuff going on
have you looked at edy's vehicle physics / vehicle physics community edition / vehicle physics pro?
anyway, if i recall you had a deadline that should be coming up in a week or two. if i were you, i would probably ask for more time
the purpose of my project is to build something from the ground up
I'm tired and need help guys. I have two arrays of the same length. Array A has values in it. In array B I need to store at each index the sum of all previous elements from A up to that index. I.e if A is [1,64,3] B needs to be [1,65,68]
Seems like a pretty simple for loop with an accumulator int?
Not to be that guy, but this is the type of coding question ChatGPT is very good at answering.
Is there a way to tap into every event EventSystem executes?
it doesn't look like there is. does anyone have pre-existing code to hack this in?
what's the goal?
The only thing I can think of is having a wrapper/redirect class that implements every module and sends out a notification whenever any of those modules are hit. But I'm not sure if that's what you're looking for/what you want to do?
I got 2 extra weeks, because had an urgent matter to take care of, so I stopped working on this
It’s text that displays damage numbers over a player/npc. It’s attached to a world space canvas on the character.
It actually gives a warning when you put a canvas renderer on the non UI text mesh. It says to remove it as it is not needed.
yes
https://docs.unity3d.com/Manual/ScriptingRestrictions.html
Reflection is supported on AOT platforms. However if this compiler cannot infer that the code is used via reflection the code may not exist at runtime
I've recently imported Unity.Notifications.Android and realized that I can't use capital letters in my Large icons. Fine, rename all the files, re-link them in the dialog box, but .. unity seems to have created and copied files to the \Library\Bee\Android\Prj\IL2CPP\Gradle\unityLibrary\src\main\res\drawable-hdpi-v11 folders (for each of the resolutions) and I can't get through a build.
Is there a way to force an import of these graphics assets again? Or do I have to rebuild my library (something I don't want to do because it takes forrrrrrrrrrever)
(files in the build directory have the old filenames with capital letters - although in the unity project and file system these are renamed)
update: rebuilding the asset library didn't even fix it, I just had to go into these directories and manually prune all the files.. but that worked and now my game has nice little notifications with context sensitive icons
looks clean
thanks
With TextMeshPro assets, is it possible to write a dynamic string output with colour values per line?
IE. Title of the section in red, body of section in green.
IE. Name of stat in one colour, stat value in another
I'm understanding I need to use the vertex colour, but am I forced to parse each line dynamically as well to change just that text?
I'm trying to avoid using the inspector or stacking a bunch of prewritten textmesh assets into a heirarchy, instead push it all through one output.
Thanks
You can use rich text tags: https://docs.unity3d.com/Packages/com.unity.textmeshpro@4.0/manual/RichTextColor.html
Got it working, thanks!
Is there a way to disable unity doing stuff with ADB? It keeps disconnecting my other window with logcat running, and it also keeps popping up these console windows doing who knows what every few minutes (like 5 times, instantly appear/disappear).
I'm trying to learn how to use PlayableGraph, but I'm kind of lost.
How can I attach an Animator to a PlayableGraph, and then (after a while), unattach it and return it to the normal system?
I think in order to attach it, I must do:
AnimationPlayableOutput animationOutput = AnimationPlayableOutput.Create(graph, graphName, animator);
AnimatorControllerPlayable ctrlPlayable = AnimatorControllerPlayable.Create(graph, animator.runtimeAnimatorController);
animationOutput.SetSourcePlayable(ctrlPlayable);
animationOutput.SetTarget(animator);
animator.runtimeAnimatorController = null;
Right?
But how can I deattach it later?
My intention is to optimize animators that are far away from camera by updating them less frequently. I know that animator has an update method, but that doesn't use batching and so it's single-threaded.
But I heard that PlayableGraph supports batching the animators.
I have these 2 lines of codes: Debug.DrawRay(transform.position, -transform.up * 100f, Color.red); Debug.DrawRay(transform.position, new Vector3(0f, 0f, -transform.localEulerAngles.z - 15f), Color.red);
The first ray is being drawn, but the second is not
The only difference between the two is the direction in the second one
Why is it an invalid direction? Why doesn't it work?
I realize that -transform.loc... can be -356 or something and subtracting 15 can cause it to be less than -360, but even the -tranform.loc... is something like -14, the code still doesn't work
Have you logged the value of -transform.localEulerAngles.x - 15f?
its .z, I copy and pasted the wrong thing
Yes I have though
Also you can put it in a nice -180..180 range with angle = Mathf.DeltaAngle(0, angle)
Personally I simply just find it harder to work with that range
this is the value of transform.up: (0.00, 0.00, -0.12)
This is the value of the other direction: (0.00, 0.00, -15.12)
Are they being drawn on top of each other perhaps
Maybe add a slight offset (or use a different axis) and different color
I tried that
Figured it out
For anyone wondering, drawray doesn't use euler angles, it only uses the vector angle thingy that transform.up returns
Vector3 direction = new Vector3(-Mathf.Sin(angleInRadians), Mathf.Cos(angleInRadians), 0f);
Debug.DrawRay(transform.position, direction * 100f, Color.red);```
I mean... It's a direction, I thought youre aware of that
And just visualizing the angle or something
Yes they both are directions though, but only the vector direction works
But it's #archived-code-advanced so I'm always afraid to ask the simple questions 😅
I feel you, I'm pretty much a beginner ;/
Hmm I think it's more clear when we distinguish directions from rotations
Like transform.up is a direction
transform.eulerAngles is an euler rotation
transform.rotation is a rotation
Hmm
The first two are vectors, but euler angles isn't a direction
Just pointing it out for future reference 👍
Got it, thank you
not trying to be rude - but there is a #💻┃code-beginner channel.
I considered rays to be a more advanced topic than a beginner one, that’s why I asked here
I might be wrong though.
Everything seems advanced when you are a beginner 😉
making it easier to do things like
when i click this card, put it in the spellcasting state
when i click anywhere else that isn't a target, cancel
Hi all! Today is the 3rd day as I'm trying to deal with zenject.
Such a question, if the projectContext itself automatically appears on the stage and cannot be added manually, which means I can’t just drag the necessary dependencies onto it, how can I throw global dependencies into it? Through delegates? What if the sceneContext is loaded along with the scene in the prefab?
Just put a big invisible UI element behind everything
Hello there, does anybody know about an algorithm that allows the use to draw mesh mesh edges with some given vertices?
I basically would like to connect all the vertices of a mesh in a uniform way, not like the way on the image
yeah so it goes
Hi all! I don't know if this is the right channel for this but I'd just like to ask how UnityEngine.XR is able to identify a certain part of a VR device (e.g. Head, Left eye, Right eye, right hand, left hand etc.) as either left eye of the VR device, Left hand of the VR device etc. by means of using the InputDevices.GetDeviceAtXRNode() ? The thing I'm working on now entails creating a device similar to that of common VR device available (e.g. Oculus, HTC Vive) and am currently trying to understand what unique identifier such functions look into.
You'd have to use the Triangle.NET library for this code
https://hastebin.com/share/yojumameva.csharp
1 - Attach the EdgeGenerator script to a GameObject in your scene.
2 - Assign a material to the edgeMaterial field in the EdgeGenerator script using the Unity Editor.
3 - Set the lineWidth value to control the width of the mesh edges.
4 - Add your vertices to the vertices list in the EdgeGenerator script using the Unity Editor or create the list programmatically in the script.
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
The XRNode is just an enumeration. Pretty sure you'd need a 2 step process for a custom VR device. 1 - Your device has some kind of SDK that sets up the representation of the different parts. 2 - You create a unity xr plugin that understands how to interface with your devices SDK. This is insanely watered down, but yea.
Oh I see I see. I actually tried to peek definitions and found that it was looking for a device ID. Is it correct to say that the ID comes from the OS of the device? Or does it come from a certain component within the device (e.g. ESP32, CH40, MPU6050, etc.)?
Oh I see I see I actually tried to peek
Thanks! I will take a look into it
Does anyone know how to get a facebook profile image url?
public void FbGetPicture(IGraphResult result)
{
if (result.Texture != null)
{
ProfilePicture.sprite = Sprite.Create(result.Texture, new Rect(0, 0, 128, 128), new Vector2());
}
}
are there examples combining kinematic character controller with navmesh agent?
and any authoritative docs for runtime navmesh updating? or is it aaron granberg still for the most flexible stuff? is his engine on burst yet?
i've seen setups using navmeshagent to move an invisible object to navigate and the character uses physics to try to stay follow the object while reacting to physics
did physics change a lot in 2022? when I transform.Rotate in 2021- = no problem, now i get all stutters
more of a physics question but that board is super dead
ah it's the simulation mode that changed, wow that broke a lot of stuff
transform.Rotate has nothing to do with physics.
if it's applied to a RB it does
If you're doing that to a Rigidbody you're doing something wrong
define wrong - it's always worked
rb.MoveRotation lacks Space.Self so I've never bothered with it
You can see navigation line (white line) for each dupe in oxygen not included game. I want to know which algorithm they have used. It seems it finds all path to every task (here digging)
What do you think? They have used a star from a dupe to every task point?
Even there is no task like under water, you see white navigation line.
It returns all reachable points where a dupe can move towards
To get accurate and bug-free physics you need to play by the physics engine's rules and use Rigidbody methods to move a rigidbody
Changing Transform properties directly skips the physics engine
You're right. In fact I looked at this code because I was surprised that it even worked, turns out I use transform.rotate to build rotation without quaternions math then use that rotation in MoveRotate... not the prettiest
Usually for multi destination search you use Dijkstra but in my experience A* works just as well. Especially with things like Anypath which is so blazing fast that it doesn't matter
I did not get it
In A star or dijkstra you have a source and destination
In the above picture, we have one source and one target?!
I think of flood fill
it looks like 1 source and 4 targets, 1 for each task queued up, no?
Underwater, there is no task at all
It returns all reachable tiles and connect them
oh I see, yeah Dijkstra would do a good job with that, it's like a pathing floodfill which will get all the reachable nodes within a certain cost
Thanks, so you agree on flood fill? I mean they have probably used it to find all reachable points?
I want something like it for 3d world (voxel based)
Flood fill is really expensive in 3d
It's not that bad. Check out Anypath, it has what you need, all you have to do is extend the grid graph type to voxel.
Anypath? Is it a package?
I'm doing what you're talking about, in the evaluator of the utility AI
and, like you, in voxel. fully procedural voxel environment too so I also need graph rebuild to be super fast.
or at least not show up in the main thread
My problem is not about implementation of a star
I have implemented it, it is also burst compatible
More, I would like to know what exactly they do when there are many tasks in different places.
Another issue is for each task, they show if it is reachable (white icon) or not (gray icon)
I do not think they run a star from each dupe to each task
so i have a ping pong paddle mesh. I need to put a hole in it as if a ping pong ball went clear through it, for my game.
i understand i need to play around with things like mesh.triangle
but i am struggling to find info on it
i need to (in this order)
add a ring of new vertices each equidistant from the point where the ball collided
delete the triangles in the middle of this ring
connect each ring on either side to connect the two holes
you can use poseidon CSG to cut a hole in a mesh using another mesh at runtime
this is the start of a long journey
use the asset instead
the asset?
poseidon csg
this one?
ok thx
is there a robust package to export a prefab with its script dependencies? as opposed to the default unitypackage exporter
It's pretty trivial to convert between local and world space rotations
I'm trying to optimise the performance cost of several Animators, by updating them X times per seconds rather than on each frame, depending on the distance towards player.
However, using the Update methods of Animator is single-threaded.
So I read that I can use PlayableGraph to batch multiple animators at the same time using multi-threading.
However, when doing so I notice that the PlayableGraph.Evaluate method's internal jobs are waited, leading to dead-time in the main thread... is there a wait to prevent that?
These jobs are probably essential for the animators to update, so there's not much you can do. Maybe look at the worker threads that execute the jobs and see if there's something slowing them down.
I'm trying to make a pixel writing job more efficient but it is throwing an error. ```
[BurstCompile]
public struct SetPixelsByIndexJob : IJobParallelFor
{
public NativeArray<Color32> Data;
public NativeArray<int> Pixels;
public Color32 Color;
public void Execute(int index)
{
var p = Pixels[index];
Data[p] = Color;
}
}``` ```System.IndexOutOfRangeException: Index {0} is out of restricted IJobParallelFor range [{1}...{2}] in ReadWriteBuffer.``` I assume there is an issue here with the index in execute not working how I think it should but I don't know how to fix it.
Here is the job in question public void TextureFill(Texture2D texture, Color32 color, int[] indices) { Debug.Log(indices); var data = texture.GetRawTextureData<Color32>(); var pixels = new NativeArray<int>(indices, Allocator.TempJob); var job = new SetPixelsByIndexJob { Data = data, Color = color, Pixels = pixels }; job.Schedule(pixels.Length, Math.Clamp(data.Length / 4, 1, 128)).Complete(); texture.Apply(); data.Dispose(); pixels.Dispose(); }
Alright. So there are restrictions in place to prevent race conditions in parallelfor jobs. that means that only the member of the collections at that index in available. I had to do [NativeDisableParallelForRestriction] public NativeArray<Color32> Data;
I don't think it will be an issue because the pixel array is generated from a hashset so no double values.
Is it the correct way of measuring the size of this struct?
public struct Data : INetworkSerializable
{
public Tile.TileData [] tiles;
public GridMode boardGridMode; // enum
public int GetSize()
{
int size = Marshal.SizeOf(this);
size += Marshal.SizeOf(typeof (Tile.TileData)) * tiles.Length;
return size;
}
}
Hi everyone, just a quick question. I'm working on some custom inspector code right now and quite often in tutorials I see people inside both OnSceneGUI and OnInspectorGUI do things like
if (_someEditorUtility == null) _someEditorUtility = Initialise()
What I am wondering is why are these things not just done on the Editors OnEnable function. What are the cases where the editor will trigger these render functions but will not have previously set its base state with OnEnable?
Is putting this sort of code on enable fine, or is just doing the null checks a safer way of doing it?
Some editor things require that they run in OnGUI
I suppose it's for the cases where all cashed values are lost due to domain reload, while the inspector is still enabled. I think I had this kind of issue when a few years ago I worked with custom editor windows. I don't remember if it was the case after code recompiling or after entering the play mode. I suppose you can test out if those cases cause similar issues.
Ah brilliant, thank you @austere jewel and @tropic vigil, I'll do it the OnGUI way then, I'll see about having a play around and getting my head around exactly when things are called and not but its good to know that there is valid reasons to put the tests outside of OnEnable. Thank you both.
What is the latest unity networking please?
Netcode
Does anyone know how to remove the clones after I shatter an object to pieces? https://gdl.space/hufewosaba.cs I added some logic in the beginning, but it won't simply destroy the objects for some reason.
What's the problem exactly? Removing them should be trivial compared to generating the geometry
Not an advanced topic. Just call Destroy on them. You're only destroying the object with this script right now
Whenever an object that has this script shatters into pieces when it reaches a certain height, I want the clones to be destroyed after a few seconds. I wrote down this logic to see if anything would happen, but it won't simply destroy the clones.
I'm not sure how to write it in code though 😅
Destroy(theClone, time);
I'm building a digital circuit simulator and have a question.
What data structure would best represent a circuit? a linked list of the component gates, considering the way circuits are sort of in a loop? or? I was also suggested to just save the state of the circuit as a struct and pass that about but I'm curious what y'all thought.
tho maybe I don't even need a list of the components or how they connect, and I just save the state as a struct, or simpler, as a variable called signal that literally tracks if its 1 or 0 at some given point and update as the simulation runs. big hmm lol.
Well, depending on your needs and specification, I would use standard classes with the help of polymorphism to construct the representation in a graph shape. This way, you would have high flexibility to accommodate any extra needs such as UI, editing tool, etc.
That being said, if you plan of having to deal with high numbers of circuit and you require performance, you should definitely try to come up with a representation that holds all the data sequentially. I do not know the specifics of digital circuit, but it would not be strange if you could express all of the require information in a tight representation with little to no "building" blocks such as how NP complete problems can be resume in [Variables, Not, Or, And, Parentheses]. Such representation could be easily hold in sequential data structure with the help of a little bit of work.
(But like, I said, I do not know your needs nor the subject you are simulating, which make it hard to find an appropriate solution)
Here a link of the first thing I found on the subject: https://codeahoy.com/learn/analysisofalgorithms/ch27/
Noice, thank you for this 🙏
it feels classic how this all leads back to np-completeness lmao
and ofc my idea of a signal variable is basically a statemachine with punch tape returning 1 or 0 looool
is circuit satisfiability really np-complete?
I think so. I've not really studied NP-Completude, I can not really help you there.
there is those millenium math problems from the clay math institute, but thats a bit tangential to this channel. anyway, thanks for the lead
when performance is a concern, you should check if you can model it all in a bunch of dense arrays, a sparse set or DAG, many very efficient algorithms exist for those
perfect
note that all graphs can be serialized to an array representation, an architecture where a each node is an object will be the worst case for performance but best case for abstraction/UX
you should maybe set a rough performance target and find an implementation that can potentially achieve that target, then don't worry about performance until the thing works.
yeah good point lol
Does anyone know how I would save & load instantiated prefabs and their transform values with JSON? I made my own JSON saving system but I'm struggling to find any answers online to this.
In my game you put down stickers that are instantiated which can be moved, resized and rotated. How would I save them with JSON?
I'm assuming it would be something like saving a unique ID per instantiated prefab together with their position, scale and rotation in a list which instantiates them on load but I'm struggling to do it in practice as I'm pretty new to JSON and saving in general.
Any pointers or examples would be super helpful 🙂
Yes, you are on the right track. You can save the instantiated prefabs and their transform values using JSON by creating a data structure that holds the necessary information and then serializing it to a JSON string.
Here is an example of how you can do this:
Create a data structure to hold the prefab and its transform values:
[System.Serializable]
public class StickerData
{
public int id;
public Vector3 position;
public Quaternion rotation;
public Vector3 scale;
}```
Instantiate your sticker prefab and populate the data structure with its transform values:
GameObject stickerPrefab = Resources.Load<GameObject>("StickerPrefab");
GameObject newSticker = Instantiate(stickerPrefab, position, rotation);
StickerData stickerData = new StickerData();
stickerData.id = newSticker.GetInstanceID();
stickerData.position = newSticker.transform.position;
stickerData.rotation = newSticker.transform.rotation;
stickerData.scale = newSticker.transform.localScale;
Add the data structure to a list and serialize it to a JSON string:
List<StickerData> stickers = new List<StickerData>();
stickers.Add(stickerData);
string json = JsonUtility.ToJson(stickers);
Save the JSON string to a file:
string path = Application.persistentDataPath + "/stickers.json";
File.WriteAllText(path, json);
To load the stickers, you would read the JSON string from the file, deserialize it back into the list of StickerData objects, and then instantiate the stickers using the saved transform values.
@raw arrow answer works pretty well. If you want to push a bit further, you can also create and inherit from a custom interface and then use the said interface for the initialisation of all MonoBehaviour that inherits from the interface.
Here is a following pseudo code that manage the serialisation of both, scene and instantiated objects. There is multiple way of doing this, each with pros and cons. Notable alternative would be: Usage of struct (DTO), Usage Attributes (Reflection), Usage of BaseClass (Instead of Inheritance), etc.
public interface MyNameSpace.ISerializable
{
public string InstantiatedPrefabID(); //Null if object is SceneObject
public string Id();
public Dictonnary<string, object> Serialize();
public void Deserialize(Dictonnary<string, object> values);
}
public class MyComponent : MonoBehaviour, MyNameSpace.ISerializable { ... }
public class MyNameSpace.Serializer
{
public void Serialize() {
//For all MyNameSpace.ISerializable
//Serialize
//Add InstantiatedPrefabID and ID to the serialize data
}
public void Deserialize() {
//For all Data
//Find all MyNameSpace.ISerializable
//If data has an InstantiatedPrefabID associated then
//Instantiated the corresponding object and deserialize
//Else then
//Deserialize into the corresponding object
}
}
And source generators of course 😄
Any examples of when a source generator would be useful?
Source generator just generates code for you depending on input, so really you can use it whenever you want to generate any code, especially repetitive ones.
Depending on what you mean by source generator you could use one for:
- Reducing Boilerplater Code
- Adding Functionality
- Optimise Code
- Maintain Code
- etc.
That being said, in most case, you are better without it.
What's mentioned above of adding attributes then using runtime reflections to inspect the attributes to de/serialize data, could be done exactly the same: adding attributes but instead using source generators to generate code that does the de/serialization, so you get the best of both worlds, simple code and no slow runtime penalty.
Are you suggesting one would be able to bypass the reflection then by using a source generator?
What do you mean bypass ?
Yes, you can generate literally any code.
Not use it
Why use reflection to access a property, when you can just generate code that does the accessing directly?
😉
Yeah, you won't need reflection. You could use it for Generating Code though
Code Generation is whole world in itself which can sometimes lead to unpleasant things.
Not necessarily
"can sometimes"
Thank you for your answer. I got your example to work the best except how would I update the transform values of each separate sticker during runtime to the correct data structure?
Source generators can only add code, but never edit/remove existing code, that constraint by itself is enough to make it much less error prone than things like C++/Rust macros.
IL weaving on the other hand, does allow you to modifying existing code, and that's when things can get ugly really fast.
Code Generation add a "Magic" effect to codes as the user might not understand exactly how the engine works.
Code Generation can sometimes fail, which can lead to a whole bunch of issues.
Code Generation requires maintenance through the whole project.
i have a bunch of coroutines basically functioning as timers that wait until a certain object has collided with another object. is there a performance difference between doing yield return null and yield return new WaitForEndOfFrame or can i just pick whichever since it isn't doing anything in the meantime?
I wouldn't say it's very magical, everything it generates can be inspected.
It's not like Update where it's magically called, code generated by source generators exist in your IDE and you can look it up.
To update the transform values of a sticker during runtime, you would need to find its corresponding data in the sticker data list and update its values:
StickerData stickerData = stickerDataList.Find(data => data.id == sticker.id);
if (stickerData != null) {
stickerData.position = sticker.transform.position;
stickerData.rotation = sticker.transform.rotation;
stickerData.scale = sticker.transform.localScale;
// You can also update any other properties of the sticker data here
}```
yield return new WaitForEndOfFrame creates and Object each time it is invoke which could slow down considerably if the coroutine is called a lot. It can be prevent by caching the object. But, as far as I know, yield return null and yield return WaitForEndOfFrame have the same results.
That being said, I would try to come with alternative if the coroutine is something that is used often. I've seen ugly usage of coroutine. StateMachine and Update (with Time.time) can most of the time works correctly.
I do agree debugging source generators sucks though, it's still one of the biggest DX pain points.
ok thanks i'll check all that out
It is magical in the sense that it is not a conventional way to work.
And you can't reference a SG project directly in Unity, you have to rebuild the project and copy over the dll every time you make changes, which is also a pretty significant downgrade to how SG works in regular C#.
Which makes the process of introducing new team member harder.
I don't see how that's different from "Update method of MB gets called every frame magically"
It is magical, I wont say otherwise, but at least it is pretty well know and documented which is not the case for most Code Generation solution made InHouse.
Hi can someone help me
The size jsonByte is smaller than the results of Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(GameLevelBuilder.GameLevelWithDefaultValue()))
If you see a .Serialize() method that doesn't exist on the class, you can just click it in your IDE and it takes you directly to the code that's generated and you can inspect it, your source generators can also directly document there "this is generated by XYZ because you decorated the class with GenerateSerialization attribute"
I do see your point though, you can expect new members to already know Unity has magical Update, whereas inhouse SG needs to be introduced, and inhouse stuffs tend to lack docs.
Exactly. That is what I am trying to say.
And yes, you can always make the whole process of Code Generation clearer. Unfortunately, we sometime do not have time/resources for that.
I think SG is under utilized, source generation sounds scary but people using other languages routinely work with them daily; just like any power feature, it comes with great responsibilities, anything can be abused if you are evil enough.
If anything though, if you have editor scripts that generate source code, that's potential place to be replaced with SG.
I tend to prefer solution that requires less engineering from my part. If I wanted to make an engine I would have done that instead of a game.
There are places where it makes sense to use, the original question is a very possible use case where you have to choose between verbose source code or runtime performance penalties, but SG can get you both.
I'm not sure how exactly the first line of code works and where I would put this? Thanks for responding again
Sorry I cant understand can you check again my post
The error means that the value you assigned to your MemoryStream is being changed (Increased) by the usage of cryptoStream.Write which is an operation that is not supported to this particular Stream. To resolves your issue, you probably want to, first, evaluates Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(GameLevelBuilder.GameLevelWithDefaultValue())) then create your MemoryStream with the appropriate size which would prevent the "increase" of the MemoryStream.
That being said, I have no directly knowledge on the usage of CryptoStream and pretty limited usage of MemoryStream. I have applied simple deductible reasoning from the given codes and Google Research results and not tested it myself.
It's ok thank you for the additional assistance 🙂
"Entities☕ "
oh right, didn't see my room was switched. Apologies.
"having a working game doesn't matter"
yield return null does not allocate the others would due to boxing and unboxing
have you ever seen CryptoStream work in a standalone player build?
i'm not sure it is supported
the way you are setting this up seems odd
you are not using a canonical key format
which means you might not know what you are doing
you are doing something very strange
why did you call it decryptionStream
that's cool
there's good preëxisting literature on this
have you lööked at it?
maybe there's an open source circuit sim
something something, EAGLE
this is worth posting to the unity forums on the appropriate playablegraph topic and pinging a unity developer. it should be possible to manually and non-synchronously call animator loops
This line of code uses the List<T>.Find method to search for a StickerData object in the stickerDataList where the id property is equal to sticker.id. It then assigns the resulting StickerData object to the stickerData variable.
Assuming that you have a list of StickerData objects and you want to update the transform values of a specific sticker with id, you can use this line of code to retrieve the corresponding StickerData object from the list.
Once you have retrieved the corresponding StickerData object from the list, you can update its transform values with the values from the sticker game object.
Marshal.SizeOf yes, tho you need to be aware that the size returned is from unmanaged type, it can be different with managed. proly you want sizeof instead
Can anyone point me to the settings Unity uses to get the paths to its assembly references?
I have a project that uses one path in Assembly-CSharp and another path in any projects created by my asmdef files.
C:\Program Files\Unity\Hub\Editor\2022.1.0f1\Editor\Data\UnityReferenceAssemblies\unity-4.8-api\mscorlib.dll
vs
C:\Program Files\Unity\Hub\Editor\2022.1.0f1\Editor\Data\NetStandard\compat\2.1.0\shims\netfx\mscorlib.dll
If it makes a difference, I started this in a 2021 LTS release and changed the editor version in Unity Hub to launch with 2022.1
Of course: as soon as I posted that question, I found the field I wanted. Edit -> Project Settings -> Player -> Other Settings -> API Compatibility Level. I switched it from .NET Standard 2.1 to .NET Framework, and Unity rebuilt the C# solution to use the newer assemblies
That explains why my asmdef projects got the 2.1 assemblies, but I'm still confused about how Assembly-CSharp got the newer assemblies at all 🤔
not much but a little. I've been looking around on google and there's some good stuff for sure!
O.O <- mfw looking at the cost of EAGLE lol
also ofc theres games like Retro Gadgets that I could model my digital circuit sim after, but idk, I don't feel like thats as a cool as some like say...
I really want to use procedural generation to like... create circuits that have to be fixed but THEN i'm basically workin on an algo for circuit satisifiability lol
So I'm trying to use a pool of objects.
To avoid instantiating and destroying objects during runtime.
I've done this basically.
Now the "terrainFloor" Game Object has multiple children.
It seems the children are just not moving when I change the position of the TerrainFloor.
Red gets moved, Blue doesn't.
When you move an object, all its children should move as well. Probably other script is changing their position. Do you have any script that could affect position of Grass and Fence?
Sadly that wasn't the case. It ended up being that the objects under Grass and Fence had a weird Static (-) flag. @tropic vigil
Unfortunately sizeof doesn't work due to the non-constant size of the struct (I suppose it's because of the array inside).
Huh?
Array size has nothing to do with struct size afaik?
Since arrays are stored by reference.
And you can just jump into the unsafe context: unsafe { }
I was trying to get the total size of the struct, so I could create a buffer of its size before sending its serialized version through the network.
Yeah but arrays in the struct are stored by reference.
The struct just stores the reference to the array.
sizeof for structs only works in unsafe context anyways last I checked.
I can't send references through the network, because each client has different references, therefore I have to fully serialize each layer of the struct including arrays.
I'm not saying you can send references.
I'm telling you how structs work in C#. What you're instead looking for, if you're trying to send the whole struct, is to use a NetworkStream.
Write the data of the struct to the stream.
On the recipient side, read the data of the struct from the stream.
It doesn't seem to work on instances. Since every struct has array of different length I gotta calculate it manually.
I'm using INetworkSerializable in this case. Works well for ClientRpc as long the data isn't huge.
public struct Data : INetworkSerializable
{
public Tile.TileData [] tiles;
public GridMode boardGridMode; // enum
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref tiles);
serializer.SerializeValue(ref boardGridMode);
}
sizeof works only on compile-time known types, wont work on instances, yeah
Mate, arrays have nothing to do with struct sizes. In fact, I can create a struct with an array in it for you right now, and it'll figure out the struct size, because arrays are always stored on the heap in C#.
struct X {
int n
int[] k
}
The above struct has a fixed size: 4 bytes for the integer, 8 bytes for the reference to an array. 16 bytes total (4 bytes for padding).
I understand that arrays are stored by reference. You missed the point of my problem through. I need to declare the buffer size for CustomMessagingManager before starting to use it to serialize the struct recursively and send it to the clients. Everything will be wrong if I don't include the size of the serialized array itself.
Yes. That's true.
Which is why I suggested you a better solution entirely.
And one that is used more popularly for game development and everything else.
NetworkStream
This code compiles.
This is the ASM.
This is output.
but that requires to enable unsafe mode in the editor, but should be fine
You're referring to type, not an instance. As I said you're giving answer that totally misses the point of my question.
Huh? I literally made a struct just like you did...
instance =/= Type
aight Im a bit lost here.. you both can continue 🥳
I'm just as lost...
I need to get the size of an instance, because every instance has different size, so I need to calculate size of each instance individually, so I can't simply check the size of a type.
Yeah, what you're doing this isn't a solution for.
I'm correcting you where you said since every struct has a different size.
I ain't gonna declare 16 byte buffer for an array that has size 1000.
Because structs don't have different sizes. Size of a struct is fixed, and determined at compile time.
What you're trying to encode is an array.
Arrays are not structs, and it's best not to confuse them with structs either.
I already encoded an array. Everything work flawlessly on ClientRpc. I just need to get the size of serialized struct.
Arrays are objects, which means the struct only contains a reference. Therefore, what you should instead do is this:
Is Tile.TileData a struct?
Can you show me that ^?
Yes. A serializable struct with instructions on how to serialize, thats is why serializing Board.Data works and I can receive properly serialized struct on another client.
Okay, can you show me what TileData has?
Like take a screenshot and post it here.
I can give you a solution to finding the serialized size.
[Serializable]
public struct TileData : INetworkSerializable
{
public int id;
public int x;
public int y;
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
{
serializer.SerializeValue(ref id);
serializer.SerializeValue(ref x);
serializer.SerializeValue(ref y);
}
}
nice. good.
so in your Data struct's NetworkSerialize<T> method, serialize the size like so:
unsafe {
serializer.SerializeValue(tiles.Length * sizeof(TileData));
}
And what's it supposed to do exactly?
How is it anyhow related to my original problem?
Why am I serializing it?
For one thing, I have no clue why you have Data as a struct. Because it gives 0 performance benefits to having it as a struct instead of a class when you literally throw an array inside it.
Secondly, the only reason I imagine you wanna get the size of it (including the array referenced inside), is so that you can send it over the network so the other side knows exactly how much data to read. Which is what this does.
I have it inside of a struct to serialize it. Netcode doesn't accept classes in [ServerRpc] and [ClientRpc] calls. I need to calculate its size of it so I can be sure I can declare buffer size for CustomMessagingManager which is unrelated.
IF for whatever reason you don't want to send it, then here you go:
public unsafe int SizeOf() => sizeof(GridMode) + tiles.Length * sizeof(TileData);
Use this then ^
This will give you full size (in bytes) of public struct Data : INetworkSerializable
Also your problem is literally the definition of a XY problem: https://xyproblem.info/
Asking about your attempted solution rather than your actual problem
My problem was declared as follows:
still considered XY problem, and I gave you solution up there.
.
Your solution returned 19204. Mine returned 19216. Definitely one solution has to be wrong.
Are you wanting to encode the data and the reference? Or just the data? (You mentioned you don't wanna send the reference)
If just the data, then mine is correct. If you want reference too, then 12 bytes (8 for reference, 4 for padding) added on top of mine = 19216
Here you said you don't want to send reference.
Marshal.SizeOf(this) includes the reference size as i mentioned (8 bytes) = 19212 ... and then since you have a 64-bit computer most likely (reads in registers of 8 bytes), 4 bytes are added as padding (will be zeroed out bytes).
in terms of actual data you wanna send over the network, 19204 is the correct amount of bytes.
I would like to ask in a bullet hell game (lets say more than 100 bullet at the same time), which approach would you guys implement to detect collision of bullet to achieve maximum performance? 1. trigger collider 2. raycast 3. constant check of each bullet distance from enemy. Anyone has such experience?
I've tested it by trials and errors. Looks like the number I need was 19208. Smaller numbers resulted in an error. So looks like the original solution wasn't the optimal one, but at least passed.
The number you needed was 19208 because of padding.
You could just get the size, take 8 - (size mod 8), and add that on top of that, and bingo you got padding.
Raycast provides maximum performance, especially if bullet is fast enough that it's undodgeable.
Collider is next, but depending on speed of bullet, certain things will need to be enabled to make sure it properly detects collisions in Unity.
Checking distance is the slowest.
By raycast, I mean calculating vector in the direction of the bullet, and seeing if it intersects the character.
Not whatever other raycast one may think of ^^
That sounds even worse than distance checking
can you explain more?
Of these options only #3 is actually a technique.
Raycasting requires colliders so I'm confused about what the difference between, 1 and 2 actually is
my thought on raycast is the Physics2D.Raycast
"raycasting" is also vague
From what to what and why
Trigger Collider is also vague. Simply having colliders is not a complete collision detection strategy
So you'd have to be more specific
It isn't. It's very simple math. You have the bullet's velocity vector, find two points from the velocity vector, formalize a line, and see if you (bullet's target) fall on that line (check if by substituting your x, you get the necessary y).
For 100 bullets, this code would at max take 500ns.
Sounds like more calculation than a sqrDist check
SqrtDist would happen every frame update
this happens once
?
- doesnt require collider but need to calculate distance in the update function or fixedupdate
- attach an collider in every bullet and make it trigger and use OnTriggerEnter to damage
- use RayCast in update to detect any enemy
Assuming the player never moves
Again, the assumption is the bullet is so fast that the player never gets the chance to move.
.
OnTriggerEnter is the best. It's the only one cutting down calculations with a spatial acceleration structure
Have you ever played a bullet hell game?
Weird assumption to make
No, I haven't. Which is why I specifically stated that assumption in the answer.
normal speed, which player can dodge
The gameplay of bullet hell games is all about dodging the bullets.
They are games with slow moving dodgeable projectiles
Spherecast seems to be more suited to this genre since bullets are usually quite big and slow.
Then, raycast isn't maximum performance. As Praetor mentioned, the best thing you can do there is check distanceSquared. No need to take the sqrt, if you're going to collide, distanceSquared will also be 0.
I know unity physics system has some optimizations included. I would suggest simply implementing different solutions and then comparing performance with the profiler.
Sticking by this
Be more specific in 3, this is used in FixedUpdate ()
GameObject[] bullet = GameObject.FindGameObjectsWithTag("Bullet");
float cRadius = cs.property.hitRadius;
Vector3 dis = bullet[i].transform.position - character[j].transform.position;
if (Mathf.Pow(dis.x, 2) + Mathf.Pow(dis.z, 2) <= Mathf.Pow(bRadius + cRadius, 2)) { hit();}"
This is garbage collection hell, not bullet hell
XD yep
ok
LOL thank you two
the amount of arrays that'll need to be GC
my god...
Usually, you'd have an array of bullets and reuse that.
To avoid instantiating them and then destroying afterwards.
I know, i have object pooling
In which case, then the distanceSquared solution I mentioned would be best.
just want to be more specific on how to calculating distance
the issue with your code here for GC is specifically the call to FindGameObjectsWithTag
It allocates an array that'll need to be deallocated right after.
Making the method a GC nightmare.
If you store a list/pool of all the bullets and just pass the list instead, you could have much faster code.
Btw, Vector3.Distance seems to be optimized, so it can be used as an alternative to .squaredMagnitude:
https://youtu.be/Xd4UhJufTx4?t=182
Find what common Unity optomizations truly make a difference. In this video I go over a bunch of interesting optimization tips as well and give you my recommendations on each.
Keep your code running fast with as little garbage allocation as possible by learning from these important concepts.
Benchmarks (let me know if you get weird results!):...
And use my distanceSquared approach.
how is Vector.Distance more optimized than distanceSquared?
to calculate the distance, you literally have to sqrt(distanceSquared)
which is an extra step no matter how you try it
even with the fast sqrt approximation code.. it still is extra instructions
Never said that.
sometimes it is slightly faster according to benchmarks. the difference between the two ways is so negligible it cannot be considered good optimization tip to use sqr distance. on low end devices it may be valid way but on high end CPUs square root is just so fast it doesn't matter
hi, i'm looking for an open source news feed to add to my unity social platform, does anyone know if i can get a completed project on this ??
looking for a way to create local co-op in unity without the new input system
need a way to make it so each player prefab only accepts input from 1 input source, so the specific controller i somehow assign to it
There is a lot of API for well know media outlet. If you want access to a special news feed, you will need to find out if they have an API. If they do not have or do not want to give you access, you will need to make a sort of Web Crawler for the specific site. Beware that such practice could be unethical (even illegal) depending on the usage you do with the information. https://en.wikipedia.org/wiki/Web_crawler
https://developers.facebook.com/docs/?locale=en_US
https://developer.twitter.com/en/docs/twitter-api
https://www.tumblr.com/docs/en/api/v2
https://discord.com/developers/docs/intro
https://en.wikipedia.org/wiki/List_of_news_media_APIs
So I asked ChatGPT for help on my digital circuit sim and its answer was suprisingly sound lmao. this whole.. ai assistant thing could slap
@frank peak Please don't post off-topic here.
sorry
this isn't true.
whatever benchmarking utility you use is flawed FYI
or your testing case is flawed (constant propagation, assembly determinant, etc.)
Tip #1 is to not trust benchmarks posted here 😛
Hello there, does anybody know of an algorithm for checking between mesh vertices distance? I want to basically check if a vertex is close enough to another and then perform my logic
An algorithm? You mean the < operator?
Doesn't seem like an advanced topic.
I'm guessing they're looking to optimise checking through all vertices in a mesh
You'd have to explain the access patterns.
Quadtrees might be helpful for you
If you are doing this query over and over on a single mesh, and want to do something like get all vertices close enough to a given position, you can build a spatial acceleration data structure like a QuadTree
Or looking up triangles edges and check those edges first sinec in most meshes those would be the closest
I mean how to check if a vertex distance is less to a threshold I set so then I can perform my logic
literally just with the < operator
if (distance < threshold) DoStuff();
again not an advanced topic
But how do I iterate through the array of my mesh and do this operation? , is it like this ? if (math.distance(meshVertices[i], meshVertices[i + 1]) < 0.05f)
{
The way you worded your question didn't imply any iteration
what kind of iteration are you looking to do
which vertices are you wanting to comparing to which?
I want to loop through all my mesh vertices and check their distance, I pretty much want to remove vertices if their distance is less or greater than a specified threshold
less than a specific threshold of distance to WHAT
some specific vertex?
Some specific position?
All other vertices?
All other vertex positions
this should work for me, Im calling this function just once
on start
I dont think it needs to check every node either
is there in the world any reason to use dijkstra instead of A*?
like i know A* is basically dijkstra that's greedy
Djisktra will give you all shortest paths to all points on the graph. A* only gets you the path to a single destination
but nonetheless i find dij useless
dij checks every posibility, no?
as i know and have written A* takes only the shortest vals
A* is little more than Dijkstra with a heuristic function and a specific target node
ye
It doesn't check every possible path, but it does visit every node
it must
since it builds ALL shortest paths
i said it wrong
goes trough
but for shortest path i mean
since finding the shortest path is what people need most of the time
Djikstra is very useful in a situation where your graph doesn't change often but you want to get the shortest path many times
I dont think it needs to check every node either
You can run djikstra and cache "signposts" to the next node on each node
then it becomes O(1) to do navigation from any given node
this is more or less how I do navigation in my tower defense game
oh cool
it's much faster than doing a full A* run for every enemy every time
yea, that's where i wanted to get
for my npc's or enemies i am using A*
and i am doing an A* every time
for them to catch the player when he is in radius
so you sayin dij is faster for changing graphs?
@sly grove
No the opposite
if you have to re-do dijkstra because your graph cahnges that's a heavy cost
for graph and target both are not change, just run djikstra once and store direction to target at every nodes
yea, alr
i thought A* was better for both non changing and changing graphs
guess i was wrong
Basically djisktra produces one of these: https://en.wikipedia.org/wiki/Shortest-path_tree
And A* produces only a single path.
So it depends what you want/need
As I said the difference is very negligible, so it was in the video the other guy posted. Feel free to test yourself and not just say its not true because ”distance requires one more step”. If you expand the sqr distance check down to float math, it will be about 30% faster than distance but having to do Vector3-Vector3 somehow makes them about equal in speed. I dont know what exactly is causing that but maybe it has something to do with making copies of the struct values or something like that. Vector3 functions like Distance avoids doing vector operations because: current scripting backends are terrible at inlining
yea, why would i ever want all the shortest paths
curious
I have tested it myself.
return Mathf.Sqrt(x) is slower than return x.
You should use an actual statistical library to do proper benchmarking.
I can give u the assembly too for the benchmarks if you'd like
and you'll realise it's 2 extra instructions.
sqrtss & add
I dont think you can use benchmarkdotnet in unity, not easily atleast
Sqrt should be comparable to doing a division. Not really something that you need to think about it when you are doing "gameplay" for High End devices. (Yes, it is still a division that you do not need)
I'm guessing it was more an academic point that it can't be faster to do more operations, rather than something worth worrying about
Maybe, did not really follow. I just know that some people are obsess with these facts and I had to find out myself to clarify it with one of my colleague. I'm relaying information that I found while having a similar discussion.
The conclusion is:
- Define Style Guide Rules for these situation. (Readability-Debuggability vs Performance)
Hello everyone, I have an issue I cannot comprehend as it only occurs for one player that I know of. (The game is on Steam and was added as a zip file)
I have a slider to select value from min to max
The script is in two parts (normally linked as .txt) :
LinearValueSelectMain
LinearValueSelectValueLimited (which inherits from LinearValueSelectMain)
Here the value is between 0 and 1.
To show the selected value, the script checks how many digit after the period there is in the correct value. So for 0,21, it will show all value as x,xx.
It has always worked until a player told me they were only seeing 0 or 1. I have absolutely no idea why it would work for most people but one?
I asked the player to send me the log file which made me wonder if it could be possible if the correct value could be "lost"?
(I forgot to add the correct value in Debug.Log, I may ask the player to get me the log again if needed)
So, normally, the log should look like this :
PathDrive : GetValuesMinMax()
PathDrive : GetValueMinMaxPathDrive(), digit after , 2
PathDrive : update with new value : 0 as : 0,00
But for this player, it looks like this :
PathDrive : GetValuesMinMax()
PathDrive : GetValueMinMaxPathDrive(), digit after , 1
PathDrive : update with new value : 0 as : 0
The theory I have at the moment is that data got lost (because why would the script works for some, but no all?). If the correct value is lost, it will be at 0, so it would show nothing after the period in the selected value. Is it possible?
What could it be? (modifié)
The point is that it's a slower operation than just returning the value. And there's no way around that. No computers are optimized enough to make it completely negligible in nanoseconds.
this code is really complex. what are you trying to do?
i understand there is a bug with it
there might be many bugs, it's very complicated
it has bad starch
also what do you mean "normally linked as .txt" ?
it sounds like you are trying to author a slider that is interactable in fist person 3d / VR
can you show a screenshot?
is it used as part of a puzzle game?
why is there a rotationdrive?
The way it should work is:
it has a min value : 0, a max value : 1.
The correct value is given from the inspector : 0.21.
The player select the value by dragging the slider, from 0 to 1.
To show the selected value to the player, the script takes into account the number of digit in the correct value, here 2, and show that much of the selected value (so instead of showing 0.454511354, it filters to 0.45)
It worked for all the testing I did, it worked for 5 players that played from steam (on different computer, etc).
But, one player, told be they would only see 0 or 1
I really have no idea how the script could not run the same way for 1,
the normally linked as .txt was for to inform the big scripts where linked at the end
It is a slider for VR and non-VR, using SteamVR scripts (from the log I got from the player, it gets the update linear value as it should)
It is indeed a puzzle game, an escape game
And this script is for the PathDrive (inherit LinearDrive from SteamVR) and Rotation Drive, that's why it's there too, but will be ignore as the object only has a as pathDrive component
I'll send a screenshot in a sec, just time to make it
They might be using a computer which does not use the comma as a decimal separator
Which is, most of the computers in the world
Values can be rounded culture-agnostic using a format string you pass to ToString. num.ToString("F2") - the number denotes the number of decimals, adjust to show more or less
Or, if you need the value as a number instead, say you need two decimals, multiply the number by 10 (to shift the decimal sep by two places), round to the closest integer, then divide by 10 to get the original number back, rounded
@regal olive
I see... So only french people can play my game to the end, thanks a lot ! I'll update my code, and get my American player to test it again (hopefully, this time it will work smoothly), do you want to let you know if that worked?
Yeah, the French and a few other cultures that use a comma. But issue aside you should not manipulate numbers like this, there's always going to be a way, built-in or not that works on all cultures.
And yeah, let me know if that did the trick
I have to be honest, I was far from thinking that comma is not used by all... I'm going to write it on a note and stick it on the wall to remember it. Now that makes totally sense why it's bad practice... I'll probably do a deep review of the rest of my code to make sure I'm not doing it elsewhere. Thanks again 🙂
It is negligible... A modern CPU does more than 30'000 Million Instruction per seconds. Adding 1 instruction that does not require to load memory won't change anything. In fact, it is near 30 instruction per nanoseconds which means that it is negligible.
That being said, it is true, that adding an instruction will always be slower than not adding one. That being the case does not mean that adding an instruction is not negligable.
Most people say to avoid SQRT because, in the past, it was a lot slower. This is not the case today.
In my opinion, for a gameplay developer (not Engine, not Graphics), such decision are of the nature of code style and should be treated as such.
https://en.wikipedia.org/wiki/Instructions_per_second
https://developer.arm.com/documentation/uan0015/b/
i recently had a compute shader that got 300% faster after not using a sqrt but fast inverse sqrt statment.
its rare but if you run something a LOT than it might make sense looking into it
Which is part of the Graphics category I was talking where it is matters a lot.
any piece of code in a shader also (potentially) runs 495072000 times per second
I'd actually love to see how you implemented the test. So far I haven't found any way to "properly" benchmark my C# code in unity, with console applications BDN is really helpful but it won't work with unity. I'm really curious to know if there is some way to make proper benchmarks in unity relatively easily (this just shows that the ways I have been doing my tests isn't really the right way. I didn't mean to say that using Vector3.Distance is faster in general, just that the difference according to my tests (which may be flawed in many ways ikik) is so small that it sometimes was even faster)
For one, it is not directly comparable to the throughput of division. That was a misconception you had.
On modern CPUs, and The latency typically ranges from 10-20 cycles, and the throughput ranges from 2-4 cycles. On older CPUs just as far as the 7th generation (2017 CPUs) Intel, the latency goes down to 28 cycles on certain ones, and the throughput up to 8 cycles.
Overall, that's as slow as a branch prediction miss, which has been a well known as an optimization target when optimizing game. The discussion isn't whether it can be just left in the code or not. The discussion is whether it should when a simpler, faster alternative is available with 0 added complexity. And that's frankly, a rhetorical question.
If you care about performance, remove it. It's practically an always occuring branch prediction miss. If you don't care about performance, then why are you even optimizing? Why would you even think of what is faster? Just make your code a performance nightmare, and as long as it works, it's fine.
It's a bigger difference on lower end devices by the way. The performance of square root instruction has improved greatly recently.
I have but I dont think that is the best way to measure performance. I think it just executes the methods x amount of times and measures the time difference, same would be achieved with Stopwatch which isnt enough in this case, atleast I cant find any information about the test framework that confirms it uses some proper method to benchmark
Did you even look at the documentation I gave you ? It clearly shows that FSQRT and FDIV are similar in both Latency and Throughput. It is true that on older generation CPU, SQRT might be worst, but you need to go far to actually see a difference where it starts to matter from a Gameplay perspective.
There are valid reasons why you would want to do the SQRT:
- Increase Readability (Whenever you mean to calculate a distance, you should calculate a distance)
- Increase Debuggability (Whenever you are keeping logs or even just inspecting variable, it is way easier to understand the content of what you are dealing with)
It is not about not caring about performance, it is about what actually matters or not. Whenever you are doing Gameplay, not Graphics not Engine or any other form of high computation programming, you should not care about performance that are negligible and should instead care about readability and maintainability. Also, when ever you have performance issue, you profile. And 100% of the time, not even an exaggeration, it is going to be because of something else. Removing a SQRT won't even be noticeable in the profiling of your game.
At the end of the day, the difference in both readability and performance is negligible and if you really care, you should define what is better for you in the code style of your company to keep an uniformity across your code.
https://www.quora.com/How-do-computers-calculate-square-roots
https://www.agner.org/optimize/instruction_tables.pdf
https://developer.arm.com/documentation/uan0015/b/
- You provided ARM documentation, which isn't the same platform for every CPU chip. It isn't the case for every CPU chip. And no you don't need to go much far, just go as far as the 7th generation Intel Chips and the overall speed decreases by 50%.
- The valid reasons are complete bullshit. As far as readability is concerned, you can just add comments explaining and every other future developer will know just as well. And as far as debug-ability goes, you can log the square root of the values. Most IDEs allow you to evaluate expressions when using the debugger, and say you use "Debug.Log" for debugging, just have it log the square root of the values.
- And it does MATTER. It doesn't matter to you because you don't really wish to optimise your code. Branch prediction failures, which take the same amount of time, are something developers of world-renowned game studios optimise away and notice at times massive speedups in their games. The same thing such as vector math, which will likely run before/after every frame in your game, would give you a huge speedup if you properly optimise it. Hence, why it does matter.
And stop linking me these documentation when they're literally useless to what we're discussing. Especially Quora documentations.
How many SQRT you need to remove to save 1ms ?
That's exactly my point. 1 SQRT removal could save you 30ms.
No, not in gameplay
No, because you won't have this amount of SQRT.
Yes, you will.
What you would do to have this amount of SQRT ?
That's exactly what I'm telling you, you're so far in your head with your own experience that you disregard every other possibility.
I'm not even talking from experience.
What you would do to have this amount of SQRT ?
Unity's OnUpdate() method runs every frame - on a device that can keep up a FPS ratio of 244FPS, that's a new frame every 4ms. Say your CPU has a clock speed of 4GHz (a very good clock speed), every CPU cycle would take 0.25ns. Moreover, lets assume you are doing about 100 SQRT operations for distance calculations per frame (usually there are more happening in games - and this is just gameplay, I haven't gotten into the engine/graphics area). That's about 500-1000ns added time. Given they are happening each frame every second, they're slowing your game by 122-244μs every second. Over the course of 5 seconds, your game has slowed down by 0.61-1.22ms.
Now, since we're considering FPS, 4ms + (122-244μs) = 4.122-4.244ms. So instead of your game running at 244FPS, you're now losing 2-6 frames and running at about 242-238 FPS. Have more of this stuff in maybe a loop, and that's even more frames you lose (just for gameplay reasons).
Not to mention, the above calculation was with consideration of a fixed clock speed (and a really good clock speed) and using CPU-cycle count for modern CPUs (Intel 13th Gen). Consider how much worse it would be with a CPU running at 2GHz on average and using CPU-cycle counts from older CPUs (Intel 7th Gen).
Small optimisations like these, whether that be in the engine side of things, graphic side of things, or the gameplay side of things are the reasons some games hit really high FPS on even low-level hardware really easily and why some struggle even on high-end hardware, when they're practically the same thing.
Nobody is telling you to think of every optimisation you could possibly do while you're making your game. In fact, that's a bad idea! It's known as premature optimisation. But simple stuff like this should be the foundation of good code. Don't add extra ops. if you don't need to (comments exist for readability).
As with most of these optimisations, they matter in hot paths where you might be running them repeatedly. The difference between Vector3.Distance and .sqrMagnitude, or math.distance and math.distancesq are measurable and not insignificant when in a tight loop
They are not at all comparable to a disk read or a Find call, but those things will not be found in tight loops, but you can find spatial queries using distances all the time
As for readability, once you understand what it is I find sqrMag/distancesq communicates more information, often indicating to me that you're comparing distances and don't need a literal distance at the end
Where I do agree that if you are working on device that are aiming at 244 FPS it is in fact non negligible if you have substantial amount of SQRT every frame,
I would argue that for every extreme situation where you want better performance, you have extreme situation where you want better readability.
One such situation would be the usage of event in a High End Console. Consider the following event:
public System.Action<float, ...> OnDetected;
If the first parameter is suppose to represent the distance, would you use the sqrDistance or not ?
You're if dealing with one value, not a tight loop, it's irrelevant. Also I would not write code with a random float in an action called OnDetected, that seems to be the problem with the code.
i have a O(n^2) algorithm for populating a space with asteroids, it has to measure + compare distances for that a lot.
sqrMagnitude is a real deal here
just to give a real world example
If you write a method that returns say a tuple or a struct, you can either have documentation for the method to ensure the end user knows what it is returning, or have variable names accordingly in the struct.
Readability really isn't an issue. Neither is debug-ability.
Like you said, it is irrelevant. And more than irrelevant, it could decrease the usability of the code, forcing people to do SQRT operation. This is the extreme.
A tight loop, is not considered tight on every platform/scenario. Always preferring SQRT operation results in issue where it does not increase performance and could pay a price in unclean code where one would include both sqrDistance and distance signature for a function or event.
Another real-world example, I have a selection preview that gets the closest 3D line that is under your cursor. As there could be many many lines in the scene, it's all just square distances, clearly labelled
Huh? Anyone who's using the code who specifically requires the square root could just do the operation themselves. Let the cost be paid then, and not in every occasion by default.
If you expect people to be using the code in a tight loop you can provide a SqrDistance property, and a Distance property, you can do both to allow for flexibility of use cases
There is no cost associated with such operation because of the nature of it. The distance has more utility than sqrDistance.
There is cost associated with it though? It's cost of the SQRT op.
Of course it has more utility, but it has the exact same utility in the cases we're talking about swapping it for
and there is a cost associated with it, the cost is easily measurable
Let me remind you: squaring a number is faster than taking square root of a number.
It is negligible in most situation.

🤦
It's negligible in many situations, and you can choose where that threshold is for you and your projects.
Hence why you use style guide.
I literally explained to you how it isn't negligible in most games.
Most game does not run at 244 FPS
Yeah because they run at lower FPS due to performance issues.
So optimizing would give more frames.
No, it wont. Because most game are aiming at 30 FPS or 60 FPS.
Where it is negligible.
There's really no need to argue about this, it's a square root, you can measure it and make your own judgement calls
Apparently most games in 2023 aim for 60 FPS. First time I heard that.
Is this still the Distance vs SquareDistance argument lol?
yeah because there are some delusional takes on what games in 2023 are aiming towards.
Like literally—60Hz+ monitors exist for no reason I guess if games aim only for 60 FPS.
Gotta find something else for everyone to argue about. Here's one - on Friday, my coworker insisted it's faster to compile implicitly typed variables (eg var) than explicitly typed ones (eg int). My stance was 25% doubt / 25% indifference / 50% code readability objections. Didnt have the time or will to benchmark. Thoughts?
sounds like nonsense to me
I highly doubt that something that has no structural implications would be relevant to compilation speed
Why would it be faster to compile implicitly typed variables ? Sounds non-sense to me too.
Isn't there a whole extra step where the compiler has to infer the type with var whereas an explicit type skips that entirely?
Yes
hello all, i am having a problem with my level select because I have it ready and done but the fade in/out animation is not working, there is no error in my console and I dont know whats wrong
can u help me with this?
#💻┃code-beginner and don't ping random people.
i dont think this is beginner
You are a beginner, it is obvious from the "there is no error in my console and I dont know whats wrong"
more experienced programmers know how to debug their code.
His line of reasoning was that the compiler doesnt trust the developer anyway when they use explicit typing. So there is still some unavoidable type-checking step. Never really explained why that would make it slower than var, but this was already one rabbit hole deep so I didnt push.
benchmarks! ¯_(ツ)_/¯
The compiler creates complex graphs and reorganises code, transforming it completely between representations, interpreting var or int isn't gonna factor into this
Lol no, your coworker must really like var. var is syntactic sugar and will lowered. It will be converted to an explicit type before compilation so the only real difference will be the time taken to convert it (which is negligible).
Is there a way I can turn off microphone permissions for unity so I can test if my code to request permissions works
revoke the permission in your OS
Thanks
I was hoping at least one person would take his side lol
It's actually the other way round.
var based code takes longer to compile.
as compared to T based code.
It's my fundamental belief that var was the worst thing the .NET team came up with.
The IL doesn't even have anything known as var (afaik), which means it's always gonna be an extra step & hurts code readability when reading code outside of an IDE — say on GitHub.
I assume var has to be slower to compile, during the lowering step it has to be replaced with explicit type; but like I don’t think anyone really cares about compile time and the impact is probably minimal, people just take coffee break while stuffs compile anyways.
There's not difference in compile time. The difference is so small it really can't be taken into comparison
.NET Compilation time in general is very quick so var is nothing to worry about
So yeah, strong disagree, this is all purely opinionated at the end
var is definitely not the worst thing in C#, this language feature is not just in C# but also C++, Java, Swift, Rust, and basically every single new programming language these days
Just the sheer amount of languages that has this features should tell you how successful it is.
Isn't there something about you have to use var for some LINQ use cases?
Don’t think so, but LINQ gets pretty hideous to type explicitly if you stop at an intermediate step; and the bigger thing is that anonymous objects cannot be typed at all, which LINQ code used to use (which I would argue tuples more or less have replaced)
https://forum.unity.com/threads/burst-static-functions-vs-inline-in-burst-code.1414518/
Maybe an interesting question about Burst for those who are experienced in it. Would love some feedback
Ohhh right, it's anonymous objects that require var. Thanks!
var is never required
It is if you use anonymous objects (unless you type it as object which is just cheat code)
It’s not, that’s probably why you never used it 😄
For intermediate types, tuples more or less have replaced it.
And anonymous objects can’t cross function barriers because they can’t be typed other than by var, so they are limited to be used only as intermediate types.
I used anonymous types quite a few times (not in Unity) but I quickly replaced them with record and record struct types, which can be declared in one line and the compiler does the hard work for you
Unity (or android OS?) appears to fire OnApplicationPause after 4 minutes of the app being in the background. Do I have any control over that?
Oh, actually, nevermind, it looks like I just accidentally fired that myself by tabbing back to the app exactly 4 minutes later
Hm.. not sure how to solve this problem.
Basically I have an idle game, the client updates game state locally and sends a save file up to the server every 60 sec or so. The server sends a keepalive to the client every 15 seconds. I'm encountering issues where the client has had the app in the background for hours but the server doesn't disconnect the client. When the client brings it to the foreground, then the connection is disconnected, but the server thought the client was connected the whole time, so it awards offline progress of "0 seconds".
Do I just want to disable the app from running in the background entirely (so it doesn't respond to keepalives in the background and the server can properly disconnect the client)? I suspect that experience is less than ideal since the player would have to login any time they tabbed out, even if it were for just a moment...
I think maybe what I'd like to have happen is the app (in the background) disconnects from the server if it's been in the background for >60 sec?
(Although I seem to recall that having unity apps quit themselves on mobile devices is not easy/normal)
I don't get the OnApplicationQuit event if I close the app using the Android OS - but the server successfully disconnects instantly
is this an http connection, a websocket, or an ordinary connection?
ordinary
Do I have any control over that?
you can run audio in the background to cheat that, but i don't think you wanna do that
so TCP?
nah that'd be bad
TCP yeah
I just tested it out and a connection stayed alive for a full 6 minutes before dropping
windows and linux have different tcp options
are you sure it's 6 minutes and not 5
also when you say keepalive, do you mean SO_KEEPALIVE
it's allright.. I'm .. just hacking together something potentially stupid that I'll regret later.. having both server and client send keepalive packets and on the server, tracking the amount of time since the last I got from each client and manually disconnecting them if it's above a threshhold
not sure it's 5 minutes, just pen-and-paper'd it
you know, small brained sense
i mean that you have a lot of application specific knowledge
that doesn't map exactly to using tcp connections as sessions
etc
and the client and server, including the network stack on phones which is not ordinary
interact in strange ways
yeah i'm just surprised that the ... network connection stays alive but unity isn't doing anything anymore (in terms of update() and game loop stuff)
in your backend, do you listen to tcp "disconnect" or "closed" events?
the keepalive from the server doesn't require a response so .. the client just happily receives the networking message and ... does nothing
yeah, but that's the problem - the client remains connected even though the game is inactive
happily connected, might i add
it's ok.. i'm nearly complete with the above solution 👆 so .. 🤷♂️ i'll just do it that way, even though i hate it
it's probably not that big a deal sending 4 bytes and back to a few hundred people every 15 seconds but it still feels wrong
imo there are three approaches
(1) use udp, which are connectionless. use your own logic for when a session starts and ends, such as heartbeats
pros:
- almost identical behavior across all platforms
- few surprises
cons: - you must adopt a real udp-based protocol. authoring your own is kind of stupid. too many details, too many bugs.
- very rarely blocked altogether on some networks, like public wifis
(2) use http. when the client needs to send a message, it posts to a well known url. the server streams events (server push)
pros:
- well documented support and behavior on all platforms
- good support for scaling, SSL, operations like observability
cons:
- cantankerous
- you must read the docs for numerous gotchas
(3) use grpc.
pros:
- identical behavior on all platforms, since the code is exactly the same
- well documented
- compatible with most things that support http, like load balancers, for ssl, observability, etc.
cons:
- lots of faff to get started in unity
- not compatible with web browser out of the box like http
- backend server support can be weak
@misty glade you are using nude tcp with your own ad hoc wire format
which has none of the pros of any of these and only cons:
- different behavior on every platform
- poorly documented which features are supported where in unity and dotnet, for example how socket options differ between server and client on windows, linux and ios
- poorly compatible with load balancing and observability
all you're going to wind up doing is reinventing udp on top of tcp
for example, you are trying to make tcp connectionless to work around the behavior of mobile devices, which is complex with tcp connections
Generally for online games, writing your own RUDP transport is pretty bonehead easy. Nobody really uses TCP or any other hacky communication protocols unless you're specifically trying to talk to a web server (useful for authentication)
All you really need is a way to send unreliable UDP packets, and reliable UDP packets and you're set.
Obviously the RUDP shouldn't block the standard UDP packets on retransmission
grpc and http are going to be superior for most people
people use tcp because they use http
Are the clients on web browsers?
anyway, this comes from my experience making multiplayer mobile games
no, the clients are all computers
PCs, phones
If they're all machines running executables, then UDP is the way to go.
Nobody uses TCP for realtime stuff like this.
udp is a bad choice for a lot of reasons
Ok tell me
okay imma take you on a little journey of deduction
in this journey, tell me, what game are you making?
It shouldn't matter.
The only reason I could think of using TCP would be on a browser where I can't access UDP sockets
hmm
@misty glade i guess this should tell you everything you need to know about this particular conversation lol
If you're making a card game where players have 10 second turns, then sure, you could get away with using TCP
Nobody is going to use TCP for realtime shooters.
what networked "realtime shooters" are authored in unity?
You have your state updates, which sit on the unreliable transport.
And then your actual reliable messages, which sit on the RUDP transport.
Rust, tarkov, etc
I could probably name hundreds more
no its a card game
Considering rust is on top 10 steam charts, and tarkov is probably close behind, why the hell would I need to name any more?
so 2 games?
You are terrible at arguing
Considering you think "rust isn't a shooter" I'm convinced that this isn't even worth my time
Rust is one of the most innovative games in the past 10 years
There's a reason it sits consistently at the top of the steam charts
I still have no idea what you're trying to argue
anyway you've shipped a multiplayer game and it works with tcp @misty glade. the biggest gotcha with mobile clients is that, using tcp alone, their answer for what is the state of the connection will very frequently disagree with what the server thinks
ah yes, the old "I'm right, and I don't need to prove myself, so I'm going to ignore you"
wonderful
whoa stepped away for a moment and le poo hit le fan 🙂
yeah i don't know i'm just focusing on your issue
heartbeats have the side effect of resetting all sorts of timeouts
which in one sense is good
lemme catch up one sec
because they are arcane
just fighting some fires
the bad part is that you can easily get in a situation where your server leaves connections "open" that should really be closed
the heartbeat thing is fine since it's not every frame, it's every 15 sec (or really configurable to be more - i don't think there's any load considerations)
yeah yeah none of that matters
you could send a heartbeat every frame
this isn't a performance issue
i'm not talking about that i don't care about it, it will literally never come up
the open connection thing isn't even really a problem.. the "problem" if any is that the client maintains the connection, but the server determines how much offline progress to award the client based on their last connected heartbeat
well the performance issue is thread per connection, if you are doing that, but not like, how many packets you send or whatever
that isn't going to matter
if they maintain connection the server thinks they're advancing in their game (which they aren't since the client is background-ed) so they connect and lose 5 minutes or so of progress
it's not a huge deal but it's .. annoying
are you asking how to know when the app is backgrounded?
guy plays a game, starts some missions, does some taps, etc, tabs out for 10 minutes, comes back and has lost half of that
nah, i can know that on the client but not on the server
i mean, sorta
the client simply sends heartbeats to the server as long as the app is in the foreground
it's OK, the heartbeat solution is in place and .. seems fine enough
not the other way around
yeah, that's what i'm doing
well the server sorta needs to as well to kill truly dead connections
not every 15s
eep why that often
1000+ concurrents, hopefully
but you will hit a resource wall with 1,000 concurrents only if you are doing thread per connection
i mean, i suppose even at that load 1000 concurrents * 4 bytes for a header every 400ms is still trivial
it has nothing to do with number of packets. you can literally process like millions of packets a second
if not 1b
1,000 threads * 4MB stack per thread is an example real limitation
i'm actually using two threads per connection 😛
but i don't know if you're doing thread per connection
well
i mean 1,000 concurrents is a lot. and 8GB of RAM is not expensive
but listen, if you wanna make your own session
that's just something you gotta do
it's unavoidable when dealing with mobile clients and notions of connectedness
it's already done and.. hopefully live on android in canada later today 🙂
the phone doesn't neatly map to what TCP ships with
the connection will be reset (RST) and therefore closed literally all the time
yeah, the .. manual keepalive thing isn't great but .. I think my little project has been around long enough that I can call some decisions locked in stone and legacy 😛
as the person is moving around and whatever
manual keepalive is great
i'm trying to say that you must write your own session, it can't be tied to whether or not a tcp connection is "alive"
this is my stack: https://github.com/vis2k/Telepathy
I don't think I get the low level stuff re: connections (RST events)
I pretty much get OnConnect OnDisconnect and OnData
hmm.. but how does it decide when a user disconnects?
do you see what i am saying?
it's murky
that idea doesn't map neatly onto tcp and phones
if a user is playing your game on the subway, and happens to lose internet for 15s, and then comes back, and they've been foregrounded the whole time
do you see what i mean? OnDisconnect is really OnAdversePossiblyNotActionableNetworkEvent(NetworkEventType someTime)
currently 4 situations:
- server is shutting down (forcefully disconnect all users)
- client disconnects voluntarily (user quits - not backgrounds - the app)
- server sends a keepalive to the client and socket reports that it's now disconnected
- client fails to send a keepalive for 60 sec
and TCP has many of these, whereas UDP has almost none
i mean actually i have to manage this shit anyway because our production server gets hammered with spoopy connection requests every few seconds
that's my staging server even, the DNS has only been allocated a week and it's already getting those all the time (on the game port!!)
if the user foregrounds Messages for 16s, then foregrounds back your app, it was actually possibly all still running
and it changes
that's fine - as long as they foreground it from time to time, that's 👍 .. it's when they background the app and never come back to it - the server thinks they're connected and advancing game state, but they're not, so they lose 5 minutes of progress
it sounds like you've already written OnDisconnect to mean OnAdverse...
yeah
what's frustrating is that this thing gives you an object you must now wrap
the lifetime of that socket object or whatever it gives you has nothing to do with the lifetime of the player's session
in clash royale the player's session simply lasts all 3 minutes
it's divorced from network connectivity
uh oh, "timeout"
timing out what? there are like 3 kinds of timeouts in tcp, and 4 in linux
not sure but i only get that one event from Telepathy
without going to deep into their stack, i only get 'OnDisconnected" for any/all disconnect events
I'm not gonna dig right now how it works .. would have to scour their codebase to see how the events are put into that receivepipe object
there's
- idle connections being closed (idle timeout)
- tcp native keepalive (keepalive timeout)
- start connection timeout (syn timeout)
- unreachable host timeout (multiple things interact with this)
the first three are affected by any loadbalancer/termination you have, such as azure load balancer
this is to say that telepathy does some wrapping around these and presents them all as a disconnect event
lemme give you some actionable knowledge lol
@misty glade the absolute best way to test these issues is to exactly test them with real hardware. however, since that's hard to automate, the best thing i've used is ToxiProxy
toxiproxy can simulate all the different kinds of real network failures effectively
for example, telepathy probably correctly gives you "connection reset by peer" if you force quit the client application (equivalent to a background kill), but it will give you nothing if the client's LTE connection gets spotty for longer than 15s
which will happen all the time! it's a mobile game
people will literally play on LTE at home, where they have 1 bar
and they will be unable to do anything because the connection is too poor, but your server will think this connection is lasting forever and they actually disconnected a while ago
here's what really happens: the player is on the subway, the connection gets spotty, then they do something else
ios background kills the app while they have 0-1 bars, and the reset packet is never received by your server
the connection is never restored
another thing that happens: the player is on the subway, the connection gets spotty for more than 60s, and the server thinks the user has disconnected because the user didn't reply to a keepalive. then all the queued up network traffic the user has been sending those 60s arrives, including keepalives. now the client, which abruptly receives a reset, is very confused. AND it's impossible to know how telepathy handles this without reading the source code, because an "unexpected reset" is different than seemingly asking the connection to close gracefully, as you do in the code when a keepalive isn't received in time.
These are all already handled - the player can't really play the game with a crappy/invalid network connection - nearly everything in the game requires some connection to the server.. but the one thing that they can do that I wanted to cover was idle completely - even with the app in the foreground this requires a connection to the server (ie, "check for a rare spawn" or "get a list of how many players are waiting in the queue for battles")
hmm
if a player is actually disconnected for more than 15 seconds then they aren't having a very good time
well i think you are in for a lot of surprises
i could only prove that my game servers deal with these issues correctly using toxiproxy
and grpc has a good general model for sessions, one that's so good it's become WebTransport (i.e. rpc for http/3, which is "just" grpc over quic)
honestly i don't think the telepathy guys would know either
why would they? they don't make or play mobile games
they are the people in the audience in blizzcon booing diablo immortal and listening to that guy say "do you not have phones?"
how does the client "know" it has a crappy network connection?
use toxiproxy if you want to fix this stuff
it sends a packet, the packet fails to send and the client connection OnDisconnects
so what i am saying is that from the client's point of view
are you doing await SendPacket()?
I'll check it out but so far (a month on steam) we haven't had any issues with connectivity/etc
fair, but also starlink sucks 😛
nobody is going to have spotty connectivity in that situation. every single phone has spotty connectivity
lemme ask you this
let's say you do await SendMessage()
is this what you do?
we're also on phone too fwiw, but limited users there
on the client? i send them synchronously
okay same diff
so you send it synchronously whatever
what happens?
do you handle a TimeoutException?
do you configure the WriteTimeout? the default is "infinity"
whichi s what is going to happen on a spotty connection
so it won't throw an exception, and it will hang forever, and it never finds out if the packet failed to send
because there are many situations where that is unknowable for a long period of time including possibly infinitely*
and unfortunately those situations happen a lot in phones
and your game logic that queued a message to be written by your networking thread
will happily churn along
a message possibly never sent
sorta - i have a timeout on the client socket polling (150ms)
When I worked on an Android app that had a BLE connection to a peripheral I encountered a bunch of issues with different Android phones handling background processing differently. Not sure if the case is same for data/wifi connections.
but it's synchronous, won't the writing thread be blocked anyway? how will it know the timeout failed?
do you interrupt the writing thread?
what do you mean client socket polling?
you only have one connection
you could be stuck on sending the heartbeat message lol
so WriteTimeout (a real timeout) versus your heartbeat, they are different things
in fact if you do this right, you'll want to be sending a lot of heartbeats, because it is much simpler to deal with those failing to send within a specified time (i.e. failing to receive an ACK from the server) versus game logic messages
Is anyone free for a sec to help me out with some neural network stuff?
just ask a question 🌈
So I have a simple neural network that I have pieced together from a couple of tutorials... I am using TanH activation and Xavier weight distribution to train against the pokemon type matchups, which I have in a CSV.. First few rows of the dataset are here...
TypeA,TypeB,Immune,Not Very Effective,Neutral,Super Effective
Bug,Fire,0,1,0,0
Bug,Grass,0,0,0,1
Bug,Fighting,0,1,0,0
Bug,Poison,0,1,0,0
Bug,Flying,0,1,0,0
In my code, the types (Bug, Fire, etc) get turned into an integer and then normalised before being passed into the net. The network at the moment has 2 input nodes, 3 hidden layers with 17 nodes each, and 4 output nodes (for each of the outcomes... Originally it was only one output but it seemed logical to have 4 for each of the categories). I am using mean-squared difference to adjust the weights of the nodes.
For some reason, after training for 1000 iterations (which I know isn't a lot, but 5000+ takes 5 minutes because it's not multithreaded yet) with a learning rate of 0.03, all of the outputs are the same for every type match up that I test so something is going awry... I have never really touched this before so I am a bit lost lol. Let me know if I can give you any more info
this isn't really a unity question
What you want to do ? I'm not an expert in AI, but it does not seem to be the correct approach for the problem as the number of variables is low and the number of combination is limited. I feel like you can fully resolve the system.
If you really want to solve the problem with AI, start with easier approach such as Naive Bayes classifier.
it's not clear what you are trying to do
Wondering how i would get a position in Ulam's spiral (aka the square spiral) given an index? (Trying to generate blocks in a spiral around the player)
What is the size of the spiral ?
I have no idea, i thought it was infinite?
I mean, what is the size of the spiral you are working with
i do not know I'm afraid, i have an excel spreadsheet i could screenshot if that would help?
What are you doing ?
trying to generate blocks in a spiral, around the player
Yeah, you gotta put a limit on those blocks...
Unity is not magic, nor computer.
What you want to do ?
I'm afraid i don't understand
Is it a graphical effect ? A gameplay mechanic ? A simulation ?
oh ok, so basically I have a 2d randomly generated terrain type game, and i want to the terrain to generate in a spiral around the player rather than just a large box, cause it would be more performant, the way i plan to do this is for every frame the player has not moved, add 1 to a counter, then grab the spiral position by using the counter as in index into the spiral, and generate that block
It wont be more performant. But I can see the aesthetic.
So, is it only for the aesthetic ?
nope, performance, I've tested the performance by switching to choosing a random position, and it is more performant, the spiral just makes it so the stuff closest to the player generates first
sorry, I've done a poor job explaining what I'm doing exactly. Let me retry:
so scenario 1, the current way is to take a 100 by 100 area around the player and check each spot to see if it is generated, if not then generate it.
scenario 2, generate 1-5 blocks every frame in a spiral pattern, meaning that insanely large areas can generate without having to do everything in 1 frame
It has nothing to do with the fact that you are generating in a spiral manner.
performance is technically the same, but scenario 2 will feel much smoother, to test this i used picking 5 random positions each frame and generating them, and yes it does feel smoother
You choose to do so for aesthetic reason.
not aesthetic, most players won't even have their renderdistance set high enough to notice a difference
Generating on multiple frame instead of 1 is common optimisation.
There is multiple way of doing so. Chunk and Distance by example.
So, now that I know what you are trying to do.
I now that you do not require random access.
And that you can simply use simple incremental algorithm.
that is what I have been looking for, the spiral seems simplest, but I can't find much info online about any of this lol
for (int i = 0; i < BlocksToGeneratePerFrame; i++)
{
GenerateBlock(SomeFunctionToGetPositionFromIndex(FramesSinceMovement + i));
}
``` essentially
I would try to exploit the architecture in this way
This way, you know whenever you need to * turn *.
something like that yes, I just can't work out how to go from an index to a position in that spriral, I'm not good enough at maths
I mean it is not math... To be honest, I would use trial and error and not try to come up directly with the answer.
It is only finding the correct imbrication for.
I have been using trial and error, nothing works, there is no info on the internet about any of this
Just exploit the architecture I presented you.
I won't do it for you.
There may be a better way to do it.
I've been trying to do that for days... Nothing works, unless i want to manually create a lookup table, and that is slow and tedius, but I'll keep trying...
i need to find a pattern somehow, some relationship between the index and when to turn, and how long the side length should be, but i suck at pattern recognition....
I gave you the pattern...
"when to turn" is litteraly there
See how every scare is a scare
1, 4, 9, 16
no?
I don't understand I'm afraid, those numbers are meaningless to me
I'll keep looking for a pattern, i hope I'll find one
fascinating, I'll try understand this, but it will take me a while, as i don't understand where you got 16+1 from, or any of the other numbers, sorry I'm not clever
1+1 Turn
1+(4-1)/2 = 3 Turn
4+1 Turn
4+(9-4)/2 = 7 Turn
9+1 Turn
9+(16-9)/2 = 13 Turn
16+1 Turn
16+(25-16)/2 = 21 Turn
fascinating, still don't understand where you are getting those numbers from, but I'll continue trying to understand it...
You should generate your terrain using noise (Perlin Noise, for example), not try to reinvent the wheel..
Previous Sqr + 1 Turn
Previous Sqr + (Next Sqr - Previous Sqr)/2 Turn
Increment Sqr
I am generating my terrain using simplex, which is similar to perlin
He is not using for terrain data but for the loading
previous square of what?
yas