コード例 #1
0
 public void StartBounce(SO_SpriteBounce sBSO, Vector2 clutterHitDir)
 {
     inUse          = true;
     spriteR.sprite = sBSO.sprite;
     direction      = (new Vector2(Random.Range(-1f, 1f), Random.Range(-1f, 1f)) + clutterHitDir).normalized;
     this.gameObject.SetActive(true);
     StartCoroutine(BouncingSpriteLerp(sBSO));
 }
コード例 #2
0
    IEnumerator BouncingSpriteLerp(SO_SpriteBounce sBSO)
    {
        // Grab the variables and values from the sprite bounce Scriptable Object.
        float           moveDist           = sBSO.MoveDist;
        float           radius             = sBSO.radius;
        ContactFilter2D contactFilter      = sBSO.contactFilter;
        float           startSpeed         = sBSO.StartSpeed;
        float           slidePercentOfDist = sBSO.slidePercentOfDist;
        int             bounces            = sBSO.Bounces;
        float           bounceHeight       = sBSO.BounceHeight;
        AnimationCurve  bounceCurve        = sBSO.bounceCurve;
        float           heightLossMult     = sBSO.heightLossMult;
        float           targetZRotation    = sBSO.Rotation;
        // Movement Variables.
        Vector2 curMainPos = spriteToMoveTrans.position;
        Vector2 startPos   = spriteToMoveTrans.position;
        Vector2 endPos     = startPos + (direction * moveDist);
        //Raycast variables.
        Vector2        prevDirection       = direction;
        Vector2        prevHitPos          = startPos;
        float          distLeft            = moveDist;
        float          distUsed            = 0f;
        bool           checkCollisions     = true;
        List <Vector2> hitPositions        = new List <Vector2>();
        List <float>   hitDistPercentAdded = new List <float>();
        List <float>   hitDistPercent      = new List <float>();

        // Fire reflecting raycasts to determine the object's trajectory.
        while (checkCollisions)
        {
            RaycastHit2D rayHit = Physics2D.CircleCast(prevHitPos, radius - testReduce, prevDirection, distLeft, contactFilter.layerMask);
            if (rayHit.collider != null)
            {
                Debug.DrawLine(prevHitPos, rayHit.centroid, Color.red, 5f);
                float distanceToCol = (rayHit.centroid - prevHitPos).magnitude;
                // Calculate the new maximum moveDist left.
                distLeft  -= distanceToCol;
                distUsed  += distanceToCol;
                prevHitPos = rayHit.centroid;
                // Add the moveDist traveled so far on 1 to a list, to know when to change direction.
                hitDistPercent.Add(distanceToCol / moveDist);
                hitDistPercentAdded.Add(distUsed / moveDist);
                // Store the hit position to know where to move to next.
                hitPositions.Add(rayHit.centroid);
                // Get the reflected direction and fire a raycast with a length of the moveDist left to see if we hit anything else.
                Vector2 reflectDir = Vector2.Reflect(prevDirection, rayHit.normal).normalized;
                prevDirection = reflectDir;
                testReduce   += testReduce;
            }
            else
            {
                checkCollisions = false;
                // If the ray dosnt hit anything calculate the last position and add it to the list.
                hitPositions.Add(prevHitPos + (prevDirection * distLeft));
                hitDistPercent.Add(distLeft / moveDist);
                hitDistPercentAdded.Add(1f);
                Debug.DrawLine(prevHitPos, prevHitPos + (prevDirection * distLeft), Color.red, 5f);
            }
            yield return(null);
        }
        // Start moving the object.
        bool movementDone = false;
        int  curTarget    = 0;

        curSpeed = startSpeed;
        // Bounce variables.
        int   bounceCount = 0;
        float bounceTimer = 0f;
        float slideDist   = slidePercentOfDist * moveDist;
        //print(slideDist);
        float bounceSegDur    = ((moveDist - slideDist) / bounces) / curSpeed;
        float yPos            = 0f;
        float baseYPos        = spriteToBounceTrans.localPosition.y;
        float startY          = 0f;
        float curBounceHeight = bounceHeight;
        float endY            = curBounceHeight;
        bool  bouncing        = true;
        // Rotation variables.
        bool    rotating       = true;
        float   moveDuration   = (moveDist - (slideDist * 0.5f)) / curSpeed;
        float   rotationDelta  = targetZRotation / moveDuration;
        Vector3 targetRotation = new Vector3(spriteToBounceTrans.eulerAngles.x, spriteToBounceTrans.eulerAngles.y, targetZRotation);
        float   zRotation;

        //float rotationDelta =
        // Move the object.
        while (!movementDone)
        {
            spriteToMoveTrans.position = Vector2.MoveTowards(spriteToMoveTrans.position, hitPositions[curTarget], curSpeed * Time.deltaTime);
            if (((Vector2)spriteToMoveTrans.position - hitPositions[curTarget]).magnitude <= 0.001f)
            {
                curTarget++;
                if (curTarget >= hitPositions.Count)
                {
                    movementDone = true;
                }
            }
            // Bounce the object.
            if (bouncing)
            {
                bounceTimer += Time.deltaTime / bounceSegDur;
                yPos         = Mathf.Lerp(startY, endY, bounceCurve.Evaluate(bounceTimer));
                //print(yPos);
                if (bounceTimer >= 1f || movementDone)
                {
                    curBounceHeight *= heightLossMult;
                    endY             = curBounceHeight;
                    //print(curBounceHeight);
                    bounceSegDur = ((moveDist - slideDist) / bounces) / curSpeed;
                    bounceCount++;
                    bounceTimer = 0f;
                    yPos        = 0f;
                    //print(bounceCount);
                    if (bounceCount >= bounces)
                    {
                        bouncing = false;
                        //print(bouncing);
                    }
                }
                spriteToBounceTrans.localPosition = new Vector3(spriteToBounceTrans.localPosition.x, baseYPos + yPos, spriteToBounceTrans.localPosition.z);
            }
            // Rotate the object.
            if (rotating)
            {
                zRotation = Mathf.MoveTowards(spriteToBounceTrans.eulerAngles.z, targetZRotation, rotationDelta * Time.deltaTime);
                spriteToBounceTrans.eulerAngles = new Vector3(0f, 0f, zRotation);
            }
            yield return(null);
        }
        spriteR.sortingOrder = -1;
    }