RPG Combat Course - Need help/guidance on implementing Virtual Mouse/Cursor

Hello everyone I need some help regarding virtual mouse/cursor. I want to copy a mechanics like on this mobile game Hero Siege: Pocket Edition (Hero Siege: Pocket Edition Gameplay Android - YouTube). This is what I have tested for now (https://youtu.be/eL6eXlcSqFI). The problem is I don’t know how to make the cursor move like the one in the sample video on Hero Siege gameplay. I want the movement to replicate the right stick analog and with limited radius around the player. But right now the cursor moves everywhere. Also do I really need the virtual mouse/cursor or maybe there’s another way regarding my problem?

This is the sort of setup that doesn’t actually use the Mouse cursor (Mobile games don’t actually have a cursor), but instead places a sprite at the correct location.

Virtual Joysticks are way outside of the course structure, and I’m not sure I’ll be much help on that front.

If you’re looking to do this on a PC, without the Virtual Joystick, you can lock the cursor, and then put a virtual cursor on the screen based on the movements of the cursor.

You can read more about locking the cursor and still getting it’s input here: How to lock & hide the cursor in Unity - Game Dev Beginner

Thanks for answering, Brian. I think what you said about mobile games placing sprite as cursor instead is what I needed. For locking in the center I think this link (How to keep an object within a circle/sphere (radius) - NO RECTANGLE - Unity Answers) can help. Now the problem is how to make the sprite behave like the movement of virtual joystick/analog. As you can see on my previous video(https://youtu.be/eL6eXlcSqFI). When I move the right virtual analog, the cursor sprite moves gradually instead of moving instantly or moving like the virtual analog. What do you think is the better solution for the movement? By the way sorry for my English and thanks again for helping.

Scale the movement of the cursor with Time.deltaTime…

        [SerializeField] float cursorSpeed = 2;
        [SerializeField] float maxCursorDistance=3;
        private Vector2 cursorOffset;

        void SetCursorOffset(float mouseX, float mouseY)
        {
            Vector2 cursorMovement = new Vector3(mouseX, mouseY);
            cursorOffset += cursorMovement * cursorSpeed * Time.deltaTime;
            if (cursorOffset.magnitude > maxCursorDistance)
            {
                cursorOffset = cursorOffset.normalized * maxCursorDistance;
            }
        }

Now you can set the “cursor” position to the center of the screen + cursorOffset.

Alternatively, you can calculate the screen position of the Player and use that location + the offset.

1 Like

It’s almost working now, but I’m having a little trouble getting the right position of the player. In this code

private Player player
        {
            get
            {
                // Get the Rewired Player object for this player. Refresh it as needed so it will get the new reference after a script recompile in the editor.
                if (_player == null) _player = ReInput.players.GetPlayer(playerId);
                return _player;
            }
        }

void Awake()
        {
            cc = GetComponent<CharacterController>();
            playerCharacter = GameObject.FindWithTag("Player");
        }

        void Update()
        {
            if (!ReInput.isReady) return; // Exit if Rewired isn't ready. This would only happen during a script recompile in the editor.
            SetCursorOffset(player.GetAxis("MouseX"), player.GetAxis("MouseY"));
            transform.position = playerCharacter.transform.position + (Vector3)cursorOffset;
        }

        void SetCursorOffset(float mouseX, float mouseY)
        {
            Vector3 cursorMovement = new Vector3(mouseX, mouseY);
            cursorOffset += (Vector2)cursorMovement * cursorSpeed * Time.deltaTime;
            if (cursorOffset.magnitude > maxCursorDistance)
            {
                cursorOffset = cursorOffset.normalized * maxCursorDistance;
            }
        }

and the sample video (https://youtu.be/UoWosnfr-Jk) it shows that the cursor sprite is on bottom left side. What I want is something like on this sample video(https://youtu.be/CWbkzeoeVtg) and code

void Update()
        {
            if (!ReInput.isReady) return; // Exit if Rewired isn't ready. This would only happen during a script recompile in the editor.
            SetCursorOffset(player.GetAxis("MouseX"), player.GetAxis("MouseY"));
            transform.position = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f) + cursorOffset;
        }

but instead of the center of the screen, I want to use the position of the player.

Also another question regarding DirectionalTargeting.cs

public override void StartTargeting(AbilityData data, Action finished)
        {
            RaycastHit raycastHit;
            Ray ray = PlayerController.GetMouseRay();
            if (Physics.Raycast(ray, out raycastHit, 1000, layerMask))
            {
                data.SetTargetedPoint(raycastHit.point + ray.direction * groundOffset / ray.direction.y);
            }
            finished();
        }

is it possible to use the position of the virtual cursor sprite and its direction instead of using the Ray ray = PlayerController.GetMouseRay();. If it’s possible can you also guide me there?

transform.position = Camera.main.WorldToScreenPoint(player.transform.position);

Both of those videos appear to be identical…
Are you referring to the position of the virtual joystick or the virtual cursor? (The virtual cursor, by the way is extremely difficult for people with red/green color deficiency to see, you might choose another color than red)

You’ll need to get the virtual cursor’s location from the script you’re using to generate it. You’re still going to need to use GetMouseRay() to turn that virtual cursor’s location into a location on the terrain (and to adjust that location so that the fireball doesn’t spike into the ground.

1 Like

Hello Brian the position of virtual cursor is working as intended now but I have a new problem, I also need some help on how to get the position of my virtual cursor position from VirtualCursor.cs to use on PlayerController.cs. This is what I have tried so far. In VirtualCursor.cs I added this function

public Vector3 virtualCursorPosition
        {
            get
            {
                return transform.position;
            }
        }

then on PlayerController.cs

        public void setCursorPosition()
        {
            cursorPosition = virtualCursor.virtualCursorPosition;
        }

        public static Ray GetCursorRay()
        {
            return Camera.main.ScreenPointToRay(cursorPosition);
        }

But I get an error An object reference is required for the non-static field, method, or property like on this picture


Maybe what I’m doing is wrong and there’s a much better way than what I’m trying to do right now?

Ah, since GetCursorRay is a static method, it can’t access instance fields directly… Simply remove the static keyword from GetCursorRay and it will become a non-static method and work as intended.

1 Like

Thank you very much Brian I think it’s working as I intended because of your help.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.