コード例 #1
0
    public void FromState(RayState rs)
    {
        // Muzzel Flash
        muzzelFlash.Flash();

        // Cast ray
        int masks = 0;

        masks |= (1 << LayerMask.NameToLayer("Player"));
        masks |= (1 << LayerMask.NameToLayer("Map"));

        var          fireDir = new Vector2(Mathf.Cos(rs.zAngle), Mathf.Sin(rs.zAngle));
        RaycastHit2D hitInfo = Physics2D.Raycast(rs.pos, fireDir, 1000, masks);

        if (hitInfo)
        {
            // Particle effect
            var effectPosition = new Vector3(hitInfo.point.x, hitInfo.point.y, -1);
            var effectRotation = Quaternion.Euler(0, 0, Random.Range(0.0f, 360.0f));
            var effect         = GameObject.Instantiate(impactEffect, effectPosition, effectRotation);
            GameObject.Destroy(effect, 1);
            //DrawRay.DrawLine(firePoint.transform.position, hitInfo.point, Color.red, 0.05f);
            DrawRay.DrawLine(rs.pos, hitInfo.point, Color.red, 1f);
        }
        else
        {
            //DrawRay.DrawLine(firePoint.transform.position, rs.zAngle, 100f, Color.red, 0.05f);
            DrawRay.DrawLine(rs.pos, rs.zAngle, 100f, Color.red, 1f);
        }
    }
コード例 #2
0
    /// <summary>
    /// This function is the core of the Lag Compensation Algorithm.
    /// When a player fires we raycast on all the backtracked colliders on the specific give tick
    /// </summary>
    /// <param name="player">This parameter is the player attached to this gamobject.</param>
    /// <param name="tickAck">This parameter is the last tick seen by the shooting player,
    /// i.e the tick that this tick answers or refers.</param>
    public RayState FireShotWithBacktrack(int tickAck)
    {
        // Debug.Log("Player " + attachedPlayer.playerId + " Fire");
        float    zAngle     = attachedPlayer.rb.rotation * Mathf.Deg2Rad;
        Vector2  headingDir = new Vector2(Mathf.Cos(zAngle), Mathf.Sin(zAngle));
        Vector2  firePoint  = attachedPlayer.firePointGO.transform.position;
        RayState newRay     = new RayState(attachedPlayer.playerId, zAngle, firePoint);

        // Debug.Log("Was answer for tick: " + tickAck);
        // Debug.Log("But last tick was: " + (NetworkTick.tickSeq - 1));
        Debug.DrawRay(firePoint, headingDir * 100f);

        // Cast a ray straight down.
        RaycastHit2D[] results = Physics2D.RaycastAll(firePoint, headingDir, 100, lagCompensationMask);

        LayerMask mapLayer = LayerMask.NameToLayer("Map");

        foreach (RaycastHit2D hit in results)
        {
            if (hit.collider.gameObject.layer.Equals(mapLayer))
            {
                // DEBUG intersection
                Vector2    intersect = hit.point;
                GameObject circ      = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                circ.transform.position   = intersect;
                circ.transform.localScale = new Vector3(0.7f, 0.7f, 0.7f);

                GameObject.Destroy(circ, 0.4f);
                break;
            }

            SnapshotInfo colliderInfo = hit.transform.parent.GetComponent <SnapshotInfo>();
            if (colliderInfo.Player != attachedPlayer && colliderInfo.SnapshotTick == tickAck)
            {
                // Kill the player, destroy its container gameobject
                GameObject.Destroy(colliderInfo.PlayerContainer);
                // Check and logs what have we hit, a headshot or a bodyshot
                ushort hitPlayerID = colliderInfo.Player.playerId;
                if (hit.collider.gameObject.name == "Head")
                {
                    Debug.Log("Player " + attachedPlayer.playerId + " Headshot Player " + hitPlayerID);
                }
                else if (hit.collider.gameObject.name == "Body")
                {
                    Debug.Log("Player " + attachedPlayer.playerId + " Bodyshot Player " + hitPlayerID);
                }
                // DEBUG intersection
                Vector2    intersect = hit.point;
                GameObject circ      = GameObject.CreatePrimitive(PrimitiveType.Sphere);
                circ.transform.position   = intersect;
                circ.transform.localScale = new Vector3(0.7f, 0.7f, 0.7f);

                GameObject.Destroy(circ, 0.4f);
                break;
            }
        }

        return(newRay);
    }
コード例 #3
0
 public void AddState(RayState state)
 {
     raysState.Add(state);
 }
コード例 #4
0
        isInside(Vertex point, LinearRing outerRing, double radiusOfInterest)
        {
            if (DEBUG)
            {
                if (radiusOfInterest < 0.0)
                {
                    throw new Exception("MkGeoAlgo.isInside: radiusOfInterest must be greater than 0");
                }
            }
            // test the bounding box of the ring with radiusOfInterest

            var bb = outerRing.boundingBox();

            if (!isInsideBoundingBox(bb.bottomLeft, bb.topRight, point, radiusOfInterest))
            {
                return(1, nextFloat(radiusOfInterest));
            }

            double bbScale = maxAbs(bb.bottomLeft, bb.topRight);

            if (bbScale < 1.0)
            {
                bbScale = 1.0;
            }
            double epsilon = nextFloat(bbScale) - bbScale;

            int             effectiveLength = outerRing.length - 1;
            Func <int, int> roundIndex      = n => (n + effectiveLength) % effectiveLength;

            EdgeBBTester edgeBBTester = new EdgeBBTester(point, radiusOfInterest);

            int    numIntersection = 0;
            int    inout           = Int32.MaxValue; // should be -1 (inside), 0 (boundary), 1 (outside)
            double buffer          = radiusOfInterest;

            // Determine the initial state. We wlll loop through the verts from "bottom"

            // We will start the loop from bottom

            // bottom is the index of the lowest vert
            int bottom = outerRing.bottomVert;

            Vertex   v1    = outerRing[bottom];
            RayState state = RayState.Below;

            if (v1.y < point.y)
            {
                state = RayState.Below;
            }
            else if (v1.y > point.y)
            {
                state = RayState.RayDone;
                inout = 1;

                // in the following v1.y === point.y
            }
            else if (bb.bottomLeft.y == bb.topRight.y)
            {
                // bounding box degenerates to horizontal line segment
                inout = 0;
                state = RayState.RayDone;
            }
            else
            {
                // Find the left-most bottom
                int j = bottom;
                for (int i = 1; i < outerRing.length; ++i)
                {
                    int    k   = roundIndex(bottom - i);
                    Vertex v_k = outerRing[k];
                    // notice that v1.y is least among all verts
                    // we are sure to find v0
                    if (v_k.y > v1.y)
                    {
                        break;
                    }
                    else
                    {
                        j = k;
                    }
                }
                bottom = j;
                state  = RayState.AboveToMiddle;
            }

            // Assertion: state === RayDone || inout == Int32.MaxValue
            //            state !== RayDone || inout != Int32.MaxValue

            Vertex v2 = outerRing[bottom];
            Vertex v0;
            Vertex xmin, xmax, ymin, ymax;

            v1 = outerRing[roundIndex(bottom - 1)];
            for (int i = 1; i < outerRing.length; ++i)
            {
                v0 = v1;
                v1 = v2;
                v2 = outerRing[roundIndex(bottom + i)];

                if (v1.x < v2.x)
                {
                    xmin = v1;
                    xmax = v2;
                }
                else
                {
                    xmin = v2;
                    xmax = v1;
                }
                if (v1.y < v2.y)
                {
                    ymin = v1;
                    ymax = v2;
                }
                else
                {
                    ymin = v2;
                    ymax = v1;
                }

                if (state == RayState.RayDone)
                {
                    if (buffer == 0.0)
                    {
                        break;
                    }
                    else
                    {
                        // We have to test edges for the distance
                        if (edgeBBTester.isInBoundingBox(xmin, xmax, ymin, ymax))
                        {
                            double updated = updateBorderBuffer(buffer, v0, v1, v2, point, epsilon);

                            // Assertion: updated == buffer || |updated| < |buffer| && |updated| < radiusOfInterest

                            if (Math.Abs(updated) < Math.Abs(buffer))
                            {
                                edgeBBTester.tightenOffset(Math.Abs(updated));
                                buffer = updated;
                            }
                        }
                        continue;
                    }
                }
                else if (state == RayState.Below || state == RayState.Above)
                {
                    if (point.y == v2.y)
                    {
                        // entering Middle
                        if (point.x == v2.x)
                        {
                            inout = 0;
                            state = RayState.RayDone;
                        }
                        else
                        {
                            state = (state == RayState.Below) ? RayState.BelowToMiddle : RayState.AboveToMiddle;
                        }
                    }
                    else if (state == RayState.Below ? v2.y > point.y : v2.y < point.y)
                    {
                        // Below -> Above || Above -> Below
                        state = state == RayState.Below ? RayState.Above : RayState.Below;
                        if (point.x <= xmax.x)
                        {
                            if (point.x <= xmin.x)
                            {
                                // there must be hit
                                numIntersection += 1;
                            }
                            else
                            {
                                // xmin.x < point.x <= xmax.x
                                double d = signedDist(ymin, ymax, point);
                                if (d == 0.0)
                                {
                                    // hit the boundary
                                    inout = 0;
                                    state = RayState.RayDone;
                                }
                                else if (d > 0.0)
                                {
                                    // one hit
                                    numIntersection += 1;
                                }
                                // otherwise, Δ < 0: there is no hit
                            }
                        }
                        else
                        {
                            // point.x > xmax.x: there is no hit
                            // if debug
                            //     println("Test 8.5")
                            // end
                        }
                    }
                    // otherwise, state === Below ? v2.y < point.y : v2.y > point.y, and we remain in Below/Above
                }
                else if (state == RayState.BelowToMiddle || state == RayState.AboveToMiddle)
                {
                    // We are on the Middle line
                    if (point.y == v2.y)
                    {
                        // Stay on the Middle
                        if (xmin.x <= point.x && point.x <= xmax.x)
                        {
                            // we are on the horizontal edge
                            inout = 0;
                            state = RayState.RayDone;
                        }
                    }
                    else if (state == RayState.BelowToMiddle ? v2.y <point.y : v2.y> point.y)
                    {
                        // Below -> BelowToMiddle -> Below
                        // or, Above -> AboveToMiddle -> Above
                        state = state == RayState.BelowToMiddle ? RayState.Below : RayState.Above;
                    }
                    else
                    {
                        // state === BelowToMiddle ? v2.y > point.y : v2.y < point.y
                        // Below -> BelowToMiddle -> Above
                        // or, Above -> AboveToMiddle -> Below
                        state = state == RayState.BelowToMiddle ? RayState.Above : RayState.Below;
                        if (point.x <= v1.x)
                        {
                            numIntersection += 1;
                        }
                    }
                } // end of state transition
            }     // end of the loop through all the verts

            // println("number of intersection = " * string(numIntersection))
            if (inout == Int32.MaxValue)
            {
                if (numIntersection % 2 == 0)
                {
                    inout = 1;
                }
                else
                {
                    inout = -1;
                }
            }
            if (buffer == radiusOfInterest)
            {
                if (radiusOfInterest >= Double.MaxValue)
                {
                    string err = "logical error: the distance to the border cannot be infinity";
                    if (DEBUG)
                    {
                        throw new Exception(err);
                    }
                    else if (geoFenceLogger != null)
                    {
                        geoFenceLogger(err);
                    }
                }
                buffer = inout < 0 ? -nextFloat(radiusOfInterest) : nextFloat(radiusOfInterest);
            }
            return(inout, buffer);
        } // isInside(LinearRing )