Ejemplo n.º 1
0
 protected virtual void Start()
 {
     m_SpriteRenderer = GetComponent <SpriteRenderer>();
     m_SortingLayerID = SortingLayer.GetLayerValueFromID(m_SpriteRenderer.sortingLayerID);
 }
Ejemplo n.º 2
0
 public static int GetLayerValueFromID(int Id)
 {
     return(SortingLayer.GetLayerValueFromID(Id));
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Yoinked fron EventSystem.cs source code...
        /// </summary>
        private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)
        {
            if (lhs.module != rhs.module)
            {
                var lhsEventCamera = lhs.module.eventCamera;
                var rhsEventCamera = rhs.module.eventCamera;
                if (lhsEventCamera != null && rhsEventCamera != null && lhsEventCamera.depth != rhsEventCamera.depth)
                {
                    //Debug.Log($"AAA");
                    // need to reverse the standard compareTo
                    if (lhsEventCamera.depth < rhsEventCamera.depth)
                    {
                        return(1);
                    }
                    if (lhsEventCamera.depth == rhsEventCamera.depth)
                    {
                        return(0);
                    }

                    return(-1);
                }

                //Debug.Log($"AAA");
                if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority)
                {
                    return(rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority));
                }

                //Debug.Log($"AAA");
                if (lhs.module.renderOrderPriority != rhs.module.renderOrderPriority)
                {
                    return(rhs.module.renderOrderPriority.CompareTo(lhs.module.renderOrderPriority));
                }
            }

            if (lhs.sortingLayer != rhs.sortingLayer)
            {
                //Debug.Log($"AAA");
                // Uses the layer value to properly compare the relative order of the layers.
                var rid = SortingLayer.GetLayerValueFromID(rhs.sortingLayer);
                var lid = SortingLayer.GetLayerValueFromID(lhs.sortingLayer);
                return(rid.CompareTo(lid));
            }


            if (lhs.sortingOrder != rhs.sortingOrder)
            {
                //Debug.Log($"AAA");
                return(rhs.sortingOrder.CompareTo(lhs.sortingOrder));
            }

            if (lhs.depth != rhs.depth)
            {
                //Debug.Log($"AAA {lhs.gameObject.name} {lhs.depth} {rhs.gameObject.name} {rhs.depth}");
                return(rhs.depth.CompareTo(lhs.depth));
            }

            if (lhs.distance != rhs.distance)
            {
                //Debug.Log($"AAA");
                return(lhs.distance.CompareTo(rhs.distance));
            }

            //Debug.Log($"AAA");
            return(lhs.index.CompareTo(rhs.index));
        }
        /// <summary>
        /// Compare two RaycastResults
        /// </summary>
        /// /// <remarks>
        /// Copied from Unity UI's EventSystem..
        /// If issues, check for updates to this in Unity's UI repo.
        /// </remarks>
        private static int RaycastComparer(RaycastResult lhs, RaycastResult rhs)
        {
            if (lhs.module != rhs.module)
            {
                if (lhs.module.eventCamera != null && rhs.module.eventCamera != null && lhs.module.eventCamera.depth != rhs.module.eventCamera.depth)
                {
                    // need to reverse the standard compareTo
                    if (lhs.module.eventCamera.depth < rhs.module.eventCamera.depth)
                    {
                        return(1);
                    }
                    if (lhs.module.eventCamera.depth == rhs.module.eventCamera.depth)
                    {
                        return(0);
                    }

                    return(-1);
                }

                if (lhs.module.sortOrderPriority != rhs.module.sortOrderPriority)
                {
                    return(rhs.module.sortOrderPriority.CompareTo(lhs.module.sortOrderPriority));
                }

                if (lhs.module.renderOrderPriority != rhs.module.renderOrderPriority)
                {
                    return(rhs.module.renderOrderPriority.CompareTo(lhs.module.renderOrderPriority));
                }
            }

            if (lhs.sortingLayer != rhs.sortingLayer)
            {
                // Uses the layer value to properly compare the relative order of the layers.
                var rid = SortingLayer.GetLayerValueFromID(rhs.sortingLayer);
                var lid = SortingLayer.GetLayerValueFromID(lhs.sortingLayer);
                return(rid.CompareTo(lid));
            }

            if (lhs.sortingOrder != rhs.sortingOrder)
            {
                return(rhs.sortingOrder.CompareTo(lhs.sortingOrder));
            }

            //Only compare depth if the two have the same raycaster
            //This is the only modification from EventSystem
            if (lhs.module == rhs.module && lhs.depth != rhs.depth)
            {
                return(rhs.depth.CompareTo(lhs.depth));
            }

            if (lhs.distance != rhs.distance)
            {
#if UNITY_2017_1_OR_NEWER
                //For Unity 2017.1+, the calculation for the distance for a raycast hit changed.
                //The camera position is now used for the origin for Physics raycasts, while for
                //GUI raycasts, the ray uses the near clipping plane as the origin.

                //In Unity, a raycast hit is known to be from a Graphics raycast
                //if it is missing its world position.
                if (lhs.worldPosition.Equals(Vector3.zero))
                {
                    lhs.distance -= lhs.module.eventCamera.nearClipPlane;
                }

                if (rhs.worldPosition.Equals(Vector3.zero))
                {
                    rhs.distance -= rhs.module.eventCamera.nearClipPlane;
                }
#endif
                return(lhs.distance.CompareTo(rhs.distance));
            }


            return(lhs.index.CompareTo(rhs.index));
        }
    /// <summary>
    /// Checks the gameobjects the mouse is over and triggers interaction for the highest object that has an interaction
    /// to perform.
    /// </summary>
    /// <param name="isDrag">is this during (but not at the very start of) a drag?</param>
    /// <param name="hitRenderer">renderer of the gameobject that had an interaction</param>
    /// <param name="interact">true iff there was an interaction that occurred</param>
    /// <returns>true iff there was a hit that caused an interaction</returns>
    private bool RayHit(bool isDrag, out Renderer hitRenderer, bool interact = false)
    {
        hitRenderer = null;

        Vector3 mousePosition = MousePosition;

        // Sample the FOV mask under current mouse position.
        if (lightingSystem.enabled && lightingSystem.IsScreenPointVisible(CommonInput.mousePosition) == false)
        {
            return(false);
        }

        RaycastHit2D[] hits = Physics2D.RaycastAll(mousePosition, Vector2.zero, 10f, layerMask);

        //collect all the sprite renderers
        List <Renderer> renderers = new List <Renderer>();

        foreach (RaycastHit2D hit in hits)
        {
            Transform objectTransform = hit.collider.gameObject.transform;
            Renderer  _renderer       = IsHit(objectTransform);
            if (_renderer != null)
            {
                renderers.Add(_renderer);
            }
        }
        bool isInteracting = false;

        //check which of the sprite renderers we hit and pixel checked is the highest
        if (renderers.Count > 0)
        {
            foreach (Renderer _renderer in renderers.OrderByDescending(r => r.GetType() == TilemapType ? 0 : 1)
                     .ThenByDescending(r => SortingLayer.GetLayerValueFromID(r.sortingLayerID))
                     .ThenByDescending(r => r.sortingOrder))
            {
                // If the ray hits a FOVTile, we can continue down (don't count it as an interaction)
                // Matrix is the base Tilemap layer. It is used for matrix detection but gets in the way
                // of player interaction
                if (!_renderer.sortingLayerName.Equals("FieldOfView"))
                {
                    hitRenderer = _renderer;

                    if (!interact)
                    {
                        break;
                    }

                    if (Interact(_renderer.transform, mousePosition, isDrag))
                    {
                        isInteracting = true;
                        break;
                    }
                }
            }
        }

        //Do interacts below: (This is because if a ray returns true but there is no interaction, check click
        //will not continue with the Interact call so we have to make sure it does below):
        if (interact && !isInteracting)
        {
            //returning false then calls InteractHands from check click:
            return(false);
        }

        //check if we found nothing at all
        return(hits.Any());
    }
Ejemplo n.º 6
0
    /// <summary>
    /// Gets the game objects under the given world position, ordered so that highest item comes first.
    ///
    /// The top-level matrix gameobject (the one with InteractableTiles) at this point is included at the end (if any of its tilemap gameobjects were at this point)
    /// </summary>
    /// <param name="worldPoint">world point to check</param>
    /// <param name="layerMask">layers to check for hits in. If left null, will use DefaultInteractionLayerMask (basically includes every layer
    /// that can have interactable things).</param>
    /// <param name="gameObjectFilter">optional filter to filter out game objects prior to sorting and checking for pixel hits, can improve performance
    /// by shrinking the amount of sorting and pixel checking that needs to be done. Func should return true if should include the gameobject, otherwise false.
    /// Be aware that the GameObject passed to this function will be the one that the SpriteRenderer or TilemapRenderer lives on, which may NOT
    /// be the "root" of the gameobject this renderer lives on.</param>
    /// <returns>the ordered game objects that were under the mouse, top first</returns>
    public static IEnumerable <GameObject> GetOrderedObjectsAtPoint(Vector3 worldPoint, LayerMask?layerMask  = null,
                                                                    Func <GameObject, bool> gameObjectFilter = null)
    {
        var matrix = MatrixManager.AtPoint(Vector3Int.RoundToInt(worldPoint), CustomNetworkManager.Instance._isServer)
                     .Matrix;

        if (!matrix)
        {
            return(new List <GameObject>());
        }


        var tilePosition = Vector3Int.FloorToInt(worldPoint.ToLocal());

        List <RegisterTile> resultRegisterTile = new List <RegisterTile>();

        //humm probably there's a better way of doing this
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition, false).ToList());
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition + Vector3Int.up, false).ToList());
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition + Vector3Int.down, false).ToList());
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition + Vector3Int.right, false).ToList());
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition + Vector3Int.left, false).ToList());
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition + Vector3Int.up + Vector3Int.right, false)
                                    .ToList());
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition + Vector3Int.up + Vector3Int.left, false)
                                    .ToList());
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition + Vector3Int.down + Vector3Int.right, false)
                                    .ToList());
        resultRegisterTile.AddRange(matrix.GetRegisterTile(tilePosition + Vector3Int.down + Vector3Int.left, false)
                                    .ToList());


        var result             = resultRegisterTile.Select(x => x.gameObject);
        var IInteractableTiles = matrix.GetComponentInParent <InteractableTiles>().gameObject;

        // var result = Physics2D.RaycastAll(worldPoint, Vector2.zero, 10f,
        // layerMaskToUse)
        // failsafe - exclude hidden / despawned things in case they happen to mouse over hiddenpos
        // .Where(hit => !hit.collider.gameObject.IsAtHiddenPos())
        // get the hit game object
        // .Select(hit => hit.collider.gameObject);


        if (gameObjectFilter != null)
        {
            result = result.Where(gameObjectFilter);
        }

        return(result
               //check for a pixel hit
               .Select(go => IsPixelHit(go.transform))
               .Where(r => r != null)
               //order by sort layer
               .OrderByDescending(r =>
                                  SortingLayer.GetLayerValueFromID(r.GetComponentInParent <SortingGroup>().OrNull()?.sortingLayerID == null
                                        ? r.sortingLayerID
                                        : r.GetComponentInParent <SortingGroup>().sortingLayerID))
               //then by sort order
               .ThenByDescending(renderer =>
                                 renderer.GetComponentInParent <SortingGroup>().OrNull()?.sortingOrder == null
                                        ? renderer.sortingOrder
                                        : renderer.GetComponentInParent <SortingGroup>().sortingOrder)
               //get the "parent" game object of each of the hit renderers
               //for a sprite renderer, the parent is the object that has a RegisterTile.
               //for a tilemap renderer, the parent is the oject that has a Matrix
               .Select(r =>
                       r is TilemapRenderer
                                        ? r.GetComponentInParent <InteractableTiles>().OrNull()?.gameObject
                                        : r.GetComponentInParent <RegisterTile>().OrNull()?.gameObject)
               //each gameobject should only show up once
               .Append(IInteractableTiles).Distinct());
    }