Making only the graphic inside the bounds of a sprite draggable - c#

I'm building a game upon which objects can be dragged around and arranged to build different types of animals. My question is, is there a way to define the draggable area of each sprite beyond just a simple rectangle? Many of the graphics in my sprites are elliptical and triangular in nature which leaves a lot of clear space around the actual image. I'd like to make just the graphic within the rectangular bounds of my sprite draggable. How can this be done?
Here are some of the graphics to illustrate what I mean by irregular shapes.
So when you draw a bounding box around these shapes there is a lot of clear space that I don't want to be draggable or clickable. I already have a script that handles dragging, but it makes the entire sprite draggable, how do I make just the 2D Polygon Collider accept the drag event?
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class DragHandling : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
Vector3 partsPanelScale = new Vector3(1.0f, 1.0f, 1.0f);
public float partScale;
// public float partRotate;
Vector3 buildPanelScale;
// Vector3 buildPanelRotate;
[HideInInspector] public Transform placeholderParent = null;
[HideInInspector] public Transform parentToReturnTo = null;
GameObject placeholder = null;
[HideInInspector] public GameObject animalPart;
[HideInInspector] public GameObject trashCan;
[HideInInspector] public GameObject partsPanel;
[HideInInspector] public GameObject partsWindow;
[HideInInspector] public GameObject buildBoard;
[HideInInspector] public GameObject horns;
[HideInInspector] public GameObject heads;
[HideInInspector] public GameObject ears;
[HideInInspector] public GameObject necks;
[HideInInspector] public GameObject bodies;
[HideInInspector] public GameObject legs;
[HideInInspector] public GameObject tails;
[HideInInspector] public GameObject more;
GameObject dragLayer;
void Start ()
{
dragLayer = GameObject.FindGameObjectWithTag("DragLayer");
buildBoard = GameObject.FindGameObjectWithTag("Board");
partsPanel = GameObject.FindGameObjectWithTag("Parts");
partsWindow = GameObject.FindGameObjectWithTag("PartsWindow");
trashCan = GameObject.FindGameObjectWithTag("Trash");
horns = GameObject.FindGameObjectWithTag("AnimalPart-Horns");
heads = GameObject.FindGameObjectWithTag("AnimalPart-Heads");
ears = GameObject.FindGameObjectWithTag("AnimalPart-Ears");
necks = GameObject.FindGameObjectWithTag("AnimalPart-Necks");
bodies = GameObject.FindGameObjectWithTag("AnimalPart-Bodies");
legs = GameObject.FindGameObjectWithTag("AnimalPart-Legs");
tails = GameObject.FindGameObjectWithTag("AnimalPart-Tails");
more = GameObject.FindGameObjectWithTag("AnimalPart-More");
}
#region IPointerClickHandler implementation
public void OnPointerClick (PointerEventData eventData)
{
if(transform.parent.gameObject == buildBoard)
{
transform.SetAsLastSibling();
}
}
#endregion
#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
// create placeholder gap and hold correct position in layout
placeholder = new GameObject();
placeholder.transform.SetParent(transform.parent);
placeholder.transform.SetSiblingIndex(transform.GetSiblingIndex());
/*
if(transform.parent.gameObject == partsPanel)
{
partsPanelScale = transform.localScale;
}
*/
parentToReturnTo = transform.parent; // store current parent location
placeholderParent = parentToReturnTo; // set placeholder gameobject transform
GetComponent<CanvasGroup>().blocksRaycasts = false; // turn off image raycasting when dragging image in order to see what's behind the image
}
#endregion
#region IDragHandler implementation
float distance = 0;
public void OnDrag (PointerEventData eventData)
{
Vector3 mousePosition = new Vector3(eventData.position.x, eventData.position.y, distance);
// Vector3 objPosition = Camera.main.ViewportToScreenPoint(mousePosition);
transform.position = mousePosition; // set object coordinates to mouse coordinates
if(transform.parent.gameObject == partsPanel)
{
transform.SetParent(dragLayer.transform); // pop object to draglayer to move object out of parts Panel
}
if(transform.parent.gameObject == buildBoard)
{
transform.SetParent(dragLayer.transform);
// Constrain drag to boundaries of buildBoard Code
}
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
transform.SetParent(parentToReturnTo); // Snaps object back to orginal parent if dropped outside of a dropzone
transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex()); // Returns card back to placeholder location
GetComponent<CanvasGroup>().blocksRaycasts = true; // turn Raycast back on
Destroy(placeholder); // kill the placeholder if object hits a drop zone or returns to parts panel
if(transform.parent.gameObject == buildBoard)
{
// Debug.Log ("Your sprite is now on the " + transform.parent.name);
buildPanelScale = new Vector3(partScale, partScale, partScale);
transform.localScale = buildPanelScale;
transform.SetAsLastSibling();
}
if(transform.parent.gameObject == partsPanel)
{
// transform.SetParent(buildBoard.transform);
transform.localScale = partsPanelScale;
}
}
#endregion
}

If you're using a BoxCollider2D as the default colliderfor your puzzle pieces, you could change that out to PolygonCollider2D instead. It automatically generates the collider for your Sprite (IIRC, it uses the alpha channel), and you can also further customize it by adding vertices to the collider's mesh.

Related

Unity: animation not working

I'm building an android game in which the player is controlled using Simple joystick plugin. When I am controlling the player using Keyboard the player animations work but when I control it using the joystick ui button the walk animation does not trigger even when the player is moving.Following are the codes used.
Player movement
using UnityEngine;
using UnityEngine.UI;
namespace CompleteProject
{
public class PlayerMovement : MonoBehaviour
{
public float speed = 6f; // The speed that the player will move at.
public Text teleportText;
public GameObject teleportCanvas;
public GameObject teleOptionCanvas;
Vector3 movement; // The vector to store the direction of the player's movement.
Animator anim; // Reference to the animator component.
Rigidbody playerRigidbody; // Reference to the player's rigidbody.
int floorMask; // A layer mask so that a ray can be cast just at gameobjects on the floor layer.
float camRayLength = 100f; // The length of the ray from the camera into the scene.
void Awake ()
{
// Create a layer mask for the floor layer.
floorMask = LayerMask.GetMask ("Floor");
// Set up references.
anim = GetComponent <Animator> ();
playerRigidbody = GetComponent <Rigidbody> ();
}
void FixedUpdate ()
{
// Store the input axes.
float h = Input.GetAxisRaw ("Horizontal");
float v = Input.GetAxisRaw ("Vertical");
// Move the player around the scene.
Move (h, v);
// Turn the player to face the mouse cursor.
Turning ();
// Animate the player.
Animating (h, v);
}
void Move (float h, float v)
{
// Set the movement vector based on the axis input.
movement.Set (h, 0f, v);
// Normalise the movement vector and make it proportional to the speed per second.
movement = movement.normalized * speed * Time.deltaTime;
// Move the player to it's current position plus the movement.
playerRigidbody.MovePosition (transform.position + movement);
}
void Turning ()
{
// Create a ray from the mouse cursor on screen in the direction of the camera.
Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
// Create a RaycastHit variable to store information about what was hit by the ray.
RaycastHit floorHit;
// Perform the raycast and if it hits something on the floor layer...
if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))
{
// Create a vector from the player to the point on the floor the raycast from the mouse hit.
Vector3 playerToMouse = floorHit.point - transform.position;
// Ensure the vector is entirely along the floor plane.
playerToMouse.y = 0f;
// Create a quaternion (rotation) based on looking down the vector from the player to the mouse.
Quaternion newRotation = Quaternion.LookRotation (playerToMouse);
// Set the player's rotation to this new rotation.
playerRigidbody.MoveRotation (newRotation);
}
}
void Animating (float h, float v)
{
// Create a boolean that is true if either of the input axes is non-zero.
bool walking = h != 0f || v != 0f;
// Tell the animator whether or not the player is walking.
anim.SetBool ("IsWalking", walking);
}
void OnTriggerEnter(Collider col)
{
if (col.tag == "Teleport")
{
teleportCanvas.SetActive (true);
if (ScoreManager.score < 200)
teleportText.text = "SORRY!! ATLEAST 200 POINTS REQUIRED";
else if (ScoreManager.score >= 200)
{
teleportText.text = "READY TO GO!!";
teleOptionCanvas.SetActive (true);
}
}
}
void OnTriggerStay(Collider col)
{
if(col.tag == "Teleport")
Time.timeScale = 0.6f;
}
void OnTriggerExit(Collider col)
{
if (col.tag == "Teleport")
{
Time.timeScale = 1f;
teleportCanvas.SetActive (false);
teleOptionCanvas.SetActive (false);
}
}
}
}
Joystick control
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
namespace GeekGame.Input{
public class JoystickMove : MonoBehaviour ,IDragHandler,IEndDragHandler
{
// remember turning is with joystick rotate
// calculate the h and the v, then give it to PlayerMovement
Animator anim;
public static JoystickMove instance=null;
public float _speed=6f;
[Tooltip("the joystick radius ")]
public float R=90f;
private float _r;
private Vector2 centerPos;
private float _h;
private float _v;
public float H{
get{return _h;}
}
public float V{
get{return _v;}
}
void Awake(){
if(instance!=null){
Destroy(this.gameObject);
}else{
instance=this;
}
}
void Start(){
_r=1f*Screen.width/960f*R; //this to calculate the scale of screen
centerPos=GetComponent<RectTransform>().position;
}
void SetHAndF(Vector2 pos){ //Horizontall and Vertical axes
Vector2 diff=pos-centerPos;
float distance=diff.magnitude;
if(distance>_r){
pos=centerPos+diff/distance*_r;
}
GetComponent<RectTransform>().position=pos;
Vector2 move=pos-centerPos;
_h=move.x;
_v=move.y;
}
public void OnDrag(PointerEventData data)
{
Vector2 newPos =new Vector2(data.position.x-20f,data.position.y-20f);
//clamp the sprite
SetHAndF(newPos);
}
public void OnEndDrag(PointerEventData data){
Debug.Log("End Drag"+centerPos);
GetComponent<RectTransform>().position=centerPos;
SetHAndF(centerPos);
}
}
}
Fixed by adding the animating function in Joystickmovement and calling it in update.
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
namespace GeekGame.Input{
public class JoystickMove : MonoBehaviour ,IDragHandler,IEndDragHandler
{
// remember turning is with joystick rotate
// calculate the h and the v, then give it to PlayerMovement
public static JoystickMove instance=null;
public float _speed=6f;
public GameObject player;
public Animator animate;
bool walking;
[Tooltip("the joystick radius ")]
public float R=90f;
private float _r;
private Vector2 centerPos;
private float _h;
private float _v;
public float H{
get{return _h;}
}
public float V{
get{return _v;}
}
void Awake(){
if(instance!=null){
Destroy(this.gameObject);
}else{
instance=this;
}
animate = player.GetComponent<Animator> ();
}
void Start(){
_r=1f*Screen.width/960f*R; //this to calculate the scale of screen
centerPos=GetComponent<RectTransform>().position;
}
void Update()
{
Animating (_h, _v);
}
void SetHAndF(Vector2 pos){ //Horizontall and Vertical axes
Vector2 diff=pos-centerPos;
float distance=diff.magnitude;
if(distance>_r){
pos=centerPos+diff/distance*_r;
}
GetComponent<RectTransform>().position=pos;
Vector2 move=pos-centerPos;
_h=move.x;
_v=move.y;
}
public void OnDrag(PointerEventData data)
{
Vector2 newPos =new Vector2(data.position.x-20f,data.position.y-20f);
//clamp the sprite
SetHAndF(newPos);
Animating (_h, _v);
}
public void OnEndDrag(PointerEventData data){
Debug.Log("End Drag"+centerPos);
GetComponent<RectTransform>().position=centerPos;
SetHAndF(centerPos);
}
void Animating (float h, float v)
{
// Create a boolean that is true if either of the input axes is non-zero.
bool walking = h != 0f || v != 0f;
// Tell the animator whether or not the player is walking.
animate.SetBool ("IsWalking", walking);
}
}
}

Get PointerDown on 2D UI Element in Unity C#

I've been through number of answers on this topic, but nothing has seemed to work for my case. I'm trying to detect a mouseDown on a UI element with a canvas renderer which is inside the hierarchy of an object with the canvas on it. I'm new to this, so I'm not sure if the canvas needs to be linked to this canvas renderer or if they have to be on the same object, but the following code is not resulting in the OnPointerDown method being activated.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections;
public class Knob : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {
public Slider slider;
public GameObject pivot;
public bool selected;
public float z;
public Image image;
public UtilityClass the;
public float min;
public float max;
void Start () {
z = 90;
Quaternion rotation = Quaternion.Euler (0, 0, z);
pivot.transform.rotation = rotation;
}
void Update() {
Vector3 mousePosition = Camera.main.ScreenToWorldPoint (Input.mousePosition);
if (selected) {
float pivotAngle = the.AngleFrom (the.Heading (pivot.transform.position, mousePosition));
if (pivotAngle >= min && pivotAngle <= max)
z = pivotAngle;
Quaternion rotation = Quaternion.Euler (0, 0, z);
pivot.transform.rotation = rotation;
}
}
public void OnPointerDown(PointerEventData eventData) {
selected = true;
}
public void OnPointerUp(PointerEventData eventData) {
selected = false;
}
}
At the moment I don't have a Collider 2D on the object, but I have "Raycast Target" selected in the Image script. Any help would be appreciated.
Credit to Juan Bayona Beriso I was missing an Event System Component.

Prevent object from jumping to center point when dragging starts

I have a script for dragging GameObjects around, but at the moment, whenever I start to drag on the object it jumps to the center itself onto the pointer. What I'd like to achieve is regardless of where I start to drag on the object it initiates drag at that point instead of jumping to the object center first. What do I need to modify in my OnDrag or OnBeginDrag method to achieve this?
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class DragHandling : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
public float partScale;
[HideInInspector] public Transform placeholderParent = null;
[HideInInspector] public Transform parentToReturnTo = null;
[HideInInspector] public GameObject trashCan;
[HideInInspector] public GameObject partsPanel;
[HideInInspector] public GameObject partsWindow;
[HideInInspector] public GameObject buildBoard;
GameObject placeholder = null;
GameObject dragLayer;
Vector3 buildPanelScale;
Vector3 partsPanelScale = new Vector3(1.0f, 1.0f, 1.0f);
Vector3 startPosition;
// PolygonCollider2D collider;
void Start ()
{
dragLayer = GameObject.FindGameObjectWithTag("DragLayer");
buildBoard = GameObject.FindGameObjectWithTag("Board");
partsPanel = GameObject.FindGameObjectWithTag("Parts");
partsWindow = GameObject.FindGameObjectWithTag("PartsWindow");
trashCan = GameObject.FindGameObjectWithTag("Trash");
// collider = transform.GetComponent<PolygonCollider2D>();
}
#region IPointerClickHandler implementation
public void OnPointerClick (PointerEventData eventData)
{
if(transform.parent.gameObject == buildBoard)
transform.SetAsLastSibling();
}
#endregion
#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
// create placeholder gap and hold correct position in layout
placeholder = new GameObject();
placeholder.transform.SetParent(transform.parent);
placeholder.transform.SetSiblingIndex(transform.GetSiblingIndex());
parentToReturnTo = transform.parent; // store original parent location
placeholderParent = parentToReturnTo; // set placeholder gameobject transform
startPosition = transform.position;
GetComponent<CanvasGroup>().blocksRaycasts = false; // turn off image raycasting when dragging image in order to see what's behind the image
}
#endregion
#region IDragHandler implementation
public void OnDrag (PointerEventData eventData)
{
Vector3 mousePosition = new Vector3(eventData.position.x, eventData.position.y, 0);
transform.position = Input.mousePosition; // set object coordinates to mouse coordinates
if(transform.parent.gameObject == partsPanel)
transform.SetParent(dragLayer.transform); // pop object to draglayer to move object out of parts Panel
if(transform.parent.gameObject == buildBoard)
transform.SetParent(dragLayer.transform);
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
transform.SetParent(parentToReturnTo); // Snaps object back to orginal parent if dropped outside of a dropzone
transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex()); // Returns card back to placeholder location
GetComponent<CanvasGroup>().blocksRaycasts = true; // turn Raycast back on
Destroy(placeholder); // kill the placeholder if object hits a drop zone or returns to parts panel
if(transform.parent.gameObject == buildBoard)
{
buildPanelScale = new Vector3(partScale, partScale, partScale);
transform.localScale = buildPanelScale;
transform.SetAsLastSibling(); // always place last piece on top
}
if(transform.parent.gameObject == partsPanel)
transform.localScale = partsPanelScale;
}
#endregion
}
I have never used any interface to implement this, But the solution should be the same as using with OnMouseDown, OnMouseUp and OnMouseDrag with the sprites. Try this with your current implementation
using UnityEngine;
using System.Collections;
public class Drag : MonoBehaviour {
private Vector3 offset = Vector3.zero;
void OnMouseDown () {
Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
worldPos.z = transform.position.z;
offset = worldPos - transform.position;
}
void OnMouseDrag () {
Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
worldPos.z = transform.position.z;
worldPos = worldPos - offset;
transform.position = worldPos;
}
void OnMouseUp () {
offset = Vector3.zero;
}
}
I have used this with an orthographic camera on Sprites. Hope this helps.
EDIT
Tried implementing the interfaces as in your code with UI elements. It is working as expected. Only thing is to set the canvas to ScreenSpace-Camera implement the code in the respective interfaces
your question is a bit confusing and if im correct you are saying that the object you start to drag keeps moving to the middle of screen , if you dont want that just update the dragged objects transform in OnEndDrag.

Object drag not moving at the same rate as the pointer

I'm trying to implement a drag and drop system but I'm having a problem with the drag rate at the moment. Currently when I drag an object it only moves a tiny fraction of the amount that my pointer actually moves. How do I fix this?
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class DragHandling : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
public float partScale;
[HideInInspector] public Transform placeholderParent = null;
[HideInInspector] public Transform parentToReturnTo = null;
[HideInInspector] public GameObject trashCan;
[HideInInspector] public GameObject partsPanel;
[HideInInspector] public GameObject partsWindow;
[HideInInspector] public GameObject buildBoard;
GameObject placeholder = null;
GameObject dragLayer;
Vector3 buildPanelScale;
Vector3 partsPanelScale = new Vector3(1.0f, 1.0f, 1.0f);
Vector3 startPosition;
private Vector3 offset = Vector3.zero;
void Start ()
{
dragLayer = GameObject.FindGameObjectWithTag("DragLayer");
buildBoard = GameObject.FindGameObjectWithTag("Board");
partsPanel = GameObject.FindGameObjectWithTag("Parts");
partsWindow = GameObject.FindGameObjectWithTag("PartsWindow");
trashCan = GameObject.FindGameObjectWithTag("Trash");
}
#region IPointerClickHandler implementation
public void OnPointerClick (PointerEventData eventData)
{
if(transform.parent.gameObject == buildBoard)
transform.SetAsLastSibling();
}
#endregion
#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
worldPos.z = transform.position.z;
offset = worldPos - transform.position;
// create placeholder gap and hold correct position in layout
placeholder = new GameObject();
placeholder.transform.SetParent(transform.parent);
placeholder.transform.SetSiblingIndex(transform.GetSiblingIndex());
parentToReturnTo = transform.parent; // store original parent location
placeholderParent = parentToReturnTo; // set placeholder gameobject transform
GetComponent<CanvasGroup>().blocksRaycasts = false; // turn off image raycasting when dragging image in order to see what's behind the image
}
#endregion
#region IDragHandler implementation
public void OnDrag (PointerEventData eventData)
{
Vector3 worldPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
worldPos.z = transform.position.z;
worldPos = worldPos - offset;
transform.position = worldPos;
if(transform.parent.gameObject == partsPanel)
transform.SetParent(dragLayer.transform); // pop object to draglayer to move object out of parts Panel
if(transform.parent.gameObject == buildBoard)
transform.SetParent(dragLayer.transform);
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
offset = Vector3.zero;
transform.SetParent(parentToReturnTo); // Snaps object back to orginal parent if dropped outside of a dropzone
transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex()); // Returns card back to placeholder location
GetComponent<CanvasGroup>().blocksRaycasts = true; // turn Raycast back on
Destroy(placeholder); // kill the placeholder if object hits a drop zone or returns to parts panel
if(transform.parent.gameObject == buildBoard)
{
buildPanelScale = new Vector3(partScale, partScale, partScale);
transform.localScale = buildPanelScale;
transform.SetAsLastSibling(); // always place last piece on top
}
if(transform.parent.gameObject == partsPanel)
transform.localScale = partsPanelScale;
}
#endregion
}
Right off the back, you should use eventData.position instead of Input.mousePosition. ScreenToWorldPoint takes a Vector3 but Input.mousePosition is a Vector2. I also personally wouldn't use ScreenToWorldPoint for this purpose, id use a raycast, and use the RayCastHit hit.point for where to put the object as its being dragged, which would be alot more accurate for you.
Actually, since you are using Unity Canvas, you should use RectTransformUtility.ScreenPointToLocalPointInRectangle(...) and put in the parent rect or canvas for what you are trying to drag. It will give you the coordinates you want.
implementation:
RectTransform parentRect = (RectTransform)objectToBeDragged.transform.parent;
Vector2 posInParent;
RectTransformUtility.ScreenPointToLocalPointInRectangle(parentRect, eventData.position, Camera.main, out posInParent);
objectToBeDragged.localPosition = posInParent;
I also just realized another problem you might be experiencing is that you are using transform.position instead of transform.localPosition not saying for sure thats the problem but sometimes that can really bite you in the ass.

Clear space around sprite image registering pointer events

I'm using Unity 5, withthe new uGUI system and I'm having a terrible time getting pointer events to ignore the clear space around my sprites and register only the image area. I've attached images and code to show where I'm at. I cannot get the this to work.
Ultimately, the thing I'm trying to achieve is to just have the click event interact with the image rather than the entire image sprite (everything in the rectangular bounding box).
My image texture type is Sprite (2D and UI). I made sure the space around my image is indeed transparent, yet the clear space around the image is still registering a click.
What am I doing wrong here? Need help!
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class DragHandling : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
public float partScale;
[HideInInspector] public Transform placeholderParent = null;
[HideInInspector] public Transform parentToReturnTo = null;
[HideInInspector] public GameObject trashCan;
[HideInInspector] public GameObject partsPanel;
[HideInInspector] public GameObject partsWindow;
[HideInInspector] public GameObject buildBoard;
GameObject placeholder = null;
GameObject dragLayer;
Vector3 buildPanelScale;
Vector3 partsPanelScale = new Vector3(1.0f, 1.0f, 1.0f);
Vector3 startPosition;
void Start ()
{
dragLayer = GameObject.FindGameObjectWithTag("DragLayer");
buildBoard = GameObject.FindGameObjectWithTag("Board");
partsPanel = GameObject.FindGameObjectWithTag("Parts");
partsWindow = GameObject.FindGameObjectWithTag("PartsWindow");
trashCan = GameObject.FindGameObjectWithTag("Trash");
}
#region IPointerClickHandler implementation
public void OnPointerClick (PointerEventData eventData)
{
if(transform.parent.gameObject == buildBoard)
transform.SetAsLastSibling();
}
#endregion
#region IBeginDragHandler implementation
public void OnBeginDrag (PointerEventData eventData)
{
// create placeholder gap and hold correct position in layout
placeholder = new GameObject();
placeholder.transform.SetParent(transform.parent);
placeholder.transform.SetSiblingIndex(transform.GetSiblingIndex());
parentToReturnTo = transform.parent; // store original parent location
placeholderParent = parentToReturnTo; // set placeholder gameobject transform
startPosition = transform.position;
GetComponent<CanvasGroup>().blocksRaycasts = false; // turn off image raycasting when dragging image in order to see what's behind the image
}
#endregion
#region IDragHandler implementation
public void OnDrag (PointerEventData eventData)
{
Vector3 mousePosition = new Vector3(eventData.position.x, eventData.position.y, 0);
transform.position = Input.mousePosition; // set object coordinates to mouse coordinates
if(transform.parent.gameObject == partsPanel)
transform.SetParent(dragLayer.transform); // pop object to draglayer to move object out of parts Panel
if(transform.parent.gameObject == buildBoard)
transform.SetParent(dragLayer.transform);
}
#endregion
#region IEndDragHandler implementation
public void OnEndDrag (PointerEventData eventData)
{
transform.SetParent(parentToReturnTo); // Snaps object back to orginal parent if dropped outside of a dropzone
transform.SetSiblingIndex(placeholder.transform.GetSiblingIndex()); // Returns card back to placeholder location
GetComponent<CanvasGroup>().blocksRaycasts = true; // turn Raycast back on
Destroy(placeholder); // kill the placeholder if object hits a drop zone or returns to parts panel
if(transform.parent.gameObject == buildBoard)
{
buildPanelScale = new Vector3(partScale, partScale, partScale);
transform.localScale = buildPanelScale;
transform.SetAsLastSibling(); // always place last piece on top
}
if(transform.parent.gameObject == partsPanel)
transform.localScale = partsPanelScale;
}
#endregion
}

Categories