I have a working joystick that has default boundaries of a square, and I’ve been able to successfully change the square to a circle using ClampMagnitude, but I’d like to know how to change that boundary to other shapes. Specifically I’d like to change the boundary to an Octagon or a Square rotated 45º so the corners of the square are pointing vertically and horizontally.
If it helps, heres’ my joystick code so far. This is meant for a touchscreen mobile device. As of now, my joystick is still squared but the flat sides of the square are actually curved. Like this but more extreme.
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
Vector3 m_PointerDownPos;
void OnEnable()
{
CreateVirtualAxes();
}
void Start()
{
m_StartPos = transform.position;
}
void UpdateVirtualAxes(Vector3 value)
{
var delta = m_StartPos - value;
delta.y = -delta.y;
if (m_UseX)
{
delta.x /= MovementRange;
m_HorizontalVirtualAxis.Update(-delta.x);
}
if (m_UseY)
{
delta.y /= MovementRange;
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)
{
// FIXED: Made this method faster by using 2 floats for delta X and Y instead of a vector3 which is later discarded
float deltaX = 0;
float deltaY = 0;
if (m_UseX)
{
deltaX = Mathf.Clamp (data.position.x - m_PointerDownPos.x, -MovementRange, MovementRange); // Take drag position relative to pointerdown position instead of pivot; Use movement range in device units as scaled by canvas scaler
}
if (m_UseY)
{
deltaY = Mathf.Clamp (data.position.y - m_PointerDownPos.y, -MovementRange, MovementRange); // Take drag position relative to pointerdown position instead of pivot; Use movement range in device units as scaled by canvas scaler
}
transform.position = Vector3.ClampMagnitude( new Vector3(deltaX, deltaY, 0), MovementRange) + m_StartPos;
//transform.position = new Vector3(m_StartPos.x + deltaX, m_StartPos.y + deltaY, m_StartPos.z); // Makes joystick boundary squared
UpdateVirtualAxes(transform.position);
}
public void OnPointerUp(PointerEventData data)
{
transform.position = m_StartPos;
UpdateVirtualAxes(m_StartPos);
}
public void OnPointerDown(PointerEventData data) {
m_PointerDownPos = data.position; // CYLFIX: Remember the exact position of pointerdown so drag can be relative to that and not to pivot
}
void OnDisable()
{
// remove the joysticks from the cross platform input
if (m_UseX)
{
m_HorizontalVirtualAxis.Remove();
}
if (m_UseY)
{
m_VerticalVirtualAxis.Remove();
}
}
}
}