View difference between Paste ID: y8iVHZGr and Vbzrt0z7
SHOW: | | - or go back to the newest paste.
1-
/* Check out our new 2D point and click adventure at */
1+
using UnityEngine;
2-
/* http://www.NotQuiteBlackandWhite.com */
2+
using System;
3
4-
/*
4+
public class SmartInput : MonoBehaviour
5-
"FrontmostSpriteClicker" for Unity
5+
6
    // Fixed size array for hit testing to avoid repeated memory allocation
7-
Attaching this script to the game camera will allow any 2D sprite that has a collider attached to receive clicks.
7+
    //  If you might have more than 10 overlapping colliders, you may need to increase array size
8-
It will ignore anything beneath the frontmost sprite i.e a sprite in a lower sorting layer or in a 
8+
    Collider2D[] Hits = new Collider2D[10];
9-
lower sorting order in the same layer.
9+
10
    void Update()
11-
This script requires that any sprite you want to be clickable has a script attached
11+
    {
12-
that has a function called OnLeftClick, and one called OnRightClick.
12+
        // Get all 2D colliders under the mouse/finger
13
        Vector3 v3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
14-
NOTE 1: Works with 2D colliders only but more code could be added to take into account 3D objects and Z depth.
14+
        int hitCount = Physics2D.OverlapPointNonAlloc(new Vector2(v3.x, v3.y), Hits);
15-
NOTE 2: Works only with an orthographic camera.
15+
16-
NOTE 3: Currently uses Camera.main, change this if the camera you are using is not tagged "MainCamera".
16+
        // If none, do nothing.
17-
NOTE 4: No effort has been made to optimise this script, it can almost definitely be improved upon.
17+
        if (hitCount == 0)
18
            return;
19-
Please get in touch with us if there's any issues with the script or if you have any questions.
19+
20-
*/
20+
        // This will be set to front-most collider
21
        Collider2D frontMostHit = null;
22-
#pragma strict
22+
23
        // Keep track of highest sort order found so far
24-
private var leftClickedObject : GameObject;
24+
        uint highestSortOrder = 0;
25-
private var rightClickedObject : GameObject;
25+
26-
private var frontmostRaycastHit : RaycastHit2D;
26+
        // For each collider hit...
27
        for(int x=0;x<hitCount;x++)
28-
// It's necessary to access the SpriteRenderer of a game object to be able to access its sorting layer ID 
28+
        {
29-
// and sorting order ("Order in Layer" in the inspector)
29+
            Collider2D hit = Hits[x];
30-
private var spriteRenderer : SpriteRenderer;
30+
31
            // Get sprite render
32-
function Update () 
32+
            SpriteRenderer sr = hit.GetComponent<SpriteRenderer>();
33
34-
	// If the left mouse button is clicked anywhere...
34+
            // Convert sorting order to unsigned value by adding the minimum (negative) value it can possibly have
35-
	if (Input.GetMouseButtonDown(0))
35+
            uint uSortingOrder = (uint)(sr.sortingOrder + short.MinValue);
36-
	{
36+
37-
		// frontmostRaycastHit stores information about the RaycastHit2D that is returned by GetFrontmostRaycastHit()
37+
            // In my game I use 3 sorting layers, you will need to adjust this.  SortingLayerOrder needs to have
38-
		frontmostRaycastHit = GetFrontmostRaycastHit();
38+
            //  a value of 0 for your first layer, 1 for second, 2 for third, and so on.  This code 
39
            uint sortingLayerOrder;
40-
		// If frontmostRaycastHit is true, i,e the user hasn't clicked on nothing, i.e GetFrontmostRaycastHit() didn't return nothing...
40+
            if (sr.sortingLayerID == 0) // Default
41-
		if (frontmostRaycastHit)
41+
                sortingLayerOrder = 1;
42-
		{
42+
            else if (sr.sortingLayerID == 1) // Background
43-
			// Assigns the game object that the collider that has been clicked on to leftClickedObject.
43+
                sortingLayerOrder = 0;
44-
			leftClickedObject = frontmostRaycastHit.collider.gameObject;
44+
            else
45-
			
45+
            {
46-
			// Sends the frontmostRaycast to a function called OnLeftClick in a script attached to whatever the leftClickedObject is.
46+
                if (sr.sortingLayerID != 2) // Foreground
47-
			leftClickedObject.SendMessage("OnLeftClick", frontmostRaycastHit, SendMessageOptions.DontRequireReceiver);
47+
                    throw new Exception("You updated sorting layers but forgot to update this code!");
48-
		}
48+
                sortingLayerOrder = 2;
49-
	}
49+
            }
50-
	// If the right mouse button is clicked anywhere...
50+
51-
	else if (Input.GetMouseButtonDown(1))
51+
            // Assign base value for layer based on layer order
52-
	{
52+
            //  1st layer = 0 to 65535
53-
		// frontmostRaycastHit stores information about the RaycastHit2D that is returned by GetFrontmostRaycastHit()
53+
            //  2nd layer = 65536 to 131,070
54-
		frontmostRaycastHit = GetFrontmostRaycastHit();
54+
            //  3rd layer = 131,070 to 196,605
55
            //  Each value increases by ushort.MaxValue to ensure that the highest value in a prior layer can never be
56-
		// If frontmostRaycastHit is true, i,e the user hasn't clicked on nothing, i.e GetFrontmostRaycastHit() didn't return nothing...
56+
            //   greater than the lowest value in the next layer.
57-
		if (frontmostRaycastHit)
57+
            uint sortingLayerBase = sortingLayerOrder * ushort.MaxValue;
58-
		{
58+
59-
			// Assigns the game object that the collider that has been clicked on to rightClickedObject.
59+
            // Actual sort order is layer base value + object order
60-
			rightClickedObject = frontmostRaycastHit.collider.gameObject;
60+
            uint sortOrder = sortingLayerBase + uSortingOrder;
61-
			
61+
62-
			// Sends the frontmostRaycast to a function called OnLeftClick in a script attached to whatever the rightClickedObject is.
62+
            // If sort order is same (mostly to ensure we always have something) or higher than our highest so far...
63-
			rightClickedObject.SendMessage("OnRightClick", frontmostRaycastHit, SendMessageOptions.DontRequireReceiver);
63+
            if (sortOrder >= highestSortOrder)
64-
		}
64+
            {
65-
	}
65+
                // Save new high value
66-
}
66+
                highestSortOrder = sortOrder;
67
68-
function GetFrontmostRaycastHit(): RaycastHit2D
68+
                // This hit is our current front-most collider
69
                frontMostHit = hit;
70-
	// Store the point where the user has clicked as a Vector3.
70+
            }
71-
	var clickPosition : Vector3 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
71+
        }
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".
72+
73-
	var hits : RaycastHit2D[] = Physics2D.LinecastAll (clickPosition, clickPosition);
73+
        // If left mouse or finger just went down between last frame and this one...
74
        if (Input.GetMouseButtonDown(0))
75-
	// If the raycast hits something...
75+
        {
76-
	if (hits.length != 0)
76+
            // Fire OnLeftDown event if this object has one
77-
	{
77+
            frontMostHit.SendMessage("OnLeftDown", SendMessageOptions.DontRequireReceiver);
78-
		// A variable that will store the frontmost sorting layer that contains an object that has been clicked on as an int.
78+
        }
79-
		var topSortingLayer : int = 0;
79+
        
80-
		// A variable that will store the index of the top sorting layer as an int.
80+
        // If left mouse or finger is down...
81-
		var indexOfTopSortingLayer : int;
81+
        if (Input.GetMouseButton(0))
82-
		// An array that stores the IDs of all the sorting layers that contain a sprite in the path of the linecast.
82+
        {
83-
		var sortingLayerIDArray : int[] = new int[hits.length];
83+
            // Fire OnLeftHoverDown event if this object has one
84-
		// An array that stores the sorting orders of each sprite that has been hit by the linecast
84+
            frontMostHit.SendMessage("OnLeftHoverDown", SendMessageOptions.DontRequireReceiver);
85-
		var sortingOrderArray : int[] = new int[hits.length];
85+
        }
86-
		// An array that stores the sorting order number of the frontmost sprite that has been clicked.
86+
87-
		var topSortingOrder : int = 0;
87+
        // Always fire OnHover if this object has one
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.
88+
        frontMostHit.SendMessage("OnHover", SendMessageOptions.DontRequireReceiver);
89-
		var indexOfTopSortingOrder : int;
89+
    }
90
}