Move mouse cursor with xbox 360 controller ingame?

The title sayes pretty much everything.
I made the xbox 360 controller work for my game on windows PC, but there is only the points where for example the menu is open where i need to move the cursor around.
Downside is, i cant seem to find how and where, even google proves not to know the answer.

Does anyone know, how can i make the mouse cursor move with the xbox 360 controller?

thank you in advance!

1 Like

Joining the question. Does nobody know how to do it?

It’s your lucky day, especially for replying to a four year old thread. I wrote this yesterday. It uses a paid asset called FastLineRenderer to draw the replacement cursor (you can’t move the actual mouse cursor), but it is trivial to convert that to Unity’s built-in LineRenderer, which should be fast enough for this simple usage. (I wrapped the code in a spoiler tag since it’s a bit lengthy for a forum post.)

In Unity you’ll have to go to Edit → Project Settings → Input and change Horizontal and Vertical as shown in the screen shots after the code. Somewhat reliable information about controller setup is available here for XBox One and 360 respectively:

You can register for pointer movement events, button 1 and button 2 clicks (I probably should have called these 0 and 1, but too late now), or you can query the class for static button 1 / button 2 click status and pointer position on frame updates if you’re already tightly tied to the update loop.

using UnityEngine;
using DigitalRuby.FastLineRenderer;

//////////////////////////////////////////////////////////////////////////////
//
// Manages events and the input cursor (mouse or gamepad).
//
// Everything in the game should register for Start and Update events rather
// than using Unity's Magic Methods. This also allows event sinks for static
// classes and custom events.
//
// Register in Awake (and don't do anything else in Awake).
// Always un-register in OnDestroy (even if other calls trigger reg/un-reg).
//
/*
        void Awake()
        {
            EventMgr.UnityUpdateClients += onUnityUpdate;
        }

        void OnDestroy()
        {
            EventMgr.UnityUpdateClients -= onUnityUpdate;
        }

        public void onUnityUpdate()
        {
            // do something
        }
*/
//////////////////////////////////////////////////////////////////////////////

public class EventMgr : MonoBehaviour {

    public FastLineRenderer CursorFLR;

    // Unity events
    public delegate void UnityStartClient();
    public delegate void UnityUpdateClient();
    public static UnityStartClient UnityStartClients;
    public static UnityUpdateClient UnityUpdateClients;

    // Input and cursor events
    public delegate void ClickButton1();
    public delegate void ClickButton2();
    public delegate void CursorMovement();
    public static ClickButton1 ClickButton1Clients;
    public static ClickButton2 ClickButton2Clients;
    public static CursorMovement CursorMovementClients;

    public static Vector3 pointerPosition;
    public static Vector3 cursorCoords;
    public static bool button1Clicked;
    public static bool button2Clicked;
    private static Vector3 previousMousePosition;

    private FastLineRendererProperties propsFLR;
    private float cursorThickness = 0.5f;
    private float cursorSize = 2.0f;
    private float joystickTraverseScreenSecs = 2.0f;
    private float joystickPixelsPerSec;

    void Start()
    {
        Cursor.visible = false;
        pointerPosition = new Vector3(Screen.width / 2, Screen.height / 2, 0);
        previousMousePosition = Input.mousePosition;
        cursorCoords = Camera.main.ScreenToWorldPoint(pointerPosition);
        button1Clicked = false;
        button2Clicked = false;

        propsFLR = new FastLineRendererProperties();
        propsFLR.Radius = 0.25f;
        propsFLR.LineType = FastLineRendererLineSegmentType.Full;
        propsFLR.LineJoin = FastLineRendererLineJoin.None;

        joystickPixelsPerSec = (float)Screen.width / joystickTraverseScreenSecs;

        if(UnityStartClients != null) UnityStartClients();
    }

    void Update()
    {
        bool cursorMoved = false;

        if(Input.mousePresent)
        {
            if(Input.mousePosition != previousMousePosition)
            {
                cursorMoved = true;
                pointerPosition = Input.mousePosition;
                previousMousePosition = Input.mousePosition;
            }
        }

        float horz = Input.GetAxis("Horizontal");
        float vert = Input.GetAxis("Vertical");
        if(horz != 0 || vert != 0)
        {
            cursorMoved = true;
            horz = Time.deltaTime * joystickPixelsPerSec * horz;
            vert = Time.deltaTime * joystickPixelsPerSec * vert;
            pointerPosition =
                new Vector3(
                    Mathf.Clamp(pointerPosition.x + horz, 0, Screen.width),
                    Mathf.Clamp(pointerPosition.y + vert, 0, Screen.height)
                );
        }

        if(cursorMoved)
        {
            cursorCoords = Camera.main.ScreenToWorldPoint(pointerPosition);
            CursorFLR.Reset();
            propsFLR.Start = new Vector3(cursorCoords.x - cursorSize, cursorCoords.y);
            propsFLR.End = new Vector3(cursorCoords.x + cursorSize, cursorCoords.y);
            CursorFLR.AddLine(propsFLR);
            propsFLR.Start = new Vector3(cursorCoords.x, cursorCoords.y - cursorSize);
            propsFLR.End = new Vector3(cursorCoords.x, cursorCoords.y + cursorSize);
            CursorFLR.AddLine(propsFLR);
            CursorFLR.Apply();
        }

        button1Clicked = Input.GetMouseButtonDown(0) || Input.GetKeyDown("joystick button 0");
        button2Clicked = Input.GetMouseButtonDown(1) || Input.GetKeyDown("joystick button 1");

        if(cursorMoved && CursorMovementClients != null) CursorMovementClients();
        if(button1Clicked && ClickButton1Clients != null) ClickButton1Clients();
        if(button2Clicked && ClickButton2Clients != null) ClickButton2Clients();
        if(UnityUpdateClients != null) UnityUpdateClients();
    }
}

Input settings I’m using for my USB XBox One controller on Win10:

Quick update, it’s better to remove your delegate handlers in a try-catch … if you do something like subscribe/unsubscribe to various events inside the class over time (instead of once in Awake), you’ll get a null reference error if the handler was removed before OnDestroy is called. You can safely ignore that error, so:

        void OnDestroy()
        {
            try
            {
                EventMgr.UnityUpdateClients -= UnityUpdate;
            }
            catch { }
        }

Discussion of another probably-better approach based on interfaces instead of delegates is here:

Just looking for clarification. You say “you can’t move the actual mouse cursor”. Do you mean this is true of just your example or is this true period?

Also, does this script go on the camera, the FPS Player or on an Event Manager game object?

Thanks for any info.