/* * Since we only have monopole magnets the formula * F = (permeability * magnet1 force * magnet2 force) / 4 * pi * r^2 * can be used * code from https://steemit.com/programming/@kubiak/magnet-simulation-in-unity */ Vector3 CalculateGilbertForce(Magnet magnet1, Magnet magnet2) { Vector3 m1 = magnet1.transform.position; // apply force based on closest magnet point to player Vector3 m2 = Physics2D.ClosestPoint(m1, magnet2.playerRb.GetComponent <Collider2D>()); // apply force based on cog of rigidbody // Vector3 m2 = magnet2.transform.position; Vector3 r = m2 - m1; float dist = r.magnitude; float part0 = permeability * magnet1.magnetForce * magnet2.magnetForce; float part1 = 4 * Mathf.PI * dist; if (part1 == 0) { return(Vector3.zero); } float f = (part0 / part1); if (magnet1.pole == magnet2.pole) { f = -f; samePole = true; } else { samePole = false; } return(f * r.normalized); }
public void Blast(Vector2 location, Vector2 agentlocation, float range, float force, int damage) { Vector2 hitPoint = Physics2D.ClosestPoint(location, charCollider); Vector2 direction = hitPoint - agentlocation; direction.Normalize(); Debug.Log(direction); float multipier = (range - (hitPoint - location).magnitude) / range; Damage((int)(damage * multipier)); blasted = force * multipier; kineForceX += force * 0.2f * direction.x * multipier; kineForceY += force * 0.2f * direction.y * multipier; Debug.Log("blasted: " + kineForceY); //horizontal = force * 0.2f * direction.x * multipier; //vertical = force * 0.2f * direction.y * multipier; setAirborne(true); blaststart = 0.1f; }
//simple pathfinding algorytm //problem with no-exit situations private List <Vector3> Pathfinding(Vector3 startPosition, Vector3 goalPosition) { List <Vector3> path = new List <Vector3>(); List <Vector3> possibleMoves = new List <Vector3>(); float bestDistance = 10000f; int bestDistanceIndex = 0; Vector3 previousMove = startPosition; Vector3 currentPosition = startPosition; path.Add(startPosition); RaycastHit2D dot; for (int j = 0; j <= 1000; j++) { dot = Physics2D.Raycast(currentPosition, (new Vector3(currentPosition.x + 1f, currentPosition.y + 1f)) - currentPosition, 2f); if (dot.collider == null) { possibleMoves.Add(new Vector3(currentPosition.x + 1f, currentPosition.y + 1f, 0)); } dot = Physics2D.Raycast(currentPosition, (new Vector3(currentPosition.x + 1f, currentPosition.y)) - currentPosition, 2f); if (dot.collider == null) { possibleMoves.Add(new Vector3(currentPosition.x + 1f, currentPosition.y, 0)); } dot = Physics2D.Raycast(currentPosition, (new Vector3(currentPosition.x + 1f, currentPosition.y - 1f)) - currentPosition, 2f); if (dot.collider == null) { possibleMoves.Add(new Vector3(currentPosition.x + 1f, currentPosition.y - 1f, 0)); } dot = Physics2D.Raycast(currentPosition, (new Vector3(currentPosition.x, currentPosition.y + 1f)) - currentPosition, 2f); if (dot.collider == null) { possibleMoves.Add(new Vector3(currentPosition.x, currentPosition.y + 1f, 0)); } dot = Physics2D.Raycast(currentPosition, (new Vector3(currentPosition.x, currentPosition.y - 1f)) - currentPosition, 2f); if (dot.collider == null) { possibleMoves.Add(new Vector3(currentPosition.x, currentPosition.y - 1f, 0)); } dot = Physics2D.Raycast(currentPosition, (new Vector3(currentPosition.x - 1f, currentPosition.y + 1f)) - currentPosition, 2f); if (dot.collider == null) { possibleMoves.Add(new Vector3(currentPosition.x - 1f, currentPosition.y + 1f, 0)); } dot = Physics2D.Raycast(currentPosition, (new Vector3(currentPosition.x - 1f, currentPosition.y)) - currentPosition, 2f); if (dot.collider == null) { possibleMoves.Add(new Vector3(currentPosition.x - 1f, currentPosition.y, 0)); } dot = Physics2D.Raycast(currentPosition, (new Vector3(currentPosition.x - 1f, currentPosition.y - 1f)) - currentPosition, 2f); if (dot.collider == null) { possibleMoves.Add(new Vector3(currentPosition.x - 1f, currentPosition.y - 1f, 0)); } for (int i = 0; i <= possibleMoves.Count - 1; i++) { float temp = Vector3.Distance(possibleMoves[i], goalPosition); if (temp < bestDistance && previousMove != possibleMoves[i]) { // Debug.Log(possibleMoves.Count); bestDistance = temp; bestDistanceIndex = i; } } previousMove = currentPosition; path.Add(possibleMoves[bestDistanceIndex]); // Debug.DrawLine(currentPosition, possibleMoves[bestDistanceIndex], Color.black, 100f); currentPosition = possibleMoves[bestDistanceIndex]; possibleMoves.Clear(); bestDistance = 10000f; bestDistanceIndex = 0; if (Vector3.Distance(currentPosition, goalPosition) < 1f) { j = 1000; } } // optimalisation of path int realCount = path.Count - 1; for (int i = 0; i <= realCount - 2; i++) { for (int j = 0; j <= realCount - 2; j++) { dot = Physics2D.Raycast(path[realCount - i], (path[j] - path[realCount - i]), Vector3.Distance(path[realCount - i], path[j])); if (!dot.collider) { path.RemoveRange(j + 1, (realCount - i) - j - 1); j = realCount + 2; } realCount = path.Count - 1; } } List <Vector3> path2 = new List <Vector3>(); path2.Add(path[0]); for (int i = 0; i < path.Count - 1; i++) { int temp = 0; for (int j = 0; j < 10; j++) { Vector3 point = path[i] + ((path[i + 1] - path[i]) / 10) * j; if (Physics2D.OverlapCircle(point, 1) && Physics2D.OverlapCircle(point, 1).tag == "Enviroment") { Vector3 point2 = Physics2D.ClosestPoint(point, Physics2D.OverlapCircle(point, 1)); path2.Add(point - Vector3.Normalize(point2 - point)); temp = 1; } else if (j == 9 && temp == 0) { path2.Add(path[i + 1]); } } } if (Physics2D.OverlapCircle(path[path.Count - 1], 1) && Physics2D.OverlapCircle(path[path.Count - 1], 1).tag == "Enviroment") { Vector3 point2 = Physics2D.ClosestPoint(path[path.Count - 1], Physics2D.OverlapCircle(path[path.Count - 1], 1)); path2.Add(path[path.Count - 1] - Vector3.Normalize(point2 - path[path.Count - 1])); } else { path2.Add(path[path.Count - 1]); } for (int i = 0; i < path.Count - 1; i++) { Debug.DrawLine(path[i], path[i + 1], Color.red, 2f); } for (int i = 0; i < path2.Count - 1; i++) { Debug.DrawLine(path2[i], path2[i + 1], Color.green, 2f); } //List<Vector3> path2 = new List<Vector3>(); //for (int i = 0; i < path.Count - 1; i++) //{ // path2.Add(path[i]); // Vector3 point = path[i] + ((path[i + 1] - path[i]) / 2); // if (Physics2D.OverlapCircle(point, 1) && Physics2D.OverlapCircle(point, 1).tag == "Enviroment") // { // Vector3 point2 = Physics2D.ClosestPoint(point, Physics2D.OverlapCircle(point, 1)); // path2.Add(point - Vector3.Normalize(point2 - point)); // } //} //if (Physics2D.OverlapCircle(path[path.Count - 1], 1) && Physics2D.OverlapCircle(path[path.Count - 1], 1).tag == "Enviroment") //{ // Vector3 point2 = Physics2D.ClosestPoint(path[path.Count - 1], Physics2D.OverlapCircle(path[path.Count - 1], 1)); // path2.Add(path[path.Count - 1] - Vector3.Normalize(point2 - path[path.Count - 1])); //} //else //{ // path2.Add(path[path.Count - 1]); //} //for (int i = 0; i < path.Count - 1; i++) //{ // Debug.DrawLine(path[i], path[i + 1], Color.red, 2f); //} //for (int i = 0; i < path2.Count - 1; i++) //{ // Debug.DrawLine(path2[i], path2[i + 1], Color.green, 2f); //} return(path2); }
// Update is called once per frame void Update() { if (Time.timeScale > 0.1f) { if (Input.GetButtonDown("Action1") && player.selected == true && gameObject.layer == LayerMask.NameToLayer("Player_outside")) { //test for object to grapple Collider2D coll = null; Vector2 ppoint; colls = Physics2D.OverlapCircleAll(transform.position, 20f, mask); //if object(s) found..,check for the closest one if (colls != null && colls.Length > 0) { Vector2 myLocation = new Vector2(transform.position.x, transform.position.y); ppoint = Physics2D.ClosestPoint(transform.position, colls[0]); Vector2 closest = ppoint - myLocation; coll = colls[0]; for (int i = 1; i < colls.Length; i++) { Vector2 ppoint2 = Physics2D.ClosestPoint(transform.position, colls[i]); if ((ppoint2 - myLocation).sqrMagnitude < closest.sqrMagnitude) { closest = ppoint2 - myLocation; ppoint = ppoint2; coll = colls[i]; } } //coll is now the closest object if (coll.gameObject.GetComponent <Rigidbody2D>() != null) { //if it is a powerline if (audioSource && throwAudio && audioSource) { audioSource.PlayOneShot(throwAudio); } if (coll.gameObject.GetComponent <Powerline>() != null) { //if line was powered, we lose control and get electrocuted bool isPowered = coll.gameObject.GetComponent <Powerline>().isPowered; line.GetComponent <Lightningstrike>().linePowered = isPowered; isElectrocuted = isPowered; if (isElectrocuted == true) { player.Die(PlayerMovement.DieReason.Electrocuted); } } else { line.GetComponent <Lightningstrike>().linePowered = false; isElectrocuted = false; } joint.enabled = true; Vector2 connectPoint = ppoint - new Vector2(coll.transform.position.x, coll.transform.position.y); connectPoint.x = connectPoint.x / coll.transform.localScale.x; connectPoint.y = connectPoint.y / coll.transform.localScale.y; //Debug.Log (connectPoint); joint.connectedAnchor = connectPoint; joint.connectedBody = coll.gameObject.GetComponent <Rigidbody2D>(); joint.distance = Vector2.Distance(transform.position, ppoint); line.enabled = true; line.SetPosition(0, transform.position); line.SetPosition(1, ppoint); } } } if (line != null && joint.connectedBody != null && joint.connectedAnchor != null) { line.SetPosition(1, joint.connectedBody.transform.TransformPoint(joint.connectedAnchor)); } //continuous update during e pressed if (Input.GetButton("Action1") && player.selected == true) { line.SetPosition(0, transform.position); } //remove line on release if ((Input.GetButtonUp("Action1") || player.selected != true) && isElectrocuted == false) { joint.enabled = false; line.enabled = false; isElectrocuted = false; player.controllable = true; } } }
// FixedUpdate is called once per fixed frame // Use Fixed Update for anything involving Rigid Bodies void FixedUpdate() { if (!inCover) // stops the nearest cover from updating if the player is already in cover { nearestCover = Physics2D.OverlapCircle(playerStats.rb.position, coverRange, wall); } if (Input.GetKey(playerStats.cover)) { if (nearestCover) // if the player is within range of valid cover based on coverRange and not in cover { coverPoint = Physics2D.ClosestPoint(playerStats.rb.position, nearestCover); // finds the closest point on the perimeter of the collider and stores it in coverPoint direction = new Vector2(playerStats.rb.position.x - coverPoint.x, playerStats.rb.position.y - coverPoint.y); // makes direction a vector pointing perp. away from the cover playerStats.rb.position = Physics2D.ClosestPoint(playerStats.rb.position, nearestCover); // moves the player to the edge of the cover playerStats.transform.up = direction; // makes the player face away from the cover if (!inCover) // if player is just entering cover { playerStats.maxSpeed = playerStats.maxSpeed * speedMultiplier; inCover = true; Debug.Log("Extents: " + nearestCover.bounds.extents); if (playerStats.transform.up == Vector3.up) { coverSide = 1; } else if (playerStats.transform.up == Vector3.right) { coverSide = 2; } else if (playerStats.transform.up == Vector3.down) { coverSide = 3; } else if (playerStats.transform.up == Vector3.left) { coverSide = 4; } else { coverSide = 0; } } if (coverSide == 1 || coverSide == 3) // if player is taking cover on the top or bottom of the cover { if (playerStats.rb.position.x < nearestCover.bounds.center.x) // the player is on the left half of the cover { distanceToCorner = playerStats.rb.position.x - nearestCover.bounds.min.x; if (distanceToCorner < cornerDistanceThreshold) // player is at left corner { atCoverCorner = true; whichCornerBool = false; } else { atCoverCorner = false; } } else if (playerStats.rb.position.x > nearestCover.bounds.center.x) // player is on the right half of the cover { distanceToCorner = playerStats.rb.position.x - nearestCover.bounds.max.x; if (distanceToCorner > 0 - cornerDistanceThreshold) // player is at right corner { atCoverCorner = true; whichCornerBool = true; } else { atCoverCorner = false; } } } else if (coverSide == 2 || coverSide == 4) // if the player is taking cover on the left or right of the cover { if (playerStats.rb.position.y < nearestCover.bounds.center.y) // player is in the bottom half of the cover { distanceToCorner = playerStats.rb.position.y - nearestCover.bounds.min.y; if (distanceToCorner < cornerDistanceThreshold) // player is at bottom corner { atCoverCorner = true; whichCornerBool = false; } else { atCoverCorner = false; } } else if (playerStats.rb.position.y > nearestCover.bounds.center.y) // player is in the top half of the cover { distanceToCorner = playerStats.rb.position.y - nearestCover.bounds.max.y; if (distanceToCorner > 0 - cornerDistanceThreshold) // player is at top corner { atCoverCorner = true; whichCornerBool = true; } else { atCoverCorner = false; } } } } } if (!Input.GetKey(playerStats.cover) && inCover == true) // if cover button isn't pressed, inCover = false { playerStats.maxSpeed = playerStats.maxSpeed / speedMultiplier; playerStats.rb.constraints = RigidbodyConstraints2D.None; inCover = false; atCoverCorner = false; playerStats.peeking = false; } }
///<summary>Returns the nearest point to the given target on the edge of this interactable's collider.</summary> public Vector2 GetClosestPoint(Vector2 target) { return(Physics2D.ClosestPoint(target, collider2D)); }