I was testing some camera settings with CM 2.7.2 and InputSystem 1.1.0-3 and ran into some issues getting the CinemachineInputProvider to pick up any values from the InputAction.
I used the following script to test the ReadValue<> data coming out of the InputAction.
using UnityEngine;
public class TestScript : MonoBehaviour
{
// Start is called before the first frame update
private PlayerControls pc;
void Awake()
{
pc = new PlayerControls();
pc.Gameplay.Cam.Enable();
}
// Update is called once per frame
void Update()
{
print("Cam action enabled: " + pc.Gameplay.Cam.enabled + " | Vector2 :" + pc.Gameplay.Cam.ReadValue<Vector2>());
}
}
Where PlayerControls is the C# Script generated by InputSystem 1.1.0.
The test yields the following result as expected (when moving the mouse) ;
However the InputProvider seems to not correctly pass the data onto the Cinemachine Freelook.
Is there some intended feature Iām overlooking or could this be a bug? On CM 2.7.1 the exact same setup works, and the camera moves, but in turn has the issue that it keeps on passing data to the camera when the Action is disabled.
Sorry for the delayed response. Indeed, this is not working properly in 2.7.2.
We will address this for 2.7.3.
In the meantime as a workaround, you can make a custom version of the CinemachineInputProvider that behaves better. Just copy the original, rename it, and put the new version in your assets. Then, edit the script and give it these contents (substitute your modified class name):
using System.Linq;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Users;
namespace Cinemachine
{
/// <summary>
/// This is an add-on to override the legacy input system and read input using the
/// UnityEngine.Input package API. Add this behaviour to any CinemachineVirtualCamera
/// or FreeLook that requires user input, and drag in the the desired actions.
/// If the Input Syatem Package is not installed, then this behaviour does nothing.
/// </summary>
[HelpURL(Documentation.BaseURL + "manual/CinemachineAlternativeInput.html")]
public class CinemachineInputProvider : MonoBehaviour, AxisState.IInputAxisProvider
{
/// <summary>
/// Leave this at -1 for single-player games.
/// For multi-player games, set this to be the player index, and the actions will
/// be read from that player's controls
/// </summary>
[Tooltip("Leave this at -1 for single-player games. "
+ "For multi-player games, set this to be the player index, and the actions will "
+ "be read from that player's controls")]
public int PlayerIndex = -1;
/// <summary>Vector2 action for XY movement</summary>
[Tooltip("Vector2 action for XY movement")]
public InputActionReference XYAxis;
/// <summary>Float action for Z movement</summary>
[Tooltip("Float action for Z movement")]
public InputActionReference ZAxis;
/// <summary>
/// Implementation of AxisState.IInputAxisProvider.GetAxisValue().
/// Axis index ranges from 0...2 for X, Y, and Z.
/// Reads the action associated with the axis.
/// </summary>
/// <param name="axis"></param>
/// <returns>The current axis value</returns>
public virtual float GetAxisValue(int axis)
{
if (enabled)
{
var action = ResolveForPlayer(axis, axis == 2 ? ZAxis : XYAxis);
if (action != null)
{
switch (axis)
{
case 0: return action.ReadValue<Vector2>().x;
case 1: return action.ReadValue<Vector2>().y;
case 2: return action.ReadValue<float>();
}
}
}
return 0;
}
const int NUM_AXES = 3;
InputAction[] m_cachedActions;
/// <summary>
/// In a multi-player context, actions are associated with specific players
/// This resolves the appropriate action reference for the specified player.
///
/// Because the resolution involves a search, we also cache the returned
/// action to make future resolutions faster.
/// </summary>
/// <param name="axis">Which input axis (0, 1, or 2)</param>
/// <param name="actionRef">Which action reference to resolve</param>
/// <returns>The cached action for the player specified in PlayerIndex</returns>
protected InputAction ResolveForPlayer(int axis, InputActionReference actionRef)
{
if (axis < 0 || axis >= NUM_AXES)
return null;
if (actionRef == null || actionRef.action == null)
return null;
if (m_cachedActions == null || m_cachedActions.Length != NUM_AXES)
m_cachedActions = new InputAction[NUM_AXES];
if (m_cachedActions[axis] != null && actionRef.action.id != m_cachedActions[axis].id)
m_cachedActions[axis] = null;
if (m_cachedActions[axis] == null)
{
m_cachedActions[axis] = actionRef.action;
if (PlayerIndex != -1)
{
var user = InputUser.all[PlayerIndex];
m_cachedActions[axis] = user.actions.First(x => x.id == actionRef.action.id);
}
}
// Auto-enable it if disabled
if (m_cachedActions[axis] != null && !m_cachedActions[axis].enabled)
m_cachedActions[axis].Enable();
return m_cachedActions[axis];
}
// Clean up
protected virtual void OnDisable()
{
m_cachedActions = null;
}
}
}