- Home /
[SteamVR] Drum physics
Sorry if this is a rookie Unity thing to ask. Clearly I need some education on Unity physics. I've searched around but can't seem to find what I'm looking for.
I've got a tracked object with capsule collider (tip of the drum stick) and rigidbody. I've got a drum surface which is basically a one-sided mesh I created with a mesh collider on it. The fact that this is SteamVR and tracked controllers may not even matter for this question, but that's my case.
Naturally I want the drum surface to trigger and play a sound when struck from the top but not when struck from any other side. So in VR the controller does not physically impact against the surface so it will pass through the surface. So the surface gets triggered on the up stroke so I get a double beat effect, when I only want the down stroke.
I thought my one-sided mesh would mean that collisions/triggers would only happen when the controller capsule collider hits the surface from the top since the mesh it one sided, but I seem to get triggered from both sides.
I may end up writing some code to convert the capsule collider hit to the drum surface local space and compare, but I'd rather it just worked.
Any advice on how to set this up properly would be of tremendous help.
Thanks so much.
Answer by EdwinChua · Aug 14, 2017 at 03:49 AM
This is more of a suggestion than an answer, but you could check if your capsule collider has a negative-Y displacement in the collision event. This would ensure that the sound is only triggered when the collider is hit, while the capsule is moving downward.
Using the OnTriggerEnter event (i.e. this script has to be attached to your drum surface):
public class yourClass()
{
bool movingDown;
public GameObject yourCollider; //assign this in Unity
Vector3 currentPosition;
void Update()
{
if (yourCollider.transform.position != currentPosition)
{
if (position.y < currentPosition.y)
movingDown = true;
else
movingDown = false;
currentPosition = yourCollider.transform.position;
}
}
void OnTriggerEnter()
{
if (movingDown)
{
//Play sound
}
}
}
With regards to specifics about VR, I probably wouldn't be able to assist you very much, but this should give you a gist.
Check out this tutorial on scripting with colliders https://unity3d.com/learn/tutorials/topics/physics/colliders-triggers
Answer by timrbetts · Aug 14, 2017 at 01:14 PM
Thanks for the reply man. Can you elaborate? Is there a property in the collision event I'm missing or do you mean comparing the transform position of the drum stick tip collider with the the transform position of the drum surface?
The calculation would have to transform the capsule collider transform position into the local space of the drum surface because the drum will never be in a perfect vertical orientation in world space. I'm not sure what this calculation is but I believe its some form of drum surface.transform.TransformPoint(drum stick tip.transform.position)?
Updated my answer with sample code. Hopefully this will give you something to start with.
Thanks so much for the example code man. I'm actually trying the 2 collider approach below for now, but I still may end up having to use something similar to your code if I have issues, so I'll let you know.
Answer by Carlotes247 · Aug 15, 2017 at 02:03 AM
If I understand properly, you might just want to increase the size of your trigger collider so that when you hit it from top you are still in it when you go through the mesh of the drum.
If you want to avoid the user to play the drum from the wrong direction, you could have 2 triggers that condition each other, one at the top of the drum (A) and another at the bottom (B) (you can't activate A if B has been activated already && you can't play A again if you hit B).
I hope it helps!
Thanks for the idea man. I tried the two collider approach last night. I have 3 colliders, A above the surface, S the surface itself, and B below the surface. I have code in OnTriggerEnter/Exit in A and B to enable/disable the other collider, so I can record which direction the hit came in from when the OnTriggerEnter occurs for S.
This almost works and I like the setup since I don't have to worry about whatever orientation the drum might be in. The problem I have appears to be that on a fast moving pass through the colliders and the drum surface, the Enter/Exit on A and B don't always appear to fire and/or if they do then the Enter doesn't occur on S, so the logic fails.
I've tried everything as OnTrigger/triggers and everything as OnCollision with rigidbody's set to Continuous Dynamic, but still hit and miss (no pun intended). Naturally the drum stick tip is also a capsule collider with rigidbody set to Continuous Dynamic.
Any suggestions on how to guarantee the events always fire?
You are welcome! $$anonymous$$aybe you can try making the colliders bigger? Last VR project I did that was the solution I used. However, we had the luxury to work with fantasy objects with unrealistic sizes.
Another option is to implement your own collision detector based on distance. That also has proven to work for me when I have smaller objects. Just check the distance to the target and when is below certain value, you trigger the event,
Let me know what solution you find! Is relevant to all of us working in VR :)
Your answer
Follow this Question
Related Questions
When and when not to use kinematic rigidbody? 2 Answers
Disabling VR Camera rotation creates ''cinema'' effect in VR device 1 Answer
Tripod with realistic physics in VR 1 Answer
ConfigurableJoint Target Position/Rotation Issues? 1 Answer
Child Movement Goes Haywire - VR - Controlled using custom bluetooth controller 0 Answers