Forum rules - please read before posting.

Checking if an AC Cutscene is active via scripting

Hello again!

I'm trying to customize some things in my game through scripts and not entirely sure how to utilize some of the AdventureCreator scripts I'd like to use. Thanks in advance for your patience-- I am not super well versed in scripting, but am trying to learn.

For my game's hotspots, I'd like for the sprite to become highlighted on hover as opposed to AC's default text appear on hover.

I have the following script attached to my hotspot-connected objects and it functions. However, I want this script to disable when the subtitles or conversation menus are open, so that the hotspots on screen are not highlightable during any speech.:

`using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AC;

public class HotspotHover : MonoBehaviour
{

public Sprite sprite;
public Sprite highlightSprite;

    void OnMouseOver()
{
    GetComponent<SpriteRenderer>().color = Color.yellow;
}

void OnMouseExit()
{
    GetComponent<SpriteRenderer>().color = Color.white;
}

}`

Per the AC documentation, I found the bool "AC.StateHandler.IsInCutscene" and tried to script a variable check via

if (AC.StateHandler.IsInCutscene());

but the script error log says "The name 'IsInCutscene' does not exist in the current context." as well as "Tuple must contain two elements."

I am sure I am approaching this incorrectly just due to scripting inexperience, so if anyone would mind giving me a gentle nudge in the right direction, I would very much appreciate it!

Comments

  • edited July 2023

    Does the Manual specifically refer to AC.StateHandler.IsInCutscene? That'll need amending, if so.

    Referencing StateHandler as a class name tells the script that you want to access a static function - that is, one that isn't tied to a specific StateHandler component.

    The StateHandler component you'll want to access exists on AC's PersistentEngine object, which is generated automatically at runtime.

    However, AC provides a static reference to this - and all Manager / engine components - within its KickStarter class. See the front page of the Scripting Guide for details.

    In short, replace it with:

    if (AC.KickStarter.stateHandler.IsInCutscene())
    
  • Thank you so much for clarifying! I found the variable I wanted to use via the documentation website rather than the scripting guide, so that's probably why I couldn't find the proper formatting.

    I was able to implement the IsInCutscene check via the script and resolve the issues, however, the hover graphic highlight does not work now that I've implemented the IsInCutscene check.

    I am posting the code I have implemented below (I have the public sprite definitions because I might change this from a highlight to a sprite swap later, irrelevant for now.)

    I tried moving the variable check to update, and having it both in start and update, and still got no results. I am attaching this script to the GameObject to be highlighted its self, if that matters.

    Thank you again for your help!

    `using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    using AC;

    public class HotspotHover : MonoBehaviour
    {

    public Sprite sprite;
    public Sprite highlightSprite;
    
    // Start is called before the first frame update
    void Start()
    {
    
        if (AC.KickStarter.stateHandler.IsInCutscene())
    
        { }
    
        else 
        {
    
            void OnMouseOver()
            {
                GetComponent<SpriteRenderer>().color = Color.yellow;
            }
    
            void OnMouseExit()
            {
                GetComponent<SpriteRenderer>().color = Color.white;
            }
        }
    
        // Update is called once per frame
        void Update()
        {
    
    
    
        }
    }
    

    }

    `

  • You'll want to make the custscene check in your Update loop, but your script implements OnMouseOver and OnMouseExit as nested functions (a function-within-a-function). These will need to be in the main body of your script for Unity to call them automatically.

    Since you'll also want to set the colour of the sprite in the Update loop, you can use a bool variable to keep track of the mouse state:

    using UnityEngine;
    using AC;
    
    public class HotspotHover : MonoBehaviour
    {
    
        private bool isSelected;
    
        void Update ()
        {
            if (!AC.KickStarter.stateHandler.IsInCutscene () && isSelected)
            { 
                GetComponent<SpriteRenderer>().color = Color.yellow;
            }
            else 
            {
                GetComponent<SpriteRenderer>().color = Color.white;
            }
        }
    
        void OnMouseOver ()
        {
            isSelected = true;
        }
    
        void OnMouseExit ()
        {
            isSelected = false;
        }
    }
    

    As an aside: while this should work, the better practice for checking if a Hotspot is selected is to hook into the OnHotspotSelect/OnHotspotDeselect custom events, as this will make it work independent of the Hotspot detection method. You should be fine with the above, but let me know if you want advice on using events to make things more flexibe.

  • Thanks Chris, both for the script and the explanation of why it functions! I feel like I have a better understanding of how to format things in C# a little better now. The script is functioning as I hoped/expected.

    I'm happy to take any advice you'd like to give! I'm currently only planning on using mouse hover only Hotspot detection in my game, but flexibility definitely never hurts!

    I appreciate your assistance as always!

  • No problem.

    Custom events are a way of running extra code when AC performs common tasks - for example, when a speech plays, when a Menu is opened etc.

    A tutorial can be found here, and more details can also be found in the Manual's "Custom events" chapter.

    With events, you can often avoid the need to run checks every frame (i.e. have an Update function). It's not a concern in this case, but the "best practice" would be to hook into events that run both when a Hotspot is selected/deselected, and also when the game enters/exit gameplay:

    using UnityEngine;
    using AC;
    
    public class HotspotHover : MonoBehaviour
    {
    
        private bool isSelected;
        private bool isInGameplay = true;
        private SpriteRenderer spriteRenderer;
    
        private void OnEnable ()
        {
            spriteRenderer = GetComponent<SpriteRenderer> ();
    
            EventManager.OnHotspotSelect += OnHotspotSelect;
            EventManager.OnHotspotDeselect += OnHotspotDeselect;
            EventManager.OnEnterGameState += OnEnterGameState;
        }
    
        void OnDisable ()
        {
            EventManager.OnHotspotSelect -= OnHotspotSelect;
            EventManager.OnHotspotDeselect -= OnHotspotDeselect;
            EventManager.OnEnterGameState -= OnEnterGameState;
        }
    
        void OnHotspotSelect (Hotspot hotspot)
        {
            if (hotspot.gameObject == gameObject)
            {
                isSelected = true;
                UpdateAppearance ();
            }
        }
    
        void OnHotspotDeselect (Hotspot hotspot)
        {
            if (hotspot.gameObject == gameObject)
            {
                isSelected = false;
                UpdateAppearance ();
            }
        }
    
        void OnEnterGameState (GameState gameState)
        {
            isInGameplay = gameState == GameState.Normal;
            UpdateAppearance ();
        }
    
        void UpdateAppearance ()
        {
            Color color = (isSelected && isInGameplay) ? Color.yellow : Color.white;
            spriteRenderer.color = color;
        }
    
    }
    

    Doing it this way makes the script a fair bit longer in this case, but with more complex logic it's often the reverse - and code is only run at the time that it needs to.

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.