Yellow-Dog-Man / Resonite-Issues

Issue repository for Resonite.
https://resonite.com
134 stars 2 forks source link

Prevent Joint/KnobControl/Slider from being duplicatable/destroyable by default #1995

Open KamilaTech opened 4 months ago

KamilaTech commented 4 months ago

Describe the issue?

Regardless of component configuration; a jointed sub-object is treated as its own entity in regards to deletion.

[Edit by Shifty]: It is a very common workflow to make use of Joints/Sliders/Knobs for elements in a world that are meant to be interacted with, but kept as part of the world, e.g. doors, windows, control knobs, etc.

Requested is some mechanism to prevent being able to duplicate/destroy newly made Joints/Knobs/Sliders by default rather than needing to manually add DestroyBlock and DuplicateBlock to these objects.

To Reproduce

// All naming is for explanation sake and holds no bearing on reproduction of the bug

1: Establish 'Object1' under Parent 'Object2' 2: Setup joint component on 'Object1' (*Ensure existing grabber is removed) 3: Grab and hold Jointed 'Object1' 4: Delete Jointed 'Object1' 5: Observe as it is separated and deleted from its parent object.

Expected behavior

Don't let me delete your door handle...

Screenshots

No response

Resonite Version Number

beta 2024.5.4.678

What Platforms does this occur on?

Windows, Linux, Android / Quest

What headset if any do you use?

Desktop, ViveProEye, Quest Pro

Log Files

FLOCKPC - 2024.5.4.678 - 2024-05-06 22_52_28.log

Additional Context

No response

Reporters

Kamila~Avali & Ikani

Frooxius commented 4 months ago

In this setup, is the Object2 completely empty? No components on it at all?

In some cases this is normal - e.g. if you have a ObjectRoot present on it. You can either add ObjectRoot on the child or put DestroyBlock in between the child and parent.

ikanimew commented 4 months ago

In this setup, we created two boxes (from the create menu), parented Object2 under Object1, deleted the Grabbabble component from Object2, then added the Joint component to Object2. We did also try adding the DestroyBlock component to Object2 and that did block destruction.

Frooxius commented 4 months ago

Can you show me the components present on Object1 (the parent)? Does it have ObjectRoot on it?

ikanimew commented 4 months ago

Object1 has the following: BoxMesh, MeshRenderer, BoxCollider, ValueCopy, and Grabbable Object2 has the following: BoxMesh, MeshRenderer, BoxCollider, ValueCopy, and Joint

I just ran a test with ObjectRoot added to Object1, Object2, Both and Neither. I was able to delete Object2 all four times.

shiftyscales commented 4 months ago

This is because a joint acts as a different kind of 'grabbable' interaction- same with sliders.

The way this is typically resolved is to make use of the DestroyBlock tagging component on the interactive item you do not want to be destroyed. This is also usually best paired with DuplicateBlock as well so doors and other interactive elements can't be duplicated either, @KamilaTech @ikanimew.

As far as I can see based on the descriptions provided- this is the object just not being set up properly with the additional needed components to prevent it from being destroyed.


If you believe otherwise, please submit video, or a replication world that depicts the issue you are describing and I can re-open this issue, and look into it further.

ikanimew commented 4 months ago

Alright, well then let's call this a UX issue and feature request, if it's not a bug.

Joints, Sliders and Knobs should have an option within the component that controls whether they are destroyable or not, with a default of not.

An alternative I could see would be to automatically add DestroyBlock and DuplicateBlock components when adding a Joint, Slider or Knob. This would make the default operation be what's expected (not deleting these objects) while still allowing the user to adjust as desired.

shiftyscales commented 4 months ago

I agree it is significantly less common that users would need/want to destroy an object that makes use of those other interactive elements. So it could be a good QOL change to ensure they aren't destroyable/duplicatable by default.

Of the two options listed- I think the more likely/better option would be to auto-attach the Destroy/Duplicate block components when a Joint/KnobControl/Slider is attached. This has precedent with other components can attach multiple components as needed for their purpose/use, and also makes it easy to clean-up/remove the Destroy/DuplicateBlock component later while re-using an existing component rather than re-writing/re-implementing the same functionality that already exists.

Seeking input from @Frooxius or @ProbablePrime.

Frooxius commented 4 months ago

I'm not fully sure if we can do this change neatly. It's making some assumptions on how these components will be used and generally for simple interaction components like this, we do not add any extra stuff, unless it's necessary for their function.

If we make this change, then it sets an odd precedent - say when these components are being constructed from the code (which later will be in-game too, with components access) and you're setting up your own structure, you have to remember (and add additional code) to cleanup these components.

That's a bit of a "dirty" way to approach something and for something simple like this, we'd generally avoid it.

The only way I can see this working is if we extend the attach system, so there's separation between "manual attaching" through inspector and just programmatic attaching and that's how we differentiate the behavior, but that needs additional general handling.