Пример #1
0
        /// <summary>
        /// Query the possible connections for this field
        /// </summary>
        /// <param name="match">Out parameter that signifies the type of match (ignore, reject or connect)</param>
        /// <param name="bothkinds">Optional boolean to specify whether we want to check for both connection field kinds</param>
        /// <param name="onlyConnectTo">An optional filter field if you only want to check connections on specific bricks</param>
        /// <returns>A list of tuples for the possible connections</returns>
        public HashSet <(Connection, Connection)> QueryConnections(out Connection.ConnectionMatch match, HashSet <Brick> onlyConnectTo, bool bothkinds = false)
        {
            HashSet <ConnectionField> onlyConnectToFields = null;

            if (onlyConnectTo != null && onlyConnectTo.Count > 0)
            {
                onlyConnectToFields = new HashSet <ConnectionField>();
                foreach (var brick in onlyConnectTo)
                {
                    foreach (var part in brick.parts)
                    {
                        if (!part.connectivity)
                        {
                            continue;
                        }

                        onlyConnectToFields.UnionWith(part.connectivity.connectionFields);
                    }
                }
            }
            return(QueryConnections(out match, bothkinds, onlyConnectToFields));
        }
Пример #2
0
        /// <summary>
        /// Query the possible connections for this field
        /// </summary>
        /// <param name="match">Out parameter that signifies the type of match (ignore, reject or connect)</param>
        /// <param name="bothkinds">Optional boolean to specify whether we want to check for both connection field kinds</param>
        /// <param name="onlyConnectTo">An optional filter field if you only want to check connections on specific fields</param>
        /// <returns>A list of tuples for the possible connections</returns>
        public HashSet <(Connection, Connection)> QueryConnections(out Connection.ConnectionMatch match, bool bothkinds = false, ICollection <ConnectionField> onlyConnectTo = null)
        {
            LayerMask mask;

            if (bothkinds)
            {
                mask = LayerMask.GetMask(GetLayer(FieldKind.receptor), GetLayer(FieldKind.connector));
            }
            else
            {
                var opposite = kind == FieldKind.connector ? FieldKind.receptor : FieldKind.connector;
                mask = LayerMask.GetMask(GetLayer(opposite));
            }

            HashSet <(Connection, Connection)> validConnections = new HashSet <(Connection, Connection)>();

            match = Connection.ConnectionMatch.ignore;

            // PhysicsScene
            var physicsScene = gameObject.scene.GetPhysicsScene();
            var size         = new Vector3((gridSize.x + 1) * BrickBuildingUtility.LU_5, BrickBuildingUtility.LU_1 * 2, (gridSize.y + 1) * BrickBuildingUtility.LU_5);
            var center       = new Vector3((size.x - BrickBuildingUtility.LU_5) * -0.5f, 0.0f, (size.z - BrickBuildingUtility.LU_5) * 0.5f);

            var hits = physicsScene.OverlapBox(transform.TransformPoint(center), size * 0.5f, BrickBuildingUtility.colliderBuffer, transform.rotation, mask, QueryTriggerInteraction.Collide);

            for (var i = 0; i < hits; i++)
            {
                var overlap = BrickBuildingUtility.colliderBuffer[i];
                var field   = overlap.GetComponent <ConnectionField>();
                if (field == null || field == this)
                {
                    continue;
                }

                if (onlyConnectTo != null && !onlyConnectTo.Contains(field))
                {
                    continue;
                }

                if (Mathf.Abs(Vector3.Dot(field.transform.up, transform.up)) < 0.95f)
                {
                    continue;
                }

                if (!GetOverlap(field, this, out Vector2Int min, out Vector2Int max))
                {
                    continue;
                }

                for (var x = min.x; x < max.x + 1; x++)
                {
                    for (var z = min.y; z < max.y + 1; z++)
                    {
                        var localPos        = new Vector3(x * BrickBuildingUtility.LU_5, 0.0f, z * BrickBuildingUtility.LU_5);
                        var fieldConnection = field.GetConnectionAt(ConnectionField.ToGridPos(localPos));
                        if (fieldConnection != null && !field.HasConnection(fieldConnection))
                        {
                            var worldPos   = field.GetPosition(fieldConnection);
                            var connection = GetConnectionAt(worldPos);
                            if (connection != null && !HasConnection(connection))
                            {
                                // Note: ConnectionValid checks both rejection and distance (position + rotation) so we need
                                //       to make sure we take care of both in case of false.
                                if (!Connection.ConnectionValid(fieldConnection, connection, out Connection.ConnectionMatch pairMatch))
                                {
                                    if (pairMatch != Connection.ConnectionMatch.reject)
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        match = pairMatch;
                                        validConnections.Clear();
                                        return(validConnections);
                                    }
                                }

                                if (pairMatch == Connection.ConnectionMatch.connect)
                                {
                                    validConnections.Add((connection, fieldConnection));
                                }
                            }
                        }
                    }
                }
            }

            match = Connection.ConnectionMatch.connect;
            return(validConnections);
        }