Forum rules - please read before posting.

[Building a new mechanic] I don't know if this is the right usecase for AC

ACVACV
edited November 2024 in Technical Q&A

Hey everyone,

I am not sure if the mechanic I am trying to build for my adventure game right now works well with AC, so I wanted to get a headsup on whether I am hitting ACs limits here and how much custom functionality the plugin can take before things get too convoluted and messy.

What I am trying to do is have players "build" the sillhouette of a creature that they have a drawing of.

They have a base object which they will attach all the other items to they need to use in order to spawn the creature.

They need to place the items at the right spots (compared to the drawing) and rotate them so that it looks similar.

When they are done, the assortment of items is going to transform into an actual NPC that you can do things with etc.

I have started prototyping this in Unity and with AC but so far, I have had to find many custom solutions such as

  1. Having a CursorIconManager script that lets me rotate the sprites of my currently selected items, instead of using ACs standard Cursor and Interaction Icon system.
  2. Having a CreatureDrawingManager script that loads the data of each creature via a scriptable object (which items do I need, how many of them etc).
  3. All the items need to be manifested as game objects instead of just triggering an interaction as they "physically" need to be in the right place with the right rotation etc.

Before asking any further questions I would be interested in whether you guys think a feature of this scope is possible to implement in AC or if for this specific feature, it would be more efficient to rely on Unity only.

Comments

  • edited November 2024
    Hey! First of all it looks amazing! I'm not that experienced with AC but just a thought how to maybe drastically simplify it - what if you had fixed rotations (say 90 degree increments that literally reload a different hotspot) and only the correct increment would switch on a variable.

    Then you'd have triggers on the right places that would interact with only the correct increment. When all of the triggers have the right increments it would transform to NPC.
  • Thank you @EridanFresh !

    We had actually thought about a similar approach and tested some early prototypes in Miro and experimented with 90 degree angles but both us and playtesters greatly preferred being able to rotate the object freely. However, we have implemented a range of acceptable rotations, right now about +-10 degrees.

  • The closest AC comes to this mechanic is the "Item arranging" puzzle template over on the Downloads page. This provides the ability to "grab and drop" sprites in the scene, "winning" if you place them in the correct spots.

    If you were starting from scratch, I'd say it'd be worth looking into customising it with the ability to rotate objects. If you've already gotten your own solution without involving AC, though, that may be the better option.

    Either way, you can certainly use AC for the NPC "awakening" with regular NPC/Hotspot components, enabled once the puzzle is solved.

  • Right, thank you.

    As I didn't realize this template existed I have started from scratch already. Would you be willing to give me feedback on my current setup? As this is one of the central features in our game I would like to adhere to good practices and make sure that this feature stays fully expandable for later.

  • From what you've described, it sounds like a good approach. You can selectively disable AC's systems, such as the cursor and interaction systems, with the Engine: Manage systems Action if you want to temporarily replace built-in behaviour with your own.

    A particular factor to consider is whether you want to include the state of the scene in save-game files. If you do, and the items are spawned in via script based on the ScriptableObject, you'd need to have a custom Remember component that can record each of their states.

  • That is a really good point actually.

    One particular problem I am struggling with right now is placing my items but only recognizing them in certain hotspots.

    In this example, the big mossy stone serves as my base object to attach the other items to. I would like to be able to place my items everyhwere in this big hotspot but only when I place the items in one of the small hotspots (which are child objects) I want the system to recognize that these hotspots are filled with the right item.

    However, since I am using an interaction between the two small hotspots and their respective items, I am not quite sure how to achieve this.

  • Alright, after having spent the day with the Arranging Items template, I am fairly sure it will do a better job than my custom solution long-term.

    I will still need to change a few things as you mentioned earlier. As I'm not entirely sure about the workflow, I will write out what the ideal scenario for my use case would be and then ask some questions about the areas I am unclear on.

    The most important part here is most likely the distinction between the usual cursor icons and gameobjects, which are pieces.

    I don't mind scripting things out in c# so there is no need to stick to visual scripting only but if there is a more efficient solution, I would of course prefer that one.

    So:

    1. Every item in the game will also have a piece component so any item can be used for creature drawing (although only some correspond with the correct slot). The item becomes a piece as soon as I drag it out of the inventory. At the same time I have to disable the CursorIcon as to not draw things twice.

    2. I have logic in place to "activate" my base object so that I can start the puzzle.

    3. There is a collider around my base object. Every time I am trying to place a game object (because by extension every item is now a game object instead of just a sprite on the cursor), it will check if I am inside or outside that collider.

    4. If outside: Left clicking will result in the item being deselected and the game object destroyed (the item simply stays in my inventory).

    5. If inside: Left clicking will result in the game object being placed at the position I clicked on (and also remove the item from my inventory). If an item is already placed, right clicking will destroy the game object and add the item back in my inventory.

    6. If a game object/piece has been placed and is also snapped to its correct slot, it stays there and cannot be removed (likely supported by a visual indicator down the line).

    7. If all slots are filled with their correct piece, the NPC will appear.

    My most important questions about this workflow:

    1. I assume I am going to need a custom script turning off the cursor Icon whenever I have an item selected and instead manually drawing the sprite of my currently selected item and attach piece and collider components to it. Any advice here?

    2. How do I turn inventory items into a piece? Even after a fair amount of research I could not find out how to spawn pieces from my inventory and destroy them in order to put the item back in my inventory.

    3. How am I going to get started on the inside/outside the collider logic. I am getting a bit confused between the two layers of gameobject vs item icon

    4. With my previous solution, I had several scriptable objects called CreatureConfig set up that are filled with the information for each creature. Are these redundant now that the ArrangingPuzzleManager exists? I would prefer to have the data on that serializable, in case some creature drawing riddles may be connected across different scenes.

    Any other hints you might have are also much appreicated. Apologies for the long post, I tried to stay as concise as possible.

  • edited November 2024

    I assume I am going to need a custom script turning off the cursor Icon whenever I have an item selected and instead manually drawing the sprite of my currently selected item and attach piece and collider components to it. Any advice here?

    The Arranging Puzzle template doesn't render selected items via the cursor - it automatically set the Cursor Manager's When inventory selected field to Change Hotspot Label when a puzzle item is selected, and restores its original value when de-selected. The items themselves are sprites within the scene that are set to follow the cursor while selected.

    If you're looking through the code, it's done via the ArrangingPuzzleManager's OnInventorySelect / OnInventoryDeselect hooks.

    How do I turn inventory items into a piece? Even after a fair amount of research I could not find out how to spawn pieces from my inventory and destroy them in order to put the item back in my inventory.

    Though the template uses the Inventory system for selection/handling, it actually generates the associated items at runtime. This is intentional, to avoid the user having to create both puzzle items and their associated entry in the Inventory Manager, but it's a good point that there are times when you'd want there to be a link.

    This should actually be possible just by adding a '[SerializeField]' attribute to the front of the ArrangingPuzzlePiece script's associatedItemID variable, and then entering into the Inspector the ID of the linked item (taken from the Inventory Manager).

    The way the template is "supposed" to work is that it expects the puzzle pieces are all in the scene to begin with. You could spawn puzzle pieces in by making them prefabs, assigning as the Item's "Linked prefab", and then using the Inventory: Scene item to spawn them in at runtime. However, the Arranging Puzzle Manager component would need to have its "pieces" array updated as pieces are added. This'd likely involve making the variable public and using a custom script to modify the array as an item is spawned in. I'll have a think about how this might be handled most easily.

    How am I going to get started on the inside/outside the collider logic. I am getting a bit confused between the two layers of gameobject vs item icon

    A regular Hotspot outside of the boundary can have an "Unhandled inventory" interaction that should run if you click on with a puzzle piece selected. A custom Action or script could then feasibly remove this from the scene, but try just having it run a simple speech Action to test this first.

    With my previous solution, I had several scriptable objects called CreatureConfig set up that are filled with the information for each creature. Are these redundant now that the ArrangingPuzzleManager exists

    I wouldn't say so - though the Arranging Puzzle template deals with what items need to be placed and where, your SO includes extra data that would be used elsewhere.

    When the puzzle is "won", the assigned "ActionList on win" will be run. This could be set up to reference / trigger additional code within the SO to spawn in the creature.

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.