What's up everyone,
as you have so astutely figured out, we were talking about how to move like you would in grill
attack. Gorilla tag, if you're not aware is a super fun VR game that was released on App Lab and
is now on Steam. It's a, you know exactly what it sounds, you're a gorilla. And you're playing tag
and a multiplayer environment. And you move around by grabbing limbs of trees and throwing yourself
up and bouncing off walls and whatnot. It's a very fun physics base kind of movement. When I was
building the test project today, I actually hung out inside of my little arena that I made for like
a solid 20 minutes just bouncing off walls and stuff. It's so much fun. So today, I'm gonna show
you how to do it. First, we're going to open up a VR project, if you'll notice unity hub actually
got an update, we're in 3.0 now, and a few things have changed. There is a dark mode now, which is
super cool. They've also changed the names of some of the buttons and how you start a new project. So
you'll notice over here open this used to be add now it is open and you can add from a project from
your computer or a remote project now and then there's also a New Project button now, so we can
click on that and it's going to bring us through this little portal and make sure you are selecting
the correct version up here at the top. So we're going to be using 2021 point 2.7 which is the
newest released version, and I'm going to go down and actually select the 3d USRP. So without the
sample scene, we now have the option to start a VR project without the sample scene in new RP, which
is the render pipeline I recommend you use for any VR project. At this point, we're going to set up
XR I've already done a full length video about how to set all this up and why you do certain settings
and why not this is just gonna be a really quick overview of like a refresher, if you already know
how to do it. If you want a more in depth video, then just check out the one in the top corner
if you already know how to do it skip to this timestamp. Also, there's chapters down below and
that's where I actually start to do this specific tutorial. Alright, for XR, we are going to go
to Edit Project Settings go down to XR plugin management and install XR plugin management, I'm
only going to do this project for PC. So we're only going to be on this PC tab here, I'm gonna
click on Open XR to install that it's going to ask if you would like to restart your project and swap
it over to the new input mode. So just hit Yes, it'll restart unity, then we're going to go
to Open XR and then I want to add a couple of interaction profiles. I'm gonna do Oculus
Touch and Valve index for this particular one. And then I'm going to swap the render mode over
to multipass. Now we go to the package manager, so Windows package manager and then click
on this plus icon and add package from get URL and we're just going to type in C
O m.unity.xr dot interaction toolkit hit Add and that's going to install the XR
Interaction Toolkit package there'll be a pop up that says there was a major change and
we'll break any older versions of this toolkit that you have used. Since this is a new project
we can just say go ahead and then we also want to install the samples so click on sample drop down
and import the default input actions sample. And then now we have a samples XR Interaction
Toolkit folder and then whatever version we downloaded and then just drill all the way down
to the bottom of those folders and then I'm going to add each of these presets should be five total
snap turning continuous turning left and right hands and then one more setting we need to do fix
is going to Edit Project Settings and then in the preset manager, these are all the presets that we
just added. I'm going to specify right and left where the left arrow head controllers are. And
now I can right click in the hierarchy go to XR and XR origin extra paste now to my project, and
it also adds an XR interaction manager that we need to add an input action manager to and then
we're going to click on the action assets in add in the XR I default input actions assets go into
the XR origin and the left and right ends just to make sure we set up the references correctly. And
yes, those are correct. So there we go, we have a XR scene setup. So the way this is going to work
is we're going to use two different formulas. One of them is a PID controller, which stands for
proportional integral derivative controller, which essentially is very fancy terms for we apply
physics to the rigid body in order to get it to go to a specific point. So how quickly can it get
there without kind of doing the rubber banding thing where it tries to hit that point, but then
overshoots it and tries to come back to it again, PID all PID does is make it kind of do a smooth
like goes really fast if it's far away, but as it gets closer, it slows down until it gets to the
exact right point that you want it we're going to use this formula to track your controller with
a physics hand where you move your controller, the physics hand will go but if it collides
with something, it's not going to go through that object, feel free to browse the wiki page
for this. There are some complex formulas that I don't really understand. I'm just going
to copy and paste some code and you can copy and paste it as well. The second formula we're
going to use is Hookes law, which is basically the formula for springs and we're going to use
springs to or basically to attach a spring and a visible spring to our physics hands and that will
allow us to push off of the ground and kind of press up against walls or do the pinch climbing
and whatnot. So we're going to use friction and Hookes laws springs to allow us to move
ourselves, this formula is a little less complex, but feel free to check it out. So first things
first, let's make a ground and have some physics hands and be able to touch things but not have our
hands go through the ground, that kind of thing. So I'm going to first just turn off the skybox. So
things are a little easier to see. And then we're going to add a ground layer. So a 3d object lane
will be called the ground. And then let's create a material and this will be the ground mat, and
we'll make that a grayish color as well drop that on to the Alright, let's add in some hands. So I'm
going to right click create an empty game object, we'll call it the physics XR rig. And under
this, we're going to add first I'm going to make sure all of these are set to the center
of the mapper and then on the physics XR rig. Underneath that we're going to create a 3d
object queue. And this is going to be hand left and scale this down really small to something
like point one 2.1 and point one, bring it up above the ground. So we're not immediately
clipping, we're also going to want to add a rigidbody on to this. And we want to increase
the mass a little bit because that'll allow us to throw ourselves a little better. And then we
also want to change interpolation to interpolate and collision detection to continuous dynamic
because this is going to be moving quite fast and calculating lots of a lot of physics. So we're
gonna create a scripts folder. Also, I'm going to create a Materials folder to add this ground
material into and then inside of the Scripts folder, I'm going to right click Create a C sharp
script and this is going to be physics hand, we can add that script to our left hand after
unity renders everything. So just drag and drop the script onto the hand. And then I'm
going to click on the hand and the hierarchy, press Ctrl D to duplicate it and rename this
one to hand right now we have both our physics hands. So one more thing we need to do before we
jump into the code. And that's prevent the hands from interacting with each other and prevent
them from interacting with the player as well. So I'm going to hold down Control and click on the
other hand. Now I have both selected, click down, click on layers, add a layer and on layer eight,
I'm going to add a layer layer. I don't know why I always add it to layer eight, but usually it's
just layer eight, grab both of the hands again and then set the layer to player and then on the XR
origin we're going to add a Absol lighter who the camera and the capsule colliders radius is going
to be something smaller like point two, five, and then the height could also be a little bit smaller
too. So point seven, maybe something that's tall enough that like picks you up off the ground, but
short enough that you can actually reach down to the ground. And I'm going to grab the whole
XR origin and bring it up until the capsule collider is above the ground. That way we don't
just click through and drop to the bottom and then we're going to grab the main camera again where
the capsule collider is set the layer two player and then we're going to back out to the XR origin
and add the rigidbody here because any forces we want to add to our XR rig, we want to add it to
the entire XR rig, not just the head. So we're gonna put our rigid body all the way out on the
parent object. And same thing for this rigid body we're gonna make interpolate be interpolate and
collision detection be continuous dynamic. Also, we need to freeze the rotation of this one or
else you'll just fall right over when you start the project. All right, this should be set up for
our hierarchy and whatnot. Now we just need to add the PID formula to our physics hands to have it
track our controllers. So I'm gonna double click on physics hands open that up. And the code editor
I'm using is called writer, it's from JetBrains, I highly recommend using this for unity are all
of your projects play, it's a really, really nice IDE. So highly recommend it's free for students.
And also I think there's a one to three month free trial too. So I'm going to clean the script up
a little bit before we start, delete these two USING statements, we're not going to use delete
the comments. And then we're going to change the update method to fix update because we're going
to be using a lot of physics stuff. Now I'm not going to pretend to understand how PID works, the
formula or the interworkings or anything, but I do know we need access to a couple variables for
PID. And we also need access to the hands rigid body. And we also need access to the players rigid
body. So I'm going to create a private rigid body variable called rigid body for the physics hands
rigid body, serialized field rigid body player rigid body. And I'm going to create a header and
call this PID so we can see it a little better in the inspector. And then when we start, we need
access to that rigid body that we just declared. So rigid body is going to be equal to get
component rigidbody. And we're actually going to adjust the max angular velocity on the rigid
body to be infinity. So basically, whenever it caps out as when you're turning your hand really
fast, if you find it being slow, like I think on my last physics hand video, I forgot to do this.
And so no matter how much you jacked up the speed, you turn your hand it's going to be capped at
a certain amount because the rigid bodies Max angular velocity is set to a pretty low amount. So
we're just going to say rigid body dot max angular velocity is going to be equal to float dot
positive infinity. And that will allow us to turn our head as fast as we want, and it should be
able to catch up. And then in our Fix update,
we want to do a few things. So we're going to
do a P D movement. So this will be just XY and Z values. And we're going to do a PID rotation. So
let's make both of these methods void PID movement and void PID rotation. Now, I'm just going to
copy and paste this. So ready for it, paste, this is the formula we're using, you can look
at it. So this is how it is set up in code in Unity converted over from the wiki formulas.
So I'm not even going to try to explain it, I just know there's a frequency a damping value,
and then we need to set up a target that we're trying to follow as well. So go back up to the
top here, when I grab a serialized field blowed frequency, and I'm gonna set this equal to 50.
Then we're gonna do another serialized field blowed stamping, we set this one equal to one,
and then we need a target of a serialized field transform. And that'll be our controller. So there
Yeah, and basically, this whole formula spits out a force that we can use to say, Okay,
for this particular frame, how much force are we applying to our physics and in order to
get to the transform position of our controller, and we can use that force on a rigid bodies, rigid
body add force force, and we're going to make that a acceleration force. So now every frame we
are calculating how fast do we need to move to that target for this particular frame, in order
to get there, but kind of smooth off and not have any of that rope band, now we're going to do a
very similar equation to the rotation, and I'm just going to copy paste this one, too, this one's
gonna be using a rotation frequency and a rotation dampening value. So I'm gonna go back up to the
top, add both of these in so serialize field float rot frequency, I'm gonna set this one equal
to 100, a little more, change that to float, and then another two lights field float, right.
And this one's going to be equal to a little less so 0.9. So the damping is effectively how
quickly it's going to go to your hand over damped, that means it's going to go slowly, but be more
precise and have less rubberbanding. If it's under damped, that means it's going to go past
your hand and kind of come back and have a little bit rubber banding, but it's going to get there
a lot faster. So it's kind of a give and take. So you can feel free to play around with these values
to get what feels right for your game. So the PID rotation spits out a torque instead of a horse
like the movement did. And effectively just use uses a little bit of Kryptonian math in here. And
we can use that torque to add to our rigid body just like we did above. So add torque, this time,
torque and also a acceleration force mode, make sure you save the project. And we can jump back
into unity and see if it works, we're gonna fill in those values, test things out. So let's grab
the left hand column values already set up nicely, and then just drag and drop the XR origin into the
player rigid body and the target is going to be our left hand controller, and then right hand is
going to be XR origin for the rigid body and the right hand controller for our target, save that.
And then I'm also going to turn the lasers off or the left and right hand controllers just because
we're not going to need them. So just uncheck the line renderer and XR interaction line visual, save
that, make sure your Oculus is and link bowed and hit play or whatever device you're using. Oh, and
there's one thing I missed that when we added that physics layer, we didn't actually update the
physics in settings. So I'm gonna go to Edit Project Settings, go over to physics, and then
scroll all the way down to get to that matrix. And we're going to uncheck where player collides with
player just so we can't interact with ourselves, and we can't interact with our hands. And now when
we hit play, you'll see we have two hands that we can move around, and they track very well with our
controllers. And then if I tried to go through the ground, they do not and they kind of fall down
correctly as well. So everything is matching up nicely. And if I add in like a little cube, so
we're going to add a 3d object cube, reset the transform, and then I'm going to shrink it down
to something quite small and add a rigidbody to it and then move it a little bit out of the way
just so we don't get it right off the bat and play you'll see we can grab the cube and pick it up
and move it around with just physics. So I'm not pressing a grab button or anything. It's
all physics, like we can pick the cube up, I can put it on my other hand, kind of
juggle it back and forth. And so this is all physics. So picking it up, we were using friction
to kind of move the cube around. And what we're going to attempt to do next is to actually do that
to our player, except pushing on kinematic objects that don't actually move. And you could imagine
how this would work for physicalized hands too, you could replace the little flat squares that we
have with pans and you have full physics hands. So I'm gonna go back and add in like a yellow
material to our hands just so we can see him a little bit better yellow to one hand, and there
we go. Alright, let's do the fun part. Let's
do the moving round when you push off the ground
or grab things or whatever. To do that we're going to add Hookes law. So let's go back to the
script. I'm going to collapse the PID rotation and movement because we're not going to need to mess
with those anymore. We're going to add Hookes law create a new method for that void Hookes law and
this one's a lot little bit simpler of a formula, so I wouldn't be able to explain that a little
bit. First, we're gonna get the displacement. So what's the distance between the hand and your
physics hands. So when you're pushing down into something, how far does that distance because
your your physics hands gonna stop when you push against something, but your real life controller
hand is not. So we're gonna grab the distance that you know the two hands are apart and use that as
a spring force to kind of propel yourself. So we need a displacement for resting, so vector three
displacement from resting. And that's just equal to the difference between your transform position
and the target position. And we're going to convert that into a force. So a vector three force
is going to be equal to displacement from resting, multiplied by some constant that we can adjust in
the inspector. So we're going to call this a climb force. And we can make the climb force up here
at the top. So underneath all of this stuff, I'm going to add a face and then a another header.
And then this header is going to say brings, and we can add the serialize field load time force.
And I'm gonna set this one equal to like 1000, I was playing around with it a little earlier in
this, this is what seemed to work the best. Now there's a problem with just adding this force
directly to your spring is that there's nothing else acting against it from the other directions.
So in springs, you have two different directions, you have the spring force, but then you have
the other directional force of whatever it's pushing against. And so we need something else.
And what we're going to call a drag force. And if you ever played bone works, you've noticed
that when you're trying to climb on things, it's very wobbly and shaky. And that's because
there is not as much drag you the player has a lot of control. But it also prevents you from making
any fast movement. So that's what we're trying to avoid. So we're going to add more drag. So we're
going to introduce a formula. Another form is the last one, I promise that adds more drag when we're
moving slow. So if our hand velocity is slower than we want more drag so that it's very precise
movement. But if we have very fast hand velocity, so we're bouncing off walls and moving things,
we don't really care as much of the drag and the preciseness, I'm trying to move fast. So we
can have a little bit of that rubber banding, because we're not gonna be holding on to things
for long, we're just trying to move really fast. So more drag, we're moving slow, less drag,
when we're moving fast is the general idea that will allow us to launch ourselves faster
and throw ourselves around and whatnot, which is most of the fun anyway. And so to calculate this
drag, I'm just going to create a float drag, and that's going to be equal to get drag, just
send it out to a method, have it calculate all the stuff and then bring it back in. And then we
can take the player rigidbody, we're going to add the force is going to be acceleration force mode
as well. And then we take the player rigidbody add force, we're going to add drag, but we're going
to multiply drag by the opposite of whatever the player rigid bodies velocity is. And we're also
going to multiply that by a blind drag force. So just like we have a climb force constant that
we can adjust, we have we'll have a climb drag force that we can also adjust. And this one's also
going to be a force mode acceleration as well. So let's create this climb, drag force up here at
the top. So I'm just going to click Next to this line and press Ctrl D to duplicate it and rename
this to drag and then I'm going to set this to about half the value, so 500. So 500 will be
the max value, and then we'll be able to scale that way down. If we're moving fast. Oh, also,
I misspelled springs, SP AR. Alright, so how do we get dragged let's make a new method. And this
is going to return a float. So float, get drag, do a vector three and a velocity. And that's
going to be equal to our target dot local position minus a previous position. So this is just a
position that we saved last frame. And we're going to use this frame to get the distance which
we can use to calculate velocity. And that's going to be divided by time dot fixed delta time,
because we're using we're doing all of this in the Fixed Update, we'll create previous position in
a second, let's finish this method out, we're going to have a dragged float, and that's going
to be equal to one divided by our hand velocity magnitude, but we never want to divide by zero.
So just in case magnitude ends up being zero, we're just going to add a really small number like
point 01. And then one more thing we need to do is clamp drag. So we never want drag to be above one
and we never want it to be below some small number like point 03. We just want it to be not zero
and not above one, you could use math dot clamp, but for some reason that's not working for
me. So we're going to do it the manual way. So drag is going to be equal to the expression is
drag greater than one question mark. And if that is true, then drag is gonna be one otherwise,
so semicolon, we're just going to set it equal to drag, and then we're going to do it for the
low end. So drag is going to be equal to drag is less than 0.03. Question mark.
So if that expression is true, then we're going to set it equal to 0.03. Otherwise, set it
equal to whatever drag is. So this is effectively clamping it from a high end and a low end and
then we're going to set previous position. So previous position is going to be equal to whatever
our transform position is, and we can return drag. So this line here is really doing most of the
work. It's inversely scaling the velocity of your hand with how extract we're adding, so let's
add previous position. So just go back up here to the top that can be a private field. So vector
three previous position, and then when we start, we're going to set previous position. So previous
positions will be equal to the transformed up position. Also, one more thing we need to do when
we start is just go ahead and set the hands. So the physics hands, just go ahead and teleport them
to wherever the controllers are just so we're not having to go through random stuff or whatever.
So we're gonna say the transformed up position is going to be equal to target position, and the
transform dot rotation is going to be equal to target rotation. So just so we're starting out
in the correct spot, so let's jump back into unity and see how that looks. And you'll see, we
can push off the ground, which is really cool. So I can kind of push down on it, and it'll
throw us but there's like this weird, like, you know, you fall slowly. And also, if you
notice, I can swipe my hand to the side, and it throws our player back and forth. The Hookes law
is also being applied to our PID controller, which is not really what we want, we when we're like
having, you know, some a little bit of spring as Hookes law would see it in our PID controller,
we don't really care about that we only really care about it when we're touching something,
so we need to just have a check to see, okay, we're only gonna apply this kind of spring to if
we're touching something, otherwise, it's gonna make us like, have some really weird behavior. So
back into the code, it's really easy fix for this, we're just going to add a bool variable called
is colliding. So bool always starts out false, which is good for us. And then we'll use
on collision, enter on collision exit, so on collision, enter is colliding is
gonna be equal to true and on collision exit is colliding is going to be equal to false. And
then back up in our fixed update, instead of always calculating Hookes law, we're going to have
a condition here that says, if we are colliding, then we calculate Hookes. Law, save that and
jump back into unity. And you can see I can very easily kind of bounce off of the ground now.
And this ground plane has all of sudden become a very small area. So you'll see, I am just
kind of swiping back and forth on the ground. And it allows me to kind of move and I can
use both hands to kind of do a fast walk or whatever. And I can just throw myself off of
the plane as well. Let's make this a little more interesting. Let's add in some trees or walls or
stuff for us to bounce off of. So I'm going to go to Window Package Manager. And then we're going
to swap over to unity registry and scroll down until we see pro builder and install that was a
really easy prototyping tool. If you've not heard of pro builder, I love it. It's great and allows
you to create shapes other than just your plain old cubes. And then we're going to kind of back
out of here. And we can go to Tools pro builder and pro Builder window, that'll pop this window up
here and we add a new shape. And I want to add in a arch, we'll do a cube first make some walls
here. So draw your cross make a little bit of a wall over there to another one here kind
of surround our oops Rosie that one kind of surround our little area here with walls. So
let's add in a point light in here because this is a little a little dark, he set that down to the
center and just bumped the intensity so we can actually see inside. And then let's make a couple
of things like a maybe a pole add like just some interesting shapes. So like a little pole to climb
up, maybe something on the wall here to stick out, we can make a little ledge thing. Let's make let's
do like a little wall over here that we can bounce back and forth between that wall and then maybe
just a smaller hole here and like a larger little base area to kind of bolt over. Alright, let's
see how that does. Jump into it, you'll see I can jump up to the bounce off of walls. So I can
pinch climb this it's a little, little hard. So there's one thing we could do to fix this, but
it's still still a tad bit difficult to manage. And one thing we can do to improve that is to
add a physics material. So I'm going to go into my materials folder, right click and go down to
physics material. There we go. And we'll just call this hand and we'll up the dynamic friction
to something like 100 and static friction also. And then we'll do friction combined as the maximum
and then find our left and right hand physics hands go to the box collider. drag those in, drag
the material in so it's in both of them now.
And now if we hit play, we should be really
sticky to the walls and whatnot. So I can either go so I can climb up and push off and
jump up to the top here and jump over here. Go off of each shard out to do the gorilla tag
click where you destroy your house. There we go. My my little cheese I just realized these look
like cheese but I could jump off of their knees and climb up around. You can even kind of go up
the corners. So if you've run over to the corner, you can jump up the jump off the corners this
might be a little too much velocity for me to climb with the corners like that. So you Have fun
with it. It's a cool little, hey, my friction is so much I can kind of push against just the corner
and go up. There we go. Have fun, go crazy. This is a super fun project. It's really fun to just
kind of hang out and bounce around and you'll see what you can do. This is probably a little more
velocity, like climb force than you would want for like a, you know, Gorilla tag replica, you could
scale that down a little bit. Yeah, fine tune the numbers a little bit. You don't want to set
the whole project up yourself, you can support me on Patreon and get access to all the source
code from every single one of my tutorials. And if you run into any issues, definitely join our
Discord. We have a really active discord and some really fun people in there. So just Join Hangout
we have a channel specifically for helping you out with any dev issues and whatnot. If you are
interested in having me do like a bigger tutorial and recreating the entire gorilla tag game, like
the multiplayer aspect lobby's how to do the tag element going over the climbing again, then leave
a comment down in the description so I know that you're interested and let me know if you have
any suggestions for other tutorials I should do. Otherwise, look out for the upcoming live streams
on the weekends. And I'll see you next week.