Hi, I have been looking for the solution to keep a prefab dragging for a long time. If i drag a gameobject through a viewportPos, the gameobject will be destroyed and instantiate a prefab at mouse position. While my mouse still down, i would like to keep the prefab dragging. Is there solution for doing that???
here is my script:
public void OnDrag(PointerEventData eventData)
{
Vector2 item_world_position = Camera.main.ScreenToWorldPoint(Input.mousePosition);
transform.position = item_world_position;
var viewportPos = Camera.main.WorldToViewportPoint(transform.position);
if (viewportPos.y > 0.165)
{
// Get the prefab to instantiate
Transform itemprefab = itemBeingDragged.GetComponent<InventoryItem>().item_prefab;
// Instantiate it to world position
Instantiate(itemprefab, item_world_position, Quaternion.identity);
itemprefab.transform.SetParent(GameObject.FindGameObjectWithTag("GroundedItem").transform, true);
Destroy(itemBeingDragged);
Destroy(itemBeingDragged.transform.parent.gameObject);
}
}
It can be done this way.
- Add the script [i will call it the **First** ] to the gameobject you drag through viewport.
- Add a Spawned script to the object you want to spawn
Warning: You are destroying the First script after the new object is spawned. If you do that, it will not work. I will recommend you to disable it til you are holding the new Spawned object. Once you do the mouse up on the new Spawned object, then destroy First.
------------------EDIT--------------------------
So i made a sample project of this scenario, tested it and it works. I would recommend you also to make a simple sample project with one UI image object in the scene, and one UI image prefab which spawns. As i am not aware of all the details of the project requirements, once you get a hold of the concept, you can add your custom functionality.
First script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class First : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
public GameObject itemprefab;
private Spawned _spawnedScript;
public static GameObject itemBeingDragged;
private Transform thisObjectTransform;
private Transform spawnedItemParent;//parent of the spawned item
private Transform mainCamTrans;
private Camera mainCamScript;
private Vector2 item_world_position;
private Vector3 viewportPos;
Vector3 startPosition;
Transform startParent;
PointerEventData data;
void Start()
{
//caching for optimisation
spawnedItemParent = GameObject.Find("Canvas").transform;//not recommended method. Must be cached from some manager script
mainCamScript = Camera.main;
mainCamTrans = Camera.main.transform;
thisObjectTransform = transform;
item_world_position = Vector2.zero;
viewportPos = Vector3.zero;
}
public void OnBeginDrag(PointerEventData beginData)
{
//pass the BEGIN pointer event data to the new spawnned object
if (_spawnedScript != null)//null till the object is spawned
{
_spawnedScript.OnBeginDrag(beginData);
}
itemBeingDragged = gameObject;
startPosition = thisObjectTransform.position;
startParent = thisObjectTransform.parent;
}
public void OnDrag(PointerEventData duringData)
{
//pass the DRAG pointer event data to the new spawnned object
if (_spawnedScript != null)
{
_spawnedScript.OnDrag(duringData);
}
item_world_position = mainCamScript.ScreenToViewportPoint(new Vector3(duringData.position.x , duringData.position.y , mainCamTrans.position.z));
thisObjectTransform.position = item_world_position;
viewportPos = mainCamScript.WorldToViewportPoint(thisObjectTransform.position);
if (viewportPos.y > 0.165 && _spawnedScript==null)
{
GameObject go = Instantiate(itemprefab, spawnedItemParent);
go.transform.position = item_world_position;
_spawnedScript = go.GetComponent<Spawned>();
/*
* Sorry i forgot to warn you that disabling the FIRST script will disable the pointer system
* I would recommend to make its color to "Clear" so that it is not visible.
* We will disable/destroy it when the player performs mouse up
*/
itemBeingDragged.GetComponent<Image>().color = Color.clear;
}
}
public void OnEndDrag(PointerEventData endData)
{
//pass the END pointer event data to the new spawnned object
if (_spawnedScript != null)
{
_spawnedScript.OnEndDrag(endData);
/*
* Here we will disable/destroy this script.
* Make sure that it is after we have passed on the pointer data
*/
// itemBeingDragged.SetActive(false);
Debug.Log("First objtect destruction");
Destroy(this.gameObject);
}
itemBeingDragged = null;
if (thisObjectTransform.parent == startParent)
{
thisObjectTransform.position = startPosition;
}
}
}
Spawned script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
//This is the new spawned object
public class Spawned : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
Vector2 temp;
void Start()
{
temp = Vector2.zero;//cache for optimisation
}
public void OnBeginDrag(PointerEventData beginData)
{
//give the object the touch/mouse position
//vector3 should not be used else it will give Z depth to the object
temp = Camera.main.ScreenToWorldPoint(beginData.position);
transform.position = temp;
}
public void OnDrag(PointerEventData duringData)
{
//give the object the touch/mouse position
//vector3 should not be used else it will give Z depth to the object
temp = Camera.main.ScreenToWorldPoint(duringData.position);
transform.position = temp;
}
public void OnEndDrag(PointerEventData endData)
{
//give the object the touch/mouse position
//vector3 should not be used else it will give Z depth to the object
temp = Camera.main.ScreenToWorldPoint(endData.position);
transform.position = temp;
}
}