Advertisement
notquiteblacknwhite

FrontmostSpriteClicker (JavaScript)

Feb 2nd, 2014
12,623
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /* Check out our new 2D point and click adventure at */
  2. /* http://www.NotQuiteBlackandWhite.com */
  3.  
  4. /*
  5. "FrontmostSpriteClicker" for Unity
  6.  
  7. Attaching this script to the game camera will allow any 2D sprite that has a collider attached to receive clicks.
  8. It will ignore anything beneath the frontmost sprite i.e a sprite in a lower sorting layer or in a
  9. lower sorting order in the same layer.
  10.  
  11. This script requires that any sprite you want to be clickable has a script attached
  12. that has a function called OnLeftClick, and one called OnRightClick.
  13.  
  14. NOTE 1: Works with 2D colliders only but more code could be added to take into account 3D objects and Z depth.
  15. NOTE 2: Works only with an orthographic camera.
  16. NOTE 3: Currently uses Camera.main, change this if the camera you are using is not tagged "MainCamera".
  17. NOTE 4: No effort has been made to optimise this script, it can almost definitely be improved upon.
  18.  
  19. Please get in touch with us if there's any issues with the script or if you have any questions.
  20. */
  21.  
  22. #pragma strict
  23.  
  24. private var leftClickedObject : GameObject;
  25. private var rightClickedObject : GameObject;
  26. private var frontmostRaycastHit : RaycastHit2D;
  27.  
  28. // It's necessary to access the SpriteRenderer of a game object to be able to access its sorting layer ID
  29. // and sorting order ("Order in Layer" in the inspector)
  30. private var spriteRenderer : SpriteRenderer;
  31.  
  32. function Update ()
  33. {
  34.     // If the left mouse button is clicked anywhere...
  35.     if (Input.GetMouseButtonDown(0))
  36.     {
  37.         // frontmostRaycastHit stores information about the RaycastHit2D that is returned by GetFrontmostRaycastHit()
  38.         frontmostRaycastHit = GetFrontmostRaycastHit();
  39.  
  40.         // If frontmostRaycastHit is true, i,e the user hasn't clicked on nothing, i.e GetFrontmostRaycastHit() didn't return nothing...
  41.         if (frontmostRaycastHit)
  42.         {
  43.             // Assigns the game object that the collider that has been clicked on to leftClickedObject.
  44.             leftClickedObject = frontmostRaycastHit.collider.gameObject;
  45.            
  46.             // Sends the frontmostRaycast to a function called OnLeftClick in a script attached to whatever the leftClickedObject is.
  47.             leftClickedObject.SendMessage("OnLeftClick", frontmostRaycastHit, SendMessageOptions.DontRequireReceiver);
  48.         }
  49.     }
  50.     // If the right mouse button is clicked anywhere...
  51.     else if (Input.GetMouseButtonDown(1))
  52.     {
  53.         // frontmostRaycastHit stores information about the RaycastHit2D that is returned by GetFrontmostRaycastHit()
  54.         frontmostRaycastHit = GetFrontmostRaycastHit();
  55.  
  56.         // If frontmostRaycastHit is true, i,e the user hasn't clicked on nothing, i.e GetFrontmostRaycastHit() didn't return nothing...
  57.         if (frontmostRaycastHit)
  58.         {
  59.             // Assigns the game object that the collider that has been clicked on to rightClickedObject.
  60.             rightClickedObject = frontmostRaycastHit.collider.gameObject;
  61.            
  62.             // Sends the frontmostRaycast to a function called OnLeftClick in a script attached to whatever the rightClickedObject is.
  63.             rightClickedObject.SendMessage("OnRightClick", frontmostRaycastHit, SendMessageOptions.DontRequireReceiver);
  64.         }
  65.     }
  66. }
  67.  
  68. function GetFrontmostRaycastHit(): RaycastHit2D
  69. {
  70.     // Store the point where the user has clicked as a Vector3.
  71.     var clickPosition : Vector3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
  72.     // 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".
  73.     var hits : RaycastHit2D[] = Physics2D.LinecastAll (clickPosition, clickPosition);
  74.  
  75.     // If the raycast hits something...
  76.     if (hits.length != 0)
  77.     {
  78.         // A variable that will store the frontmost sorting layer that contains an object that has been clicked on as an int.
  79.         var topSortingLayer : int = 0;
  80.         // A variable that will store the index of the top sorting layer as an int.
  81.         var indexOfTopSortingLayer : int;
  82.         // An array that stores the IDs of all the sorting layers that contain a sprite in the path of the linecast.
  83.         var sortingLayerIDArray : int[] = new int[hits.length];
  84.         // An array that stores the sorting orders of each sprite that has been hit by the linecast
  85.         var sortingOrderArray : int[] = new int[hits.length];
  86.         // An array that stores the sorting order number of the frontmost sprite that has been clicked.
  87.         var topSortingOrder : int = 0;
  88.         // 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.
  89.         var indexOfTopSortingOrder : int;
  90.  
  91.         // Loop through the array of raycast hits...
  92.         for (var i = 0; i < hits.length; i++)
  93.         {
  94.             // Get the SpriteRenderer from each game object under the click.
  95.             spriteRenderer = hits[i].collider.gameObject.GetComponent(SpriteRenderer);
  96.        
  97.             // Access the sortingLayerID through the SpriteRenderer and store it in the sortingLayerIDArray.
  98.             sortingLayerIDArray[i] = spriteRenderer.sortingLayerID;
  99.            
  100.             // Access the sortingOrder through the SpriteRenderer and store it in the sortingOrderArray.
  101.             sortingOrderArray[i] = spriteRenderer.sortingOrder;
  102.         }
  103.        
  104.         // Loop through the array of sprite sorting layer IDs...
  105.         for (var j = 0; j < sortingLayerIDArray.length; j++)
  106.         {
  107.             // If the sortingLayerID is higher that the topSortingLayer...
  108.             if (sortingLayerIDArray[j] >= topSortingLayer)
  109.             {
  110.                 topSortingLayer = sortingLayerIDArray[j];
  111.                 indexOfTopSortingLayer = j;
  112.             }
  113.         }
  114.  
  115.         // Loop through the array of sprite sorting orders...
  116.         for (var k = 0; k < sortingOrderArray.length; k++)
  117.         {
  118.             // If the sorting order of the sprite is higher than topSortingOrder AND the sprite is on the top sorting layer...
  119.             if (sortingOrderArray[k] >= topSortingOrder && sortingLayerIDArray[k] == topSortingLayer)
  120.             {
  121.                 topSortingOrder = sortingOrderArray[k];
  122.                 indexOfTopSortingOrder = k;
  123.             }
  124.             else
  125.             {
  126.                 // Do nothing and continue loop.
  127.             }
  128.         }
  129.  
  130.         // How many sprites with colliders attached are underneath the click?
  131.         Debug.Log("How many sprites have been clicked on: " + hits.length);
  132.        
  133.         // Which is the sorting layer of the frontmost clicked sprite?
  134.         Debug.Log("Frontmost sorting layer ID: "+ topSortingLayer);
  135.        
  136.         // Which is the order in that sorting layer of the frontmost clicked sprite?
  137.         Debug.Log("Frontmost order in layer: "+ topSortingOrder);
  138.  
  139.         // The indexOfTopSortingOrder will also be the index of the frontmost raycast hit in the array "hits".
  140.         return hits[indexOfTopSortingOrder];
  141.     }
  142.     else // If the hits array has a length of 0 then nothing has been clicked...
  143.     {
  144.         Debug.Log("Nothing clicked.");
  145.         return;
  146.     }
  147. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement