#archived-code-advanced
1 messages · Page 123 of 1
how do you assign to unity recompilation? I have native containers i need to dispose if i recompile code but on disable and on destroy doesn't get triggered when i recompile. So the containers are not disposed of.
im constantly getting leak warnings as a result
There are a number of editor event you can hook into, for example this: https://docs.unity3d.com/ScriptReference/AssemblyReloadEvents.html
thanks
I feel like I have generally 3 types of methods in scripts
Main ones defining main jobs this script doing, usually public called outside or private put in Update like general Enemy TakeDamage or AgressiveState from fsm
Big to medium private ones which are usually an abstracted away functionality of main ones like isCanShootPlayer (I wonder if I should consider renaming those, is isCan bad construct?)
Small private ones which are abstracted away chunks bits of code above which happened to be used in several other methods
Now the problem is it gets muddy when I am redacting those scripts, bigger script file is the worse
When revisiting I usually want to see only main methods, however when I am redacting main one I want to see the smaller relevant to it nearby, and when I am redacting smaller ones I want to see the smallest relevant ones nearby...
How do I even structure code? Are there any articles on this topic you can recommend to read?
Why do you need to see them nearby?
You'd generally use your ide features to navigate through code. For example in VS, F12 to jump to the method definition. Then there's "go back" button. You should also configure different short cuts. For example, alt up/down to navigate to the next occurrence of the symbol, alt left/right to navigate to previous viewed position.
As well as use context menu commands, like find references. With such features you can easily navigate your code and edit it conveniently.
Also, if you need to view your methods to remember what they do, the naming is probably bad, or comment docs should be added.
trying to investigate a memory leak with run-time Texture2ds not being Destroyed after use. I took 2 snapshots: A is from the lobby and B is from actual game session, when Texture2ds are created.
B has 300mb difference in resident memory, but the memory profiler doesn't show where that 300mb is allocated. Why? Is there a way to figure it out?
Is it possible that the texture2ds that weren't destroyed are now "Hidden" and Unity only knows that they are taking 300mb? but it doesn't know they are Texture2ds?
Have you tried destroying the textures and seeing if that helps?
It could be fragmentation, but if you already know the issue why do you not solve it ?
testing rn
im not 100% sure yet if thats the issue
It really does not seem to be the case from the memory you are showing.
If i want to use a compute shader to generate vertex data and pass that to the vert/frag shader. What would be the easiets way to do that?
have the compute shader write data to a ComputeBuffer/GraphicsBuffer and have the other shader read data from that buffer
Do i need to pass the vertices and indicies buffer?
I want to disable hand tracking in my game on Quest. It's a controller-based game, but when I double tap my controls together, hand tracking turns on and my players can't play until it turns off again. I know Gorilla Tag has this turned off, so it should be possible.
I'm using the OpenXR plugin, and have hand interaction poses turned off.
Anyone know how I can turn it off?
Do Graphics.RenderPrimitivesIndexed and Graphics.RenderPrimitives essentiality do the same thing. I see in both they are passed a position and triangle buffer.
Hello everyone, sorry for bothering you. I'm working on a project with Unity Render Streaming. I've managed to interact with the UI, but I can't find a way to interact with objects. Specifically, I want to click on a 3D object to make it disappear. Does anyone know how to do this? Thank you!
Clicking on 3D objects is the same. Use IPointerDownHandler or IPointerClickHandler. Just make sure your object has a Collider and your camera has a Physics Raycaster
Oh i will try, thank you
oh it's work, thank you
I'm creating a tool that automatically adds a scene to the build list if it isn't already included. Unfortunately, it appears that SceneUtility.GetBuildIndexByScenePath doesn't update right away. Is there any way to force an update?
Alright, after some testing, I realized it doesn't have anything to do with frames. Before Unity enters PlayMode, it makes a build of the game. It doesn't matter if editor code adds a scene to the build, if it happens during runtime that play session won't see the scene in the build.
Is there a way to add the scene to the build list before the editor enters play mode? I've tried both [InitializeOnEnterPlayMode] and [InitializeOnLoad], but both happen too late for changes to the Build scenes to affect the play session.
You'll need to hook up to unity's compilation/assembly reload pipeline.
what are you even trying to achieve? why do you need this?
I'm doing some procedural terrain generation with indirect mesh renderers on every terrain chunk. For reasons I can't figure out, when it initially loads, it renders every chunk's plants where the 0,0 chunk is. However, as you can see in the video, whenever I update the code for that indirect mesh renderer (regardless of if it changes any of the actual code), all the plants start rendering on the correct terrain chunk. Wtf is happening?
The coordinates being passed to the renderers are relative to the position of the chunks they're attached to, until I mess with the code like I did in the video, they all seem to render in world space instead of local space
Can you tell me how to set up multiplayer for Unity Render Streaming? For example, the Unity multiplayer sample on GitHub doesn't work, and I can't find any tutorials. Thank you.
Doesnt work is nothing anyone in here can work with. Noones gonna guide you here how to set it up but everyone is willing to help, if you are stuck somewhere.
Hello everyone, sorry to bother you, but I need your help. I'm working on an online car game in Unity, and I'm facing some issues that I really can't fix on my own. The problem is that I can't get the cars to spawn on the map chosen by the players in the game. Only the host is able to spawn their car on the map. Let me explain the car selection process.
We have a "Host" scene to create a game, then we move to a new scene, which is the lobby. The host creates a game that players can join. Once the players have joined, the host starts the game, which loads a "Game" scene where the menus are displayed, meaning the map selection, then the car category, and finally the car selection. After that, we click on "Play," which loads the map scene and removes all other scenes.
And it's from the map scene that everything bugs. In other words, the cars don’t spawn, even though I set them up with the required Mirror components.
I'll leave my GitHub here—if you could take a look, that would be really great.
https://github.com/scotty800/lobby
also
in #archived-networking
pretty sure there's a seperate server for mirror issues
thanks man
Hi there, does anyone know if MarkerFlags.ScriptDeepProfiler is usable by the end user in any way?;
Define end user? Like the people playing your game? Or you as a Unity developer making a game?
good point, the developer.
It's used with https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Unity.Profiling.ProfilerMarker.html isn't it?
Can you all think of a performant way to store a collection of different MonoBehavior Component references (of different types), and then to access those component references by their specific types later, without casting?
Obvious answer would seem to be “No, not by normal means.”
But I feel like maybe I’m missing something..
Maybe UnsafeUtility.As<T, U>()…which I believe does a cheap, C-style cast…but am I being stupid?
Casting is not particularly an heavy operation ?
That may be. But this would be a hotpath, and I’m at least looking for a way to avoid it.
Start by profiling before assuming, you might find that it does not cost a lot and that whatever funky method you try is actually costing more.
Low level performance is kinda complicated and it is easy to forget a factor when attempting to optimize.
That is always good advice, ty.
Do you have any ideas about direct solutions to the original question?
It depends on the whole context, but usually you want to store them continuous without polymorphism for the best performance.
Otherwise, you can use __makeref to convert from <T> to <U> without boxing if you are working with value type.
You know…you answered me, which I appreciate. But I never know how to respond to someone who:
1- second-guesses the validity of someone’s whole question, and
2- doesn’t read the question
You answered some other question. I’m not sure why.
- understand that most people here ask for solutions to problems they should not have in the first place
- see 1
I…did not consider that. Sorry folks
but to be fair, if you ask in advanced and use the right terminology, people will take you seriously
You’re saying I didn’t use the right terminology?
no, just in general
you're way too polite to be called a fool
The real issue here, is that you asking to optimize an hotpath of code but the way you are going about is wrong. If you want optimize code, you should use DataOriented approach. Otherwise, it feels like you are not that serious about optimizing it.
Big can o worms there. :p
Which makes thing like casting, as far as I know, not really a big issue, feel silly.
There’s only so far towards DOD you can go, when working in MonoBehavior land. :p
using a monobeaviour in the first place makes most other optimizations futile
what are you missing?
You can use an hybride approach also.
you can get very very far with .jobs, .burst, .mathematics and .collections
I’d love to talk to people about this subject, but it’s a pretty deep one. I’m not sure I have time on my lunch break. :p
I guess the short answer would be:
- close to 10 years of development, without clear communication from Unity about plans for future feature support/parity with GO Unity.
- lack of support for some common, important features like Navmesh, UI, Animation, and others. Working with DOTS for core game logic, on anything besides a small or hobby game, it’s easy to run into a minefield of compatibility gotchas - some of which you might not hit until late into development.
- the necessity to roll your own versions of major features, which GO unity users have access to without issue.
For a company with a team to pay, DOTS unfortunately still represents a large production gamble, even though I am a huge fan and cheerleader.
I’d also push back against the idea that there’s no point in optimizing a GO-based game. That…doesn’t make sense to me.
Most all Unity games are made with managed, GO, OOP code. And I’d bet all of them optimize their hot paths.
i see your point, i'd say dotsEntities is for systems that need it and for teams who don't gain much from unity's bare bones builtin systems
DOTS (minus entities) is used everywhere in unity when performance matters.
And where data isn’t stored in Mono components
and you don't need entities to be data oriented
I’ve been in DOTS land for too long. Do people working on non-DOTS projects not store the majority of their data in MonoBehaviors anymore? Maybe I’m out of the loop.
I hear about people using Bursted jobs on their own in GO-based projects. But I figured those must be being used in isolated cases, where data was intentionally stored separately from MonoBehaviours, to make that possible.
Would you mind explaining more what you meant here?
data orientation is about writing code in a way that its execution causes fewer wasted computation on the CPU, primarily due to cache misses which force a page load from main memory which makes the CPU core wait 20-100 cycles while doing nothing. you can optimize your code to do that without any fancy libraries
I understand. I meant…due to the existing data layout of GameObjects and their Components, it’s actually difficult to work in an optimized DOD way with GO-based code…at least, not without avoiding the use of Components and rolling your own data structures.
At least…compared to unmanaged ECS, GO optimizations are kind of a drop in the bucket
thats not entirely true, nobody forces you to iterate game objects or mono behaviours, and even if you do, doing so in a more batched way improves performance already
if you don't access the gameobject or component through a reference, they do not impact your algorithm
Oh, got it
…how does one access a GameObject or component though something other than a reference?
(Without unsafe code)
you dont
think of it as a mesh, which is just a bunch of primitive structs/types in arrays, you can make operations on them extremely fast without ever touching the components they sit on while doing so
True. But you’re going to incur fetching costs just by accessing the mesh in the first place.
not necessarily
you could access the raw data pointer, but thats maybe a step too far
If it’s stored in a MonoBehavior
the point is not to avoid the copying, the point is to avoid random memory access while doing math
it also isn't stored in a monobehaviour, its only copied from native memory into a c# object of your choice on access
Tbh, these sound like micro-optimizations, compared to the unmanaged sequential layouts of DOTS ECS code.
You didn’t let me answer! :p
whether you make that array yourself or get it from entities doesn't matter
entities uses the same APIs, there is no magic
you can access all that stuff without entities
“…at least, not without avoiding the use of Components and rolling your own data structures.”
idk what you are really arguing here
There's a difference between having logic on a component and having logic/data on individual instances of components
I am trying to make navmesh generation
based on A* grid
I managed to make it to some extend
however for large map, when I do it in chunk, there is this weird gap
What is the way to solve it?
For these perf benefits you need an array of structs but with a lack of pointers you need a better way to reference them... like an id...
What the hell?
This is a programming channel
Anyone know if it is possible to debug a native dll in Visual Studio? It's my dll and I have the pdb
I guess I can setup a normal C# project, but I was wondering if there is a way to do it inside of Unity
Should be possible. Try breaking somewhere and having a look at the loaded modules in the modules window. If your dll is listed there, you can load the symbols for it via the context menu. Then there's also an issue with the source code. If it's not in the unity project, you might need to reference it in the C# project or something.
Okay thanks, I appreciate it!
If you have a Vs project for the native DLL you can attach and debug just fine
Does require an editor restart though if you recompile it as only managed ones can be reloaded
on large structs it can
it's similar to Unsafe.As<TFrom, TTo>() in c# and you must ensure the layout is the same between TTFrom -> TTo
why you want to do it on components? it makes sense on structs tho
Thanks for replying. I...am pretty sure this will sound like one of those answers that immediately screams "your design is wrong.". And maybe it is. I'm investigating a potential new architecture for some code, and figuring out pain points.
In that design, I've wound up with a case in which I need to store a map of Components, but then access them later as their derived Component type. Why not just store Type-specific references somewhere? Good question, but it would be an involved explanation. Not claiming any smarts here.
If I read that case about someone else's code, I might think "That design sounds suspicious.". Which is probably a sign that I'm on the wrong track.
Although...as best I can tell, GetComponent() also does a pointer reinterpretation behind the scenes. And I don't think that's the expensive part of that function. So if I'm only doing this at the same frequency as someone might call GetComponent(), then maybe it's not so smelly? Hmm. :/
well unless you notice perf issues with casting classes a lot or encounter lots of failed casts at runtime its probably fine
Yeah, if we are talking about boxing/unboxing.
GetComponent() is costly though. (Not because of casting)
It really is far from getting a reference in a list.
So if I'm only doing this at the same frequency as someone might call GetComponent(), then maybe it's not so smelly? Hmm. :/
This is smelly.
For a hotpath code at least
Otherwise, everything you just said before is overengineering on so many level.
I appreciate that. Can you explain further?
GetComponent should never be called in a "hot path". If you think you are approach is similar in performance as GetComponent and you feel it is not an issue, then you are either not in an hotpath or you have really,really low performance requirement.
Which would means that casting a reference is in no case an issue.
I would never call GetComponent in a hotpath, nor did I ever say that.
Alright, maybe I understood it wrong. I believe you were asking about hot path code earlier, and you were now saying that whatever you do might be similar to GetComponent.
Anyway, if you want more information you should start by profiling, giving more context and actually being ready to invest time in other programming paradigm. My bad, if I misunderstod.
No worries. I’ve been hotheaded lately, and it’s stupid. My apologies
Yeah…that pattern is pretty smelly. :/ :p
How do you folks reconcile when people say both “that’s code smell”, and also “don’t worry about it unless it causes perf problems when profiling.”?
When is “that’s code smell” a big enough problem to not even implement?
In this particular instance I think its fine. A similar example could be a service provider which would also involve getting and casting to some derived type.
I guess there is is a way to avoid the cast, using a static generic class. Something like:
public static class ComponentStore<T> where T : Component
{
static Dictionary<GameObject, T> componentsByGameObject;
}
That would spread out the references a lot more than a single Dictionary<TypeID, Component> though. So it may end up actually being slower than casting.
!code
if you have many instance of type T it may be worth it but why do you need GameObject as the key?
📃 Large Code Blocks
Use links to services like:
https://paste.mod.gg/, https://hastebin.skyra.pw/, https://paste.ofcode.org/, https://paste.myst.rs/, https://scriptbin.xyz/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
What key would you imagine instead?
I could use a UUID associated with the GO, but that’s essentially the same approach
im trying to imagine when you would have GameObject instead of T to begin with
if you need T all the time then work with T
My underlying challenge is that I’m trying to use some ECS-style patterns in a GO/Monobehavior world, in which systems iterate over applicable GOs, and do work by accessing their Components.
Those systems can’t very well store references to every GO’s Components ahead of time (and the GOs being worked on could change each frame anyway).
And the GOs themselves don’t store references to all of their components ahead of time. I would need to write a unique MonoBehavior for every different combination of Components a GO could have on it, in order to do that in a way that avoids casting.
…Hope that made some kind of sense in text.
well managed class references in a dictionary isnt gonna achieve this so its not worth doing
Isn’t going to achieve what, exactly?
Seems like it would functionally work, no? (Performance is another story)
well it sounds like you are trying to do an ecs like pattern but in a way that does not yield its perf benefits
might as well just use ECS and Entities for real
That’s definitely true. I don’t ever hope for anything except ‘decent’ perf when using GO-based code to begin with.
I’m using this pattern for some logical benefits. The way the code is organized.
My hope here isn’t to reach DOTS levels of performance. Just to avoid terrible performance. :/
I would absolutely be using DOTS, if it was more ready for prime time. :/ I’m back on managed land, after trying to make DOTS work for our needs for literal years, unfortunately.
But that’s a larger topic. :p
If you start using structs for your data/components then it may start to make sense but ECS for unity has lots of code gen and use of native code to further increase performance gains
It’s not what DOTS can do (of which I’m a huge fan). It’s what it can’t do - which includes some very basic engine features, lots of late-in-development gotchas, and poor communication from Unity about what we can depend on in the future.
For reasons like that, it’s just too large of a production risk for a company like ours, unfortunately. Believe me, I am a DOTS stan. 🙂
…I could use code generation to solve my problems here (generating custom components to hold the references I need).
..I was trying to avoid that for some reason. I’m not sure why…I guess I thought that would be code smell too. Not so elegant?
But maybe the straightest line solutions are the best, and it’s best not to worry for too long about it
I'm not sure what you should do but really think hard about what you do and if it will yield any benefits
Thanks for spending some time on it.
it sucks how much effort it takes to yield nice perf benefits due to managed code but thankfully unity have quite a few solutions now such as jobs, burst and native collections
https://paste.ofcode.org/nqz85WMFNzWrL4peW5XCBC
guys i wrote this custom hlsl for a custom node in unity shader graph for a toon shader
it has worked fine until i tried to covert the last part for work with foward+ render path
its working but only with large light covering a big obeject some help ??
yoooo, anyone wanne see mine (selfmade) dungeon generation? (idk if thats "advanced", but im proud af of it)
still just beta room models, but the generation is all done :O
How can i handle Multiplayer to only send info of other clients it can see or like are close to a corner to the client from a server ?
Im using Purrnet, but a general C# idea of how to do this would be helpful as im struggling to implement this as a "anticheat" thing, while also keeping the clientside prediction and serverside rollback working
source engine achieves something similar to this (controlling when entity data is transmitted) by using its visleaf system:
https://developer.valvesoftware.com/wiki/PVS
Im not sure if the unity occlusion culling system can be queried in a similar way or if you would need to make a similar system and data for your game
thank you i look into it
My solution would just make the server raycast from each peer to then determine if any two of these peers would be visible to each other. But, this be not be accurate enough if we're just determining if the pivot itself is revealed and not the whole player mesh, so there would be some extra logic needed.
I guess occlusion culling could determine it, but you're leaving it up to the server to create a depth buffer for each of these players to determine what's occluded from their viewport.
Hi!
I get editor crashes after trying to read a disposed NativeArray element from managed code. Is this expected behaviour?
editor.log:
Obtained 29 stack frames
0x00000179f005e3f6 (Mono JIT Code) (wrapper managed-to-native) System.Buffer:InternalMemcpy (byte*,byte*,int)
0x00000179f0059dcb (Mono JIT Code) System.Buffer:Memcpy (byte*,byte*,int)
0x00000179f005c063 (Mono JIT Code) string:memcpy (byte*,byte*,int)
0x00000179f3208e13 (Mono JIT Code) Unity.Collections.LowLevel.Unsafe.UnsafeUtility:ReadArrayElement<Foo> (void*,int)
0x00000179f3208b8b (Mono JIT Code) Unity.Collections.NativeArray`1/Enumerator<Foo>:MoveNext ()
(...)```
not sure why there is a string:memcpy etc.
i surely get a feeling that it was never intended to use native collections outside of jobs. there are safety checks in jobs, it will throw an exception at you when you try to run a job with a disposed container afaik.
Anyone know if there's a way to reduce GC alloc to 0 when using Awaitables like this example in the Unity docs? I call it every frame, idea is I have a job that I want to start at frame x, then complete it on frame x+1, but it's seemingly allocating every time I call it.
{
// Wait until end of frame to avoid competing over resources with other Unity subsystems
await Awaitable.EndOfFrameAsync();
var jobHandle = ScheduleSomethingWithJobSystem();
// Let the job execute while the next frame starts
await Awaitable.NextFrameAsync();
jobHandle.Complete();
// Use results of computation
}
JobHandle ScheduleSomethingWithJobSystem()
{
...
}```
Unity docs say "Calling an Awaitable-returning method usually doesn’t allocate memory, since Awaitable instances are pooled by default." which I'm not seeing in the profiler, it always seems to alloc
Just out of curiosity, why are you reading an array that you've disposed? By convention, it shouldn't be useful (or relied on!) anymore.
im 99% sure when you dispose of a native array the memory is deleted right then, so it tried to copy from invalid memory to some new managed object and thus caused the segmentation fault signal
though suprising it was not caught on the managed side to prevent a crash
it needs to allocate if none in the pool when 1st time awaiting OR fresh start OR when you await lots of them at once so there's none available in the pool, so it must allocate.
After you're done awaiting, it will be sent back to the pool, so the next time you await them it will be free or won't allocate if there's one/multiple of them available in the pool.
it'll allocate when the pool has no instances to supply to you. An awaitable is released to the pool when disposed or and exception happens in the operation it represents. (the dispose happens internally based on how the awaitable API is used, typically when SetResult or SetException is called and after all continuations have been processed)
Yeah that behaviour simply doesn't happen unfortunately. In profiling a standalone build (and editor), it's allocating even though I'm calling await once per frame. The weird thing is, sometimes it will allocate, some frames it won't.
again how many of them you're awaiting at once...
2-3, absolute max
cant say much than just weird... sadly
All good, thanks for the info.
So atm I'm doing a pretty brute force call to the await() method in an update loop, don't spose there's any way to just force it to not dispose the awaitable?
probably there is if you use reflection, since the c# awaitable also has a corresponding native awaitable it might be dangerous to mess around with that. Also consider that the awaitable is thread safe, and the pool is behind a sync-lock you may not get immediate results from just calling the C# api
can you show it here, i mean the screencap, also make sure it's not your method that's allocating
dont thread, let others see it here
now send the screencap of said alloc in the profiler
Only other thinking is do I need to call it some other way than by just using the method name
no... just don't..
you generally dont want to mess with pooled object states
isn't that exactly what i said
Yeah dw I'm not going into reflection or crazy stuff, I'll just turn it back into a non awaitable before I do that
I mean, those are zero alloc...
the allocation is from unrelated stuff (non awaitable stuff) in that method
so its you homework now to trace them down
well, what you're doing by calling it withou await is basically creating a dangling thread without anything holding a reference to it, so thats generally considered bad and you should if possible create wrapper around it or await it inside an async context
what are you on about?
there's no additional/extra thread, unity uses custom single threaded syncContext
the continuation is guaranteed back to the mainthread
unless you do Task.Run OR task Factory then thats another story
Better example. Pretty sure it is the async pool allocing (but weirdly, not every frame, just when it feels like it):
Splitting off the exact same code that's in the async to the normal LateUpdate() loop, 0 alloc ever
lots of pooling implementations that are using weakRefs would not hold the pooled objects for long, simply bcos there's a risk those objects accidentally promoted to gen2 already(note gen2 dont exist in IL2cpp, it is in mono OR future CoreCLR if unity finaly done with the migration).
also note holding unused objects for long would cause memory abstraction which might hurt the perf much later on. so cleaning them up once in a while would be a good practice and totally makes sense
note, I'm not sure if unity is weakref-ing here nor do I know in details about the awaitable<T> impl, but from technical pov, cleaning them up once in a while is what myself would do too.
that said, this statement is true "Calling an Awaitable-returning method usually doesn’t allocate memory, since Awaitable instances are pooled by default."
they just need to make the *usually* to be bold text 😄
Yeahh I feel like there's a way they could make it a lot closer to 0 alloc than it currently is, oh well, it is a new feature after all so I should expect it's a bit like this
I feel like there is probably an easy way to do what I'm trying to do, which is start one job per frame, and just run it off the main thread, then by the end of the frame grab the results, without alloc
imo their AsyncMethodBuilder being a ref type is a bad decision. They should make it struct instead and no need to be pooled...
which essentially what UniTask is doing
UniTask being the best solution still for async in unity 😆
Ended up putting it all into a coroutine... 12 bytes/frame which I'm sure technically I can live with, but yeah annoying there's not a 'perfect' solution :/
what about the OnPreRender() and OnPostRender() callbacks?
Atm I'd really prefer to have everything in one function to maintain readability. If I split the job between functions (like those, or even Update then LateUpdate) I'll have to start maintaining jobHandle references, few more annoying things.
reading your initial code you schedule the job, you wait a frame and go "fuck it ill wait for its completion on the main thread"
with unitask you can await the job completion so it can execute and not block the main thread needlessly
idk if this is an advanced issue but it feels like it is
unity raycast cant return UV from convex mesh or pretty much any mesh that isnt a non convex mesh collider
This normally wouldnt be a problem, however my game uses a funny little destruction system which heavily relies on texture modification during runtime, i have a huge issue where my vehicle is meant to be a rigidbody, but for it to be a rigidbody, it must not have a non convex mesh collider, however, my destruction script gets UVs from the vehicle, but it cant do that if its a rigidbody because then the mesh colliders are convex.
There is a paid asset on unity asset store that adds support for non convex mesh collider rigidbodies, however im pretty sure it cant return UVs because it isnt mentioned anywhere that it can.
the best solution i can think of right now is having a non convex mesh & collider for my car, that basically gets teleported to it and then returns proper UVs i can then use on the visible vehicle parts
it's a bug. the thing is, i expected an exception to be thrown, given that there is a IsCreated flag there that could be checked in the native array indexer.
yep, exactly
Correct, Raycast hit UV and triangle index only works for non convex mesh Collider
This isn't a bug
is there any workaround for my issue? other than doing this?
What you described is one workaround (two colliders). Another would be a custom system not based on a mesh collider
Like pre baked collision damage areas
Do native to managed callbacks have to reference static delegates?
The Unity Editor is crashing sometimes when the callback is invoked on an instanced object.
I didn't have this problem in a normal .NET console app so maybe a mono thing?
Example:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void NativeDefaultDeviceDelegate(IntPtr deviceId, IntPtr friendlyName, uint role);
i feel like the first one is likely to be performance heavy and the second one wouldnt be as detailed in the destruction, im gona go with the first one and if it proves to truly be laggy, ill move on to the second one
Hi, guys! I have a player controller with more than 2,000 lines.
Can anyone recommend some cool content to learn the best way to modularize it?
Number of lines of code is not generally that meaningful of a measure
The question you need to ask yourself is "does this script have more than one responsibility?"
Is it handling just movement? Or is it also handling unrelated things like sounds, animation, etc?
intresting.
but i really think that something could be modular.
the problem is that i wanna see big games examples.
and it is rare.
Big games(AAA) are not always pretty. Sometimes they have worse code than indie games.
If you share your script we might be able to suggest something.
the design question you have to ask yourself is: "can i organise the code in such a way that the important logic (the main business the system is dealing with) is all close together and easily readable, i.e. not polluted by details" then "can i maybe layer the system in a way that the details are a library or engine of modular components that get conducted by a higher level controller, in turn keeping any high-level concerns externalized". A character controller is usually a mess of different concerns (animation, gameplay, physics, audio, debugging, testing, automation, different modes etc.)... a "good" controller would make maintenance of these different concerns easy, such that changes limit the potential for bugs and other issues. When every concern is mixed in with all others, it becomes very difficult to understand what changes are safe and which ones can cause problems. When methods make assumptions about state that is not passed into it as an argument, or when it doesn't work for all possible argument combinations, the code becomes "hard to maintain". The bigger a project gets, the more formal the APIs get, as a way to help with making the assumptions/guarantees about whats going on explicit.
I work professionally and one of the main project of our company has 10k controller. Not really something you should consider doing, but it still can work.
Single Responsibility Principle is really a good one. Unfortunately it is sometimes hard to understand/put it in practice correctly. However, if you search for the SOLID+T(Tell Don't Ask) principle you should find an array of example on how to concretely implements it.
Crazy to think about it.
any tips for seeing "pretty" code for a person who likes to see examples?
A lot of handlers and all called.
More than 30 atributes.
Maybe look up some open source projects on GitHub. There were a few projects that unity officially supported. Don't remember the names.
So intresting and make sense. For a controller, be easier is better than short.
The solution to this is to break it down into smaller "components(not necessarily unity components). State machine pattern could be used as well to isolate different states.
You character controller shouldn't handle everything, like camera, equipment, sound, cheats
I love SOLID because, i m a software engineer. But as GameDev i 'm trying undertand how to use in unity.
Group parameters/properties into structs or class, instead of having a lot of primitive fields.
Events that look very promising, any type of content for learning?
Thank you, bro.
There's a lot of theory, but it takes experience to know how to apply it. Maybe start by looking at the OOP principles and SOLID principles
One of the reasons for seeking modularization was to reuse logic in NPCs, Monsters n animals.
You can google the specific patterns as well. There are plenty of resources on finite state machine pattern.
the key is to not loose sight of what problem you actually want to solve, the immediate one of player value and the implied ones of the developer. All the principles that get thrown around, code features and patterns are ultimately only ideas that you have to put in service of something, in themselves they do nothing an achieve nothing. You may want to have a quick read of this book: https://www.amazon.com/dp/173210221X
This book addresses the topic of software design: how to decompose complex software systems into modules (such as classes and methods) that can be implemented relatively independently. The book first introduces the fundamental problem in software design, which is managing complexity. It then disc...
Thank you, I will definitely read it.
So I think I figured out what the problem was in case anyone is curious or searches in the future. I wasn't storing the callback as a part of the class instance so I think it was getting garbage collected. I don't think I saw this behavior in my console app because garbage collection probably wasn't triggering.
So for example, I was doing this which was crashing the unity editor:
public class MyClass
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void NativeDefaultDeviceDelegate(
IntPtr deviceId,
IntPtr friendlyName,
uint role
);
[DllImport("TestNative")]
private static extern void Initialize(NativeDefaultDeviceDelegate defaultChanged);
public void Initialize()
{
Initialize(OnDefaultDeviceChanged);
}
private void OnDefaultDeviceChanged(IntPtr deviceIdPtr, IntPtr friendlyNamePtr, uint role)
{
}
}
It needed to be changed to this to keep the delegate around:
public class MyClass
{
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private delegate void NativeDefaultDeviceDelegate(
IntPtr deviceId,
IntPtr friendlyName,
uint role
);
[DllImport("TestNative")]
private static extern void Initialize(NativeDefaultDeviceDelegate defaultChanged);
private readonly NativeDefaultDeviceDelegate _defaultDeviceChanged;
public MyClass()
{
_defaultDeviceChanged = OnDefaultDeviceChanged;
}
public void Initialize()
{
Initialize(_defaultDeviceChanged);
}
private void OnDefaultDeviceChanged(IntPtr deviceIdPtr, IntPtr friendlyNamePtr, uint role)
{
}
}
how would one achieve this sort of camera shifting like they have in diablo 2?
So i want to open a menu and then have the camera still follow and look at my character, and rotate around them... but everything should be shifted to the side.
im using cinemachine
really wouldn't have anything to do with cinemachine.
This would be using multiple Unity cameras and setting their viewports.
or just a single unity camera and an overlay ui that animates alongside the camera viewport changing
Can you elaborate please?
on which part
Could make it lerp nicely with two virtual cameras
What you would do with the viewport
but diablo is kinda instant
you would change it to only draw on part of the screen as in your screenshot
Yeah that's what I think.. so you'd have main virtual camera and another one that's got a viewport that's shifted?
CM cameras don't define viewports AFAIK
I'd probably not touch the viewport rect as the UI is obscuring it anyway
changing the viewport rect is what lets you "shift" the image over
I see
nobody said to get rid of CM
it's just not relevant to this problem
imo
Okay but basically I need to fiddle with the viewport rect
yes
Thanks
yeah viewport rect or just have a virtual offset
I was looking for the "thing" that's needs to change so I know what to lookup
Thank you both 🙏
My game is in my bio if you're interested 😁
The sameway that you are using it in software engineering. In fact, if you are not able to use them in GameDev, it might be because you do not truly understand them and you are simply applying what you learned without knowing truly "why".
You kinda of have an roadmap here. Each handler can be a class for starters.
still need help with this
If your plants are loading relative to the chunks that they are attached to, my best guess is that they are attached to (0,0) at load time.
Can you ensure the chunks are loaded before creating the plants? That's not much of an answer, I know.
As far as I can tell, the chunks are loaded before the coordinates for all of the plant positions are even finished being processed
that's why there's a delay
the prefab they're attached to before being initialized has coordinates at 0,0
lemme try changing those and see if that affects anything
oof, it didn't
also changing their initialization coordinates doesn't seem to change anything either
Took me an entire day but i got my rigidbody vehicle parts to work with my destruction script.
Every time an object is damaged, it gets a copy of it created under the map (if a copy of the same mesh doesnt already exist) and the same raycast that was performed for the original, is also performed in the simulation and the simulation returns uv coordinates for the rigidbody
Hello, I have a question.
In Unity, an Animator is instanced. How do I make so that Animator is not instanced (having exactly the same variables)? I have exactly 2 same rigs, and I want them to play the same animation, but I don't want to put script inside the second rig.
In Unreal Engine, the AnimBP is shared in the character blueprint (if we have 2 rigs using same AnimBP, the variables would share).
Make the first rig a prefab and get rid of the second rig
But it won’t follow the first rig (the second mesh)
Hey guys, I was wondering if anyone who has lots of experience in the saving data realm of coding.
I wanted to create a world like Kyora but I'm struggling on how to save the data of each pixel.
I find I have to store the pixels world coordinate and ID for what kind of material it is (stone, dirt, sand, etc. ). I found that would take a lot of bytes even with lossless compresion.
Than I see a world like this and I just end up wondering how in the hell is all that being saved.
EXPERT GUIDANCE NEEDED!
~It would be awesome if someone cant point me in the right direction of instuction on how to achieve this or towards someone who can further assist me.~
Than I see a world like this and I just end up wondering how in the hell is all that being saved.|
In a 3d bitmap more or less, most likely compressed, yes.
I have to store the pixels world coordinate and ID for what kind of material it is
You don't have to store the world coordinate
that's an intrinsic part of its position in the array
Games with procedural terrain generation, like Minecraft, terraria( and probably the game you shared), usually only save the seed that was used for the procedural generation and delta changes(if the world can be modified by the player). Then when the game loads it regenerates the world from the seed and applies the delta changes.
the games not in 3d, dont know if that matters just assuming 3d bitmap has something to do with that
doesn't minecraft save the whjole world after generation?
You linked a 3d game and asked about it
so i answered
it's not that important of a distinction though
either way it's just data
No,I don't think so. Maybe caching the visited chunks at best.
like run an a function to interpret its position in the long list of saved data. sorta like find out its position by its index?
definitely only the generated chunks
but I thought it stores all generated chunks in full
anyway either approach is valid
'you don't "find out" its position by index
the position IS the index
in the 3d bitmap you mean?
In whatever array the data is being stored in
IIRC Minecraft does store generated chunks in full, because generation can change from version to version.
Yes, but you want to decide if it's acutally each "pixel" that's stored or if it's using marching squares or something
and to reduce the processing effort needed to re-gen them
my current modded world is 2.86gb
the region data is 2.3gb of that
You probably wouldn't want to save the whole map even with a bitmap. If it's just 1 million pixels/tiles in width and height, and you use 1 int per tile, it's already gonna be like 4 GB of data if my calculation are correct.
you store generated chunks like minecraft does.
But also you wouldn't use a whole int per tile
unless you need 4 billion tile types
I was assuming a bit mask, so that different info about the tile could be stored
But yeah, it could be less
also you can compress the data, and store groups of chunks in different files
you could probably save data in semi batches right? eg. if
[x10,y10] to [x20,y20] consists of the exact same tile you don't need to save that info per cord, you could save that "batch" and re-build that knowledge at runtime?
that's called compression, yes
you'd probably just want to use off the shelf compression though unless you know something special about your data.
Compression algorithms handle repeating values extremely well.
Depending on preferred storage to processing ratio you could also maybe track if the given chunk has been modified compared to it's original seed generated version and if it hasn't just don't save it?
yes, you could , but that has issues
like your procgen code cannot change from version to version
or the world changes
Forsure, depends on what they want. (i could personally actually see that is a possible benefit depending on how its handled)
General purposed compression algorithms in theory perform worse than if you come up with your own specialized algorithm catered specifically towards your data, but there's a bunch of science in it that you are probably not going to do better. An alternative approach is to transform your data in a way that makes existing general purposed algorithm compress better, eg delta encoding, going z>x>y rather than x>y>z, etc.
still need help with this
been some time, maybe reelaborate your issue
if anybody somehow managed to make their own compression algorithm that beats the ones we already have today, feel free to claim their noble prize 😄
The positions of the coordinates being fed into my indirect mesh renderers change if the shader recompiles at runtime
For specialized data, that's very much possible. Most existing compression algorithms are general purposed and cannot make much assumption about the data it's compressing.
it was sarcasm comment 😄 incase you missed it
they're not worse worse per se (imo).
LZ for example, only bad on repetitive data, not to mention some algos are patented there, but they don't suck like the majority of people love to think they're
Is there a way to force a script recompile on a single ASMDEF that doesn't require a script change?
i think reimporting the asmdef file itself or any script inside it should do it
Doesn't seem to be quite the same, a reimport does trigger a recompile but it doesn't log any roslyn warnings. Changing any script file inside of the assembly does trigger them though 🤔
Can confirm that reimporting a script inside of the assembly does though, thanks!
I've tried looking into IPreprocessShaders but it seems you can only choose to strip variants, not force them to be included.
There was a bug in some unity versions with shader stripping and addressables (basically all variants were stripped) but probably not whats happening to you.
Yeah, I don't think so since nothing uses addressables in this build
How do you calculate a mesh's normals if you're iterating over the vertex list by row and column?
(assuming said mesh is just a flat grid)
form tris first. there's a rule that determines tri normal based on vertex order
I do have that already
I ask because I'm making procedural terrain, and I'm trying to do the thing where you smooth normals between tile edges
normal = Cross(v1 - v0, v2 - v0).normalized
aka tri.normal = Cross(tri.v1 - tri.v0, tri.v2 - tri.v0).normalized
for shared vertices just do normals[i] += ..^ when calculating normals, then normalize each entry again at the end
oh, so I need to iterate over the vertices twice?
no, not the vertices
you should go through each vertex ONCE to calculate tris (mesh.triangles)
then you should iterate through the triangles twice. One for normals[i] += triangles[i]...normalized;, and the other for normals[i] = normals[i].normalized;
there are more performant ways to ONLY normalize the shared vertices, if you find that slow. But on most use cases just iterating through each of the normals likely won't be too slow.
do a if (normals[i].squareMagnitude > 1) on the second loop if you wanna squeeze in some easy performance
Ah, gotcha. It's been super easy to confuse myself with how I'm writing this, since I'm calculating the normals for one mesh using another with extra "border" faces so the terrain tile seams don't stand out
For context, my mesh generation is based on this video
https://www.youtube.com/watch?v=64NblGkAabk
But I'm trying to apply the stuff in this video to the previous
https://www.youtube.com/watch?v=NpeYTcS7n-M
Generate a landscape through code!
Check out Skillshare! http://skl.sh/brackeys11
This video is based on this greatwritten tutorial by Catlike Coding:
https://bit.ly/2Qd1o1d
● Perlin Noise: https://youtu.be/bG0uEXV6aHQ
● More on generating terrain: https://youtu.be/wbpMiKiSKm8
● Singleton: http://wiki.unity3d.com/index.php/Singleton
❤️...
Welcome to this series on procedural landmass generation. In this episode we go on a long journey to fix a tiny problem with the mesh normals.
The full source code for this episode can be found here:
https://github.com/SebLague/Procedural-Landmass-Generation
If you'd like to support these videos, I have a Patreon page over here: https://www.p...
and it seems like their approaches to iterating over vertices and tris are very different
cool!
I can't seem to get that working
This is what I came up with
// normals first pass
List<Vector3> normalsBordered = new List<Vector3>(vertexCountBordered);
for (int i = 0; i < vertexCountBordered; i++)
{
normalsBordered.Add(Vector3.zero);
}
for (int vertBordered = 0, trisBordered = 0, z = -1; z < zSegments + 1; z++)
{
for (int x = -1; x < xSegments + 1; x++)
{
int vertex00 = vertBordered + 0;
int vertex01 = vertBordered + xSegments + 1;
int vertex10 = vertBordered + 1;
int vertex11 = vertBordered + xSegments + 2;
Vector3 normal000111 = Vector3.Cross(
verticesBordered[vertex01] - verticesBordered[vertex00],
verticesBordered[vertex11] - verticesBordered[vertex00]
).normalized;
Vector3 normal001011 = Vector3.Cross(
verticesBordered[vertex11] - verticesBordered[vertex00],
verticesBordered[vertex10] - verticesBordered[vertex00]
).normalized;
normalsBordered[vertBordered + 0] += normal000111;
normalsBordered[vertBordered + 1] += normal000111;
normalsBordered[vertBordered + 2] += normal000111;
normalsBordered[vertBordered + 3] += normal001011;
normalsBordered[vertBordered + 4] += normal001011;
normalsBordered[vertBordered + 5] += normal001011;
vertBordered++;
trisBordered += 6;
}
vertBordered++;
}
// normals second pass
for (int vert = 0, vertBordered = 0, tris = 0, trisBordered = 0, z = -1; z < zSegments + 1; z++)
{
for (int x = -1; x < xSegments + 1; x++)
{
normalsBordered[vertBordered + 0] = normalsBordered[vertBordered + 0].normalized;
normalsBordered[vertBordered + 1] = normalsBordered[vertBordered + 1].normalized;
normalsBordered[vertBordered + 2] = normalsBordered[vertBordered + 2].normalized;
normalsBordered[vertBordered + 3] = normalsBordered[vertBordered + 3].normalized;
normalsBordered[vertBordered + 4] = normalsBordered[vertBordered + 4].normalized;
normalsBordered[vertBordered + 5] = normalsBordered[vertBordered + 5].normalized;
if ((x >= 0 && x < xSegments) && (z >= 0 && z < zSegments))
{
draft.normals[vert + 0] = normalsBordered[vertBordered + 0];
draft.normals[vert + 1] = normalsBordered[vertBordered + 1];
draft.normals[vert + 2] = normalsBordered[vertBordered + 2];
draft.normals[vert + 3] = normalsBordered[vertBordered + 3];
draft.normals[vert + 4] = normalsBordered[vertBordered + 4];
draft.normals[vert + 5] = normalsBordered[vertBordered + 5];
vert++;
tris += 6;
}
vertBordered++;
trisBordered += 6;
}
if (z >= 0 && z < zSegments)
vert++;
vertBordered++;
}```
and here's what I'm getting currently lol
what's with the draft lol
also, why does your code look so confusing xD
all of this is is a modification of the stuff in this third video lol
https://www.youtube.com/watch?v=f9uueg_AUZs
Download Link: https://drive.google.com/open?id=1B_IwrJKX9sQishwyrUbmWYCZrmhUwJTb
The project is using Unity 2017.3.0. Just FYI.
Update: Unity 2017.2.0 introduced the Vector2Int class. It doesn't make a difference, but it makes more sense to use it to keep track of tiles. It didn't exist when I originally made it...
the outer loop ends with vertBordered++? 
it's equivalent to "vert" in Brackey's video, it's just to indicate that it's for the vertices of the bordered mesh
the bordered mesh being the one the normals are calculated from
can you show your mesh generation code?
Should I send the file or is there a site I should use to share it?
uh, is that right?
whole thing should be simple after you get the vertices, and should be writeable like this:
Vector3[] vertices = GetVertices(...);
int[] triangles = GetTriangles(vertices);
Vector3[] normals = GetNormals(triangles);
!code
📃 Large Code Blocks
Use links to services like:
https://paste.mod.gg/, https://hastebin.skyra.pw/, https://paste.ofcode.org/, https://paste.myst.rs/, https://scriptbin.xyz/
📃 Inline Code
Surround code with three backquotes. Not quotation marks.
To format as C#, add cs to the first line:
```cs
// Your code here
```
Add a comment with a line number if there is an error message.
~~well you win then!~~oh no seems it was taken down... try https://hatebin.com
The owner of this domain has not yet uploaded their website.
oh wow
I'm old
use the recommended sites not whatever gdl space is
didnt haste bin go all shitty too
gdl.space was a hosting site hosted by Game Dev League -- the main Unity Discord Server before this server got every single unity user lol
A tool for sharing your source code with the world!
and hatebin was the good hastebin
Vector3[] GetNormals(int[] triangles, Vector3[] vertices) {
Vector3[] normals = new Vector3[vertices.Length];
for (int i = 0; i < triangles.Length; i += 3) {
var (i0, i1, i2) = (triangles[i + 0], triangles[i + 1], triangles[i + 2]);
var (v0, v1, v2) = (vertices[i0], vertices[i1], vertices[i2]);
var (e1, e2) = (v1 - v0, v2 - v0);
var normal = Vector3.Cross(e1, e2).normalized;
for (int j = 0; j < 3; j++) { normals[i + j] += normal; } // 0, 1, 2
}
for (int i = 0; i < normals.Length; i++) {
if (normals[i].sqrMagnitude > 1) { normals[i] = normals[i].normalized; }
}
return normals;
}
won't lie to you, I didn't even know you could do var (i0, i1, i2)
and for real use an architecture like the one mentioned here for headache--; 😄
easier said than done given what I'm working with lol
but yeah I'll break up the function a bit
also, this is missing the most important aspect of what I'm trying to do lol
it's just calculating the normals for a mesh and applying it to said mesh
that should be all it should be doing 😄
But what I'm doing is calculating the normals of a mesh using a different version of the mesh with extra vertices around the edge
no no, that's not the GetNormals's job.. if you want a different mesh, make the different mesh have the correct set of triangles 😛
..dude
Welcome to this series on procedural landmass generation. In this episode we go on a long journey to fix a tiny problem with the mesh normals.
The full source code for this episode can be found here:
https://github.com/SebLague/Procedural-Landmass-Generation
If you'd like to support these videos, I have a Patreon page over here: https://www.p...
watch this video please
or at least skip to the part where they explain how normal calculation works
for terrain tiles
I have watched this video in the past pretty sure. What about it?
he has the exact same code (in different style)
start at 6:48
his method labels the vertices unused in the final mesh as negative values
which doesn't apply to my method, where there isn't a difference between how border vertices and non-border vertices are calculated
the only way you can tell that a vertex is a border vertex in the context of my implementation is by going through it the same way it was initially generated
If that's avoidable, that would be lovely, but this is what I managed to get working up to this point
ok just to clarify all you want is adjacent chunks to appear smoothly connected, right? Did I misunderstand?
yes
and to solve that, you created another mesh from what I understood
that copies the original meshes, and adds vertices between the seaming points
eh, sort of. It places vertices in the same positions where those vertices would be on adjacent terrain tile meshes
so basically to connect m1 + m2, you create a m3 that contains m1 + m2 + m12_border?
or just a new mesh representing the m12_border?
the mesh used to calculate the normals for m1 would be m1 + m12_border, since it's not using the entirity of the m2 mesh
gotcha. Then you seriously don't need any special handling for the normals other than what I said 😛
Did you try that and saw it didn't work for you?
reason is that if the triangles are set up correctly, the normals will also be calculated correctly without having to check the original mesh
That probably calculates it correctly for the bordered mesh, the problem is grabbing the correct normal values from that mesh to apply to the final mesh
yes yes it'll all be correct! Since you copy the tris from the original mesh anyway -- the normals are also copied
sort of
basically normals are only cached as an optimization. In almost every single case they can be inferred by the vertex position of each triangle
it's not "copied" necessarily, the two meshes are made at the same time with different indexes
because as far as I know, I shouldn't be trying to use negative indexes in a list
just go ahead and try the normal calculation code xD just copy paste the code in
SebLag is indeed using negative vertex indices I suppose for smaller list size and cleaner code
since your mesh's vertices list already contains the border vertices (assuming), you haven't done anything wrong
draft.vertices only contains the vertices of the final mesh
verticesBordered is what has the vertices used to calculate normals
also I need to edit your function to make it use lists instead of arrays
actually.. what if you just do mesh.RecalculateNormals();? Does it make it look jagged?
I don't think I can while it's still a draft
the function only returns the draft of the final mesh
so I wouldn't be able to do any calculations relating to borders
I changed your function to this
List<Vector3> GetNormals(List<int> triangles, List<Vector3> vertices)
{
List<Vector3> normals = new List<Vector3>(vertices.Count);
for (int i = 0; i < triangles.Count; i += 3)
{
var (i0, i1, i2) = (triangles[i + 0], triangles[i + 1], triangles[i + 2]);
var (v0, v1, v2) = (vertices[i0], vertices[i1], vertices[i2]);
var (e1, e2) = (v1 - v0, v2 - v0);
var normal = Vector3.Cross(e1, e2).normalized;
for (int j = 0; j < 3; j++) { normals[i + j] += normal; } // 0, 1, 2
}
for (int i = 0; i < normals.Count; i++)
{
if (normals[i].sqrMagnitude > 1) { normals[i] = normals[i].normalized; }
}
return normals;
}```
"index out of range"
at for (int j = 0; j < 3; j++) { normals[i + j] += normal; } // 0, 1, 2
likely because the number of vertices != the number of triangles
because they're connected faces
oops yeah use triangles.Count when initializing the normals list
wait.....
for (int j = 0; j < 3; j++) { normals[i0 + j] += normal; }
yeah I was about to say, how do we apply that to the final mesh then
vertices.Count was correct
that's.. not what it should be
it's actually not responding to light at all now it seems
ah I just had the function commented out
can u show a pic of the issue?
with this?
List<Vector3> GetNormals(List<int> triangles, List<Vector3> vertices)
{
List<Vector3> normals = new List<Vector3>(vertices.Count);
for (int i = 0; i < triangles.Count; i += 3)
{
var (i0, i1, i2) = (triangles[i + 0], triangles[i + 1], triangles[i + 2]);
var (v0, v1, v2) = (vertices[i0], vertices[i1], vertices[i2]);
var (e1, e2) = (v1 - v0, v2 - v0);
var normal = Vector3.Cross(e1, e2).normalized;
for (int j = 0; j < 3; j++) { normals[i0 + j] += normal; } // 0, 1, 2
}
for (int i = 0; i < normals.Count; i++)
{
if (normals[i].sqrMagnitude > 1) { normals[i] = normals[i].normalized; }
}
return normals;
}
like, with i0 + j
oh wait alright I see the issue
just swap the for loop with manual += on normals[i0], [i1], [i2]
List<Vector3> GetNormals(List<int> triangles, List<Vector3> vertices)
{
List<Vector3> normals = new List<Vector3>(vertices.Count);
for (int i = 0; i < triangles.Count; i += 3)
{
var (i0, i1, i2) = (triangles[i + 0], triangles[i + 1], triangles[i + 2]);
var (v0, v1, v2) = (vertices[i0], vertices[i1], vertices[i2]);
var (e1, e2) = (v1 - v0, v2 - v0);
var normal = Vector3.Cross(e1, e2).normalized;
//for (int j = 0; j < 3; j++) { normals[i0 + j] += normal; } // 0, 1, 2
normals[i0 + 0] += normal;
normals[i0 + 1] += normal;
normals[i0 + 2] += normal;
}
for (int i = 0; i < normals.Count; i++)
{
if (normals[i].sqrMagnitude > 1) { normals[i] = normals[i].normalized; }
}
return normals;
}```
index out of range at normals[i0 + 0] += normal;
List<Vector3> GetNormals(List<int> triangles, List<Vector3> vertices)
{
Vector3[] normals = new Vector3[vertices.Count];
for (int i = 0; i < triangles.Count; i += 3)
{
var (i0, i1, i2) = (triangles[i + 0], triangles[i + 1], triangles[i + 2]);
var (v0, v1, v2) = (vertices[i0], vertices[i1], vertices[i2]);
var (e1, e2) = (v1 - v0, v2 - v0);
var normal = Vector3.Cross(e1, e2).normalized;
normals[i0] += normal;
normals[i1] += normal;
normals[i2] += normal;
}
for (int i = 0; i < normals.Count; i++)
{
normals[i] = normals[i].normalized;
}
return normals.ToList();
}
or
List<Vector3> normals = new List<Vector3>();
for (int i = 0; i < vertices.Count; i++) { normals.Add(Vector3.zero); }
...
return normals;
it should also be clarified, the only reason why these values are successfully being applied to the final mesh is because I'm still using the second pass from my original code
this?
What I was trying to say earlier was that you can't just slap the normals from the bordered mesh onto the final because they're different sizes and have different indexes
yeah
I was kinda planning you would do GetNormals with draft.triangles and draft.vertices lol
ah, that likely wouldn't work either
both the bordered mesh and final mesh are generated starting from one corner and going row by row, the issue is that the border becomes the starting point of the bordered mesh
that's why I have both a vert and vertBordered
because their indexes are different
...
if (z >= 0 && z < zSegments)
vert++;
}
// uvs
for (int i = 0, z = 0; z <= xSegments; z++)
{
for (int x = 0; x <= zSegments; x++)
{
draft.uv[i] = new Vector2((float)x / xSegments, (float)z / zSegments);
i++;
}
}
draft.normals = GetNormals(draft.triangles, draft.vertices);
return draft;
although I admitedly still can't really understand why it's two separate meshes being created at the same time
so that I don't have to double the amount of for loops in my function lol
I'd be doing the same calculations twice for two meshes that are identical in shape besides the additional faces from the border
This does need to be as performant as I can get it
it's gonna be running on the Meta Quest 3 lol
oh, oof
maybe try making it work first before optimizing 😛
unless you can 100% understand what's going on in your code
because I'm struggling (it's 3AM tho :p)
Is there any better way that I can keep track of which vertices of the bordered mesh belong to the original mesh without relying on their indexes?
because that's what my implementation tries to do, but what you're providing assumes that draft.vertices[17] = verticesBordered[17]
which is not true
can you go ahead and try this real quick first?
sure, but it looks like that assumes I'm using negative indexes
with this ^ GetNormals method -- no negatives
I'm just suggesting you try using the GetNormals method after UVs calculation of your original code
gotcha. I think the issue is the new mesh has few too many vertices.
trying to decypher the code to verify atm lol
it should have more triangles -- not vertices
using existing vertices of two meshes to form new triangles
oh, no this doesn't have any information directly from neighboring meshes
it only has the means to calculate where the vertices on that neighboring mesh are
I see.. but if you just place two adjacent meshes without modifications, do they have a sufficient offset between them? or
placing them as they should be placed is what you're seeing here
even without modifications?
okay so think about it like this
faces without connected edges form a hard edge between them
you put two separate meshes side-by-side and line them up perfectly, it's identical to if they were the same mesh without a connected edge between them
gotcha. so you seem to understand you need neighboring mesh info -- where exactly in your code does that happen? in GetHeight?
yes
yeah sorry I may indeed not be able to help you.. still can't understand why you calculate for two meshes here instead of just draft
okay so back to the hard edge thing
if you wanna get rid of a hard edge, you gotta connect the faces, right?
once you have them connected, you can calculate the normals again and it'll be seamless
the trick is that once you have those normals calculated, you don't need those neighboring faces anymore
so what my code is supposed to do is grab those normals which are calculated as if the mesh were attached to all of it's neighboring meshes, and slap them onto the mesh that isn't attached
this is explained in the video I sent earlier
I assume you skimmed through it given how quickly you sited the code in it
he uses this graphic to explain it
the white vertices are the ones that belong to the final mesh
the black vertices are the ones that only exist in the context of the normal calculation, which is done on a separate mesh that is identical except for having those extra vertices
yup I got that -- in your case they're part of the mesh, though (called draft)
were you planning on discarding those "extra" vertices somehow? If so I completely missed that.
yes, that's what the point of creating two meshes at the same time is
one has the extra vertices, the other doesn't
last question (same question as before, actually)-- and you'll only retrieve the delta for the MeshRenderer? Or the whole draft?
(delta being just the black vertices + their neighbors)
because in case you'll be using the whole draft, might as well only calculate the draft, is my point
the black vertices are only used to calculate the normals of the white vertices on the edge, after that they're not needed
alright! Gotcha better now 😄
was just confused because in the code you posted you're doing this:
so assumed you were going for some kind of hack
ah, yeah that's only done after the draft is already completed. And to clarify, I didn't make that ToMesh() method, that's part of the asset that was modified to make this procedural terrain generation work at runtime
Procedural Toolkit is the one I think
that's all explained in this video
https://www.youtube.com/watch?v=f9uueg_AUZs
Download Link: https://drive.google.com/open?id=1B_IwrJKX9sQishwyrUbmWYCZrmhUwJTb
The project is using Unity 2017.3.0. Just FYI.
Update: Unity 2017.2.0 introduced the Vector2Int class. It doesn't make a difference, but it makes more sense to use it to keep track of tiles. It didn't exist when I originally made it...
I can't really watch this 😄
why are you returning draft though in your method, if you just want a copy of the original mesh with altered edge normals?
shouldn't you be instead generating a new mesh with the standard vertices but the normals on the edges kinda altered?
because this is a modified version of a pre-existing method included in the code from that video
maybe I should clarify as well, none of what I wrote directly works with any Mesh types
it's all done while it's still a draft
hm ok so you can use the GetNormals method to get the normals of the bordered vertices + tris, but the issue is with mapping them back to draft, which has different indices
exactly, yes
and SebLague's approach of using negative indices to filter them out didn't appeal to you :p
is it even possible for me to use negative indices?
yeah I can see it requiring a complete rewrite for it to happen
have you debugged it to check if there's a pattern you can count on regarding the triangle indices?
like, maybe first original tri index would be mesh.width, ending up at mesh.width * mesh.height
the only thing I have to go off with the way I'm currently doing it is the fact that I have control over how the vertices are indexed in the firstplace, trying to figure out which vertices are which by effectively reverse engineering itself
wanna try the non-performant version, see if it's otherwise sound? 😛
var bNormals = GetNormals(bTriangles, bVertices);
var dNormals = new int[dVertices.Count];
for (int i = 0; i < bNormals.Count; i++)
{
var bVert = bVertices[i];
if (!dVertices.Contains(bVert)) { continue; }
var dIdx = dVertices.IndexOf(bVert);
dNormals[dIdx] = bNormals[i];
}
draft.normals = dNormals.ToList();
return draft;
(sorry for the weird code style)
I'll give that a try after I finish eating, just got dinner
Also, to clarify the misunderstanding:
- I was thinking
draftis the FULL mesh including borders the whole time until 15 minutes ago 😅
Ooh I see lol. Yeah we gotta discard those borders cuz otherwise there'll be overlapping faces that'll z-fight
or whatever the term is
yeah exactly that's why I was thinking u wanted to hack it 😄
fair lol
if this works (meaning everything is setup correctly), I came up with a more optimized way:
- Use a single mesh*, and add all the STANDARD vertices for the non-bordered version
- Add the "extra" vertices & triangles to the END of the standard lists
- Calculate normals (should work with the exact same method)
- Remove the "extra" vertices & triangles & normals before returning the mesh
*single mesh meaning you get to discard trianglesBordered and verticesBordered and heavily simplify the code
does the order of the triangles or vertices in the list not matter?
reason is vertex and triangle order shouldn't be relevant in this context. All you need is just the correct vert indices on the correct triangles
huh. I was under the assumption it did
but that can get way too technical for 4AM Lyr 😅
fair, it at least gives me some direction. I appreciate the help
was fun
I have a quick question. I was looking through some of the mathf source code and I'm wondering how the hell this works. it's comparing a boolean to a number, originalTo, current, output are all numbers
(originalTo - current > 0.0F == output > originalTo)
are booleans represented as numbers?
where something like 0 == False would return as True?
In C++ yes. In c# I'm pretty sure it was stricter than that and required an explicit cast. Might be wrong.
But actually that could just be comparing 2 bools. One is from the expression before == and the other to the right.
Whoever wrote this is just a crazy person.
// Gradually changes a value towards a desired goal over time.
public static float SmoothDamp(float current, float target, ref float currentVelocity, float smoothTime, [uei.DefaultValue("Mathf.Infinity")] float maxSpeed, [uei.DefaultValue("Time.deltaTime")] float deltaTime)
{
// Based on Game Programming Gems 4 Chapter 1.10
smoothTime = Mathf.Max(0.0001F, smoothTime);
float omega = 2F / smoothTime;
float x = omega * deltaTime;
float exp = 1F / (1F + x + 0.48F * x * x + 0.235F * x * x * x);
float change = current - target;
float originalTo = target;
// Clamp maximum speed
float maxChange = maxSpeed * smoothTime;
change = Mathf.Clamp(change, -maxChange, maxChange);
target = current - change;
float temp = (currentVelocity + omega * change) * deltaTime;
currentVelocity = (currentVelocity - omega * temp) * exp;
float output = target + (change + temp) * exp;
// Prevent overshooting
if (originalTo - current > 0.0F == output > originalTo)
{
output = originalTo;
currentVelocity = (output - originalTo) / deltaTime;
}
return output;
}
OHHH
ye ur right
we can too with inline ternary
iirc this would end up being branchless in plain c# too var t = true ? 1 : 0
i dont think in unity tho 😅
i have little faith in ancient mono
assuming you're targeting IL2CPP, it does at least pass through a modern compiler in the end haha
thats true, presuming the produced cpp isnt nasty. some of what it gens is basically unreadable
// Prevent overshooting
if ((originalTo - current > 0.0F && output > originalTo) ||
(originalTo - current < 0.0F && output < originalTo))
{
output = originalTo;
currentVelocity = (output - originalTo) / deltaTime;
}
Hey, I need to delete some generated files in my project, but I'm not sure where Unity caches these. Does anyone know where they might exist relatively? I haven't been able to find them, even by searching for the *.g.cs files on disk on Windows.
have you searched for SystemGenerator?
I just found it all, actually. Library/PackageCache
I tried plenty of substrings and wished I could just know what the root was.
This just lead me to whatever internal method was throwing the exception, unfortunately. The stack trace didn't help... It was obfuscated like that. I knew that the type in the generated file was referencing a type that didn't exist anymore and that very error was blocking recompilation that would fix it.
Eeessh, okay... my project is in a strange broken state because my custom assembly OmiAssembly needs the UnityEngine.InputSystem definition as a reference. Here's a screenshot of what I'm looking at:
Note the "Missing reference" in the inspector when I select this assemblydefinition object in the first image.
In the second image, you can see that I can only view the assembly definitions that I have created in my project and none of Unity's build-in ones. If I try to click on the crossed eye icon (to show hidden files - allegedly there are 50?), nothing happens. I cannot view package files.
The errors in the console are suggesting that UnityEngine.InputSystem cannot be linked as a using.
Correct because your assembly reference is broken
You need to press the+ and add the input system assembly as a dependency
And remove the broken one with the -
Yes... my problem is that I can't locate those assemblies anymore in the dropdowns.
I'll restart Unity without entering Safe Mode to demonstrate, if you can wait a moment. @sly grove
Thanks for responding, btw.
When I expand the drawer for Assembly Definitions, I see these three options. These are the assembly definitions that are defined as assets in my project. There is a hidden files icon (the eye with a cross) that shows that there are hidden files that I can display, but clicking on that button does not change what files are available in the selection window. The button is responsive, but does not toggle over to showing the allegedly hidden files. @sly grove
Clicking one time on the + button here creates a new entry labeled (No possible reference). Here is also a view of what is in that dropdown.
@sly grove To make it clear where I'm specifically stuck.
I am installing a new version of Unity Editor (6000.0.41f1). I don't really want to create a new project and reimport parts piecemeal, but I'm unsure how to unravel this problem where core Unity assemblies are unavailable in the editor to provide for my own dependencies.
Did you actually have the package you need to reference installed?
If you do just go to that folder in project window and drag drop?
The InputSystem package is installed; my code needs to import it as using UnityEngine.InputSystem; to compile, but not seeing it is causing it not to compile, and in the editor, I can't reference the assemblydefinition for InputSystem in order to set it up as a dependency on the AssemblyDefinition scriptableobject.
For context, "my code" is a separate assembly. I could try to get rid of custom assemblies and let everything be Assembly-CSharp... I'll try that.
Do you see Packages/Input System in project panel
I'm waiting on a reimport right now so can't check, but thanks for asking. 😦
I would love to find the assembly in Packages/ if that's what you're thinking. 😄
asmdef is in packages if you do have it installed
I'll check when I can and can ping you with the result, if you would like/are willing. I appreciate the help.
Sure. If you are not seeing it I suspect some kind of installation problem
This wasn't a problem before I had some generated code that I KNEW was looking for structs that got refactored out of existence. To solve that, I tried to delete the generated files *.g.cs in the Library folder. Then, my custom assemblies couldn't find their dependencies, and the UnityEditor wouldn't locate .asmdef in property drawers, so I got caught in this state. @jolly token
So now, my assemblies can't find Unity dependencies and compile, but Unity won't compile to reveal the dependencies that I need.
So the editor isn't allowing me to view the Packages/ dependencies in property drawers to possibly solve the problem.
But right now, it's doing a reimport, so I can't tell you exactly where I'm at.
If I need to, I'm mentally prepared to port over to a new project, but I would like to understand how to salvage this problem within the confines of Unity.
Hmm yeah we'll see
I'm treating this as a tooling issue for now. Thanks for taking an interest!
Still rebuilding the project.
I have a problem with my multi-training. As you can see, when a ML-Agent touch the wall or the ball, the episode ends, giving a positive or a negative Reward. The only problem is that the if one AI ends his episode, ends the episode of all others. Please help me!
I wonder if this is an Odin problem or something
One thing you can do is find a project with an asmdef with the input system ref and copy the yaml
Thanks! I’ve actually decided to restart this project and reintegrate stuff somewhat piecemeal. Half the game is legacy stuff that was getting converted over to entities, and a huge branch of stuff ought to be its own package, so it is sort of worth it.
Like, a lot of state automata are generic, but contain some stuff that should just be part of derived classes. Too many references to UnityEngine in places where the code isn’t really “Unity-side”, etc. It could use a pass.
anyone familiar here with burst? I'm looking to do some optimizations on my codebase and want to start integrating jobs in the future. However since I still haven't fully wrapped my head around it I'm just starting simple by going through my code and restructuring things to utilize burst whenever possible
with that I have a couple of questions about [BurstCompile]
are there any benifits to using [BurstCompile] on a struct? from what I've read there is
and in addition, when using [BurstCompile] on the parent struct, any sub methods within the struct (i.e. static methods) do they automatically get flagged with [BurstCompile] or do I have to add it manually?
The whole struct should get burst compiled. You would know if it didn't work if the job cannot compile or execute.
the struct is not being used in a job currently, I'm also wondering if using that tag also has benifits performance wise?
like I mentioned I read online from sources that there is, but not too sure
You can have a job in normal managed c# or choose to use burst with it which will compile it to native code to then execute.
When you use burst you are limited in what you can use and often need to use native collections to put data in and get data out
Burst compiler just compiles the code using certain CPU features, like SIMD, so not any kind of code could benefit from it. It's mainly useful for vector math, where many variables(vector components) get processed in a single CPU operation. Possibly loops with arrays are simd optimized as well if there are certain math operations performed. There are some other features too, but you should research it yourself.
You can try it out, test and profile with/without to see if it provides any difference in your specific case.
Using it on a struct would just mark the methods of the struct to be burst compiled, just like you said. I think it applies to static methods too. You should check the docs to make sure.
Anyone know how Unity's build system works?
I'm trying to get a source generator packaged with a nuget package to work - so the package comes with a .dll library and a .dll source generator.
When writing scripts, I can reference stuff in the .dll library fine, but when the generated code from the source generator isn't able to.
I've checked the unity logs and there aren't any warnings
once coreClr migration is done, we don't even need burst for SIMD.
Vector128/256 and vector generics are right around the corner 🤤
Just out of curiosity could you elaborate on those examples? New to the subject and would love to learn more
They are natively accelerated and parallelized on hardware(cpu) level. So you can take advantage of AVX/AVX2/SSE42 cpu instructions pretty easily. And yeah, they're goddamn fast!
here have a read -> https://learn.microsoft.com/en-us/dotnet/standard/simd
that said, y'all better learn how to bitshift starting from now 😉 ... bitshifting is king when it comes to simd
Fun fact, System.Numerics types been SIMD'd since ancient times including their Vector2/3/4 and Matrices
And TensorPrimitives makes it super easy to write fast hardware accelerated code in some cases
Tensor apis will eventually be official, no more for separate nuget package 🤤
can’t wait
missed the example part, but the code would look like this
var xyzx_a = Vector128.Shuffle(a, Vector128.Create(0, 1, 2, 0)) ^ neg;
var dat = Fma.MultiplySubtract(yzxz_1, zxyz_0, Fma.MultiplyAdd(val0, b, Fma.MultiplyAdd(val1, val2, val3 * val4)));
in this case I'm shuffling a 128 bit vector once, then XOR-ing , then do bunch of FMA3 instruction mm_fmadds Multiply + Add (Fused operations). Those 6 operations will just be 3 instructions in this case and 1 rounding, due to it's fuse nature of FMA3 instruction
ignore the janky naming scheme there, straight up copied/pasted from my code 😌
gotta be careful with shuffle tho
until this is implemented
nah, the regular Shuffle is not the same with ShuffleNative... the Native version is unsafe operation, the regular Shuffle is pretty much safe
Hey, how do I check if a Component I have referenced earlier still exists or if its GameObject has been deleted from the scene?
Is this related to the garbace collector (do I need to interact with it to figure that out)?
You can check it against null. Like (component != null) or using a conditional null check if you are trying to access a method inside the component, like ( component?.Method())
Are you getting any specific error?
Well, the thing is I am storing a reference to a component that at this point still exists, when the component gets removed from the scene later, the reference remains non-null but accessing into it causes a Unity crash
? shouldnt be used on unity objects, it doesnt use unitys null check
This really doesnt sound like an advanced issue so maybe post your code in #archived-code-general or #💻┃code-beginner
i'm downloading a .txt file at run-time and I don't know the encoding used. I wanna get it into utf8. Is there some simple method I can use to convert from aribtrary encoding into utf8? or do i have to write it myself.
like because it needs to handle utf16-le, utf16-be, ascii, etc.
if you use it as a text asset you should be able to get text but else you can convert binary to utf8 and other encodings manually:
https://learn.microsoft.com/en-us/dotnet/api/system.text.utf8encoding?view=net-9.0
System.Text.Encoding.UTF8.GetString can be used for example
Where are you getting these files that you don't know how they're encoded?
well i do know where they are, it's currently utf16-le
but in case it changes
oh well if endianness is different then you need to double check but most platforms now are little so it can probably be ignored
What would be the adviced way to get LUA into unity 6?
Moonsharp? Is there something newer/better? Any insights?
It seems most lua assets on the store are just moonsharp wrappers
Moonsharp is the best way I know
Can you guys share some reasons for bringing in LUA to a project?
- mod support
- making a simple scripting language for your game designers
Thanks exposing it to users or non-devs is the use case I also had in mind.
Was wondering whether I was missing something important
You can also hire a bunch of Roblox devs/players for "cents", instead of actual C# developers.
I know it’s a joke but Roblox devs are actual developers too
No need to repeat my joke.😛
Maybe they're developers on the level of game modders. Though, some modders(Skyrim fo example) mess with things on a deeper level than actual game developers(like code injection and rendering pipeline modifications)
Well I know some very talented devs that do games with Roblox from time to time
I’ve never seen any actually publish a game tho — I heard them rant about silly restrictions like physics etc.
I know industry professionals who are doing roblox stuff because the industry is that fucked. I wouldn’t underestimate some of the projects going on in roblox nowadays, quite a few surpass most stuff you’d see here
if you're not using custom encoding when streamReading, you can just do this
Encoding.UTF8.GetString(Encoding.Default.GetBytes(myString));
Weird question, but is it possible to give an object "FPS Priority". Imagine a scenario where a bunch of physics simulations fluctuate around 60 fps, but there is a bouncing ball that I want to see at 100 fps, even if that means that the other objects dip to 55 fps. Weird question, I know.
probably only with you enabling or disabling rigidbody simulation manually
best i can see is being able to override solving itterations per rigidbody https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Rigidbody-solverIterations.html
if it works for your use case, you can use multiple physics scenes with different simulation rates i think: https://learn.unity.com/tutorial/multi-scene-physics#
Oh that is interesting.
So I could detect that the deltaTime on the ball is getting too high and adjust the simulation rate of other objects.
I'm not actually trying to make a ball bounce but that's the easiest way to explain it.
oh dang i totally forgot about this, you could just use this to always simulate important objects more frequently
or others less
Are you sure you dont just want interpolation?
Do you actually need it to simulate more often or just to look smoother?
I don't think that two physics scenes can interact with each other
It's complicated and very much in the idea state. The scenes not being able to interact wouldn't be a problem.
So it turns out when uou do multi-threading, if another thread is allocating lots of memory, that another thread can slow down other threads though they are not connected in any way. It happens because stuff happens at IO level?
can someone confirm this behaviour? that it is actually the case?
could be due to memory allocation on one thread blocking another? or some large gc run? tbh im not sure 🤔
How are you multi threading
the main thread has
dictionary
main thread is mono behaviour and doesnt do anything with the dictionary
the 2nd thread runs and allocates and adds lots of stuff to the dictionary
did you pre allocate the dictionary size? are you making lots of garbage as you do this?
Is this an actual thread or something like a task
virtual thread?
C# doesn't currently have virtual threads, I got confused
@novel plinth Can they...?
I did not allocate the dictionary size. i am expanding over time rapidly using another thread
I have a thread and the thread has arrays of tasks
What and how are you generated data
if you are adding many thousands of elements then the dictionary will keep being re allocated to resize. so giving a smart initial size can help greatly.
the idea was that the 2nd thread would not interfear with mainthread(unity)
I just allocate bunch of bytes array to add to dictionary
Is this in editor?
no. it is ran during gameplay
it is in the editor and executed when u hit play
how you spawned the thread?
i'm confused here, you said tasks, or the good ole Thread?
actually I am abit confused between tasks and thread.
I launched a thread called Apple and then I created bunch of tasks inside the thread Apple
I just realized I don't know clear difference between tasks and thread
task = task
thread = worker (one who performs tasks)
When I create bunch of tasks, I dont specify which thread is going to run it.
when I create a thread I specify what code that thread is going to run
what is running my tasks?
It depends
This is an essential truth of async in its purest form: There is no thread.
(not that say that there is never a thread)
If you do task.run, it generally spawns a thread (I think unless you have some weird scheduler it always spawns a thread)
First I am going to try to set initial dictionary size and see if it resolves my issue
second if it doesnt then... I dont know
lol
You could always provide more info, rather than us having to pull everything out of you
Task.Run and unity jobs should be using already created worker threads
could it be using the main-thread (unity)?
no
i mean you said that ☝️ ... arrays ain't free... if you know you'll allocate alot, use ArrayPool<T>
or just Span<T>... I personally prefer the latter
i like me some stackalloc span sometimes
for(int i = 0; i < bestNumThreads; i++){
var threadIndex = i;
tasks[i] = Task.Run(() => {
//Allocate lots of memory
});
}
// return;
Debug.Log($"Number of tasks: {tasks.Length}");
while(!tasks.All(t => t.IsCompleted)){
// Wait for all tasks to complete
}```
I dont think the issue was dictionary
I removed the dictionary expanding section and just did lots of memroy allocation
The game still freezes-chokes up
ofcourse it allocates, as I pointed out above, arrays aint free
no that is secion of code inside a thread
those Task.Runs would most likely kill the perf more than you gain anything from it
not the main thread
var tasks = new Task[bestNumThreads];
for(int i = 0; i < bestNumThreads; i++){
var threadIndex = i;
tasks[i] = Task.Run(() => {
//Allocate lots of memory
});
}
// return;
Debug.Log($"Number of tasks: {tasks.Length}");
while(!tasks.All(t => t.IsCompleted)){
// Wait for all tasks to complete
}
Yea sometimes the cost of starting many tasks or threads out weighs the benefits
Perhaps 1 thread where you re use allocated memory would be better? can you share more of the work?
I think that's how I should do it
per task, just allocate one array, then re-use
right now I create LOTS of small arrays per task
you can also look at the unity job system + burst + native collections
native collections are needed for burst but also mean no gc!
I think Unity's job system is really helpful that it provides framework that tells you how to use it. But I feel like all the structures of using Unity's job system adds too much work on my shoulders. Of course I wouldn't run into walls like this if I used Unity's job system. I think my issues happen due to my low understanding of inner workings of the computer system. I think if I were smart, I wouldn't have ran into the wall and just would have been fine multithreading myself without using unity's job system.
in case you don't know Dictionary<T> ain't thread safe.
that said, I don't think you really understand the concept of multithreading here..
yeah I think my understanding of the multithreading is low
I do use ConcurrentDictionary and other concurrent stuff though
concurrent collections are good when you may be reading and/or writing from the collection from multiple threads
e.g. block other thread till writing is safe, skip reading until its safe to do so on main thread (so we dont pause the main thread)
the main purpose of those (concurrent-) collections is to have lock-free thread safety
I mean you might jsut be overloading the threadpool and also overloading the allocator
I doubt it because, when I set the allocated array to be small, the problem goes away
I do allocate like [1000000] size of two ints worth of array for like 10x10x10 times
so that would be (64 bytes) * 1000000 * 1000 bytes
Last one i used was a concurrent queue so perhaps i did it in a strange way 🤔
Consider using ArrayPool<T> for those arrays, it's zero alloc 99.999% of the time if you return it back to the pool each time you're done with it.
also, what heavy operation that requires you to task.run in a tight loop like that?
I'm saying is that, if it can be done on the mainthread, ditch out those task.runs and it will save you lotta headache
basically reading a map like in Minecraft, read map from disk, load it onto ram
I should re-use array (as buffer) or use ArrayPool. This seems like being clear the more I talk
I made a mistake. When I just need to read, I could have just reused the array 100%
pls tell me you're reading 1000+ maps at a time so I'd not complain 😄
The entire map I am reading is about size of
100100100 1010*10, so that woud ble 1,000,000,000 units multiplied by 64
64,000,000,000 bytes
Sure but that's a problem that is exaggerated by large sizes (they take longer to allocate, threads take longer to free up, compounding issues)
you should really start listening to what people are telling you here, this has all been pointed out to you over the past week.
all the comments are just repetitions of the same ideas and advice
The issue is my stupidty of not reusing an array but instead creating arrays each time I need to read, I think, as pointed out I should use ArrayPool
How about you try that out and report back?
your issue is that you don't fully understand your problem and whether/how to solve it via multithreading
That sounds great
Then why do you even program or make game? lol... if you need to fully 100% understand how to do something from scratch to finish, you are not going to start anything.
we learn as we go
we learn to walk before we run though
You have a point, some people learn more chaotically
I upvote this opinion
I don't want to sit and read through all the ins and outs of multithreading. I would like to build something and hit walls and burn.
anyway gona do the thing to fix my game and comeback to report
yes it works yeaeeee
no more choking to freeze
I can construct meshes almost immediately. But it looks like reading files is slow.
I guess I need to load file content to my ram ahead of time (during loading I guess?) instead reading it when I need to render a chunk
still looks pretty slow. is this doing something like marching cubes?
but glad its better than before!
That's 500x500x500 cubes though, hmmmm
I do agree that it feels slow still
This is when I pre-loaded the world data onto memory instead reading it each time.
I removed Tasks. It is faster now. But it seems faster if the loaded data is bigger at certain than certain number. I calculated the performance gain in seconds. The whole loading data runs about 20~30% faster at best case. I guess it's not necessarily worth it.
told ya 🍷
I probably need to really scale up work load if I wnated to take advantage of it
it seems like the bigger the amount of work, better it is
so I think I solved "loading issues"
rendering 500x500x500 voxel cubes take about 18 seconds
I feel like this is slow
make a bigger chunk instead
I am using 16x16x16 sub-chunk size, just like Minecraft
you can then further insteanced mesh them
but then when I edit one voxel, the bigger the size of chunk to be changed in rendering
also I feel like this rendering being slow is more of my fault than the design of it
16x16x16 subchunk rendering size is blazing fast in Minecraft
I must be doing something stupid to slow it down
if you want to keep it, make a bigger chunk as LOD
I can do that? chunks as LOD?
so at certain distance it wont kill the perf
sure why not?
or if you're lazy, just use instanced indirect and make their bounds be your culling distance
so no need for LOD this way
but I'd still prefer LOD tho, you'll have more control over it
and much simpler especially when they've fixed shape like a cube you showed
I don't understand this; so I know launching lots of thread can be rather inefficient than doing it with a single thread. Let's say I launch a thread. Then in that thread I launch 100 threads and 100 tasks of inefficient slow jobs. But these inefficient jobs should not slow down the main thread right? but the main thread (unity) slows down significantly.
I expect Unity(main thread) to run flawlessly because all the dirty works are being done in other threads. Main threads do not have any lock either.
I tested whether it is my system slwoing down by running some 3D games. The other 3D games run fine. So I think the threads launched are somehow still connected to main-thread. And this is driving me nut. How is this possible?
ohhhhhhhhh
could it be because the other thread is expanding list inside the Monobehaviour?
ohhhhhhhhhhh
If the thread is expanding the list(or dictionary) inside MonoBehaviour, the object needs to be reallocated for the new size
ohhhhhhhhhh!
A lot of multi-threading is fundementally limited in Unity because of how much has to circle back to unity's systems which are mostly single threaded
yes. I didn't know how the hell it was circling back
but as always, I was the problem, the human error
which is why compute shader is superior
I mean compute shader being in the GPU makes it, by design, separated from the CPU. Which is cool I guess
I reserve my CPU for physics and pathfinding calcs. Let the gpu do everything else
Right now I need to generate mesh for my Minecraft like world
do you think I could use compute shader to generate chunk shapes?
pretty standard ye
I never heard using GPU to create verticies and send it back to CPU then I set the mesh with the GPU-generated vertices to send it to GPU
the process, I think, I can do it, but that sounds so odd
Why do you need to send it back? Just do everything in the GPU
because I want triangles to feed to MeshRenderer?
r u suggesting I do that... what was it called... the method ahhh lettude method?
voxel lattice
I heard this is pretty inefficient
most folks I know that do voxel stuff, are against it
I made a cool level editor system for my vr game with save and loading that detects if the player is in vr or emulating the apk on pc for the editor version, but when i try building it says handles and editorGUI dont exist in the context. Please help. I even tried wrapping to see if i could even get it to build even though the version wouldnt work in a emulator and only the editor but that still didnt work
wait chat i think i figured it out
i had it drawing gizmos in here for no reason
Was looking into my previous project I was working with this and yeah, I do all the iterating for chunking inside of the GPU, pass it back to the CPU to then use the Mesh API. I think it turned out to be a lot quicker than trying to thread it but I wasn't something I probably had correctly implemented.
https://cdn.discordapp.com/attachments/288887968960086016/1166100514459635772/Unity_mFVEeeMNor.mp4
Had it rebuilding pretty quickly too
nice
trying to figure where I left off but editor tooling is my bane
btw
I am realizing even if I do mesh generation fast
I will prob run into fps issue
I wish Unity had Nanite like Unreal
this is so sad
I really like C# and Unity but I might need to move to Unreal
for this project only perhaps
Why does unity not have Nanite. It's been years. And I know that Chinese Unity already does Nanite stuff 😦
Everyone creating their own voxel engine nowadays. Just do that np
i have written a script that combines spriterenderers into a mesh, then creates a texture to place on the mesh based on my spriterenderers. Everything works fine in editor, but when i build my project, the texture looks all different.. Im not sure why the results would change in my build but work in the editor.
Any ideas?
are any of your sprites in an atlas?
no none of them are
I called RecalculateBounds() on mesh, I heard this triggers frustum culling
I don't think this is what u r referring to? What is the "instanced indirect"?
this?
Renders multiple instances of a mesh using GPU instancing and rendering command arguments from commandBuffer.
ohhh so I could copy paste a cubes
I think I need to do this
Distant Horizons is an incredible mod for Minecraft that is basically the future of the game...
Distant Horizons https://www.curseforge.com/minecraft/mc-mods/distant-horizons
How to install Distant Horizons https://www.youtube.com/watch?v=pIRSjKz9RLg
#minecraft #distanthorizons
they can do 1000+ render distance thanks to LOD
lol how do you even LOD voxels
yeah it's a bit odd
chunking is basically the LOD
I think the maximum LOD would be
16x16x16 chunk being rendered as a single cube
16x16x16x could be rendered using 8x8x8 voxel data
basically treat the chunk like an image file and resize it
makes sense, would require maping the texture across it at that size
and would only work if all textures match
well, actually not exactly. UVs would be what changes the texture.... so yeah basically chunking
its odd
yeah
I need LOD so bad though
I originally ditched the idea of tiny voxels
but with LOD I think it is possible
It just came up to me if I do box sampling to 100^3 voxel cube it will be 96^3 (each box sampling will reduce edges) and so on and so on until it is 4^3 voxels cube size
is it possible to lock a cursor in its palce in unity?
yes
how?
google search
wait are you saying that you went to lock a cursor not in the center but where it is?
yes
you will need to lock the cursor in the center then render your custom cursor on the screen and when you want to lock it you do not move the custom cursor
but i dobnt have a custom cursor
custom cursor is just an image that you draw on screen
you just throw a circle in the paint application
use that as your cursor
but then the position of the main cursor will be in the middle of the screen
yes
does it have to be a real cursor? do you have a reason for it to be a real cursor?
It's not really possible to lock the hardware cursor anywhere except the center.
yeah since i want em to like hold right click to orbit around the player
and then let go of it to stop
You can get partway there with cursor warping, but Unity's framerate will always be slower than the mouse cursor hardware poll rate
why can't you just throw a fake cursor? if you draw a fake cursor that looks like a real cursor it's the same look
they needa fix that tbh
if you also implement the functionality of cursor to a fake cursor it's just going to be same as the real cursor
Ok for this you can save the position, lock/hide it while dragging, then cursor warping it back to the original position and show it again when you're done
how do you cursor warp?
I didn't know that you could warp your cursor back to where it was
but I can already imagine some complications that's related to Windows
I bet there is going to be complications when executed inside the scene and as a build
Sorry newer link here https://docs.unity3d.com/Packages/com.unity.inputsystem@1.13/manual/Mouse.html
alrighti ma see if it works
honestly I didn't know you could move cursors around
is this new? I don't think it existed before
it's new as of the new input system
(which is like 5 years old)
I think I remember this. I think long ago I tried to use it and it was very glitchy. as I said it behave differently depending on where I was using it
That's a 5 year old post.
yes I'm reading through the thread and I'm remembering I experiencing the same issue
I remember it was like weird when I used in scene, standalone, and Apple pc
How to reproduce: 1. Open the attached project's Scene labeled "GamepadMouseCursorSample" 2. Plug-in a Gamepad 3. Enter the Play Mod...
aha
Please help me. I need to rotate a rigidbody about an axis, like RotateAround but physically
set its angular velocity
The angular velocity rotates it about the pivot of the object.
indeed
This is not what I need
