if (playerController.ShootBall==true)
{
// Calculate the impact point relative to the paddle's center (-1 at bottom, 1 at top)
float hitPoint = (transform.position.y - collider.transform.position.y) / collider.bounds.size.y;
Vector3 newDirection = new Vector3(Mathf.Sign(ballRb.linearVelocity.x) * -1, hitPoint).normalized;
acceleration++;
ballRb.linearVelocity = ballRb.linearVelocity.normalized * (initialSpeed * acceleration);
}
This script is located in the ball script. When I press space bar, I make an instantiate and call this ball. What I want it to fly in the direction as illustrated in the picture below:
My problem is that the ball goes straight line and moves right or left when the player moves the paddle right, left as it is flying straight. However, I placed this code in another game object and placed that game object in the prefabs folder and I called this ball in the SpawnManager prefab global variable. So it should be a separate identity. Any advise?
Think maybe you are not exactly in the right forums to ask this question but its ok will try to solve it however in the right forums can be more faster answer.
So the use case
You instantinate an object/entity which is a ball
It does go nicely however on impact it goes straight.
What I think happening is : When ball hits the paddle it tries to move forward still and since there is collision it goes right or left straight cause of rigid body physics cannot move through collision since in your scripts new direction never applied to it.
ballRb.linearVelocity = ballRb.linearVelocity.normalized * (initialSpeed * acceleration); This running but impact and new direction not there.
So lets assume, you press a button in your managers and onInput you instantinate this ball prefab/entity which has a script like below.
public float initialSpeed = 20f;
public float acceleration = 1f;
private Rigidbody2D ballRb;
void Start()
{
// access rigid body , this can even have a validation not to crash if applied on an entity that doesnt have a rb.
ballRb = GetComponent<Rigidbody2D>();
// Launch immediately when instantiated it will be on tick once, you can random it or make it static
Vector3 launchDir = new Vector3(1f, Random.Range(-0.3f, 0.3f), 0f).normalized;
// Apply just start velocity since
// we do not apply acceleration yet
ballRb.linearVelocity = launchDir * initialSpeed ;
}
void FixedUpdate()
{
// Now we have a velocity on every tick can apply an acceleration if you like
Vector2 vel = ballRb.linearVelocity;
ballRb.linearVelocity = vel + vel.normalized * acceleration * Time.fixedDeltaTime;
}
// Bounce on paddle collision
void OnCollisionEnter2D(Collision2D collision)
{
// If we collided, you dont need to check tag on this case but better check
if (collision.gameObject.CompareTag("Paddle"))
{
float hitPoint = (transform.position.y - collision.transform.position.y)/ collision.collider.bounds.size.y;
Vector3 newDirection = new Vector3(Mathf.Sign(ballRb.linearVelocity.x) * -1f, hitPoint, 0f).normalized;
// Keep current speed but change direction, acceleration will do its job on update already
float currentSpeed = ballRb.linearVelocity.magnitude;
ballRb.linearVelocity = newDirection * currentSpeed;
}
}
and if you are not doing physics simulation but kinematic one you can
public float initialSpeed = 20f;
public float acceleration = 5f;
private Vector2 direction;
private float currentSpeed;
private Rigidbody2D ballRb;
void Start()
{
ballRb = GetComponent<Rigidbody2D>();
// Ensure body is not simulated but kinematic
ballRb.bodyType = RigidbodyType2D.Kinematic;
// Initial launch
direction = new Vector2(1f, Random.Range(-0.3f, 0.3f)).normalized;
currentSpeed = initialSpeed;
}
void FixedUpdate()
{
// Move manually, get current position, add a direction normalized scaled by speed and time
ballRb.MovePosition(ballRb.position + direction * currentSpeed * Time.fixedDeltaTime);
// we can apply an acceleration to our speed which will give a greater distance calculation on each upcoming tick
currentSpeed += acceleration * Time.fixedDeltaTime;
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Paddle"))
{
float hitPoint = (transform.position.y - collision.transform.position.y)
/ collision.collider.bounds.size.y;
direction = new Vector2(
-Mathf.Sign(direction.x),
hitPoint
).normalized;
}
}