Reputation: 25
I decided I wanted to learn how to work with the unity2D engine, and started with trying to make pong. This was going pretty good, until I found a problem I couldn't find/didn't understand an answer for on google .
Every time the player/AI hits the ball, I make the ball go a little bit faster. This works fine until the ball goes pretty fast (still playable though) and just passes through the player/AI. I solved this by making the box collider of the player/AI really long, but at really high (and unplayable) speeds it still goes through.
My solution works, but isn't that pretty, and I wonder if there is a better solution for this (make the engine check more often for collisions?).
Here's the script for the ball movement (Javascript):
#pragma strict
var StartSpeed : int;
var speedFactor : float;
function Start () {
yield WaitForSeconds(2);
StartBall();
}
function ResetBall () {
GetComponent.<Rigidbody2D>().velocity.x = 0;
GetComponent.<Rigidbody2D>().velocity.y = 0;
transform.position.x = 0;
transform.position.y = 0;
yield WaitForSeconds(0.5);
StartBall();
}
function StartBall () {
var randomDirection = Random.Range(0f,1f);
var randomAngle = Random.Range(-Mathf.PI/4, Mathf.PI/4);
if(randomDirection < 0.5f){
GetComponent.<Rigidbody2D>().velocity.x = Mathf.Cos(randomAngle) * StartSpeed;
GetComponent.<Rigidbody2D>().velocity.y = Mathf.Sin(randomAngle) * StartSpeed;
}else{
GetComponent.<Rigidbody2D>().velocity.x = - Mathf.Cos(randomAngle) * StartSpeed;
GetComponent.<Rigidbody2D>().velocity.y = Mathf.Sin(randomAngle) * StartSpeed;
}
}
function OnCollisionEnter2D (colInfo : Collision2D) {
if(colInfo.collider.tag == "Player"){
GetComponent.<Rigidbody2D>().velocity.x = speedFactor * GetComponent.<Rigidbody2D>().velocity.x;
if(colInfo.collider.GetComponent.<Rigidbody2D>().velocity.y == 0){
GetComponent.<Rigidbody2D>().velocity.y = speedFactor * GetComponent.<Rigidbody2D>().velocity.y;
}
var vel = GetComponent.<Rigidbody2D>().velocity;
Debug.Log("Speed: " + vel);
}
}
Any other comments on the script that may improve it are welcome!
EDIT: I tried the following (as Andrew suggested):
function OnCollisionEnter2D (colInfo : Collision2D) {
if(colInfo.collider.tag == "Player"){
GetComponent.<Rigidbody2D>().AddForce( Vector2 (speedFactor * GetComponent.<Rigidbody2D>().velocity.x, speedFactor * GetComponent.<Rigidbody2D>().velocity.y));
var vel = GetComponent.<Rigidbody2D>().velocity;
Debug.Log("Speed: " + vel);
}
}
This still causes the problem I had before.
Upvotes: 0
Views: 937
Reputation: 1044
Update your RigidBody settings and set Collision Detection
to Continuous
(it will probably be set to discrete) and your high speed collision will work fine.
Upvotes: 1
Reputation: 679
Whole physics including collision detection runs on FixedUpdate, so to actually detect any collision colliders must collide when FixedUpdate is called. Let's say one collider isn't moving (wall for example) and another is going right at it, on current call of FixedUpdate collider that is moving is just before the wall, while on the next call of FixedUpdate collider that is moving has passed the wall, because that is it's position step per frame. Visually we see that colliders did collide, but they didn't collide on any call to FixedUpdate. Now, there are two solutions to this, lower the speed or lower the timestep of FixedUpdate ( http://docs.unity3d.com/Manual/class-TimeManager.html ), but this can be bad for framerate, it all depends what machines are you targeting and how hardware hungry your game is.
There is also this open source script which you should look at : http://wiki.unity3d.com/index.php?title=DontGoThroughThings#C.23_-_DontGoThroughThings.js
Upvotes: 0
Reputation: 8163
You shouldn't be messing with the velocity
directly, try just using AddForce()
instead.
Upvotes: 0