#archived-code-advanced
1 messages Β· Page 128 of 1
I have no idea how to copy-paste stuff correctly into discord
so one sec
*.blank
*.blank.meta
This implies that the build is rebuilding addressable. I don't know if that's supposed to happen or not. DId you modify anything related to addressables?
nope
because I haven't got too much experience with Perforce, I rather know Git
**/*.blank
**/*.blank.meta
might work
I mean if the building complains about the addressables.json orwhatever it was called
then /Assets/StreamingAssets/*.json
That would need to be added.
though, I wonder if it would help, considering it must already be in the depot
because Git worked differently, Git never complained about anything during building
Try it out and tell us
do I need to restart p4 somehow?
or it will just recognise the p4ignore changes
Probably not. Maybe restart the editor if it's the plugin that is causing the issue
I received the same errors
but btw, that addressables_keys.json is not read only, and it was not read only before I modified the ignore file
Okay, at this point I'd try to remove the p4 plugin
well, I believe that would cause me an extremely hard time to place it back. So maybe I will go to a place where I can connect to P4. But that will be probably only tomorrow (today is a national holiday)
I just wanted to progress
Why? what exactly so difficult about adding it back?
what p4 plugin do you mean btw?
p4 plugin of Unity?
p4 plugin of VS?
Unity
Yeah addressables updates some shit every time it builds
But that's post processing I think? The build itself might already be done by that point
btw
some of you asked the task manager
I don't even know who it was
this is how it looks like when it gets stuck at Finished
is there a unity plugin for v4 btw?
I just connected to p4 from Unity and that's how it works
I'd assume it's a package
well, I didn't need anything like that
I could connect without any plugins
from Unity to P4
and it told me its connected to P4
there's an Offline Work checkbox in the Unity though, related to P4
but it told me to only check it if you know what you're doing
Well, you probably should learn what you're doing and then check it...
I mean I afraid I wouldn't be able to add my changes back when I will be online
You just need to remember what files are modified and use "reconcile offline work"
Look it up. Read the P4 manual.
I have returned.
So if I already had scripts, where I have removed the read-only from, and modified them, does that mean I basically already "working offline" and I should check the "work offline" checkbox and use "reconcile offline work" when I have connected to the p4 server again?
Yes
since then I realized the build is basically created, not sure if its 100% finished, but its created
since then I figured out the issue had nothing to do with P4
and now the build gets created 100%, the progressbar also goes along to the very end
Hi! I'm looking for advice on how I can go forward with a tool I'm currently working on - I'm feeding data for levels, characters, dialogue, etc from the StreamingAssets directory to give game dev modding communities something to play around with when I release my project (as well as generally making building content in the game easier for me once systems are code complete). I've managed to jump most hurdles relatively fine, but I'm stuck on one thing here with no apparent forum posts really leading me anywhere helpful so far.
I'm looking to take .png files from StreamingAssets as sprites (this part I've done now) and insert them into a mecanim clip at runtime so that I can make different run cycles. Any ideas? π
Unity hate you and dont let us modify clips at runtime π¦
Could I maybe just make an ultra generic animclip in a prefab and pass new sprites onto the game objects that are referenced?
you got animation clips
Load the image: https://docs.unity3d.com/6000.2/Documentation/ScriptReference/ImageConversion.LoadImage.html
Cerate a sprite from it: https://docs.unity3d.com/6000.0/Documentation/ScriptReference/Sprite.Create.html
Inserting the sprite at runtime is probably best done with this: https://docs.unity3d.com/Packages/com.unity.2d.animation@10.2/manual/SpriteSwapLanding.html
I understand animation clips can't be modified, but the assets they reference can right? π
er, animationcurves ;p
animation clips can be modified at runtime?
You can also make different animationoverridecontrollers and swap them out
I've already done the first two, but thanks anyway! From what I can see in the sprite swapping thing, that's for 2D only right?
isn't this 2D/
I'm using sprites in a 3D environment, think like Paper Mario.
Of course but you cant replace an asset at runtime unless you replace the texture data and keep the sprites in tact
you're still using SpriteRenderer then
so it's the same
I mean, it doesn't matter too much if it's part of the streamingassets, you just need to bind everything accordingly
Oh okay, I wasn't sure if that package only worked in screenspace or something π
If you're not using SpriteRenderer then you're using MeshRenderer and you can just create a material with your sprite you want to swap in.
2D games don't work in screen space
they're the same as 3D games just with a fixed camera angle
Ah my bad. Been doing SDL stuff lately and you kinda do draw to the screen on those, so I think I'm a little confused haha
Spritesheet, except I'm not using sprite aliases, just individual files.
Thank you! Hopefully this is at runtime
of course, yes
really all you need to do is swap these images over some curve rather timeline of keypoints
not like we're talking 3D with bone deformations
It seems like creating SpriteLibraryAssets is only possible from within editor.
Guess I'll do some chasing to see if I can sprite swap .pngs onto a SpriteLibraryAsset at runtime
you can add sprites to it at runtime
I really need it to be as user friendly as possible with regards to modding tools. If i start locking things behind needing Unity installed, it might make it too awkward for people to want to play around with.
Interestinggg
Thank you very much for pointing me in the right direction!
What was the cause then?
some custom post process code running when build has been finished
can I have an issue if I don't use "reconcile offline work"?
because I don't really understand how it works
Yes. You might have changes locally that are not tracked by perforce.
fantastic
It simply runs checks on all the workspace files and checks if they are synced/up to date or not.
If it finds files that are changed, it adds them to the pending changes.
ok, if I use shelve on every changelist, then I will be okay, right? so then I can return to the current state anytime, right?
Well, to use a shelve, it needs to keep track of your changes in the first place.
Reconcile is specifically for cases where perforce loses track of local files
so the "reconcile offline work" only shows the modified files since the last checkout, right?
Yes
so then if I use "reconcile offline work", and then shelve all changelists, then I can return to the current state anytime, right?
Should be able to, yes.
ok, and if I modify a shader and that shader modifies like 20 materials, should I commit and push all of them?
or I should only commit and push the shader in this case?
because I never needed to modify shaders
Well, it depends on what kind of changes these are and the workflow your company is following.
If these changes are made automatically due to your shadow changes, it's usually a good manner to upload all the changes involved so that these changes wouldn't pile up on other people machines that don't even know about your changes.
and materials could be merged as well?
with yamlmerge or with something else?
Everything can be merged. It's just a matter of difficulty.
I assume if they're serialized as yaml, they should be merged automatically.
Anyways, you're asking questions that there are no definite answers to outside of actual specific case.
because I always afraid of version control systems
especially if I'm unfamiliar with it
because people can lose hours of work with one wrong command
Then learn about it properly. Or setup a test environment and mess with it until you're satisfied.
Generally, you can't really break stuff to a point of no repair
Unless you have been given rights to delete changesets or depots
Generally, if you have it configured correctly, this shouldn't happen. Even when you pull changes, they would just be applied additively or merged with your local changes.
and after I have shelved stuff, I can revert or discard them, right?
If they are applied to the workspace, yes.
what does it mean they are applied to workspace?
they are in the workspace, yes
if that's what you meant
@untold moth have you meant this?
I am trying to use an nuget roslyn code generator in unity (installed by nuget for unity).... i get this error here:
Assembly 'Assets/Packages/Microsoft.CodeAnalysis.CSharp.Workspaces.4.1.0/lib/netstandard2.0/Microsoft.CodeAnalysis.CSharp.Workspaces.dll' will not be loaded due to errors:
Reference has errors 'Microsoft.CodeAnalysis.Workspaces'.
Anyone having an idea how to resolve this? Using unity 6
Yes. That's what I meant. The whole point of shelves is so that you can store changes somewhere without submitting them or having them applied to the workspace.
Glad for any help! Struggling with this since ages
So i kinda solved my roslyn source generator iussue... atleast unity tells me it generated the files. But i cant find them.
Where are generated files from roslyn located at? Also my rider instance does not show me that the generated code is usable, it cant find the methods... any ideas?
Anyone? Where the heck do i find the generated files... unity says theres an syntax error inside that file but i cant inspect it since its not there.
The generated files don't exist physically on disk, they are entirely in memory. I don't know about Rider, but in VS/VS Code you can view them in the solution explorer > the project > analyzers > the generator.
how to compile a dll for platform A if it contains a constraint for platform B, which preprocessor directive doesn't exist for platform A?
both A and B are NDA stuff
what do you mean by "contains a constraint"?
you can define constraints (preprocessor directives) for dlls
but since then I solved the thing I wanted
Have you measured instantiate time through reflex and compared it with simple instantiation?
I have tested by creating 100 game objects. In simple instantiation, it takes 0.01 seconds but through zenject, it takes 0.7 seconds!
The difference is significant.
I want to load a map with many trees.
It takes around 20 seconds for small map
I think I have to create trees using Unity instantiate. So define a class as jungle to handle and manage all trees and inject dependencies to the trees manually.
What do you think?
From what I remember zenject uses reflection so ofc its gonna be a lot slower than normal function calls.
Surely you can just init them manually in this situation?
how many deps can a tree have anyway π
Should use the profiler to understand the issue properly
if you instantiate it through zenject iirc you're telling it to go through the whole hierarchy of the new object, usually you don't need that and can save a lot of time by instantiating it yourself and injecting only the component you care about
depending on the hierarchy of your object that can save a lot of time
but yeah profile it, there's all sorts of other things that could be wrong with your setup
i'd generally just avoid using zenject for something that spawns hundreds of instances though, usually it's just simpler to have one parent object with references to the dependencies that tells the instances what to do, and then you don't need hundreds of individual references to those dependencies
which is usually going to be faster no matter how you set them...
you can also try VContainer which has some source generation tricks to speed up instantiation, avoiding a lot of reflection
Reflex claims to be faster than both https://github.com/gustavopsantos/Reflex/, though these are simpler DI frameworks.
@untold moth if I copy and paste a p4 workspace into a different folder (as a security save) and if I modify that, that won't appear in the original project as dirty files, right?
Right
Thanks, yes I know I can avoid component injection in spawned gos and instead reference them through inspector or a bridge component which keeps all components and centeralize it but you know injection using DI is so clean and elegant
I love it, it is so neat
Maybe, just inject scene gos as singleton but inject internal components using ref or get component
"I love bad performance is so neat!"
Yes, they claim reflex is faster but there is no doc.
Also, they say there is no factory api. You should write your own factory
Yes but all scripts are on the root.
Reflection is slow.
OK, thanks dudes. I test vcontainer code Gen version
I would add root only injection to VContainer if you know you don't need it to traverse every bone on a character π
@dreamy escarp This seems to be part of your #π»βcode-beginner question? Add context to there instead of trying to move it here.
Hi all,
Iβm running into a design issue with UniTask. I use it in multiple parts of my game to sequence events. opening panels, waiting for them to close, handling level transitions, etc.
Since I don't want the same task running multiple times in parallel, I always need to check if the task is already running before scheduling a new one.
Up until now I did this by using ".Preserve()" and then storing the UniTask as a variable and checking its status.
I prepared a sample script to demonstrate this:
{
private UniTask _task;
public void ButtonClicked()
{
if (_task.Status == UniTaskStatus.Pending)
{
return; // we are already doing the thing!
}
_task = DoTheThing(this.destroyCancellationToken).Preserve();
}
private async UniTask DoTheThing(CancellationToken cts)
{
Debug.Log("Starting the thing");
await UniTask.Delay(TimeSpan.FromSeconds(1), cancellationToken: cts);
Debug.Log("Finished doing the thing");
}
}```
However this causes Exceptions of DoTheThing to be swallowed and only displayed once the GC runs.
While investigating this, I found that using the Status property of UniTask should not be used at all, since its not save because of pooling: https://github.com/Cysharp/UniTask/issues/643
So now I'm wondering if there's another way to do this? I could define a bool flag "isRunning" instead and set it to true at the start and end after the task is done, but this does not work if the task is cancelled?
Am I missing something?
Its because the task is not awaited. This should be fixable if you use .Forget() on the new Task returned from perserve.
and with preserve/lazy unitask you can await it in multiple places so you could have your ButtonClicked function still await it.
You mean like this?
_task.Forget();```
I was under the assumption that both of these are opposites to each other, so I can't combine them
I'll try that out, thanks! I
What I know is Forget() will make sure the exceptions are reported.
I think UniTask.Lazy / preserve are the same (making a new task that is not re used in the pool so can be awaited many times)
I think you should be using cancellation token source instead of this preserve setup
Maybe not actually, I thought you were cancelling the existing task. The setup feels a bit dodgy to me, but perhaps it's just the stripped down example that makes it appear that way
Hello,
I would like to ask about updating a project from Unity 2021 to Unity 6. After updating the project and exporting it to Xcode for testing, I encountered the following errors in Xcode (note: the export process completed without any issues):
Error:
Undefined symbol: __storeKitCanMakePayments
I noticed that the main difference is that in the project exported from Unity 6, the new GameAssembly now includes IL2CPP combined, instead of including all the source files for compilation under the UnityFramework target as it did previously.
How would using a cancellation token help me tracking the status of the running task? π€ Isn't this only giving me the option to interrupt it? I dont want to interrupt it, I only want to prevent a new one from being started while one is running.
I'm also a bit hesitant using the Preserve+Status approach, since the dev is advising against using it.
I was thinking, maybe this is a valid approach
{
private bool _isRunning;
public bool TryRun(Func<UniTask> taskFunc)
{
if (_isRunning) return false;
Run(taskFunc).Forget();
return true;
}
private async UniTaskVoid Run(Func<UniTask> taskFunc)
{
_isRunning = true;
try
{
await taskFunc();
}
finally
{
_isRunning = false;
}
}
}```
Update all of your plugins as many things have changed since 2021
hi all guys, I've made a shader to render game objects with a solid color given with a uniform
I want a custom camera to use such shader, how do I do that?
I think I found an answer here:
https://discussions.unity.com/t/is-it-possible-to-override-unity-camera-rendering/194536
wtf, I don't understand how to get my OnPreRender() callback called
in a component living in a GameObject that also has a Camera component
are you using the built in render pipeline?
I think so π€
you should check . . .
this is the MonoBehavior component having OnPreRender()
that looks like a URP camera to me, which means OnPreRender is not going to be called
but, again, you should actually check what render pipeline you are using instead of assuming.
so you're using HDRP, which still means no OnPreRender call since that is BiRP only
π¦
I'm used to lower level programming, what I'm trying to do is to invoke a simple vert/frag shader from the camera perspective
the scriptable render pipelines should have events you can subscribe to for render steps, you'd have to check the relevant documentation though
thanks π
I don't want to use hdrp for one camera, i'd like to invoke a simple vert/fragment pipeline (e.g. rasterize geometry to screen and assign a solid color). Is there a way to do that in Unity?
I've been reading about renderingPath and RenderingPipeline object
using hdrp pipeline for rendering geometry with a solid color (no lights) sounds an overkill to me
many ways to render something without using a gameobject + mesh renderer
You can get away with a shader that bypasses most render pipeline stuff if its unlit too
But wise to make it properly to benefit from batching
This:
RenderPipelineManager.beginCameraRendering += OnBeginCameraRender;
and filtering by the camera works
Inside OnBeginCameraRender I can render my stuff either using this or simpler using camera.RenderWithShader(myShader)
but then it looks like hdrp overwrites everything -_-
what you you mean "overrides everything?" You can render stuff when you want but if you want the camera to do NOTHING you need to render post sky/bg colour and have an empty scene
How might one create an animation clip that edits the main texture of a material on a mesh renderer through script
which part needs to happen through script? Creating the clip?
The clip is created through script then the clips keyframe should swap the main texture of the material
oh this is editor only
yeah I don't think you can do it other than with float values
I have used that and it always returns the mesh renderer as null reference
Editor is fine seeing as my script runs on preprocess
it doesn't return anything so I don't know what you mean by that
But here's a similar task with a working example: https://discussions.unity.com/t/creating-animation-clip-at-runtime-from-sprites-2d/645129
I will give this a shot when I am home(est 2.5 hours) then return if I still have issues. My problem has been when creating the editor curve bindings the path always returns to null even though itβs set correctly
I mean if I clear the screen in OnBeginCameraRender then the HDRP pipeline is executed and the final target is the lit scene
what I want is just to invoke one custom shader program when the camera renders the world
itβs so easy in low level graphics
here it looks like I have to integrare my custom pass with the HDRP pipeline
for example by clearing everything that was rendered and add my pass as a post pass
or by doing it before, but I had no success now
I wonder if Unreal is more tweakable
Why not just create a custom render pipeline. If you don't need anything that hdrp or urp does, that sounds like the most straightforward option.
I'm rendering a realistic world and I want a camera to act as a segmentation sensor
so it has to detect some objects and draw them with a solid color
so i'm using hdrp, but for that camera I want to invoke a custom shader
In built-in you had camera replacement shader for that, but in HDRP, it seem like you'd use a CustomPass api.
Thanks for your reply. Iβve updated all of my plugins except for the Prime31 StoreKit plugin, which is very outdated and no longer maintained. I wonder if I should rewrite all the codes for IAP that would take a lot of time .
Hello, I'm trying to access an initialized variable class but it returns empty from a function with a button. What am I doing wrong here?
This prints correct values as their instances are initialized on the start.
But when I press a button to trigger this function, it prints 0 or null as if my instance created in start doesn't exist.
These are the classes.
Use the debugger to step both through the initialization and the method where you access the data. Make sure that both places point to the same gamedata instance.
Hello everyone, not sure if this is advanced or general question, but if anyone has had any experience with the motion matching package from the asset store, I would like to ask a question about an issue I am having. Thanks π
It is the same gameData instance, when I try to log takeNo variable for example, both start and the method prints the same value, but not in the case when accessing leftChars. Fixed, it seems the issue was it was getting overwritten by cloud code values that is empty.
Does anyone know why this:
protected override void Execute(CustomPassContext ctx)
{
var camera = ctx.hdCamera.camera;
CustomPassUtils.RenderFromCamera(ctx, camera, ctx.cameraColorBuffer, ctx.cameraDepthBuffer, ClearFlag.Color | ClearFlag.Depth, everythingElseMask);
}
isn't rendering the terrain?
π¦
Use the frame debugger to see what's going on with that pass
Very useful thank you!!!
is there any way to initialize this buffer with no value?
before receiving values (so at scene start) I get a kernel error at for it, so I need to either check if it's empty in this shader or initialize it somehow
void CSMain (uint3 id : SV_DispatchThreadID) {
float current = NState[id.xy].x;
float past = Nm1State[id.xy].x;
float right = NState[id.xy + uint2(1,0)].x;
float up = NState[id.xy + uint2(0,1)].x;
float left = NState[id.xy - uint2(1,0)].x;
float down = NState[id.xy - uint2(0,1)].x;
float newWaveHeight = current * 2 - past + .25 *
(right + up + left + down - 4 * current);
newWaveHeight *= dispersion;
for (int i = 0; i < (int)effects.Length; i++) {
float2 adjustedPosition = resolution / 2 / range * (effects[i].xy - position) + resolution / 2;
if ((uint)floor(adjustedPosition.x) == id.x && (uint)floor(adjustedPosition.y) == id.y) newWaveHeight = 1;
}
//if (id.x == floor(effect.x) && id.y == floor(effect.y)) newWaveHeight = effect.z;
Np1State[id.xy] = newWaveHeight;
}```
this is the compute shader
and it's responsible for calculating the waves on the ground
also my gpu really doesn't like the sheer amount of distortion, is there some hidden performance issues with the scene color node?
this is currently what the shader does
at a wave res of 1024x1024 my gpu temp goes up 15C and raising on lowering it doesn't seem to change this, meaning it may be to do with the distortion I apply using scene color and tiling & offset
there is a dedicated #archived-shaders channel that covers all shader-related topics including compute shaders
I guess it did drift into more of a shader problem, but I did think since my original problem was with a compute shader it may be better suited here
compute shader is still a shader
you got a point lmao
You should be able to 0-clear it on the CPU side.
does that mean I pass in an empty value from the cpu?
Yes. With the ComputeBuffer it seems like SetData is the only option.
removing my empty check on it causes this
Well, don't create a 0 size buffer
I could make a nothing value at the start that gets skipped by the gpu
just so I always have actual length in my buffer
Wdym? Buffers are of fixed lengths, like arrays.
If you init it with length 1, you'll only have 1 element to work with on the gpu
I set buffer size in the cpu before sending it
Well then that should be enough
the idea is to have multiple vector 2 positions on the floor to dictate positions on the waves
so any pixel in the buffer gets set to a "height" of 1, causing a wave
Since you set the data there anyway.
so make a nothing value to avoid zero length buffers then?
and just do something like this to ignore it?
yep doing this fixed it ty
Where??
I feel like there's a big chunk of context missing in your question
Is that in a shader?
Or on the CPU side?
I insert an 0, 0 value in the list on the cpu side before sending it to the compute shadercs wavePositions.Value.positionList.Insert(0, new(0, 0)); ComputeBuffer effects = new(wavePositions.Value.positionList.Count, sizeof(uint) * 2, ComputeBufferType.Structured); List<Vector2> objects = new(wavePositions.Value.positionList); effects.SetData(objects); waveCompute.SetBuffer(0, Effects, effects);
then I skip the first value of the buffer on the gpu sidecpp for (int i = 0; i < (int)effects.Length; i++) { if (i==0) continue; float2 adjustedPosition = resolution / 2 / range * (effects[i].xy - position) + resolution / 2; if ((uint)floor(adjustedPosition.x) == id.x && (uint)floor(adjustedPosition.y) == id.y) newWaveHeight = 1; }
I was gonna say branching bad but i guess for a compute shader its not gonna matter much?
in fact I can just set I to 1 lemme just do that
for (int i = 1; i < (int)effects.Length; i++) {
float2 adjustedPosition = resolution / 2 / range * (effects[i].xy - position) + resolution / 2;
if ((uint)floor(adjustedPosition.x) == id.x && (uint)floor(adjustedPosition.y) == id.y) newWaveHeight = 1;
}```
I don't think you can get the length of the buffer in a shader..?
that should fix branching
it's coming up as an error in my ide but works at runtime
I have... frankly no idea why it works but it does
If there was an error during compilation, your shader is likely a version before you added that code.
I've been using this shader for a month, so there's a slim chance of that
You should select the shader in the editor and look at it's inspector
the inspector doesn't show it's contents
just has a button to show compiled code and it brings me to what I believe is the machine code version of it...?
looks like machine code to me
It's assembly
that yeah
if it was using a previous version of the compute shader, having a wave under the player would not work at all, since it hinges on the buffer
in other words I have genuinely zero clue why it works
and I made the thing
Where is r0.y set?
Or mentioned in the assembly before that code
since that's an assembly variable I don't actually know what that's referring to
Share the whole thing.
**** Platform Direct3D 11:
Compiled code for kernel CSMain
keywords: <none>
binary blob size 1252:
//
// Generated by Microsoft (R) D3D Shader Disassembler
//
//
// Input signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Input
//
// Output signature:
//
// Name Index Mask Register SysValue Format Used
// -------------------- ----- ------ -------- -------- ------- ------
// no Output
cs_5_0
dcl_globalFlags refactoringAllowed
dcl_constantbuffer CB0[2], immediateIndexed
dcl_uav_typed_texture2d (float,float,float,float) u0
dcl_uav_typed_texture2d (float,float,float,float) u1
dcl_uav_typed_texture2d (float,float,float,float) u2
dcl_uav_structured u3, 8
dcl_input vThreadID.xy
dcl_temps 3
dcl_thread_group 8, 8, 1
0: ld_uav_typed_indexable(texture2d)(float,float,float,float) r0.x, vThreadID.xyyy, u0.xyzw
1: ld_uav_typed_indexable(texture2d)(float,float,float,float) r0.y, vThreadID.xyyy, u1.yxzw
2: iadd r1.xyzw, vThreadID.xyxy, l(1, 0, 0, 1)
3: ld_uav_typed_indexable(texture2d)(float,float,float,float) r0.z, r1.xyyy, u0.yzxw
4: ld_uav_typed_indexable(texture2d)(float,float,float,float) r0.w, r1.zwww, u0.yzwx
5: iadd r1.xyzw, vThreadID.xyxy, l(-1, 0, 0, -1)
6: ld_uav_typed_indexable(texture2d)(float,float,float,float) r1.x, r1.xyyy, u0.xyzw
7: ld_uav_typed_indexable(texture2d)(float,float,float,float) r1.y, r1.zwww, u0.yxzw
8: mad r0.y, r0.x, l(2.000000), -r0.y
9: add r0.z, r0.w, r0.z
10: add r0.z, r1.x, r0.z
11: add r0.z, r1.y, r0.z
12: mad r0.x, -r0.x, l(4.000000), r0.z
13: mad r0.x, r0.x, l(0.250000), r0.y
14: mul r0.x, r0.x, cb0[0].z
15: bufinfo_indexable(structured_buffer, stride=8)(mixed,mixed,mixed,mixed) r0.y, u3.yxzw
16: ushr r0.zw, cb0[0].xxxy, l(0, 0, 1, 1)
17: utof r0.zw, r0.zzzw
18: div r1.xy, r0.zwzz, cb0[1].zzzz
19: mov r1.zw, vThreadID.xxxy
20: mov r2.x, r0.x
21: mov r2.y, l(1)
22: loop
23: ige r2.z, r2.y, r0.y
24: breakc_nz r2.z
25: ld_structured_indexable(structured_buffer, stride=8)(mixed,mixed,mixed,mixed) r2.zw, r2.y, l(0), u3.xxxy
26: add r2.zw, r2.zzzw, -cb0[1].xxxy
27: mad r2.zw, r1.xxxy, r2.zzzw, r0.zzzw
28: round_ni r2.zw, r2.zzzw
29: ftou r2.zw, r2.zzzw
30: ieq r2.zw, r1.zzzw, r2.zzzw
31: and r2.z, r2.w, r2.z
32: movc r2.x, r2.z, l(1.000000), r2.x
33: iadd r2.y, r2.y, l(1)
34: endloop
35: store_uav_typed u2.xyzw, vThreadID.xyyy, r2.xxxx
36: ret
// Approximately 0 instruction slots used
The whole assembly I mean
oh one sec
that's the entire thing
if you can read that props to you because I can barely discern what it's doing
but it does work as far as I'm aware
Besides some sampling cost, it's provided to you regardless if you use it or not. Similarly like sampling a depth map from the camera
It's basically just a render texture without the setup
oh I see, makes sense why it's a bit costly
shouldn't be too bad though, the scenes I use this shader in are meant to be pretty barren by design
Why are you using compute here anyway. This effect can be done in the shader without any of the complexity
those being the hub world (sorta like the hunters dream in bloodborne) and the main menu (which I'm planning to make kinda interactive)
eh that's just kinda how I did it at first when I was learning this stuff and I kinda just stuck to it
and since it does work, and the compute shader has improved the performance vastly over what I was doing previously, I may as well leave it like that
Aight, but if you do want something you can do all in the shader graph you'd use a secondary mask as a render texture to modify the water
with a camera rendering the mask from the top orthographically right?
Yep
yeah I switched over to something like this because it improved performance and I only really need a couple pixels to do waves
a mask would be useful on big objects though and I am kinda considering it again
before this compute shader this effect was raising my gpu temp to 60C at a fraction of the resolution it's currently running at
It seems to be getting the length from the buffer, but this shouldn't work in plain hlsl. The assembly command corresponds to GetDimensions in hlsl.
As you can see in the docs, there's no Length property or field in a structured buffer:
https://learn.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-object-structuredbuffer
I guess it's something unity adds. But it's so weird there are no mentions of it in unity context...
and trying it out on a potato pc got it running at maybe 10 fps
or in rider for that matter
the solution I was using before was really bad tho, so I think I can pull off a render mask better now
Compute overall is probably better as you don't need to sample every pixel of the scene texture so it makes sense, but otherwise not the greatest cost in the world
I don't think rider affects how the shader is compiled.
no I mean, rider does not know of the Length value, it comes up as an error
which is weird, but apparently it still works lmao
Ah, yeah. Because normally it doesn't exist.
reading up on it there seems to be a GetDimensions() thing I could use
no point tho, if it works, don't fix it
and I think the way that list is handled is pretty good regardless
it's stored in a scriptable object so you don't need to reference any script to add a wave
you just add an element to that list, and it creates an elevation at that pixel for a frame, which causes a wave
so the only real performance problem is having a shader shader use scene color on a pretty big quad, making it have to render a large portion again
Do you have any includes in your shader? Some unity default headers/include files perhaps?
compute or the normal one?
The one that has buffer.Length
I see. Weird. I guess it's a modification they done to the hlsl compiler.
// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain
// Create a RenderTexture with enableRandomWrite flag and set it
// with cs.SetTexture
RWTexture2D<float> NState;
RWTexture2D<float> Nm1State;
RWTexture2D<float> Np1State;
RWTexture2D<float> obstacles;
uint2 resolution;
float dispersion;
RWStructuredBuffer<float2> effects;
float2 position;
float range;
[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID) {
float current = NState[id.xy].x;
float past = Nm1State[id.xy].x;
float right = NState[id.xy + uint2(1,0)].x;
float up = NState[id.xy + uint2(0,1)].x;
float left = NState[id.xy - uint2(1,0)].x;
float down = NState[id.xy - uint2(0,1)].x;
float newWaveHeight = current * 2 - past + .25 *
(right + up + left + down - 4 * current);
newWaveHeight *= dispersion;
for (int i = 1; i < (int)effects.Length; i++) {
float2 adjustedPosition = resolution / 2 / range * (effects[i].xy - position) + resolution / 2;
if ((uint)floor(adjustedPosition.x) == id.x && (uint)floor(adjustedPosition.y) == id.y) newWaveHeight = 1;
}
Np1State[id.xy] = newWaveHeight;
}
the compute is incredibly short and simple
and it just changes a wave texture that gets sampled in the shadergraph shader
The issue with using undocumented API is that you don't know if it works correctly. It might break on some platforms for example.
The only way you have to verify it is by seeing it in action, which is not reliable
Or I guess reading the assembly code
...which is not a skill in my possession lmao
I don't fully remember what the problem was on linux, I believe the dispersion was calculated differently since the effect spread a lot less
How might one fix this issue. Im trying to create an animation clip through script that will swap out a material
Here's my code
It would be preferred if there was a way to swap out just the main texture of this material but if needed it can be the material
```
String path = AnimationUtility.CalculateTransformPath(MainButtons[index].transform, gameObject.GetComponentInParent<Transform>());
Debug.Log(path);
EditorCurveBinding binding = EditorCurveBinding.PPtrCurve(path, typeof(MeshRenderer), "m_Materials.Array.data[1]");
ObjectReferenceKeyframe[] key = new ObjectReferenceKeyframe[] { new ObjectReferenceKeyframe {value = new Material(Shader.Find("Standard")), time = 0f} };
AnimationUtility.SetObjectReferenceCurve(clip, binding, key);```
The (Missing!) means an object with the path doesn't exist so something is up. If you select it in the animator and press F2 to rename it will show the path
yes and it is the correct path im just guessing the issue is with the aquiring the material part. I have no idea how to fix that and its been busting my balls for days and fully halted work
okay so ima kms now
wait
i may have fixed it
fyi get component in parent will check itself then parents so doing that with Transform wont do anything useful π
why not use transform.parent ?
yea i noticed that lol
i just did and it worked for the mat lol
BUTTTT
i still need to figure out how to swap the main texture to a diff one. Got any idea on that?
trying to save with optimization by not creating a mat for each texture
can material properties be animated? sprite renderers support sprite changing but ofc thats via the renderer comp
I sure to god hope so because if not this gonna be using a very large amount of materialsπ
any clue as to why this is happening
Not sure why the alpha clip state is wrong, may need to ask in #archived-shaders
its not just alpha clip. The alpha is just not working until you do something in the shader menu
Also its prefered to use string instead of String for core types
I presume this texture is using alpha from greyscale but im not sure if this makes a difference
its using input texture alpha
force of habit lol ty
when you update it it does for some reason, thats why im confused
wat no it dont
im confused now
Hi, I'm trying to implement a glass breaking function that is kind of or it is indeed advanced and I'm a beginner. Below is my glass breaking feature requirements
- I have a fractured glass to replicate glass breaking when hit
- I have a metal ball to throw at the glass panel (fractured glasses combined)
- When a ball is thrown at a part of the glass panel, it should shatter/break in that spot breaking those specific fractured glass and a few surrounding them just like how it works in real life.
- the ones that are intact with no support of other fractured glasses that are connected to the other fractured glasses connected to the ground or to the ground directly itself should fall down how it works realistically.
I tried a few things from my end that didn't help, below is a list of attempts I made
- Added Mesh Collider (convex checked) and added RB (isKinematic set to true) to all the fractured glasses
- Tried implementing with a basic script which breaks the glasses where it's hit and a few surrounding it but some of the fractured glasses in air that are intact with no support from the base are still in same position without falling down.
- Tried many ways but still failing miserably
Please, can someone help me with implementing this feature as I'm in need of it badly
Non kinematic rigidbody is probably the most straight forward and simple way to implement it.
How would I even begin creating bots to my Tarot Chess game? Basically chess, but with cards changing the gameplay completely. I cannot copy the chess thing and then add a card thing, as ai would act very weird. I need to make it in one somehow. J have watched a video using a method that chooses the most effective path. But with cards it's not really easy to say, as it's a question if using it or not, which one, limit of cards that can be used and the effectiveness of the move, which gives a lot more options than in regular chess.
You are asking the most difficult question in game dev.., how to make an AI that optimizes for fun in a context of arbitrary rules.
the decision space is very large when using flexible rules, so you can either encode expert knowledge into an inference engine or create a machine learning setup that can optimize for the outcomes you want.
i believe machine learning would be easier than studying the game and programming every outcome... However, i got into gamedev 2 years ago as a hobby, adn havent ever even touched making AI.
the gamedev space has mostly given up on making AI that has "playing strength"
we've basically figured out in the early 2010s that players don't want actually clever NPCs, just the illusion of plausible behaviour, and for example an NPC announcing what they would do is perceived as 'intelligent' while any actual cleverness is either too difficult to play agains or does not get noticed.
so, as a result, nothing much has happened outside chess/go engines and some academic attempts to solve 80s arcade/NES games with ML
when you look at strategy games, the opponents have some sophisticated AI but their strength also needs to be tuneable, so they typically fall back on cheating mechanisms or ability modifiers, not actually better decisions
So, you are saying i shouldnt go for it? Instead i should make templates of behavior and cards drawn or something?
I donβt know enough about your gameβs specifics to make a recommendation, Iβm just pointing out the potential for difficult times, depending on your choices.
Well, it is chess with cards that completely change the gameplay
that could mean anything
what you're asking is vague, we have no clue how these cards affect your gameplay. if you were asking purely about making a chess bot, you'd likely just use an existing system that handles the calculations. When the cards changes the rules of chess, then this is something you'd have to do yourself.
If you want the AI to be smart and play as a really smart human, thats simply something you'd have to train. Otherwise you make it difficult through unfair advantages if your card system allows for it. If you want a somewhat dumb AI, you could just check possible moves and evaluate the resulting position.
Ok, let's say I want to train ai. How?
There are plenty of resources on that online. Start by looking at the unity ml agents toolkit.
To put it simply you configure the agent, provide it with inputs into your game and feedback info/reward. Then you train it: make it play millions of times(against a human?replay? another agent?) until it improves to your desired level.
This seems costly
Well, yes. It's costly. Machine learning is costly.
Simpler games with simpler rules and defined reward functions can train a smaller model faster. The more complex the game is, the harder it is to train a successful agent model.
Which is why you don't really see it being used in complex games often.
Best to go with a adversarial approach with a bit of genetic mutation sprinkled in between generations. I have found this to be able to achieve good results rather fast
have you seen anything related to chess bots? like stockfish or whatever google had. The training around those are already complex and they're using data from millions of games.
Do you really need a smart AI here that plays fair? Even figuring out how to train it is a hard task. if you know very little about AI then really id reconsider the goals here
Ive taken a course on this and I still wouldnt sign up to do this myself
I mean, I want to figure out the way to actually have an AI opponent at the first place, then to make it good
Once I will achieve the first, making it cheat shouldn't be that difficult
But I have no idea how to do that
that part depends entirely on your card system, cause you can't give unfair advantages in a standard chess game. Like maybe higher chances of them getting better cards
Then you'll need to hardcode it.
For example, if have card type A and it's parameter is bigger than opponent card parameters, use it to attack or something like that. There's gonna be a lot of this kind of conditional checks. Start simpler and make it more complex slowly by adding more conditions.
And it's gonna be very dependent on your game rules, which is why you don't really find any kind of generic tutorials on this.
If you add variables to a LocalizedString, do you later need to unadd them so the string unsubscribes from them?
Or does the subscription magically not keep the reference to it alive, and has it be cleared somehow
If there's API for adding/removing variables then it probably suggests that you need to handle that manually. I don't know for sure tho, so far I haven't needed them.
There's one for adding and clearing. But there's nothing in the docs that suggests it as far as I've seen at least
How you authorize graph data using unity inspector when you don't want to use GraphView?
This is a ridiculously frustrating issue for me, and I'm kind of dying for some help.
I've got this mirrors and lasers game I'm working on, where the laser comes out of a beacon using Physics2d.Raycast() logic, then uses a line renderer over the top of it!
When it hits a mirror, it tells the mirror script all of the information from the beacon ray-cast using a RecieveRaycast() function, and then the mirror fires off a new reflection using the same logic as the beacon!
The issue is, for some reason: the mirror ray-cast travels a distance of 0 and collides with itself. I tried using Physics2D.queriesStartInColliders = false; in BOTH Start() functions of the beacon script and the mirror script, no dice :[
I really have zero clue where to go from here, I know for a fact that it's getting all the info right before shooting out the ray, because I tested it with Debug.DrawRay() and it all worked out!
Sorry for the absolute WALL of text, I'm in dire need of some help, my deadline for this is real soon and even my lecturer doesn't know what's going on 
The first step is to print out the name of the object that the raycast is hitting
Also your ReceiveRaycast function is doing something really funky:
Vector2 reflection = Vector2.Reflect(direction, hit.normal);```
Where on earth is hit.normal coming from here?
At the beginning of the game hit is just an uninitialized RaycastHit2D struct.
so that normal vector is going to be 0
(0,0) to be precise
you need to pass in the normal as a parameter
e.g.
ReceiveRaycast(hit.point, direction, hit.normal, reflectionCount)```
I would kind of highly recommend having your RaycastHit2D variables only be local variables, it's bad form to give them a larger scope than that, it will lead to bugs like this.
they generally become irrelevant and outdated very quickly.
Hello again! Thank you for responding, I think I understand where you're coming from, you'll have to excuse me this is sort of my first time with ray-casting,
I think I see what you mean with the hit.normal, that was supposed to be transferred over by the BeaconLogic script! That's totally my bad, let me see if I can quickly fix that one
this is sort of my first time with ray-casting,
In the future, you should be in #π»βcode-beginner
So sorry about that, I thought the issue was much more complex than it probably actually is 
The designations of the channels refer to your experience level, not the problem complexity.
Beginner problems seem complex to beginners.
Understood, apologies again 
Very quick followup: it works now, thank you so much for catching all of my mistakes :]
Hey, just curious. How many of you are doing automated testing?
And if you do, do you use Unity's test runner?
-# Any Unity-specific talks and devlogs are welcome
Hardly anyone who talks in here operates in a context where automated testing is perceived as providing ROI. Those who do test, use the tool that gets their testing needs done most efficiently, what these are depends on whatβs being tested. Unity test runner is the primary choice when testing stuff that involves runtime behavior and unity lifecycles. Most would like to have comprehensive tests but generally capitulate at least partially while climbing that mountain.
Yeah, I bounced due to the required effort vs benefit long ago too. But got curious how hard it would be to setup a layer for tests that essentially just... runs the game. Without bothering with mocking half of it for isolation
Not hard.
As it seems that it's what games like Factorio and Minecraft do
The issue is that it does not really make sense in most context. Factorio would be one of the only popular games that does run test. And the "modern" minecraft.
If you build your architecture from the start to be capable of being completed automatically, this is quite powerful in the late stages of development
itβs the only thing that really matters to platforms and publishers (no game breaking issues on the happy path)
Another viable strategy, used more often, is to decouple your game logic in such a way that it cannot break easily. And test only the systems that ensure it doesnβt break. Then allow players to get back to an unbroken state should anything go wrong.
From the games I know there's also Sea of Thieves that does it
Most live service games will have extensive automated testing
That seems like a lot of work tho, so the "benefit to cost" ratio goes down a lot
On the contrary, thatβs the approach which minimizes effort
I find that most large games nowadays are designed around production and maintenance constraints more so than anything that would improve player experience.
Maybe I don't get the approach you are describing then 
imagine a RPG, lets say asassins creed, you have 20 main-quest missions that would be game breaking if they bug out. but you also have 100 side quests which can bug out because they don't block anything in the main quest. You can then focus on testing the main quest, which makes the game completable. And for all the side quests, you offer a very robust "abandon" or "restart" quest button
if you make a game like, say, Thimbleweed Park (or any point and click adventure), basically everything is on the critical path and needs to work
but those games are very simple, to test since the state space is fairly constrained
if you have a puzzle game, you also need to test only if they are solvable, not whether every move is 'safe'.
It's not something you would test automatically tho... right?
depends on the number of puzzles, i think a puzzle game should have an automated solver as a core feature
but that comes naturally to the genre
for example if your puzzle game can show "hints", it can also solve the game automatically
I mean... I kinda agree. But it's not like the puzzles will become unsolvable randomly, and solver interacting with the whole game seems like a heavy thing.
Also, making a whole solver seem likea lot of effort for something that again, doesn't break randomly.
I get testing the systems, movements and interactions. But puzzles? Not really
Depending on the kind of hits the game has. Not every hint needs to be generated automatically
if you knew that breaks when you make a change, you need no testing
i'm just illustrating a generic attribute that many puzzles have, you can always argue that example X does things differently
Yeah, but things that can break puzzles would be changes in interactions. That's why you would test the interactions automatically, right?
Kinda like how you don't write automated tests that play the game start to finish (as far as I know) as that's something playtesters do
Yeah, I know. But from my experience, automated hints that would need a solver are a minority, I don't think I know a game that has those even
no, playtesters are not testing for solvability, that can be automated, they test for edgecases that you never thought about to write a test for
π€ I still don't think I agree on this beeing beneficial
(assuming you already have automated testing for interactions themselves)
when you do the math, manual testing vs automated testing vs time to release, you will get your answer what you can/should do.
all i can say from my personal experience is that fixing a bug is ~10-1000x more expensive than not making it in the first place
Yeah, I know. But let's say we are talking about a Sokoban game, a complex one even. Let's say Baba is You.
Once you write the tests for what all the rules do, and tests that for example check if the tiles move like they should... there's nothing there to break, because you covered every case you need for the game to work.
Writing tests for all the hundred levels doesn't really add any extra cases, right?
I mean, yeah. Of course. But writing and maintaining tests also costs time and effort.
So if less tests can cover the same amount of cases, it's good.
Tho, I guess with an automated puzzle solver you don't really write any tests yourself... so I can see that being handy
are you sure those games you mentioned are doing end to end tests like that? I find that very unlikely
unit tests are usually very welcome and easy to do, as long as your game logic is dettached from presentation
very unlikely that an open ended game is end-to-end testable
By those games you mean Factorio and Minecraft?
(Or is that aimed at Anikki? I don't remember mentioning end-to-end tests)
yeah, I mean, you mentioned running the game for testing, so I figured you're were talking about end to end testing
Not really, wait a moment
Look at this timestamp
https://youtu.be/vXaWOJTCYNg?si=SVC8xFnnO_WvqYre&t=987
Henrik Kniberg shares why and how the developers at Mojang built a visual framework to bootstrap and enable end-to-end test automation of Minecraft. The talk is followed by a Q&A.
Henrik Kniberg
Twitter: @henrikkniberg
GoClimate: https://www.goclimate.com/
Blog at Crisp: https://blog.crisp.se/author/henrikkniberg
Support this channel o...
And here's Factorio (they have a headless mode, but this timestamp shows the one with graphics enabled. It seems that headless still runs full game, just without the visuals and such)
https://youtu.be/AmliviVGX8Q?si=W62SbsofeqkDjyqq&t=1082
Fixing of one bug from the beginning to the end.
This is an example video, where I try to show the process, and a first vide (and take) I did, it might theoretically be interesting to someone, and if nothing else, recording it is a good way for me to get productive, as I can't check internet while doing it :)
I don't think this is much more useful than having unit tests
or any different at all
So it's not end-to-end as it runs small scenarios. But it's running in-game instead of being completely isolated from it like unit tests are
Why not? It has the same benefits as integration tests would. You can run it in the broader context and you can test more complex interaction that you just cannot test while checking a single unit
you could also have integration tests, but I don't see why you would need to fully start the game and render anything
unless the render is also validated for some reason
Factorio and Minecraft might be a special case here, because everything can be created inside the game itself anyway
Well, Factorio doesn't need to start rendering. And it seems from the video that you usually wouldn't have it enabled.
The main benefit of starting the game as it would run normally that I can see is just the fact that it's simpler.
Making sure the game logic is fully decoupled takes time, so being able to ignore that without much issues seems like a good thing.
Also, in case of Factorio it makes sure there's no extra things that could mess with the expected behaviour.
depending on your architecture you have game logic decoupled from presentation "for free"
I find it hard to believe that such big decoupling would be free compared to some simpler architecture.
And even excluding visuals, you have all the managers and game state to worry about
there are some simple MVC-like architectures that provide you that decoupling already, it's nothing too fancy
then it's up to you to figure how to create those game states from code
you also usually want to keep the test cases very focused, otherwise they'll be too brittle
I guess I'm not familiar enough with this architecture to see it as equally easy to what you would typically do in Unity
In case of Factorio the scenarios seem quite focused. Even if run in the whole game's systems context.
In the video above the test case is "if I place those 5 belts and drag a belt, it does not place properly"
yeah this Factorio thing is pretty awesome, especially being able to run headless
but as I said, it's a very specific type of game
you can easily create an empty world, add your stuff and run it
which is something very similar to a unit/integration test
I imagine that in a more "typical" game rather than a sandbox with building, you could do a similar thing but with either having some scenes to build the scenarios or some code-focused scenario building system.
But no matter the game it still should be possible to "start the game -> open a simple scenario -> test -> assert" as it's kind what you would be doing when wrtiting code anyways, right?
Yeah, tho I am curious how hard would it be to integrate it with unity's way of doing things.
A workflow more or less like "load scene -> find objects -> act -> assert" seems doable, but I don't know how practical it would be
Also, it would seem that it still counts as end-to-end (at least mostly) even tho the scenario is small. Because it tests it from the user perspective, in the context of full application
well, it always depends a lot
what I have learned from trying automated testing for a while is that it is much easier to test things and maintain the tests when they are smaller and more focused, like unit tests
The only difference is that you skip the input (partially) and rendering
Playdead (Limbo), Call of Duty and Facepunch does integration tests of some kind.
if you design your stuff decoupled from Unity you have control over absolutely everything and can create any scenario you want without ever fully starting the game
there was a place that I worked that had some image-diff tests, that was pretty cool although very hard to debug when things went wrong π
Limbo has a complete playthrough test and Facepunch did at least performance testing. I don't remember the extent/reasons Call of Duty did it.
I recall reading somewhere about those CoD tests, at least for performance
Factorio hits the smaller and focused aspect. Even tho it's not fully isolated unit tests.
Because again, making all the components and system fully isolated and something you can test independently sounds harder than not worrying about that. Because then you have to make sure nothing has external dependencies, interaction system cannot be aware of Unity, nor the player and so on
Yeah, no. Image-diff sounds like a recipe for a test as fragile as thin glass 
Sometimes it's helpful to just know that there's a significant difference.
Treating Unity as a presentation layer and completely separating my game's logic from it is something I remember trying and giving up on very quickly. I can see the benefits, but I don't think they outweigh the downsides for most games
One fragile test I have experience with is whether the project compiles or not π
I can see that, although I luckily managed to do something like that for all my projects
Complete playthrough test seems crazy... but I can see it being useful. Especially for a game like Limbo. I wonder if it's just a big macro, or something more sophisticated
I recall it being several small segments with a lot of "resets" in-between.
same experience here, in every case i've seen it attempted it failed and ended up in a reinvention of gameobjects, it only makes sense if one fully embraces ECS architecture or if the ROI of testablity is so extreme that all the pain makes it worth it
Are you games turn-based puzzles perchance? I can see that as the most likely genre to apply this approach to... and maybe games with a complex simulation like Factorio
So probably something closer to "one test per checkpoint" kind of thing?
yeah, I'm currently working on a turn-based RPG in a personal project and ECS at work π did some mobile puzzles before
Pretty much. The game itself is somewhat segmented anyway.
I guess it probably gets very difficult to decouple the layers if you interact with physics stuff
I imagine anything that touches physics or is more bound to time rather than discrete steps.
Also, decoupling from Unity kinda means not being able to use Unity as an authoring tool for levels and actors (even if just partially) so you have to reinvent things like component system as @compact ingot said.
Either that, or you have a lot of boilerplate
authoring is fine, you just need a way of mapping the logic entities to the visual entities
configuration can be provided from any source
also worth considering that often the tricky stuff to test is not actually the code but the configurations that get injected into the code (i.e. stuf that designers make)
which raises the question, what even is correctness in any given game
Can that even be tested? I feel like testing the output of designers isn't reasonable.
(Hence my comment before about testing interactions instead to ensure the game works as expected)
My game has a scripting system and that's decently well tested with Unity's test runner. The game also has a backend API but that's tested separately by itself.
If someone can disable all enemy spawning through authoring and ship it, what does that say about the process?
This gets to a larger question about observability, but illustrates that you can have completely functioning systems and end up with a completely broken game.
in some sense the working game that sells well is the test for that
i think it can be tested to some extent if configuration is entirely declarative and complete, but that obviously is more a theoreticaly thing than a practical one.
That means the designers have enough control to make design happen
Yeah, I can see the benefit of say... having a scene validation tool (like the one for... I think Budget Cuts?) that makes sure everything is set up properly. But I don't really get that from your example
Yes. My overall point is that you should include overall health of the game in your "testing" strategy. The discussion is a bit different when talking about development from the ground up, but unit testing is the least of my priorities (with some exceptions) if I wanted to make sure the next build (or current one) is a functioning/good one.
Yeah, but I don't think that's something an automated test should do. It sounds more like a process aspect rather than tooling
does anyone have any experience using the job system with creating their own physics engine? I am trying to artificially create my own simple gravity for numerous entities, however everytime my scene activates it does bizarre behavior.
A good example of bad behavior I am getting is all of the properties of the selected items are changed for some reason. The material data is encapsulated with the only task of my job script is to apply a constant downward force but it also moves all the items to 0 0 0 on my scene?
any help is greatly appreciated, I am stuck on this one
It's hard to imagine anyone being able to materially help you without seeing any code.
What do you mean creating your own physics engine?
Are you actually solving the collisions yourself?
Creating a physics engine is something you do outside of unity. Where you have explicit control of everything happening.
Unity just calls PhysX APIs, for example.
The unity given rigid body and physics are not good engineering tools on performance for me. I am building my own of that, I already have my own custom colliders written in c#.
For instance you cannot input the heat rise off moisture or the temperature changes of water that affects water currents. Many things cannot be done with the simply unity given components
Why not use ECS if GameObject physics is not fast enough for you?
I am using ecs and the job system, with a burst setup
Why reinvent the wheel? You'll probably not be able to make it better than a team of professional engine developers.
Then use the ecs physicsπ€·ββοΈ
I already made it, now I just need to solve the data corruption
When you use ecs it struggles at millions of tiny voxels
If it doesn't work, it doesn't count as "made it"
I wish I could use ecs honestly but my task requires I reinvent the wheel
Anyways, if you need specific help, you should share more details on your setup and code.
Hello guys.
I'm currently if a solution i have build works, if im re-inventing the wheel or if i should search for another one.
Im this current project, i'm saving to json references to scriptable objects as string GUIDs that are read-only, created on the scriptable object Awake(if its null). Then, i use the Resources.Load to get all scriptable objects that i need and store them in a singleton on different dictionaries by type.
This is supposed to already be a fix where i was previously saving it as the scriptable object name. I understood that, if the game has already been released and we need to change name of objects because of typos or a game design decision, then it would break the save data for players that references those objects.
But now, i believe that if we need to delete an object after a reference has already been saved, then it will break the save data anyway.
Should i be using addressables to fix this problem? Has anyone already encountered this problem?
Thanks
if you completely delete something referenced by old save data it'll break no matter what system you use to reference it, so if you want to keep compatibility between versions you should maybe just avoid deleting anything?
If your save file has some kind of version you can implement manual upgrading logic to fix older saves (e.g. change id "foo" to "bar")
Addressables wont help if the address is changed as the same issue happens.
Changes to save data often come with save data versioning and converters to load saves from older versions and convert them to the correct new format. Many games also just scrap old version saves and force the player to start a new game.
Yeah, i guess parsing save files is actually a thing.
thanks for the inputs guys
A primitive setup ive used before is to save index and name per piece but then also save a small manifest of what the id-names were for the version the save was made on. Then you can use the index if you need to name change, the name it you need to index change and can potentially refer to the saved manifest to handle upgrading saves
Did anyone ever happened that when calling .Schedule for a Unity jobs sometimes the editor freezes or am I the only one?
I've got a technical design question I'd love to bounce off someone. I'm building a multiplayer, FPS, wand-based spell casting system, where the player holds a wand. On click, they begin casting a spell, and need to move their mouse in a predefined motion to ready a spell, and then click again to cast that spell.
My original technical design was to spawn an invisible sphere to represent the player's mouse movement, and then invisible paths, made up of a startSphere, pathCylinder, and endSphere. On click, the orb and the path spawn, and then we use 3D collision detection to make sure the orb exits the startSphere, stays colliding with the path, and enters the endSphere, then a new path spawns and they player repeats until casting the spell.
I got to thinking that, because spells are cast using a 2D plane really (the x and y movement of the mouse or gamepad stick), this could instead be a 2D object and collision. Which could be better for performance. But there's the element of what the player (and other players) see when casting the spell. I want the spell to be visible to the player and other players as it's being cast. So as players draw upwards with the mouse, a particle effect "draws" itself upwards. So that players can see the sigil being drawn.
I know both of these would work. But I'm too new to Unity to understand the implications of each design decision on the challenge of drawing the sigil in 3D space. Could anyone help advise generally on which way they'd approach this?
The physics engine is not a good way to do gesture detection, no
Neither solution seem to be appropriate.
Could you explain why? I'd love to learn.
The first one make little to no sense as you said it, the player is interfacing in a 2D space. (Expect if you mean in VR)
Also, it would be kinda hard to know if you are on the path or not. THe only way that I believe it would make sense is if you use a spline + move the sphere when the player is near.
But again, that makes little sense in 2D space.
Personally, I would probably opt for drawing a "texture" (But again, that would be a pretty weak approach given that it cannot handle most variation)
Yeah, the piece that I ran into issue with, and where things started to get really complex was where I was tracking the path that the player was drawing using colliders, you'd also need to make sure their cursor was moving in the direction of the writing.
Since posting, I actually found this tool called $1 Recognizer that allows you to create point data for different shapes, and then players can "record" the path of their spell casting. It compares the point data of the defined shape to the point data of the player's recorded cast, and outputs a % similarity between the two.
Think I might use this and see what effect it has on performance. The way it's implemented allows a muuuuuuuuch quicker definition of different sigils, and it also allows programatic creation of new sigils as well, which has a ton of potential.
woa that is cool
You could also develop your own AI with sentis that being said.
I have to check how this is implemented though, and what risks it might fall into (if I'm not mistaken, the speed at which players record their spell, and the number of points that exist in the pre-defined shape will have a major impact on % comparisons)
Probably one of the most out of the box usage for it
Ooh, interesting. There's even an example that follows almost exactly what I'm looking for on the main page: https://unity.com/products/sentis
Also, you should proably test it because things like that happens
The example (which i presume is JS) seems to be very fast so i see no problem using this
should be easy to transform some points in 3d to a 2d plane once drawn to then compare
100%. Though this, I think, is intended functionality. There's built-in recognition of rotated shapes.
I'm gonna look into Sentis though, that's the first I've heard of it and it might actually be perfect. I wonder, too, whether Sentis might be the more appropriate tool if I want multi-stroke comparison. The same team who made $1 also made $N, but there's a piece of me that wants to keep things "within Unity" where possible.
Obviously, it was an example. If you were to make your own you would have way more control.
Sentis is only a tool run AI model
It's not an AI model
Ahh, so it depends on an external AI model, you mean.
I mean, that would probably what you should use to run the model you posted.
My point was more about creating your own model though.
From my little testing, it seems to heavily base around the start point and directions, not the actual shape/detected sharp edges, you can make a triangle, but if it's drawn from bottom to top, it detects wrong, however top to bottom detects as that's where the start point should be, and directions should go, the image detects as 82% since the start point, and directions all match to the rectangle, so it's not an ideal solution as it's very predetermined, so I'd advise against using it if possible.
melting kermit the frog be like:
okay so a small question
I've got a mesh simplifier tool that can either compress the mesh to around 70% its original size in the custom file format, or just give it in the regular .asset mesh file
the regular .asset mesh file is extremely large due to being a text file, binary version of it is hilariously even bigger than that, somehow
does it make sense to compress it? Unity copies all the saved mesh data from disk into RAM/VRAM right?
I mean having this mesh sized 92 KB is insane
I'm planning to use the zstd compression algorithm for this
Don't trust the file size when it comes to actual size in a build. The runtime size depends on what models you are actually using, but judging from the inspector it's gonna be 37.5 + 6.9 KB = 44KB size in VRAM. Also why exactly are you worrying about a 94KB mesh?
Hello, I would need to create a tiled texture2d based on another texture2D. For example, I have one 1024x1204 image with a half white stripe on the left and a half black stripe on the right. I'd like to tile this texture in a new 1024x1024 texture with the vector 10,5 for example (so tileX is 10 and tileY is 5). How should I proceed? From what I saw online, it seems to involved reading pixels but it can get complicated. I thought there might be an easier solution since it's simply some tiling logic. It's basically the same as what materials do with the tiling property except I need to save this new image.
You sure can do something like
for pixel p in pixels:
p = pixels.readPixel(p.coordinates + someOffset)
but why do you need to do that?
the answer is shaders! unity provided lit/unlit shaders already provide tiling options to achieve this
i think they are confused about reading the pixels cpu side
that too. 1024x1024 is more than million already so doing that on CPU is not optimal but I'm just wondering whether you actually want to do that in GPU side either or can just solve the issue by other means
I could also imagine situations where using CPU would be reasonable too so would need to know more about the original issue. This screams XY problem
If it HAS to be a new texture you can either use a compute shader or graphics blit to do the tiling via a material: https://docs.unity3d.com/ScriptReference/Graphics.Blit.html
Should be the fastest way i think π€
Yea id like to hear the actual problem where a new texture is required
Well, I'm using the lit layered shader and I'm creating various textures with a mask map so I can stack clothes texture on top of each other. So I could have one layer with a heart logo on the left of the cloth and a ring logo on the right, it's filly customizable by the player, up to the 3 additional layers. The mask texture are create on the fly. I have the heart grayscale jpg in an image and the ring jpg in another one. I'll have hundreds of such clothing layers but the player will only use a few so I don't want to generate ALL the possible mask layer combinations, I want to do it at runtime. Moreover, the game is moddable and players will be able to add their own images which will need to be layerable too.
Google seems to say if I create a material, assign my texture, tiling and offset then retrieve the texture from this, it'll give me the tiled and offseted texture. I'll give it a shot, seems simpler than manipulating pixels.
That will not work, I can reveal that much to you. The Offset value in materials is just one property affecting the way a shader might draw the texture, it doesn't change the representation of the texture on CPU side (nor on GPU)
I'm not fully confident I fully understand the type of system you are aiming for but it sounds like compute shaders or Graphics.Blits might be of use if you want it to be very performant. If you only need to generate the texture once at start, doing on CPU side might be fine too. Btw. don't use jpg:s for textures, they are just of low quality due to compression but won't affect the size on build (compression on build is defined separately of the original texture on the import settings)
If you have a custom shader you can do tiling in there anyway, its very easy
Working on a game for client. The client wants to make scrollable level selection screen like this.
What's the best way to make something like this in Unity?
Is it fully 2d, 3d or mix of both?
You can make 2D look 3D and the other way around so in that sense there's not much of a difference but to me that seems like 2D sprites placed on top of 3D sphere/cylinder (2.5D)
Might be worth looking at some animal crossing inspired world wrapping dev media online, there's a couple available shaders that have been made that may be tweakable to get to that kinda experience
Shaders was my first thought too but then I started doubting whether making the UI elements interactable would become a problem (assuming those dots along the path for example need to be selectable) but I think that should be doable still
Ummm, I'm someone who passed the beginner stages recently, I don't find most youtube guides or udemy courses very beneficial anymore. I'm now trying to build a somewhat big jrpg with somewhat decent system design i hope.
It's been going steady for 2-3 months but now i'm a bit blurry about the future of the game, since things like scene management with addressables for my game, i feel like im just reinventing the wheels but in a way more inefficient and less scalable.
I feel like i should be studying similar released games codebase but i think it would take too much time just trying to understand what's going on alone since it's made by big teams...
How did you guys progress in this phase ? Any advice is greatly appreciated...Thank you !
I'm sure you've heard this before, but the most efficient way to learn how to make games and write good code is to make many smaller games, rather than one big game. It's the same with any other skill. If you want to get good at painting, you should make a bunch of paintings. Your first paintings are going to be bad, but with each new painting you'll get better, learn new techniques, become more efficient. But if instead of that, you decide to immediately start with a huge, complicated painting and say you'll learn along the way, I'm sure you can imagine that isn't really going to work as well.
Well, the game i'm working on is not that big. I'm constantly refactoring, trying to improve the existing systems with the new things i learned, that's why it's taking so long. Those problems only surfaced when I work on a game of this complexity. If i try to make smaller games I don't think I'll learn as much (I did make smaller games before this). But there's a limit to how much i can improve doing this solo
On that note, is there a good source of code (for rpg if possible) in general or scene management + addressables in particular ?
OK I'll look into it, thanks. For JPG, I don't mind the lower quality. Since textures are 2K and not compressed being stored in the streaming assets folder, having a smaller size JPG compared to a PNG really reduce the game download size. And the more textures I add, the more the size will be saved. JPG are a bigger issue when you want to keep editing the same file if I understood that part right. You lose quality each time you save your JPG. So if you save it only once, the quality loss won't matter too much.
Possibly but I don't have enough skills myself to replicatethe lit layered shader through shader graph and tweak it to make the layer mask tilable by channel.
All that can be done in a lit shader graph. It's only an issue if you need to modify actual lighting or do something post lighting.
Hi, i noticed this problem in XR interaction toolkit
i want to have domain reload disabled for faster reload times, but Device Simulator has this piece of code for creating its instance...
the statement that "Will execute the static constructor as a side effect." is simply not true with domain reload disabled and i dont understand why would anyone do that -_-
Where can i report this issue, its a bit annoying because i need to make my own settings and disable the native ones to make it work...
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad), Preserve]
public static void Initialize()
{
// Will execute the static constructor as a side effect.
}
[Preserve]
static XRInteractionSimulatorLoader()
{
if (!XRDeviceSimulatorSettings.Instance.automaticallyInstantiateSimulatorPrefab ||
(XRDeviceSimulatorSettings.Instance.automaticallyInstantiateInEditorOnly && !Application.isEditor))
return;
After upgrading to Unity 6, tile animations stop being synced up.
As you can see here, the animation of the tiles are not in sync, whereas they were before upgrading to Unity 6.
Trying to set animationStartTime to 0 in the GetTileAnimationData overload does not fix the issue.
I have not seen this change being documented anywhere, so what's going on?
These tiles are placed at runtime, at possibly different times.
(I'm also using a custom tile implementation deriving from TileBase)
How are you animating the tiles exactly?
My guess would be that the issue comes from some internal chunking they changed. Try putting a few tiles to the right to see if it's some magical threshold or if it's just that exact edge tile
Just setting the animatedSprites array on the TileAnimationData struct
Not based on chunks, if I place each tile with pause inbetween they are all out of sync completely
Exactly by the placement delay

It's possible that the GetTileAnimationData might be queried once per tile then. So animationStartTime goes out of sync
I have a super dumb idea tho
Try setting animationStartTime to -Time.time
@finite pond
Oh boy, I did try Time.time but not the negative lol, lemme try that
even worse, looks like negative times are completely ignored
so the animation only starts after the initial negative time is elapsed
That's... an interesting result
Okay, found a method that might potentially work better
Try calling that on all the tiles after placing them
Or you might try doing
SetAnimationTime(/* position of just placed tile*/, Time.time)
After each tile
That should make it so all of them are synced nicely to one universal time
im flabbergasted that they make such a drastic change without documentation lol
Okay, setting to 0 does not work. ill try the time next
time works neither
what the helly
Make sure the animationStartTime is set to 0 tho
@finite pond // Wait, SetAnimationTime does not work at all?
having both the animationStartTime and SetAnimationTime calls also does not address the issue, at least not when setting it to 0
ill try a few more permutations
π€
the API itself works fine, i use it in other areas
For the record, I never worked with animated tiles. I'm just doing educated guess work based on the docs
yea, SetAnimationTime itself works fine (used by the waving grass), however the animated water tiles are still broken
WAIT! Another discovery
It shouldn't matter according to how the functions work, but let's try it
Show me your GetAnimationData function please
public override bool GetTileAnimationData(Vector3Int position, ITilemap tilemap, ref TileAnimationData tileAnimationData)
{
if (SkipTileRefreshScope.IsRefreshing)
{
return false;
}
if (!_isAnimated)
{
return false;
}
if (!_ruleset.TryGetRule(this, tilemap, position, out var rule))
{
return false;
}
var spriteSheet = GetSpriteSheet(tilemap, rule, position);
if (!rule.Animation!.GetTileAnimationData(this, position, spriteSheet, ref tileAnimationData))
{
return false;
}
tileAnimationData.flags = _animationFlags;
tileAnimationData.animationStartTime = 0;
return true;
}
OH
there is a new TileAnimationFlags!
SyncAnimation
that didnt exist before U6
Yeah, was about to add that to the code
My guess is that they changed something internally to make tilemaps more performant and probably made syncing animations opt in instead
Oh...
yea, even with SyncAnimation being the sole bit thats active on the flags
You removed the SetAnimationTime calls, right?
yep
Well... that's a bit puzzling
setting animationStartTime also doesnt affect it
Will throw it into my TODO for tomorrow and see if I can repro this on my machine. Seems like a weird problem
What Unity version are you using?
6000.0.48f1
Got it, tho I can't guarantee I will find time for it
Yeah, cool art by the way
thanks, its Quest Master in case you're curious!
i had to switch to URP because i was facing major issues with MaterialPropertyBlocks
and this tile animation issue is a major painpoint i didnt expect to face lol
What was it?
i believe it was some kind of limitations of the underlying implementation. i was using MBPs a lot and renderers in close promixity started to share and swap values with each other
i ruled out everything, i didnt pool the instances either
additionally the SRP batcher was a nice upgrade to dynamic batching
Could be some weird batching behaviour, I think in URP you are supposed to just clone the material at runtime instead of using MBPs
yep, in URP i had to rewrite the entire logic to rely on cloned materials instead of MBPs
i was using MBPs with the built in Pipeline
Tho I never had property blocks mixing with each other... very weird
That's wacky
all unique renderers, all unique MBP instances
yep
and i couldnt afford not to batch them
Anyhow, good luck with the issue. I'm gonna go back to working and all that boring stuff.
Will let you know if I figure something out
thanks for helping me rubber duck debug this issue
I am getting thoroughly flummoxed by some binary parsing I'm doing. The values I'm getting in code for this particular float just don't make sense which is weird because all of the ones before it work fine and they're all from the same file (it's not like the number formatting would change within the same file?)
I was getting a weird result using BinaryReader.ReadSingle() so I wrapped up my own to inspect it in the debugger.
private static float ReadFloat(BinaryReader reader)
{
byte[] bytes = reader.ReadBytes(4);
return System.BitConverter.ToSingle(bytes, 0);
}
The bytes its getting are 0xC2240120, which by any online hex-to-float converters I can find, should convert to -41.0011, which is exactly the number I'm expecting to find here. When I step out of this function in the debugger, it's returned 1.093889E-19 which is nowhere near right. Anyone know what might be going wrong? There are multiple other ReadFloats before this, including negative ones, that all parse exactly as expected.
is this all done on desktop like win/linux?
Big endian vs little endian
what platforms even use big endian that work with unity though?
Why would endianness just swap halfway through a file?
Is ReadSingle big or little endian?
No idea, but you can see your result is big endian
was this value only changed on some arm system?
Well dang, that did it
Why does this file swap endianness halfway through
I made the file I should know what endianness it is and I explicitly told it little-endian
I'm gonna blame Java for this one, the file is written by a Java program and it probably just doesn't do what I asked of it
OH well that would have been good to mention π
endianness is a pain. I wrote something a while ago in rust to convert endianness of DXT data
I didn't think it would be relevant, I am directly encoding it all to little endian. Snippet of the java that writes this particular float:
ByteBuffer buffer = ByteBuffer.wrap(buf);
buffer.order(ByteOrder.LITTLE_ENDIAN);
buffer.putFloat(f);
out.write(buf,0,4);
So how the hell did it end up backwards?
I guess it's not really a problem for this server
but god damn I hate working with Java
How do you guys handle needing to patch built files, in my case the generated Xcode project's UnityAppController.mm file?
My immediate thought is to have a build post process that asserts the file to be what it's expected to be, then overwrites it with patched content. Is this how people typically go about it?
Only time ive had this we replaced the file before invoking xcode via fastlane in our build job
Hmm, sounds like the same idea just done with an external tool.
Destroy waits until the update loop or lateupdate loop before actually destroying and setting null an object?
i think i tested ondisabled and it was called imamdiately when Destroy (component) was called, didn't wait on the end of the update loop
OnDestroy is dead last in the event loop.
https://docs.unity3d.com/6000.0/Documentation/Manual/execution-order.html
I see, what is the safest way to early exit for object destruction? i tried ==null and that didn't work, , !object neither, object is null doesn't crash but still nullrefs
if (theObject == null)
If you're talking about an object that was destroyed this frame, Unity will not help you detect that
use your own bool flag
if (theobject==null && theobject.enabled)
crashed when theobject is null (i think) on the second condition so I ended up with
if(agent is null || !agent.enabled) return;
which nullrefs but doesn't crash
NullReferenceException
at (wrapper managed-to-native) UnityEngine.Behaviour.get_enabled(UnityEngine.Behaviour)
π€·ββοΈ
what are you trying to do?
that first one is guaranteed to throw a null ref exception if the object is null
you made sure it was null then tried to access .enabled on it
have the thing not crash tsss, i meant to write || not &&
Have it not crash when you do what?
what are you trying to accomplish with the code?
It's not that complicated of a question - "I want to know when an object is destroyed or it has been disabled" for example
you shouldn't use is null with UnityEngine.Object subtypes, just basic null checking with equality is all you need to solve every NRE with them
a last minute fix to a bug i that don't understand...
mmm I think I just understood what might be happening: object received damage, object receive push command from the damager, push starts a coroutine, damage causes destruction, coroutine still runs when things are being destroyed.. somehoh. I thought coroutine were getting nuked when the component gets nuked but this seems to be delayed.
are you sure the problem isn't the nuking isn't delayed?
object destruction isn't instant
Showing the code and the error(s) might help
good call, lemme see, you're right destruction is delayed by the game logic, and also by lifecycle
public void Push(Vector3 direction,float duration)
{
if(agent is null || !agent.enabled) return; //bug agent should never be null but it is
float kickbackMove = 0.01f*agent.avoidancePriority;
kickbackMove = Mathf.Min(kickbackMove,5f);
if(agent.isOnNavMesh) {
if(_coroutinePush!=null) StopCoroutine(_coroutinePush);
_coroutinePush = StartCoroutine(SmoothPush_C(kickbackMove*direction.XZ(),duration));
}
IEnumerator SmoothPush_C(Vector3 relativeMove,float duration)
{
float elapsedTime = 0f;
Vector3 initialMove = Vector3.zero;
while (elapsedTime<duration) {
float t = elapsedTime/duration;
agent.Move(Vector3.Lerp(initialMove,relativeMove,t));
elapsedTime += Time.deltaTime;
yield return null;
}
}
}```
this nullrefs but doesn't crash on window, let's see on android...
I don't see anything that destroys anything here
Anyway as vertx said never use is with Unity objects
if(agent == null || !agent.enabled)```
if(destroyOnDeath) { Destroy(gameObject,deathDelay); }
Unrelated, but you also you have to set the coroutine to null after stopping it, it won't become null by itself
that's the one causing trouble
I have no context for where this is
ok, good to know
here is the one calling push and handledamageprovider is the one changing damage which then causes the delayed destruction
{
yield return null;
var damageables = new HashSet<MCDamageHandler>();
var cols = Physics.OverlapSphere(transform.position,radius);
var rigidbodies = new HashSet<Rigidbody>();
foreach (var c in cols) {
if(c.attachedRigidbody?.GetComponent<MCNotAffectByExplosions>() || c.transform.root==transform) continue;
//gather pushables
if(c.attachedRigidbody) { rigidbodies.Add(c.attachedRigidbody); }
//gather damageables
var d = c.GetComponent<MCDamageHandler>()?.realSelf;
if(d && d!=originator && (damageSameTeam || d.team!=team)) damageables.Add(d);
}
//process them
foreach (var rb in rigidbodies) {
Paralyze(rb.gameObject);
var d01 = Mathf.Clamp01(1-Vector3.Distance(transform.position,rb.position)/radius);
if(rb.TryGetComponent<MCMoveNavmesh>(out var agent)) agent.Push(explosionForce*d01*(agent.transform.position-transform.position),.2f);
else rb.AddExplosionForce(explosionForce*d01,transform.position,radius,1,ForceMode.Impulse);
}
foreach (var d in damageables) {
if (!d) continue;//hack shouldn't be happening but it is
float d01 = Mathf.Clamp01(1-Vector3.Distance(transform.position,d.transform.position)/radius);
var actualDamage = d01*Damage;
d.HandleDamageProvider(this,actualDamage,transform.position,transform.forward);
D.raw(new Shape.Text(d.transform.position,actualDamage),1f);
}
}```
Completely unnecessary side-comment; Probably very slightly cheaper to flip that first if statement right
the agent is null? then it won't shield the !agent.enabled from null (not that is does anything but at least it stopped the crash, somehow)
I'm confused about agent.Push(explosionForce*d01*(agent.transform.position-transform.position),.2f);
you're calling agent.Push(..) but then inside Push there's some variable called agent there too?
What is that variable?
yeah i'm quite proud of the naming. agent in Explode is a MCMoveNavmesh and the one that's in the push function is a navmeshagent
Turns out Unity does have a way to let you subclass app controller, but it's barely documented. There are some forum threads you can Google and piece information together.
found the crash
Coroutine::InvokeMoveNext(ScriptingExceptionPtr*)
Coroutine::InvokeMoveNext(ScriptingExceptionPtr*)```
because of the delayed destroy the agent turned null in the coroutine and the crashlog doesn't see inside coroutine so it kept pointing at the wrong stuff.
on a side not, I should detox from them. Coroutine always break in weird ways
what do you guys use instead?
I've never really had issues with them. If you're constantly having issues with it, that's more of an indicator your setup has flaws. It's not like everyone's putting up with random crashes.
There were a few points that others stated above, like the not using ? on unity objects. Did you manage to change everything suggested?
The alternatives are pretty much update or async. You definitely wouldnt want to just avoid coroutines in favor of update because some code is really easier to make as a coroutine. I dont suggest async either because you would really have to know what you're doing with it
yeah but was of no help because read what I said, the crash is nullref in coroutine, not live cycle of null check
what
pretty sure the reason why ? is being brought up is if it was requested to be destroyed that frame the ? will result in true but the == will result in false, no?
Specifically it does a null check in managed code while Object lives in unmanaged code. They may not always match.
So itβs simply asking the wrong question
i really have no clue what this is supposed to mean, and truthfully its borderline impossible to read your code given the style. There were also a lot of ? used in that Explode coroutine, hopefully you changed those too. It'd probably solve this part too if (!d) continue;//hack shouldn't be happening but it is
As others wrote above, just checking for null is all you should need. Maybe try to recreate this in a separate minimal project to see if it's really a problem with your updated code.
guys, I understand you like to jump on problems trying to fix them but this is solved. had nothing to do with how the null was tested, it was lack of catching null in a coroutine - you can relax.
no but the ? in the context of destroying objects can lead to not catching null.
I'm glad you found the problem but even if it wasn't the issue it's directly related
? with UnityEngine.Objects is not a safe null check
π€·ββοΈ didnt get the impression it was solved from previous messages but glad its solved anyways.
you're right, the ? is a problem , i still have a few throughout my code and will fix this one now - thx
yea i understood that message as you found the crash, but wasnt aware you fixed it. It was pretty clear from way before that agent was null and you were trying to access something on it.
coroutine is convenient, problem is rider debugger has trouble stepping through them, and hotreload does a full recompile on coroutine change. i end up rolling in state machine more and more to replace them, but as you said it's heavier
what wasn't clear was where the agent was null, that's another problem with coroutine, the crash log generated by unity won't point inside them so i ended up chasing something which wasn't a problem.
had to be a trace from the hardware itself
that's probably why i'm so laser focused on that coroutine thing: i didn't know all those caveats, and i'm sure someone else will run into them, so maybe they can find that here
oh btw my point here was that it was probably super slightly better to test for the collider.transform.root == transform before testing for if the collider.attatchedRigidbody != null && collider.GetComponent<MCNotAffectByExplosions>() since the root check is likely cheaper. very minor difference im sure
btw, i'm always fuzzy on this unityObject?.Method thing, do you guys split it like this?
if(c.attachedRigidbody && c.attachedRigidbody.GetComponent<MCNotAffectByExplosions>() || c.transform.root==transform) continue;
It's not really about it being heavier (which usually means performance), sometimes its just more of a pain to write. Like each yield suddenly becomes its own bool or timer that you need to store. If you already have a ton of logic inside update, it gets awkward very quickly.
on windows you said it didnt crash but gave a null ref. didnt this also give you the line that it happened on?
it did, and that line wasn't inside the coroutine that had a nullref
those first two checks being seperate and explicit seem right yeah. Although you may prefer to use layering to avoid picking those up in the first place rather than using the MCNotAffectedByExplosions component but depends on the context of your project
layering?
Physics.OverlapSphere can take in a layermask for object filtering
indeed, that wouldn't work in this case
it's a physics heavy game so i had to decouple gameplay and interactions
and I'm always weary of tags, never used thm actually, always seems very "string-y"
I am also team fuck tags π
Sometimes I will use them for very broad content identification though
hehe, yeah anything that pushes gameplay to the editor setup is looking for trouble, and i'm a bug fan of rigging in editor, just get hurt plenty
btw, is there a more concise way of getting these sorta things null check when accessing stuff.ofstuff, since stuff?.ofStuff won't work with unity objects due to lifecycle ?
c.attachedRigidbody && c.attachedRigidbody.GetComponent<MCNotAffectByExplosions>()
i would honestly change a lot for readability sake
foreach (Collider c in cols) {
Rigidbody currentRb = c.attachedRigidbody;
if(currentRb == null)
continue;
if(currentRb.GetComponent<MCNotAffectByExplosions>())
continue;
}
no not really
by the way you're writing code, i assume you're a big JS fan
i know what you mean, i always try to write in less LOC because i can remmeber code better when it looks a certain way
could also safely getcomponent off the collider to avoid needing a line to ref the rb?
foreach (Collider c in cols) {
if(c.attachedRigidbody == null) continue;
if(c.GetComponent<MCNotAffectByExplosions>()) continue;
}
the attachedRigidbody isnt always on the same object
pascal but yeah i resumed programming in java
what's weird?
think they're referring to my comment of why their suggestion wouldnt work. its not really weird though given a lot of setups have colliders as children objects
what !bawsi says, and also i use a lot of collider's physics event transfer to rigidbody, force of habit
ah yeah? what does your non-weird code looks like? π
anyway i'm tired, gotta get ready for the flight and release tom, i'll read in the morn - ciao everyone, thanks thx
probably some weirder shit like using a physical material as an object reference to identify ignore explosion objects π
Imagine a world where Unity used .IsAlive instead of overriding ==.
I was thinking about it at some point. And I'm still not sure which approach is better honestly π€
-# Also, having a .IsAlive() extension method instead of .IsAlive property would be better if we go that path
I've unironically written code like if (someGameObject is not null && someGameObject == null). I'd take anything over that.
Wait, why would you write code like that?
== null already checks the C# side null first as far as I remember
Yes, but the entire condition is meant to check "there is a someGameObject but it's already destroyed."
Oh right. not null. My bad
It would read so much better if the someGameObject == null was instead !someGameObject.IsAlive or someGameObject.IsDestroyed.
Curious, when did you need that?
It's for a tweening system, a tween can be bound to nothing (in which case the tween will always run to completion) or bound to a GO, and in the latter case it will abort when the GO is destroyed.
destroyCancellationToken can be useful for being notified of a destroy (and ofc to use with async things)
Yeah the code was written before that was a thing.
Valid
UniTask has a component that implements this for versions without this
If only GameObject had one. They only added it to MonoBehaviour.
yea tbh at this point they should just add an event to gameobject for destroying...
Okay, so we have a few common scenarios:
- Is object destroyed on Unity side? (the most common scenario)
- Is object destroyed on Unity side but alive on C# side?
- Is interface instance destroyed on Unity side if it's a Unity object and null if it's a Plain C# object?
- Is
objectdestroyed on Unity side if it's a Unity object and null if it's a Plain C# object?
Right, @scenic forge ?
-# I'm asking to explore potential APIs, want to make sure we are on the same page
to be honest I think a lot of newer people might get confused on the fact that you could access those values if they were true. .IsBeingDestroyed or something might be nice though? idk
Yeah basically any Unity object which exists on the native side, and the C# object is just a way to communicate with it. There are times you want to know both whether the native object is still alive or not, and whether the C# variable is null or not.
well remember the actual ref cant actually be null unless it never had a valid ref to begin with (or was set to null)
So yea checking alive state is technically different to "is this ref null"
It can be confusing if you don't usually work with interoping with native resources. If you do (eg app dev with things like file handles), it's quite common to have a C# object proxying your access to the native resource, and you can close the native resource while still holding onto the C# object for other purposes.
sure but also that likely places you in the minority of people using Unity which given the fact this mostly comes down to a "quirk" of how == works is likely something your aware of how to avoid aswell
One thing I hate is that .? cant be used safely as that does not use the UnityEngine.Object.Equals override π
but makes sense from lang design that it doesnt use this
With current implementation those cases look like so
obj == nullobj is not null && obj == nullobj == null || obj is UnityEngine.Object uObj && uObj == nullobj == null || obj is UnityEngine.Object uObj && uObj == null
With IsAlive property it would be just awful
obj == null || !obj.IsAliveobj != null && !obj.IsAliveobj == null || obj is UnityEngine.Object uObj && !uObj.IsAliveobj == null || obj is UnityEngine.Object uObj && !uObj.IsAlive
With an extension method like IsAlive()it could be slightly better
!obj.IsAlive()obj != null && !obj.IsAlive()!obj.IsAlive()!obj.IsAlive()(depending on the implementation)
But to be fair, you can write such extension yourself in the end, @scenic forge
you could still do obj?.IsAlive() if you want to check for actual null
You can also use pattern matching.
Oh, that's fair. Forgot about that
obj is { IsAlive: true } and obj is not { IsAlive: true } (as well as the false variants) will cover all use cases, since pattern matching like that also null checks.
Some of these combinations can also do obj?.IsAlive yeah.
logically i kinda get why you might want IsAlive but given the usecases where you would use it wouldn't it a majority of times be assumed to be alive so instead like human language wise wouldn't the opposite such as "IsDying" be preferable?
Tbh unreal already has something like this: https://dev.epicgames.com/documentation/en-us/unreal-engine/BlueprintAPI/Utilities/IsValid
I care less about IsAlive vs IsDestroyed, either one is better than nothing.
I feel like
if (foo.IsAlive()) foo.DoStuff()
```seems natural as far as the naming goes
Okay, I can see how that design decision would go well with pattern matching
natural in isolation but in c# and unity 9/10 im just gonna null check directly for consistency
The point is to explore an alternate scenario where IsAlive is a way Unity does it. So it would feel natural in that regard
Sure but Unity uses c#
one could argue abuses
if im dealing with monobehaviours and base classes ideally i wanna treat them the same way for something like this
And? Nothing in C# specs says that "overriding null comparison is the correct way to notify if the underlying resource was destroyed"
It's less about correctness and more about consistency
But you can't always treat them the same, for example if the are casted to object at any point
For a majority of people using Unity how often do you think they are casting to object
maybe a more common use case is a MonoBehaviour that implements an interface, you can't check for "unity null" through an interface reference
I'm not saying it's common. As I showed above, == null works fine for most common cases.
However, there's a point to saying that doing it the way Unity did it hides the complexity that you have to be aware of usually
Hiding that complexity leads to accidental usage of ?
I think you can, one moment let me check
the overloaded operators are on the concrete Object type, so C# won't use them for things that aren't that type
Forsure but i guess my argument is for "i wish doing ? just worked" and doubling down on incorrectly overriding c# rather than pivoting to a different solution
π§ I add a public GameObject gameObject {get;} property to help with this
I mean, the fact that an entire analyzer (warns you about ?. and ??) needs to exist, and despite that people still run into issues because of it, should be a pretty good indicator that the current design is quite flawed.
Oh yeah, this was awful to deal with π
Oh yeah, you actually can't, @stuck plinth.
To think I used Unity for years now and never ran into this issue 
it's fine until one day suddenly you have the weirdest bug lol
Yeah, I know. It wouldn't be the first time I ran into fake null. I'm just surprised I never ran into it with interfaces
-# Corrected the example above
I even knew what it was - just had no idea how to solve it
You have to cast to Object and then check for null
Why? Instead of doing foo.gameObject == null which gives you some info... but you don't know if it's an interface not bound to an object or one where the object was destroyed.
You can just do foo is Component c && c == null
(or you can create a bunch of extension methods)
But remember to cast to Object and not Object :v
tbh both work but i prefer the method not requiring the cast
could even have a "IsAlive" bool/func in the interface and we have gone full circle π
obj is GameObject { IsAlive: true } π
I would rather just have an extension method that takes object
Also, regarding interface shenanigans. Reminder that
Foo<T>(T bar) where T : IBaris technically faster (in some cases) than Foo(IBar bar)
:P
well duh, the generic method is generated for uses
Makes sense, though if I reach a stage where I"m worried about that kinda performance I'm probably iterating over a struct array already, instead of classes
Here it actually is about structs.
The former is faster in cases where it's a struct implementing an interface. Doesn't change anything for classes
(Only for structs, as far as I remember)
Oh, migth be. Never decompiled IL2CPP
There's a huge list of generated generics in the intermediate C++ source
il2cpp cannot do runtime generic creation from what I remember
Unless you do something crazy with reflection (which IL2CPP doesn't like), it's going to be known at compile time anyway
yea generics should be produced per use, especially in c/cpp
who knows what happens in cursed managed cpp land
Oh god... Cpp templates ;-;
IL2CPP fully supports Reflection, except for Reflection.Emit, because of AOT restrictions. It's mainly code stripping that gets in the way, but that just needs to be configured.
By default, IL2CPP creates a shared generic implementation for reference type arguments, templated implementations for value types, but you can tell it to use a shared implementation for value types as a build setting, which decreases build time and size, but costs performance.
https://unity.com/blog/engine-platform/il2cpp-full-generic-sharing-in-unity-2022-1-beta
One of my projects made really heavy use of struct generic type arguments and our builds started to fail because IL2CPP was generating over 9 gigabytes of C++ source code from instantiating all the different types. The new build setting saved that project.
9 gigabytes of C++ source code is a phrase straight from my nightmares
Not sure if this is advanced or general but just out of curiosity more than problem solving, why does [RuntimeInitializeOnLoadMethod] not run on generic interfaces? (or maybe just generics in general?)
guessing something serialization related?
The type and method names are serialized in RuntimeInitializeOnLoads.json in the _Data folder of builds, so you can see the format it's in.
What would you expect it to do on generic types? What type would it choose?
the type i declared? eg.
[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/SpawnManagerScriptableObject", order = 1)]
public class ScriptableSingleton : ScriptableObject, ScriptableInterface<ScriptableSingleton>
{
}
(tried on monobehaviour too incase it was scriptableobject life related)
im guessing the issue is that the attribute lives in the interface but the decleration of the generic lives here
Oh, an instantiated generic type. I thought you meant:
public interface ScriptableInterface<T>
{
[RuntimeInitializeOnLoad]
private static void OnInit()
{
}
}
Yeah that is what i am doing
i just figured the existance of defining it would allow that type to exist
To support this, Unity would have to additionally search for every type that gets used as a type argument in the interface.
And what if you had this:
public class MyGenericClass<T> : MyGenericInterface<T>
{
}
and you instantiated it in a method somewhere.
private void Awake()
{
var a = new MyGenericClass<float>();
var b = new MyGenericClass<string>();
}
I wasn't aware that would be an additionl step so fair
In this specific usecase that's not a valid example since that would be after the attribute is intended to fire
oh right i understand now
Though the fact i have it defined explicitly puts me in the middle of reality and that example right
@finite pond // Okay, I did some testing
And it works
Sort of, turns out that having the speed at anything other than 1 makes it desync
From what you can see, it seems that the animation time is kept in "1 frame per unit" and is affected by speed (kinda stupid naming choice, but sure)
As for Sync Animation flag, it seems to work however I saw you use a rule tile, right?
Can you check that without SetAnimationTime and with that flag set, the animation is synced but on rule tile variant basis?
That is, the straights are synced separately from say... corners
If what I suspect is true, the best approach might be to keep a reference to one of the animated tiles to get its animation time for syncing
tilemap.SetAnimationTime(/* newly placed tile coords */, tilemap.GetAnimationTime(/* one of the existing tile coords */));
i dont use rule tiles
i use a custom implementation
i also did more testing and found this
its definitely somehow the chunking
when i place just two tiles adjacent to each other, their animation syncs up correctly
but when i combine them to larger chunks, it breaks
and this is without setting animationStartTime or using SetAnimationTime
just TileAnimationFlags.SyncAnimation
(using the SRPBatch render mode)
Still, your implementation creates multiple Tile objects, right?
As in edge tile and corner tile exist as separate assets
no
my ruleset implementation provides the sprite based on input cell
thats it
then its set
or animation if its animated
public abstract bool TryGetRule(Tile tile, ITilemap tilemap, Vector3Int cell, [NotNullWhen(true)] out TileRule? rule);
Can you show the code?
i did yesterday, but sure
public override bool GetTileAnimationData(Vector3Int position, ITilemap tilemap, ref TileAnimationData tileAnimationData)
{
if (SkipTileRefreshScope.IsRefreshing)
{
return false;
}
if (!_isAnimated)
{
return false;
}
if (!_ruleset.TryGetRule(this, tilemap, position, out var rule))
{
return false;
}
var spriteSheet = GetSpriteSheet(tilemap, rule, position);
if (!rule.Animation!.GetTileAnimationData(this, position, spriteSheet, ref tileAnimationData))
{
return false;
}
tileAnimationData.flags = _animationFlags;
return true;
}
I mean the code for getting the tile. Not animation data
the sprite variant you mean?
Maybe?
I'm trying to decipher what the code is actually doing and how it could in theory break
public bool GetTileAnimationData(Tile tile, Vector3Int cell, SpriteSheet spriteSheet, ref TileAnimationData tileAnimationData)
{
if (CachedSprites.TryGetValue((cell, spriteSheet), out var sprites))
{
tileAnimationData.animatedSprites = sprites;
}
else
{
sprites = new Sprite[Sprites.Length];
if (UseRandomCellOffset)
{
var cellOffset = new Vector2Int(GetRandomCellOffset(new Vector3Int(cell.x, 0)), GetRandomCellOffset(new Vector3Int(0, cell.y)));
cell.x *= cellOffset.x;
cell.y *= cellOffset.y;
}
else
{
cell.x *= CellOffset.x;
cell.y *= CellOffset.y;
}
for (var i = 0; i < Sprites.Length; i++)
{
var index = i;
index += cell.x;
index += cell.y;
index = index.Mod(Sprites.Length);
sprites[i] = spriteSheet[Sprites[index]]!;
}
tileAnimationData.animatedSprites = sprites;
CachedSprites[(cell, spriteSheet)] = sprites;
}
tileAnimationData.animationSpeed = Speed;
return true;
}
This is the one for animated tile rules
Anyways, let's just assume that for some reason Unity considers them different tiles and run with that
I assumethe Speed is not 1, right?
Nah
Let's try with this
Basically, this copy pastes the animation time from one water tile to another
You just have to know where any other water tile is
sounds like a ridiculous workaround but ill try it sure
exact same behaviour as this
i have one idea
Go on
I find it weird that tilemap.SetAnimationTime did not work because it fixed the issue in my testing
Can you try doing a isolated example akin to something I did above?
one sec, last idea i have
https://gist.github.com/Wokarol/c1b00cc3d76c19b3d539efcc69004dad
Here's the code for mine
Ok, i replaced calls to Tilemap.RefreshTile with this now:
public static class SynchronizedTileRefresher
{
private static readonly Dictionary<TileBase, Vector3Int> LastCells = new();
public static void RefreshTile(Tilemap tilemap, Vector3Int cell)
{
tilemap.RefreshTile(cell);
var tile = tilemap.GetTile(cell);
if (tile == null)
{
return;
}
if (LastCells.TryGetValue(tile, out var lastCell))
{
tilemap.SetAnimationTime(cell, tilemap.GetAnimationTime(lastCell));
}
LastCells[tile] = cell;
}
}
And this actually fixes it
Major pain point because of the added null check overhead
i should be able to inject the tile itself though, which will eliminate the overhead
not too bad with an extension method syntactically either
just still dont understand the reason for this breaking lol
is it a bug we're working around now?
cause clearly the syncanim flag is not working as implied
public static class SynchronizedTileRefresher
{
private static readonly Dictionary<TileBase, Vector3Int> LastCells = new(ReferenceComparer<TileBase>.Instance);
public static void RefreshTile(Tilemap tilemap, Vector3Int cell, Option<TileBase> tile)
{
tilemap.RefreshTile(cell);
if (!tile.HasValue)
{
return;
}
if (LastCells.TryGetValue(tile.Value!, out var lastCell))
{
tilemap.SetAnimationTime(cell, tilemap.GetAnimationTime(lastCell));
}
LastCells[tile.Value!] = cell;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RefreshTile(Tilemap tilemap, Vector3Int cell)
{
RefreshTile(tilemap, cell, tilemap.GetTile(cell));
}
}
public static class TilemapExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RefreshTileSynchronized(this Tilemap tilemap, Vector3Int cell, Option<TileBase> tile)
{
SynchronizedTileRefresher.RefreshTile(tilemap, cell, tile);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void RefreshTileSynchronized(this Tilemap tilemap, Vector3Int cell)
{
SynchronizedTileRefresher.RefreshTile(tilemap, cell);
}
}
near zero overhead final implementation
It's more so weird Unity design decision we are working around
i checked the docs of the TileAnimationFlags.SyncAnimation again, and it speaks of "animations that are the same", so i wonder what consitutes being the "same". i assume a reference check on the sprites array and matching speed?
Basically, Animation Time is not in seconds. It's in frames... sort of.
So for an animation with speed = 2, it increments twice as fast. That's why using Time.time failed
right
I previously assumed it's based on TileBase reference. But it might not be in that case
Not sure
yea im trying something rn to validate my assumption
yea, assumption wasnt correct
the workaround it is
should i try to implement MT with DOTS for mobile ? or is it so little supported that i should just focus on optimizing the main game thread
MT? DOTS should work properly on mobile afaik.
Multi Threading
yeah im not scared of DOTS not running on mobile, i found good demos of it, im just wondering if i should consider MT
i dont know how much cores mobile hardware has
Probably at least a few. Which should be enough to provide improvement.
Optimizing the main thread or going dots are not really 2 equivalent options. They involve a lot more than just performance.
You should decide if you want to go GameObjects or ECS and then think about optimization within that context.
You can use threads to do non unity things and the job system without needing to use Entities too.
Depends on the situation tbh and it depends on if you need to interact with gameobjects/entities or not.
You usually see high core counts in many modern devices, to improve efficiency
Every semi modern device has multiple cores/threads but all non ancient operating systems use time slicing.
i need hundreds of moving entities so ECS is kinda the only decent option afaik
ECS is the only viable option
and thanks for everyone's answer for MT, i guess ill use it if i got time for heavy workloads
Why? You cannot use a managed thread to modify a Transform so ECS is the only way to do something like this π
wdym by that ?
is MT used by default with ECS ?