Hi, so i copied this script from stack overflow to help me move an object along a curve, when the game starts, the ball fires upwards and lands down on the target, could this possible be changed to fly along a sideways curve instead of an upward curve? I really have no idea how the math works. Or if someone knows a better way I could achieve a side curve? Or should I just use Lerp? Thank you in advance
public class BallisticLauncherTest : MonoBehaviour
{
public GameObject ballGameObject;
public Transform target;
// Use this for initialization
void Start()
{
ThrowBallAtTargetLocation(target.position, 10f);
}
// Throws ball at location with regards to gravity (assuming no obstacles in path) and initialVelocity (how hard to throw the ball)
public void ThrowBallAtTargetLocation(Vector3 targetLocation, float initialVelocity)
{
Vector3 direction = (targetLocation - transform.position).normalized;
float distance = Vector3.Distance(targetLocation, transform.position);
float firingElevationAngle = FiringElevationAngle(Physics.gravity.magnitude, distance, initialVelocity);
Vector3 elevation = Quaternion.AngleAxis(firingElevationAngle, transform.right) * transform.up;
float directionAngle = AngleBetweenAboutAxis(transform.forward, direction, transform.up);
Vector3 velocity = Quaternion.AngleAxis(directionAngle, transform.up) * elevation * initialVelocity;
// ballGameObject is object to be thrown
ballGameObject.rigidbody.AddForce(velocity, ForceMode.VelocityChange);
}
// Helper method to find angle between two points (v1 & v2) with respect to axis n
public static float AngleBetweenAboutAxis(Vector3 v1, Vector3 v2, Vector3 n)
{
return Mathf.Atan2(
Vector3.Dot(n, Vector3.Cross(v1, v2)),
Vector3.Dot(v1, v2)) * Mathf.Rad2Deg;
}
// Helper method to find angle of elevation (ballistic trajectory) required to reach distance with initialVelocity
// Does not take wind resistance into consideration.
private float FiringElevationAngle(float gravity, float distance, float initialVelocity)
{
float angle = 0.5f * Mathf.Asin((gravity * distance) / (initialVelocity * initialVelocity)) * Mathf.Rad2Deg;
return angle;
}
}
Since you’re asking for a “sideways” curve, I’ll assume the desired trajectory isn’t necessarily a result of a force like gravity but more of a cosmetic choice. If that’s the case, I have a slightly exotic proposition:
Interpolate the position of the object that should follow the curve between its start position and the end point of the curve, and to calculate how far the object should be offset perpendicular to the straight line you would get that way (i.e. the “elevation” in the vertical case), use an AnimationCurve. Make it a public / serialized field, then you get a nice little curve editor in the inspector to specify just how the curve should look. To get the offset value, use AnimationCurve.Evaluate(float time) and reuse the “time” parameter used for the interpolation (possibly normalized to range [0…1]). You can then add the resulting value multiplied by transform.right to the object’s position (that would offset it along its local “right” direction) each frame after the lerp.
Something like this:
Thank you for the info, I found a million curved shot tutorials that handle upward motion but couldnt really find a solution to a side curve that i can figure out so I’m giving up
Thank you for your help but I realised it was way too complicated for me so I have given up on the idea, I was looking at a free lerp asset that handled stuff for me, but I couldnt work that either so I’ll come back later down the line when I can understand this stuff better
When a thrown ball (as in baseball) curves, the net effect is essentially a tilted gravity vector.
While the main part of the gravity goes straight down, the aerodynamic “tilt” would be lateral according to the flight path of the ball, and obviously tons of other aerodynamic details that you probably don’t really care about in a game.
Here’s a quick functional example: download my MakeGeo project and then go into the Ballistic3D.cs file and replace its Update() method with this:
// REPLACE the existing Update() method in Ballistic3D.cs in my MakeGeo project
void Update ()
{
transform.position += velocity * Time.deltaTime;
velocity += gravity * Time.deltaTime;
// curveball example for @iamthebubb:
{
// calculate the "flat forward" speed
Vector3 forwardVelocity = velocity;
forwardVelocity.y = 0;
forwardVelocity.Normalize();
// rotate this vector 90 degrees to one side (negative is left)
Vector3 sidewardVelocity = Quaternion.Euler (0, -90, 0) * forwardVelocity;
// scale it by however strong we want the curve effect
sidewardVelocity *= 4.0f;
// add this curve acceleration into the velocity
velocity += sidewardVelocity * Time.deltaTime;
}
}