drip item issue( inventory) !!

hi to all… i’m having a weird issue with my inventory script… all works fine but the drop function not…
sometimes when drop item from inventory (moving it outside the inventory slot) item dont appear on floor but pass throguht it and go out form the scene. I noticed this happen more often when i have several object of the same type in my inventory, but happen rarely even if i have a single object…

thisis the code for my item script

using UnityEngine;
using System.Collections;

[RequireComponent(typeof(Rigidbody))]

public class Item : MonoBehaviour
{
    public int itemID;
    public int maxStackAmount;

    public float interactTime;

    public bool usable;

    [HideInInspector]
    public bool wasPlaced;

    public Texture2D slotIcon;
   
   
   

    private Renderer thisRenderer = null;
    private Collider thisCollider = null;

    private Inventory playerInventory = null;



    private void OnValidate ()
    {
        if (itemID < 1)
            itemID = 1;

        if (maxStackAmount < 1)
            maxStackAmount = 1;

        if (interactTime < 1)
            interactTime = 1;
    }

    private void Awake ()
    {
        thisRenderer = GetComponent<Renderer>();
        thisCollider = GetComponent<Collider>();

        playerInventory = GameObject.FindObjectOfType<Inventory>();
    }

   

    public void PickupItem (Transform player)
    {
        // Set our parent as the Player's Camera.
        transform.parent = player.Find("Camera").Find("Inventory Items");

        if (thisRenderer == null)
        {
            for (int i = 0; i < transform.childCount; i++)
                transform.GetChild(i).GetComponent<Renderer>().enabled = false;
        }
        else
        {
            thisRenderer.enabled = false;
        }

        thisCollider.isTrigger = true;
    }

    public void DropItem ()
    {
        transform.position = transform.parent.position;
        transform.rotation = transform.parent.rotation;
        transform.parent = null;

        if (thisRenderer == null)
        {
            for (int i = 0; i < transform.childCount; i++)
                transform.GetChild(i).GetComponent<Renderer>().enabled = true;
        }
        else
        {
            thisRenderer.enabled = true;
        }

        thisCollider.isTrigger = false;
        GetComponent<Rigidbody>().AddForce(transform.forward * 40, ForceMode.Force);
    }

    private void Interacting ()
    {
        if (!playerInventory.InventoryHasSpace())
            return;

        GameObject playerCamera = playerInventory.transform.FindChild("Camera").gameObject;

        PlayerInteraction interaction = playerCamera.GetComponent<PlayerInteraction>();

        interaction.interactTime = interactTime;
        interaction.interactLabel = "Picking up...";
    }

    private void Interacted ()
    {
        playerInventory.AddItem(this);
    }
}

i dont have any issue or error on console

any hnit?

I don’t know what your scene view looks like, but if the origin of your parent object is on the ground plane or terrain, then when you set the position of the dropped object to that of the parent on line 72, it’ll already be intersecting the floor collider, so there’s a good chance it’ll fall through it. If this is the problem, just raise up the dropping position on the y axis.

yes the origin of the parent object is on the ground plane on terrain if i indeded waht you mean(are simply helath packs for player health…) … i tried to raise the drop position on the y axis but this is not my problem since evenif i set and hight value for the y axis randomlly ojbeect fall trought the terrain when dropped

Then the next thing I’d troubleshoot would be the collisions between your health packs and the terrain without your script. If you get a bunch of health packs and just place them around your scene at various heights, do any of them fall through the terrain? Very small colliders, or colliders moving quickly (or worse, both) are very prone to this. Mesh colliders won’t work either of course.

If that’s the problem, then adjust the colliders and collision settings. If not, play your game and pause when you’ve dropped a health pack. In the heirarchy, check if the health pack game object you just dropped has a working collider on it. Your script requires a rigidbody component, but doesn’t specify for a collider.

Next idea would be that perhaps it’s colliding with the player’s own collider, or more likely with other colliders from the other dropped objects. If that’s true then as the health packs are dropped they might be accellerated massively as Unity’s physics figures it’s deeply intersecting another collider, and so fires them back out of it so fast that they’re not always registered as hitting the terrain even with relatively normal colliders. This could be solved with collision layers, or in a couple of other ways through script.

Sorry I couldn’t just point at something that’s definitely the issue - it may be that I don’t know enough yet to be able to pin it down, but it could still just be that I have missed something. If you post a project file then I’d be happy to try and replicate the problem that way.

1 Like

thakns again for your help and for yur hints…

as you said i think issue is caused by collision with player own collider and dropped object are massively accellerated and pass troght the terrain…
how can i solde this… what do you mean about collison layers?? or are these other ways trought script?

OK, so if this is the problem, then you can test it to be sure by temporarily disabling gravity for the player as well as the player’s colliders.

If your dropped objects behave themselves under those test conditions, then enable it all again and have a quick read through Unity’s collision layers page in the manual.

This now provides you with a tool that can help solve the problem, but the exact way you choose to use it totally depends on what you want to happen in your game logic. Bear in mind that there are actually two similar problems at play simultaneously if this is the case; firstly that the object is overlapping the player collider, and secondly that the dropped object colliders are smushed on top of each other as they are positioned for ejection.

The easiest way to solve the first of the two problems is to have the position from which they are chucked start already outside of the player collider.

The easiest way to solve the second problem is to either only drop one object at once, or to have objects ignore each other’s collisions using collision layers.

But if you don’t like that behaviour, then there are a bazillion other ways to do this that are a tad more complicated.

Here’s an example - Dropped objects just overlap each other in a big smush, but you can drop as many as you like all at once without any weird physics. Once you’ve dropped them, you can’t pick them up until a little bit of time has elapsed, so as to avoid instantly hitting them again or having crazy collisions happen as they exit your inventory. What this means is that they are effectively on a layer that only interacts with the Terrain layer. After a second or two, they are moved to a layer that interacts with both the Terrain and the Player layers. To do this, set the layers as described here, then have a function in your dropping script that makes sure they are in the Terrain only layer as they’re chucked out, and have a script on the dropped objects that, after a designated amount of time will change them back to the layer that can collide with both the Terrain and Player, but still can’t collide with other droppable objects.

Another example - Objects can only be dropped one at a time, but they can collide with each other to make a big, satisfying, physics-ey rigidbody heap. Again, once you’ve dropped them you have the small delay with them on the special layer to avoid unwanted behaviour. By having only one object being dropped at a time, unless the player is mashing the drop button like crazy (if it’s a problem you can additionally put a timer in to prevent excessively fast dropping) you’ll not have multiple dropped objects spawning on top of each other in a glitchy heap. This avoids the previously example’s necessity of having them unable to interact with other dropped objects. Note you can’t really do the same trick as with the Player’s layer, as if you drop two objects in the same place, when their timers run out they may well explode wildly off each other as they realise their colliders already overlap.

There are other tricks too that can facilitate other solutions, such as using a collider and a trigger on the same object or creating an array of non-overlapping points from which stuff can be dropped simultaneously so as to avoid dropped object overlapping. Personally I solved this problem in my current project by using an animation that either places down or throws an object based on user inputs. The trigger for the object to react again with the player is the point at which the animation releases the object, and objects don’t interact with the player’s big and unweildy capsule collider ever, but do get booted around by the finer compound collider that makes up the more detailed shapes of the various body parts.

One last quick edit - just in case you aren’t already aware - make sure you don’t use mesh colliders on moving objects. If you absolutely must, make them convex.

Best of luck!

Wow… mant many many thanks for your great help and explaination…you give me some great tips on how to solve my issues and i think i solved them…

my only remaining issue(dont related to my prevoiuse issue) is the interaction with object dont works properly since when i come too close the object pickup dont work and i must move away from obejct to make it pickupable again…

i tried too many modes but i cannot figured how to fix this…

can you pelae try to give me some hints about that too??

here my player interacton script…

using UnityEngine;
using System.Collections;

public class PlayerInteraction : MonoBehaviour
{
    public float interactDistance;

    [HideInInspector]
    public float interactTime = float.MaxValue;

    [HideInInspector]
    public string interactLabel;

    [HideInInspector]
    public GameObject currentObject;

    public Texture2D emptyBarTexture;
    public Texture2D fullBarTexture;

    public KeyCode interactInput;

    private float interactTimer = 0f;

    private bool pressedKey = false;

    private RaycastHit hit;

    private void OnValidate ()
    {
        if (interactDistance < 0)
            interactDistance = 0;
    }

    private void Update ()
    {
        // Create a new Ray from our position pointing forward.
        Ray ray = new Ray(transform.position, transform.forward);

        if (Physics.Raycast(ray, out hit, Mathf.Infinity))
        {
            float hitDistance = Vector3.Distance(transform.position, hit.point);

            if (hitDistance <= interactDistance)
            {
                currentObject = hit.transform.gameObject;

                if (Input.GetKeyDown(interactInput))
                    pressedKey = true;

                if (Input.GetKey(interactInput) && pressedKey)
                {
                    currentObject.SendMessage("Interacting", SendMessageOptions.DontRequireReceiver);

                    if (interactTimer >= interactTime)
                    {
                        currentObject.SendMessage("Interacted", SendMessageOptions.DontRequireReceiver);

                        interactTimer = 0f;
                        pressedKey = false;
                    }
                    else
                    {
                        interactTimer += Time.deltaTime;
                    }
                }
                else
                {
                    currentObject = null;
                    interactTimer = 0f;
                    pressedKey = false;
                }
            }
            else
            {
                currentObject = null;
            }
        }
        else
        {
            currentObject = null;
        }
    }

    private void OnGUI ()
    {
        if (currentObject != null && Input.GetKey(interactInput))
        {
            Rect interactLabelRect = new Rect
                                     (
                                         Screen.width / 2 - 100 + (interactLabel.Length * 5),
                                         Screen.height - 60,
                                         interactLabel.Length * 10,
                                         50
                                     );

            GUI.Label(interactLabelRect, interactLabel);

            Rect barRect1 = new Rect(Screen.width / 2 - 100, Screen.height - 40, 200, 10);
            Rect barRect2 = new Rect(Screen.width / 2 - 100, Screen.height - 40, (interactTimer / interactTime) * 200, 10);

            GUI.DrawTexture(barRect1, emptyBarTexture, ScaleMode.StretchToFill);
            GUI.DrawTexture(barRect2, fullBarTexture, ScaleMode.StretchToFill);
        }
    }
}

What is the PlayerInteraction script attached to, and where is the transform’s position relative to other game objects in the scene?

It might be a good idea to use Debug.DrawRay to draw a visible representation of the raycast so you can see if it’s just physically missing the target, or more likely originating inside the target object’s collider and therefore ignoring it in favour of a null or more distant target that’s outside of the range of interactDistance.

yes, i used debug drawray yet and all is fine simply interact is not active when player is too lcose t oobject or above it…

script is attached to main camera…

Could you post a screenshot of the scene view (complete with debug lines) of what’s happening when the objects are failing to interact?

i figured it’s is related to the player height since i tried with player crouched and pickup works correcly even when player is closest to pickup… so it’s something related to the player ray distance with the object in the playerinteraction.cs script… but i dont know what…

I’m afraid there are too many potential possibilities for me to help you with debugging this one unless you can provide more data about it :frowning: The ray goes straight out from your transform (transform.forward), so if that’s at an angle then that could produce this behaviour, but otherwise so could a great many other things. If you’ve used the scene view with the debug lines to visualise it, and the line is in constant contact with the target’s collider whilst you’re still unable to interact, then I honestly don’t know what to suggest right now. If you’d prefer not to post screenshots, then your best bet is to treat this in a scientific manner and systematically work your way through it by debugging each individual component that could be at fault until you isolate the exact issue. If all else fails, maybe try putting up a new post specifically for this new problem, providing as much relevant info as possible - maybe someone a bit more experienced than myself could see something I’ve missed?