#archived-code-advanced

1 messages ยท Page 126 of 1

sly grove
#

you're taking the accumulated value and trying to add it each frame

#

of course that's going to be a problem

#

the reason it works when you have the identity line there is because if you reset your value to 0, then add the accumulated value, it will look qcorrect

#

the right way is really just to set the rotation directly based on the accumulated value, instead of using an additive approach

#

transform.rotation = Quaternion.AngleAxis(t.CurrentValue, axis);

proud finch
#

so use

#

ahh i see

#

thanks friend

#

also what is the difference between angleAxis and Euler?

sly grove
#

euler angles are x,y,z rotations

#

AngleAxis is a number of degrees and an axis around which to rotate

#

just two different ways of expressing a rotation

proud finch
#

but I can use .Euler right

sly grove
#

if you have a set of euler angles to use

#

based on the code right now it looks like you have an axis and an angle

proud finch
#

Okay, tysm

wooden compass
#

Hey, general question :
How are these type of games made please ? Here I'm referring to games that have programming / logic systems in their game like here "Human Resource Machine".

How's the right side panel where the player must write his logic handled through programming in Unity ? How do you handle loop in it ? How do you jump from one part to another in C# ? etc...

Here's a 3 minutes review of the game : https://www.youtube.com/watch?v=73bwLQQHExk

Human Resource Machine review and gameplay by Tomorrow Corportation! This is a programming and logic game from the creators of World of Goo and Little Inferno that'll test your brain and your ability to do things in quick, logical fashion. In this Human Resource Machine review I'm playing a review copy provided by the developers. Human Resource ...

โ–ถ Play video
sly grove
wooden compass
sly grove
#

it's a turing machine

#

i don't know that game in particular

#

It's not something you will learn in 5 minutes somewhere

wooden compass
#

That doesn't help me ๐Ÿฅฒ

sly grove
#

wow you watched all those videos in 30 seconds

#

It's the same as any other language except you skip the parsing/lexing part and you go straight to the AST representation of the program

wooden compass
#

No, it's just that they're low level languages

#

AST ?

sly grove
#

High level, low level, doesn't matter

#

Abstract Syntax Tree

mighty shore
#

does anyone know how to play AnimationClip without animator?

#

I have lots of animations and mapping them in Mechanism sounds like a nightmare

regal lava
#

The Animation component is still there but you need to change the clips to legacy to use it

lament salmon
mighty shore
#

I was thinking about buying the asset you mentioned, but it's almost 100 bucks. so I am wondering if I could just not use it

regal lava
#

I've been meaning to try Animancer

mighty shore
#

its kinda not cheap though...

regal lava
#

It's free unless you sell your game then you buy it for the license

mighty shore
#

what

#

I didn't know

#

wowee

regal lava
#

May be some premium features? Or maybe I am misremembering

mighty shore
#

Animancer Pro Features: you can try out the following features for FREE in the Unity Editor with Animancer Lite, but you will need to purchase Animancer Pro to use them in a runtime build or access the Source Code.

#

free version has a limited feature

#

how do I mark an animation legacy

regal lava
#

Ah, well shoot that stink. Was in a humble bundle for like 10 bucks a year or so ago ;p

regal lava
mighty shore
#

found it

echo coral
#

If you select more than one anim clip the inspector half breaks and shows the legacy option ๐Ÿค”

sterile thunder
#

How to ship my Unity devtools package as DLLs, without prefabs breaking

regal olive
#

Should you ever use coroutines for delaying anything in code?

lament salmon
#

That's their main use case, so yeah

regal olive
#

Is there any memory concerns?

#

like I need to use it to disable a particle effect after a second for example

sly grove
#

Also creating yield instructions also uses memory

tall ferry
oak halo
#

By hooking into BeginCameraRendering and EndCameraRendering in URP, I should be able to perform a LookAt on a billboard, such that when the final frame renders it appears to be facing each camera in the scene at the same time, right?

#

The reason I ask, is because I've attempted that but it appears that the final frame only shows the billboard with its LookAt facing ONE camera, not EVERY camera

#

Here is an example:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Rendering;
using static UnityEngine.GraphicsBuffer;

public class BillboardProcesser : MonoBehaviour
{
    public string billboardTag = "Billboard";

    void OnEnable()
    {
        RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering;
    }

    void OnDisable()
    {
        RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering;
    }

    void OnBeginCameraRendering(ScriptableRenderContext context, Camera cam)
    {
        GameObject[] billboards = GameObject.FindGameObjectsWithTag(billboardTag);
        foreach (GameObject obj in billboards)
        {
            Transform billboardTransform = obj.transform;

            // Rotate the billboard to face the camera -- ONLY ON THE Y AXIS.
            Vector3 targetPostition = new Vector3(cam.transform.position.x, billboardTransform.position.y, cam.transform.position.z);
            billboardTransform.LookAt(targetPostition);
        }
    }
}
#

Visual: the billboard faces the scene camera dead on, but not the orbiting camera (bottom right)

#

Logging each LookAt I can see that each cameras render is properly adjusting the LookAt, but I think Unity is doing something weird behind the scenes and disregarding this

#

Unity appears to call a new BeginFrameRendering pass for EACH camera individually for the final frame, and moving the LookAt into that pass still yielded the same issue ๐Ÿค”

#

ex: seperate passes for SceneCamera and MainCamera

sly grove
#

Oh sorry I see you have one centralized processor here

#

rather than a MB on each billboard

#

so this wouldn't exactly work. At least - not unless you could guarantee this central processor is "visible" to all cameras

oak halo
#

I actually gave that a shot, but for some reason it wouldn't fire at all on the billboard ๐Ÿ˜ญ

#

Honestly I'm kindof at a loss... I think there is a weird engine optimization occurring which causes these minute changes to not actually show in the cam views

#

I think I'm just going to sleep on it and hope one of you brilliant folks has some insight lol

oak halo
sly grove
#

I wonder if it's not actually just an issue with that. That little camera preview window might not trigger the full suite of render callbacks

oak halo
#

Both scene and game view, the orbit camera showed in the scene view actually renders to a RawImage in a UI widget

#

Here is an example

#

you can see in the scene view that the billboard points the rendering camera, but in the game view the rendertexture orbit camera does not show the LookAt result

sly grove
#

I only just now saw the billboard at all lol

oak halo
#

yeah sorry its a little subtle

#

if you compare left vs right in this case you can see the left scene view is pointed at the camera, but if you zoom into the render texture on the right (driver side window) you can see it's not facing the rendering camera

chilly heart
#

is it possible to have a script where you can serialize an event to add a certain listener to?

untold moth
abstract ermine
#

how do you guys get over analysis paralysis for big projects... ๐Ÿ˜‚

i feel like ive been debating the "best approach" for a system for weeks. albeit it is probably the most important system in the game... but still

serene pawn
humble leaf
#

You eventually reach the point of enlightment where you accept there is no best approach to anything.

#

The best approach in the moment is making progress, so just make it work for what you know what you have to accomplish now and let the future iterations and features figure themselves out.

oak halo
slate spoke
#

My project uses a custom procedural terrain generation system that stores the transforms of all the objects within it (which only exist as indirectly rendered meshes). The point of this is to be able to point a raycast at the terrain and "select" whichever object is closest to the hit point, which it finds using a KDTree algorithm. It works, but the KDTree search takes about half a second to process.

I wanna add an indicator for when the raycast is started that tells the user whether the area they're pointing the raycast at is within a certain radius of one of those objects. I'm not sure how to do that without trying to use the KDTree search every single frame, though

misty seal
dusty wigeon
slate spoke
dusty wigeon
#

You could also not calculate every frame, but every X frames

slate spoke
#

it's for a VR game that's gonna run on the Quest 3, it's a data visualization thing primarily

dusty wigeon
#

How many object we are talking about

slate spoke
#

roughly 900 total at any given point, but anywhere between like 5-50 per terrain tile

dusty wigeon
#

How many in total ?

#

Because 900 is not a lot, but 900,000 now is something else.

slate spoke
#

the full dataset is about 700k

#

but it's scaled so that only 900 are loaded in at any given point

dusty wigeon
#

I see, and how deep is your tree

slate spoke
#

each terrain tile has it's own tree

#

not sure about depth

#

(I didn't write the kdtree code)

dusty wigeon
#

I mean, if your tree is really deep, then it is usually. If it is really broad, it is useless also.

#

If you have not written the code, you should start there.

#

Write your own implementation.

slate spoke
#

given my deadline, that doesn't sound like a very efficient use of time

dusty wigeon
#

There is nothing we can do here. This issue is advanced and you do not have the appropriate knowledge to have a discussion where we could solve your issue.

#

At least, I won't try to help you more given that I have no idea how to help you without doing it for you.

slate spoke
#

:\

slate spoke
dusty wigeon
echo coral
#

A struct array will be all together in memory vs a class type array

dusty wigeon
#

In other words, instead of having class that points to your children, you would use ID to point to its children.

#

Then, you would obviously need to group up the data such as you reduce the amount of cache miss.

#

But obviously, its irrelevant if you are not ready to write your own implementation.

slate spoke
#

the amount of google searches for the terminology you're using I've having to do per message is uh.. Relli_LOL

dusty wigeon
#

I mean, we are in advanced, not in beginner.

#

You might want to switch there.

slate spoke
#

you're telling me to go to beginner to figure out how to improve a real-time search algorithm?

dusty wigeon
#

Im telling you to learn how to code before learning how to optimize

slate spoke
#

and you're treating me like a child lmao

dusty wigeon
#

Optimizing something you have not written or you do not understand is extremely hard.

dusty wigeon
#

And do not worry, I also needs to take a step back to understand what I am dealing with before attempting to modify it.

#

Everyday.

slate spoke
#

Trust me, I get it lol. All of my development for this game been almost exclusively optimization-focused

#

custom procedural terrain generation, indirect mesh rendering, etc all running on phone hardware

untold moth
#

Do you even need to do something complicated as a search?
Can you not do a sphere cast or something. Assuming your objects have colliders.

slate spoke
#

that's the thing, there are no actual objects because of the indirect mesh rendering

untold moth
#

Well, you could add some.

#

Even if temporarily

#

You do have transforms, do you not?

slate spoke
#

technically yes, though I had to make a custom transform class since normal Transforms seemingly have to be tied to a gameobject

echo coral
#

sounds like ecs should have been used from the start

slate spoke
#

the system I'm using for indirect mesh rendering does have some stuff set up for having objects in the scene as actual gameobjects, I might see if I can have it do that for objects within a certain radius of the player

#

ecs?

echo coral
#

usually combined with burst + jobs to greatly improve performance for certain tasks

slate spoke
#

oh, huh. That does sound like exactly what I was trying to implement manually lol

untold moth
#

Yeah. That's the issue with reinventing the wheel: you can't expect other tools that unity provides to work(like physics) without some hacks.
Should've probably looked at DOTs before starting.

dusty wigeon
#

Just for fun, are you sure you are not bulding the tree each frame instead of simply querying it ?

slate spoke
untold moth
#

I think proper profiling is in order as well. We don't even know what exactly is talking 0.5s at the moment.

slate spoke
echo coral
#

can you share some code?

dusty wigeon
#

Because 700k element is not a lot of a KDTree

#

Build: O(n log n)
Query: O(log n)

#

Drastically different.

untold moth
#

And on the other hand, if we're only dealing with loaded tiles, are there really 700k objects to search through at any given time?

slate spoke
slate spoke
untold moth
slate spoke
#

I think I did have it working like that at some point, it'd just freeze for a few seconds every time I did a query

slate spoke
slate spoke
# untold moth Did you profile?

not sure if I did at the time, but sampling from a smaller dataset resulted in shorter frame drops, so conclusions were drawn lol

untold moth
#

That's not conclusions. That's assumptions.
You're boasting about how experienced you are at optimizations by now, but it seems like you're skipping optimization rule 0 - always profile first. Optimize based on the profiling data. Make conclusions based on profiling data.

echo coral
#

blah blah
profile it right now ๐Ÿ˜

dusty wigeon
#

"What is a profiler ?"

#

I hope you are beyond that lol

slate spoke
#

It's not that I don't use profiler, I've just yet to look through the profile searching for things in the context of what we're trying to fix now

echo coral
#

how else do you expect to do this? wishful thinking and luck?

dusty wigeon
untold moth
#

And it would be even less efficient to optimize blindly

dusty wigeon
#

Sometimes I need to make a build which can take 1-4 hours depending on the project.

#

I still do it.

#

I have multiple computer to work on.

slate spoke
#

alright what do I need to be profiling specifically, then?

dusty wigeon
#

Or I do it at night.

dusty wigeon
slate spoke
#

:|

dusty wigeon
slate spoke
#

what should I be looking for within the profiler

#

is what I mean

dusty wigeon
#

I mean, your code.

#

Literraly...

echo coral
#

Look at big ass spike in framerate graph, find what took super long in that frame, go down the stack and READ

untold moth
#

And that's another reason why this question should have been in code beginner. Using the profiler is around the basics.

slate spoke
untold moth
# slate spoke

You'll need to use the hierarchy mode and sort it by CPU time.

echo coral
# slate spoke

build/enable "deep profiling" to get more info for calls

#

otherwise only unity managed stuff gets shown but yes you want to use the other view to better explore the stack of the calls.

#

you can also use Stopwatch to track how long things take yourself

dusty wigeon
#

Or use ProfileMarker to costumize the profiler

slate spoke
dusty wigeon
#

And we do not care, we are looking at relative.

slate spoke
#

...yeah so that's making the terrain generation take several minutes

untold moth
#

Then look at the related code and add profiler markers.

#

Also, if you're doing something heavy like terrain generation, it's a good idea to split it into several frames to avoid freezing your app

slate spoke
#

I am, somewhat

#

apparently not perfectly with how often this profiler is freezing

echo coral
#

i dread to think how this was written but usually best for tasks like that to be jobs or threaded

slate spoke
#

I use UniTask wherever I can

untold moth
#

Well, deep profiling would add some overhead depending on the code

echo coral
#

async doesnt automatically mean threading

#

unless you are running on another thread using it + awaiting result

slate spoke
echo coral
#

seeing Clone() doesn't bode well

#

Whats PritiveDataFrameColumn.Item doing then

untold moth
#

GC memory at that too.

#

And the whole player loop allocates even more, so I wouldn't be surprised if GC is the bottleneck

#

But yeah, cloning and marshalling memory(assuming that's what it is) doesn't help either.

slate spoke
# echo coral Whats ``PritiveDataFrameColumn.Item`` doing then

not sure how to check what specifically it's doing, but if I had to guess what it's from, it's likely the search that's done after the kdtree. The dataset is a list of lines from a series of transcripts, each line being a separate datapoint. After the datapoint is found with the KDTree, it goes through the whole dataset and finds all of the datapoints with the same file number and recreates the original full transcript

echo coral
#

ah i just realised you ofc cant share this code
can you describe with more specifics, whats allocating? is there any attempts to avoid heap allocation?

#

use of classes or structs?

#

as said, many things are contributing here

slate spoke
echo coral
#

ideally you would read yourself and identify problem areas

#

only soo much we here can do with no extra info ๐Ÿ˜ฆ

slate spoke
echo coral
#

why are functions async when nothing is awaited ๐Ÿ˜

slate spoke
#

likely from when I was originally figuring out how Tasks worked and was just spamming it everywhere Relli_LOL

echo coral
#

yea undo all of that

slate spoke
#

I've learned a lot since but there's remnants

echo coral
#

its not free to produce a Task

slate spoke
echo coral
#

an async function that does not await inside is a waste

untold moth
#

I'more curious what the heck are these abominations?
level.parq.df.Filter(level.parq.df["file_num"].ElementwiseEquals(fileNum))

slate spoke
echo coral
#

what is it from

slate spoke
#

but it's the only thing I can get methods from parquet.net to spit out that's useful to me

#

which is being used because the original dataset is a .parquet file

echo coral
#

your data needs to be in a good format to not be dog slow to read

slate spoke
#

which is a big reason why I don't like working with parquet files as well lol

#

but I'm stuck with it as far as I know

echo coral
#

for such large work its clear its not gonna fly anymore ๐Ÿ˜†

untold moth
#

You should probably cache the data in memory to avoid reading from file every time.

#

And also make it more readable.

slate spoke
#

it only reads the file once

#

I'll send the parquet parser script

untold moth
slate spoke
untold moth
#

Reading about DataFrame makes me think it's really not intended for use in real time apps like games.

slate spoke
#

but also I'd need to mess with the code included with parquet.net to create the methods necessary to output anything other than a dataframe, which I would assume involves reverse engineering parquet.net

untold moth
slate spoke
#

right, but you're saying instead of swapping to a better pre-existing solution, I should make a whole new one from scratch?

untold moth
#

You can use data frame when loading the data initially. But then you should put it in your own data structures optimized for you use case.

untold moth
#

DataFrame is intended for data analysis. Not real time applications.

slate spoke
#

What would be a good thing to convert it to, then?

untold moth
#

Your own data structure. I don't know what kind of data you're working, but a list of structs or classes with the data pulled from the data frame should do. Point is, you should not use it every frame or every query you're doing.

slate spoke
untold moth
slate spoke
#

I think it's currently unused, though

#

At one point I did try storing the dataset as an IList

#

I think it was meant to be a workaround for not being able to use a List with the custom indirect mesh renderer the project used to use

untold moth
#

I don't know about IList and don't see a point of using it there. Is it an interface?

Anyways, that's irrelevant at the moment. The point is that you need your own data structures and logic that would be able to search through them if needed.

echo coral
#

Well said, nothing i can add. Goodluck

scenic forge
#

I think I've also suggested a while ago that you process the data at build time and convert them to your own format that's tailored to your game, so you don't need Parquet.NET or whatever at runtime.

untold moth
#

Yeah, unless they expect to load new files at runtime.

slate spoke
#

it does need to be at least decently modular

#

the point of this whole project is to make a data visualization system that can be easily adapted to different datasets with visuals that can be easily modified

#

the more standardized, the better, in that context

slate spoke
untold moth
slate spoke
#

the datapoints determine where things are rendered lol

untold moth
#

If you need some data for rendering, then create a separate data structure for rendering that is compatible with however you're doing your rendering.

#

You could have a fixed array or a native collection that you fill with the data from your scene data.

slate spoke
#

said and done already lol

#

partially due to how much easier the GPUI asset I use now makes it

scenic forge
slate spoke
slate spoke
#

are you saying make a custom filetype?

untold moth
untold moth
# slate spoke are you saying make a custom filetype?

If you need custom file types, yes. But it wouldn't solve your current issue: loading data from disk is expensive, processing data with data analysis tools is expensive.

What you need is data in the memory that you can access easily. And make it easier to read the code too.

scenic forge
# slate spoke are you saying make a custom filetype?

I'll use a very simple example, let's say the data you are working with is just a list of numbers, and at runtime the game needs to access the data in the form of "give me the sum of number 123 to 456." If you are just using the data given to you directly, then every time the game asks you for a sum, you have not better way than to loop from number 123 to 456 and add them up.
But now you have the knowledge of what the data is like and how the game is going to access the data, you can first process the data in a way that makes it more performant to access. For this example, you can process the data in this way: the processed data is still a list of numbers, but the first number is the sum of all original numbers up to the first, the second number is the sum up to second, etc.
Now with processed data, if the game asks for "the sum of number 123 to 456," you simple just take processedData[456] - processedData[122] and that's it, so much faster than before.
Is "a list of numbers that are sums" a new file type? I don't know and it doesn't matter. The point is that look at how your game is going to use the data, and process your data in a way that makes your game's data access faster by front loading the calculations.

slate spoke
#

not necessarily the ordering of the data

#

I'm not sure what kinda ordering techniques would do much good for the stuff I'm doing with it, though

#

I guess the way it comes by default is good for getting full transcripts

#

but if I were to reorder that to attempt to benefit the coordinate searching, I would assume it'd mess that up

scenic forge
#

You can process your data into two copies, one copy that's good at accessing transcripts, another copy that's good at coordinate search.

#

You have endless freedom and possibilities, you are not confined by whatever Parquet supports.

slate spoke
#

True, but doing that too much would defeat the point of this project

#

it's gotta be easily adaptable

#

maybe if I were to also make a tool that does that dataset reordering automatically

untold moth
#

Universally adaptable app is a fantasy. It would require AGI to process truly arbitrary data.

Which is why you would need to put some constraints such that it is the responsibility of the data provider to provide data compatible with your apps.

#

If you standardize the input data such that there are always specific fields in specific order, you can then do whatever and however you want with it.

#

Whether it's recording or something else.

slate spoke
#

Fair enough then, I guess it's just a matter of figuring out what reordering works best for attempting to find coordinates within given 2D ranges

#

how would that work, then? if you were to make one dataset ordered by X coordinate and another by Z, then you'd have to figure out which datapoints match up between the two after filtering

untold moth
#

You could generate a quad tree for example.

But I'd start with a simple brute force search. I'm sure even that is gonna be faster than 0.5s with what you're doing now.

slate spoke
#

..is that not what's already happening?

untold moth
#

No. You're using DataFrame and what not which is the main bottleneck.

#

What a true brute force would look like is just looping an array/list of positions and caching the closest one to the target position. That's it.

slate spoke
#

I don't think the kdtree system does any searches with dataframes

#

or well nvm I think, you're right

#

yeah, lol

    // filters DataFrame by given bounds to determine which plants are on a chunk
    public async UniTask<DataFrame> GetDataFrameRange(DataFrame df, Vector2 min, Vector2 max)
    {
        level.debug.Log($"Creating chunk-specific DataFrame");

        if (df.Rows.Count <= 0)
        {
            Debug.LogError("DataFrame is empty (no plants are on this chunk), returning null");
            return null;
        }

        // TODO: There's gotta be a faster way to do this
        DataFrame tileDf = df;
        await UniTask.RunOnThreadPool(() =>
            { tileDf = tileDf.Filter(tileDf["umap_x"].ElementwiseGreaterThan(min.x)); });
        await UniTask.RunOnThreadPool(() =>
            { tileDf = tileDf.Filter(tileDf["umap_x"].ElementwiseLessThan(max.x)); });
        await UniTask.RunOnThreadPool(() =>
            { tileDf = tileDf.Filter(tileDf["umap_y"].ElementwiseGreaterThan(min.y)); });
        await UniTask.RunOnThreadPool(() =>
            { tileDf = tileDf.Filter(tileDf["umap_y"].ElementwiseLessThan(max.y)); });


        level.debug.Log("Chunk-specific DataFrame created");
        return tileDf;
    }```
#

// TODO: There's gotta be a faster way to do this

Smashcut to 4 months later: there was, in fact, a faster way to do this

#

Upon doing some googling for the custom filetype thing, I assume ScriptableObjects are my friend here

untold moth
#

You don't need a custom file type. Although it could help eventually.

slate spoke
#

Which implies storing the data in some other file

untold moth
#

Or if you're creating the data files yourself and have full control over it.

slate spoke
slate spoke
echo coral
echo coral
#

Do note that sometimes the work is too small for benefiting from using another thread (can turn out to be slower)

torpid knot
#

I'm back working on my game's enemies and I've run into a problem again - equipping gear.

#

So based on the enemy's "tier" it will randomly equip a selection of clothes, helmets, armor, weapon, yada yada yada

#

It was kind of a nightmare but I have it working. It really is a nightmare to manage, though, because I need to actually duplicate the base fbx out to its own separate thing and keep all of it updated.

#

My question is, how expensive would it really be if I just had all of the equipment spawned in, and selectively enabled/disabled stuff when needed? The enemy with everything spawned in is about 70 gameobjects,

#

On another hand, spawning in the prefabs separately basically copies the skeleton for every piece of gear, that's like 300 gameobjects

#

But they're just empties. I really don't know the internal workings of this and what is actually expensive so I would really appreciate some insight.

untold moth
torpid knot
#

I don't want there to be lag spikes when spawning in enemies

torpid knot
untold moth
untold moth
#

If you're really worried you should test both scenarios and profile them.

torpid knot
#

Oh the latter

#

mb

#

Wait so it is better or worse?

untold moth
#

It would be a little bit worse. In theory.

torpid knot
#

Because there are more empties? What actually affects the footprint?

untold moth
#

On practice, it might not be noticible

untold moth
#

And roughly speaking the more memory you need to instantiate/initialize, the more expensive it would be to instantiate the GameObject.

#

However, once it's loaded, it's just there. If the total amount of updated object during the frame is the same in both scenarios, there wouldn't be a difference during normal frames.

#

If you're really worried, you should test and profile both to see for yourself .

ivory aurora
#

Is there an event that can be subscribed to whenever objects are instantiated? (similar to sceneLoaded, sceneUnloaded, etc.)

tall ferry
kindred spindle
#

I have shared a relatively complex coding issue in coding general. Any advice is greatly appreciated.

ivory aurora
# tall ferry not that im aware of, it sounds like a bad idea to need something like this. if ...

Well, I didn't want to resort to modifying all the codes that use Instantiate. I wanted to translate texts and leave the project intact, without needing to modify the script or add extra components. I only wanted to modify fields that contain text or text-type components using search. I can check this when a scene starts, but I can't check the objects that are instantiated. It would be a worse idea to constantly check for new objects, so only using Instantiate is sufficient.

But I can't find an event in Unity that I can sign up for to check out just this part.

tall ferry
ivory aurora
tall ferry
ivory aurora
tall ferry
echo coral
#

Where I work our localisation system is to just use an id to get the translation string (depending on the current lang ofc) and set on text object/do something else.
Either way it needs manual effort to set up ๐Ÿคทโ€โ™‚๏ธ

proud finch
#
fixed4 frag (v2f i) : SV_Target {
    return float4(1, 0, i.uv.x, 1);
}```Can someone please explain why in my hlsl shader the color is only being outputed as red and not a gradient as it should be?
echo coral
west umbra
#

Can someone help me with a problem of my dll not working in my build?
I created a simple dll file that creates an overlay border for my unity app.
In the editor the dll is working perfect, only when I make a build, my dll does nothing, no crash, no log file being created, and nothing mentioned in my player.log.
I tried attaching visual studio debugger, I tried using DebugView, and even have my dll output to a logfile.
Everything works in editor, but not in my build. I have run out of options to try, and am at a loss

echo coral
west umbra
#

It was attached for native, but never broke in my exported functions, not even in DLLMain

echo coral
#

is it ticked to be included for windows on the dll in editor?

west umbra
#

Yes, doublechecked all import settings, and the right file gets exported to my build

stuck plinth
west umbra
#

If I run it in the editor, it does work, it calls the correct native method, no errors

stuck plinth
#

right, but what about if you debug the build?

west umbra
#

If I create a debug build, with script debugging, using Debug.LogError I get no messages at all

stuck plinth
echo coral
#

managed debugging works differently to native code debugging with unity which is why its important to make sure its attached correctly for native code

stuck plinth
#

i'm not talking about debugging the native code, i'm just saying use the unity debugger to debug your C# code

#

it sounds like it's not being called in the first place, so the problem is probably on the C# end?

echo coral
#

Im not sure because they claim DllMain was not called either but this was probably confirmed via debugger too

#

I agree that it should be checked both ends though

stuck plinth
#

i think unity wouldn't load the DLL until you call one of its exported functions so that tracks

#

ie, it isn't calling them!

echo coral
#

ah i presumed it would be loaded on launch but makes sense ๐Ÿค”

stuck plinth
#

i've never needed it but i guess that's what this box does

west umbra
#

I never needed that one before, but will try it out, also just saw that visual studio could not find the correct symbols, maybe wrong pdb file got attached

echo coral
#

Hmm could be. My experience is only with android/ios with unity compiling the cpp for me.

stuck plinth
echo coral
#

c# -> unity attach
cpp -> normal process attach

west umbra
#

I will first go back to unity, and attach my build to check the c# part, and afterwards check my cpp with visual studio debugger with the correct pdb file

echo coral
#

should be able to attach both (presuming you have a sln for your dll too)

stuck plinth
#

if it's true that your methods aren't being called, part of the problem in VS may be that the module is never being loaded so it won't even try to load that pdb

west umbra
#

It seems that for me, when building for x64 on a windows 64 bit platform -
#if UNITY_STANDALONE_WIN && UNITY_STANDALONE_WIN64 returns false ๐Ÿค”
Changing it to #if UNITY_STANDALONE_WIN && UNITY_64 fixed the problem, now my dll is being recognized again

echo coral
#

anyway its 2025 you can probably forget about win 32

west umbra
#

The second one was accidently taken from an older project where that error never gave any problems ๐Ÿ˜–
I probably can forget about win32 but do have a dll for it, in case someone with old computer runs my app.
Thanks for the help though, by attaching both c# and cpp I found the issue.

kindred spindle
#

Can the DOTS system lower performance of my voxel engine? I wasn't using it before and now that I am it is struggling to work like it used to. I am running using job system and burst, rendering my voxels at a much slower rate and with way more constant lag.

sly grove
#

Don't deal in vagueries

kindred spindle
sly grove
#

I mean "Can the DOTS system lower performance of my voxel engine?" Is an extremely vague question

#

nobody knows anything about your voxel engine or how you are using DOTS.

You need to use the profiler to get real insight about why you're having framerate issues.

kindred spindle
#

oh okay

#

I was more along the lines asking if I was wasting time on the DOTS system

#

since it has given me zero benefits

sly grove
#

DOTS itself is good but nobody has enough information except you to make that call. We don't know what we're comparing to or in what way you've utilized it it.

oak halo
echo coral
#

I'd say I understand rendering to a decent degree but im no expert. I'm going to presume at some point during the update cycle that transforms changes no longer take effect on the meshes and triangles rendered. So what you are seeing is when the transform data was last synced to the transformation matrix used with the draw calls.

#

the frame debugger should show the transformation for the draw call

oak halo
#

good lead, will investigate thanks

languid isle
#

is there a feedback email for Unity and its upcoming changes? I have an extreme opinion that should be shared with the top brass for hiring a Java developer to "fix" basic default coding such as FindObjectsOfType/FindObjectsByType - and making it a disgusting mess of nonsensical trash.

sly grove
languid isle
#

ty!

humble leaf
#

There is no off topic here, thanks.

tiny compass
#

How do people render small text without suffering from anti alliasing ? We're using textmeshpro and it's really bad especially on platforms that have a low render resolution

oak halo
#

looks like the mesh update works too, I guess mixing world canvas rendering and the URP rendering callbacks is dubious

#

makes sense

echo coral
#

Great news. Perhaps canvas mesh rebuilds only happen at one point hence the previous issues

oak halo
#

Yeah, thanks for the lead!

#

I've got it working pretty well now, hooking into those render callbacks provides a waaaaay cleaner way to achieve what I'm looking for

#

glad that it worked out

earnest heron
#

Hey all,
Have anyone used Mesh Baker for models with LOD Group ? Does it support that ?

topaz phoenix
#

Hi
I want to make a system where I can put script (MonoBehaviour) as a reference in a var (List) in my script. I want to create a tool to make Bosses easily without any more code (except patterns).
But I can't assign this in my inspector (screenshot). How I can do this? Or should I do something else?
Ty

thin mesa
#

you need to drag an instance of the object in, not the script itself. and if the script is something that shouldn't be attached to a gameobject in order to reference it then it should be either a scriptable object or a plain c# class (which you would use something like SerializeReference plus an asset that draws an inspector for SerializeReference)

sly grove
cold temple
#

!code

thorn flintBOT
cold temple
thin mesa
#

you've probably got your own class called SceneManager and it's trying to use that instead

#

also not an advanced issue

cold temple
#

i think that was it thank you

unborn otter
#

why was fragmentation tab being removed from mem profiler ? i find it quite useful locating fragmentation issue

serene herald
#

Hello ! I am looking for a solution to display this correctly in the inspector.
I am using Unity 6 HDRP.

#

like that

sly grove
# serene herald

Where did RenderingLayerMask come from? I don't see that as a type anywhere in the docs.

#

Are you sure it's not just a LayerMask?

serene herald
#

it's use for specify layer on light , mesh or decal

sly grove
#

use LayerMask as the type

serene herald
#

if i use LayerMask , the unity layer mask are display in my inspector , but i want to display RenderingLayerMask

#

not the LayerMask of unity

sly grove
#

Does this not work?

serene herald
#

The only thing that doesn't work is the display of the RenderLayerMask in the inspector.

#

when i expose it from a monobehaviour

#

On the other hand, it works with Unity's default components.

#

I found this solution, but it's quite strange that it isn't implemented by default like it is for LayerMask.

serene herald
#

mhmmm weird ^^

echo coral
# serene herald mhmmm weird ^^

is this a custom inspector or the default on your mono rn? I guess check to make sure this file exists in your package ver?

serene herald
#

the file exist yes and i'm not on a custom inspector for my monobehaviour

sly grove
serene herald
#

nop default assembly

abstract hill
#

Hi everyone, I'm trying to use Transforms within the unity jobs and understand that to do so I need to use TransfromAccess structs.

Currently the only way I can see how to use this is with TransformAccessArrays, however, the container that will hold the transforms is going to be resizing almost every frame, so this would mean I would have to do the resize, convert to an array and then convert to a transformAccessArray.

I also want to bundle a bit more data for each element too, so I was hoping I could create a struct that holds said data and a single instance of TransformAccess, created on Awake and disposed of on OnDestroy of a monobehaviour, then just use this struct in a NativeHashMap.

However I cannot seem to create a single instance of the TransformAccess, how can I do this, if this is possible?

My current approaches are either do the above, deal with the slowdown of creating the arrays and transformAccessArrays every frame or just sample the transforms as I only need to get the read the positions not set them.

sly grove
abstract hill
#

How would the transformAccessArray deal with non full arrays then?

Right now the only things it takes in are a standard array and a jobCount.

If I have an array of 100 elements but I am only using 20, then even if I manage that memory correctly since we can't set the copy capacity of the transformAccessArray would it not load junk memory and cause issues?

sly grove
abstract hill
#

Or do you mean to predefine the capacity and then copy the elements over

sly grove
abstract hill
abstract hill
#

Just looked and it says Transform so yeah

#

Final question then sorry, does this kind of approach scale for running every frame? As I would still need to create the TransformAccessArray each frame, even if I didn't have to create the Array?

#

Or can you dynamically change the size, but not capacity of a transform access array

#

dw

#

I just realised it has a length property

#

All is good xD

#

Thank you

sly grove
sly grove
abstract hill
#

Oh, intresting! Does this work as dynamic memory like Lists then? Can I just add and remove and have the TAA deal with the capacity changing?

Or will that still be something I will have to manage, (fine either way just wanting to make sure xD)

abstract hill
#

Excellent! Thank you,

abstract hill
#

I realised I'm going to have to carry some extra data that needs to couple with the index of the TAA, I'm going to be manually dealing with the capacity of this other array to match the TAA. However on resize with it being automatic, how much does it resize itself by? I can't find anything online about this, and secondly if I manually set the capacity to a given number doing collisionEntityTransforms.capacity = 10 does this empty the list / if not does it keep the ordering?

sage radish
abstract hill
#

Its not necisarilly, it just means I wont have to have an extra in variable to manage the capacity of the Malloc array. I was going to see if since these two arrays need to be directly coupled (in terms of order and size) I could just make sure the manually allocated array uses the same capactity variable as the TAA. So instead of manually dealing with 1 with 2 capacity variables, I could just use the already existing varriable built into the TAA and manually deal with both

sly grove
#

I'm not even sure that TransformAccessArray automatically resizes

#

I don't see any indication it does, the Add method's documenation is sparse.

sage radish
#

The docs certainly don't answer that question.

sly grove
#

indeed

sage radish
#

But I'm pretty certain it does. I don't remember having to check capacity before calling Add, but it's a while since I've used it.

abstract hill
#

This is the main thing I need to do, but once they are added since the collisionEntity is a struct it becomes a copy and looses the ability for me to change it. So when I then go to remove it I cannot know what the position of where to remove,

My thoughts where to store an index in the collisionEntityData itself on being added, so then I can remove it from that location and update the other elements in the list. However for that to work it then needs to be a pointer.

public void AddCollisionEntity(in Transform transform, CollisionEntityData collisionEntityData)
{
    collisionEntityTransforms.Add(transform);
    collisionEntityDataList.Add(collisionEntityData);
}

public void RemoveCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
    collisionEntityTransforms.RemoveAtSwapBack(collisionEntityData->listLocation);
    collisionEntityDataList.RemoveAtSwapBack(collisionEntityData->listLocation);
}
sly grove
#

You could always just check the capacity after you add, and if it's bigger than your other array, reallocate the other array to match

#

Or just use a NativeList for the other array and don't worry about it

sage radish
abstract hill
sage radish
#

But if you use NativeList, you don't have to do this. It stores a pointer to the list and count, so it can be passed around as a value.

echo coral
#

native containers are a struct but they should point to only 1 block of native memory

#

so I presume it will always share this memory till its released manually

abstract hill
sage radish
#

All the unsafe collections are pointers to data, so the data never gets copied. Structs like UnsafeList have a pointer to the data and a field for the count, so you have to pass that as a reference if you want to update the count. But NativeList wraps the count in a pointer too, so you don't have to pass it around as reference.

abstract hill
#

This should explain a bit for what I mean by this:

public unsafe class WorldCollisionEntity : MonoBehaviour
{
    #region [ Serialised Fields ]
    [SerializeField] private float _collisionInfluenceDistance;
    #endregion

    #region [ Unserialised Fields ]
    private Transform _transform;
    private CollisionEntityData* _collisionEntityData;
    #endregion

    private void Awake()
    {
        _transform = transform;
        
        _collisionEntityData = (CollisionEntityData*) UnsafeUtility.Malloc(sizeof(CollisionEntityData), 4, Allocator.Persistent);
        *_collisionEntityData = new CollisionEntityData(_collisionInfluenceDistance);
    }

    private void OnDestroy() => UnsafeUtility.Free(_collisionEntityData, Allocator.Persistent);

    private void OnEnable() => WorldCollisionPoolManager.Instance.AddCollisionEntity(_transform, _collisionEntityData);
    private void OnDisable() => WorldCollisionPoolManager.Instance.RemoveCollisionEntity(_transform, _collisionEntityData);
}

[BurstCompile]
public struct CollisionEntityData
{
    #region [ Properties ]
    public int listLocation;
    public float collisionInfluenceDistance;
    #endregion
    
    public CollisionEntityData (float collisionInfluenceDistance)
    {
        this.collisionInfluenceDistance = collisionInfluenceDistance;
        listLocation = -1;
    }
}
sage radish
#

Any particular reason why you are using Malloc instead of NativeArray or NativeList?

abstract hill
#

The idea is that the game objects control their own behavior, this component just updates the collision manager on Enable or Disable to remove them from the lists.

The collision manager then handles the Jobs for loading which cells (cell based procedural system) have colliders

sage radish
abstract hill
# sage radish And this is not possible with `NativeArray`?

Do you mean to have a nativeArray of length 1? If so then you can't nest native arrays inside other native arrays.

If you mean to have a single native array on the manager, then yes that would work, however then we run into the problem again of ordering and knowing which item to remove on disabling the gameobject, as the order may have changed so caching a value on start woulnd't work.

Instead you would need to update every object each time that one changes with their new index, so rather then a single object interacting with the manager, you would instead have a single object interact with the manager that then calls every other connected object to update their indexes

#

I want to avoid event calls like this as it makes following the flow of things a nightmare.

echo coral
#

Im confused why you are storing pointers to structs tbh

sage radish
#

And it's crucial that WorldCollisionEntity has direct access to its data as a pointer? It's not just the manager that needs it?

abstract hill
#

Mainly its to have a single source of truth for updating the index of where it sits in the array.

sage radish
#

Does it have access to the array? Why does it need its index?

#

I assume you've omitted the code that uses it in the code you pasted.

abstract hill
#

Its not fully written yet so I can't really post it. But I can post what I have atm if that helps.

abstract hill
# sage radish Does it have access to the array? Why does it need its index?

For when its removed.
For example:

Say I have for game objects, that
When I add these I need to know where in the list they are for later, so I store their positions as their indexs

A, B, C, D

A = 0
B = 1
C = 2
D = 3

if I remove B I check what index it had which in this case is 1, and remove that

A, C, D

I then want to remove C,

The problem is that since I havn't updated the indexes C still have the index of 2 so I would actually be removind D.

If instead I updated C and D's indexes to update the change then this would solve this.

Given however I cannot use a single source of truth from the gameobject side when I then call the remove function from the game object it can't know without having its own version of the index.

Either by keeping the original object itself, which handles its own position changes, or by having a callback event that updates all gameobjects with their new indexes (which is unneccary)

#
public void AddCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
    collisionEntityTransforms.Add(transform);
    collisionEntityDataListPtr.Add(collisionEntityData);
}

public void RemoveCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
    collisionEntityTransforms.RemoveAtSwapBack(collisionEntityData->listLocation);
    collisionEntityDataListPtr.RemoveAtSwapBack(collisionEntityData->listLocation);
}


private void FixedUpdate()
{
    CheckCurrentCollisionStatus();
    ProcessCollisionUpdates();
}

private void CheckCurrentCollisionStatus()
{
    int size = worldCollisionEntityTransforms.Count;
    
    (_previousActiveColliders, _currentActiveColliders) = (_currentActiveColliders, _previousActiveColliders);
    if (_currentActiveColliders.Capacity < size) _currentActiveColliders.Capacity = size;
    _currentActiveColliders.Clear();

    CheckCurrentCollisionStatusJob job = new ()
    {
        
    };

    TransformAccessArray transformAccessArray = new (worldCollisionEntityTransforms.ToArray(), 16);
    JobHandle jobHandle = job.Schedule(transformAccessArray);
    jobHandle.Complete();
}

private void ProcessCollisionUpdates()
{
    
}
#

The idea for the code above is that In CheckCurrentCollisionStatus, I iterate over all gameobjects and return the cells around them that need to be active for collision. ProcessCollision then checks which need to be turned on / off from a objectPool of Collision components on the manager.

#

As I mentioned the codes not really written, the main points of intrest are the Add and remove functions.

#

My current plan is to update them to this:

public void AddCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
    collisionEntityTransforms.Add(transform);
    collisionEntityDataListPtr.Add(collisionEntityData);

    collisionEntityData->listLocation = collisionEntityTransforms.length - 1;
}

public void RemoveCollisionEntity(in Transform transform, CollisionEntityData* collisionEntityData)
{
    collisionEntityTransforms.RemoveAtSwapBack(collisionEntityData->listLocation);
    collisionEntityDataListPtr.RemoveAtSwapBack(collisionEntityData->listLocation);
    
    collisionEntityDataListPtr[collisionEntityData->listLocation]->listLocation = collisionEntityData->listLocation;
}
#

This would work, given I also add some code on Add for managing both the containers capacity. Though I do understand that this isn't a very pleasant way for doing this.

#

Though it would mean only the swapped item would get updated on remove instead of everything. And the memory would be accessed via pointer to do so rather event listeners.

#

Tbh, a better solution to all of this would be to have a way of coupling persistent data directly with the transformAccess, though I looked into this early and that doesn't seem possible

echo coral
#

Is the main issue here how you keep these indexes valid? Why can you loop and remove the first ptr match?

abstract hill
#

Its to keep the different gameobjects able to call and remove themselves from the collision manager. Basically I just need to know where in the list a gameobjects data is. (both for the WorldCollisionData struct and the transform).

echo coral
#

But if you use a native list for example and the monobehaviour has the ptr to its object, it can be removed with just this.

#

That is what List.Remove() can do anyway, loop and remove when a comparison is true

sterile nebula
#

Quick question: When exactly do I know I should use a ScriptableObject?

I know itโ€™s used to store and share data, but how do I know when I should use it instead of MonoBehaviour?

sage radish
#

Another option is to create a sparse array of indices. Assign a permanent index for each object and save the internal, moving index in the sparse array. That's quicker to fetch than a dictionary, but uses more memory, depending on how sparse it becomes.

abstract hill
echo coral
#

well atm you have a list of pointers right?
you cannot safely have a pointer to an array item as ofc these will change any time

abstract hill
echo coral
#

I meant that if you have a list/array of pointers you can loop over and compare the ptr address to the one you wish to remove and remove this way.

#

a ptr is just a number

sage radish
#

At the very least, if you want to store a pointer to the index on the object itself, make it private, wrap it in a regular struct. There's no need for the script to know the index or even that it is storing one. It just needs to pass it back to the manager when it wants to remove itself.

abstract hill
#

Oh like a pointer to an int inside the struct? That would work too, I would still need to Malloc that int though.

#

Given unity will be doing stuff below the hood, would it be faster to try and use Native containers as much as possible? Given their is some overhead with copying the data to the native array does the format of native containers outway that compared to just passing raw pointers?

regal lava
sage radish
echo coral
#

What I would have is a Native list of CollisionEntityData and give each some unique id when its added so they can get removed later.
Then we have them all allocated all together and avoid using unsafe in managed land.

#

I think doing a malloc for each one is not doing you any favours when you are trying to benefit from burst jobs

regal lava
sterile nebula
regal lava
#

So the best way I describe them is data that can be easily swapped around on the editor and can easily be referenced by multiple different objects (unlike serializing classes)

abstract hill
regal lava
sage radish
# sterile nebula Quick question: When exactly do I know I should use a ScriptableObject? I know ...

The way I think about it is this:
MonoBehaviour is how you create your own custom component type.
ScriptableObject is how you create your own custom asset type.

Examples of built-in components: AudioSource, Rigidbody, MeshRenderer
Examples of built-in assets: AudioClip, Mesh, Material

Which category fits better for your need?

This gets a little fuzzy since GameObjects themselves can also be assets in the form of a prefab. But generally, prefabs exist to be instantiated. It's possible to use a prefab like an asset that you don't ever instantiate, but it's not often done.

echo coral
#

So if you have a native array/list/whatever that holds structs not pointers it will be better and basically the same as what you have now but without the initial malloc of each element.

abstract hill
# sage radish The native containers should be your starting point, and only move to malloc and...

I'm not sure if i'm just not getting it with the native containers but I'm finding its actually harder to work with then predefining the memory myself. Stuff like capacity changes, parallel writing and accessing the structs outside of the single job (keeping them around for the lifetime of the program without copying them) causes more headaches then just having manually made memory given I know I have to deal with it all.

Its weird I know but I've been playing with the Arrays, HashSets and Queues a fair bit now and each time i feel like I run into more problems with the containers then without.

I think I will just need to do some more reading on everything and see some examples, I'm coming in "blind" with jobs and native containers so I'm almost definatly picking up bad habbits.

I do appreaciate the help though!

Thank you everyone ^-^

sterile nebula
#

Thanks a ton, @regal lava and @sage radish ! I finally get it. I really appreciate your guys' help. You guys are the best! ๐Ÿ”ฅ And it wasnโ€™t confusing at all, actually, it was explained really well in just a few words. Thank you so much!

echo coral
# abstract hill Gotcha!

Remember in this case you cannot safely keep a pointer to a struct in the list/array as it could become another (due to removals) or the list could be reallocated and moved to elsewhere.
An index works but you are back to your original issue of making sure your stored indexes are correct later.

misty walrus
#

Hey, I'm trying to create a texture during runtime and use it as an asset sprite but I am getting blocked in any direction I want to go in:

  1. I tried creating a new texture and assigning it to the sprite asset, for some reason it fails and editor shows "Type mismatch"
  2. I tried creating a texture in editor and manipulating it in runtime, but setting pixels are not allowed for its graphic format, so that fails too
echo coral
misty walrus
#

Sorry I meant TMP_AssetSprite

muted sparrow
#

anybody got any resources I can look at for some design idealogies for setting up a character stat skill system?

untold moth
untold moth
shell knoll
#

hello, I upgraded my project from Unity 2023.2 to Unity 6 (43f1) and while I can successfully build locally both Android and iOS (with Xcode 16.0) , the iOS Unity Cloud Build is failing in the XCode build phase (I tried both Xcode 16.0 and 16.1). I think it has something to do with the shift to SPM (Swift Package Manager) target signing because the log shows it's failing with multiple "Signing for 'something' requires a development team. Select a development team in the Signing & Capabilities editor. (in target 'something' from project 'something')". But I don't know how to fix those errors. Can anyone provide any hint please? I'm attaching the whole Xcode log

misty glade
# shell knoll hello, I upgraded my project from Unity 2023.2 to Unity 6 (43f1) and while I can...

Don't think this is SPM - it's likely your distribution certificate ("Apple Distribution: Drest Limited"). Are you familiar with how to sign, create and specify the certificate, and use a provisioning profile?

I've just gone through this pain implementing a CICD pipeline (codemagic) and it's.. kind of a pain.

That being said, there's nothing in your logfiles that indicate a failure.. whatever's failing is either later in the log or in another process..

echo coral
#

I'm often needing to have my works Jenkins xcode Auth fixed so I know the pain

misty glade
#

we migrated from Jenkins to CodeMagic and .. despite some of the pain points, I have to say I'm loving life on the new CICD pipeline

random barn
#

So, i am working with a script of quake movement made in unity with Character Controller. It would be so much better for all the things i want to do to be RigidBody based. Is this possible to do? I dont know, and still i am kind of new to this. If i understand it right, for the quake movement to be working right you have to tweak the physics laws and concepts so that it works how it should. With RigidBody you have default values that are behaving like real-life objects and cannot really change that. They can, but it is not as customizable as CC. Thanks for all the help. :)) https://paste.mod.gg/yucyzjfysneu/0

sly grove
#

This isn't really an advanced question btw

random barn
#

so its possible?

#

how would it work?

sly grove
#

You would do the same logic, but use Rigidbody instead and rely on Rigidbody's built-in momentum and forces and such to do everything

#

The actual answer to your question is the code itself, which I'm not going to write for you

#

It's going to require you to understand three things:

  • How to code
  • How Rigidbodies work
  • How the physics expressed in this code works'
echo coral
echo coral
native beacon
ebon crag
#

Does Unity have any way to visualize Spline Data on a spline (just the position) or would I need to make a gizmo for it?

sly grove
#

make sure you turned gizmos on

#

I recommend this^

ebon crag
#

Yeah I'm already in that mode

#

by spline data I mean the drawers I have open (int data and object data), not the knots or the spline itself

sly grove
#

how would you expect that to be visualized?

#

I don't think it has anything for that no

ebon crag
#

just a dot on the spline

sly grove
#

!collab

thorn flintBOT
#

:loudspeaker: Collaborating and Job Posting

We do not accept job or collab posts on Discord.
Please, use Discussions to promote yourself as job-seeking, advertise commercial job offers, or look for non-commercial projects to participate in:
โ€ข Collaboration & Jobs

wicked leaf
bronze dock
#

Can I ask shader help here since they are code related?

bronze dock
#

I won't get any help any time soon

eager plume
#

Hi all, any Unity devs using Vim or similar editors that may want to chat about their favorite motions? It's for a little project I'm working on

random barn
#

Thanks for help @echo coral @sly grove

dapper cave
#

does it make sense to do a cullinggroup pass on DrawInstancedMesh? I read in the doc that it splits batch per groups then does a culling pass per group, I just don't know what groups are..

regal lava
#

Unity culls and sorts instanced Meshes as a group. It creates an axis-aligned bounding box that contains all the Meshes, calculates the center point, then uses this information to cull and sort the Mesh instances. Note that after culling and sorting the combined instances, Unity does not further cull individual instances by the view frustum or baked occluders. It also does not sort individual instances for transparency or depth efficiency.

dapper cave
#

I think that worst case scenario is so bad anyway that culling wouldn't help unless meshes themselves provide cover to each other. And experience on Unreal wasn't too favorable to deploying GPU culling to solve that.

#

I'll have to get more clever I think.

#

Do you understand the docu as: it makes one big bbox for a drawmeshinstacned and then cullt hat bbox? or do you think it splits a call into subgroups?

regal lava
#

Unity 6 has additional GPU culling via the resident drawer feature which uses depth map to further cull instanced meshes

dapper cave
regal lava
#

Oh, no. I've not touched any of the VR stuff but I should jump onto it ;p

dapper cave
regal lava
#

Probably androids I guess unless you consider WebGL/GPU builds running on my decade old laptops

dapper cave
#

mobile android will do, even decade old edsktop have more ompf in some areas

#

u6 gives you faster perfs with that new gpudrawer thing?

regal lava
#

It's buggy with web builds, but it's great at culling stuff like grass when occluded by trees and stuff like that

#

There's a bit more to the whole resident drawer feature, and they are still working on it, but it does kinda break some of my shaders too. It's still relatively new so I expect it to improved upon with 7

#

Similarly with the render graph

ebon crag
#

I'm using splines, is this normal? Getting a lot of NREs here whenever domain gets reloaded or I enter Play mode I have absolutely zero stacktrace to work with so I assume it's editor stuff?

#

I get no warnings or errors about it in the console and it just runs fine regardless

ebon crag
#

Maybe splines just don't like being in subscenes because I disabled the subscene it was in and now its silent

dapper cave
shell knoll
# misty glade Don't think this is SPM - it's likely your distribution certificate ("Apple Dist...

thanks for the info. Yes, I am familiar with how to sign, at least with the basics. The strange thing here is that we signed and still can sign successfully this app with Unity 2022 and 2023 without any issue, so if there's an issue with the distribution certificate, for some reason the issue only exists with Unity 6. Can you provide some more detailed help please? This is a huge porblem for me because it's blocking the whole engien upgrade initiative.

dawn inlet
#

hey, does anyone know definitive info about using bluetooth game controllers on macOS apps for distribution on the Mac App Store?

We're using Rewired for game controller support and our builds were using the bluetooth and usb entitlements when codesigning. Previously this was ok but App Store review has started rejecting our submissions because we don't explicitly request bluetooth access from the user with a native OS popup. There's no way to request this from the user in the Unity c# api and will need to be done with a native plugin I think. It's hard to get useful info on if Unity would actually pop this request itself using the info in the player project settings for 'bluetooth usage info'. I've not seen Unity do this before.

The Rewired docs wipe their hands of real info, instead just listing some troubleshooting stuff around it all but ultimately saying they don't have solid info.

short bear
#

what's the best i18n solution currently? Should I use I2 Localization or Unity's built-in solution? or is there any other recommended solution? (for Unity 2022)

livid kraken
#

Does [InitializeOnLoad] not run in batch mode ? I'm experiencing a wierd discrepancy between our automated CI and local building.

ruby salmon
#

does anyone know how to get the actual bone that a skinnedmeshrenderer is linked to?

#

like if i add a sphere collider to the mesh when it animates the sphere stays in the same place, but if i find the right bone and put it in there it moves as expected,

#

but i dont know how to find the right bone without manually doing it

#

i know its the problem of the model but ive had the guy modelling it out for 6 months now and he has never once got it right

echo coral
ruby salmon
#

yeh but how do i know which one relates to the right mesh, and i think its more coding than animation surely, i need to write a script to do it

echo coral
#

a bone is a transform so yea you can find the closest to some position. many verts of the mesh can be weighted to the bone however.
So yea you can do a distance check and pick the smallest dist

#

but if its a humanoid you can just learn the hierachy that you will basically always see for bones

ruby salmon
#

ah, yeh this is just a one off model, i love it but its never been right,

#

dont suppose u have a script showing how to do what you said there ๐Ÿ™‚ seems like it would be difficult, ill ask copilot see what it can do ๐Ÿ™‚

echo coral
#

Finding the closest thing out of a set is easy:

Transform closest = null;
float closestDist;
Vector3 ourPos = transform.position;
foreach(var otherTransform in transformList)
{
    float distance = Vector3.Distance(ourPos, otherTransform.position);
    if(closest == null || distance < closestDist)
    {
        closest = otherTransform;
        closestDist = distance;
    }
}

Debug.Log($"Closest transform is {closest} with distance of {closestDist}");
#

solutions that get all the distances in a list then sort the list are bad

ruby salmon
#

thanks i will give that a try i actually got somehting similar from copilot earlier but iassumed it was wrong when i saw the distance checks etc

#

cheers!!!

echo coral
#

we can make it faster if we use squared distance instead (as square root is a tad costly) but for editor stuff its not really a problem

ruby salmon
#

yeh, have u tried it before, actually works?

ruby salmon
#

thanks yeh i found that but it just gave me an array on tons of bones couldnt make sense of it

echo coral
#

thats the point

ruby salmon
#

yeh but i expected one bone to lin kto one mesh

#

not many

#

i guess my modeller just needs to export it properly, never had this issue

echo coral
#

it can be 1 mesh or many sub meshes but there is not a 1 to 1 match of a bone to a sub mesh. go research how skinning with bones works.

ruby salmon
#

ok thanks

stoic otter
#

Hi im trying to build for UWP ut i don't get why i get an error something about failed to run refrernce rewriter with command and something about the System.Memory version

stoic otter
livid kraken
ruby salmon
#

ah

#

my arist is renaming the bones and meshes for me so i can do it manually ๐Ÿ™‚

earnest heron
#

Hey all,
I have a scene with so many cliffs (With 3 LODs), I want to optimize the scene with Mesh Baker.
Mesh Baker can bake LODs togther but can't add them to LOD Group automatically. So I have to make a system to do that.
Now before starting, I want to know if it makes sense to bake cliff (And other props) which are next to each other or near enough, to gain more FPS and performance in my game ?

unkempt nova
#

In the example you circled it doesn't seem like combining them would reduce a lot of polygons to me. So seems like a lot of effort for very minimal returns to me

echo coral
wet magnet
#

What is the code "theory" or logic to updating server builds and client builds

For example updating a rust server that has builds and player inventories on etc to a new update that adds new items etc
how does that work? because you can update the game via steam but dedicated servers running a server build i dont understand how they recieve updates

sly grove
tulip fox
#

can you run c++ plugins in Unity Job?

sly grove
wet magnet
dusty wigeon
#

Minecraft does kinda work like that.

untold moth
wet magnet
#

But to actually update the servers automatically

#

Like on next launch do i just make then check an external database fkr changes in files then download thosebchanges or what

hushed fable
hushed fable
# wet magnet Wdym by that?

Separate program can do large changes to the server setup regardless of state of the server(s) being changed.

hushed fable
#

Note down the steps required to spin up a new server and getting clients to start connecting to them.

wet magnet
wet magnet
#

or my other pc

wary kiln
#

Hey, so I've made a project to generate a world procedurally but I see like land is not really big and often cut by the water. I've lowered the water level and the Noise but not really know how to make it more real, does someone know what values should I change?

tough stream
# wary kiln Hey, so I've made a project to generate a world procedurally but I see like land...
Minecraft Wiki

World generation (sometimes abbreviated as worldgen) is the procedural generation process Minecraft uses to algorithmically generate terrain, biomes, features, and thus ultimately decides which blocks are placed where. Minecraft worlds are made of 16ร—16 blocks wide chunks stretching the full height of the dimension. Because there are more than ...

#

minecraft uses a lot of noise maps for climate and stuff to get more realistic terrain

wary kiln
#

Let me check

unkempt nova
#

You should use multiple layers of noise for terrain generation if you want more control imo. Here's an example of it: https://www.youtube.com/watch?app=desktop&v=uY9PAcNMu8s

In this episode we'll create a noise filter to process noise, and layer it for more interesting terrain. Episode 04 is out for early access viewers here: https://www.patreon.com/posts/21079771

Noise script:
https://github.com/SebLague/Procedural-Planets/blob/master/Procedural Planet Noise/Noise.cs

Get the project files for this episode:
ht...

โ–ถ Play video
wary kiln
#

I think the way to go is by putting an offset? However that wont change much of how it is looking

modest slate
#

Is there any way to have multiple conflicting packages in one project?
What I mean is that many packages dump their settings into the Assets, and you cannot exclude or ignore those packages or settings for a specific build, unless you manually make the folder "invisible" by using ~.
Let's say I have two headset I am trying to develop XR for. One XReal, one AR for Meta. Their packages are conflicting, and can't live well together in the same project

#

The solution is to have multiple projects, each one for every setup?

long ivy
#

how do they conflict exactly? I would personally prefer one project with feature-enabling scripting defines if needed than multiple projects or doing weird things abusing Unity's special folder handling

modest slate
#

Well for instance try to support XReal together with Meta Passthrough VR. Or... the OpenXR don't like Oculus VR installed and etc.

#

And they also dump files on Assets, like config files, or manifest files. Both packages try to edit a manifest file

#

And that cause issues

#

In visual studio you can have multiple projects in one scene. Each project referst to files, it doesn't not replicate the folder structure

#

So you can have different projects have different files includes or excluded. All in the same solution

robust pulsar
#

Or just sqrt everything and scale it up

#

But thatโ€™s unreliable

wet magnet
#

Is there a steamworks documentation?

#

there is a steamworks SDK documentation but is there the steamworks unity wrapper documentation i cannot find it anywhere

untold moth
#

Doesn't seem like there's an official solution, so anything you'd find is an open source solution by third party devs.

wet magnet
#

๐Ÿ‘ ty

untold moth
#

Thankfully, wrappers are usually straightforward, so it should be pretty easy to read the source code.

vestal laurel
# modest slate So you can have different projects have different files includes or excluded. Al...

There are multiple strategies to bring sanity to this type of project. The first is what @long ivy mentioned, scripting defines to include/exclude platform specific code. But this will not solve the platform specific assets added by SDKs, and as you highlighted the overrides to the manifest files, etc.

One strategy would be to use version control and branches to segment incompatible platforms. One branch for Quest, one for XReal and a main branch where the common elements are tracked.

Like this you can avoid incompatibility errors due to SDKs not coexisting.

There is a great ebook on version control with Unity.

Unity

This guide explains the key concepts of version control, compares different version control systems (VCS), and provides an introduction to Unity DevOps tools.

lament salmon
wary kiln
#

I'll have to test

lament salmon
#

You can scale a perlin value by simply multiplying it

wary kiln
#

Yeah could be

modest slate
dawn zinc
#

I just wish they had more

vestal laurel
vestal laurel
dawn zinc
wet magnet
#

Does anyone here have example code for how you can integrate with steams master server list using facepunch steamworks

Yes i have read the entire documentation but whatever way i attempt to do it i can never manage to get it to work

thin mesa
wet magnet
#

alright let me refrain ๐Ÿ˜ญ

mossy herald
#

Hi guys I wanna ask is it difficult to put a circular indicator right? Like in the MachiaVillain game where you see a color circle underneath the characters but combine it with an arrow to lock-on something (enemy, object, etc.).

echo coral
mossy herald
echo coral
mossy herald
echo coral
mossy herald
echo coral
#

Insert? I'm gonna presume it's a quad or sprite renderer

mossy herald
untold moth
#

2 GB worth of 125 million allocationsnotlikethis

slate spoke
#

My attempt at making a custom datatype optimized for searches has resulted in performance worse by orders of magnitude

slate spoke
#

gotta optimize my optimizations lmao

untold moth
#

Just don't allocate that muchthinksmart

slate spoke
#

gotta figure out how to do that

#

though, on closer inspection, it might actually be the search algorithm for my datatype tanking the performance

#

makes sense given how chunky it is but idk a better way to do it

untold moth
#

It's the memory allocations. As for where they originate, it's hard to say without seeing the code.(Or making more pinpoint profiling with markers/memory profiling).

#

I don't know if it was you, but some time ago there was a person dealing with a huge amount of data, and they were suggested to use native collections to avoid GC allocations.

slate spoke
#

okay I think it's several things together causing the issue

#

but most notably, it's probably the async function I'm using for the loading loop for my generative terrain, which is being called directly from update

#

I assume that's the problem but I also don't know what the alternative to that is in my case

winter bane
#

guys my game doesn't build stuff properly what do i do

in editor everything is fine , but when i build the game it screws up some prefabs materials, and layers, is there a way to make a proper build same as playmode

untold moth
untold moth
slate spoke
#

I wanna figure out how to make sure it's not trying to calculate literally everything in a single frame first

untold moth
slate spoke
untold moth
slate spoke
#

...does the 125 million alloc calls in a single frame not indicate that?

untold moth
#

Though, honestly you should know how it works, since you wrote the code.

untold moth
slate spoke
untold moth
#

Then it calculated all on one frame.

slate spoke
untold moth
#

Probably.

slate spoke
#

how would I do that, then?

#

that's what I'm trying to find out currently

untold moth
#

I'd assume that the issue is in loadUtil.YieldForFrameBudget();

#

It probably doesn't yield properly.

slate spoke
#
        public async Task YieldForFrameBudget()
        {
            TimeSpan timeElapsed = DateTime.Now - startTime;
            if (timeElapsed.TotalSeconds > frameBudget)
            {
                // reset the start time and wait a frame
                startTime = DateTime.Now;
                await UniTask.Yield();
            }
        }
untold moth
#

Mm... Probably don't want to operate on seconds scale.

#

If it's less than a second, you're never gonna yield

slate spoke
#

Ah. What do you recommend, then?

echo coral
#

perhaps loading this on another thread is wise

untold moth
#

Though, it seems to be a double, so I guess it can represent time smaller than a second

slate spoke
echo coral
untold moth
echo coral
#

you should only be using UniTask and UniTaskVoid

slate spoke
#

when would I want to use one vs the other?

echo coral
#

UniTask can be awaited, UniTaskVoid cannot so should be used when you do not intend to await it.

#

UniTaskVoid is a replacement for async void so it still uses UniTask and not Task.

#

You can also consider pre allocating the list capacities to avoid reallocations when it resizes

slate spoke
#

Another part where I'm a bit lost on what the correct implementation should look like with UniTask is in the sort functions for my custom datatype
https://codeshare.io/G76Dra

#

which is likely responsible for the majority of the allocs

untold moth
#

There's so much weirdness in that code.
For example, you have array fields in a class, but then you allocate new lists to put some data in them to create a new array from them to assign to the fields. The lists are obviously a lot of immediate GC allocations.

slate spoke
#

code architecture is definitely not my specialty ^^;

#

kinda just learning as I go with this stuff

untold moth
#

This is not code architecture though. You could just create arrays of your defined size (or max estimated size) and just assign the elements to the arrays directly.

#

This is kinda like basic programming thing.

slate spoke
#

Ah, yeah true

#

Fixed that, though not much difference yet

echo coral
#

Yea you should sort the list

#

You should not use Linq to do it and produce a whole new array... Bad idea

#

I forget if array can be sorted in place.

slate spoke
#

Is there an easy way to do that without Linq or am I gonna have to implement sort algorithms manually?

#

I wanted to use System.Linq.Async at one point but it apparently relies on .Net 9 or something unity doesn't support

echo coral
#

List has a sort function and you can do it easily using CompareTo

slate spoke
#

wait so am I using lists or not .-.

echo coral
#

E.g.
list.Sort((a, b) => a.CompareTo(b));

#

You want to avoid using linq to sort as you need to allocate a whole new collection for the result which as we saw, is an issue for you

slate spoke
#

so it won't be a problem to use lists instead of arrays?

echo coral
#

Btw it may be more performant to just sort everything together on another thread, perhaps you can profile it a bit

slate spoke
#

the profiling, that is

slate spoke
#

I guess I'm not super familiar with IComparer

slate spoke
#

I think first off that the search algorithm just doesn't work, but also it's one of the things likely tanking performance

#

since it's ran for every tile of generated terrain

#

so 49 times at startup

#

since the coordinate arrays for x and y are sorted separately, the intent is to use the minimum xy coordinate of the search range to find the lowest value x and y coordinates via binary search and then just move up the array and grab every value until they exceed the max xy coordinate.

#

then, since the separate x and y coordinates have an index assigned to each point, it takes the x list and y list created by the binary searches and compares them to see which index values are shared between the two lists

dawn zinc
# slate spoke code architecture is definitely not my specialty ^^;

So I took a look at it, I think you would really benefit from changing some of those classes to structs. It'll allow you to store your data on the stack instead of the heap because they're a value type, which doesn't generate garbage for the garbage collector. Id also recommend using readonly on any fields that don't get modified outside of their constructor

#

And also because you're generating so often, it'd be ideal if you check your integer types and make sure you only use what you need to reduce what the CPU is using

#

Float, int, byte, short, etc

scenic forge
#

For this case, they are all in arrays already, so changing them to structs wouldn't move them from heap to stack.

echo coral
#

Long term data that size would not be in the stack anyway

dawn zinc
#

Yup, they're on the heap because the array is, but structs still help because theyre inline inside the array, not separately allocated. So we avoid GC and get better cache performance compared to classes

#

I'm thinking speaker, saha, date, umapx, umapy, hdbscan_label, could all be turned into readonly structs and be beneficial compared to them being classes

#

File, maybe, but it's more complex so it's not as valuable but could be. The testimony stuff would remain classes

#

It's still beneficial to convert them to readonly structs even in arrays

echo coral
#

Oh my bad yes structs for the array elements would be useful depending on how the data is used

#

Though rn the issue was a lot of allocation at once

paper plaza
#

hey! I was wondering if any extra memory is allocated whenever an animation controller is given to an animator object

#

im trying to implement a pooling system and if Unity's animation system requires memory to be allocated when swapping the controller on something, that kind of defeats the purpose of the pooling system in the first place

ebon crag
#

Has Unity support of GLTF been getting better as of these past years? I remember how about pretty much every single game developer, or at least the ones I know of, has been using FBX for all projects
I've found about https://docs.unity3d.com/Packages/com.unity.cloud.gltfast@6.12 and I'm pretty interested on it. I can't think of a single game that imports models at runtime other than VRChat, and I don't know how exactly they work so I have no idea how to go around this

crisp temple
spiral talon
#

Hi all,

i have a prefab with two components (A and B) that both use the same ScriptableObject for shared data/events. I want each instance of the prefab to have its own unique copy of the ScriptableObject, so A and B still share it within the prefab, but not across multiple prefab instances.

I saw a community-driven Unity project where they used ScriptableObjects as event channels โ€” and Iโ€™d love to adapt that approach. But Iโ€™m running into the problem where multiple prefab instances all share the same ScriptableObject asset, which causes cross-instance interference.

Since Iโ€™m building a larger project, the prefab might contain many components โ€” not just A and B โ€” so Iโ€™m looking for a clean and scalable solution that keeps shared data per prefab instance but avoids global SOs.

Whatโ€™s the best way to handle this at runtime?

long ivy
spiral talon
#

I want to achieve both with this one solution.
For example, I want that every enemy on hit invoke an onHit event to update their own lifeGui. But if they all uses the same SO (pre configured with serializefields), then all enemies listen on that event in the SO and will update their life.

When i make an instance or lets say a clone of that SO event in script A, then the B script doenst know about it because i couldnt pre configure it and i would need to call it from script A to know each other.

long ivy
#

if enemy life gui is one of the components they have, why wouldn't you just configure an event (UnityEvent) on the prefab instead? And if it's not, it probably makes sense for your script that wants to invoke onHit to expose an event anyway, and have whatever script spawns enemies hook the event up to the right gui at runtime. That way everything is decoupled

spiral talon
#

yes the gui is a component on the enemy too. how would you subscribe as gui to the lifecontroller event then? just have a normal reference in the gui of the lifecontroller and have onenable method something like this: lifecontroller.onHit += UpdateLife? simple as that?

#

i wanted to avoid having a reference of other classes, not only for different GOs, but also for all the scripts within one GO.

#

Right now im doin that with something like enemyEventManager, that knows all scripts alone and connects all events to another scripts. but its too much work on the long run for me.

long ivy
#

as a simple example: suppose onHit from LifeController have one arg, a float which is % of health remaining. Then LifeController has UnityEvent<float> onHit. HealthGui has a public LifeChanged(float percent). You then set up, in the prefab, onHit to call LifeChanged. Neither script references each other directly

exotic trout
#

Just personal two cents but I think using scriptableobjects and unityevents in general to handle this kinda essential logic thats contained within a single prefab is abit overengineered

#

Oh sorry misread, lifegui is seperate

long ivy
#

It definitely can be. Depending on how complicated your setup becomes, it can get very hard to debug if you have events triggering events which trigger more events

exotic trout
#

In this case is the scriptableobject usage here strictly to just limit what kind of events off the enemy outside code can see?

long ivy
#

proto's use case seems like a bad case for SO usage. It can't be both global and local, and it sounds like they want a strictly local solution to update same-instance components. That means direct reference, UnityEvents, C# events, or a mediating class either in the instance itself or code that sets those events up between components at runtime when spawning enemies

spiral talon
spiral talon
#

So without SO event for help, there will always be a class that has a reference of another class in order to subscribe to events, am i right?

long ivy
#

no

spiral talon
#

" You then set up, in the prefab, onHit to call LifeChanged. "

How can u do that without having a reference?

#

You mean in the unity inspector?

long ivy
#

yes

#

here's an example of what it would look like. Neither script knows anything about the other

spiral talon
#

That is just a prettier solution for game designer isnt it? You have a reference in the life controller of the gui...

exotic trout
#

not to be pendantic but you can get the ref off the unityevent

spiral talon
exotic trout
#

sorry i should have sent that message as a reply, I meant that message to evilreaper to point out that via that they can know about the other

long ivy
long ivy
#

the life controller knows only that it has an event to publish, with no idea what (if anything) is listening

spiral talon
#

But its still maybe the best possible solution here for my case.

long ivy
#

the event does, the script has no references itself

#

that's where the "let's communicate with something specific" knowledge goes

exotic trout
#

im not saying it matters or not but there is a connection

spiral talon
#

You could write your solution in the inspector also in code. And you would need the reference of course like you did with draging the script into the other.

long ivy
#

yes, but the idea is to prevent these two classes from being coupled together. That is one of the solutions I suggested earlier. This one is more flexible and better design-wise, if your events aren't too complicated

spiral talon
#

Alright, thank you so much to discuss with me.

#

I write an action rpg for over a year and with over 100 classes it starts to get messy. so i need a good architecture. just FYI why i ask.

deft palm
#

the wander around code isnt working for me

#

i just copy and pasted

#

i think the wanderTimer being 0 has something to do with it

slate spoke
scenic forge
#

I took a quite look, and the last bit of code already has so many problems:

var xyRange = from x in xRange
                join y in yRange
                on x.value equals y.value
                into matches
                where matches.Any()
                select x;
xyRange.ToList();

List<Testimony> xyList = new List<Testimony>();
for (int i = 0; i < xyRange.Count(); i++)
{
    xyList.Add(testimonies.testimonyArray[xyRange.ElementAt(i).index]);
}
#

xyRange.ToList() materializes a list and returns it, but you are not using the return value so that line of code does nothing but allocates garbage.

#

The loop using xyRange.Count() and xyRange.ElementAt(i) enumerates the sequence over and over.

#

The entire loop to create a list could just be removed and turn into one single select on xyRange. Not that I would recommend LINQ either if this is performance critical code.

#

I'm not too sure what advice to give since this piece seems like quite a big mess in many ways.

#

I'm guessing one problem you are having is that there are too many technologies at your disposal and you don't fully understand what they are abstracting over to know if and how they should be used. LINQ ToList() doesn't turn it into a list in place, Count()/ElementAt(i) are not the same things as List.Count/List[i], and a lot of these misuses compound into all the performance issues you are having.

brisk pasture
#

really anything more complicated then a single select or where just use a loop it will be easier to read and expand upon it

echo coral
#

Its like sorting a collection just to grab the first element

slate spoke
echo coral
#

if the array is rows/columns in order and you want a rectangular range then you can calculate the start + end index and bam you have your range to grab.

slate spoke
#

which is why there's separate arrays for x and y

dapper cave
#

I'm baking a scene into an SDF to drive boid flow simulation, it's 19MB total, 300k cells. Anyone did that and saw big improvement by using some compression on the SDF?

#

19MB won't fit in cache so I was wondering if it matters a lot in a job+burstified thing

echo coral
#

I thought you meant that your array was say a 5x5 grid defined as Thing[25] or Thing[5,5]

slate spoke
#

there isn't a way to do that without iterating over every point?

#

because there's 670k points

echo coral
#

how did you think linq does this ๐Ÿ˜

#

Unless you know before hand that a range will fit your criteria and can skip checking each element then yea you need to check them all

slate spoke
#

that's what this is though, right?

#

a range of XY coordinates

echo coral
#

I think i need an example of the data to comment any more

echo coral
#

ahh right the positions are floats.
You would need to pre sort them into fixed size areas (e.g. 5x5x5) to be able to cut down the data to search, this would let you narrow the search
https://en.wikipedia.org/wiki/K-d_tree

In computer science, a k-d tree (short for k-dimensional tree) is a space-partitioning data structure for organizing points in a k-dimensional space. K-dimensional is that which concerns exactly k orthogonal axes or a space of any number of dimensions. k-d trees are a useful data structure for several applications, such as:

Searches involving a...

#

you can then use the input range to quickly pick the sets of data to actually search in detail

slate spoke
#

so should the first step of the data processing be to assign indexes to the XY coordinates based on which fixed size area they lie in? or should separate arrays be made for each area?

scenic forge
#

FWIW, the problems I pointed out above have nothing to do with algorithm, it's all just misusing LINQ.

slate spoke
echo coral
#

This suggestion is to speed up a "loop over 600k elements and do a vector2 >min && <max comparison" check

#

i didnt try to fully understand the existing code so want to be clear about what I mean

slate spoke
#

I have no idea if that's better than doing a K-D tree

#

because I do have a K-D tree implementation provided by a colleague, but it's just C# code without anything related to Unity in it

#

so none of it runs async or anything

#

all of the K-D Tree implementations I'm finding are at least 4 years old

scenic forge
#

All the problems I've mentioned, like xyRange.ToList() doing nothing, is something you should know when you write the code.

#

(This is not saying there isn't a better algorithm for the problem you are solving, but a better blueprint doesn't help if you are not laying out the bricks and pouring the concrete correctly)

slate spoke
untold moth
slate spoke
#

because this is what feels like my 8th attempt at solving the same problem by rewriting the same massive chunk of code and whether or not I finish this by the 24th is the difference between me having a job or not

untold moth
#

Then maybe start simpler. Focus on optimizining your current implementation instead of rewriting it.

slate spoke
#

that's what I was originally doing, until I realized that the stuff I was using to do it couldn't be done async

#

then I was told that the best route would be to make an entire custom datatype

untold moth
#

I don't know how far you progressed since the last time, but you had huge GC issues irc

slate spoke
# untold moth Why not?

because I was using DataFrames, and all of the query stuff that comes with tries to do every computation in a single frame as far as I can tell

#

and every attempt I did at making it not do that failed

#

at this point I'm losing track of everything I've tried

untold moth
#

Yeah, I remember you using data frames and that it was a very bad idea. But didn't you move from that already?

slate spoke
#

that's what I'm trying to do with making a custom datatype

untold moth
#

Okay, but that's all pretty old news, is it not? I think yesterday you had mainly GC issues.

#

Or was it the day before?๐Ÿค”

untold moth
slate spoke
#

I mean, it "works"

#

It doesn't error and eventually spits out what I want

untold moth
#

Without dataframes, right?

slate spoke
#

kinda yeah

#

though my current coordinate search doesn't work

#

everything else functions at least

untold moth
#

Okay, so, now to optimizing it. Did you work on the crazy amount of memory allocations?

slate spoke
#

just, worse than DataFrame stuff

#

that's what I'm stuck on

untold moth
#

I think you were given several pointers yesterday. Did you fix them?

slate spoke
#

The testimonies constructor looks like this now

        testimonyArray = testimonyList.ToArray();
        speakerArray = new Speaker[testimonyList.Count];
        fileArray = new File[testimonyList.Count];
        sahaArray = new Saha[testimonyList.Count];
        hearing_typeArray = new Hearing_type[testimonyList.Count];
        locationArray = new Location[testimonyList.Count];
        dateArray = new Date[testimonyList.Count];
        umap_xArray = new Umap_x[testimonyList.Count];
        umap_yArray = new Umap_y[testimonyList.Count];
        hdbscan_labelArray = new Hdbscan_label[testimonyList.Count];


        for (int i = 0; i < testimonyArray.Length; i++)
        {
            int index = (int)testimonyArray[i].index;
            speakerArray[i] = new Speaker(index, testimonyArray[i].speaker);
            fileArray[i] = new File(index, testimonyArray[i].file, (int)testimonyArray[i].file_num, (int)testimonyArray[i].file_index);
            sahaArray[i] = new Saha(index, testimonyArray[i].saha_page, (int)testimonyArray[i].saha_loc);
            hearing_typeArray[i] = new Hearing_type(index, testimonyArray[i].hearing_type);
            locationArray[i] = new Location(index, testimonyArray[i].location);
            dateArray[i] = new Date(index, testimonyArray[i].date);
            umap_xArray[i] = new Umap_x(index, (float)testimonyArray[i].umap_x);
            umap_yArray[i] = new Umap_y(index, (float)testimonyArray[i].umap_y);
            hdbscan_labelArray[i] = new Hdbscan_label(index, (int)testimonyArray[i].hdbscan_label);
        }
}```
#

sorts look like this

    public async UniTask SortFile()
    {
        await UniTask.RunOnThreadPool(() =>
        {
            //fileArray = fileArray.OrderBy(row => row.file_num).ThenBy(row => row.file_index).ThenBy(row => row.index).ToArray();
            Array.Sort(fileArray, Comparer<File>.Create((x, y) =>
            {
                if (x.file_num != y.file_num)
                {
                    return x.file_num.CompareTo(y.file_num);
                }
                else if (x.file_index != y.file_index)
                {
                    return x.file_index.CompareTo(y.file_index);
                }
                return x.index.CompareTo(y.index);
            }));
        });
    }```
untold moth
#

Did you profile after the changes?

slate spoke
#

sorting seems to run fine, but I think the performance tank happens when filtering by coordinate

untold moth
#

The basics of optimizations:

  • Test and profile
  • Identify bottlenecks in the profiling data
  • Fix
  • Repeat
untold moth
slate spoke
#

I haven't done deep profiles because they've been taking way too long

#

I'm currently going by debug logs

untold moth
#

You don't need deep profiles. You can understand enough with regular profiling and custom markers

#

You're gonna get the same and more info with a profiler, rather than logging.

slate spoke
#

I'll need to figure out how to use custom markers properly then

untold moth
#

Start without markers to see the whole picture.

#

Then you can make some assumptions on your code and place the markers accordingly.

slate spoke
untold moth
#

Ok, so it's still an issue of GC allocations.

#

And looking at your code it doesn't seem like you've done anything about it.

#

Avoid creating new objects.

#

As well as things like ToArray

#

If you want to use lists, preallocate them with setting the capacity to the max expected count.

#

Prefer structs over classes where possible

#

You were told all of that before and it doesn't seem like you implemented any of this.

slate spoke
#

A lot of that comes from not knowing good alternatives

#

like here for example,

        List<Testimonies.Umap_x> xRange = new List<Testimonies.Umap_x>(testimonies.testimonyArray.Length);
        for (int i = mid; i < testimonies.umap_xArray.Length; i++)
        {
            await loadUtil.YieldForFrameBudget();
            xRange.Add(testimonies.umap_xArray[i]);
            if (testimonies.umap_xArray[i].value >= max.x)
                break;
        }```
#

I need to grab all of the Umap_x elements out of testimonies.umap_xArray (which is sorted beforehand) whose x property lies within a specific range

#

what would I output the results of that to if not a new list?

slate spoke
untold moth
#

You can use a list. Just preallocate it. Don't use new in here.

#

Make it a class field and init it with the max assumed capacity

slate spoke
#

I guess 680k then

untold moth
#

Well, optimization is often a trade off. Often a trade of between memory consumption and processing resources.

untold moth
slate spoke
#

I don't know the length of that range in the array itself

#

I just use a binary search to find the first index in that range

#

and go up the array until I find the last

untold moth
#

Well, start with allocation optimizations first. You can think about algorithmical optimizations later.

slate spoke
#

Something like this at the start of the class, then?

    private List<Testimonies.Umap_x> xRange = new List<Testimonies.Umap_x>(680000);
    private List<Testimonies.Umap_y> yRange = new List<Testimonies.Umap_y>(680000);```
untold moth
#

Yes. Though, do you really expect it to contain 680000 elementes at some point?

slate spoke
#

the entire dataset is 680000 and the distribution is uneven

#

so, it's possible

untold moth
#

Then yeah

#

Software often would have hard limitations on ranges for performance reasons. Maybe you should consider such a limitation yourself. I.e. not allowing more than X amount of elements in this list at the same time

#

Or if you split the processing over several frames, you can split the range as well, so that you use less of the elements at the same time

slate spoke
#

I'd likely have to make multiple versions of this function that support different sizes, then

#

given how many different things use it

slate spoke
#

that's why I keep bringing up async stuff

#

literally anything to get a Quest 3 to not try and do everything all at once so the user doesn't throw up whenever frames drop

untold moth
#

So does it happen in 1 frame atm?

slate spoke
#

the 125m allocs, yeah

#

after everything initially loads, it's worked fine

untold moth
#

This also allocates:

    xyRange = (from x in xRange
                  join y in yRange
                  on x.value equals y.value
                  into matches
                  where matches.Any()
                  select x).ToList();

Not sure about the linq itself(it probably does to), but ToList is definitely allocating. Might want to avoid doing linq here.

untold moth
slate spoke
#

making those lists class variables did help a lot it seems

slate spoke
untold moth
untold moth
slate spoke
#

haven't changed that name yet

untold moth
#

What code?

untold moth
#

Oh, is it from a marker?

slate spoke
#

yes

untold moth
#

For starters add markers around loops

#

And the linq part

slate spoke
slate spoke
untold moth
#

Expand the markers and share the new code

untold moth
#

Yeah, that linq part seems to be allocating a lot.

#

It's weird that the other loops are allocating too.

#

Can you share the updated code?

untold moth
#

Since the async doesn't seem to work for you, can you comment out the await loadUtil.YieldForFrameBudget(); lines as well as a make the method non async?

#

Then profile again.

slate spoke
#

I'll have to also make the return type List<Testimony> instead of Task<List<Testimony>>

untold moth
#

Yeah

slate spoke
#

op wait

#

wrong frame I think, though this should be checked out later probably

#

yeah if anything it seems like yieldforframebudget was helping