Forum rules - please read before posting.

Changing the cursor during gameplay manually

I'm trying to change the cursor during gameplay, I made a close-up interaction for a 3D game that let's the player interact with an object with images on it and the 'hotspot' should be only where the image is, so mesh colliders wouldn't work. So I'm sort of bypassing the usual hotspot functionality but I'd like the cursor to change to the look icon when you mouse over, then run an interaction. Everything else is working except the icon change. I'm trying to run AC.KickStarter.playerCursor.SetCursorFromID(2); in my code but it's not changing the cursor. I tried different ID's and none of them seemed to change it.

I'd really appreciate any guidance, thank you!

Comments

  • I'm not sure I'm following the reason a collider can't be used - can you share details/screenshots on the situation that calls for such a workaround?

    If a Hotspot isn't currently active, AC will play the "main" cursor by default. In this case, changing the cursor would be a case of modifying this cursor's texture:

    KickStarter.cursorManager.pointerIcon.ReplaceTexture (myNewTexture);
    

    This'll affect the texture in the Cursor Manager itself, so you'd also need to set this to the correct default value when your game begins.

  • Aha, gotcha. Yeah in this case it's our character is going close up to a photo of a silhouette of a woman wearing a veil. It's basically sign-posting because you have to recreate the side view of her during a puzzle. So the player should be able to mouse over the head and have that highlight, the body, and the veil. So I ended up layering three quads on top of eachother (they're in the exact same spot), each with a transparent (alpha-cutoff) image that has a body part or veil. The player goes into the closeup view, pauses the player control and activates the portrait and can mouse over each part and highlight it. To get pixel perfect mouseover detecting, I'm using a screen-based raycast, with a layer mask that only sees the quad gameobjects with the images. The hit returns an array of the colliders and I loop through and check the alpha level of the image at that hit point. If it's above a certain threshold, that's the highlighted layer. Then if I mousedown, I have it run an interaction based on that layer's name.

    (sorry if that's confusing, I could do a vid if that helps)
    Here's a code snippt of the selection. Thank you so much for your help and guidance!

    void Update() {
    if(is_on && !AC.KickStarter.stateHandler.IsInCutscene()) { // && Input.GetMouseButtonDown(0)) {
    Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
    RaycastHit[] hits = Physics.RaycastAll(ray, Mathf.Infinity, quadLayerMask);

            // Sort the hits by distance
            hits = hits.OrderBy(h => h.distance).ToArray();
    
            bool found_target = false;
            foreach (RaycastHit hit in hits)
            {
                // Check if the texture at the hit point is transparent
                Renderer renderer = hit.collider.GetComponent<Renderer>();
                Texture2D texture = (Texture2D)renderer.material.mainTexture;
                Vector2 textureCoord = hit.textureCoord;
                int x = (int)(textureCoord.x * texture.width);
                int y = (int)(textureCoord.y * texture.height);
                Color color = texture.GetPixel(x, y);
    
                if (color.a > alphaThreshold)
                {
                    GameObject selectedQuad = hit.collider.gameObject;
                    //Debug.Log("Selected Quad: " + selectedQuad.name);
                    AC.KickStarter.playerCursor.SetCursorFromID(1);
                    found_target = true;
                    hit.collider.gameObject.GetComponent<Renderer>().material.color = Color.red;
                    // Perform any action on the selected quad
                    if(Input.GetMouseButtonDown(0)) {
                        Debug.Log("Clicked on: " + selectedQuad.name);
    
                        string obj_name = selectedQuad.name.ToLowerInvariant();
    
                        if (obj_name.Contains("body"))
                        {
                            body.Interact();
                        }
                        else if (obj_name.Contains("veil"))
                        {
                            veil.Interact();
                        }
                        else if (obj_name.Contains("head"))
                        {
                            head.Interact();
                        }
    
                    }
                    //break;
                } else {
                    //Debug.Log("Transparent:" + hit.collider.gameObject.name);
                    hit.collider.gameObject.GetComponent<Renderer>().material.color = Color.white;
                }
            }
    
            //if(!found_target) KickStarter.playerCursor.ResetSelectedCursor();
        }
    }
    
  • edited April 2023

    Thanks for the details.

    In terms of the most robust approach, I'd say you're probably best off switching to a custom Hotspot detection system, which will allow you to select Hotspots in your script - while giving the benefits of e.g. updating the cursor icon automatically.

    You can then set your game's Hotspot detection method option to Custom Script. This is an option you can set in the Settings Manager, but you can also set it through code with:

    KickStarter.settingsManager.hotspotDetection = HotspotDetection.CustomScript;
    

    Once set, you can then select Hotspots manually with the SetActiveHotspot function.

    If you attached a Hotspot to each body part quad, you could then update your code to select it with:

    KickStarter.playerInteraction.SetActiveHotspot (selectedQuad.GetComponent<Hotspot>());
    

    For more details on selecting and interacting with Hotspots through script, see the Manual's "Custom interaction systems" chapter.

  • Aha! I get it, ok that makes perfect sense and sounds much better than what I've implemented. That's exactly the info I needed, thank you so much for your help!!

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.