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)); }
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; }