Question by
ryand555 · Jul 09, 2020 at 08:32 PM ·
c#2djoystick2d rotation
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.
Comment
Answer by Shiropopi · May 17, 2021 at 10:17 AM
@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;
}
}