-4.1 then -4.2 so they are positioned on one another… all have 2d box collider and script applied to destroy petal on onmousedown… the problim is , when i click on the front most petal positioned suppose on -5 it destroys any of the petal positioned underneath it , like in between -4.9 to -4.1 … what i want is . it should detect the front most collider sprite first rather then the collider applied on the underneath petals… i also have tried help form here
but its not working …
function OnMouseDown()
{
// print("ok");
Destroy(gameObject);
}
Hi Omer, you need to get rid of the OnMouseDown function altogether to use a raycasting method.
Step 1: Attach the frontmostspriteclicker script to your main camera.
Step 2: Anything with a collider that you want to be able to click on must have a script attached with a function in it called OnLeftClick. If it is one of the petals you might want something like
function OnLeftClick(raycastHit : RaycastHit2D)
{
// print("ok");
Destroy(gameObject);
}
Step 3: Re-writing the script to use z depth won’t be too complex (afraid I don’t have time to do it right now) but it would be something like, where you see this code:
// Loop through the array of raycast hits...
for (var i = 0; i < hits.length; i++)
{
// Get the SpriteRenderer from each game object under the click.
spriteRenderer = hits*.collider.gameObject.GetComponent(SpriteRenderer);*
// Access the sortingLayerID through the SpriteRenderer and store it in the sortingLayerIDArray. sortingLayerIDArray = spriteRenderer.sortingLayerID;
// Access the sortingOrder through the SpriteRenderer and store it in the sortingOrderArray. sortingOrderArray = spriteRenderer.sortingOrder; } Don’t bother accessing the sprite renderer at all and just store the z depth in an array: hitDepth = hits*.collider.transform.position;* And then where you see this code: // Loop through the array of sprite sorting layer IDs… for (var j = 0; j < sortingLayerIDArray.length; j++) { // If the sortingLayerID is higher that the topSortingLayer… if (sortingLayerIDArray[j] >= topSortingLayer) { topSortingLayer = sortingLayerIDArray[j]; indexOfTopSortingLayer = j; } } Put something like: if (hitDepth[j] >= topSortingLayer) { topSortingLayer = hitDepth[j]; hitDepthOfTopSortingLayer = j; } Hope that helps, I wish I had more time to rewrite the code properly. Let me know how you get on, I’d love to include a link to a Z depth sorting sprite clicker on the site
private var leftClickedObject : GameObject;
private var rightClickedObject : GameObject;
private var frontmostRaycastHit : RaycastHit2D;
//private var hitDepth[]:Transform;
// It's necessary to access the SpriteRenderer of a game object to be able to access its sorting layer ID
// and sorting order ("Order in Layer" in the inspector)
private var spriteRenderer : SpriteRenderer;
function Update ()
{
// If the left mouse button is clicked anywhere...
if (Input.GetMouseButtonDown(0))
{
// frontmostRaycastHit stores information about the RaycastHit2D that is returned by GetFrontmostRaycastHit()
frontmostRaycastHit = GetFrontmostRaycastHit();
// If frontmostRaycastHit is true, i,e the user hasn't clicked on nothing, i.e GetFrontmostRaycastHit() didn't return nothing...
if (frontmostRaycastHit)
{
// Assigns the game object that the collider that has been clicked on to leftClickedObject.
leftClickedObject = frontmostRaycastHit.collider.gameObject;
// Sends the frontmostRaycast to a function called OnLeftClick in a script attached to whatever the leftClickedObject is.
leftClickedObject.SendMessage("OnLeftClick", frontmostRaycastHit, SendMessageOptions.DontRequireReceiver);
}
}
// If the right mouse button is clicked anywhere...
else if (Input.GetMouseButtonDown(1))
{
// frontmostRaycastHit stores information about the RaycastHit2D that is returned by GetFrontmostRaycastHit()
frontmostRaycastHit = GetFrontmostRaycastHit();
// If frontmostRaycastHit is true, i,e the user hasn't clicked on nothing, i.e GetFrontmostRaycastHit() didn't return nothing...
if (frontmostRaycastHit)
{
// Assigns the game object that the collider that has been clicked on to rightClickedObject.
rightClickedObject = frontmostRaycastHit.collider.gameObject;
// Sends the frontmostRaycast to a function called OnLeftClick in a script attached to whatever the rightClickedObject is.
rightClickedObject.SendMessage("OnRightClick", frontmostRaycastHit, SendMessageOptions.DontRequireReceiver);
}
}
}
function GetFrontmostRaycastHit(): RaycastHit2D
{
// Store the point where the user has clicked as a Vector3.
var clickPosition : Vector3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
// Retrieve all raycast hits from the click position (to the same click position - more a dot than a ray) and store them in an array called "hits".
var hits : RaycastHit2D[] = Physics2D.LinecastAll (clickPosition, clickPosition);
// If the raycast hits something...
if (hits.length != 0)
{
// A variable that will store the frontmost sorting layer that contains an object that has been clicked on as an int.
var topSortingLayer : int = 0;
// A variable that will store the index of the top sorting layer as an int.
var indexOfTopSortingLayer : int;
var hitDepthOfTopSortingLayer: int;
// An array that stores the IDs of all the sorting layers that contain a sprite in the path of the linecast.
var sortingLayerIDArray : int[] = new int[hits.length];
// An array that stores the sorting orders of each sprite that has been hit by the linecast
var sortingOrderArray : int[] = new int[hits.length];
// An array that stores the sorting order number of the frontmost sprite that has been clicked.
var topSortingOrder : int = 0;
// A variable that will store the index in the sortingOrderArray where topSortingOrder is. This index used with the hits array will give us our frontmost clicked sprite.
var indexOfTopSortingOrder : int;
// Loop through the array of raycast hits...
for (var i = 0; i < hits.length; i++)
{
// // Get the SpriteRenderer from each game object under the click.
// spriteRenderer = hits*.collider.gameObject.GetComponent(SpriteRenderer);*
// // // Access the sortingLayerID through the SpriteRenderer and store it in the sortingLayerIDArray. // sortingLayerIDArray = spriteRenderer.sortingLayerID; // // // Access the sortingOrder through the SpriteRenderer and store it in the sortingOrderArray. // sortingOrderArray = spriteRenderer.sortingOrder; _ var hitDepth = hits*.collider.transform.position; }*_
// Loop through the array of sprite sorting layer IDs… for (var j = 0; j < sortingLayerIDArray.length; j++) { // If the sortingLayerID is higher that the topSortingLayer… // if (sortingLayerIDArray[j] >= topSortingLayer) // { // topSortingLayer = sortingLayerIDArray[j]; // indexOfTopSortingLayer = j; // } * if (hitDepth[j] >= topSortingLayer)* * {* * topSortingLayer = hitDepth[j];* * hitDepthOfTopSortingLayer = j;* * }*
}
// Loop through the array of sprite sorting orders… for (var k = 0; k < sortingOrderArray.length; k++) { // If the sorting order of the sprite is higher than topSortingOrder AND the sprite is on the top sorting layer… // if (sortingOrderArray[k] >= topSortingOrder && sortingLayerIDArray[k] == topSortingLayer) // { // topSortingOrder = sortingOrderArray[k]; // indexOfTopSortingOrder = k; // } // else // { // // Do nothing and continue loop. // } * if (hitDepth[k] >= topSortingLayer)* * {* * topSortingLayer = hitDepth[k];* * hitDepthOfTopSortingLayer = k;* * }*
// How many sprites with colliders attached are underneath the click? Debug.Log("How many sprites have been clicked on: " + hits.length);
// Which is the sorting layer of the frontmost clicked sprite? Debug.Log("Frontmost sorting layer ID: "+ topSortingLayer);
// Which is the order in that sorting layer of the frontmost clicked sprite? Debug.Log("Frontmost order in layer: "+ topSortingOrder);
// The indexOfTopSortingOrder will also be the index of the frontmost raycast hit in the array “hits”. return hits[indexOfTopSortingOrder]; } } else // If the hits array has a length of 0 then nothing has been clicked… { Debug.Log(“Nothing clicked.”); return; } }
OK … for everyone who is suffering from this problem … Solution is …
Apply 2d collider on the sprite
Keeps the Sprites According to the Z position. For example, if your camera is at -10 z position , your background could be at -5 , characters could be at -6 and forground at -7.
If 2d collider doesn’t fit to the sprite position , for example if you have star or sprite like zigzag/not equal than use 2d Polygon Collider(atleast it helped me in this situation).
I dont know layered effect or not but try to keep the layers dafault.
Have Fun … Finally i am out of The Hell of 2D Collider …
and i used
function OnMOuseDown(){
//////do what ever you want to do here
}