#archived-code-advanced
1 messages · Page 176 of 1
Well, I guess your weapon is being culled at some point.
don't use scenes. make your level content a prefab
Or your mesh normals are inverted or or or. take another mesh and test, use a primitive for testing purposes
Very weird indeed.
I'll test it some more
You can also try to put your not visible weapon right in front of your camera, so your main cam does see the whole mesh and not just parts
what kind of game are ou making?
you gave me an idea
@serene girder you had a bug where you got into a lot of red herrings
1sec
Making a tower defense variant, i also ahd a bug with visual studio crashing the editor, but iswapped to vs code and its fine
i also fixed the issue by making a separate variable
have you looked at a tower defense asset?
to study how things work?
you could learn a lot
depends what your goals are
There are a ton of free YouTube tutorials on tower defense. I don’t think an asset purchase here is necessary at all.
@undone coral not really, i like documenting myself on the go, and so far I haven't gotten problems, jsut these strange interactions that are more algorithm wise
That doesn't make any sense
I know it doesn't
@serene girder it's okay. focus on this journey as a programming learning exercise 🙂
thanks, im making it for my bachelor project
there are traditions to writing FPSes and solving these problems. what is the goal?
is there a way to force your project's [FormerlySerializedAs] attrs to propagate their new names to their scene/prefab/scriptableobject fields? i hate leaving these attrs around forever
You can mark assets as dirty with this package, which will force them to reserialize with the new names.
https://github.com/rhys-vdw/dirty-boy
Traditions suck. Break traditions until you figure out why they were traditional in the first place. Nullius in verba.
ooh cool! you still have to go asset by asset with this though right?
You can multi-select objects, and ScriptableObjects are automatically reserialized it seems.
thanks!
Hey I am trying to get some custom world generation going in. for this i would like to make use of noise and chunks. unfortunately my chunks are not lining up correctly. anyone who has an idea as to why that might be?
Hastebin is a free web-based pastebin service for storing and sharing text and code snippets with anyone. Get started now.
I was thinking of generation a huge portion of the map beforehand and then splitting it up but not only is that really expensive. if you generate more than that it would still give the same issue
I solved it by changing Culling Mode to "Always Animate" in the animator on that specific object
It prob has something to do with a certain bone in the mesh, idk.
It's fixed now tho
Yeah, it was cullin gthe whole object then and just hiding it
yeah probably
Guys quick question, if I have made all my projects in unity version 2020.3.29f1 and then upgrade to 2020.3.31f1 would I get the prompt that I would need to convert all my projects to that version? or since its the same year will it not need to?
Because the computers at my college have unity 2019.2.8f1 installed and I am wondering if I install 2019.4.36f1 would I need to keep converting to and from versions?
there's no prompt to upgrade a project typically. You will see the prompt when you try to open a project in a newer version of the editor
yes thats what i mean
you are free to continue using the older version of the editor with your project indefinitely
also this is really a #💻┃unity-talk question
do I need the exact same version on both computers so that I wont need to keep converting to and from
yes
alright ty
you could ask that a LTS version is installed
im not sure if this is the right place but i wanted to have a formula field on the inspector for something like "3 * atk + 2 * def" but im thinking it might be bad for performance to evaluate the expression every time the action is executed is there a way to compile the formula string into C# code programatically as i press play (or maybe its better during compile), how can i do it? or is it possible?
for context, i have a scriptable object for AbilityAction so that an Ability can just execute a list of actions and i wanted to make a Deal Damage AbilityAction that I could put formulas instead of constant floats
use a const
yes it's possible, no it's not trivial to do it right
how?
can Debug.Log be set to output dates and times in the Player.log?
is there a global setting for the logging format?
too much noise on google
but a const need to have a value so i can't change it in the inspector?
other than that i dont think theres a way
There is, but it involves string manipulation, ie. a parser whose complexity depends on the structure of the string
It can go from a simple string split and a few int.Parse calls, to a char-by-char analyzer
And it spits out a class or struct instance containing your values
so in the end its better to just have a list of formulas ready i guess
Or, the class instances directly, serialized so you can set the values in the Inspector
Sprinkled with inheritance/interfaces to have a common point between all of these "stats"
@undone coral https://paste.myst.rs/m4l3r734
Does this look right for a gamestate struct?
a powerful website for storing and sharing text and code snippets. completely free and open source.
Or would I be better off with a Block[][] BlockArray
and copy it into a native array when I do multithreaded processes?
persistent allocations need to be disposed
try using a regular array for now, and implementing a copy
if i need help with making a 2d multiplayer game through photon engine do i ask in advanced?
aight
Is this somewhere I can ask for help with debugging?
Hello, I am trying to become a "pro" in Unity. But not sure how to. I made some small projects but I want to make something bigger and learn about advanced stuff.
I heard about "modularizing so you can run modules without running a simulation". How can I archieve that? Where can I read about it / how can I google about it?
Wherever you heard it in the first place I guess
it's a really odd thing to latch onto though
do you suggest something better / more important?
Just work on ever more complicated games
all that stuff will come out of necessity
If you really want to see/apply that principle, I recommend making a virtual board game?
modularizing so you can run modules without running a simulation
What does that even mean
I guess running it on visual studio without clicking the Unity Editor "play" button
that sounds like a pain in the ass
No I don't think it's that
I think it's more like, if you're making a checkers game for example, you'd basically build out a library of code that handles the whole checkers game simulation
without any GameObjects or visual aspects at all
and then you can use Unity as a presentation layer
But idk - it's worded kinda weirdly
I've tried doing that, it's a pain in the ass 😄
imo not worth worrying about unless you're doing something hella complex
that isn't to say compartmentalization is a bad thing
I just want to become a better programmer and get hired
best thing to do is build up a portfolio of projects
showcasing a decently wide array of abilities
I have a itchio profile with some game jams entries, but I want to learn useful stuff that companies want. Like design patterns, unit tests, etc. Making small projects won't teach me that stuff
what about dependency injection
There's a few extant frameworks for Unity: https://assetstore.unity.com/packages/tools/utilities/extenject-dependency-injection-ioc-157735
I think that could be useful for me, since I always do a lot of work referencing objects between scripts.
I always do public GameObject anotherScript and drag and drop the other object in the editor. But not sure if that's the best way
is it? I though I was doing the noobest thing ever
Most noobs can't figure out how to do that
it's a little less "noobish" to use [SerializeField] GameObject anotherScript; and even less noobish than that to use [SerializeField] SomeComponentType anotherScript;
It's relatively rare to have a good reason to reference a GameObject directly rather than some specific Component
yeah, the most generic I usually do is to reference the Transform
if I'm doing placement things
Is it possible to have a shader reference variables from each point of a mesh?
https://i.gyazo.com/c89f041011c9c845b2338d448db971e7.png
https://i.gyazo.com/fdd287b7ca08787b3d97a9cc16160f15.png
^ Basically, I have a dye shader that's being applied to an animated skeleton that's all part of one mesh. It recolors the RGB channels of slots, bla bla bla, but the point is this:
- I could set materials per slot, but that has an absolutely enormous performance overhead.
- I could use a render separator for spine (the skeleton extension) but that severely restricts what can be dyed & means slots with the same slot have to all be on the same layer.
3. Ideally, I'd like to be able to just have the shader be applied to the entire skeleton's mesh renderer material and have it read the desired variables from each slot by vertex or whatever. Is that possible?
the second image is a pixel art
what is the visual result you want?
you can associate a texture with your sprite that contains the information you need
then reference it in the material
what does it have to do with meshes in the pixel art?
protips for namespace usage? sorry if this is a newb question lol
...well, sort of
i can't build my project using that dll and this is the error i got:
ArgumentException: The Assembly System.Deployment is referenced by System.Windows.Forms ('Assets/Plugins/System.Windows.Forms.dll'). But the dll is not allowed to be included or could not be found.
wait, does this mean i need the System.Deployment dll too?
oh shit it actually works now
noice
@valid flame could be useful for you too. make sure you have the System.Deployment.dll file in your assets folder
pls no necropost
I have no context or memory of this conversation
oh i thought you were still interested about the system.windows.forms thing
alrighty then
How would I SphereCast with an start and end point instead of a start and direction?
Like a line cast but with a radius
Solved it by doing this, still wondering if there is a better solution
Not sure what you are not satisfied with. You basically use the standard call there
Yes exactly, I was just wondering if there is a standard call that gives me the option to insert a start and end position
https://docs.unrealengine.com/4.27/en-US/BlueprintAPI/Collision/SphereTraceComponent/
How it would be done in Unreal
Sphere Trace Component
Unreal has the opposite were you can't fire a ray and you have to calculate the ray end position manually were in Unity you need to calculate the end position yourself
well its just a small difference to get the distance of two points with vector3.distance and use that as distance or other ways. I guess you are good to go with your approach so far
ye, using the direction magnitude was already clever since I need to calculate the direction anyways. Well thanks for the info, this will do for now
Could someone explain why I am getting this error and how can I fix that
This is the code https://gdl.space/ineyececuk.cs
and this is the script that calls that code https://gdl.space/xogunupaya.cpp
what I am doing is making a post request in an IEnumerator, then waiting for it to return a json string using another IEnumerator, then finally returning that string from the function that started those coroutines
Errors because your getProfileJson coroutine is declared inside another method, so Unity couldn't find it
It will produce the same error for waitForJson
Take them out of the method and mark them private if you don't want them to be accessible from the outside
both of them are inside the Get method
Yes, that is the problem
If I take them out I'll have to pass a string to getProfileJson
Yes, that is the fix
Use return values, out parameters to provide values back to the caller method
On what line is the exception thrown now?
No idea, you'll have to debug it more. Also you have a flaw in your code, the lines
StartCoroutine(waitForJson());
Debug.Log("wait finished");
won't actually make it wait before running the Debug.Log, as StartCoroutine starts the coroutine and resumes execution right away
It's like a background task being started on another thread
You have to wait for it by making Get() itself a coroutine, and every sub-coroutine you want to wait, you do yield return StartCoroutine(SubCoroutine()) for example
And you can't return anything from coroutines, so you have to store the state inside class fields
Like you have right now, the bool receivedJson
okay
You can always throw in a UnityAction as a callback that gets invoked on the end of your desired coroutine
Bump?
use async / await via UniTask to "return" things from coroutines
including web requests
Hey y'all. Doing a whole Steam voice integration deal right now. TL;DR - I'm successfully sending compressed audio packets (of player's voices) to other clients who then decompress it and add the decompressed sounds to these float[] buffers. There seem to be 2 ways to get those float buffers into your spreakers. 1. Set up some kind of sound by making an audio clip and then sort of hacking the sound in PCMReaderCallback of the AudioClip or 2. writing an OnAudioFilterRead and just adding the voice into an audiosource as a custom filter (which runs on the audio thread). Ended up getting option 2 working as a proof of concept.
I think Option 1 would be better if I solved some issues with it. Was wondering if anyone knew of a good sample for just feeding floats into a running audio clip without it randomly turning itself off b/c it hits the end of it's data array or whatever.
are you trying to do a voice game
or a game with voice*
there are traditions
buffering sounds better
Hi.
If I have a cube parent that I want all child objects to follow, how do I scale the cube without having all the children be stretched around?
Is it possible to link transforms somehow?
Thanks, will take a look.
Furthermore, what's the best way to use and highlight shaders that are stored in Packages? They don't show up in the inspector and when I menu dive down Packages I can't drag them onto the object. Am I supposed to drag stuff from Packages to Assets as needed?
Is there any way GraphicsBuffers can hold your custom struct?
seems like the issue is that sizeof(CustomStruct) fails,
adding [StructLayout(LayoutKind.Sequential)] doesn't work
also [StructLayout(LayoutKind.Explicit, ...)] doesn't work
Well, you can definitely hard-code the size and then it can hold the struct just fine. You can probably also use UnsafeUtility.SizeOf
You do need to make very sure the layout of the struct (and its size) matches what's expected on the other side.
sort of a general C# question but is there a way to provide a capacity for an event Action ahead of time kind of like you can for a List etc. to avoid allocation when multiple things are added to it?
i know it's small and i'm not using them so much that it'd become an actual performance problem probably, but just as a matter of principle
Hm, you can manually implement the event (i.e. write add and remove) and back it with a list or something. I'm not aware of any way to tell the auto-implemented events to reserve capacity like that, but maybe someone else is.
hm yeah i might actually end up doing something like that, mostly because i get distracted by any spike on the GC graphs when profiling
some platforms have limits on the number of graphics buffers
those are? im not targeting low-end devices
maybe it was compute buffers
there's a limitation on iphones
that's significant
it impacts a lot of unity assets that's why i know about it, i don't know what it is specifically sorry
Does anyone here have experience streaming audio data to FMOD?
I've got a nice voice chat system working using built in audio and need some help understanding how to feed data to a stream via pcm callback.
sorry i didn't mean to be vague
yea that's not what im targeting, the buffers do end up being used within a compute shader tho
no worries 🙂
Can anyone tell me which version of Visual Studio should I download for Unity? (Community 2022, Professional 2022 or Enterprise 2022)
be a vs code chad
You could use VS Code :P
can you try System.Runtime.InteropServices.Marshal.SizeOf instead of sizeof @fervent cave
i think sizeof is an unsafe keyword right?
you can use structures in a graphics buffer
You can use VS Code?!
I was just looking at a tutorial and he said to use Visual Studio
I'm new to Unity so...
im almost done implementing the SoA approach, if there's any issue with performance or portability ill look at changing it
Yo i've coincidentially been using these Interop Marshal calls to copy data between arrays.
This may seem like a silly question but is Marshal.copy used for copying data from pointers in separate applications?
not sure
i'd prob google it since it's arcane
Fair, FMOD is audio middleware and has its own stuff going on.
Who is this marshal guy after all? Better not be related to json
Not really #archived-code-advanced, but: The Community version is fine.
guys, does anyone here know how to make a player detector for an enemy in a 2d platformer game. The enemy type is melee
wdym by player detector
You mean like allowing the enemies to reference and detect the player?
how do the enemy know if player is near
currently i am doing a raycast to the front of the enemy object. But what happens if the player jump. The player will be over the raycast but still very much near the enemy
you can define a radius for the enemies, then check whether the distance between player & enemy is within that radius
but with this approach enemies could detect the player through walls etc.
you could do a boxcast instead of a raycast
with a tall enough box that the player can't jump over it
i see. There is a edge case that i just can't solve though?
What i do for detection in my game is one Detection script on the player.
The player has an overlapsphere around them that checks if the monster can see them and says "you can see me"
Its faster to check one player against all enemies instead of each enemy having hitboxes around them
The game also has sound mechanics with same principle, it does CheckVisibility(otherMonster, myVisibility), CheckAudibility(otherMonster, myAudibility)
The player sphere will touch everything through walls so you can get references to the monster, thats where you check line of sight and real max distance
What do i do in this case?
i want the player detector to not detect the player if there is a gap between them, because the enemy is a melee type that can't cross a gap.
In a case like this i want the enemy to act like the player is nowhere near. But how do i do that?
pathfinding 😄
That has to do with their ai, yeah pathfinding
you need a 2d pathfinding algorithm - if there's no path to the target you know it can't reach the player
Here's one option https://github.com/h8man/NavMeshPlus
i am using behavior tree that uses the player detector. so in this case the enemy can see the player and the behavior tree has the enemy idling on the edge.
i was thinking if i can do some other kind of player detection then i could update the the behavior tree accordingly so that the enemy doesn't sit idle on the edge when there is a player on the other side
Can I lerp from a higher number to a lower number?
{
webcamTexture = new WebCamTexture();
Renderer render = GetComponent<Renderer>();
render.material.mainTexture = webcamTexture;
webcamTexture.Play();
}```
So, I was using webcamTexture, I need to handle an error if Unity can't access the webcam. However, try-catch don't works because the error is native code neither simple checks like "webcamTexture == null" or anything. Is there anything that I can do to handle webcam errors?
isnt it then just
Mathf.Lerp(higherValue, lowerValue, Time); ?
yes
how can I set a field of scriptable object to be readonly/constant once initialized. I create the object from a script and for some reason (or I have not found another way) ScriptableObject.CreateInstance<MyScriptableObj>(); doesn't call the underlying constructor. So if I have a readonly field in MyScriptableObj I can't assign to it
you can't use constructors with Unity object slike SOs and MBs
best option is not to use readonly but to have properties with only getters
thanks, ill look into that new to c#
same problem as with readonly. I basically want to use a scriptableobject as data-container for a baked bit mask. I thought using scriptable objects are an elegant way to store them and make them inspectable within the editor
new question folks
void OnAudioFilterRead(float[] data, int channels){
anyone know how to pre-predict the number of channels this will have
like... i'm always getting 2 channels but idk if i can rely on that... you know?
change an audio source to mono, channels should then be 1. I guess all your audio files are stereo
you can do
bitMaskAsset.bitMaskContainer = new BitMaskContainer {
bitMask = bitMask,
floodCount = floodCount,
...
}
declare the fields in the struct read only and make a custom editor that fully replaces the struct instead of modifying the fields. believe Odin may already support this workflow
[Serializable] struct BitMaskContainer {
readonly BitMask bitMask;
...
}
otherwise don't overthink it, use an Interface in your code with read only properties
and implement it with the struct. keep the field private
thanks, what's Odin?
class MutableBitMaskContainer : IBitMaskContainer {
// inspector editable
[Serializable] private BitMask bitMask;
BitMask bitMask => m_BitMask;
}
interface BitMaskContainer {
bitMask {get;}
}
inspector asset
helps you write inspector windows for stuff like this
just easier to do
not sure if it supports this exact use case OOB though
I ended up going with this:
https://answers.unity.com/questions/489942/how-to-make-a-readonly-property-in-inspector.html
Unity is the ultimate game development platform. Use Unity to build high-quality 3D and 2D games, deploy them across mobile, desktop, VR/AR, consoles or the Web, and connect with loyal and enthusiastic players and customers.
actually really useful to have that as an attribute
you can still change the field within a script just not in the editor
congratulations, you've just moved up in the expanding brain meme
level 0: "how do i make these fields read only"
level 1: "why stress so much about access when i control all the source code? i can always give myself access"
don't move down the ladder! don't say performance!
don't do it!
well I did change the VFX package to make some class public xd
it's not COMPILE TIME read only so there's no optimization
lol
C# readonly != compile time read only*
yeah so you see
your body arrived earlier than your brain did
access controls in your own source are API documentation
that's why in go, they use an uppercase or lowercase letter, rather than a keyword
jk they have no good reason for that it was a bad idea
Will burst compilation work if I make calls to external public methods that are non-static?
public readonly int2 BoardSize;
public bool WithinBorder(int2 destination)
{
return destination.x >= 0 &&
destination.x < BoardSize.x &&
destination.y >= 0 &&
destination.y < BoardSize.y;
}
public bool IsEmpty(ref NativeArray<BlockParams> nativeBoard, int2 topPosition)
{
if (!WithinBorder(topPosition)) return false;
return nativeBoard[VectorToIndex(topPosition)].BlockType == BlockType.Empty;
} ```
I'm calling IsEmpty from a burst compiled method
Hi guys. You probably know about nativeArrays which a great when you actually never want dispose it. I would like to have a nativeReferenceType like for Materials which never changes, so when switching Materials it just points to that new or old Material.
Would safe a Destroy(Material) on every switch because it copys the value and just leaves the old Material to the Gc. (which never gets cleaned so I destroy it on the spot).
How do you guys solve the issue to safe that destroy?
"Would safe a Destroy(Material) on every switch because it copys the value and just leaves the old Material to the Gc. (which never gets cleaned so I destroy it on the spot)." I don't know what you mean here
Like here for example. I switch all the Materials to a glowmaterial (because it is cheaper than switching a boolean or glow value in the shader for many diff objects) which just leaves the old material for the gc and copys the values to a new material that gets assigned.
When I could use a nativeArray (for referencetypes) I could maybe just change the pointer to the references and never copy any values
what are you trying to do
implement highlighting?
because it is cheaper than switching a boolean or glow value in the shader for many diff objects
i don't think that's true.
the glowing should be implemented as a feature of your uber shader, in shader graph
you would recreate the standard Lit material and add your Highlight Glow feature
and use that as your shader for your materials everywhere
no
I thought so :<
Yea I'm trying, in the bug fixing stage hehe
I have that approach for the Hextiles (material property block) which have a simple Shader and is faster but some Objects have multiple Materials and also Shader where this approach is slower.
Thats why I switch all the materials for the big Multimaterial Objects (which is faster than switching a variable via mpb even with the stupidly needed destroy(material))
What I want is pin down the Reference types (materials), so they don't move around in the heap and just switch pointers instead of copying values.
Unity has one, called transformaccessarray which is a godsend but it is only for transforms.
so you're just saying you don't want to copy the materials array?
i think you can use Renderer.GetMaterials(List<Material> m)
it's really hard to tell
So NativeQueue doesn't copy, apparently.
I've wasted like 3 hours because NativeQueue doesn't copy 😦
I hope not for me 😅
No, just my own thing
Ah good^^. .GetMaterials sadly just copys the materials on the render into a list.
What I mean is what is noted in the notes:
https://docs.unity3d.com/ScriptReference/Renderer-materials.html
But I think I gonna figure it out myself how to use pointers and pinned down code
oof, good luck
You are correct sir
i think you're boned
How do I export and import shaders in an asset bundle? It doesn’t seem to work for me. I’ve heard something about shadervariants but I’m not sure how to use them in this way.
Shaders in asset bundle will work but will fully work only for the references to shader from within the asset bundle.
Unity needs to generate shader variants ahead of time
Hi, i want to perform a 0-1 scaling on 3d sphere.
Let me explain, i am shooting a raycast on a 3d sphere and i want a method which can get a float number between 0 (center of spehere) to 1 (circumference or outerline of sphere) depending upon the raycasthit point (position). How can i achieve this.
I have tried calculating diffrence between the position of sphere and racast impact point, it works somewhat but is complex to implement in code. Is there any Mathf function or Vector functions which i can use to calculate this 0-1 scaling easily.
if you shoot a ray towards a sphere shouldnt the impact point always be on the spheres surface?
yes i want to scale that surface to 0-1 in float number
so when i shoot i can get a number between 0 - 1 that specifies where the impact happen
mathf.clamp01(valueToClamp)?
i am not clamping any value
isn't this what you want?
oh wait nvm
some googling found me this for scaling a value
var result = Mathf.Lerp (10, 100, Mathf.InverseLerp (1, 5, 3));
but youll need to look at what the lerp paramas are and plug in your range of values
You said "0 (center of spehere) to 1 (circumference or outerline of sphere)", but how does that work with a raycast? Sejadis' point was that a raycast from outside a sphere can never hit its "center", it always hits on the surface.
var result = Mathf.Lerp (0, 1, Mathf.InverseLerp (minInput, maxInput, 3)); i think would work
oh lol
Then you will need to try telling us again what you actually want. If you don't want 0->1 to be center->surface, what do you want 0 and 1 to mean?
So, sometimes what you want isn't what you need.
i just made a pokemon ball 😂😂
Aha. In that case, if you're only interested in the X axis, you can calculate Mathf.Abs(hit.x - center.x) and then remap that from [0, radius] to [0, 1] by dividing it by radius.
going to try it
Anybody knows a better alternative to check if a method was overriden or not? Faster than the below reflection would be nice
private bool Overriden(MethodInfo method)
{
return method.GetBaseDefinition().DeclaringType != method.DeclaringType;
}
I have a narrow box object like a tight rope. I use a trigger on the bottom of my player to start the balance walk over this area. But I need the player to be positioned in the center of the walk area. I don't want to use a position object on the box object, I want to somehow use code to calculate it. Is there a way to do this?
Since you are working with a sphere, and detect hit on it's surface, you can normalize the vector between hit and center. This will create a directional vector at length 1, which you can multiply with the radius to get the original position
A normalized vector will never exceed 1 for any x, y, z
True, if I'm not mistaken, Mathf.Abs((center - hit).normalized.x) should also be equivalent to what I said, with the added benefit of y and z being easy to access too.
this seems way easy i can try
You probably don't want to use Mathf.Abs because you want to hit the left/bottom side as well
I was assuming they meant "0 to 1" literally and wanted a "distance from center" value. If they do want the direction, then leave off the Abs and get -1 to 1, yeah
You can simplify this. But it would barely make any difference speed wise.
return method.GetBaseDefinition() != method
The only "faster" way to do it (afaik) is to create a property or method where you manually return true if you have overridden it in a derrived class (or perhaps an enum if you have C derived from B derived from A etc). This is a tedious, manual task, but is way better for performance as Reflection is really slow.
I was resorted to this method due to how unmaintainable the project is, not only that, it's based on the older or rather ancient framework.. I found a better solution to this 🙂
thanks guys!👍
for saving fields, would you rather have
this.SaveField(() => testVariable);```
or
```cs
this.SaveField("anyKeyString", testVariable);```
you're looking for style points or just want to ask for opinions 🙂
whatever floats your boat
any reason to choose the latter
Well, the first one would possible cause trouble with duplicate names
the implementation guarantees the field to be saved uniquely
Hello.
I have a size of 1 GB .apk file on the cloud, and I need to download and save it into the persistence data folder to execute when it is finished.
I got Access denied on the editor when I try to write it to the C:/
do you have any starting point for me
Directly writing to the root C:\ or in a subfolder?
Because I think writing to the root isn't allowed if you're not admin
also that isn't "the persistence data folder" on any system
Do they mean the roaming one? C:\Users\<user>\AppData\Roaming?
Or just anything under AppData
?
what are you trying to do
apk? c:/ drive?
Is there a way to run the profiler in standalone builds without the editor? Does anyone have experience with this?
yeah that's possible
How do people performance sample live games?
There is just so much noise on google it’s hard to find 🥺
Like the API for uploading a profiler report
Or if there’s a preexisting way to turn it into a more standard tracing format like chrome’s or jaeger’s
it's in the manual
If we need a loop inside a coroutine, what's the point of WaitForSeconds() ?
that question makes no sense. a loop doesn't change the execution speed of your program marginally. if you want to wait, you have to delay / wait for seconds.
A loop is for doing things multiple times. WaitForSeconds is for waiting before continuing the coroutine. The two aren't connected in any way.
Loops loop as fast as possible (like all code in unity except for the coroutine yield statements, it runs within a single frame)
WaitForSeconds waits.
Sometimes you want to wait in the middle of a loop.
Sometimes you loop without waiting
Sometimes you wait without looping
So a for loop speed isn't relative to the framerate
if I do for(float t = 0; t < duration; t+=Time.deltaTime)
It won't take "duration" amount of time
Only if you yield return null inside the loop
There is never any "waiting" in code unless it's in a coroutine and you ask for it to wait with a yield statement
Time.deltaTime is just a number, it doesn't do anything magical
So what kind of coding needs to be done to produce the kind of painting shown in this trailer?
Runtime mesh/texture manipulation?
The texture is almost definitely being modified on the GPU with shaders. Setting pixels one by one on the CPU is too slow.
That’s most likely the case. Atleast with unity the most expensive part of manipulating textures using cpu is applying the changes. Changing few pixels on cpu isn’t really that expensive but the applying part is (well if the image is reasonable sized (something like 1000x1000) and the texture doesnt use mipmaps, youre most likely not having problems running the app at 60fps or so) . In any case gpus are much (really a lot) more optimized on this type of things
help
used PrefabAssetType.Model and it worked ty
Ight so in this code (The List contains a list of scripts which then contain an abstract class for the AI) it saying the name of the coroutine does not exist in the current context, but it should?
all that it says is
i tried changing it and realized another issue, why is this script which inherits from monobehaviour not active?
I think RenderTexture could be helpful if you want to manipulate texture on gpu. You can take a look at Graphics.Blit if you want to modify rendertexture using a shader. I think you could do something using compute shaders too
Why do you think it's not active?
wait i think i figured out the issue
i did
fucj
nvm i solved it it was really dumb and just a simple mistake on my part
i'm trying to profile without the editor
i am imagining
1. a standalone player is built with
[RuntimeInitializeOnLoad]
static void StartProfiling() {
SomeAPI.Profile(filePathForReport: "report.bin");
}
2. upload "report.bin" to server
surely this must exist
Maybe you're looking for something like this. Unfortunately you need to collect all your data and convert to binary in your own format with this approach
https://docs.unity3d.com/ScriptReference/Unity.Profiling.ProfilerRecorder.html
are you aware of an asset / library that does the wiring already?
this is really helpful
i can grep.app this 🙂
no
who am i kidding
nobody is this sophisticated writing open source code for games lol
Um sorry no. I use this to get very limited amount of data from this for my game to display realtime performance stats for the user
🤮
yeah this is metrics
but i want those sick stacks
i don't see the tracing (yet)
looks like they wrote their own tracing for build logger
and it doesn't use the Profiler tracing
they must have a tracing agent
Are you looking to profile building pipeline? Or trying to profile player?
it's impossible to google for this stuff - "tracing"
i'm trying to profile the player
i was chasing a possibility that this code uses the Unity Profiler's tracing
but it does not
they wrote their own tracing... for some reason
why not just make one yourself
i can definitely use jaeger's c# client
but unity already has a high quality tracer
i need the rendering instrumentation anyway
which i could not do myself
i'd have to e.g. fork HDRP and change all their calls to profiler
and that wouldn't give me that much in the end anyway
if (!Application.isPlaying || points_buffer == null || (points_buffer != null && num_points != points_buffer.count))
Hi, this line in my compute shader marching cubes algorithm is giving me this error:
Parameter name: _unity_self```
I don't know what I should do to fix it, all I know is that `points_buffer` is the null value and google doesn't have much to offer on this situation.
points_buffer is a ComputeBuffer so if I initialize it early, it will be angry for poor garbage collection
It doesn't make sense to me that it would be so sensitive to whether points_buffer is null, because that case is accounted for in the if statement
Here's the whole method:
void CreateBuffers()
{
int num_points = points_per_axis * points_per_axis * points_per_axis;
int num_voxels_per_axis = points_per_axis - 1;
int num_voxels = num_voxels_per_axis * num_voxels_per_axis * num_voxels_per_axis;
int max_triangle_count = num_voxels * 5;
// Always create buffers in editor (since buffers are released immediately to prevent memory leak)
// Otherwise, only create if null or if size has changed
if (!Application.isPlaying || points_buffer == null || (points_buffer != null && num_points != points_buffer.count))
{
ReleaseBuffers();
triangle_buffer = new ComputeBuffer(max_triangle_count, sizeof(float) * 3 * 3, ComputeBufferType.Append);
points_buffer = new ComputeBuffer(num_points, sizeof(float) * 4);
tri_count_buffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
}
}
what line is it saying the error occurs on
!Application.isPlaying this is toxic
are you Releaseing a null buffer
Can you explain? I'm rewriting someone's code, so their logic isn't entirely clear to me. He does a lot of Application.isPlaying checks.
@round pawn It throws that exception if you .Release a buffer and then later try to access .count on it.
Calling Release will not make it compare == null, so that check doesn't save you, but does make calling .count invalid.
Ahhh, that makes sense
You can either set your reference to null after Releaseing, or check IsValid() before accessing count I believe
the buffers still need to be released when the application isn't playing, if it makes sense to do so
is there a way to insert a one-time function execution in a DOTween sequence?
so as opposed to an oncomplete
it can happen at a specified time?
InsertCallback 🙂
I applied your logic and it works exactly how i want it gives value from centre to raycast impact point (0 - 0.999) without multiplying the radius, can you explain why you said to multiply with radius, is it necessary. And one more thing the values in the normalize vector between hit and centre are negative also as it should be for x < 0f and y <0f, is there a way to always return positive value with some vector3 function or i have to manually check and multiply with -1 each vector value.
Hello, I recently jumped from unity 5.x to the 2021 version (Big Jump!) I am in the process of learning the new Unity.Netcode functions and the issue I am having now is that I cannot send GameObject references via ServerRpc calls. Does anyone have recommendations to get around this?
Unity 5.x worked:
void CmdThisGuy(GameObject objWithNetworkIdentity)
Unity 2021 Does not work:
void ThisGuyServerRpc(GameObject objWithNetworkObject)
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace XUnits
{
public class DatabaseTest
{
[field: SerializeField] private List<ScriptableUnitDatabase> databases { get; set; }
[Test]
public void DatabaseTestSimplePasses()``` ive got that code in a unit test script but it ( unity editor ) cant resolve ScriptableUnitDatabase BUT Visual studio can resolve it..
```using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace XUnits
{
[CreateAssetMenu(fileName = "UnitDatabase", menuName = "Units/Database")]
public class ScriptableUnitDatabase : ScriptableObject````
Hey everyone, I'm trying to make a card game just for funzies and I'm cracking my head open about how to create kind of generic ScriptableObjects that represent every possible kind of card that my game contains.
So, my cards are ScriptableObjects that have an effect, and this is the script representing the effect:
I wanted to represent the whole possible range of things a card can do here.
For example: A card that has condition "RaceCardPlayed", Suffix "All", Target "Race" and EffectTarget "Health" would read: When a X race card is played, ALL X race cards you control receive + Y health.
However, this doesn't really work as a single file would need to have space for all kinds of references, like possibly reference to health, damage, card, class, all units in the scene, available skills... not easily modular at all.
But creating different ScriptableObjects for different groups of effects don't really seem to work as well, since there are a multitude of groups of enums here that interact with each other, it's not really a vertical hierarchy such as "Card -> Battlecard" or "Card -> Spellcard". I would need "Passive -> RaceCardPlayedAllClassHealthEffectPassive" or things like that.
How would you handle this situation?
I'm currently working on a mobile game that requires the use of abilities, each defined with a bunch of properties (target type, sub stat to be used, etc.)
I handled it by creating the AbilityDefinition which also contains what I call templates. Objects which essentially store everything an ability can have, and I show/hide things you can change based on what the designer selects via enums.
However, this was really only possible (for me, since I don't really do editor scripting), with Odin Inspector.
You can see the list of sub stat modifiers (2 elements), but customized differently.
Another example I use this is with events in the game. Needed a way to "generically" define an event to be used, and more importantly the results of that event. Each option is a list of results EventOptionTemplate, which shows/hides properties based on the type (enum) selected.
So, that's all to say, the only way I've handled it was basically giving the SO all the properties of the definition and let the designer fill in what's needed. Then at runtime, you just make informed decisions based on those properties (if something was flagged true, or a specific enum was set).
i would recommend reading this series of articles of recreating hearthstone:
https://theliquidfire.com/2017/08/21/make-a-ccg-intro/
generally his solution is to have an generic event system that any card can post a notifcation to, and any card can subscribe to any notifcation. so a card can subscribe to "if a race card was played", and if it was then activate the effect of buff health. i would make any effect like that a class, and then in the buff health class have an int to decide how much to buff health.
im currently working on understanding that system too so i dont know exactly how it works but it seems promising and scalable to me
i would generally make cards scriptable objects, and everything that can make up the cards can be classes/enums that you can include in the scriptable card fields
Hey-o, I was wondering what the status of using Expression Trees at runtime was?
I was reading that they don't work on IOS, or maybe when using IL2CPP...? Or both? It wasn't really clear to me and was hoping for some insight.
Thanks a bunch! Your system seems reaally nice and similar to what I'm trying to do. I was thinking exactly about finally giving in and purchase Odin, as I knew they have toggleable inspector thingies. I'm still not entirely comfortable with having basically all possible references inside the script and just have them "turned off" in the inspector, but your idea of having these template objects may be really interesting to have some sort of separation.
I don’t understand the burst documentation. It says
“When running a Burst job in the editor, the first attempt to call the job will cause the asynchronous compilation of the Burst job to be kicked off in the background, while running the managed C# job in the mean time.”
I thought everything needs to be compiled before the program can even start. And even if it could, Wouldn’t it be best if it was compiled before the game even begins to prevent unnecessary slowdown in game?
I'm not sure if this is exactly how it works as I don't have a great handle on how Burst compiles, but I would imagine that it's similar to non IL2CPP, where the code is compiled into IL, and then it is JIT compiled into machine code at runtime. This only happens in the editor so you don't have to waste time compiling things that are not used, and it's also cached—so it will only get recompiled if the IL changes.
Ah, this option is for running the code in the editor, not the binary. Thank you
hello
I am trying to load audio clip from raw data
raw data means compressed audio data
audio compression is Vorbis
i can only load it through Fmod native C++ code but i want to do it with unity
any help pls?
i am asking for 5 days continuously but no one is responding
i know Unity has the correct api to do this as well but there is no example for how to
https://github.com/khindemit/unity-wrapper-vorbis here's a plugin that maybe does that
You can dig into the source or use it as is
i dont just need vorbis
i want to support most likely all audio formats in UnityEngine.AudioCompressionFormat
except the mp3 format cuz its normal and can be read easily
You said vorbis in your opening post :l
sorry i forgot to say the whole thing
i want to dynamically load all compression formats
Still, that plugin may give you some insights
yes its a native plugin
As far as unity apis is concerned
it reads from the path and load as VorbisOGG
but i want to save the vorbis to mp3
like convert all compressed audios to mp3
and it can convert an audio clip to vorbis and save to filestream
which is something i really dont need
any ideas for how can i convert
i tried FMOD
But FMOD is in C++ and it is hard
You can use ffmpeg to convert audio files
ffmpeg -i file.ogg compressed.mp3
Why do you want to convert from OGG to MP3 though? That will double-compress the audio and seriously harm the quality
Looks like it supports reading anything in that unity supports
one question
i dont have audio type
i have audio bytes which are compressed
so audio compression is someway related to audio types
.ogg
.mp3
.wav
If you want to determine which format the file is in, you can read the header
For example, if the file starts with four bytes corresponding to the ASCII string RIFF, it's probably a wav
vorbis is most likely .fsb
Can you decide whether my link works before you continue this debate
ohk
You can't load fsb files in Unity like that though
Not using the above API anyway
You would need to use FMOD for Unity to load those
i am using FMOD
i also used FMOD factory
but it didnt work
all C++ native libraries
I thought you were just trying to load audio at runtime
I did too
same
succeeded?
No I thought that's what you wanted to do lol
I thought you wanted to load OGG files, but you didn't know the format they were in
So you wanted to convert everything to MP3
no
if it were the audio type then i have a complete enum that specifies the format
{
case AudioType.ACC:
return ".m4a";
case AudioType.AIFF:
return ".aif";
case AudioType.IT:
return ".it";
case AudioType.MOD:
return ".mod";
case AudioType.MPEG:
return ".mp3";
case AudioType.OGGVORBIS:
return ".ogg";
case AudioType.S3M:
return ".s3m";
case AudioType.WAV:
return ".wav";
case AudioType.XM:
return ".xm";
case AudioType.XMA:
return ".wav";
case AudioType.VAG:
return ".vag";
case AudioType.AUDIOQUEUE:
return ".fsb";
}```
for audio type 0
it would be m4a
but i am using Compressed audio
I'm not sure why this matters, do you have more information on what you're doing?
loading compressed audio in unity on runtime
Do these audio files originate from within your project or something?
originate from my code
loaded from raw serialized bytes
Then just reference the AudioClip?
There's a communication error here, I thought you had something like:
game/
game.exe
game_Data/
StreamingAssets/
sound.ogg
and you wanted to load sound.ogg
lol no
Then is the audio file in your project, in Assets?
i am trying to load all audio compressions in unity on runtime
let me show something
here is a library that allows you to load texture 2d from any texture format and saves it to directory as a .png
done by me
same work i am trying with audio clips
compressed one
So you have an AudioClip and you want to save it to a file at runtime then?
like changing their compressions
nope
i have raw bytes of an audio clip which is serialized
most likely audio data
How are you getting these bytes?
I'm so confused
btw there's a port of NAudio for Unity.. but quite ancient https://github.com/WulfMarius/NAudio-Unity
Hello. I'm creating a LimitedList<T> : List<T> class with the int Limit property. How do I serialize it so that it is displayed in the inspector? Do I really need to create a custom drawer?
Yes, you will need to create your own property drawer
You need to add the Serializable attribute
To your cladd
Class
Yea, I already discovered that
TIL you can use FLAC in Unity natively, just do (AudioType)7
I noticed that AudioType actually maps directly to the FMOD_SOUND_TYPE enum
Which has FMOD_SOUND_TYPE_FLAC defined as 7, then I looked at AudioType in the reference sources and it's indeed there, just commented out
I assume it's commented because either
A. They don't support FLAC on platforms that don't use FMOD
B. It wasn't exposed originally so nobody has gone through the process to make it a public API
I tested and it works perfectly fine in both editor and build on Windows at least
NAudio already works fine in Unity as-is, I've used it in production before. This is probably for really old Unity versions or something, though it was last updated in 2018 so who knows
if its a serialized encoded byte[] you would need to decode the audio samples to raw audio (uncompressed PCM)
for wav files its simple since the uncompressed audio is directly available after first 44 bytes (header).
https://docs.unity3d.com/ScriptReference/AudioClip.SetData.html
you can alternatively use UnityWebRequest to get the audio clip itself directly. but this is limited only for a file/url
https://docs.unity3d.com/ScriptReference/Networking.UnityWebRequestMultimedia.GetAudioClip.html
if you're creating a library, saving to file and unsaving would not likely be an option for you
also beware of the bits per sample in Unity. many audio formats still store the audio in 16bits per sample, but unity expects a 32bits/sample (floating pt)
I have a clarification question.
If I have a interface with methods that take/return System.object, and I implement them in a generic class with generic overloads. And then I have a variable of that interface assigned to an instance of the generic class.
When calling the methods, does it use the generic ones if possible?
Yes
To call the object overload, you need to pass in an object, meaning you'll need to cast in most cases
There are exceptions though, mostly related to constraints and multiple type parameters
When in doubt, hover over the call in your IDE
Right, so this would be correct?
interface IGetSet { object Get(); void Set(object value); }
class GenericGetSet<T> : IGetSet
{
public T Get() { .. }
public void Set(T value) { .. }
object IGetSet.Get() { return Get(); }
void IGetSet.Set(object value) { Set((T)value); }
}
// In some class...
IGetSet _getSet = new GenericGetSet<float>();
// This will use the generic imp and avoid boxing correct?
_getSet.Set(0.5f);
No, that will call the non-generic implementation
Dang it...
You will need another IGetSet<T> interface, and use that
Or just use GenericGetSet<T> directly
Yeah, that won't work for my use case as I don't know the type
Then yeah, you can't call the generic version
Generics require you to know the type
You can avoid the boxing though, with a bit of work
Oh?
You need to implement a Variant type
public readonly struct Variant
{
readonly object typeOrValue;
readonly VariantUnion value;
[StructLayout(LayoutKind.Explicit)]
struct VariantUnion
{
[FieldOffset(0)]
public int Int32;
[FieldOffset(0)]
public float Single;
[FieldOffset(0)]
public double Double;
// etc
}
public Variant(float value)
{
typeOrValue = typeof(float);
this.value = new VariantUnion { Single = value };
}
}
You would use Variant instead of object
Then you can implement cast operators on this
To store a class in a Variant, you'd store it in typeOrValue
if typeOrValue is a Type object, the value is in the union
Clever approach
I tried using variants ages ago but it went over my head at the time
Never heard of variants before, I was just looking them up, but this is great.
This is quite interesting, it isn't quite clicking for me though. I think I have two questions, firstly, why store the type? And secondly, if you have an object value, you would still need to box it correct?
If you don't store the type, you don't know what's in the variant
Also for reference, there's a proposal to add a variant type to .NET officially: https://github.com/dotnet/runtime/issues/28882
Oh of course, you need the type for getting the value back out
There is an example implementation you can look at
And secondly, if you have an object value, you would still need to box it correct?
If you have anobject, it is already either a boxed value or a reference type
The idea is that you would use Variant everywhere instead of object, which will avoid boxing value types
public interface IGetSet
{
public Variant Get();
public void Set(Variant value);
}
For insight, my usecase is that I will be getting/setting 'base types' (int, float, bool, Vector3, etc.) via reflection (or actions and functions)
If you're doing this via reflection, you cannot avoid the boxing
At least, not in many cases
Reflection is super allocatey with few exceptions
Presumably there'd be some kind of lambda compiling
At which point I have to wonder if maybe this should be approached differently
Since that's not super AOT friendly
I think this is editor only?
If it's editor-only you have more options yeah
You're doing SO variants right
Yeah, that is what I thought. No, it is runtime sadly
I am, but unrelated to this.
Do you have more information on the scenario?
Ohk
What types are you wanting to set values on? What do they look like? Etc
Do you control the classes/structures you're working with?
Yeah, I am working on an editor tool that lets you connect up properties of different class so that you can have them drive each other. So, if you have a WindController from one asset, you can have it's WindStrength property control the wind setting in your audio controller and you sky and water material etc.
So it will only be working with numeric types, and maybe bools.
Why do generics and not just have a serialized object like class with boolvalue, intvalue, etc
I was just trying to figure out how to make it performant and avoid boxing
Generics in no way are required
I think just doing a so type thing would work fine
Variant is like that but a bit more space efficient I guess
What do you mean?
Doing an SO type thing
Serialized object
Sorry, typing on my phone
Not the best way to talk about code lol
lol
@final steeple Thanks for letting me know about that variant (pattern?). It solved an issue I was having in a much cleaner way than I was.
Not related to that, but man are delagates fancy, they can take simple GetValue reflection code from like 21ms to 3ms (over 10k iterations)
(The variant will let me setup math operations really easy!)
Variants are super handy yeah
They're pretty easy to get used to and very efficient
I was going to have like classes with an array of the value and then add/subtract/multiply/divide methods you would override and all sorts of stuff. This is so much cleaner haha.
Random thing, but can anyone explain the syntax for operator overloading and implicit casting?
To me the ordering of the keywords seems nonsensical and inconsistent. Am I missing something for why it makes sense and is logical?
example?
To me it seems like it should be public static operator Data +(Data a, Data b) {.. }
As that would make it consistent with implicit conversion public static implicit operator Data(float f) {.. }
You could consider operator+ the "name" of the function
the difference is, with implicit, you don't care about any operator so theres just 'an' operator. with operator overloading you care about what operator to overload operator + not operator Data
and if you go after 'normal' c# method declarations........you can't start a method name with a non-word character
I guess, but that would then make implicit the 'return type' of implicit conversion method (ish)
Not quite, implicit is a modifier, like unsafe or checked/unchecked
+1
For an implicit or explicit operator, there is no "name" only a return type, hence why that's used as a "name"
a better question is: why is it not possible to declare methods only differentiated by the return type???
Because the return type is not part of the signature in IL
Why isn't it? Couldn't tell you
Same goes for generic constraints
the IL allows for methods only differentiated by return type though
Maybe I was misremembering and thinking of constraints then
It almost makes sense, the operator keyword sort of switching its meaning between being a keyword when used with implicit to be a 'name' when using for operators
But either way the syntax would be pretty weird since you could only call such methods by casting the result or relying on target-typing
yeah, but if you need 'casting' that'd be fine with me. the compiler can optimize that away
It's not an optimization problem, really
It's just weird-looking syntax and non obvious
I think overloading on return type would be very useful, don't get me wrong
but there are syntax problems to work out for sure
🤷
yeah
stackalloc can give you either a T* or a Span<T> depending on the target type
(and also whether it's used in an expression or not)
Like if I (mentally) add a method name to a implicit conversion method it makes sense to me now. And I guess if I look at the operator as part of the name of the operator overloading it also makes sense. I still say it is funky syntax though. I think I will at least be able to remember it now though.
Thanks guys.
var a = stackalloc byte[1]; // byte*
var b = (stackalloc byte[1]); // Span<byte>
var c = (Span<byte>)stackalloc byte[1]; // Span<byte>
SomeMethod(stackalloc byte[1]); // always Span<byte>
👍
span is a bit wierd. i can't quite understand is why you have to fixed a span to get the raw pointer....since span is already pretty much that
Because Span can refer to managed memory, which can be moved by the garbage collector
Since Span can refer to any kind of memory, it needs to account for that in its API
ah, right
So if you need a pointer, you need to ensure it's pinned
If you know that the span is pointing to memory that is already pinned though, you can do Unsafe.AsPointer(ref MemoryMarshal.GetReference(span))
Which will avoid any overhead of fixing
nice
and i really need a 'simple' fixed statement. if you have to pin 5 or more types, the indentation is killing the code
(on that note, everything is technically pinned always in Unity, because the GC used by Unity (Boehm) doesn't do any compaction of the heap, and thus nothing moves)
don't rely on that if you ever want to move to a version of Unity using CoreCLR though lol
that is not to be taken into account though. with any code you write. they will use CoreCLR in the future where that's not true
You can have fast paths for it, which I do in a few places
You just have to guard it behind an "IsUnityMono" check
Most of the time it's more effort than it's worth though
bleargh
You'd only want to do it in a really hot path
also do you have an example of this? Preferably a real-world example from your code, there might be a nicer way to handle it
A lot of the time you can avoid the need to pin altogether using MemoryMarshal APIs
A simpler fixed like there is for using has been proposed before, but if I recall correctly it was rejected because pinning is generally something you want to be short-lived
Having the simpler syntax would mean more code fixing addresses longer than necessary due to the lack of blocks
well, still (almost) the same code from a few days ago. but it's kinda ok, since i only have to fixed 3 times. and i guess most is managed, so not sure how effective memorymarshal would be
Ah, yeah a lot of that code didn't actually need to fix anything at all
But there was a lot of code and I was worn out so I didn't bother getting into the specifics lmao
For the most part though, stackalloc + using pointers and avoiding marshalling would help significantly there
yeah, i may look into that. it's fine for now. but still, a using like - simple fixed would still be nice, roslyn doesn't have to recommend using it, but i pretty much have to pin for the entire duration of the method, so it'd help
If you need to do that, you can have an overload that takes pointers
public void A(ref int a, ref int b)
{
fixed (int* pA = &a)
fixed (int* pB = &b)
{
InternalA(pA, pB);
}
}
void InternalA(int* a, int* b)
{
}
.......which shifts the pinning to calling code.....which i also don't want
oh wait. ahh i see
I've used that approach several times, usually when interacting with native APIs that take a lot of strings
i don't imagine you have experience with any WebAuthN api?
Nope
Sort of, it depends
yeah......not getting around pinning memory then
How long are these strings?
about 20 chars prob
oh you can definitely do that on the stack
but variable length
yup, span helps there
ok, so how? using char[] instead of string?
writing up an example right now
Debug.Assert(input.Length <= 15);
var buffer = stackalloc char[16]; // 15 + 1 for null terminator
input.CopyTo(new Span<char>(buffer, 15));
buffer[input.Length] = '\0';
// pass buffer pointer to native
that's to fit a maximum of 15 chars
increase as necessary
ah, ok, imma try that.
Basically you just copy the data you need into the stack and pass that along
Which can be more efficient for small amounts of data
:/ just noticed you can't json serialize ref structs
Yeah, ref structs can't be used in generics either, because it would allow them to be boxed
If you need to serialize it, it probably shouldn't be a ref struct to begin with
What does this ref struct contain?
i mean i'd like to, it's small enough for ref struct probably, and it would also be more secure for the data. but i have to (de-)serialize from and to json
Why does it need to be a ref struct and not a normal struct?
so it won't be allocated on the heap
structs are only allocated on the heap if you choose to allocate them there
which would make it managed again
If you really want to serialize it to/from json, you can have another struct that contains the actual data but is private, and you serialize that
public ref struct A
{
Storage storage;
public int Value
{
get => storage.Value;
set => storage.Value = value;
}
public static A FromJson(string json)
{
// ...
}
struct Storage
{
public int Value;
}
}
But all that said, I'm not really sure it has to be a ref struct here
If you pass it by value, it's already pinned
If you pass it by ref, you can just pass it by pointer instead to ensure the values you receive are pinned
that doesn't work btw. ref structs can only contains other ref struct fields
That's not true
A ref struct is identical to a normal struct except:
- It can only be stored on the stack or in unmanaged memory
- It is allowed to contain byref-like fields (such as a Span<T>)
- It cannot be boxed as a result of #1, and therefore cannot be used as a generic parameter (because the
ref struct-ness information is lost)
my bad. i just tested it. but i could've sworn ref structs were only allowed to have ref struct fields....
Only a ref struct can contain a field of a ref struct type, that much is true
But a ref struct can still contain any other type of field
right
I still hate that it's called a "ref" struct
Because it's not passed by ref
It just means that it's allowed to contain ref-like fields
i don't mind the ref
This confusion has been propagated to Unity's multiplayer code, in documentation they imply that they're passed by ref
Which is outright wrong
what?
Let me find the snippet
Two-way serializer wrapping FastBufferReader or FastBufferWriter.
Ref structs help enforce both of those rules: they can't out live the stack context in which they were created, and they're always passed by reference no matter what.
Which is just... completely wrong
I hope that's just a documentation mistake and they don't actually think these are being passed by ref...
thats.........terrible
i'm not so sure that that's 'just' a documentation error
pls do
I first noticed this months ago lmao
Just completely forgot to get around to reporting it
hmmm....anyway, i'd like the public api to disallow saving the data in a class which would put it on the heap. -> bad for security and would bug out memorymarshal
that's why i was thinking about ref struct
As long as the input API takes pointers it's safe, but that's up to you as an API author
Since the native API holds onto the pointers you give it (I assume), refs aren't safe since they'll only be pinned for the duration of the method
I suppose there's also the option of internally storing a pointer, and you just have a struct wrapping it
Which would make it safe to store anywhere
But then you need to allocate and free the memory manually
nah, i can imagine that being a back breaker
It's a bit of a pain, yeah
I suppose a SafeHandle would make it not too bad, but eh
and, i don't want to store it anywhere. only the stack
Then yeah, you'll need to have a proxy type if you want to serialize it
yeah. i'll try some things and see how it goes
sorry to bother you again but how can i do this:
public ref struct MyRefStruct
{
public MyRefStruct()
{
Type = stackalloc char["myString".Length]; //this does not work
"myString".CopyTo(Type);
}
public int Alg { get; set; } = -7;
public Span<char> Type { get; set; }
}
You need to take the buffer as input, rather than allocating it in the constructor
Also you generally don't want to do a "dynamic stackalloc", always prefer a constant length
but my strings are variable length
Yes, you need to allocate a buffer of the maximum size
and then slice it
a variable length stackalloc is much more expensive than a constant one
oooof. call that memory waste
It's memory that you can't really avoid "wasting" without paying a significant cost
that could easily turn into a stackoverflow
You will be more likely to stackoverflow with a dynamic stackalloc
Check out the internal ValueStringBuilder type for an example of how this is often done:
unlikely. because my strings might very well be shorter, not longer than 20 char
Either way, you should always stackalloc 21 chars in that case
(You need an extra char for a null terminator)
do i? i don't really care for termination
If you're passing a pointer to native code you do
damn
Otherwise it can read out of bounds
There is one exception and that's if the API also takes a length for the string
But in general you'll want to always null terminate for safety
anyway, how is dynamic stackalloc more expensive than 'arbitrary cost number' stackalloc?
Because it can't be optimized statically
ah
And it requires more code to perform
Look at the JIT output for a dynamic vs static stackalloc on sharplab
yeah i should do that XD
C#/VB/F# compiler playground.
It requires a loop and is just all around really inefficient compared to a constant size
yeah. can see that
I have 2 libraries
one is x86 and other is x64
i want to add both
how can i do so?
Typically you'll have a threshold where instead of the stack, you switch to a heap buffer (pinning it if necessary)
Put them in Plugins/x86 and Plugins/x86_64 and set up the platforms in the inspector
something else: does a literal string "myString" for example, already contain the null terminator or do i have to ad it? couldn't find anything on the internet
ohk
They're always null terminated so that you can safely pin a string and pass the pointer to native code
ok, good
However the null terminator is not reflected by Length and is otherwise "hidden"
yeah
It's basically just there to help you when you're working with native code/pointers
you cannot stackalloc ref structs???
You can, but only as a pointer
because getting a span would require generics
var ptr = stackalloc MyRefStruct[500];
DoSomething(ptr, count);
bleargh. lets. please. support. ref. constraints.
allow T : ref struct will probably happen in the next C# version
11?
Yeah, I believe so
i hope so
tracking issue
that should allow stackalloc-ing ref structs then, right?
it's scheduled for .NET 7 which places it in C# 11
yeah, because the issue isn't that you can't stackalloc them, it's that they can't be used in generics and therefore you can't use a Span<RefStruct>
So that will "just work" as a result of fixing this
too bad. not available in preview yet
It's not even implemented in the language yet, still being designed
yeah XD
At the moment the syntax seems like it will be allow T : ref struct
but there's no guarantee yet
allow T : ref struct ? shouldn't it be where T : ref struct?
ahh, yeah makes sense
Similarly, there may be allow T : static at some point
tf does that do?
To allow static classes in generics
Which would be useful once they can implement interfaces with only static members
ahhh,
ok, sometimes i just cannot understand roslyn. i am stackalloc-ing a ref struct to a pointer, the ref struct only has value types and span, and my stackalloc is complaining about: 'cannot take address of managed type myRefStruct'
If the ref struct contains managed references (which is what a Span is), then you can't get a pointer to it yeah
wait what? but span is ......... ref struct
A span is a ref struct containing a ref and a length
a ref is managed
ref struct Span<T>
{
ref T reference;
int length;
}
is a rough definition for what Span is
yeah i know........but i have no managed type in my span stackalloc myRefStruct[] which contains Span<char> type = stackalloc char[16]
You'll need to change that struct to contain char* instead of Span<char>
or make your own UnmanagedSpan<T> type
But if you need to stackalloc a struct that itself contains a span, that seems suspicious
I'm assuming you want to pass MyRefStruct to native code
In which case it shouldn't contain a span
because a span can't be sent to native code
(the pointer within the span can, if pinned)
no. it's just the json tree. it's made up of multiple objects, which are nested in each other. i'm only ever passing specific values from those to the native interop structs (which take pointers 90% of the time)
Do you have a more complete example of the types? It's almost 3am so my brain is having a hard time visualizing the whole thing lol
Ah in this particular case you probably can't avoid the fixing of those strings specifically
and currently i feel like i just started programming XD
Not without a lot of effort at least
public Span<char> Attestation { get; set; } = stackalloc char[7];
I had no idea that worked
I mean, it makes sense, but wow
TIL
it does work
It might be easier to implement this whole thing without worrying about the ref struct problem at first
and then you can look at transforming some types into ref structs after
Since right now there are a lot of unfortunate limitations that can make heavy ref struct usage a major pain to write
yeah, i can feel that
but yeah thanks anyway. maybe i'll get around to ref-struct-ifying this eventually, but for now i guess i'll keep fixed-ing my types
np
and i don't want to keep you up longer
It's definitely a struggle learning all this stuff lol
I wrote some REALLY bad interop code years ago
Eventually it comes naturally though
I actually noticed some of my older crappy repos getting forked recently, had to go archive them and add notes about them being bad code lmao
well, i mean, i don't have that many problems with writing the interop, but the improvement and not fixed-ing everything would've been nice
Yeah I just mean figuring out how best to make use of ref structs and all of the adjacent features
def
the thing is, i am writing PInvoke code for api's microsoft doesn't actually want you to PInvoke or work with at all. (don't tell 'em XD)
lmao
and so the great new source generator project (CSWin32) is not particularly helpful with this api. no documentation, just plain c structures, nothing else
I actually tried to google some of the functions when you posted the other code and it definitely seemed like a new API
There were almost no results at all
it's not new. it exists since .........i think 2017?
like i said, it doesn't seem like microsoft want's 'normal' devs to use this api
and this has been a side project for me for about 4 years now, but every time i found a lead on how to possibly use it in standalone applications, that lead died out after a few weeks, most sources / api end points getting deprecated pretty much right after i found them (had nothing to do with me though, just normal lifecycle) until i finally found my new lead about a week ago and this actually seems like the way to go
hooray
I think I should probably put this here, as it's turning out that this issue is much harder to solve than I thought it would be, and #archived-code-general Seems to be more for generic small questions instead of large issues like this.
Let me rephrase what I said in that channel:
So, I'm making a 2D pixel art game where you can fly around in a space ship in a randomly generated galaxy and do various different things.
Space is big. It's vastly, hugely, mind-bogglingly big. So to have a game environment that fits this famous quote I wrote a generator that generates a random galaxy based upon a couple of variables and a whole bunch of math.
Now, the problem is with rendering it.
This is a render of a galaxy with 25000 stars:
break it into chunks and load the chunks? the implementation of this is up to you tho and might be tricky depending upon your generation code
You can see the issue with this if you look at the top part of the image. Rendering this seems to be very expensive, and the framerate suffers from it. For more context, these are all rendered as 2D sprites.
Preferably I would like to have it be somewhat stable up to 100000 stars. More if possible, but I would be happy with that. Right now, not even 10000 stars runs at a stable 60FPS. I've done some test, and to get a mostly stable 60FPS you can only have up to 3000-5000 stars. For the record, I have a Ryzen 5 2600 and RX 570 8G.
are the sprites sprite renderer set to individual or chunk mode? that can make some different
I'm actually new to unity (though not to programming as a whole), so I don't know what that is. Could you please tell me more about that?
maybe thats a tilemap only thing hmm
its usually on the sprite renderer but i only see it on the tilemap renderer
yeah nvm its a tilemap thing
Yeah, that looks like a tilemap thing.
how are the sprites organized, are they just individual sprites
game objects tend to be very slow. you have to use some sort of batching (GPU instancing maybe?) to get rid of loads of heavy draw calls
I have a prefab GameObject. In the Start() method of the renderer, it goes through all of the stars and sets properties such as the size, color, a different texture for certain star types, etc.
I've been told that over in #archived-code-general too. I have looked into it, having both read up on it and watched some tutorials, but at least for now, it seems to be way too advanced for me and it all just goes over my head.
I just tried blindly following a tutorial (I know, bad thing to do), and of course that didn't end up leading anywhere.
https://www.youtube.com/watch?v=e5WXx4PQXpU maybe try this tutorial, it doesn't seem too hard
GPU instancing sounds hard, but it'll take you two minutes and completely change what you can do. Unity has made it so easy to do GPU instancing that there's no reason not to: don't get daunted by the complicated-sounding name.
it goes thru what it means too
It's one of the first search results, I watched it and it doesn't apply.
The thing is, all of these tutorials need me to input some kind of mesh into their game instancing, but I don't have a mesh, I'm using sprites, not 3D models.
If you really want to have that many starts, you just can't use thousands of gameObjects. You can see how Sebastian lague draw million of separate dust particles using GPU instancing: https://www.youtube.com/watch?v=PGk0rnyTa1U. If you feel like it's too complicated, you have to start with something simpler
Yup, pretty much.
Or too many objects
Make sure dynamic batching is on
Check the frame debugger to see why things aren't getting batched
I think you need a custom material
what material are you using for you sprites
cuz if you look here at the material panel theres a checkbox for gpu instancing
but its unchecked and unavailable for the default materials (ie like the lit sprite material from the 2d extras pack or w/e)
Default, I created a 2D Sprite GameObject, dragged the texture into it, and didn't change the material.
ah okay
Yup, that was one of the things I encountered too.
maybe if you make a custom material derived from the material you're using and just turn on gpu instancing then youll get the perfomance gains you want?
I tried that, but I couldn't find the default material in any of the packages.
I also tried creation a new material, and changing nothing except for GPU instancing, but that actually halved my FPS and made it so the sprites don't render anymore.
oof lol
how do i regenerate my packages folder? it seemingly empty all of a sudden, even stuff like URP isn't there lol
even tho it still works in game/im using the urp Sprite-Lit-Default material?
ah nvm you can just right click > create > material then set the shader to the default-lit-sprite material and enable gpu instancing
Man, there doesn't seem to be a way to speed up getting/setting values of fields via FieldInfo without using Emit/ExpressionTrees :/
yeah, basically
(This wouldn't be a problem for me if people actually followed C# guidelines and didn't create public fields)
There technically is for blittable types
But not for classes or non-blittable structs
Well actually in Unity you can
UnsafeUtility.GetFieldOffset
also I know you said this ages ago but I have literally never been able to remember the operator syntax, so you're not alone
You mean get fields within blittable types?
Marshal.OffsetOf will give you the offset of a field in a blittable struct
But Unity offers UnsafeUtility.GetFieldOffset which works for everything
I am really enjoying gleaning editor knowledge from you lol
lmao
there's so many nooks
Ah, well that is handy to know but yeah I don't think that will be useful?
You get the field offset, and then assign the value at that offset using unsafe code
Doesn't get much faster than that
It's basically a direct field assignment
Do you happen to have a resource for learning more about this?
And potential draw backs?
That's about it, yeah
As for learning about it, I don't really have any resources on-hand
Basically the logic is just, if you have the offset to the field, you know where it is in the object
So just don't mess up and you're all good?
So you can just get a pointer to the object, add the offset, and set it
yah, put on your bomb defusing gear and dive in
So let's say we have
class TestClass
{
public int ValueA;
public int ValueB;
}
We want to set ValueB via reflection
but that's slow
Let's say we have a FieldInfo for ValueB
You can call UnsafeUtility.GetFieldOffset with that to get the offset
From there, you can do:
byte* addr = null;
UnsafeUtility.CopyObjectAddressToPtr(obj, &addr);
*(int*)(addr + offset) = 600;
// ValueB is now 600
Keep in mind that since this doesn't pin the object, it's only safe in Unity where the GC doesn't move objects (this will change when Unity moves to CoreCLR)
There is a way to do it without that problem by either pinning the object, or using the Unsafe class, which requires an extra DLL since Unity isn't using a version of .NET with that class built in yet
This seems....risky...
Only if you use that code outside of Unity
This takes a minute to process, but I think I get it. Very neat!
The safe way is:
ref int valueB = ref Unsafe.AddByteOffset(ref Unsafe.As<StrongBox<int>>(a).Value, (nuint)o);
valueB = 600;
"safe"
There's currently an aliasing bug in .NET with regard to Unsafe.As<T>, but it's not a problem in Unity and the aliasing bug will (hopefully) be fixed soon
"Save" proceeds to use Unsafe

My other two options are to either say f-it and use straight up reflection, or to say f-it and generate a C# script that is then used at runtime...
though you need to subtract 16 from the offset when doing this, because the offset Unity gives you is the offset from the object address and not the object data address
Or rather, you need to subtract sizeof(nuint) * 2
is it unsafe wrt GC because GC can move the data in between getting the pointer and writing to it
So 8 on 32-bit, 16 on 64-bit
Working on a parser for a node graph. Each node can return different values and I need to handle that. Would the vistor pattern be appropriate for this?
I guess the parser will be the visitor and each node handles giving it the correct data.
