Detect a Full 360 input on a joystick

Hello , i’m currently using the CrossPlatformInputManager system to create a 2D game , i’m not currently using the joystick to rotate the player but what i do want is to trigger a player ability by preforming a full 360 loop within a few seconds.
I have been looking online and cannot find any suggestions on how to do this , most of my current inputs work on the Horizontal and vertical axis inputs if that’s relevant but i don’t know how to do this.

Any suggestions would be great ,Thank you.

@ryand555 I know it’s a little late but…


Here the answer


You can tweak the variables in the inspector to get the result you wish.

using System.Collections;
using UnityEngine;

public class JoyStickSpin : MonoBehaviour
{
	[Header("Spinning Dectection Options")]
	[SerializeField] private float spinAngleCheckUpdateTimer = 0.1f; // Frequency of the spin check in second
	[SerializeField] [Range(0.0f, 180.0f)] private float spinValidAngleLimit = 30.0f; // The minimum angle needed between the old input and the current input to have a valid check
	[SerializeField] private int validSpinCheckRows = 5; // Numbers of valid spin check to perform in a row to consider the joystick spinning 
	
	// Private fields

	// This one don't need to be serialized, it's only for debug purposes
	// If you want the isSpinning bool value, use the property
	[SerializeField] private bool isSpinning = false; // If true, the joystick is considered spinning

	private Vector2 joyStickInput = Vector2.zero; // Register the input value of the joystick
	private Vector2 lastJoyStickInput = Vector2.zero; // Store old joystick input
	private bool isCheckingSpinInput = false; // Determine if we are currently checking joystick spin or not
	private int validSpinCheckCounter = 0; // Store the number of valid check performed in a row

	// Property
	public bool IsSpinning
	{
		get { return isSpinning; }
		private set { }
	}

	// Reset variables in the case where the script is renabled
	private void OnEnable()
	{
		isCheckingSpinInput = false;
		isSpinning = false;
	}

	void Update()
	{
		JoyStickInput(); // Getting our input
		CheckJoyStickSpinning(); // Check spinning here

		// Testing if this is working well, delete that part after verification
		if (isSpinning)
		{
			Debug.Log("Spinning");
		}
	}

	private void JoyStickInput()
	{
		joyStickInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
	}

	private void CheckJoyStickSpinning()
	{
		// Coroutine check in allowed only if the input is changing and that another coroutine check is not running
		if (joyStickInput != lastJoyStickInput && !isCheckingSpinInput)
		{
			// Put the ischecking bool to true (avoid multiples checks at the same time) and start coroutine to detect joystick spin
			isCheckingSpinInput = true;
			StartCoroutine(JoyStickSpinningDetection());
		}

		// After a few coroutine spin checks, examine if we have enough successful check in a row to consider the joystick is currently spinning
		if (validSpinCheckCounter == validSpinCheckRows)
		{
			isSpinning = true;
		}
		else
		{
			isSpinning = false;
		}
	}

	IEnumerator JoyStickSpinningDetection()
	{
		// Copy current input value to use it after the coroutine waits
		lastJoyStickInput = joyStickInput;

		yield return new WaitForSeconds(spinAngleCheckUpdateTimer);

		// Check if the angle between the old input and current one is more or equal to the given angle limit value
		if (Vector2.Angle(lastJoyStickInput, joyStickInput) >= spinValidAngleLimit)
		{
			// The check is successful, increment the check counter by one
			validSpinCheckCounter++;

			// If the check counter is already equal or superior to the valid numbers of successful check needed, we clamp it.
			// This is because to consider if the joystick is spinning or not we are checking if (validSpinCheckCounter == validSpinCheckRows)
			validSpinCheckCounter = Mathf.Clamp(validSpinCheckCounter, 0, validSpinCheckRows);
		}
		else
		{
			// The check is not valid, we are resetting the counter value to zero
			validSpinCheckCounter = 0;
		}

		// Signaling that the coroutine check is done
		isCheckingSpinInput = false;
	}
}