예제 #1
0
    /// <summary>
    /// Attempts to generate a bouncy richochet path. Not guaranteed to leave make path successful
    /// </summary>
    /// <param name="mode"></param>
    /// <param name="path"></param>
    /// <param name="angleBundle"></param>
    void attemptBonucyRicochetPath(ricochetMode mode, RicochetPath path, Vector3 angleBundle)
    {
        Vector3 launchVector = generateLaunchVector(angleBundle);                                                          //Calculating launch direction
        Vector3 objectPositionWhenContactMade = generateStartingContactPoint(mode) + launchVector * _ricochetObjectRadius; //Calculating the starting point

        //Calculating the ricochet points...
        path.ricochetPositions.Add(objectPositionWhenContactMade);
        RaycastHit hitResults = new RaycastHit();

        for (int i = 0; i < maxNumberofBounces; i++)
        {
            Physics.SphereCast(objectPositionWhenContactMade, _ricochetObjectRadius, launchVector, out hitResults, maxPathSegmentLength, interactingLayers, QueryTriggerInteraction.Ignore);
            if (hitResults.collider == null) //Nothing was hit...
            {
                path.ricochetPositions.Add(objectPositionWhenContactMade + launchVector * maxPathSegmentLength);
                break;
            }
            else if (hitResults.collider.gameObject.layer == LayerMask.NameToLayer(destinationLayer))
            { //Found where it was supposed to go! End here
                objectPositionWhenContactMade = objectPositionWhenContactMade + hitResults.distance * launchVector;
                path.ricochetPositions.Add(objectPositionWhenContactMade);
                path.isSuccessful = true;
                break;
            }
            else //Just hit a bouncing surface
            {
                objectPositionWhenContactMade = objectPositionWhenContactMade + hitResults.distance * launchVector;
                path.bounces++;
                path.ricochetPositions.Add(objectPositionWhenContactMade);
                launchVector = Vector3.Reflect(launchVector, hitResults.normal);
            }
        }
    }
예제 #2
0
    void drawReceptionAngle(Vector3 position, ricochetMode mode, float length)
    {
        Vector3 angleBundle = getAngleBundle(mode);
        Color   drawColor   = getDrawingColor(mode);


        Vector3 pathVector = Vector3.zero;

        //Receiving from right
        pathVector = Quaternion.AngleAxis(angleBundle.x, Vector3.up) * Vector3.forward;
        DebugExtension.DebugCapsule(position, position + pathVector * length, drawColor, _ricochetObjectRadius);

        //Receiving from left
        pathVector = Quaternion.AngleAxis(angleBundle.x, Vector3.down) * Vector3.forward;
        DebugExtension.DebugCapsule(position, position + pathVector * length, drawColor, _ricochetObjectRadius);

        //Receiving from up
        pathVector = Quaternion.AngleAxis(angleBundle.y, Vector3.left) * Vector3.forward;
        DebugExtension.DebugCapsule(position, position + pathVector * length, drawColor, _ricochetObjectRadius);

        if (angleBundle.z != 0)
        {
            //Receiving from down
            pathVector = Quaternion.AngleAxis(angleBundle.z, Vector3.right) * Vector3.forward;
            DebugExtension.DebugCapsule(position, position + pathVector * length, drawColor, _ricochetObjectRadius);
        }
    }
예제 #3
0
    /// <summary>
    /// Generates the point at which this path shoudl start (from the player bullseye).
    /// This code relies on the assumption that for each bullseye later, a certain part of its bottom middle resion will be overlapped by the previous layer
    /// </summary>
    Vector3 generateStartingContactPoint(ricochetMode mode)
    {
        Vector3 startingPoint = Vector3.zero;

        startingPoint.z = target.position.z;

        //Setting the rects needed for the calculations...
        Rect targetRect      = new Rect();
        Rect overlappingRect = new Rect(Vector3.zero, Vector3.zero);

        switch (mode)
        {
        case ricochetMode.hit:
            targetRect = hitRect;
            break;

        case ricochetMode.nearmiss:
            targetRect      = nearMissRect;
            overlappingRect = bufferRect;
            break;

        case ricochetMode.miss:
            targetRect      = missRect;
            overlappingRect = nearMissRect;
            break;
        }


        startingPoint.y = Random.Range(targetRect.yMin, targetRect.yMax);

        if (overlappingRect.size.SqrMagnitude() != 0 && startingPoint.y <= overlappingRect.max.y)
        {
            //Only choose an x from the sides
            if (Random.Range(0, 2) == 1)
            {
                startingPoint.x = Random.Range(overlappingRect.xMin, targetRect.xMin);
            }
            else
            {
                startingPoint.x = Random.Range(overlappingRect.xMax, targetRect.xMax);
            }
        }
        else
        {
            //Choose any x
            startingPoint.x = Random.Range(targetRect.xMin, targetRect.xMax);
        }

        return(startingPoint);
    }
예제 #4
0
    /// <summary>
    /// Returns the angle limits to a particular ricochet path mode
    /// </summary>
    /// <param name="mode"></param>
    /// <returns></returns>
    Vector3 getAngleBundle(ricochetMode mode)
    {
        switch (mode)
        {
        case ricochetMode.hit:
            return(maxHitAngles);

        case ricochetMode.nearmiss:
            return(maxNearMissAngles);

        case ricochetMode.miss:
            return(maxMissAngles);

        default:
            return(Vector3.zero);
        }
    }
예제 #5
0
    Color getDrawingColor(ricochetMode mode)
    {
        switch (mode)
        {
        case ricochetMode.hit:
            return(Color.red);

        case ricochetMode.nearmiss:
            return(Color.yellow);

        case ricochetMode.miss:
            return(Color.green);

        default:
            return(Color.white);
        }
    }
예제 #6
0
    /// <summary>
    /// Generates a straight path to the corruption sphere.
    /// If the scene is set up properly, this code should never leave path unsuccessful.
    /// </summary>
    /// <param name="mode"></param>
    /// <param name="path"></param>
    void generateGuaranteedPath(ricochetMode mode, RicochetPath path)
    {
        Vector3 launchVector = Vector3.forward;
        Vector3 objectPositionWhenContactMade = generateStartingContactPoint(mode) + launchVector * _ricochetObjectRadius; //Calculating the starting point

        //Calculating the ricochet points...
        path.ricochetPositions.Add(objectPositionWhenContactMade);
        RaycastHit hitResults = new RaycastHit();

        Physics.SphereCast(objectPositionWhenContactMade, _ricochetObjectRadius, launchVector, out hitResults, maxPathSegmentLength, destinationLayerMask, QueryTriggerInteraction.Ignore);
        if (hitResults.collider == null) //Nothing was hit...
        {
            return;                      //Worse case scenario
        }
        else
        {
            objectPositionWhenContactMade = objectPositionWhenContactMade + hitResults.distance * launchVector;
            path.ricochetPositions.Add(objectPositionWhenContactMade);
            path.isSuccessful = true;
        }
    }
예제 #7
0
    /// <summary>
    /// Genertates a richochet path. If the scene is set up properly, this is guaranteeded to return a successful path. Check just in case, though.
    /// </summary>
    /// <param name="mode"></param>
    /// <returns></returns>
    public RicochetPath GenerateSuccessfulPath(ricochetMode mode)
    {
        RicochetPath path = new RicochetPath();

        path.mode = mode;
        Vector3 angleBundle = getAngleBundle(mode);

        for (int attempt = 0; attempt < 100; attempt++)
        {
            attemptBonucyRicochetPath(mode, path, angleBundle);
            if (path.isSuccessful)
            {
                break;
            }
            path.reset();
        }

        if (!path.isSuccessful)
        {
            generateGuaranteedPath(mode, path);
        }
        return(path);
    }