A what's up everyone Mark Price your slopes column and we're making great progress with our arcade app.
And what we've done so far is we've made it so you can see three objects three 3-D objects in a View
Controller in a scene view the rotating.
And when you tap it it prints the name so we know which one is being tapped and we're actually passing
that name back to a remote place or ABC.
And what we want to do here in the on ramp selected OK is what we want to do is we want to make it so
it stores the name of the object that we're going to be placing.
OK.
And then when we need to detect when the screen is tapped again so we can actually place it in the appropriate
spot.
But on this screen this time.
So we're going to need a variable to store the name of the ramp so let's go up to the top here and create
a new variable here var and we're going to say selected ramp is going to be of type string and it isn't
optional because it may at first there's nothing there.
So var selected ramp.
And what we're going to do is say selected ramp ramp name.
It looks good to me.
And then we just probably need to implement the touches began to override function here.
So let's put that let's put it here just for fun or to say touches began.
And anytime a touch starts it'll call this code here which is what we want.
And then let's just write some code to detect the touch get it's the position of the touch and then
we need to place a 3D object at the point that's being touched.
OK so it detects a touch figures out where on the screen it's happening.
And then we can place an object there and when detecting a touch on the on the view here this A-R scene
view you do it a little bit differently than we just did it in the regular scene.
So let's go ahead and get started here.
So guard let touch equals touch up first.
So we're guarding against there not being touch or.
Yeah.
We're guarding against they're not being attacked so we're grabbing touches down first.
OK.
And then the next thing is let results equals scene view.
Hit tests we are using the similar test because it is using the same functionality under the hood that
we just did.
So hit test.
And in this case we're going to type touch dot location for the point.
OK you touch that location.
OK.
Seen you.
There you go.
OK we're calling the touch that location function seem you got confused by the syntax here.
And then lastly we have the options and what we want in this case is a feature point.
OK.
We'll let this stop airing out on us.
Come on now what did I spelled wrong.
Feature point.
This looks good to me.
Closing closing.
That's correct.
What does it yelling at me for.
Does not like it at all what is going on.
Feature point feature point types.
Oh I called the wrong I called the wrong
the wrong thing types.
OK.
And what I wanted to do was show you the feature point here.
OK.
So result type result type from intersecting the near future point.
This is in our kit.
And so basically remember it detects the floors in the walls and everything.
And so when you tap it's using it's very complex under the hood math to figure out where on the wall
or the floor that you tap and get the actual distance to stuff.
Very cool stuff.
Very complex stuff in there doing that for us and so that's what future point does.
You can also look at some of the other things that they have here as well to see what they do.
I will not be explaining them because we are using the feature point.
It's just going to get the nearest intersection in your in your room or you're outside or wherever it's
detecting.
OK.
Guard let hit.
Feature equals results that last else return.
So now we're getting the results of a tap.
So here's something really important.
Understand sometimes a market can't find angles if your rooms too dark it can't find an angle if it's
too dark anywhere or too fuzzy.
Or let's say you're just looking at the ground but it can't see walls or can't see a car in the distance
or something that can give it some context.
You may get nothing here and it will return.
So if you're in our app and other apps let's say especially in our app if you're tapping and like nothing's
happening it's because we're hitting this return same.
And the reason why is because it's not finding the feature on the ground.
But you'll notice when you move closer to something where there's two objects.
It works.
And so it needs it needs context in order to be able to place the object.
OK hit feature results that last else return.
So we got to make sure that we actually find an object when when it's being tapped.
It finds that reference point OK let it transform equals as seen matrix for.
OK.
And what we're going to do is we're just going to pass in the the world transform the hit feature so
hit feature that world transform.
OK.
So grabbing the transform from the from the tap.
OK.
Meaning remember if there was nothing we're returning we're not even getting here otherwise there was
something and we are going to take it and get the transform for it so we can actually use it and place
a 3-D object.
OK.
Let me hit position equals se and vector 3 make.
We're going to say hit transform
em for one hit.
Transform em for two and get transformed for three and a fourth.
Thank you.
Let's make sure there's no errors here.
OK.
And you're probably wondering.
Hey Mark how do you know what for one and for 2 and 4 3 is.
Well if we can click this here OK we're going to be sadly disappointed because there's not a whole lot
of information on what these are but what's happening is this C-n matrix for is storing data in regards
to the transform from this from this hit test here.
And because Apple documentation and Apple examples say so I know that M for one and for two and forth
three are the translation or the positioning floats that you need to access.
Outside of that I honestly am not sure how you would figure it out.
There's no documentation on there but in the Apple documentation they do reference these three points
as translation or position.
And so that's what we're grabbing here of the hit position which is why you got to read Apple documentation.
Usually it's very safe to do things the way that they do it.
And their example projects.
So what we've done here is we have we've looked at we've done a hit test so we grabbed the touch.
We've done a hit test on that touch on to get the results.
Now if there was a tap.
OK what we're doing is we're grabbing the world transform of that touch.
OK.
So the hit feature is going to it's going to find the horizontal and vertical position of where you
tapped.
And again you know make sure you tap on something that has context.
We're grabbing the word transform for that.
And then we're creating a positioning vector 3 here of the actual position and 3D accordant space so
we can place an object.
And you don't have to understand this completely in order to use it.
But this is typically the process you'll follow when placing objects in a market in a 3-D space very
similar to this here.
OK the next step is to actually place an object on the screen.
So how do we do that.
Well we're going to have to create the node like we did in the in the picker with the three objects
and then place it at the position.
So down here we can create a function called Place ramp.
We're going to pass in the position of S in vector 3 like so.
And then let's call this function up here.
So we're going to say placed ramp.
And let's just pass in the hit position like so.
And then what do we need to do here we need to actually get those ramps again.
So see here yeah we've got timeless do it.
So over here in our ramp picker OK we've got these We've got these three objects here as you can see
these three 3-D objects and we need to be able to have similar code so what I want to do is I want to
refactor to make this more more reusable.
OK so we're going to go to our project here and new group and we're going to call this model.
And inside the model folder we're going to add a new file.
OK.
And what we want to do is just make this a swift file and make empty right now.
And let's call this ramp and we're going to import scene kit.
So class is going to be ramp.
And then what we're going to do is create a series of functions static functions that we can just call
to get the things that we want to get.
So what we can do is we can say class phunk get pipe for getting the halfpipe and it's going to return
in N.S.A. like so.
And then what we can do is we can go to a ramp picker code and we can copy some of the stuff here.
So it's going to take this copy the pipe go back to our ramp pace to here will change changes to let's
do this time and left.
But instead of adding to the root note we'll just returned the note itself like so very good.
And then we'll create one for will create two others for class phunk get pyramid C.A. and then world
class phunk get quarter for the quarter as seen.
No.
Like so.
And let me point out here where we're specifically grabbing objects.
OK.
And placing them with a certain scale and things because we want them to look a certain way.
If you're actually building a game or there's lots of things going on objects being instantiated coming
from different places of course you wouldn't manually like place individual objects here because you
would be able to manage it all by I say scene kids.
I think it's pretty rough to work with.
I would not make a game and sink it.
If you want to make full scale game do it and unity 3D absolutely for sure.
And we do have courses on an amazing course actually.
And it's so easy to use.
And so if you really are serious about working with a market and making something immersive where you
don't need the standard controls from Iowa has worked with unity.
It's absolutely fantastic.
OK.
And so node run action rotate we're going to take this out because we don't want the we don't want to
run the rotation on the on the objects that are in the in the market.
So when you take that out there.
And so there's our get pipe Let's go back to our picker and let's go ahead and copy this one so ramp
ramp.
So this is the pyramid right.
Yep this is great.
Let here and the law here we're just we're refactoring making a little more better.
It's not a huge improvement but it's a little improvement and that's good enough for me.
Return node like so.
And let's go over here again to our quarter pipe and do the same thing.
Good quarter and we're going to say let and let us get rid of the action and let's get rid of the root
node thingy and let's return the node like so.
And then what we can do is go back to our ramp picker and we can refactor this here which is nice and
you know what let's actually let's put this in a function as well to this this rotate action.
Let's put it in there so let's go back to our ramp actually.
And it's great another class function class phunk start to make this bigger for you here.
We start rotation pass in a node and we're just going to rotate it as C.A..
All we have to do is take those lines of code from the ramp picker namely the rotation like so place
it here and then let's grab the run action like so and place it in the ramp as well.
So did I just do.
I did something silly didn't I.
This is my go here it goes.
And the ramp.
There we go.
And then back to the ramp.
The ramp picker.
We will do the no dot run action command see and Pat put it over here and our ramp.
OK so we're just taking this note that was passed in and we're just running an action on it.
So now what we can do now that this is all cleaned up we can make our code it's a cleanable be here
and now we can make our code more clean up in the rent picker.
So what I want to do is I want to let's just delete all this stuff here.
OK.
And this too it should be pretty easy to say lead pipe equals ramp that get pipe and then we're going
to say ramp it up start rotation and we'll pass in the pipe to start rotating it and then we'll say
seen that root node ADD child and we're just going to say pipe.
No big deal like so we'll do the same thing for the other one so let Pairin pyramid equals ramp Dogget
pyramid ramp start rotation.
Now we're going to say pyramid and then seen that root node add child node and we're going to say pyramid
pyramid and WILLMORE let a quarter pipe or quarter equals ramp get quarter and we're to say ramp dot
start rotation quarter and then we're going to say seen up root node.
Add child node and we're going to say quarter.
So let's make sure our code is still working mate meaning the ramps are still there same positions and
that they are rotating.
So it's run the app and see secret button and they are rotating.
Sure enough they're rotating and this looks really really good.
Cool.
So what we've done is we've just refactored our code we've cleaned it up we've made it more reusable.
And now what we can do to stop this is we can go into our ramp placer which I'm already here and now
we can actually place the ramp.
We can we can use that those same functions that we just used and place the ramp somewhere on the screen.
OK.
So it should be as simple as Plett ramp equals.
Well shoot we don't know which we don't know which ramp to ramp to use.
We know the selected name of a ramp but we don't know which one to use.
So we probably need to get one more function in our ramp here.
So we can actually just determine which ramp to get.
So I'll put up here at the top.
A new function we're going to say class phunk get ramp for name.
All right.
Or to say ramp name of type string.
Perfect.
And we're going to return an Essene node.
We're simply going to switch the ramp name.
That's all.
All right.
No big deal.
So if the case is pipe Let's go ahead and just return the ramp that pipe.
All right.
And then if the case is quarter let's return ramp get quarter and if the case is pyramid let's just
return the ramp get pyramid like so and the default we will return the ramp get pipe like so
that should work.
It's giving us an Erich's.
It did not return this wonderful wonderful go away read as we go.
Ok cool.
So back to rent place or now we can actually get our ramp just by passing in the name of the ramp so
let's ramp equals ramp get ramp for name and we're going to pass him the selected ramp.
And what we actually need to do here is if the left ramp name equals select the ramp because it's an
optional.
And it may or may not have a value in it and we don't want to crash.
So this is a time when a user could actually have not done something correctly and it could be nil.
And so we want to make sure we account for it here with the optional.
And in this case we will not say ramp name.
Okay so there's our ramp.
And then let's go ahead and give it a position.
So I tab.
Okay.
So the ramp up position is going to be equal to the position or the the finger tap.
Okay like so and then for the scale we want to set the schedule back to normal size.
Remember on the on the list with three items made it really small.
We want to do the default size so ramped up scale is going to be equal to.
Vector 3 make and we're going to say point zero 0.01 0.01 and 0.01 So we're just getting it back to
its default size so it's nice and large and we're going to say seen view that scene the root node and
child node and we're going to pass in the ramp and that would just fetch from our ramp class.
Cool.
This is really cool.
I'm really curious to see if it works.
So in order to test this we're going to actually have to use it on a device.
So let's do that now.
So I've got my actual phone attached here and I am using the cable you can use the Wi-Fi building but
it's a lot slower that I found so the cable is much faster and I'm going to run it and make sure we
don't have any crashes make sure everything works.
And it may not work perfectly because my office right here is really dark and it needs light in order
to process this.
But I at least want to see if something gets on the screen.
So I'm running the app here.
And of course we see the big half pipe from before because it loads by default when we get rid of that.
I think we need to delete the one that's coming up by default so I'm going to stop this real quick start
my recording on my phone.
I was loving the new screen recording pretty nifty.
And let's make sure we get rid of any default half pipes on here yeah this pipe that DA.
Well we actually want to do is create an empty scene here let's just create a new scene file new file
we want to do resources and a scene kit scene file and I'm just going to call this main main scene here
save it and I'm just going to put this over here in the our assets folder.
And what I want to do is we go to empty scene which is fine.
So this is good.
What I want to do here is go to our ramp placer and I want to just load this new scene instead this
main scene here OK so we're going to do is change this from pipe that DADT to main s c and.
OK.
And what I also want to do here on the scene we're at is type in scene view auto enable default lighting
to true to set default lighting here.
OK.
So let's go ahead and run this again.
We record it on my phone and run it OK it's running in the big huge half pipe is gone.
I'm trying to tap but nothing is happening.
Oh A.B. I know why it's not because we haven't selected one yet.
That's why.
Let's select an object analyst at the pyramid.
We also forgot to dismiss the view controller tap off though and it dismisses fine.
Let's tap somewhere and there it is.
It's definitely working.
As you can see but it's it's found a bad surface here.
Again it's really dark.
You see him moving around here.
You have to do a lot of this.
It's really dark here and it's just not placing it in the right spot.
And so of course we're going to build tools to fix this but also the room is not a great test for this
because it's very dark and it can't detect the walls and the surface very well.
But it did place it there and it's the right size in my opinion so very cool.
So it's definitely working.
We just need to make it a little more accurate so.
So it's working.
We did it.
And if you're going to find yourself when working with our kit you're going be running outside of the
house a lot and moving around.
At least I did when I had to build this made many many trips because the rooms just not a good example
especially since we're doing ramps like High-Fives they need to be really big and it's not going to
fit in my house.
So we're going to call this video done what we've done is we've actually we refactored some code so
our our assets are usable are seen files are usable and then what happens is we tap on the screen and
it does detection and then we get the point we grab the ramp and we place it there and it's actually
we've got our quit working.
We've accomplished what we need to do but we need to do more cleanup.
Now we need to implement controls removing things and create a better solution here altogether so that's
it for now.
Let's finish this up.
Mark Price a dove slopes dot com see assume.