#archived-code-advanced

1 messages Β· Page 128 of 1

hybrid tundra
#

sry

#

I have no idea how to copy-paste stuff correctly into discord

#

so one sec

#

*.blank

#

*.blank.meta

untold moth
#

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?

hybrid tundra
#

were in the p4ignore

#

inside that folder

hybrid tundra
#

because I haven't got too much experience with Perforce, I rather know Git

untold moth
hybrid tundra
untold moth
#

aah

#

Yeah

hybrid tundra
#

then /Assets/StreamingAssets/*.json

untold moth
#

That would need to be added.

hybrid tundra
#

yeah

#

I just didn't know I need to add this to make that error get removed

untold moth
#

though, I wonder if it would help, considering it must already be in the depot

hybrid tundra
#

because Git worked differently, Git never complained about anything during building

untold moth
#

Try it out and tell us

hybrid tundra
#

or it will just recognise the p4ignore changes

untold moth
#

Probably not. Maybe restart the editor if it's the plugin that is causing the issue

hybrid tundra
#

but btw, that addressables_keys.json is not read only, and it was not read only before I modified the ignore file

untold moth
#

Okay, at this point I'd try to remove the p4 plugin

hybrid tundra
#

I just wanted to progress

untold moth
hybrid tundra
#

p4 plugin of Unity?

#

p4 plugin of VS?

ebon abyss
#

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

hybrid tundra
#

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

hybrid tundra
#

I just connected to p4 from Unity and that's how it works

ebon abyss
#

I'd assume it's a package

hybrid tundra
#

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

untold moth
#

Well, you probably should learn what you're doing and then check it...

hybrid tundra
untold moth
#

You just need to remember what files are modified and use "reconcile offline work"

#

Look it up. Read the P4 manual.

hybrid tundra
hybrid tundra
# untold moth Yes

since then I realized the build is basically created, not sure if its 100% finished, but its created

hybrid tundra
#

and now the build gets created 100%, the progressbar also goes along to the very end

rich ivy
#

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? πŸ™‚

echo coral
#

Unity hate you and dont let us modify clips at runtime 😦

rich ivy
#

Could I maybe just make an ultra generic animclip in a prefab and pass new sprites onto the game objects that are referenced?

regal lava
#

you got animation clips

rich ivy
#

I understand animation clips can't be modified, but the assets they reference can right? πŸ™‚

regal lava
#

er, animationcurves ;p

rich ivy
#

animation clips can be modified at runtime?

regal lava
#

You can also make different animationoverridecontrollers and swap them out

rich ivy
sly grove
#

isn't this 2D/

rich ivy
echo coral
sly grove
#

so it's the same

regal lava
#

I mean, it doesn't matter too much if it's part of the streamingassets, you just need to bind everything accordingly

rich ivy
#

Oh okay, I wasn't sure if that package only worked in screenspace or something πŸ™‚

sly grove
#

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

rich ivy
#

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

sly grove
#

are you doing spritesheet animation

#

or skeletal animation

rich ivy
#

Spritesheet, except I'm not using sprite aliases, just individual files.

sly grove
#

Here's how to do sprite swapping for spritesheets

rich ivy
#

Thank you! Hopefully this is at runtime

sly grove
#

of course, yes

regal lava
#

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

rich ivy
#

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

rich ivy
#

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!

untold moth
hybrid tundra
hybrid tundra
#

because I don't really understand how it works

untold moth
untold moth
#

If it finds files that are changed, it adds them to the pending changes.

hybrid tundra
untold moth
#

Reconcile is specifically for cases where perforce loses track of local files

hybrid tundra
untold moth
#

Yes

hybrid tundra
# untold moth Yes

so then if I use "reconcile offline work", and then shelve all changelists, then I can return to the current state anytime, right?

hybrid tundra
#

or I should only commit and push the shader in this case?

#

because I never needed to modify shaders

untold moth
#

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.

hybrid tundra
#

with yamlmerge or with something else?

untold moth
#

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.

hybrid tundra
#

especially if I'm unfamiliar with it

#

because people can lose hours of work with one wrong command

untold moth
#

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

untold moth
hybrid tundra
untold moth
hybrid tundra
#

they are in the workspace, yes

#

if that's what you meant

#

@untold moth have you meant this?

vocal dagger
#

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

untold moth
vocal dagger
vocal dagger
#

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?

vocal dagger
#

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.

scenic forge
hybrid tundra
#

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

stuck plinth
hybrid tundra
#

but since then I solved the thing I wanted

timber flame
#

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?

echo coral
#

how many deps can a tree have anyway 😐

untold moth
#

Should use the profiler to understand the issue properly

stuck plinth
#

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...

odd turret
#

you can also try VContainer which has some source generation tricks to speed up instantiation, avoiding a lot of reflection

hushed fable
hybrid tundra
#

@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?

timber flame
echo coral
#

"I love bad performance is so neat!"

timber flame
timber flame
hushed fable
gentle fox
#

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?
echo coral
#

and with preserve/lazy unitask you can await it in multiple places so you could have your ButtonClicked function still await it.

gentle fox
#

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

echo coral
#

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)

austere jewel
#

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

sonic falcon
#

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.

gentle fox
# austere jewel I think you should be using cancellation token source instead of this preserve s...

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;
        }
    }
}```
echo coral
undone sedge
#

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?

undone sedge
#

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

thin mesa
#

are you using the built in render pipeline?

undone sedge
#

I think so πŸ€”

thin mesa
#

you should check . . .

undone sedge
#

this is the MonoBehavior component having OnPreRender()

thin mesa
#

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.

undone sedge
thin mesa
#

so you're using HDRP, which still means no OnPreRender call since that is BiRP only

undone sedge
#

😦

#

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

thin mesa
#

the scriptable render pipelines should have events you can subscribe to for render steps, you'd have to check the relevant documentation though

undone sedge
#

thanks πŸ™‚

undone sedge
#

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

undone sedge
#

This:
RenderPipelineManager.beginCameraRendering += OnBeginCameraRender;
and filtering by the camera works

undone sedge
#

but then it looks like hdrp overwrites everything -_-

echo coral
sage wadi
#

How might one create an animation clip that edits the main texture of a material on a mesh renderer through script

sly grove
sage wadi
sly grove
#

oh this is editor only

#

yeah I don't think you can do it other than with float values

sage wadi
#

I have used that and it always returns the mesh renderer as null reference

sage wadi
sly grove
sage wadi
#

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

undone sedge
#

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

untold moth
undone sedge
#

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

untold moth
sonic falcon
jaunty falcon
#

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.

untold moth
storm onyx
#

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 πŸ™

Use the Motion Matching for Unity tool from Vault Break Studios on your next project. Find this & more animation tools on the Unity Asset Store.

jaunty falcon
undone sedge
#

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?

#

😦

untold moth
undone sedge
#

Very useful thank you!!!

upbeat token
#

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
upbeat token
#

also my gpu really doesn't like the sheer amount of distortion, is there some hidden performance issues with the scene color node?

#

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

thin mesa
#

there is a dedicated #archived-shaders channel that covers all shader-related topics including compute shaders

upbeat token
#

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

thin mesa
#

compute shader is still a shader

upbeat token
#

you got a point lmao

untold moth
upbeat token
untold moth
upbeat token
untold moth
upbeat token
#

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

untold moth
#

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

upbeat token
#

I set buffer size in the cpu before sending it

untold moth
upbeat token
#

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

untold moth
#

Since you set the data there anyway.

upbeat token
#

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

untold moth
#

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?

upbeat token
#

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; }

echo coral
#

I was gonna say branching bad but i guess for a compute shader its not gonna matter much?

upbeat token
#

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;
}```
untold moth
upbeat token
#

that should fix branching

upbeat token
#

I have... frankly no idea why it works but it does

untold moth
#

If there was an error during compilation, your shader is likely a version before you added that code.

upbeat token
#

I've been using this shader for a month, so there's a slim chance of that

untold moth
#

You should select the shader in the editor and look at it's inspector

upbeat token
#

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

untold moth
#

It's assembly

upbeat token
#

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

untold moth
#

Or mentioned in the assembly before that code

upbeat token
#

since that's an assembly variable I don't actually know what that's referring to

untold moth
#

Share the whole thing.

upbeat token
#
**** 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
untold moth
#

The whole assembly I mean

upbeat token
#

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

regal lava
#

It's basically just a render texture without the setup

upbeat token
#

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

regal lava
#

Why are you using compute here anyway. This effect can be done in the shader without any of the complexity

upbeat token
#

those being the hub world (sorta like the hunters dream in bloodborne) and the main menu (which I'm planning to make kinda interactive)

upbeat token
#

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

regal lava
#

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

upbeat token
#

with a camera rendering the mask from the top orthographically right?

regal lava
#

Yep

upbeat token
#

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

untold moth
# upbeat token ``` **** Platform Direct3D 11: Compiled code for kernel CSMain keywords: <none> ...

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...

upbeat token
#

and trying it out on a potato pc got it running at maybe 10 fps

upbeat token
#

the solution I was using before was really bad tho, so I think I can pull off a render mask better now

regal lava
#

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

untold moth
upbeat token
#

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

untold moth
#

Ah, yeah. Because normally it doesn't exist.

upbeat token
#

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

untold moth
upbeat token
#

compute or the normal one?

untold moth
#

The one that has buffer.Length

upbeat token
#

nope, nothing

#

the only thing at that height in the file is #pragma kernel CSMain

untold moth
#

I see. Weird. I guess it's a modification they done to the hlsl compiler.

upbeat token
#
// 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

untold moth
#

The issue with using undocumented API is that you don't know if it works correctly. It might break on some platforms for example.

upbeat token
#

in this case, it does

#

linux does not like it

untold moth
#

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

upbeat token
#

...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

sage wadi
#

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);```
echo coral
sage wadi
#

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

echo coral
#

fyi get component in parent will check itself then parents so doing that with Transform wont do anything useful πŸ˜†

#

why not use transform.parent ?

sage wadi
#

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

echo coral
#

can material properties be animated? sprite renderers support sprite changing but ofc thats via the renderer comp

sage wadi
#

I sure to god hope so because if not this gonna be using a very large amount of materials😭

sage wadi
echo coral
sage wadi
#

its not just alpha clip. The alpha is just not working until you do something in the shader menu

echo coral
#

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

sage wadi
#

its using input texture alpha

echo coral
#

the tex preview does not show alpha though

#

java moment

sage wadi
#

wat no it dont

#

im confused now

scenic zinc
#

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

  1. I have a fractured glass to replicate glass breaking when hit
  2. I have a metal ball to throw at the glass panel (fractured glasses combined)
  3. 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.
  4. 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

  1. Added Mesh Collider (convex checked) and added RB (isKinematic set to true) to all the fractured glasses
  2. 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.
  3. Tried many ways but still failing miserably

Please, can someone help me with implementing this feature as I'm in need of it badly

dusty wigeon
brisk hound
#

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.

compact ingot
#

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.

brisk hound
compact ingot
#

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

brisk hound
compact ingot
brisk hound
compact ingot
tall ferry
# brisk hound So, you are saying i shouldnt go for it? Instead i should make templates of beha...

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.

brisk hound
untold moth
#

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.

untold moth
#

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.

livid kraken
#

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

tall ferry
# brisk hound This seems costly

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

brisk hound
#

Once I will achieve the first, making it cheat shouldn't be that difficult

#

But I have no idea how to do that

tall ferry
untold moth
#

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.

glass cradle
#

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

narrow python
glass cradle
#

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

austere summit
#

How you authorize graph data using unity inspector when you don't want to use GraphView?

stone frost
#

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 notlikethis

sly grove
#

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.

stone frost
sly grove
stone frost
#

So sorry about that, I thought the issue was much more complex than it probably actually is notlikethis

sly grove
stone frost
#

Understood, apologies again sadok

#

Very quick followup: it works now, thank you so much for catching all of my mistakes :]

bleak marsh
#

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

compact ingot
# bleak marsh Hey, just curious. How many of you are doing automated testing? And if you do, d...

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.

bleak marsh
#

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

bleak marsh
#

As it seems that it's what games like Factorio and Minecraft do

dusty wigeon
#

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.

compact ingot
#

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.

bleak marsh
compact ingot
#

Most live service games will have extensive automated testing

bleak marsh
compact ingot
#

I find that most large games nowadays are designed around production and maintenance constraints more so than anything that would improve player experience.

bleak marsh
compact ingot
# bleak marsh Maybe I don't get the approach you are describing then <:UnityChanThink:88516959...

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

bleak marsh
#

That one way to do it, true

compact ingot
#

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'.

bleak marsh
#

It's not something you would test automatically tho... right?

compact ingot
#

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

bleak marsh
#

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

compact ingot
#

everything can break randomly

#

thats the whole issue

bleak marsh
compact ingot
#

if you knew that breaks when you make a change, you need no testing

compact ingot
bleak marsh
# compact ingot everything can break randomly

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

bleak marsh
compact ingot
bleak marsh
compact ingot
#

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

bleak marsh
#

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?

bleak marsh
odd turret
#

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

compact ingot
#

very unlikely that an open ended game is end-to-end testable

bleak marsh
#

(Or is that aimed at Anikki? I don't remember mentioning end-to-end tests)

odd turret
#

yeah, I mean, you mentioned running the game for testing, so I figured you're were talking about end to end testing

bleak marsh
#

Not really, wait a moment

#

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...

β–Ά Play video
#

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 :)

β–Ά Play video
odd turret
#

or any different at all

bleak marsh
#

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

bleak marsh
odd turret
#

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

bleak marsh
# odd turret you could also have integration tests, but I don't see why you would need to ful...

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.

odd turret
#

depending on your architecture you have game logic decoupled from presentation "for free"

bleak marsh
#

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

odd turret
#

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

bleak marsh
#

I guess I'm not familiar enough with this architecture to see it as equally easy to what you would typically do in Unity

bleak marsh
odd turret
#

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

bleak marsh
#

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?

bleak marsh
bleak marsh
odd turret
#

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

bleak marsh
#

The only difference is that you skip the input (partially) and rendering

hushed fable
#

Playdead (Limbo), Call of Duty and Facepunch does integration tests of some kind.

odd turret
#

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 πŸ˜†

hushed fable
#

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.

odd turret
#

I recall reading somewhere about those CoD tests, at least for performance

bleak marsh
bleak marsh
hushed fable
#

Sometimes it's helpful to just know that there's a significant difference.

bleak marsh
hushed fable
#

One fragile test I have experience with is whether the project compiles or not πŸ˜„

odd turret
bleak marsh
hushed fable
compact ingot
bleak marsh
bleak marsh
odd turret
#

yeah, I'm currently working on a turn-based RPG in a personal project and ECS at work πŸ˜‚ did some mobile puzzles before

hushed fable
odd turret
#

I guess it probably gets very difficult to decouple the layers if you interact with physics stuff

bleak marsh
#

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

odd turret
#

authoring is fine, you just need a way of mapping the logic entities to the visual entities
configuration can be provided from any source

compact ingot
#

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

bleak marsh
scenic forge
#

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.

hushed fable
#

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.

compact ingot
#

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.

bleak marsh
#

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

hushed fable
# bleak marsh That means the designers have enough control to make design happen

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.

bleak marsh
kindred spindle
#

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

sly grove
plush hare
#

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.

kindred spindle
#

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

untold moth
kindred spindle
untold moth
#

Why reinvent the wheel? You'll probably not be able to make it better than a team of professional engine developers.

untold moth
kindred spindle
#

I already made it, now I just need to solve the data corruption

#

When you use ecs it struggles at millions of tiny voxels

untold moth
#

If it doesn't work, it doesn't count as "made it"

kindred spindle
#

I wish I could use ecs honestly but my task requires I reinvent the wheel

untold moth
#

Anyways, if you need specific help, you should share more details on your setup and code.

fringe root
#

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

stuck plinth
echo coral
untold moth
fringe root
#

Yeah, i guess parsing save files is actually a thing.
thanks for the inputs guys

exotic trout
#

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

mellow plinth
#

Did anyone ever happened that when calling .Schedule for a Unity jobs sometimes the editor freezes or am I the only one?

weary kraken
#

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?

sly grove
dusty wigeon
weary kraken
dusty wigeon
#

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)

weary kraken
#

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.

https://depts.washington.edu/acelab/proj/dollar/index.html

echo coral
#

woa that is cool

dusty wigeon
#

You could also develop your own AI with sentis that being said.

weary kraken
#

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)

dusty wigeon
#

Probably one of the most out of the box usage for it

weary kraken
dusty wigeon
#

Also, you should proably test it because things like that happens

echo coral
#

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

weary kraken
#

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.

dusty wigeon
dusty wigeon
#

It's not an AI model

weary kraken
#

Ahh, so it depends on an external AI model, you mean.

dusty wigeon
#

My point was more about creating your own model though.

proven oxide
# weary kraken 100%. Though this, I think, is intended functionality. There's built-in recognit...

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.

exotic trout
#

melting kermit the frog be like:

fierce oracle
#

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

fierce oracle
#

I'm planning to use the zstd compression algorithm for this

novel wing
#

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?

muted root
#

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.

somber swift
echo coral
#

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

somber swift
#

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

echo coral
#

Yea id like to hear the actual problem where a new texture is required

muted root
#

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.

somber swift
somber swift
# muted root Well, I'm using the lit layered shader and I'm creating various textures with a ...

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)

echo coral
#

If you have a custom shader you can do tiling in there anyway, its very easy

fresh goblet
somber swift
exotic trout
#

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

somber swift
#

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

glacial pawn
#

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 !

sage radish
# glacial pawn Ummm, I'm someone who passed the beginner stages recently, I don't find most 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.

glacial pawn
# sage radish I'm sure you've heard this before, but the most efficient way to learn how to ma...

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 ?

muted root
# somber swift I'm not fully confident I fully understand the type of system you are aiming for...

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.

muted root
echo coral
grizzled valve
#

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;
finite pond
#

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)

bleak marsh
#

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

finite pond
finite pond
#

Exactly by the placement delay

bleak marsh
#

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

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

bleak marsh
#

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

finite pond
#

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

bleak marsh
#

@finite pond // Wait, SetAnimationTime does not work at all?

finite pond
#

ill try a few more permutations

bleak marsh
#

πŸ€”

finite pond
bleak marsh
#

For the record, I never worked with animated tiles. I'm just doing educated guess work based on the docs

finite pond
#

yea, SetAnimationTime itself works fine (used by the waving grass), however the animated water tiles are still broken

bleak marsh
#

WAIT! Another discovery

#

It shouldn't matter according to how the functions work, but let's try it

#

Show me your GetAnimationData function please

finite pond
#
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

bleak marsh
finite pond
#

zamn

#

they really snuck it in there

bleak marsh
#

My guess is that they changed something internally to make tilemaps more performant and probably made syncing animations opt in instead

finite pond
#

right

#

lmao it still doesnt work

bleak marsh
#

Oh...

finite pond
#

yea, even with SyncAnimation being the sole bit thats active on the flags

bleak marsh
#

You removed the SetAnimationTime calls, right?

finite pond
#

yep

bleak marsh
#

Well... that's a bit puzzling

finite pond
#

setting animationStartTime also doesnt affect it

bleak marsh
#

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?

finite pond
#

6000.0.48f1

bleak marsh
#

Got it, tho I can't guarantee I will find time for it

finite pond
#

no worries

#

definitely a big issue lol

bleak marsh
#

Yeah, cool art by the way

finite pond
#

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

finite pond
#

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

bleak marsh
#

Could be some weird batching behaviour, I think in URP you are supposed to just clone the material at runtime instead of using MBPs

finite pond
#

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

bleak marsh
#

Tho I never had property blocks mixing with each other... very weird

finite pond
#

lemme show you

bleak marsh
#

That's wacky

finite pond
#

all unique renderers, all unique MBP instances

#

yep

#

and i couldnt afford not to batch them

bleak marsh
#

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

finite pond
#

thanks for helping me rubber duck debug this issue

plain abyss
#

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.

echo coral
#

is this all done on desktop like win/linux?

austere jewel
echo coral
#

what platforms even use big endian that work with unity though?

plain abyss
#

Is ReadSingle big or little endian?

austere jewel
#

No idea, but you can see your result is big endian

echo coral
#

was this value only changed on some arm system?

plain abyss
#

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

echo coral
#

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

plain abyss
#

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

echo coral
#

thats on x86 right?

#

if so then yea makes no sense when told to be little

scenic forge
#

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?

echo coral
#

Only time ive had this we replaced the file before invoking xcode via fastlane in our build job

scenic forge
#

Hmm, sounds like the same idea just done with an external tool.

dapper cave
#

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

dapper cave
sly grove
#

If you're talking about an object that was destroyed this frame, Unity will not help you detect that

#

use your own bool flag

dapper cave
sly grove
#

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

dapper cave
sly grove
#

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

austere jewel
#

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

dapper cave
# sly grove Have it not crash _when you do what_?

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.

exotic trout
#

are you sure the problem isn't the nuking isn't delayed?

#

object destruction isn't instant

sly grove
dapper cave
dapper cave
# sly grove Showing the code and the error(s) might help

    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...

sly grove
#

I don't see anything that destroys anything here

#

Anyway as vertx said never use is with Unity objects

#
if(agent == null || !agent.enabled)```
dapper cave
austere jewel
#

Unrelated, but you also you have to set the coroutine to null after stopping it, it won't become null by itself

dapper cave
#

that's the one causing trouble

sly grove
sly grove
#

or what object that is

#

or when Push gets called

dapper cave
#

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);
        }
    }```
exotic trout
#

Completely unnecessary side-comment; Probably very slightly cheaper to flip that first if statement right

dapper cave
sly grove
#

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?

dapper cave
scenic forge
dapper cave
#

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?
tall ferry
#

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

dapper cave
exotic trout
#

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?

ebon abyss
#

So it’s simply asking the wrong question

tall ferry
# dapper cave yeah but was of no help because read what I said, the crash is nullref in corout...

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.

dapper cave
#

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.

exotic trout
#

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

tall ferry
dapper cave
tall ferry
dapper cave
dapper cave
#

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

exotic trout
dapper cave
#

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;

tall ferry
tall ferry
dapper cave
exotic trout
exotic trout
#

Physics.OverlapSphere can take in a layermask for object filtering

dapper cave
#

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"

exotic trout
#

I am also team fuck tags πŸ˜„

Sometimes I will use them for very broad content identification though

dapper cave
#

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>()

tall ferry
#

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;
  }
tall ferry
#

by the way you're writing code, i assume you're a big JS fan

dapper cave
exotic trout
#

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;
  }
tall ferry
dapper cave
exotic trout
#

oh right

#

that weirdness

dapper cave
#

what's weird?

tall ferry
#

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

dapper cave
exotic trout
#

Yeah, might just be a personal thing aha

#

it trips** me up sometimes

dapper cave
#

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

exotic trout
#

probably some weirder shit like using a physical material as an object reference to identify ignore explosion objects πŸ˜„

scenic forge
#

Imagine a world where Unity used .IsAlive instead of overriding ==.

bleak marsh
#

-# Also, having a .IsAlive() extension method instead of .IsAlive property would be better if we go that path

scenic forge
#

I've unironically written code like if (someGameObject is not null && someGameObject == null). I'd take anything over that.

bleak marsh
#

== null already checks the C# side null first as far as I remember

scenic forge
#

Yes, but the entire condition is meant to check "there is a someGameObject but it's already destroyed."

bleak marsh
#

Oh right. not null. My bad

scenic forge
#

It would read so much better if the someGameObject == null was instead !someGameObject.IsAlive or someGameObject.IsDestroyed.

bleak marsh
#

Curious, when did you need that?

scenic forge
#

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.

echo coral
#

destroyCancellationToken can be useful for being notified of a destroy (and ofc to use with async things)

scenic forge
#

Yeah the code was written before that was a thing.

echo coral
#

UniTask has a component that implements this for versions without this

sage radish
echo coral
bleak marsh
#

Okay, so we have a few common scenarios:

  1. Is object destroyed on Unity side? (the most common scenario)
  2. Is object destroyed on Unity side but alive on C# side?
  3. Is interface instance destroyed on Unity side if it's a Unity object and null if it's a Plain C# object?
  4. Is object destroyed 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

exotic trout
scenic forge
#

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.

echo coral
#

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"

scenic forge
exotic trout
#

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

echo coral
#

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

bleak marsh
#

With current implementation those cases look like so

  1. obj == null
  2. obj is not null && obj == null
  3. obj == null || obj is UnityEngine.Object uObj && uObj == null
  4. obj == null || obj is UnityEngine.Object uObj && uObj == null

With IsAlive property it would be just awful

  1. obj == null || !obj.IsAlive
  2. obj != null && !obj.IsAlive
  3. obj == null || obj is UnityEngine.Object uObj && !uObj.IsAlive
  4. obj == null || obj is UnityEngine.Object uObj && !uObj.IsAlive

With an extension method like IsAlive()it could be slightly better

  1. !obj.IsAlive()
  2. obj != null && !obj.IsAlive()
  3. !obj.IsAlive()
  4. !obj.IsAlive() (depending on the implementation)

But to be fair, you can write such extension yourself in the end, @scenic forge

echo coral
#

you could still do obj?.IsAlive() if you want to check for actual null

scenic forge
#

You can also use pattern matching.

bleak marsh
scenic forge
#

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.

exotic trout
#

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?

echo coral
scenic forge
#

I care less about IsAlive vs IsDestroyed, either one is better than nothing.

bleak marsh
bleak marsh
exotic trout
bleak marsh
exotic trout
#

Sure but Unity uses c#

stuck plinth
exotic trout
#

if im dealing with monobehaviours and base classes ideally i wanna treat them the same way for something like this

bleak marsh
exotic trout
#

It's less about correctness and more about consistency

bleak marsh
exotic trout
#

For a majority of people using Unity how often do you think they are casting to object

stuck plinth
bleak marsh
#

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 ?

bleak marsh
stuck plinth
exotic trout
#

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

echo coral
scenic forge
#

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.

ebon abyss
bleak marsh
#

Oh yeah, you actually can't, @stuck plinth.
To think I used Unity for years now and never ran into this issue UnityChanSalute

stuck plinth
bleak marsh
#

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

ebon abyss
#

You have to cast to Object and then check for null

bleak marsh
bleak marsh
echo coral
#

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 😐

scenic forge
#

obj is GameObject { IsAlive: true } πŸ˜„

bleak marsh
#

Also, regarding interface shenanigans. Reminder that
Foo<T>(T bar) where T : IBaris technically faster (in some cases) than Foo(IBar bar)
:P

echo coral
#

well duh, the generic method is generated for uses

ebon abyss
bleak marsh
bleak marsh
ebon abyss
#

I think IL2CPP does it in any case.

#

Not 100% certain

bleak marsh
#

Oh, migth be. Never decompiled IL2CPP

ebon abyss
#

There's a huge list of generated generics in the intermediate C++ source

echo coral
#

il2cpp cannot do runtime generic creation from what I remember

ebon abyss
#

Unless you do something crazy with reflection (which IL2CPP doesn't like), it's going to be known at compile time anyway

echo coral
#

yea generics should be produced per use, especially in c/cpp

#

who knows what happens in cursed managed cpp land

bleak marsh
#

Oh god... Cpp templates ;-;

sage radish
#

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.

#

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.

ebon abyss
#

9 gigabytes of C++ source code is a phrase straight from my nightmares

exotic trout
#

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?

sage radish
#

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?

exotic trout
#

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

sage radish
#

Oh, an instantiated generic type. I thought you meant:

public interface ScriptableInterface<T>
{
    [RuntimeInitializeOnLoad]
    private static void OnInit()
    {
    }
}
exotic trout
#

Yeah that is what i am doing

#

i just figured the existance of defining it would allow that type to exist

sage radish
#

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>();
}
exotic trout
#

I wasn't aware that would be an additionl step so fair

exotic trout
#

oh right i understand now

#

Though the fact i have it defined explicitly puts me in the middle of reality and that example right

bleak marsh
#

@finite pond // Okay, I did some testing

#

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 */));
finite pond
#

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)

bleak marsh
#

As in edge tile and corner tile exist as separate assets

finite pond
#

no

bleak marsh
#

🀨

#

How?

finite pond
#

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);

bleak marsh
finite pond
#

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;
}
bleak marsh
#

I mean the code for getting the tile. Not animation data

finite pond
#

the sprite variant you mean?

bleak marsh
#

Maybe?

#

I'm trying to decipher what the code is actually doing and how it could in theory break

finite pond
#
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

bleak marsh
#

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?

finite pond
#

no

#

its not

#

should i try 1?

bleak marsh
#

Nah

bleak marsh
#

Basically, this copy pastes the animation time from one water tile to another

#

You just have to know where any other water tile is

finite pond
#

sounds like a ridiculous workaround but ill try it sure

finite pond
bleak marsh
#

Okay, time to do some debugging then I guess

finite pond
#

i have one idea

bleak marsh
#

Go on

finite pond
#

nvmd

#

lol

#

didnt fix it either

bleak marsh
#

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?

finite pond
#

one sec, last idea i have

bleak marsh
finite pond
#

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

bleak marsh
finite pond
#

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?

bleak marsh
#

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

finite pond
#

right

bleak marsh
#

Not sure

finite pond
#

yea im trying something rn to validate my assumption

#

yea, assumption wasnt correct

#

the workaround it is

vague flame
#

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

untold moth
vague flame
#

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

untold moth
#

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.

echo coral
#

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.

ebon abyss
echo coral
#

Every semi modern device has multiple cores/threads but all non ancient operating systems use time slicing.

vague flame
echo coral
#

ECS is the only viable option

vague flame
#

and thanks for everyone's answer for MT, i guess ill use it if i got time for heavy workloads

echo coral
#

Why? You cannot use a managed thread to modify a Transform so ECS is the only way to do something like this πŸ‘

vague flame
#

is MT used by default with ECS ?