/* * @author Valentin Simonov / http://va.lent.in/ */ using System; using TouchScript.Layers; using UnityEngine; namespace TouchScript.Hit { /// /// An object representing a point hit by a pointer in 3D, 2D or UI space. /// public struct HitData { #region Consts /// /// Type of hit /// [Flags] public enum HitType { /// /// An unknown hit. /// Unknown, /// /// Nothing hit, but some object grabbed the pointer. /// Screen, /// /// 3D hit. /// World3D, /// /// 2D hit. /// World2D, /// /// UI hit. /// UI } #endregion #region Public properties /// /// Gets the type of the hit. /// /// The type. public HitType Type { get { return type; } } /// /// Gets target Target the hit. /// /// Hit Target. public Transform Target { get { return target; } } /// /// Gets the layer which detected the hit. /// /// Hit layer. public TouchLayer Layer { get { return layer; } } /// /// Gets raycast hit object for a 3D hit. /// /// Raycast hit object. public RaycastHit RaycastHit { get { return raycastHit; } } /// /// Gets 2D raycast hit object for a 2D hit. /// /// 2D raycast hit object. public RaycastHit2D RaycastHit2D { get { return raycastHit2D; } } /// /// Gets raycast hit for a UI hit. /// /// UI raycast hit object. public RaycastHitUI RaycastHitUI { get { return raycastHitUI; } } /// /// Indicates if this is a Screen Space hit. /// public bool ScreenSpace { get { return screenSpace; } } /// /// Gets the point in 3D where raycast hit the object. /// /// Point in 3D. public Vector3 Point { get { switch (type) { case HitType.World3D: return raycastHit.point; case HitType.World2D: return raycastHit2D.point; case HitType.UI: return raycastHitUI.WorldPosition; } return Vector3.zero; } } /// /// Gets the normal at the point in 3D wher eraycast hit the object. /// /// Normal vector. public Vector3 Normal { get { switch (type) { case HitType.World3D: return raycastHit.normal; case HitType.World2D: return raycastHit2D.normal; case HitType.UI: return raycastHitUI.WorldNormal; } return Vector3.forward; } } /// /// Distance to the hit point. /// public float Distance { get { switch (type) { case HitType.World3D: return raycastHit.distance; case HitType.World2D: return raycastHit2D.distance; case HitType.UI: return raycastHitUI.Distance; } return 0f; } } /// /// Sorting layer of the hit target. /// public int SortingLayer { get { switch (type) { case HitType.World3D: return 0; case HitType.World2D: if (sortingLayer == -1) updateSortingValues(); return sortingLayer; case HitType.UI: return raycastHitUI.SortingLayer; } return 0; } } /// /// Sorting order of the hit target. /// public int SortingOrder { get { switch (type) { case HitType.World3D: return 0; case HitType.World2D: if (sortingLayer == -1) updateSortingValues(); return sortingOrder; case HitType.UI: return raycastHitUI.SortingOrder; } return 0; } } #endregion #region Private variables private HitType type; private Transform target; private bool screenSpace; private TouchLayer layer; private RaycastHit raycastHit; private RaycastHit2D raycastHit2D; private RaycastHitUI raycastHitUI; private int sortingLayer; private int sortingOrder; #endregion #region Constructors /// /// Initializes a new instance of the struct. /// /// Target Target. /// Touch layer this hit came from. /// If the hit is screenspace UI. public HitData(Transform target, TouchLayer layer, bool screenSpace = false) { this.target = target; this.layer = layer; this.screenSpace = screenSpace; sortingLayer = -1; sortingOrder = -1; raycastHit = default(RaycastHit); raycastHit2D = default(RaycastHit2D); raycastHitUI = default(RaycastHitUI); type = HitType.Screen; } /// /// Initializes a new instance of the struct from a 3D raycast. /// /// 3D raycast value. /// Touch layer this hit came from. /// If the hit is screenspace UI. public HitData(RaycastHit value, TouchLayer layer, bool screenSpace = false) : this(value.collider.transform, layer, screenSpace) { raycastHit = value; type = HitType.World3D; } /// /// Initializes a new instance of the struct from a 2D raycast. /// /// 2D raycast value. /// Touch layer this hit came from. /// If the hit is screenspace UI. public HitData(RaycastHit2D value, TouchLayer layer, bool screenSpace = false) : this(value.collider.transform, layer, screenSpace) { raycastHit2D = value; type = HitType.World2D; } /// /// Initializes a new instance of the struct from a UI raycast. /// /// UI raycast value. /// Touch layer this hit came from. /// If the hit is screenspace UI. public HitData(RaycastHitUI value, TouchLayer layer, bool screenSpace = false) : this(value.Target, layer, screenSpace) { raycastHitUI = value; type = HitType.UI; } #endregion #region Private functions private void updateSortingValues() { var sprite = target.GetComponent(); if (sprite == null) { sortingLayer = 0; sortingOrder = 0; } else { sortingLayer = sprite.sortingLayerID; sortingOrder = sprite.sortingOrder; } } #endregion } }