Forum rules - please read before posting.

Question about Cursor snapping to Hotspots (aim assist) for Controllers

Hello everyone, and happy holidays.

I have a question regarding cursor movement via controller. I am nearly finished porting the entire game for Steam Deck and other consoles, but I have noticed that it is a bit difficult to aim at hotspots when using a controller.

I have a setup where the left stick controls direct movement and the right stick controls the mouse cursor. I was wondering if there is any setting built into Adventure Creator that can be enabled to act as a kind of aim assist, snapping to the nearest hotspot when the stick is moved, rather than requiring the player to be extremely precise with cursor placement.

Thank you in advance, as always.

Comments

  • For a 2D or 3D game?

    It should be possible with a custom script, but it's not trivial - particularly if you want it to be based on the shape of Hotspots rather than a straightforward distance check to the Hotspot centre.

    One possible approach may be to inflate a Hotspot's collider, and then - when selected - reduce it again and move the cursor to its centre.

  • For a 2D game. I'm sorry, I always forget to share that bit of info. So the best way to approach this would be to detect the hotspot's collision and then snap to its center?

  • The correct approach is a bit open-ended, but snapping to its centre would only be part of it: you'd still need a way to detect if the cursor is "near" a Hotspot without being over its original bounds.

    Here's a sample script you can attach to some Hotspots to see the approach I was getting at. It expands the bounds of the Hotspot's Box Collider when the cursor moves towards it, and shrinks it again when it moves away. It may well need tweaking to suit your needs, however:

    using UnityEngine;
    using AC;
    
    public class SnapToHotspot : MonoBehaviour
    {
    
        bool isExpanded;
        Vector2 lastFrameCursorPosition;
        float moveDot;
        const float Expansion = 0.3f;
    
        void Start()
        {
            lastFrameCursorPosition = KickStarter.playerInput.GetMousePosition();
        }
    
        void OnEnable() => EventManager.OnHotspotSelect += OnHotspotSelect;
        void OnDisable() => EventManager.OnHotspotSelect -= OnHotspotSelect;
    
        void Update()
        {
            if (KickStarter.playerInteraction.GetActiveHotspot() && KickStarter.playerInteraction.GetActiveHotspot().gameObject == gameObject) return;
    
            var cursorPosition = KickStarter.playerInput.GetMousePosition();
            var cursorMoveDirection = (cursorPosition - lastFrameCursorPosition).normalized;
            if (cursorMoveDirection.sqrMagnitude == 0f) return;
    
            var directionToCentre = (GetComponent<Hotspot>().GetIconScreenPosition() - cursorPosition).normalized;
    
            var newMoveDot = Vector2.Dot(cursorMoveDirection, directionToCentre);
            moveDot = Mathf.Lerp(moveDot, newMoveDot, Time.deltaTime * 15f);
            if (moveDot > 0f)
            {
                Expand();
            }
            else
            {
                Shrink();
            }
    
            lastFrameCursorPosition = KickStarter.playerInput.GetMousePosition();
        }
    
        void OnHotspotSelect(Hotspot hotspot)
        {
            if (hotspot.gameObject == gameObject)
            {
                KickStarter.playerInput.SetSimulatedCursorPosition(hotspot.GetIconScreenPosition());
            }
        }
    
        void Expand()
        {
            if (isExpanded) return;
            SetSize(Expansion);
            isExpanded = true;
        }
    
        void Shrink()
        {
            if (!isExpanded) return;
            SetSize(-Expansion);
            isExpanded = false;
        }
    
        void SetSize(float expansion)
        {
            Vector3 localScale = transform.localScale;
    
            if (TryGetComponent(out BoxCollider2D box))
            {
                var expandedWidth = box.size.x + (expansion / localScale.x);
                var expandedHeight = box.size.y + (expansion / localScale.y);
    
                box.size = new Vector2(expandedWidth, expandedHeight);
                box.size = new Vector2(box.size.x + expansion, box.size.y + expansion);
            }
        }
    
    }
    
  • Thank you so much for going above and beyond to help devs out! I'll give it a try. Thank you!

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.