- Home /
Item pickup and drop function
So I am working on a pickup and drop object function on a 2d game.
To summarize the function, The player has a disabled object as a players child and when the player picks up the dropped object, the dropped object gets destroyed and the object that is disabled gets activated. After this process, the player has a choice to drop the object again, which makes the object in the players hand back to disabled and the dropped object which is a prefab gets instantiated from the players hand. Oh and of course the prefab object that is dropped has a destroy function whenever the player presses a key to pick it up.
The problem occurs after the instantiation. The instantiated clone's destroy method doesn't work after the first process of pick and drop. The original object works perfectly but at the second attempt which is the pickup and drop function for the clone doesn't work. To be clear the original dropped object's destroy function works but the clone prefab object's destroy function doesn't work even though they both have the same destroy script attached. The instantiate function(which is the drop function) works fine but because the destroy function (which is the pickup) doesn't work the player just duplicates the object at the pickup process.
Someone plz save me!!
// this is basically the script of the players object activation
public class object_controller : MonoBehaviour
{
public static bool hasItem;
public GameObject spear;
public GameObject spear_dropped;
bool spear_scanner;
void Update ()
{
pickUp();
drop();
}
void pickUp ()
{
if (spear_scanner == true)
{
spear.SetActive(true);
spear_scanner = false;
hasItem = true;
}
}
}
void drop ()
{
if (Input.GetKeyDown(KeyCode.Q) && hasItem == true)
{
hasItem = false;
if (spear.activeSelf == true)
{
spear.SetActive(false);
Instantiate(cane_dropped, transform.position, Quaternion.identity);
}
}
}
void OnTriggerEnter2D ( Collider2D collision )
{
if (collision.CompareTag("spear"))
{
spear_scanner = true;
}
}
void OnTriggerExit2D ( Collider2D collision )
{
if (collision.CompareTag("spear"))
{
spear_scanner = false;
}
}
}
// and this is the script for the object itself which is the spear
public class dropped_objects : MonoBehaviour
{
public static bool scan;
void Update ()
{
if (Input.GetKeyDown(KeyCode.E))
{
if (scan == true && object_controller.hasItem == false)
{
Destroy(gameObject, 0.01f);
}
}
}
void OnTriggerEnter2D ( Collider2D collision )
{
if (collision.CompareTag("hands"))
{
scan = true;
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("hands"))
{
scan = false;
}
}
}
Answer by privatecontractor · Jan 22 at 03:52 PM
Hi,
sry for mistakes (editing on crapy phone...) after destroying old GameObject, when collision occurs, so when you pick up another GameObject, you also need to grab new GameObject references... and assign them to your spear/ droped_spear variables. Also when you destroying old one, need to remove not existing references. Hope you get it, because currently you assign GameObjects at inspector, and never reassigne them.
void drop()
{
if (Input.GetKeyDown(KeyCode.Q) && hasItem == true)
{
hasItem = false;
if (spear.activeSelf == true)
{
spear.SetActive(false);
**spear = null;**
**droped_spear** = Instantiate(cane_dropped, transform.position, Quaternion.identity) ;**
}
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.CompareTag("spear"))
{
spear_scanner = true;
**spear = collision.gameObject;**
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.CompareTag("spear"))
{
spear_scanner = false;
}
}
Hope will do..
Answer by andrew-lukasik · Jan 23 at 03:50 PM
I don't usually like generalizations in code, but this case would make much sense this way.
Here is a compact, generalized solution so your items can be anything and not something specific & hardcoded. It's also easier to understand I think.
// ItemController.cs:
using System.Collections.Generic;
using UnityEngine;
// SOLE RESPONSIBILITY:
// Enables item picking up and dropping ability. Nothing else.
public class ItemController : MonoBehaviour
{
[Header("Required fields")]
public Transform Socket = null;// picked up items goes here
[Header("Read-Only fields")]
public ItemDefinition EquipedInfo = null;
public GameObject Equipped = null;
public List<ItemWorld> Contacts = new List<ItemWorld>();
void Update ()
{
if( Input.GetKeyDown(KeyCode.E) ) Equip();
if( Input.GetKeyDown(KeyCode.Q) ) Unequip();
}
void Equip ()
{
if( Contacts.Count!=0 )
{
ItemWorld worldItem = Contacts[0];
ItemDefinition worldItemInfo = worldItem.Definition;
Destroy( worldItem.gameObject );
if( Equipped!=null ) Unequip();
Equipped = Instantiate( worldItemInfo.PlayerPrefab , Socket );
Equipped.transform.localPosition = Vector3.zero;
Equipped.transform.localRotation = Quaternion.identity;
EquipedInfo = worldItemInfo;
Debug.Log($"{EquipedInfo.Label} equipped");
}
else Debug.Log("no items to equip");
}
void Unequip ()
{
if( Equipped!=null )
{
Destroy( Equipped );
GameObject droppedAsWorldItem = Instantiate( EquipedInfo.WorldPrefab , transform.position , Quaternion.identity );
Debug.Log($"{EquipedInfo.Label} dropped");
Equipped = null;
EquipedInfo = null;
}
else Debug.Log("nothing to unequip");
}
void OnTriggerEnter2D ( Collider2D collision )
{
ItemWorld item = collision.GetComponent<ItemWorld>();
if( item!=null ) Contacts.Add( item );
}
void OnTriggerExit2D ( Collider2D collision )
{
ItemWorld item = collision.GetComponent<ItemWorld>();
if( item!=null ) Contacts.Remove( item );
}
}
ItemWorld.cs:
using UnityEngine;
// SOLE RESPONSIBILITY:
// Provide a reference to relevant ItemDefinition. Nothing else.
public class ItemWorld : MonoBehaviour
{
public ItemDefinition Definition;
}
ItemDefinition.cs:
using UnityEngine;
// SOLE RESPONSIBILITY:
// Data about an item. Nothing else.
[CreateAssetMenu( fileName="item definition (0)", menuName="Game/Item Definition", order=1 )]
public class ItemDefinition : ScriptableObject
{
public string Label = "player-facing name of this object";// ie. no "stick_0001" but "Stick Of Mighty Powers"
public GameObject PlayerPrefab = null;
public GameObject WorldPrefab = null;
// public float Damage;// etc
}
Your answer
Follow this Question
Related Questions
Picking Up Objects Using C# Not Working 1 Answer
Pick up script goes straight to drop action 0 Answers
Multiple Cars not working 1 Answer
How to pick / drop object 1 Answer
Picking up a box 2 Answers