Sunday, September 29, 2013

Unity Touch Joystick Player Movement - Touch FPS Controller


Check out the finished code below the videos

Part 1 - Player Movement Joystick

Part 2 - Player Rotation Joystick
  • 0:15 - Quick fix for a problem with our player movement script from the last tutorial
  • 2:10 - Setting up our scene for the new joystick
  • 2:35 - Creating an enum to choose what type of joystick we want in a drop down menu
  • 4:45 - Using the enum to change the functionality of our joystick for rotation
  • 6:30 - Adding in our rotation logic
  • 7:38 - Using touch2Watch to make our joystick pay attention to the correct finger
  • 8:25 - Quick overview of our rotation script
  • 9:00 - Demonstration of the look rotation joystick working
  • 9:35 - Changing the sky color with our third joystick, for funzies
  • 10:50 - Demonstration of third joystick controlling sky color
  • 11:15 - Overview of why we need to manage our touch2Watch indexes
  • 12:20 - Creating a TouchManager script
  • 14:15 - Explaination of how we will manage our touches2Watch
  • 16:38 - Adding in a failsafe to make sure our joysticks never get stuck when there are no touches on the screen
  • 17:35 - Outro, thanks for watching :D
Check out the videos above to hear the explanation and see the code in action
/*/
* Script by Devin Curry
* www.Devination.com
* www.youtube.com/user/curryboy001
* Please like and subscribe if you found my tutorials helpful :D
* Twitter: https://twitter.com/Devination3D
/*/
using UnityEngine;
using System.Collections;

public class Joystick : TouchLogicV2//NOTE: This script has been updated to V2 after video recording
{
 public enum JoystickType {Movement, LookRotation, SkyColor};
 public JoystickType joystickType;
 public Transform player = null;
 public float playerSpeed = 2f, maxJoyDelta = 0.05f, rotateSpeed = 100.0f;
 private Vector3 oJoyPos, joyDelta;
 private Transform joyTrans = null;
 public CharacterController troller;
 private float pitch = 0.0f,
 yaw = 0.0f;
 //cache initial rotation of player so pitch and yaw don't reset to 0 before rotating
 private Vector3 oRotation;
 void Start ()
 {
  joyTrans = this.transform;
  oJoyPos = joyTrans.position;
  //cache original rotation of player so pitch and yaw don't reset to 0 before rotating
  oRotation = player.eulerAngles;
  pitch = oRotation.x;
  yaw = oRotation.y;
 }
 public override void OnTouchBegan()
 {
  //Used so the joystick only pays attention to the touch that began on the joystick
  touch2Watch = TouchLogicV2.currTouch;
 }
 public override void OnTouchMovedAnywhere()
 {
  if(TouchLogicV2.currTouch == touch2Watch)
  {
   //move the joystick
   joyTrans.position = MoveJoyStick();
   ApplyDeltaJoy();
  }
 }
 public override void OnTouchStayedAnywhere()
 {
  if(TouchLogicV2.currTouch == touch2Watch)
  {
   ApplyDeltaJoy();
  }
 }
 public override void OnTouchEndedAnywhere()
 {
  //the || condition is a failsafe so joystick never gets stuck with no fingers on screen
  if(TouchLogicV2.currTouch == touch2Watch || Input.touches.Length <= 0)
  {
   //move the joystick back to its orig position
   joyTrans.position = oJoyPos;
   touch2Watch = 64;
  }
 }
 void ApplyDeltaJoy()
 {
  switch(joystickType)
  {
  case JoystickType.Movement:
   troller.Move ((player.forward * joyDelta.z + player.right * joyDelta.x) * playerSpeed * Time.deltaTime);
   break;
  case JoystickType.LookRotation:
   pitch -= Input.GetTouch(touch2Watch).deltaPosition.y * rotateSpeed * Time.deltaTime;
   yaw += Input.GetTouch(touch2Watch).deltaPosition.x * rotateSpeed * Time.deltaTime;
   //limit so we dont do backflips
   pitch = Mathf.Clamp(pitch, -80, 80);
   //do the rotations of our camera
   player.eulerAngles += new Vector3 ( pitch, yaw, 0.0f);
   break;
  case JoystickType.SkyColor:
   Camera.mainCamera.backgroundColor = new Color(joyDelta.x, joyDelta.z, joyDelta.x*joyDelta.z);
   break;
  }
 }
 Vector3 MoveJoyStick()
 {
  //convert the touch position to a % of the screen to move our joystick
  float x = Input.GetTouch (touch2Watch).position.x / Screen.width,
  y = Input.GetTouch (touch2Watch).position.y / Screen.height;
  //combine the floats into a single Vector3 and limit the delta distance
  
  //If you want a rectangularly limited joystick (used in video), use this
  Vector3 position = new Vector3 (Mathf.Clamp(x, oJoyPos.x - maxJoyDelta, oJoyPos.x + maxJoyDelta),
                                  Mathf.Clamp(y, oJoyPos.y - maxJoyDelta, oJoyPos.y + maxJoyDelta), 0);//use Vector3.ClampMagnitude instead if you want a circular clamp instead of a square
  
  //If you want a circularly limited joystick, use this (uncomment it)
  //Vector3 position = Vector3.ClampMagnitude(new Vector3 (x-oJoyPos.x, y-oJoyPos.y, 0), maxJoyDelta) + oJoyPos;
  
  
  //joyDelta used for moving the player
  joyDelta = new Vector3(position.x - oJoyPos.x, 0, position.y - oJoyPos.y).normalized;
  //position used for moving the joystick
  return position;
 }
 void LateUpdate()
 {
  if(!troller.isGrounded)
   troller.Move(Vector3.down * 2);
 }
}