I've done a lot of tutorials recently about how to you know use your character move your
character that kind of stuff but let's do a video about how to interact with the world
let's uh talk about buttons in vr this is going to be one of the most basic
go-to ways that the player is going to interact with your world you want to have be able to
press a button you want to have a console with a whole bunch of different things on it and
all that kind of stuff so today we're going to talk about how to do a normal physics based push
button so without further ado let's jump into it out of like the other videos where we completely
start from scratch I'm actually going to copy and paste one of the old tutorial videos that I did
about the physics hands so I'm just going to copy and paste that into this folder and rename it to
physics button and now I can open up unity and we're going to add a new project and then find
that project physics button select the folder and select the new version that I just downloaded
confirm and this is going to put us right where we left off with the physics-based hands tutorial
so if you have not seen that video check that out up here I'll link it just so you can get caught up
to speed and then catch up with us here now when you first load it up it's not going to load on the
correct scene so we're going to click on scenes and click on the sample scene and that's going to
bring us into where we left off with this table and grabbable cube we're just going to go ahead
and delete both of these won't be needing that and then I've also noticed that you need to do
one thing in the project settings just to update it to the newest version just go into xr plugin
management click on this little exclamation point next to open xr and then click fix all and that'll
fix any issues from the last version to the new version so I'm going to go in here and create a
3d cube object set the transform back to zero and this is going to be a pedestal for a button to
sit on pedestal and I'm just going to resize this so it looks like a actual pedestal you know and
then let's grab that blue material and make the pedestal blue all right now let's make button so
we're going to make a new empty game object we're going to call this one button and then inside of
the button we're going to create another 3d object and this one's going to be a cylinder and we're
going to scale this one down try not to move it on the x y or z axis just on the scale we're going to
move the entire button with the parent button game object so make sure everything else underneath it
is set to a zero position rotation so if you need to reposition just go back out to your parent
button and reposition it and this is going to be the base so we're going to rename it to base
and this base comes with a capsule collider but we're actually going to remove that and then we're
going to add a mesh collider and set the convex to true and then we're also going to add a rigid body
and we're going to set this one to is kinematic just so that it doesn't move around while we're
hitting it with physics all right now we're going to make a new game object inside of button and
this is going to be called push make sure the transform is set to 0 and then we're going to
go back out to the base press ctrl d to duplicate it and then put it inside of this push game object
and then we're going to rename this new base to uh clicker and the clicker is just going to be
the visual part of the button so we're going to remove the rigidbody remove the mesh collider
and we're going to scale it down just a little bit and then go back out to push and you can move the
bush game object up so it looks like a button and then we're gonna take this other material and drop
that on the button and I'm actually gonna turn it into like a red color that looks better so now we
have a little button object but right now if we were trying to push it nothing would happen we
need to do a few more things onto this push game object first we're going to add a box collider
and scale this down 0.1.1.1 it down a little more just enough so it covers most of the surface area
of the pushable part of the button and if you want to get super detailed with it you can add another
smaller box collider inside of these little areas here but for the purposes of this tutorial it's
totally fine you can mess around with different kinds of colliders here I'm just going to use a
box collider because it's easy now we're going to add a configurable joint and this is what's
going to join the base to the top and allow the spring action when you press down the button so
let's go through this bit by bit a configurable joint will actually mimic any of the other kind
of joints so springs or hinges or anything like that you can mimic each one of those joints from
the configurable joint and we might have been able to use a spring joint with this or a slide joint
or something like that but we're just going to do configurable because that's the one i know how to
do it with this connected body is going to be the base and the base has to have our rigid body in
order to go here the anchor we're going to auto connect it and then each one of these motion and
angular motion values we're going to set to locked except for the y motion the y motion is going to
be limited everything else is locked this will allow us to move the push part of the button
up and down in a limited um range and that way it can't get pushed all the way through the base and
it can't be released up above and give us some weird behavior and then linear limit is how far
the button can get pushed down and we're going to do a small amount like .015 or something
like that we can adjust this later and then last thing inside of this configurable joint
is the y drive we're going to set the spring to 50 and we're going to set the dampener to 10 and so
this will be the velocity that it balances back up with and the dampener is preventing that kind of
springiness at the top let's go back to the rigid body we're going to want to uncheck use gravity
and then for constraints we want to freeze all of the rotations the configurable joint also helps
with this but we're never going to want to move the x y or z so we're going to freeze all of those
and everything else here is fine as it is and now if you were to play I'm just going to switch back
into scene view with the game playing and you'll see that the button will bounce up and down and if
you wanted to play with the threshold you go back into rigidbody and click use gravity that'll push
it down to the minimum and then you can adjust it using the linear limit and so you can set the
bottom limit of the button here and I'm just going to keep it at 0.015 because that's that's a pretty
good spot we've got the actual physics of the button working correctly now we just need to make
it actually trigger an event whenever we press so to do that we're going to need to make a custom
script I'm going to call this physics button let's start by adding some events we want a on
pressed in an unreleased event this is going to be public unity event on press and then we can do
two in the same line by adding a comma type in on released unity event will need to be added with a
using statement so with my ide I can alt enter and it'll give me suggestions if you're using visual
studio you can press control period that'll give you some suggestions or you can just type in this
using statement using unity engine.events here at the top let's add a couple configurable variables
these will be serialized field and private we want a threshold value so this is going to be a float
threshold and we're going to set this to about 0.1 float this value you can set in the editor
because of the serialized field portion and it's going to be the percentage of the button press
that is going to be needed to activate the button and we're going to make another serialized field
also a float and this is going to be a dead zone I'm going to set this to zero two five float and
this like with a uh any joystick controller it's a dead zone in the middle where if there's any kind
of bounciness there at the end it's not going to press and release the button a whole bunch
of times so this is just to prevent any of that and then we're gonna want three private variables
we want a private bool is breast we're gonna want a private vector three start position and then a
private configurable joint and we're going to call this one joint is pressed is going to keep
track of if the button has already been pressed so that way we don't send the on pressed or on
released event over and over and over again every frame it's only going to happen once
so this is basically our state management the start position is going to help us compare the
start position to the current position to tell how far the button has moved and then the configurable
joint is obviously the joint and we're going to get the linear limit from that let's go into the
start method we're gonna set our start position equal to the transform dot local position it's
important to use local position and not the dot position because those are two different things
and then let's set our joint that's going to be equal to get component configurable joint
all right in the update method this is where we're going to determine when we're going to call the on
pressed and on released methods so let's actually create the those methods first so these are the
two methods we want to call when the button is pressed or released inside of these we're going
to want to set these pressed variable and then we're also going to want to call the appropriate
event so when it's pressed we're going to set is pressed equal to true and we're going to invoke
the unpressed event and then we're also going to add a debug statement just so that we know our
code is working and then I'm going to copy this move it into the released method and change the
appropriate values so is pressed will be false and we're going to be invoking on released and instead
of logging press we're going to log released all right how do we know when to call these methods
well in the update method first we want to check to see if is pressed has not been toggled before
so we're checking for the case where the player has just pressed the button down but we haven't
registered it yet so if is pressed is not true and we also need to check to see if the button
position is in the right spot to do that we're going to make a method called get value and I'll
go over that in a minute we're going to use that value plus the threshold and see if it's greater
than or equal to one and if so we're going to call pressed and then we do the opposite how do we tell
if the player has just released the button we're gonna check to see if is pressed is true and the
value minus threshold is less than or equal to zero and if that's the case we're going to call
released so let's make this get value method the reason I'm doing this instead of just getting you
know the difference in the values is because we want to actually be able to have multiple kinds
of buttons and multiple sizes multiple you know push depths that kind of thing so in order to
do that we're going to standardize the distance to a percentage so the percentage is going to be from
zero to well actually it's gonna be from negative one to zero to positive one based on you know the
spring pushed in or the spring released but in this case the dampening should prevent the button
from getting you know pulled back out so let's do a private we're going to return it float get value
so inside of here we're going to create a variable called value and that's going to equal a vector
3 dot distance and the distance between the start position and the current local position so
transform.local position and then in order to get the percentage we're going to divide that by the
joint linear limit we're going to call joint linear limit dot limit and then we're going to
check for the dead zone so if math.abs of value is less than the dead zone then value is going to
be equal to zero so if it's within that small number it's just going to set it back to zero
and then we're going to return a clamped version of this mathf.clamp value between
negative one and positive one and that just prevents any weird numbers that pop up there
we go and now we can test it with the pressed and released debug logs so make sure to save your code
let's go back into unity you'll see over here with the physics button now we have a threshold
and dead zone that we can manipulate and then also we have an unpressed and unreleased event
that we can add any kind of object or thing so if we wanted to you know turn a light on and
off we can put the light object in here and then have it turn off or on based on if the button is
pressed or released you know normal unity event stuff so let's hit play run this just go back to
scene view click over to console and then when i push this down push the push down you'll see
the released and the pressed and then we can swap over to vr and try it with the physics too
and you'll notice that each time we press that the console is registering the pressed and the
released so in the case that you add an event to this the event will also get fired off whenever
the pressed or the released happens and from here you can play around with the threshold how much
do you want the button to be pressed down you can play around with the limit that we talked
about earlier before the code and the dead zone all that kind of stuff and this can be picked up
moved around you can reposition it turn it rotate it whatever it's going to work exactly the same no
matter what you do to it so you can use this for doors escape rooms have fun with it and
let me know what you do with it there you go a working physics based push button can I just say
what an amazing support you guys have been since I've mentioned Patreon last week I've
gotten such an overwhelming support from you guys this has been incredible and on that topic we are
doing a Patreon live stream next week and I think we're just gonna do a private zoom call
small group of people we're just gonna talk about you know what projects you're working
on what projects I'm working on in the future you know a fun discussion for an hour or so so
if you're interested in jumping in on that check out my Patreon consider supporting
it would mean the world to me and if you just want you know the source project the project we
talked about today or any other previous project it's all available there as well and I want to
give a shout out to the newest VIPs on Patreon Eva and Jane thanks so much for your support
and Tim and Austin your continued support blows me away I am so appreciative of everyone on
Patreon thank you so much and as usual free of charge I reply to every single comment on any
of my videos so if you run into any bugs or any issues or if you just want to chat just throw a
comment out there and I will reply as soon as I can and I'll see you guys in the next video