Following from my previous tutorial, Creating an Orbit Cam for iOS, today we’re going to learn how to drag an actor around a level using touch. If you haven’t read the previous tutorial, I would recommend doing so before starting this one.
The first thing we need to do is create the class we’re going to move around. We’ll make a custom class so it’s easier to make the detection code in our PlayerController.
Pretty simple here, our Tapped function will let us change the material so the player knows what actor has been selected. Using the ? : format is easy. You put the condition you’re checking for before the question mark, then what to do if it’s true or false. Example:
It’s a more compact way of saying:
Very useful for simple checks.
Now we need to add two variables to our AwesomeMobilePC class.
DragActor will hold a reference to the AwesomeMobileActor that we’re moving, and the bool we will use to prevent the camera from moving around while we’re dragging the DragActor.
There is one line we need to add to our SetupZones function, since we’ll be using the swiping motion to move the DragActor instead of a tap.
We’ll process our FreeLookZone’s input in our own function, CheckDragActor (click image to enlarge).
You may notice that the first half of this function looks a lot like our TapToMoveTap function. We’re using a trace here to determine whether or not we want to move our DragActor, as well as where we want to move it to. Inside our ForEach is where most of the work takes place. We only want to be able to drag the actor when we click on it, if we’re clicking off of it the player may only be trying to rotate the camera. To do that we’ve added a local boolean, bAllowDragActor. If our trace hits the current DragActor, we know that the player is trying to move it so we allow it. Next, we want to move the actor to the “top most” actor’s hit location, not anything behind or below it if we have a level with multiple floors. We make a variable bFirstHitActor here, and only take the first actor that isn’t the DragActor itself to figure out our hit location.
After we exit our ForEach we know two things: Whether the DragActor was along the trace the player started so we know they want to move it or not, and whether or not we hit an actor we can move our DragActor to. If the player doesn’t want to move the DragActor we need to let the camera function know, so we save bAllowDragActor as our class variable bDraggingActor.
Next, if we already know the player doesn’t want to move the DragActor, we should exit the function before we move DragActor.
Finally, if we know the player is trying to move DragActor, then move it to our HitLoc.
Now for a few changes to our TapToMoveTap function.
In this function’s ForEach, if we tapped on an AwesomeMobileActor we want to select it instead of moving the camera, so we set the DragActor here and then exit out of the function. If not, after the ForEach runs we check if there’s a current DragActor, if there is then it means the player has tapped outside of the DragActor and wants to unselect it, so we do that and exit out of the function. If there’s no current DragActor then we know the player is trying to move the camera, which is the last part of that function.
Now, while we have a DragActor and we’re moving it around, we don’t want the camera to move. We need to change the two lines in PlayerTick that deal with the player input (click to enlarge):
We use more of the ? checks here. If there’s no DragActor or there is and we’re not moving it, then move the camera.
That just about does it! Compile the code and open the editor. We’ll use a copy of the SimpleCourtyard to test this, so save it under a different name and add an AwesomeMobileActor near the center. Now go to View, open World Properties, and in the World Info tab, set Game Types Supported On This Map and Game Type For PIE to AwesomeMobileGame. This makes sure that the script file makes it to the iOS device. Save the map. Now, double check that you have the gametype set in your MobileGame\Config\DefaultGame.ini like this:
And that you have your RequiredMobileInputConfigs set up in the same file:
If not, close the editor and make the changes to your DefaultGame.ini file. Reopen the editor and run the test map. You’ll notice you can tap the actor to select it, drag it around the screen, move the camera around while you have it selected, and unselect it by tapping away from it. We’re good to go!
Now for your challenge. You’ll notice when you drag the actor it snaps to the touched location before following your finger. Try using a vector to save an offset to get rid of the snap. Have fun!