Hi, I use crossplatforminput in my game and I have a problem with AxisTouchButton script. Im little confused with the responseSpeed value and Mathf.MoveTowards from OnPointerDown and OnPointerUp. The problem is that those OnPointerDown and OnPointerUp are called only once. ResponseSpeed float has to be big enough so axisvalue can reach it max or min on one call. I dont understand how those m_Axis.Update(Mathf.MoveTowards… should work as they are called only once. And because this is unitys standard asset with no modifications so Im little confused why its not working?
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
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));
}
}
}
Hi, I came to a solution to make it work as I think it was intended.
I added a boolean to mark the button as pressed, and then increment the axis value in the Update method. This makes the ResponseSpeed float work as intended.
As an extra, I also added a flag to make the button pressed when clicking outside button and then dragging over it. Useful for responsive plataformer left/right movement for example.
using UnityEngine;
using UnityEngine.EventSystems;
namespace UnityStandardAssets.CrossPlatformInput
{
public class AxisTouchButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerExitHandler, IPointerEnterHandler
{
// 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
private AxisTouchButton m_PairedWith;
private CrossPlatformInputManager.VirtualAxis m_Axis;
public bool IsActivatingOnDragEnter;
[HideInInspector] public bool IsButtonPressed;
private void Update()
{
if (IsButtonPressed)
{
m_Axis.Update(Mathf.MoveTowards(m_Axis.GetValue, axisValue, responseSpeed * Time.deltaTime));
}
else
{
if (!m_PairedWith.IsButtonPressed)
{
m_Axis.Update(Mathf.MoveTowards(m_Axis.GetValue, 0, returnToCentreSpeed / 2f * Time.deltaTime));
}
}
}
private void OnEnable()
{
if (!CrossPlatformInputManager.AxisExists(axisName))
{
m_Axis = new CrossPlatformInputManager.VirtualAxis(axisName);
CrossPlatformInputManager.RegisterVirtualAxis(m_Axis);
}
else
{
m_Axis = CrossPlatformInputManager.VirtualAxisReference(axisName);
}
FindPairedButton();
}
public void OnPointerDown(PointerEventData data)
{
MakeButtonPressed();
}
public void OnPointerUp(PointerEventData data)
{
IsButtonPressed = false;
}
public void OnPointerExit(PointerEventData data)
{
IsButtonPressed = false;
}
public void OnPointerEnter(PointerEventData data)
{
if (IsActivatingOnDragEnter)
{
MakeButtonPressed();
}
}
private void FindPairedButton()
{
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];
}
}
}
}
private void OnDisable()
{
m_Axis.Remove();
}
private void MakeButtonPressed()
{
if (m_PairedWith == null)
{
FindPairedButton();
}
IsButtonPressed = true;
}
}
}
p.s: sorry for ressing the topic, but this was the only one I found that described exactly my frustration with this script.
I have been digging for days looking for a solution to a problem related to AxisTouchButton where it would never get all the way to 1 or -1. It would max out at, for example, 0.035. To make matters worse, the max number wouldn’t always be the same and it didn’t always go back to zero when the button was released. This seems to clear up all of the issues I have been struggling with. Thanks so much.