Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using UnityEngine;
- using System.Collections;
- public class SimpleSteering : MonoBehaviour
- {
- Rigidbody2D rb2D;
- //Target we want to hit. Rigidbody2D because we can hit if it's moving.
- //Needs to be set or object will fly into nowhere.
- public Rigidbody2D target;
- //Force multiplier. We multiply force with magnitude of 1(normalized) to this.
- public float forcePower = 20f;
- //Limit of speed. See its comment in FixedUpdate().
- public float speedLimit = 5f;
- void Start()
- {
- rb2D = GetComponent<Rigidbody2D>();
- //Random speed at start.
- rb2D.velocity = new Vector2(Random.Range(-speedLimit, speedLimit), Random.Range(-speedLimit, speedLimit));
- }
- //Measures distance in clockwise and counterclockwise directions between angles in radians and returns smallest
- float ShortestAngleBetween(float anglestart, float anglefinish)
- {
- float counterClockwiseDistance, clockwiseDistance;//Counterclockwise
- if (anglefinish < anglestart)
- {
- clockwiseDistance = anglestart - anglefinish;
- counterClockwiseDistance = Mathf.PI * 2 - anglestart + anglefinish;
- }
- else {
- clockwiseDistance = Mathf.PI * 2 - anglefinish + anglestart;
- counterClockwiseDistance = anglefinish - anglestart;
- }
- if (counterClockwiseDistance < clockwiseDistance) return counterClockwiseDistance;
- else return -clockwiseDistance;
- }
- //Checks angle in radians between vectors. Positive is counterClockwise, negative is clockwise.
- float AngleBetweenVectors(Vector2 first, Vector2 second)
- {
- float ang1 = Mathf.Atan2(first.y, first.x), ang2 = Mathf.Atan2(second.y, second.x);
- return ShortestAngleBetween(ang1, ang2);
- }
- void FixedUpdate()
- {
- Vector2 targetPosition;
- //Target position with preemtion so that we can hit if it isn't stationary.
- if (rb2D.velocity.magnitude > 0.0001f)
- targetPosition = (target.position + target.velocity * (rb2D.position - target.position).magnitude / rb2D.velocity.magnitude);
- else//Division by zero case
- targetPosition = target.position;
- //Direction we want to fly
- Vector2 direction = targetPosition - rb2D.position;
- //Angle difference coefficient 30 here can be modified. Smaller means we rotate to needed angle aggressively
- float angleChangeMagnitude = AngleBetweenVectors(direction, rb2D.velocity) * Mathf.Rad2Deg / 30;
- //Force basis.
- Vector2 resultingForce = new Vector2(angleChangeMagnitude, 1);
- //We take force basis, normalize it and multiply by power.
- rb2D.AddRelativeForce(forcePower * resultingForce.normalized);
- //Rotate the object itself to face where it flies. -90 because we fly to Y, not X.
- rb2D.rotation = Mathf.Rad2Deg * Mathf.Atan2(rb2D.velocity.y, rb2D.velocity.x) - 90;
- //Speed limit. Without it, we will often miss as missile will go spiral and, won't have enough side force to rotate properly.
- //Can be solved by multiplying side force (angleChangeMagnitude) by value that depends on rb2D.velocity.magnitude.
- if (rb2D.velocity.magnitude > speedLimit)
- rb2D.velocity = rb2D.velocity.normalized * speedLimit;
- }
- //Note: for simplicity, collisions don't check if we hit another missile. That doesn't affect result much.
- public void OnCollisionEnter2D(Collision2D collision)//In case we don't use trigger collider
- {
- Debug.Log("Hit");
- Destroy(gameObject);
- }
- public void OnTriggerEnter2D(Collider2D collision)//In case we use trigger collider
- {
- Debug.Log("Hit");
- Destroy(gameObject);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement