Forum rules - please read before posting.

Inventory item select - drag and drop

Hi All,
I am sure this has been discussed many times over. Unfortunately, searching through the forum and elsewhere I am not getting the right information.

I want to select an item from the inventory list. Drag it over to the main screen (anywhere) and display the object on the mainscreen. Research tells me, I am to create a hotspot for the object to be dropped into. I will also need to create an actionlist. This is where my problem arises. I don't know what needs to go in the actionlist and in what order to make it happen.

What I have done so far, Inventory:Select, Object:Add - Relative to GameObject:Hotspot

I also want to make sure the selected GameObject/item is sized appropriately (its small in the inventory list but needs to be at its normal size in main screen).

Anyone know the process?

Comments

  • You're referring to literally drop an item into the scene so that it appears there - as opposed to AC's "drag and drop" mode that allows for item dragging with a single hold of the mouse button? Or is "drap and drop" also enabled?

    This isn't a built-in feature, so you'll need a bit of custom scripting to help here. Is this for a 2D or a 3D game? If it's in 3D, should it be floating if not clicked in the ground? I think some screens to illustrate the intended behaviour will help clarify things here.

    An item in the Inventory Manager, and its in-scene representation, are two different things (see e.g. the Worm on the ground vs the Worm in the inventory in the 2D Demo).

    You'll first need to create a prefab of the item that can be placed in the scene (i.e. a Sprite Renderer that you can scale to the appropriate size, along with whatever components e.g. Hotspot that you want it to have). Then make it a prefab, and assign it as the corresponding inventory item's Linked prefab field. Through script, we can then reference that linked prefab and spawn an instance dynamically.

    Be aware that to save the presence of prefabs spawned at runtime, you'll need to attach the Remember Transform component - see the Manual's "Saving scene objects" chapter for details on this.

    Anyway, this script will get you most of the way there - but I'll need details above to refine things properly:

    using AC;
    using UnityEngine;
    
    public class InventorySceneDrop : MonoBehaviour
    {
    
        public Hotspot hotspotToDropOnto;
    
    
        private void OnEnable ()
        {
            EventManager.OnInventoryDeselect += OnInventoryDeselect;
            EventManager.OnInventorySelect += OnInventorySelect;
            EventManager.OnHotspotInteract += OnHotspotInteract;
    
            hotspotToDropOnto.TurnOff ();
        }
    
    
        private void OnDisable ()
        {
            EventManager.OnInventoryDeselect -= OnInventoryDeselect;
            EventManager.OnInventorySelect -= OnInventorySelect;
            EventManager.OnHotspotInteract -= OnHotspotInteract;
        }
    
    
        private void OnInventoryDeselect (InvItem invItem)
        {
            hotspotToDropOnto.TurnOff ();
        }
    
    
        private void OnInventorySelect (InvItem invItem)
        {
            hotspotToDropOnto.TurnOn ();
        }
    
    
        private void OnHotspotInteract (Hotspot hotspot, AC.Button button)
        {
            if (hotspot == hotspotToDropOnto)
            {
                InvItem lastItem = KickStarter.runtimeInventory.LastSelectedItem;
                KickStarter.runtimeInventory.Remove (lastItem);
    
                Vector3 screenPosition = Input.mousePosition;
                screenPosition.z = 1f; // depth from camera
    
                Vector3 position = Camera.main.ScreenToWorldPoint (screenPosition);
                GameObject newObject = (GameObject) Instantiate (lastItem.linkedPrefab, position);
                newObject.name = lastItem.linkedPrefab.name;
    
                if (newObject.GetComponent <RememberTransform>())
                {
                    newObject.GetComponent <RememberTransform>().OnSpawn ();
                }
            }
        }
    
    }
    

    Paste into a C# script named InventorySceneDrop, add it to your scene, and assign the Hotspot in your Inspector. It uses event hooks to do the following:

    • When an item is selected, turn the Hotspot on
    • When the game begins, or when an item is deselected, turn the Hotspot off
    • When the Hotspot is interacted with, remove the last-selected item from the inventory, and spawn it's "linked prefab" into the scene
  • Okay Chris, I have tried above and getting a bit confused. The script provided was giving me a bit of problems.
    Anyway, I seem to have it working. Its a 2D activity game. I was able to instantiate the object upon clicking an inventory item. I was hoping to drag it into scene and then it pops to its normal size. I think the script above does that. Just not getting it on my end.

    I have provided a video of my work so far (https://imgur.com/a/3sTkQwJ). I need to lock in a gameobject (ie bowl) so others can be moved in front of it (layers). The bowl is layer 0 and the cornflakes/apple is layer 1. Apparently, the bowl is always selected and not the layers in front of it.

    I am also trying to remove a gameobject with rightmousebuttondown click. Not working.

    Re: Bowl and cornflakes, I could replace that with another prefab of both in a bowl and it becomes one gameobject. That would mean any other food that goes into a bowl, I will have to make that type of food in a bowl.

    Q: Is there a maximum in the inventory list? Am I able to scroll further(for instance add 50 different food types)

  • The script provided was giving me a bit of problems.

    Such as?

    I need to lock in a gameobject (ie bowl) so others can be moved in front of it (layers).

    If you're talking about Sprite layers - those only deal with how things are displayed relative to one another, not with how they interact.

    How are you dragging the items in the scene around? With a Draggable, or some custom system? And is this a 2D scene or 3D scene (so far as AC understands it)?

    AC logic raycasting is handled by distance from the camera - so moving non-bowl items further to the camera should make them take precedence, though perhaps it would be better to simply disable whatever component on the bowl makes it moveable, so that it doesn't respond to input.

    I am also trying to remove a gameobject with rightmousebuttondown click. Not working.

    Is your Interaction method set to Context Sensitive? Right-clicking can be used to run a Hotspot's Examine interaction, to which you can attach an Object: Add or remove Action to remove it.

  • Im using AC's PickUp:Moveable system to move the sprites around.

    Ok, I have disabled the bowl's collidier . It can instantiate and then sit there.

    Re: removing object. Yes, my interaction is set to Context Sensitive. I have created an examine interaction and attached the action Object: Add or Remove. Not working.

    Re:Script...Doesn't do anything. I have tried it a few times in 3d and 2d apparently, I get this "position" error in line 52 of the InventorySceneDrop.cs (I do not use this with my PickUp:Moveable system though).

  • I have created an examine interaction and attached the action Object: Add or Remove. Not working.

    There's not much here to go on. Is the Interaction running, or the Action not working? You can find out by adding an ActionList: Comment Action to output something to the Console when it's triggered - does it display?

    If so, let's see some screenshots of the ActionList, and the full Inspector of the prefab it's referring to.

    Re:Script...Doesn't do anything.

    Try this:

    using AC;
    using UnityEngine;
    
    public class InventorySceneDrop : MonoBehaviour
    {
    
        public Hotspot hotspotToDropOnto;
    
    
        private void OnEnable ()
        {
            EventManager.OnInventoryDeselect += OnInventoryDeselect;
            EventManager.OnInventorySelect += OnInventorySelect;
            EventManager.OnHotspotInteract += OnHotspotInteract;
    
            hotspotToDropOnto.TurnOff ();
        }
    
    
        private void OnDisable ()
        {
            EventManager.OnInventoryDeselect -= OnInventoryDeselect;
            EventManager.OnInventorySelect -= OnInventorySelect;
            EventManager.OnHotspotInteract -= OnHotspotInteract;
        }
    
    
        private void OnInventoryDeselect (InvItem invItem)
        {
            hotspotToDropOnto.TurnOff ();
        }
    
    
        private void OnInventorySelect (InvItem invItem)
        {
            hotspotToDropOnto.TurnOn ();
        }
    
    
        private void OnHotspotInteract (Hotspot hotspot, AC.Button button)
        {
            if (hotspot == hotspotToDropOnto)
            {
                InvItem lastItem = KickStarter.runtimeInventory.LastSelectedItem;
                KickStarter.runtimeInventory.Remove (lastItem);
    
                Vector3 screenPosition = Input.mousePosition;
                screenPosition.z = 1f; // depth from camera
    
                Vector3 position = Camera.main.ScreenToWorldPoint (screenPosition);
                GameObject newObject = (GameObject) Instantiate (lastItem.linkedPrefab);
                newObject.transform.position = position;
                newObject.name = lastItem.linkedPrefab.name;
    
                if (newObject.GetComponent <RememberTransform>())
                {
                    newObject.GetComponent <RememberTransform>().OnSpawn ();
                }
            }
        }
    
    }
    
  • edited April 2020

    Okay, I have sorted out removing objects as I did not add the removeable script to the gameobject. However, each and every one of them, when I instantiate them onto scene, they all disappear at once. I were to remove them individually. How do I resolve this to remove them individually?

    Its coming together nicely. Not able to drag from the inventory though but instantiate them on scene. They can move around individually using the "Pickup Moveables".

    Lastly, how do I implement your script. I tried using it but I can not get it to work though. I think somewhere in the steps I am not getting it right.

    As requested, my Actionlist and Inspector is in video attached. https://imgur.com/a/b6D7Co8

  • Please show the Inspector in full - you're only showing part of it in the video, and most of the components are collapsed.

    You've also got a "Remove Objects" component, and I'm not sure what relevance that has.

    ActionList assets refer to scene objects by ID number - is the Butter_Examine's referenced ID 97976 unique to the Moveable_Butter prefab, or do your other prefabs share the same ID number? What is the effect of running this list manually from the Inspector?

    To use the script, create the Hotspot you described in your first post and attach the script to it, assigning the Hotspot in the Inspector field. Don't create any Interactions.

    It should turn off automatically when the scene begins, and turn itself on when you select an inventory item. If you use an item on the Hotspot, it should spawn the item in the scene. You'll have to disable your item "Use" interactions to select items, as a Use interaction will override this behaviour.

  • Remove Objects component is there because it will not work without it. I tried it on its own and its un-clickable. I suspected it needs a button function to remove it.

    All the other prefabs have different ID numbers. However, they all share the same Remove Objects script so that's why its disappearing from scene at once. Its the only method I know to remove the gameobject from scene. I suspect you're saying its supposed to work without the script.

    Video can be seen from here:

  • I researched via other people's experience and noticed that removing objects is not best practice so the best solution is to either make GO invisible or transport them out of scene. Tried these, and apparently the examine button will not do anything.

    However, if I were to transport using "Use" ActionList, the GO will transport to wherever I assign it to.

    Q: am I to create anything for the "Examine" button to make it function? Like I did with the remove objects script.

    I'm using Unity 2019.3.2f1 AC: v1.70.4

  • I don't know what's on your Remove Objects script, but you have no Examine interaction defined in your Hotspot. This is where your remove/teleport Actions need to be run from.

    Your video shows that the "Butter_Examine" list works when run - but the scene instance of the item is separate from the item in the inventory. Assigning this list in the "Examine" interaction slot in the Inventory Manager will not have any effect when manipulating the spawned object within the scene - it's a different entity.

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

    public class RemoveObjects : MonoBehaviour
    {
    public GameObject GameObject;
    // Start is called before the first frame update
    void Start()
    {
    KickStarter.playerInput.InputGetMouseButtonDownDelegate = CustomGetButtonDown;
    }

    private bool CustomGetButtonDown (int buttonName)
    {
        return Input.GetMouseButtonDown(1);
    }
    
    // Update is called once per frame
    void Update()
    {
        if(Input.GetMouseButtonDown(1))
        {
            Destroy(GameObject);
        }
    }
    

    }

    Okay, understood. Its a different entity. After trying out prefab and hotspot:examine on its own, it doesnt work at all. So, when an GameObject is in scene and attached a hotspot:examine on its own, it works.

    Can't have both at once. What is my next best solution? I loved the spawning from inventory and I like to remove individual GameObjects.

  • Your script doesn't account for which object the mouse is over when a button is pressed - so any object with it attached will be deleted.

    So, when an GameObject is in scene and attached a hotspot:examine on its own, it works

    But when attached to a prefab it doesn't? The prefab's Hotspot will need to have its Interaction source field set to Asset File so that you can assign an ActionList asset into it - but otherwise there shouldn't be any difference in behaviour. Let's see how things are set up now.

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.