Forum rules - please read before posting.

Interaction Scheduling

I want to select a hotspot interaction while another interaction is still playing and character to do the second hotspot action after the first one is done.

Simply, Interactions chosen in a row has to work AFTER another.

Like Sims 1 action scheduling but in a much simpler way:
Sims 1 Actions Scheduling Example

It's pushing the boundaries of what adventure creator is for but I always wanted this option while playing adventure games.

Comments

  • It can be done, but you'd need to make use of a custom interaction system, since AC's built-in one can 1) only be run while in gameplay, and 2) triggers an interaction instantly.

    See the Manual's "Custom interaction systems" chapter for details, but essentially it'd be a case of having an interaction menu queue up details of the interaction to run, and then run the first of the queue once no existing interaction or cutscene is running. For this, you'd probably want to create a data class to store such "pending" interactions, that you can then add to a queue.

    Very roughly, something like:

    using UnityEngine;
    using AC;
    using System.Collections.Generic;
    
    public class UpdateSpeechActions : MonoBehaviour
    {
    
        private List<PendingInteraction> pendingInteractions = new List<PendingInteraction> ();
    
        public void Update ()
        {
            if (KickStarter.stateHandler.IsInGameplay () && KickStarter.playerInteraction.GetHotspotMovingTo () == null)
            {
                if (pendingInteractions.Count > 0)
                {
                    pendingInteractions[0].Run ();
                    pendingInteractions.RemoveAt (0);
                }
            }
        }
    
        public void QueueUseInteraction (Hotspot hotspot, int iconID)
        {
            pendingInteractions.Add (new PendingInteraction (hotspot, iconID, false));
        }
    
    
        public void QueueInvInteraction (Hotspot hotspot, int itemID)
        {
            pendingInteractions.Add (new PendingInteraction (hotspot, itemID, true));
        }
    
    
        private class PendingInteraction
        {
    
            public Hotspot hotspot;
            public int iconID;
            public bool isInventoryInteraction;
    
            public PendingInteraction (Hotspot hotspot, int iconID, bool isInventoryInteraction)
            {
                this.hotspot = hotspot;
                this.iconID = iconID;
                this.isInventoryInteraction = isInventoryInteraction;
            }
    
            public void Run ()
            {
                if (isInventoryInteraction)
                {
                    hotspot.RunInventoryInteraction (iconID);
                }
                else
                {
                    hotspot.RunUseInteraction (iconID);
                }
            }
    
        }
    
    }
    
  • edited June 2022

    Sorry for late response, I didn't want to just ask questions without trying to understand the problem.

    I did not understand "interaction menu queue up" means. Does it mean custom scripting in Menu manager elements?

    I want to use scheduling with "Interaction methods" provided with the engine but I think that is not possible unless I edit "PlayerInteraction.cs", which I bet won't end well for me.

    So... can scheduling be done using Custom action scripts?

    I tried to use this script by:
    1.Setting "Interaction method" to "Custom Script"
    2.Placing the "UpdateSpeechActions.cs" code to a new GameObject in the scene

    But it doesn't schedule, just goes to the second clicked hotspot:

    using UnityEngine;
    using AC;
    using System.Collections.Generic;
    
    public class UpdateSpeechActions : MonoBehaviour
    {
    
        private List<PendingInteraction> pendingInteractions = new List<PendingInteraction> ();
    
        public void Update ()
        {
            if ((Input.GetMouseButtonUp (0) || (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Ended)) && KickStarter.stateHandler.IsInGameplay () && KickStarter.playerInput.GetDragState () == DragState.None)
            {
                Ray ray = Camera.main.ScreenPointToRay (KickStarter.playerInput.GetMousePosition ());
                if (Physics.Raycast (ray, out RaycastHit hit, KickStarter.settingsManager.hotspotRaycastLength, 1 << LayerMask.NameToLayer (KickStarter.settingsManager.hotspotLayer)))
                {
                    Hotspot hitHotspot = hit.collider.gameObject.GetComponent<Hotspot> ();
                    if (hitHotspot)
                    {
                        pendingInteractions.Add (new PendingInteraction (hitHotspot, -1, false));
                    }
                 }
            }
            if (pendingInteractions.Count > 0)
            {
                pendingInteractions[0].Run ();
                pendingInteractions.RemoveAt (0);
            }
    
        }
    
    
    
        public void QueueUseInteraction (Hotspot hotspot, int iconID)
        {
            pendingInteractions.Add (new PendingInteraction (hotspot, iconID, false));
        }
    
    
        public void QueueInvInteraction (Hotspot hotspot, int itemID)
        {
            pendingInteractions.Add (new PendingInteraction (hotspot, itemID, true));
        }
    
    
        private class PendingInteraction
        {
    
            public Hotspot hotspot;
            public int iconID;
            public bool isInventoryInteraction;
    
            public PendingInteraction (Hotspot hotspot, int iconID, bool isInventoryInteraction)
            {
                this.hotspot = hotspot;
                this.iconID = iconID;
                this.isInventoryInteraction = isInventoryInteraction;
            }
    
            public void Run ()
            {
                if (isInventoryInteraction)
                {
                    hotspot.RunInventoryInteraction (iconID);
                }
                else
                {
                    hotspot.RunUseInteraction (iconID);
                }
            }
    
        }
    
    }
    
  • I did not understand "interaction menu queue up" means. Does it mean custom scripting in Menu manager elements?

    You mentioned The Sims in your original post, which involves choosing an interaction from a list inside a menu - similar to AC's "Choose Hotspot Then Interaction" menu. I assumed you were after something similar, but the technique above should still work regardless of how interactions are triggered.

    The main thing to look out for though, is that the queue must only be processed while in gameplay. As running an Interaction will cause the game to go into "cutscene" mode, skipping this check will cause all interactions to run at once.

    Be sure to check that you're in gameplay before processing the queue - see the IsInGameplay check wrapping around the queue-processing block in my original script's Update function.

    Side note: I mis-named the class name - you don't need to use "UpdateSpeechActions" for the class/file name. Best renamed to something like PendingInterations instead.

  • edited June 2022

    Thank you very much! Best asset I ever bought from unity store.

    I hope it scheduling gets to be part of adventure creator someday! Here is the messy code where scheduling works if anyone is interested:

    using UnityEngine;
    using AC;
    using System.Collections.Generic;
    
    public class UpdateSpeechActions : MonoBehaviour
    {
    
        private List<PendingInteraction> pendingInteractions = new List<PendingInteraction> ();
    
        public void Update ()
        {
            if ((Input.GetMouseButtonUp (0) || (Input.touchCount == 1 && Input.GetTouch (0).phase == TouchPhase.Ended)) && KickStarter.stateHandler.IsInGameplay () && KickStarter.playerInput.GetDragState () == DragState.None)
            {
                Ray ray = Camera.main.ScreenPointToRay (KickStarter.playerInput.GetMousePosition ());
                if (Physics.Raycast (ray, out RaycastHit hit, KickStarter.settingsManager.hotspotRaycastLength, 1 << LayerMask.NameToLayer (KickStarter.settingsManager.hotspotLayer)))
                {
                    Hotspot hitHotspot = hit.collider.gameObject.GetComponent<Hotspot> ();
                    if (hitHotspot)
                    {
                        pendingInteractions.Add (new PendingInteraction (hitHotspot, -1, false));
                        Debug.Log(hitHotspot);
                    }
                 }
            }
            if (KickStarter.stateHandler.IsInGameplay () && KickStarter.playerInteraction.GetHotspotMovingTo () == null)
            {
                if (pendingInteractions.Count > 0)
                {
                    pendingInteractions[0].Run ();
                    pendingInteractions.RemoveAt (0);
                }
            }
    
    
        }
    
    
    
        public void QueueUseInteraction (Hotspot hotspot, int iconID)
        {
            pendingInteractions.Add (new PendingInteraction (hotspot, iconID, false));
        }
    
    
        public void QueueInvInteraction (Hotspot hotspot, int itemID)
        {
            pendingInteractions.Add (new PendingInteraction (hotspot, itemID, true));
        }
    
    
        private class PendingInteraction
        {
    
            public Hotspot hotspot;
            public int iconID;
            public bool isInventoryInteraction;
    
            public PendingInteraction (Hotspot hotspot, int iconID, bool isInventoryInteraction)
            {
                this.hotspot = hotspot;
                this.iconID = iconID;
                this.isInventoryInteraction = isInventoryInteraction;
            }
    
            public void Run ()
            {
                if (isInventoryInteraction)
                {
                    hotspot.RunInventoryInteraction (iconID);
                }
                else
                {
                    hotspot.RunUseInteraction (iconID);
                }
            }
    
        }
    
    }
    
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.