@@ -0,0 +1,246 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &100004
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 400000}
- 20: {fileID: 2000000}
- 81: {fileID: 8100000}
- 114: {fileID: 11400006}
m_Layer: 0
m_Name: MainCamera
m_TagString: MainCamera
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &100006
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 400002}
- 54: {fileID: 5400000}
- 136: {fileID: 13600000}
- 114: {fileID: 11400004}
m_Layer: 0
m_Name: RigidBodyFPSController
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &400000
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: .600000024, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 400002}
m_RootOrder: 0
--- !u!4 &400002
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100006}
m_LocalRotation: {x: 0, y: 1, z: 0, w: -1.62920685e-07}
m_LocalPosition: {x: -30, y: 1, z: 25}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 400000}
m_Father: {fileID: 0}
m_RootOrder: 0
--- !u!20 &2000000
Camera:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_Enabled: 1
serializedVersion: 2
m_ClearFlags: 1
m_BackGroundColor: {r: .192156866, g: .301960796, b: .474509805, a: .0196078438}
m_NormalizedViewPortRect:
serializedVersion: 2
x: 0
y: 0
width: 1
height: 1
near clip plane: .300000012
far clip plane: 1000
field of view: 60
orthographic: 0
orthographic size: 5
m_Depth: 0
m_CullingMask:
serializedVersion: 2
m_Bits: 4294967295
m_RenderingPath: -1
m_TargetTexture: {fileID: 0}
m_TargetDisplay: 0
m_HDR: 0
m_OcclusionCulling: 1
m_StereoConvergence: 10
m_StereoSeparation: .0219999999
--- !u!54 &5400000
Rigidbody:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100006}
serializedVersion: 2
m_Mass: 10
m_Drag: 0
m_AngularDrag: .0500000007
m_UseGravity: 1
m_IsKinematic: 0
m_Interpolate: 0
m_Constraints: 112
m_CollisionDetection: 0
--- !u!81 &8100000
AudioListener:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_Enabled: 1
--- !u!114 &11400004
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100006}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 81c9795a96c094f4cbde4d65546aa9b2, type: 3}
m_Name:
m_EditorClassIdentifier:
cam: {fileID: 2000000}
movementSettings:
ForwardSpeed: 8
BackwardSpeed: 4
StrafeSpeed: 4
RunMultiplier: 2
RunKey: 304
JumpForce: 50
SlopeCurveModifier:
serializedVersion: 2
m_Curve:
- time: -90
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
- time: 0
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
- time: 90
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
m_PreInfinity: 2
m_PostInfinity: 2
CurrentTargetSpeed: 8
mouseLook:
XSensitivity: 2
YSensitivity: 2
clampVerticalRotation: 1
MinimumX: -45
MaximumX: 90
smooth: 1
smoothTime: 18
advancedSettings:
groundCheckDistance: .100000001
stickToGroundHelperDistance: .600000024
slowDownRate: 20
airControl: 0
--- !u!114 &11400006
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 83c81407209f85e4c87c0cda8b32868e, type: 3}
m_Name:
m_EditorClassIdentifier:
Camera: {fileID: 2000000}
motionBob:
HorizontalBobRange: .100000001
VerticalBobRange: .0500000007
Bobcurve:
serializedVersion: 2
m_Curve:
- time: 0
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
- time: .5
value: 1
inSlope: 0
outSlope: 0
tangentMode: 0
- time: 1
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
- time: 1.5
value: -1
inSlope: 0
outSlope: 0
tangentMode: 0
- time: 2
value: 0
inSlope: 0
outSlope: 0
tangentMode: 0
m_PreInfinity: 2
m_PostInfinity: 2
VerticaltoHorizontalRatio: 2
jumpAndLandingBob:
BobDuration: .150000006
BobAmount: .200000003
rigidbodyFirstPersonController: {fileID: 11400004}
StrideInterval: 4
RunningStrideLengthen: .722000003
--- !u!136 &13600000
CapsuleCollider:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100006}
m_Material: {fileID: 13400000, guid: c2815a7ab32e42c4bb42f59caacb8ec1, type: 2}
m_IsTrigger: 0
m_Enabled: 1
m_Radius: .5
m_Height: 1.60000002
m_Direction: 1
m_Center: {x: 0, y: 0, z: 0}
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 100006}
m_IsPrefabParent: 1
@@ -0,0 +1,259 @@
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using UnityStandardAssets.Utility;
using Random = UnityEngine.Random;

namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (CharacterController))]
[RequireComponent(typeof (AudioSource))]
public class FirstPersonController : MonoBehaviour
{
[SerializeField] private bool m_IsWalking;
[SerializeField] private float m_WalkSpeed;
[SerializeField] private float m_RunSpeed;
[SerializeField] [Range(0f, 1f)] private float m_RunstepLenghten;
[SerializeField] private float m_JumpSpeed;
[SerializeField] private float m_StickToGroundForce;
[SerializeField] private float m_GravityMultiplier;
[SerializeField] private MouseLook m_MouseLook;
[SerializeField] private bool m_UseFovKick;
[SerializeField] private FOVKick m_FovKick = new FOVKick();
[SerializeField] private bool m_UseHeadBob;
[SerializeField] private CurveControlledBob m_HeadBob = new CurveControlledBob();
[SerializeField] private LerpControlledBob m_JumpBob = new LerpControlledBob();
[SerializeField] private float m_StepInterval;
[SerializeField] private AudioClip[] m_FootstepSounds; // an array of footstep sounds that will be randomly selected from.
[SerializeField] private AudioClip m_JumpSound; // the sound played when character leaves the ground.
[SerializeField] private AudioClip m_LandSound; // the sound played when character touches back on ground.

private Camera m_Camera;
private bool m_Jump;
private float m_YRotation;
private Vector2 m_Input;
private Vector3 m_MoveDir = Vector3.zero;
private CharacterController m_CharacterController;
private CollisionFlags m_CollisionFlags;
private bool m_PreviouslyGrounded;
private Vector3 m_OriginalCameraPosition;
private float m_StepCycle;
private float m_NextStep;
private bool m_Jumping;
private AudioSource m_AudioSource;

// Use this for initialization
private void Start()
{
m_CharacterController = GetComponent<CharacterController>();
m_Camera = Camera.main;
m_OriginalCameraPosition = m_Camera.transform.localPosition;
m_FovKick.Setup(m_Camera);
m_HeadBob.Setup(m_Camera, m_StepInterval);
m_StepCycle = 0f;
m_NextStep = m_StepCycle/2f;
m_Jumping = false;
m_AudioSource = GetComponent<AudioSource>();
m_MouseLook.Init(transform , m_Camera.transform);
}


// Update is called once per frame
private void Update()
{
RotateView();
// the jump state needs to read here to make sure it is not missed
if (!m_Jump)
{
m_Jump = CrossPlatformInputManager.GetButtonDown("Jump");
}

if (!m_PreviouslyGrounded && m_CharacterController.isGrounded)
{
StartCoroutine(m_JumpBob.DoBobCycle());
PlayLandingSound();
m_MoveDir.y = 0f;
m_Jumping = false;
}
if (!m_CharacterController.isGrounded && !m_Jumping && m_PreviouslyGrounded)
{
m_MoveDir.y = 0f;
}

m_PreviouslyGrounded = m_CharacterController.isGrounded;
}


private void PlayLandingSound()
{
m_AudioSource.clip = m_LandSound;
m_AudioSource.Play();
m_NextStep = m_StepCycle + .5f;
}


private void FixedUpdate()
{
float speed;
GetInput(out speed);
// always move along the camera forward as it is the direction that it being aimed at
Vector3 desiredMove = transform.forward*m_Input.y + transform.right*m_Input.x;

// get a normal for the surface that is being touched to move along it
RaycastHit hitInfo;
Physics.SphereCast(transform.position, m_CharacterController.radius, Vector3.down, out hitInfo,
m_CharacterController.height/2f, ~0, QueryTriggerInteraction.Ignore);
desiredMove = Vector3.ProjectOnPlane(desiredMove, hitInfo.normal).normalized;

m_MoveDir.x = desiredMove.x*speed;
m_MoveDir.z = desiredMove.z*speed;


if (m_CharacterController.isGrounded)
{
m_MoveDir.y = -m_StickToGroundForce;

if (m_Jump)
{
m_MoveDir.y = m_JumpSpeed;
PlayJumpSound();
m_Jump = false;
m_Jumping = true;
}
}
else
{
m_MoveDir += Physics.gravity*m_GravityMultiplier*Time.fixedDeltaTime;
}
m_CollisionFlags = m_CharacterController.Move(m_MoveDir*Time.fixedDeltaTime);

ProgressStepCycle(speed);
UpdateCameraPosition(speed);

m_MouseLook.UpdateCursorLock();
}


private void PlayJumpSound()
{
m_AudioSource.clip = m_JumpSound;
m_AudioSource.Play();
}


private void ProgressStepCycle(float speed)
{
if (m_CharacterController.velocity.sqrMagnitude > 0 && (m_Input.x != 0 || m_Input.y != 0))
{
m_StepCycle += (m_CharacterController.velocity.magnitude + (speed*(m_IsWalking ? 1f : m_RunstepLenghten)))*
Time.fixedDeltaTime;
}

if (!(m_StepCycle > m_NextStep))
{
return;
}

m_NextStep = m_StepCycle + m_StepInterval;

PlayFootStepAudio();
}


private void PlayFootStepAudio()
{
if (!m_CharacterController.isGrounded)
{
return;
}
// pick & play a random footstep sound from the array,
// excluding sound at index 0
int n = Random.Range(1, m_FootstepSounds.Length);
m_AudioSource.clip = m_FootstepSounds[n];
m_AudioSource.PlayOneShot(m_AudioSource.clip);
// move picked sound to index 0 so it's not picked next time
m_FootstepSounds[n] = m_FootstepSounds[0];
m_FootstepSounds[0] = m_AudioSource.clip;
}


private void UpdateCameraPosition(float speed)
{
Vector3 newCameraPosition;
if (!m_UseHeadBob)
{
return;
}
if (m_CharacterController.velocity.magnitude > 0 && m_CharacterController.isGrounded)
{
m_Camera.transform.localPosition =
m_HeadBob.DoHeadBob(m_CharacterController.velocity.magnitude +
(speed*(m_IsWalking ? 1f : m_RunstepLenghten)));
newCameraPosition = m_Camera.transform.localPosition;
newCameraPosition.y = m_Camera.transform.localPosition.y - m_JumpBob.Offset();
}
else
{
newCameraPosition = m_Camera.transform.localPosition;
newCameraPosition.y = m_OriginalCameraPosition.y - m_JumpBob.Offset();
}
m_Camera.transform.localPosition = newCameraPosition;
}


private void GetInput(out float speed)
{
// Read input
float horizontal = CrossPlatformInputManager.GetAxis("Horizontal");
float vertical = CrossPlatformInputManager.GetAxis("Vertical");

bool waswalking = m_IsWalking;

#if !MOBILE_INPUT
// On standalone builds, walk/run speed is modified by a key press.
// keep track of whether or not the character is walking or running
m_IsWalking = !Input.GetKey(KeyCode.LeftShift);
#endif
// set the desired speed to be walking or running
speed = m_IsWalking ? m_WalkSpeed : m_RunSpeed;
m_Input = new Vector2(horizontal, vertical);

// normalize input if it exceeds 1 in combined length:
if (m_Input.sqrMagnitude > 1)
{
m_Input.Normalize();
}

// handle speed change to give an fov kick
// only if the player is going to a run, is running and the fovkick is to be used
if (m_IsWalking != waswalking && m_UseFovKick && m_CharacterController.velocity.sqrMagnitude > 0)
{
StopAllCoroutines();
StartCoroutine(!m_IsWalking ? m_FovKick.FOVKickUp() : m_FovKick.FOVKickDown());
}
}


private void RotateView()
{
m_MouseLook.LookRotation (transform, m_Camera.transform);
}


private void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
//dont move the rigidbody if the character is on top of it
if (m_CollisionFlags == CollisionFlags.Below)
{
return;
}

if (body == null || body.isKinematic)
{
return;
}
body.AddForceAtPosition(m_CharacterController.velocity*0.1f, hit.point, ForceMode.Impulse);
}
}
}
@@ -0,0 +1,55 @@
using System;
using UnityEngine;
using UnityStandardAssets.Utility;

namespace UnityStandardAssets.Characters.FirstPerson
{
public class HeadBob : MonoBehaviour
{
public Camera Camera;
public CurveControlledBob motionBob = new CurveControlledBob();
public LerpControlledBob jumpAndLandingBob = new LerpControlledBob();
public RigidbodyFirstPersonController rigidbodyFirstPersonController;
public float StrideInterval;
[Range(0f, 1f)] public float RunningStrideLengthen;

// private CameraRefocus m_CameraRefocus;
private bool m_PreviouslyGrounded;
private Vector3 m_OriginalCameraPosition;


private void Start()
{
motionBob.Setup(Camera, StrideInterval);
m_OriginalCameraPosition = Camera.transform.localPosition;
// m_CameraRefocus = new CameraRefocus(Camera, transform.root.transform, Camera.transform.localPosition);
}


private void Update()
{
// m_CameraRefocus.GetFocusPoint();
Vector3 newCameraPosition;
if (rigidbodyFirstPersonController.Velocity.magnitude > 0 && rigidbodyFirstPersonController.Grounded)
{
Camera.transform.localPosition = motionBob.DoHeadBob(rigidbodyFirstPersonController.Velocity.magnitude*(rigidbodyFirstPersonController.Running ? RunningStrideLengthen : 1f));
newCameraPosition = Camera.transform.localPosition;
newCameraPosition.y = Camera.transform.localPosition.y - jumpAndLandingBob.Offset();
}
else
{
newCameraPosition = Camera.transform.localPosition;
newCameraPosition.y = m_OriginalCameraPosition.y - jumpAndLandingBob.Offset();
}
Camera.transform.localPosition = newCameraPosition;

if (!m_PreviouslyGrounded && rigidbodyFirstPersonController.Grounded)
{
StartCoroutine(jumpAndLandingBob.DoBobCycle());
}

m_PreviouslyGrounded = rigidbodyFirstPersonController.Grounded;
// m_CameraRefocus.SetFocusPoint();
}
}
}
@@ -0,0 +1,115 @@
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

namespace UnityStandardAssets.Characters.FirstPerson
{
[Serializable]
public class MouseLook
{
public float XSensitivity = 2f;
public float YSensitivity = 2f;
public bool clampVerticalRotation = true;
public float MinimumX = -90F;
public float MaximumX = 90F;
public bool smooth;
public float smoothTime = 5f;
public bool lockCursor = true;


private Quaternion m_CharacterTargetRot;
private Quaternion m_CameraTargetRot;
private bool m_cursorIsLocked = true;

public void Init(Transform character, Transform camera)
{
m_CharacterTargetRot = character.localRotation;
m_CameraTargetRot = camera.localRotation;
}


public void LookRotation(Transform character, Transform camera)
{
float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;

m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f);
m_CameraTargetRot *= Quaternion.Euler (-xRot, 0f, 0f);

if(clampVerticalRotation)
m_CameraTargetRot = ClampRotationAroundXAxis (m_CameraTargetRot);

if(smooth)
{
character.localRotation = Quaternion.Slerp (character.localRotation, m_CharacterTargetRot,
smoothTime * Time.deltaTime);
camera.localRotation = Quaternion.Slerp (camera.localRotation, m_CameraTargetRot,
smoothTime * Time.deltaTime);
}
else
{
character.localRotation = m_CharacterTargetRot;
camera.localRotation = m_CameraTargetRot;
}

UpdateCursorLock();
}

public void SetCursorLock(bool value)
{
lockCursor = value;
if(!lockCursor)
{//we force unlock the cursor if the user disable the cursor locking helper
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}

public void UpdateCursorLock()
{
//if the user set "lockCursor" we check & properly lock the cursos
if (lockCursor)
InternalLockUpdate();
}

private void InternalLockUpdate()
{
if(Input.GetKeyUp(KeyCode.Escape))
{
m_cursorIsLocked = false;
}
else if(Input.GetMouseButtonUp(0))
{
m_cursorIsLocked = true;
}

if (m_cursorIsLocked)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
else if (!m_cursorIsLocked)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}

Quaternion ClampRotationAroundXAxis(Quaternion q)
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1.0f;

float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan (q.x);

angleX = Mathf.Clamp (angleX, MinimumX, MaximumX);

q.x = Mathf.Tan (0.5f * Mathf.Deg2Rad * angleX);

return q;
}

}
}
@@ -0,0 +1,265 @@
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

namespace UnityStandardAssets.Characters.FirstPerson
{
[RequireComponent(typeof (Rigidbody))]
[RequireComponent(typeof (CapsuleCollider))]
public class RigidbodyFirstPersonController : MonoBehaviour
{
[Serializable]
public class MovementSettings
{
public float ForwardSpeed = 8.0f; // Speed when walking forward
public float BackwardSpeed = 4.0f; // Speed when walking backwards
public float StrafeSpeed = 4.0f; // Speed when walking sideways
public float RunMultiplier = 2.0f; // Speed when sprinting
public KeyCode RunKey = KeyCode.LeftShift;
public float JumpForce = 30f;
public AnimationCurve SlopeCurveModifier = new AnimationCurve(new Keyframe(-90.0f, 1.0f), new Keyframe(0.0f, 1.0f), new Keyframe(90.0f, 0.0f));
[HideInInspector] public float CurrentTargetSpeed = 8f;

#if !MOBILE_INPUT
private bool m_Running;
#endif

public void UpdateDesiredTargetSpeed(Vector2 input)
{
if (input == Vector2.zero) return;
if (input.x > 0 || input.x < 0)
{
//strafe
CurrentTargetSpeed = StrafeSpeed;
}
if (input.y < 0)
{
//backwards
CurrentTargetSpeed = BackwardSpeed;
}
if (input.y > 0)
{
//forwards
//handled last as if strafing and moving forward at the same time forwards speed should take precedence
CurrentTargetSpeed = ForwardSpeed;
}
#if !MOBILE_INPUT
if (Input.GetKey(RunKey))
{
CurrentTargetSpeed *= RunMultiplier;
m_Running = true;
}
else
{
m_Running = false;
}
#endif
}

#if !MOBILE_INPUT
public bool Running
{
get { return m_Running; }
}
#endif
}


[Serializable]
public class AdvancedSettings
{
public float groundCheckDistance = 0.01f; // distance for checking if the controller is grounded ( 0.01f seems to work best for this )
public float stickToGroundHelperDistance = 0.5f; // stops the character
public float slowDownRate = 20f; // rate at which the controller comes to a stop when there is no input
public bool airControl; // can the user control the direction that is being moved in the air
[Tooltip("set it to 0.1 or more if you get stuck in wall")]
public float shellOffset; //reduce the radius by that ratio to avoid getting stuck in wall (a value of 0.1f is nice)
}


public Camera cam;
public MovementSettings movementSettings = new MovementSettings();
public MouseLook mouseLook = new MouseLook();
public AdvancedSettings advancedSettings = new AdvancedSettings();


private Rigidbody m_RigidBody;
private CapsuleCollider m_Capsule;
private float m_YRotation;
private Vector3 m_GroundContactNormal;
private bool m_Jump, m_PreviouslyGrounded, m_Jumping, m_IsGrounded;


public Vector3 Velocity
{
get { return m_RigidBody.velocity; }
}

public bool Grounded
{
get { return m_IsGrounded; }
}

public bool Jumping
{
get { return m_Jumping; }
}

public bool Running
{
get
{
#if !MOBILE_INPUT
return movementSettings.Running;
#else
return false;
#endif
}
}


private void Start()
{
m_RigidBody = GetComponent<Rigidbody>();
m_Capsule = GetComponent<CapsuleCollider>();
mouseLook.Init (transform, cam.transform);
}


private void Update()
{
RotateView();

if (CrossPlatformInputManager.GetButtonDown("Jump") && !m_Jump)
{
m_Jump = true;
}
}


private void FixedUpdate()
{
GroundCheck();
Vector2 input = GetInput();

if ((Mathf.Abs(input.x) > float.Epsilon || Mathf.Abs(input.y) > float.Epsilon) && (advancedSettings.airControl || m_IsGrounded))
{
// always move along the camera forward as it is the direction that it being aimed at
Vector3 desiredMove = cam.transform.forward*input.y + cam.transform.right*input.x;
desiredMove = Vector3.ProjectOnPlane(desiredMove, m_GroundContactNormal).normalized;

desiredMove.x = desiredMove.x*movementSettings.CurrentTargetSpeed;
desiredMove.z = desiredMove.z*movementSettings.CurrentTargetSpeed;
desiredMove.y = desiredMove.y*movementSettings.CurrentTargetSpeed;
if (m_RigidBody.velocity.sqrMagnitude <
(movementSettings.CurrentTargetSpeed*movementSettings.CurrentTargetSpeed))
{
m_RigidBody.AddForce(desiredMove*SlopeMultiplier(), ForceMode.Impulse);
}
}

if (m_IsGrounded)
{
m_RigidBody.drag = 5f;

if (m_Jump)
{
m_RigidBody.drag = 0f;
m_RigidBody.velocity = new Vector3(m_RigidBody.velocity.x, 0f, m_RigidBody.velocity.z);
m_RigidBody.AddForce(new Vector3(0f, movementSettings.JumpForce, 0f), ForceMode.Impulse);
m_Jumping = true;
}

if (!m_Jumping && Mathf.Abs(input.x) < float.Epsilon && Mathf.Abs(input.y) < float.Epsilon && m_RigidBody.velocity.magnitude < 1f)
{
m_RigidBody.Sleep();
}
}
else
{
m_RigidBody.drag = 0f;
if (m_PreviouslyGrounded && !m_Jumping)
{
StickToGroundHelper();
}
}
m_Jump = false;
}


private float SlopeMultiplier()
{
float angle = Vector3.Angle(m_GroundContactNormal, Vector3.up);
return movementSettings.SlopeCurveModifier.Evaluate(angle);
}


private void StickToGroundHelper()
{
RaycastHit hitInfo;
if (Physics.SphereCast(transform.position, m_Capsule.radius * (1.0f - advancedSettings.shellOffset), Vector3.down, out hitInfo,
((m_Capsule.height/2f) - m_Capsule.radius) +
advancedSettings.stickToGroundHelperDistance, ~0, QueryTriggerInteraction.Ignore))
{
if (Mathf.Abs(Vector3.Angle(hitInfo.normal, Vector3.up)) < 85f)
{
m_RigidBody.velocity = Vector3.ProjectOnPlane(m_RigidBody.velocity, hitInfo.normal);
}
}
}


private Vector2 GetInput()
{

Vector2 input = new Vector2
{
x = CrossPlatformInputManager.GetAxis("Horizontal"),
y = CrossPlatformInputManager.GetAxis("Vertical")
};
movementSettings.UpdateDesiredTargetSpeed(input);
return input;
}


private void RotateView()
{
//avoids the mouse looking if the game is effectively paused
if (Mathf.Abs(Time.timeScale) < float.Epsilon) return;

// get the rotation before it's changed
float oldYRotation = transform.eulerAngles.y;

mouseLook.LookRotation (transform, cam.transform);

if (m_IsGrounded || advancedSettings.airControl)
{
// Rotate the rigidbody velocity to match the new direction that the character is looking
Quaternion velRotation = Quaternion.AngleAxis(transform.eulerAngles.y - oldYRotation, Vector3.up);
m_RigidBody.velocity = velRotation*m_RigidBody.velocity;
}
}

/// sphere cast down just beyond the bottom of the capsule to see if the capsule is colliding round the bottom
private void GroundCheck()
{
m_PreviouslyGrounded = m_IsGrounded;
RaycastHit hitInfo;
if (Physics.SphereCast(transform.position, m_Capsule.radius * (1.0f - advancedSettings.shellOffset), Vector3.down, out hitInfo,
((m_Capsule.height/2f) - m_Capsule.radius) + advancedSettings.groundCheckDistance, ~0, QueryTriggerInteraction.Ignore))
{
m_IsGrounded = true;
m_GroundContactNormal = hitInfo.normal;
}
else
{
m_IsGrounded = false;
m_GroundContactNormal = Vector3.up;
}
if (!m_PreviouslyGrounded && m_IsGrounded && m_Jumping)
{
m_Jumping = false;
}
}
}
}
@@ -0,0 +1,32 @@

Importing the CrossPlatformInput package adds a menu item to Unity, "CrossPlatformInput", which allows you to enable or disable the CrossPlatformInput in the editor. You must enable the CrossPlatformInput in order to see the control rigs in the editor, and to start using Unity Remote to control your game.

The CrossPlatformInput sample assets contains two main sections.

1) The folder of prefabs provide a variety of ready-to-use "MobileControlRigs". Each control rig is suitable for a different purpose, and each implements the touch or tilt-based equivalent of some of the default standalone axes or buttons. These are ready to drop into your scene, and to use them you simply need to read the axes via the CrossPlatformInput class, rather than Unity's regular Input class.

2) The set of scripts provided are the scripts we used to put together the control rigs prefabs. They provide a simplified way of reading basic mobile input, such as tilt, taps and swipe gestures. They are designed so that various mobile controls can be read in the same way as regular Unity axes and buttons. You can use these scripts to build your own MobileControlRigs.



For example the Car control rig feeds the tilt input of the mobile device to the "Horizontal" axis, and has an accelerator and brake touch button which are fed as a pair into the "Vertical" axis. These are virtual equivalents of the real "Horizontal" and "Vertical" axes defined in Unity's Input Manager.

Therefore when you read CrossPlatformInput.GetAxis("Horizontal"), you will either get the "real" input value - if your build target is non-mobile, or the value from the mobile control rig - if your build target is set to a mobile platform.

The CrossPlatformInput scripts and prefabs are provided together as an example of how you can implement a cross-platform control solution in Unity. They also allow us to provide our other sample scenes in a form that can be published as standalone or to mobile targets with no modification.

To use the CrossPlatformInput, you need to drop a "Mobile Control Rig" into your scene (or create your own), and then make calls to CrossPlatformInput functions, referring to the axes and buttons that the Rig implements.

When reading input from the CrossPlatformInput class, the values returned will be taken either from Unity's Input Manager settings, or from the mobile-specific controls set up, depending on which build target you have selected.

The CrossPlatformInput class is designed to be called instead of Unity's own Input class, and so mirrors certain parts of the Input API - specifically the functions relating to Axes and Buttons:
GetAxis, GetAxisRaw
GetButton, GetButtonDown, GetButtonUp

Notes for coders:
This package sets two compiler define symbols. One is always set automatically, the other is optionally set from a menu item.

Importing the "CrossPlatformInput" package will automatically add a compiler define symbol, "CROSS_PLATFORM_INPUT". This enables the CrossPlatformInput functions defined in some of the other Sample Asset packages (such as the Characters, Planes, etc). Without this symbol defined, those packages use Unity's regular Input class, which means they can be imported alone and still work without the CrossPlatformInput package.

The optional define (which is set by default, but can be disabled using the "Mobile Input" menu), is "MOBILE_INPUT". This causes the MobileControlRigs to become active when a mobile build target is selected. It also enables certain mobile-specific control nuances in some of the packages, which make more sense when the character or vehicle is being controlled using mobile input (such as auto-leveling the character's look direction). This define is optional because some developers prefer to use standalone input methods instead of the Unity Remote app, when testing mobile apps in the editor's play mode.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

@@ -0,0 +1,376 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &100000
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 224: {fileID: 22400000}
- 223: {fileID: 22300000}
- 114: {fileID: 11400000}
- 114: {fileID: 11400012}
m_Layer: 5
m_Name: MobileSingleStickControl
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &100002
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 224: {fileID: 22400002}
- 222: {fileID: 22200002}
- 114: {fileID: 11400010}
- 114: {fileID: 11400008}
m_Layer: 5
m_Name: MobileJoystick
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &100004
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 224: {fileID: 22400004}
- 222: {fileID: 22200000}
- 114: {fileID: 11400006}
- 114: {fileID: 11400004}
- 114: {fileID: 11400002}
m_Layer: 5
m_Name: JumpButton
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &100006
GameObject:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 224: {fileID: 22400006}
- 222: {fileID: 22200004}
- 114: {fileID: 11400016}
- 114: {fileID: 11400014}
m_Layer: 5
m_Name: Text
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100000}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1301386320, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
ignoreReversedGraphics: 1
blockingObjects: 0
m_BlockingMask:
serializedVersion: 2
m_Bits: 4294967295
--- !u!114 &11400002
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 85bf3be603548374ca46f521a3aa7fda, type: 3}
m_Name:
m_EditorClassIdentifier:
Name: Jump
--- !u!114 &11400004
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -1862395651, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
delegates:
- eventID: 2
callback:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 11400002}
m_MethodName: SetDownState
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument: Jump
m_BoolArgument: 0
m_CallState: 1
m_TypeName: UnityEngine.EventSystems.EventTrigger+TriggerEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
- eventID: 3
callback:
m_PersistentCalls:
m_Calls:
- m_Target: {fileID: 11400002}
m_MethodName: SetUpState
m_Mode: 1
m_Arguments:
m_ObjectArgument: {fileID: 0}
m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine, Version=0.0.0.0,
Culture=neutral, PublicKeyToken=null
m_IntArgument: 0
m_FloatArgument: 0
m_StringArgument: Jump
m_BoolArgument: 0
m_CallState: 1
m_TypeName: UnityEngine.EventSystems.EventTrigger+TriggerEvent, UnityEngine.UI,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
--- !u!114 &11400006
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Sprite: {fileID: 21300000, guid: 3d8675433a508ec47b8f895201eacf20, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &11400008
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100002}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 00c3c865782347f41b6358d9fba14b48, type: 3}
m_Name:
m_EditorClassIdentifier:
MovementRange: 100
axesToUse: 0
horizontalAxisName: Horizontal
verticalAxisName: Vertical
--- !u!114 &11400010
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100002}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: -765806418, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1}
m_Sprite: {fileID: 21300000, guid: 9866a92691696b346901281f2b329034, type: 3}
m_Type: 0
m_PreserveAspect: 0
m_FillCenter: 1
m_FillMethod: 4
m_FillAmount: 1
m_FillClockwise: 1
m_FillOrigin: 0
--- !u!114 &11400012
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100000}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71398ce7fbc3a5b4fa50b50bd54317a7, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!114 &11400014
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100006}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 1573420865, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_EffectColor: {r: 0, g: 0, b: 0, a: .125490203}
m_EffectDistance: {x: 2, y: -2}
m_UseGraphicAlpha: 1
--- !u!114 &11400016
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100006}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 708705254, guid: f5f67c52d1564df4a8936ccd202a3bd8, type: 3}
m_Name:
m_EditorClassIdentifier:
m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: .643137276}
m_FontData:
m_Font: {fileID: 12800000, guid: 01cd679a1b9ee48bf9c546f6ce2cb97e, type: 3}
m_FontSize: 26
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 10
m_MaxSize: 40
m_Alignment: 4
m_RichText: 1
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: Jump
--- !u!222 &22200000
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
--- !u!222 &22200002
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100002}
--- !u!222 &22200004
CanvasRenderer:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100006}
--- !u!223 &22300000
Canvas:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100000}
m_Enabled: 1
serializedVersion: 2
m_RenderMode: 0
m_Camera: {fileID: 0}
m_PlaneDistance: 100
m_PixelPerfect: 1
m_ReceivesEvents: 1
m_OverrideSorting: 0
m_OverridePixelPerfect: 0
m_SortingLayerID: 0
m_SortingOrder: 0
--- !u!224 &22400000
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100000}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 0, y: 0, z: 0}
m_Children:
- {fileID: 22400004}
- {fileID: 22400002}
m_Father: {fileID: 0}
m_RootOrder: 0
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 0, y: 0}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: 0, y: 0}
--- !u!224 &22400002
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100002}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 22400000}
m_RootOrder: 1
m_AnchorMin: {x: .160000011, y: .200000003}
m_AnchorMax: {x: .160000011, y: .200000003}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 80, y: 80}
m_Pivot: {x: .5, y: .5}
--- !u!224 &22400004
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 22400006}
m_Father: {fileID: 22400000}
m_RootOrder: 0
m_AnchorMin: {x: .779999971, y: .00999999978}
m_AnchorMax: {x: .99000001, y: .150000006}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: .5, y: .5}
--- !u!224 &22400006
RectTransform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100006}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 22400004}
m_RootOrder: 0
m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 0, y: 0}
m_SizeDelta: {x: 0, y: 0}
m_Pivot: {x: .5, y: .5}
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 100000}
m_IsPrefabParent: 1
@@ -0,0 +1,144 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!1 &100000
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 400000}
- 114: {fileID: 11400004}
m_Layer: 0
m_Name: MobileTiltControlRig
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &100002
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 400002}
- 114: {fileID: 11400000}
m_Layer: 0
m_Name: TiltSteerInputH
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!1 &100004
GameObject:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
serializedVersion: 4
m_Component:
- 4: {fileID: 400004}
- 114: {fileID: 11400002}
m_Layer: 0
m_Name: TiltSteerInputV
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
--- !u!4 &400000
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100000}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: 385.509033, y: 268.018066, z: -62.2695312}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children:
- {fileID: 400004}
- {fileID: 400002}
m_Father: {fileID: 0}
m_RootOrder: 0
--- !u!4 &400002
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100002}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -928.193604, y: -473.736786, z: -.00032043457}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 400000}
m_RootOrder: 1
--- !u!4 &400004
Transform:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
m_LocalPosition: {x: -928.193604, y: -473.736786, z: -.00032043457}
m_LocalScale: {x: 1, y: 1, z: 1}
m_Children: []
m_Father: {fileID: 400000}
m_RootOrder: 0
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100002}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5c2d84226fbbaf94e9c1451f1c39b06a, type: 3}
m_Name:
m_EditorClassIdentifier:
mapping:
type: 0
axisName: Horizontal
tiltAroundAxis: 0
fullTiltAngle: 50
centreAngleOffset: 0
--- !u!114 &11400002
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100004}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5c2d84226fbbaf94e9c1451f1c39b06a, type: 3}
m_Name:
m_EditorClassIdentifier:
mapping:
type: 0
axisName: Vertical
tiltAroundAxis: 1
fullTiltAngle: -35
centreAngleOffset: 45
--- !u!114 &11400004
MonoBehaviour:
m_ObjectHideFlags: 1
m_PrefabParentObject: {fileID: 0}
m_PrefabInternal: {fileID: 100100000}
m_GameObject: {fileID: 100000}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 71398ce7fbc3a5b4fa50b50bd54317a7, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1001 &100100000
Prefab:
m_ObjectHideFlags: 1
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications: []
m_RemovedComponents: []
m_ParentPrefab: {fileID: 0}
m_RootGameObject: {fileID: 100000}
m_IsPrefabParent: 1
@@ -0,0 +1,75 @@
using System;
using UnityEngine;
using UnityEngine.EventSystems;

namespace UnityStandardAssets.CrossPlatformInput
{
public class AxisTouchButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
// designed to work in a pair with another axis touch button
// (typically with one having -1 and one having 1 axisValues)
public string axisName = "Horizontal"; // The name of the axis
public float axisValue = 1; // The axis that the value has
public float responseSpeed = 3; // The speed at which the axis touch button responds
public float returnToCentreSpeed = 3; // The speed at which the button will return to its centre

AxisTouchButton m_PairedWith; // Which button this one is paired with
CrossPlatformInputManager.VirtualAxis m_Axis; // A reference to the virtual axis as it is in the cross platform input

void OnEnable()
{
if (!CrossPlatformInputManager.AxisExists(axisName))
{
// if the axis doesnt exist create a new one in cross platform input
m_Axis = new CrossPlatformInputManager.VirtualAxis(axisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_Axis);
}
else
{
m_Axis = CrossPlatformInputManager.VirtualAxisReference(axisName);
}
FindPairedButton();
}

void FindPairedButton()
{
// find the other button witch which this button should be paired
// (it should have the same axisName)
var otherAxisButtons = FindObjectsOfType(typeof(AxisTouchButton)) as AxisTouchButton[];

if (otherAxisButtons != null)
{
for (int i = 0; i < otherAxisButtons.Length; i++)
{
if (otherAxisButtons[i].axisName == axisName && otherAxisButtons[i] != this)
{
m_PairedWith = otherAxisButtons[i];
}
}
}
}

void OnDisable()
{
// The object is disabled so remove it from the cross platform input system
m_Axis.Remove();
}


public void OnPointerDown(PointerEventData data)
{
if (m_PairedWith == null)
{
FindPairedButton();
}
// update the axis and record that the button has been pressed this frame
m_Axis.Update(Mathf.MoveTowards(m_Axis.GetValue, axisValue, responseSpeed * Time.deltaTime));
}


public void OnPointerUp(PointerEventData data)
{
m_Axis.Update(Mathf.MoveTowards(m_Axis.GetValue, 0, responseSpeed * Time.deltaTime));
}
}
}
@@ -0,0 +1,50 @@
using System;
using UnityEngine;

namespace UnityStandardAssets.CrossPlatformInput
{
public class ButtonHandler : MonoBehaviour
{

public string Name;

void OnEnable()
{

}

public void SetDownState()
{
CrossPlatformInputManager.SetButtonDown(Name);
}


public void SetUpState()
{
CrossPlatformInputManager.SetButtonUp(Name);
}


public void SetAxisPositiveState()
{
CrossPlatformInputManager.SetAxisPositive(Name);
}


public void SetAxisNeutralState()
{
CrossPlatformInputManager.SetAxisZero(Name);
}


public void SetAxisNegativeState()
{
CrossPlatformInputManager.SetAxisNegative(Name);
}

public void Update()
{

}
}
}
@@ -0,0 +1,318 @@
using System;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput.PlatformSpecific;

namespace UnityStandardAssets.CrossPlatformInput
{
public static class CrossPlatformInputManager
{
public enum ActiveInputMethod
{
Hardware,
Touch
}


private static VirtualInput activeInput;

private static VirtualInput s_TouchInput;
private static VirtualInput s_HardwareInput;


static CrossPlatformInputManager()
{
s_TouchInput = new MobileInput();
s_HardwareInput = new StandaloneInput();
#if MOBILE_INPUT
activeInput = s_TouchInput;
#else
activeInput = s_HardwareInput;
#endif
}

public static void SwitchActiveInputMethod(ActiveInputMethod activeInputMethod)
{
switch (activeInputMethod)
{
case ActiveInputMethod.Hardware:
activeInput = s_HardwareInput;
break;

case ActiveInputMethod.Touch:
activeInput = s_TouchInput;
break;
}
}

public static bool AxisExists(string name)
{
return activeInput.AxisExists(name);
}

public static bool ButtonExists(string name)
{
return activeInput.ButtonExists(name);
}

public static void RegisterVirtualAxis(VirtualAxis axis)
{
activeInput.RegisterVirtualAxis(axis);
}


public static void RegisterVirtualButton(VirtualButton button)
{
activeInput.RegisterVirtualButton(button);
}


public static void UnRegisterVirtualAxis(string name)
{
if (name == null)
{
throw new ArgumentNullException("name");
}
activeInput.UnRegisterVirtualAxis(name);
}


public static void UnRegisterVirtualButton(string name)
{
activeInput.UnRegisterVirtualButton(name);
}


// returns a reference to a named virtual axis if it exists otherwise null
public static VirtualAxis VirtualAxisReference(string name)
{
return activeInput.VirtualAxisReference(name);
}


// returns the platform appropriate axis for the given name
public static float GetAxis(string name)
{
return GetAxis(name, false);
}


public static float GetAxisRaw(string name)
{
return GetAxis(name, true);
}


// private function handles both types of axis (raw and not raw)
private static float GetAxis(string name, bool raw)
{
return activeInput.GetAxis(name, raw);
}


// -- Button handling --
public static bool GetButton(string name)
{
return activeInput.GetButton(name);
}


public static bool GetButtonDown(string name)
{
return activeInput.GetButtonDown(name);
}


public static bool GetButtonUp(string name)
{
return activeInput.GetButtonUp(name);
}


public static void SetButtonDown(string name)
{
activeInput.SetButtonDown(name);
}


public static void SetButtonUp(string name)
{
activeInput.SetButtonUp(name);
}


public static void SetAxisPositive(string name)
{
activeInput.SetAxisPositive(name);
}


public static void SetAxisNegative(string name)
{
activeInput.SetAxisNegative(name);
}


public static void SetAxisZero(string name)
{
activeInput.SetAxisZero(name);
}


public static void SetAxis(string name, float value)
{
activeInput.SetAxis(name, value);
}


public static Vector3 mousePosition
{
get { return activeInput.MousePosition(); }
}


public static void SetVirtualMousePositionX(float f)
{
activeInput.SetVirtualMousePositionX(f);
}


public static void SetVirtualMousePositionY(float f)
{
activeInput.SetVirtualMousePositionY(f);
}


public static void SetVirtualMousePositionZ(float f)
{
activeInput.SetVirtualMousePositionZ(f);
}


// virtual axis and button classes - applies to mobile input
// Can be mapped to touch joysticks, tilt, gyro, etc, depending on desired implementation.
// Could also be implemented by other input devices - kinect, electronic sensors, etc
public class VirtualAxis
{
public string name { get; private set; }
private float m_Value;
public bool matchWithInputManager { get; private set; }


public VirtualAxis(string name)
: this(name, true)
{
}


public VirtualAxis(string name, bool matchToInputSettings)
{
this.name = name;
matchWithInputManager = matchToInputSettings;
}


// removes an axes from the cross platform input system
public void Remove()
{
UnRegisterVirtualAxis(name);
}


// a controller gameobject (eg. a virtual thumbstick) should update this class
public void Update(float value)
{
m_Value = value;
}


public float GetValue
{
get { return m_Value; }
}


public float GetValueRaw
{
get { return m_Value; }
}
}

// a controller gameobject (eg. a virtual GUI button) should call the
// 'pressed' function of this class. Other objects can then read the
// Get/Down/Up state of this button.
public class VirtualButton
{
public string name { get; private set; }
public bool matchWithInputManager { get; private set; }

private int m_LastPressedFrame = -5;
private int m_ReleasedFrame = -5;
private bool m_Pressed;


public VirtualButton(string name)
: this(name, true)
{
}


public VirtualButton(string name, bool matchToInputSettings)
{
this.name = name;
matchWithInputManager = matchToInputSettings;
}


// A controller gameobject should call this function when the button is pressed down
public void Pressed()
{
if (m_Pressed)
{
return;
}
m_Pressed = true;
m_LastPressedFrame = Time.frameCount;
}


// A controller gameobject should call this function when the button is released
public void Released()
{
m_Pressed = false;
m_ReleasedFrame = Time.frameCount;
}


// the controller gameobject should call Remove when the button is destroyed or disabled
public void Remove()
{
UnRegisterVirtualButton(name);
}


// these are the states of the button which can be read via the cross platform input system
public bool GetButton
{
get { return m_Pressed; }
}


public bool GetButtonDown
{
get
{
return m_LastPressedFrame - Time.frameCount == -1;
}
}


public bool GetButtonUp
{
get
{
return (m_ReleasedFrame == Time.frameCount - 1);
}
}
}
}
}
@@ -0,0 +1,17 @@
using System;
using UnityEngine;

namespace UnityStandardAssets.CrossPlatformInput
{
public class InputAxisScrollbar : MonoBehaviour
{
public string axis;

void Update() { }

public void HandleInput(float value)
{
CrossPlatformInputManager.SetAxis(axis, (value*2f) - 1f);
}
}
}
@@ -0,0 +1,118 @@
using System;
using UnityEngine;
using UnityEngine.EventSystems;

namespace UnityStandardAssets.CrossPlatformInput
{
public class Joystick : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler
{
public enum AxisOption
{
// Options for which axes to use
Both, // Use both
OnlyHorizontal, // Only horizontal
OnlyVertical // Only vertical
}

public int MovementRange = 100;
public AxisOption axesToUse = AxisOption.Both; // The options for the axes that the still will use
public string horizontalAxisName = "Horizontal"; // The name given to the horizontal axis for the cross platform input
public string verticalAxisName = "Vertical"; // The name given to the vertical axis for the cross platform input

Vector3 m_StartPos;
bool m_UseX; // Toggle for using the x axis
bool m_UseY; // Toggle for using the Y axis
CrossPlatformInputManager.VirtualAxis m_HorizontalVirtualAxis; // Reference to the joystick in the cross platform input
CrossPlatformInputManager.VirtualAxis m_VerticalVirtualAxis; // Reference to the joystick in the cross platform input

void OnEnable()
{
CreateVirtualAxes();
}

void Start()
{
m_StartPos = transform.position;
}

void UpdateVirtualAxes(Vector3 value)
{
var delta = m_StartPos - value;
delta.y = -delta.y;
delta /= MovementRange;
if (m_UseX)
{
m_HorizontalVirtualAxis.Update(-delta.x);
}

if (m_UseY)
{
m_VerticalVirtualAxis.Update(delta.y);
}
}

void CreateVirtualAxes()
{
// set axes to use
m_UseX = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyHorizontal);
m_UseY = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyVertical);

// create new axes based on axes to use
if (m_UseX)
{
m_HorizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_HorizontalVirtualAxis);
}
if (m_UseY)
{
m_VerticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_VerticalVirtualAxis);
}
}


public void OnDrag(PointerEventData data)
{
Vector3 newPos = Vector3.zero;

if (m_UseX)
{
int delta = (int)(data.position.x - m_StartPos.x);
delta = Mathf.Clamp(delta, - MovementRange, MovementRange);
newPos.x = delta;
}

if (m_UseY)
{
int delta = (int)(data.position.y - m_StartPos.y);
delta = Mathf.Clamp(delta, -MovementRange, MovementRange);
newPos.y = delta;
}
transform.position = new Vector3(m_StartPos.x + newPos.x, m_StartPos.y + newPos.y, m_StartPos.z + newPos.z);
UpdateVirtualAxes(transform.position);
}


public void OnPointerUp(PointerEventData data)
{
transform.position = m_StartPos;
UpdateVirtualAxes(m_StartPos);
}


public void OnPointerDown(PointerEventData data) { }

void OnDisable()
{
// remove the joysticks from the cross platform input
if (m_UseX)
{
m_HorizontalVirtualAxis.Remove();
}
if (m_UseY)
{
m_VerticalVirtualAxis.Remove();
}
}
}
}
@@ -0,0 +1,85 @@
using System;
#if UNITY_EDITOR
using UnityEditor;
#endif
using UnityEngine;


namespace UnityStandardAssets.CrossPlatformInput
{
[ExecuteInEditMode]
public class MobileControlRig : MonoBehaviour
{
// this script enables or disables the child objects of a control rig
// depending on whether the USE_MOBILE_INPUT define is declared.

// This define is set or unset by a menu item that is included with
// the Cross Platform Input package.

#if !UNITY_EDITOR
void OnEnable()
{
CheckEnableControlRig();
}
#endif

private void Start()
{
#if UNITY_EDITOR
if (Application.isPlaying) //if in the editor, need to check if we are playing, as start is also called just after exiting play
#endif
{
UnityEngine.EventSystems.EventSystem system = GameObject.FindObjectOfType<UnityEngine.EventSystems.EventSystem>();

if (system == null)
{//the scene have no event system, spawn one
GameObject o = new GameObject("EventSystem");

o.AddComponent<UnityEngine.EventSystems.EventSystem>();
o.AddComponent<UnityEngine.EventSystems.StandaloneInputModule>();
}
}
}

#if UNITY_EDITOR

private void OnEnable()
{
EditorUserBuildSettings.activeBuildTargetChanged += Update;
EditorApplication.update += Update;
}


private void OnDisable()
{
EditorUserBuildSettings.activeBuildTargetChanged -= Update;
EditorApplication.update -= Update;
}


private void Update()
{
CheckEnableControlRig();
}
#endif


private void CheckEnableControlRig()
{
#if MOBILE_INPUT
EnableControlRig(true);
#else
EnableControlRig(false);
#endif
}


private void EnableControlRig(bool enabled)
{
foreach (Transform t in transform)
{
t.gameObject.SetActive(enabled);
}
}
}
}
@@ -0,0 +1,133 @@
using System;
using UnityEngine;

namespace UnityStandardAssets.CrossPlatformInput.PlatformSpecific
{
public class MobileInput : VirtualInput
{
private void AddButton(string name)
{
// we have not registered this button yet so add it, happens in the constructor
CrossPlatformInputManager.RegisterVirtualButton(new CrossPlatformInputManager.VirtualButton(name));
}


private void AddAxes(string name)
{
// we have not registered this button yet so add it, happens in the constructor
CrossPlatformInputManager.RegisterVirtualAxis(new CrossPlatformInputManager.VirtualAxis(name));
}


public override float GetAxis(string name, bool raw)
{
if (!m_VirtualAxes.ContainsKey(name))
{
AddAxes(name);
}
return m_VirtualAxes[name].GetValue;
}


public override void SetButtonDown(string name)
{
if (!m_VirtualButtons.ContainsKey(name))
{
AddButton(name);
}
m_VirtualButtons[name].Pressed();
}


public override void SetButtonUp(string name)
{
if (!m_VirtualButtons.ContainsKey(name))
{
AddButton(name);
}
m_VirtualButtons[name].Released();
}


public override void SetAxisPositive(string name)
{
if (!m_VirtualAxes.ContainsKey(name))
{
AddAxes(name);
}
m_VirtualAxes[name].Update(1f);
}


public override void SetAxisNegative(string name)
{
if (!m_VirtualAxes.ContainsKey(name))
{
AddAxes(name);
}
m_VirtualAxes[name].Update(-1f);
}


public override void SetAxisZero(string name)
{
if (!m_VirtualAxes.ContainsKey(name))
{
AddAxes(name);
}
m_VirtualAxes[name].Update(0f);
}


public override void SetAxis(string name, float value)
{
if (!m_VirtualAxes.ContainsKey(name))
{
AddAxes(name);
}
m_VirtualAxes[name].Update(value);
}


public override bool GetButtonDown(string name)
{
if (m_VirtualButtons.ContainsKey(name))
{
return m_VirtualButtons[name].GetButtonDown;
}

AddButton(name);
return m_VirtualButtons[name].GetButtonDown;
}


public override bool GetButtonUp(string name)
{
if (m_VirtualButtons.ContainsKey(name))
{
return m_VirtualButtons[name].GetButtonUp;
}

AddButton(name);
return m_VirtualButtons[name].GetButtonUp;
}


public override bool GetButton(string name)
{
if (m_VirtualButtons.ContainsKey(name))
{
return m_VirtualButtons[name].GetButton;
}

AddButton(name);
return m_VirtualButtons[name].GetButton;
}


public override Vector3 MousePosition()
{
return virtualMousePosition;
}
}
}
@@ -0,0 +1,79 @@
using System;
using UnityEngine;

namespace UnityStandardAssets.CrossPlatformInput.PlatformSpecific
{
public class StandaloneInput : VirtualInput
{
public override float GetAxis(string name, bool raw)
{
return raw ? Input.GetAxisRaw(name) : Input.GetAxis(name);
}


public override bool GetButton(string name)
{
return Input.GetButton(name);
}


public override bool GetButtonDown(string name)
{
return Input.GetButtonDown(name);
}


public override bool GetButtonUp(string name)
{
return Input.GetButtonUp(name);
}


public override void SetButtonDown(string name)
{
throw new Exception(
" This is not possible to be called for standalone input. Please check your platform and code where this is called");
}


public override void SetButtonUp(string name)
{
throw new Exception(
" This is not possible to be called for standalone input. Please check your platform and code where this is called");
}


public override void SetAxisPositive(string name)
{
throw new Exception(
" This is not possible to be called for standalone input. Please check your platform and code where this is called");
}


public override void SetAxisNegative(string name)
{
throw new Exception(
" This is not possible to be called for standalone input. Please check your platform and code where this is called");
}


public override void SetAxisZero(string name)
{
throw new Exception(
" This is not possible to be called for standalone input. Please check your platform and code where this is called");
}


public override void SetAxis(string name, float value)
{
throw new Exception(
" This is not possible to be called for standalone input. Please check your platform and code where this is called");
}


public override Vector3 MousePosition()
{
return Input.mousePosition;
}
}
}
@@ -0,0 +1,145 @@
using System;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace UnityStandardAssets.CrossPlatformInput
{
// helps with managing tilt input on mobile devices
public class TiltInput : MonoBehaviour
{
// options for the various orientations
public enum AxisOptions
{
ForwardAxis,
SidewaysAxis,
}


[Serializable]
public class AxisMapping
{
public enum MappingType
{
NamedAxis,
MousePositionX,
MousePositionY,
MousePositionZ
};


public MappingType type;
public string axisName;
}


public AxisMapping mapping;
public AxisOptions tiltAroundAxis = AxisOptions.ForwardAxis;
public float fullTiltAngle = 25;
public float centreAngleOffset = 0;


private CrossPlatformInputManager.VirtualAxis m_SteerAxis;


private void OnEnable()
{
if (mapping.type == AxisMapping.MappingType.NamedAxis)
{
m_SteerAxis = new CrossPlatformInputManager.VirtualAxis(mapping.axisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_SteerAxis);
}
}


private void Update()
{
float angle = 0;
if (Input.acceleration != Vector3.zero)
{
switch (tiltAroundAxis)
{
case AxisOptions.ForwardAxis:
angle = Mathf.Atan2(Input.acceleration.x, -Input.acceleration.y)*Mathf.Rad2Deg +
centreAngleOffset;
break;
case AxisOptions.SidewaysAxis:
angle = Mathf.Atan2(Input.acceleration.z, -Input.acceleration.y)*Mathf.Rad2Deg +
centreAngleOffset;
break;
}
}

float axisValue = Mathf.InverseLerp(-fullTiltAngle, fullTiltAngle, angle)*2 - 1;
switch (mapping.type)
{
case AxisMapping.MappingType.NamedAxis:
m_SteerAxis.Update(axisValue);
break;
case AxisMapping.MappingType.MousePositionX:
CrossPlatformInputManager.SetVirtualMousePositionX(axisValue*Screen.width);
break;
case AxisMapping.MappingType.MousePositionY:
CrossPlatformInputManager.SetVirtualMousePositionY(axisValue*Screen.width);
break;
case AxisMapping.MappingType.MousePositionZ:
CrossPlatformInputManager.SetVirtualMousePositionZ(axisValue*Screen.width);
break;
}
}


private void OnDisable()
{
m_SteerAxis.Remove();
}
}
}


namespace UnityStandardAssets.CrossPlatformInput.Inspector
{
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof (TiltInput.AxisMapping))]
public class TiltInputAxisStylePropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty(position, label, property);

float x = position.x;
float y = position.y;
float inspectorWidth = position.width;

// Don't make child fields be indented
var indent = EditorGUI.indentLevel;
EditorGUI.indentLevel = 0;

var props = new[] {"type", "axisName"};
var widths = new[] {.4f, .6f};
if (property.FindPropertyRelative("type").enumValueIndex > 0)
{
// hide name if not a named axis
props = new[] {"type"};
widths = new[] {1f};
}
const float lineHeight = 18;
for (int n = 0; n < props.Length; ++n)
{
float w = widths[n]*inspectorWidth;

// Calculate rects
Rect rect = new Rect(x, y, w, lineHeight);
x += w;

EditorGUI.PropertyField(rect, property.FindPropertyRelative(props[n]), GUIContent.none);
}

// Set indent back to what it was
EditorGUI.indentLevel = indent;
EditorGUI.EndProperty();
}
}
#endif
}
@@ -0,0 +1,156 @@
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace UnityStandardAssets.CrossPlatformInput
{
[RequireComponent(typeof(Image))]
public class TouchPad : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
// Options for which axes to use
public enum AxisOption
{
Both, // Use both
OnlyHorizontal, // Only horizontal
OnlyVertical // Only vertical
}


public enum ControlStyle
{
Absolute, // operates from teh center of the image
Relative, // operates from the center of the initial touch
Swipe, // swipe to touch touch no maintained center
}


public AxisOption axesToUse = AxisOption.Both; // The options for the axes that the still will use
public ControlStyle controlStyle = ControlStyle.Absolute; // control style to use
public string horizontalAxisName = "Horizontal"; // The name given to the horizontal axis for the cross platform input
public string verticalAxisName = "Vertical"; // The name given to the vertical axis for the cross platform input
public float Xsensitivity = 1f;
public float Ysensitivity = 1f;

Vector3 m_StartPos;
Vector2 m_PreviousDelta;
Vector3 m_JoytickOutput;
bool m_UseX; // Toggle for using the x axis
bool m_UseY; // Toggle for using the Y axis
CrossPlatformInputManager.VirtualAxis m_HorizontalVirtualAxis; // Reference to the joystick in the cross platform input
CrossPlatformInputManager.VirtualAxis m_VerticalVirtualAxis; // Reference to the joystick in the cross platform input
bool m_Dragging;
int m_Id = -1;
Vector2 m_PreviousTouchPos; // swipe style control touch


#if !UNITY_EDITOR
private Vector3 m_Center;
private Image m_Image;
#else
Vector3 m_PreviousMouse;
#endif

void OnEnable()
{
CreateVirtualAxes();
}

void Start()
{
#if !UNITY_EDITOR
m_Image = GetComponent<Image>();
m_Center = m_Image.transform.position;
#endif
}

void CreateVirtualAxes()
{
// set axes to use
m_UseX = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyHorizontal);
m_UseY = (axesToUse == AxisOption.Both || axesToUse == AxisOption.OnlyVertical);

// create new axes based on axes to use
if (m_UseX)
{
m_HorizontalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(horizontalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_HorizontalVirtualAxis);
}
if (m_UseY)
{
m_VerticalVirtualAxis = new CrossPlatformInputManager.VirtualAxis(verticalAxisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_VerticalVirtualAxis);
}
}

void UpdateVirtualAxes(Vector3 value)
{
value = value.normalized;
if (m_UseX)
{
m_HorizontalVirtualAxis.Update(value.x);
}

if (m_UseY)
{
m_VerticalVirtualAxis.Update(value.y);
}
}


public void OnPointerDown(PointerEventData data)
{
m_Dragging = true;
m_Id = data.pointerId;
#if !UNITY_EDITOR
if (controlStyle != ControlStyle.Absolute )
m_Center = data.position;
#endif
}

void Update()
{
if (!m_Dragging)
{
return;
}
if (Input.touchCount >= m_Id + 1 && m_Id != -1)
{
#if !UNITY_EDITOR

if (controlStyle == ControlStyle.Swipe)
{
m_Center = m_PreviousTouchPos;
m_PreviousTouchPos = Input.touches[m_Id].position;
}
Vector2 pointerDelta = new Vector2(Input.touches[m_Id].position.x - m_Center.x , Input.touches[m_Id].position.y - m_Center.y).normalized;
pointerDelta.x *= Xsensitivity;
pointerDelta.y *= Ysensitivity;
#else
Vector2 pointerDelta;
pointerDelta.x = Input.mousePosition.x - m_PreviousMouse.x;
pointerDelta.y = Input.mousePosition.y - m_PreviousMouse.y;
m_PreviousMouse = new Vector3(Input.mousePosition.x, Input.mousePosition.y, 0f);
#endif
UpdateVirtualAxes(new Vector3(pointerDelta.x, pointerDelta.y, 0));
}
}


public void OnPointerUp(PointerEventData data)
{
m_Dragging = false;
m_Id = -1;
UpdateVirtualAxes(Vector3.zero);
}

void OnDisable()
{
if (CrossPlatformInputManager.AxisExists(horizontalAxisName))
CrossPlatformInputManager.UnRegisterVirtualAxis(horizontalAxisName);

if (CrossPlatformInputManager.AxisExists(verticalAxisName))
CrossPlatformInputManager.UnRegisterVirtualAxis(verticalAxisName);
}
}
}