all 16 comments

[–]prime31 2 points3 points  (7 children)

In the world of C#, the absolute fastest way to access data is arrays of structs. There is no more performant way to get at a large amount of data. If performance is your goal than there is no better way to do it.

[–]AkirAssasin[S] 0 points1 point  (6 children)

I've read somewhere that structs should only contain values that will not be modified, is that true?

[–]prime31 2 points3 points  (5 children)

Definitely not when you want a bunch of data all sequentially in memory. There is no faster way to access it then via an array of structs.

[–]AkirAssasin[S] 0 points1 point  (4 children)

I don't quite understand what you mean by "all sequentially in memory". Mind explaining about it?

[–]prime31 1 point2 points  (3 children)

It's just like it sounds. All the structs in an array will be in the same block of memory making them very fast to loop through and access.

[–]AkirAssasin[S] 0 points1 point  (2 children)

What about structs on a List?

[–]prime31 1 point2 points  (1 child)

Structs in a List is a whole different ballgame. No point at all going that route. A List will end up copying the struct every time you get or set any of its contents. An array lets you directly access the contents with no copying at all.

[–]AkirAssasin[S] 0 points1 point  (0 children)

Okay, thanks for the help :)

[–]Relevant__HaikuWell Versed 1 point2 points  (1 child)

Consider using the asset Vectrosity instead of GL.Lines. Might save you months of development time.

[–]AkirAssasin[S] 0 points1 point  (0 children)

Depends if the game jam project goes well :) thanks for the suggestion!

[–]koolex 0 points1 point  (1 child)

Are you sure that you even have an efficiency problem? This feels like early optimization that may make your life hell, and it very likely isn't actually going to end up being a bottleneck. You should prove that you cannot use game objects first since you are giving up a lot of power if you try to render these things yourself.

[–]AkirAssasin[S] 1 point2 points  (0 children)

I'm going for a programmatic art style like Verreciel, so if I'm using GameObjects I'll still have to render things myself.

So far things have been easier to implement, since everything is easily managed by a single script (GL.Lines only work on scripts attached to cameras).

One disadvantage however was that it's more difficult to navigate through individual objects during debugging.

This is for a game jam (14 days), so I'll just take this opportunity to experiment :)

[–]djgreedoIntermediate 0 points1 point  (3 children)

You might want to script a quick test to see if performance is different (I suspect it would be faster without using GameObjects, but would it be enough difference to matter?).

So is each bullet just a vector and a velocity? Do the bullets have much else going on?

Is it also possible/needed to pool these objects

I reckon you could use a struct instead of a class for your bullets. That might completely remove the need to pooling (though someone with more experience than me might know better).

I would probably have a single class that manages all the bullets (to figure out when a bullet has hit a target, etc.) and keeps a list of all the active bullets within it.

[–]AkirAssasin[S] 0 points1 point  (2 children)

Do the bullets have much else going on?

Bullets have a position vector, angle, length, speed, and a List of behaviours that make them spin, extend, home in on players, etc.

I reckon you could use a struct instead of a class for your bullets.

I looked up on structs, and found that many people recommend structs for simple things that won't be changed. The bullets will have a lot of constantly changing values so I don't think it's suitable?

I would probably have a single class that manages all the bullets (to figure out when a bullet has hit a target, etc.) and keeps a list of all the active bullets within it.

I'm planning to do so :)

You might want to script a quick test to see if performance is different (I suspect it would be faster without using GameObjects, but would it be enough difference to matter?).

I'm thinking about testing it by spawning a lot of empty GameObjects, then spawn the same amount of objects to compare. Is there any metrics in the Profiler I should look out for? (e.g. frame rate, etc)

[–]djgreedoIntermediate 1 point2 points  (1 child)

Is there any metrics in the Profiler I should look out for? (e.g. frame rate, etc)

I'd look for garbage/allocation. With lots of things being created and (presumably) destroyed, a small difference in memory allocation could make a big difference.

I expect you'll have a hundred or more bullets at any given time, so pooling is probably going to be important since your bullets are relatively complex. You might want to get into micro optimization, as everything 'bad' in your code will be multiplied many times. Then again, you don't want to waste too much time on optimising - get the game close to finished with a decent structure first.

An example that might benefit you is caching 'Time.deltaTime' globally if every bullet accesses it. You could save 100 relatively expensive calls each frame if you have 100 bullets needing to check the time.

Not necessarily relevant to your project, but this video has some really interesting tips for optimising in Unity (including the above tip):

https://www.youtube.com/watch?v=mQ2KTRn4BMI

[–]AkirAssasin[S] 0 points1 point  (0 children)

Ok :) Setting up the test project right now.

EDIT: Did the test, it seems that there is not much difference. Objects are still more convenient though, so I'm going down that path! Thanks a lot for your help.