IEnumerator FadeInCoroutine() { Time.timeScale = 1f; fadeTimerStart = Time.unscaledTime; fadeTimer = Time.unscaledTime + fadeDuration; fadePanel.enabled = true; fadePanel.color = Color.black; while (true) { if (Time.unscaledTime > fadeTimer) { fadePanel.enabled = false; break; } else { float a = VectorExtras.ReverseLerp(Time.unscaledTime, fadeTimerStart, fadeTimerStart + fadeDuration); a = VectorExtras.MirrorValue(a, 0f, 1f); fadePanel.color = new Color(fadePanel.color.r, fadePanel.color.g, fadePanel.color.b, a); } yield return(null); } if (onFadeDone != null) { onFadeDone.Invoke(); } }
IEnumerator FadeOutCoroutine() { Time.timeScale = 0f; fadeTimerStart = Time.unscaledTime; fadeTimer = Time.unscaledTime + fadeDuration; fadePanel.enabled = true; fadePanel.color = Color.clear; while (true) { yield return(null); if (Time.unscaledTime > fadeTimer) { fadePanel.color = Color.black; break; } else { float a = VectorExtras.ReverseLerp(Time.unscaledTime, fadeTimerStart, fadeTimerStart + fadeDuration); fadePanel.color = new Color(fadePanel.color.r, fadePanel.color.g, fadePanel.color.b, a); } } //Time.timeScale = 1f; if (onFadeDone != null) { onFadeDone.Invoke(); } }
void Update() { Color c = text.color; c.a = VectorExtras.Remap(min, max, 0, 1, terrain.GetPlayerDistance()); text.color = c; }
void Update() { if (positions == null || positions.Count <= 0 || segments == null || segments.Count <= 0) { return; } positions[0] = VectorExtras.AnchoredMovePosTowardTarget(head.transform.position, positions[0], segmentSpacingMax); float ang = VectorExtras.VectorToDegrees(VectorExtras.Direction(segments[0].transform.position, head.transform.position)); angles[0] = Mathf.MoveTowardsAngle(angles[0], ang, bodyRotateSpeed * Time.deltaTime); segments[0].transform.rotation = Quaternion.AngleAxis(angles[0], Vector3.forward); segments[0].transform.position = positions[0]; Vector3 nextPos = VectorExtras.AnchoredMovePosTowardTarget(head.transform.position, positions[0], segmentSpacingMax); for (int i = 1; i < segments.Count; i++) { positions[i] = VectorExtras.AnchoredMovePosTowardTarget(nextPos, positions[i], segmentSpacingMax / 3f); ang = VectorExtras.VectorToDegrees(VectorExtras.Direction(segments[i].transform.position, nextPos)); angles[i] = Mathf.MoveTowardsAngle(angles[i], ang, bodyRotateSpeed * Time.deltaTime); segments[i].transform.rotation = Quaternion.AngleAxis(angles[i], Vector3.forward); segments[i].transform.position = positions[i]; nextPos = VectorExtras.AnchoredMovePosTowardTarget(positions[i - 1], positions[i], segmentSpacingMax / 3f); } }
void AddPath() { for (int i = 0; i < segmentsPerChunk; i++) { int ind = i + overallIndex; float noise = Perlin1D(ind, pathNoiseScale, pathNoiseOctaves, pathNoisePersistence, pathNoiseLacunarity); Vector2 point; float noiseFactor = VectorExtras.Remap(0, 100, 0, 1, ind); point = Vector2.down * ind * segmentLength + (Vector2.right * noise * noiseFactor); path.Add(point); } overallIndex += segmentsPerChunk; }
public float PointDistanceAlongPath(Vector2 point) { int currentSegmentIndex = ClosestSegmentIndexToPoint(point); float distance = 0; for (int i = 1; i < currentSegmentIndex; i++) { distance += Vector2.Distance(path[i - 1], path[i]); } Vector2 projected = VectorExtras.ProjectPointOnLineSegment(path[currentSegmentIndex - 1], path[currentSegmentIndex], point); distance += Vector2.Distance(path[currentSegmentIndex - 1], projected); return(distance); }
void Update() { _deltaTime = Time.deltaTime * simulationSpeed; if (isSimulating) { //Check edges we are in contact with. Check for changes MovementData newMovement = new MovementData(movement); //Private Vector2 inputForce = GameManager.inputAxis * moveSpeed * _deltaTime; newMovement.velocity += inputForce; collisionSides = GetSurroundings(newMovement.position); CollisionModify(collisionSides, ref newMovement); if (collisionSides.HasFlag(Edges.Below)) { newMovement.velocity.x = Mathf.MoveTowards(newMovement.velocity.x, 0f, groundDrag); } MovementData prediction = Verlet(newMovement, collisionSides.HasFlag(Edges.Below) ? Vector2.zero : Acceleration()); //Private //NOTE this implementation for collisions is NOT accurate with Verlet!! Need a better solution... float distance = Vector2.Distance(movement.position, prediction.position); Vector2 direction = VectorExtras.Direction(movement.position, prediction.position); List <RaycastHit2D> hits = FilterIgnored(ignoredColliders, Physics2D.BoxCastAll(movement.position, collider.size, 0f, direction, distance)); if (hits.Count > 0) //Did we hit something? { RaycastHit2D hit = hits[0]; prediction.position = hit.centroid + (hit.normal * bloatSpacing); } movement = prediction; transform.position = new Vector3(movement.position.x, movement.position.y, 0f); collisionSides = GetSurroundings(transform.position); ExternalCall(collisionSides); } }
public int ClosestSegmentIndexToPoint(Vector2 point) { float shortestDistance = float.MaxValue; int currentSegmentIndex = 0; for (int i = 1; i < path.Count; i++) { Vector2 projectedPos = VectorExtras.ProjectPointOnLineSegment(path[i - 1], path[i], point); float dist = Vector2.Distance(projectedPos, point); if (dist < shortestDistance) { shortestDistance = dist; currentSegmentIndex = i; } } return(currentSegmentIndex); }
void Update() { if (initalized == false) { return; } int index = TerrainController.Singleton.ClosestSegmentIndexToPoint(head.transform.position); index = Mathf.Min(index + 1, TerrainController.Singleton.path.Count - 1); Vector3 target; if (Vector3.Distance(head.position, PlayerController.Singleton.transform.position) < chasePlayerDistance) { target = PlayerController.Singleton.transform.position; } else { target = TerrainController.Singleton.path[index] + (Vector2)TerrainController.Singleton.transform.position; } float myDistance = TerrainController.Singleton.PointDistanceAlongPathTotal(head.position); float playerDistance = TerrainController.Singleton.PointDistanceAlongPathTotal(PlayerController.Singleton.transform.position); distToPlayer = playerDistance - myDistance; float percent = VectorExtras.ReverseLerp(distToPlayer, minSpeedDistance, maxSpeedDistance); float curve = speedCurve.Evaluate(percent) * (maxSpeed - minSpeed); speed = curve + minSpeed; //VectorExtras.Remap( minSpeedDistance, maxSpeedDistance, minSpeed, maxSpeed, diff ); head.position = Vector3.MoveTowards(head.position, target, speed * Time.deltaTime); float a = VectorExtras.VectorToDegrees(VectorExtras.Direction(head.position, target)); headAngle = Mathf.MoveTowardsAngle(headAngle, a, headRotateSpeed * Time.deltaTime); head.transform.rotation = Quaternion.AngleAxis(headAngle, Vector3.forward); Debug.DrawLine(head.position, target, Color.cyan); }
/// Return what side of our box collider was impacted. private static Edges GetCollisionSide(RaycastHit2D hit) { if (hit.collider == null) { return(Edges.None); } Vector2Int sign = VectorExtras.Sign01(-hit.normal); if (sign.y != 0) //Prioritize top or bottom collisions first { return(sign.y == 1 ? Edges.Above : Edges.Below); } else if (sign.x != 0) { return(sign.x == 1 ? Edges.Right : Edges.Left); } else { return(Edges.None); } }
IEnumerator MineStartDelay() { float targetTime = 0f; while (true) { miningDirection = (GameManager.InputToEdge() & _lastContacts) & ~Edges.None; // & ~Edges.none removes bit None from calculation if (isMining == true) //Are we trying to start mining? { float startTime = Time.time; //'targetTime' is not used here since we would like to track progress of our timer float endime = Time.time + miningTime; minerVisual.visible = true; minerVisual.SetTile(miningTile); GameManager.inputEnabled = false; mover.isSimulating = false; //Disable player controller so we can move the player manually. Vector3 playerStart = transform.position; Vector3 playerEnd = new Vector3(miningTile.x + 0.5f, miningTile.y + 0.5f, 0f); while (true) { float progress = VectorExtras.ReverseLerp(Time.time, startTime, endime); transform.position = Vector3.Lerp(playerStart, playerEnd, progress); minerVisual.Set(progress); if (Time.time >= endime) { GameManager.singleton.level.blocks[miningTile.x, miningTile.y] = 0; GameManager.singleton.level.UpdateMap(); transform.position = playerEnd; mover.movement.position = new Vector2(playerEnd.x, playerEnd.y); break; } yield return(null); } GameManager.inputEnabled = true; mover.isSimulating = true; minerVisual.visible = false; miningTile = new Vector2Int(-1, -1); yield return(null); } else { if ((int)(miningDirection & ~Edges.None) != 0 && isOnGround && mover.movement.velocity.magnitude < stopMiningVel) //Check for any direction OTHER than none { Edges startingMine = miningDirection; while (true) { miningDirection = (GameManager.InputToEdge() & _lastContacts) & ~Edges.None; // & ~Edges.none removes bit None from calculation if (miningDirection != startingMine || isOnGround == false || mover.movement.velocity.magnitude > stopMiningVel) //Check if we should stop beginning to mine { targetTime = miningStartDelay; startingMine = Edges.None; miningTile = GameManager.EdgeToDirection(Edges.None); //Set no tile break; } else { //As long as the starting inputs are held, countdown our timer before actually starting to mine. targetTime -= Time.deltaTime; if (targetTime <= 0f) { targetTime = miningTime; miningTile = tileCoord + GameManager.EdgeToDirection(miningDirection); //Set the adjacent tile to be mined. break; } } yield return(null); } } } yield return(null); } }
Vector2 ClosestPointAlongPath(Vector2 point) { int currentSegmentIndex = ClosestSegmentIndexToPoint(point); return(VectorExtras.ProjectPointOnLineSegment(path[currentSegmentIndex - 1], path[currentSegmentIndex], point)); }
public void UpdateTerrain() { bottomPoints.Clear(); topPoints.Clear(); float pathLength = 0; for (int i = 1; i < path.Count; i++) { Vector2 segment = path[i] - path[i - 1]; Vector2 perp = Vector2.Perpendicular(segment).normalized; Vector2 startPerpCutoff = perp; if (i > 1) { Vector2 prevSegment = path[i - 1] - path[i - 2]; Vector2 prevPerp = Vector2.Perpendicular(prevSegment).normalized; startPerpCutoff = ((startPerpCutoff + prevPerp) / 2).normalized; } Vector2 endPerpCutoff = perp; if (i < path.Count - 1) { Vector2 nextSegment = path[i + 1] - path[i]; Vector2 nextPerp = Vector2.Perpendicular(nextSegment).normalized; endPerpCutoff = ((endPerpCutoff + nextPerp) / 2).normalized; } // Debug.DrawLine(path[i - 1], path[i - 1] + startPerpCutoff * 100, Color.magenta); // Debug.DrawLine(path[i], path[i] + endPerpCutoff * 100, Color.cyan); for (int j = 0; j < segment.magnitude; j += terrainPointDensity) { Vector2 point = Vector2.Lerp(path[i - 1], path[i], j / segment.magnitude); float sample = previousChunksDistance + pathLength + Vector2.Distance(path[i - 1], point); float bottomNoise = Perlin1D(sample, terrainNoiseScale, terrainNoiseOctaves, terrainNoisePersistence, terrainNoiseLacunarity, 0); float topNoise = Perlin1D(sample, terrainNoiseScale, terrainNoiseOctaves, terrainNoisePersistence, terrainNoiseLacunarity, 100); float caveWidth = VectorExtras.Remap(0, distanceToMinCaveWidth, startingCaveWidth, minCaveWidth, sample); Vector2 bottomPoint = point - ((perp * caveWidth) + (perp * bottomNoise)); Vector2 topPoint = point + ((perp * caveWidth) + (perp * topNoise)); if (!IsLeft(path[i - 1], path[i - 1] + startPerpCutoff, bottomPoint) && IsLeft(path[i], path[i] + endPerpCutoff, bottomPoint)) { bottomPoints.Add(bottomPoint); } if (!IsLeft(path[i - 1], path[i - 1] + startPerpCutoff, topPoint) && IsLeft(path[i], path[i] + endPerpCutoff, topPoint)) { topPoints.Add(topPoint); } } pathLength += segment.magnitude; } float skirtPadding = 3000; topPoints.Insert(0, topPoints[0] + Vector2.right * skirtPadding); topPoints.Add(topPoints[topPoints.Count - 1] + Vector2.down * skirtPadding); topPoints.Add(topPoints[topPoints.Count - 1] + Vector2.right * skirtPadding); bottomPoints.Insert(0, bottomPoints[0] + Vector2.left * skirtPadding); bottomPoints.Add(bottomPoints[bottomPoints.Count - 1] + Vector2.down * skirtPadding); bottomPoints.Add(bottomPoints[bottomPoints.Count - 1] + Vector2.left * skirtPadding); if (Application.isPlaying) { topSection.UpdateSpline(topPoints); bottomSection.UpdateSpline(bottomPoints); } }