2D Toolkit Forum

2D Toolkit => Support => Topic started by: ricke on June 07, 2016, 06:55:59 pm

Title: Kinematic Physics, Breakout, and the death of my sanity
Post by: ricke on June 07, 2016, 06:55:59 pm
Hi there.  I'm still new to Unity and 2D Toolkit and have been spending a lot of my time the past few weeks trying to learn all that I can.  Partly as a learning exercise and partly because I thought it would be fun, I'm trying to roll over an old version of a breakout clone that I made several years ago.  As ball mechanics are key in such a game, I have been focusing my beginning efforts on getting those nailed down tight.  And despite my best efforts, Unity has been laughing at my pitiful attempts to make it work and feasting on my soul in the process. :o  So I thought I'd see if anyone here has some ideas on what I could be doing wrong.  I'm not sure if this is a problem with 2D Toolkit, Unity, or me... but I thought I'd start here.  :)

Just some background to begin on my project structure (I didn't list all components on my game objects, only the ones I thought pertinent to the issue):

With that said, my problem lies in my collision checking in the BallController script.  Observation of the game play at this point shows the collisions working, but inconsistently (and strangely so).  My goal has been to do a simple reflection of the ball, whether on a boundary or a brick... in other words, I reverse the x / y axis of the ball appropriately based on what collided with the ball.  The boundaries are straightforward in this regard, but the bricks are giving me fits. 

I'm trying to use a RaycastHit2D to determine my collision point and reflect the ball properly, but for the life of me I can't get it operate consistently.  The ball will perform several collisions flawlessly, even tightly packed collisions between bricks.  Then boom... the ball just decides to continue right through a brick like nothing happened.  My debugging seems to indicate the collision occurs but it doesn't change direction.  Next time... it reflects off the same brick just fine, but will pass through a different brick later on.  Rinse and repeat.

Here's my BallController code for reference.  Perhaps another set of eyes will catch something I'm missing or perhaps something I'm doing wrong.  Any help would be greatly appreciated.

Code: [Select]
using UnityEngine;
using System.Collections;

public class BallController : MonoBehaviour
{
    private GameController _gameController;
    private Rigidbody2D _rb;
    private CircleCollider2D _collider;
    private tk2dCamera _camera;
    private bool _keepAlive;

    // Use this for initialization
    void Start()
    {
        // HACK: Keep the balls on the board for now
        _keepAlive = true;

        // Get a reference to the game controller script
        _gameController = GameObject.FindGameObjectWithTag("GameController").GetComponent<GameController>();

        // Get a reference to the rigid body for the ball
        _rb = GetComponent<Rigidbody2D>();

        _collider = GetComponent<CircleCollider2D>();

        //Get a reference to the camera
        _camera = FindObjectOfType<tk2dCamera>();

        Debug.Log(string.Format("Spinning up new ball -- Position: {0},{1}  Velocity: {2},{3}", transform.position.x, transform.position.y, _rb.velocity.x, _rb.velocity.y));
    }

    void OnTriggerEnter2D(Collider2D other)
    {
        Debug.Log(string.Format("Before Collision: {0},{1}", _rb.velocity.x, _rb.velocity.y));

        if (other.gameObject.CompareTag("PointBrick"))
        {
            RaycastHit2D hit = Physics2D.Raycast(new Vector2(transform.position.x, transform.position.y), _rb.velocity, 50.0f, LayerMask.GetMask("Default"));
            if (hit.collider != null)
            {
                Debug.Log(string.Format("Hit -- Brick Transform: {0},{1}  Ball Transform: {2},{3}  Collision Point: {4},{5}", hit.transform.position.x, hit.transform.position.y, transform.position.x, transform.position.y, hit.point.x, hit.point.y));
                Debug.Log(string.Format("Brick Bounds -- Min: {0},{1}  Max: {2},{3}  Center: {4},{5}",
                    hit.collider.bounds.min.x, hit.collider.bounds.min.y, hit.collider.bounds.max.x,
                    hit.collider.bounds.max.y, hit.collider.bounds.center.x, hit.collider.bounds.center.y));

                if (hit.point.x <= hit.collider.bounds.min.x || hit.point.x >= hit.collider.bounds.max.x)
                    _rb.velocity = new Vector2(-_rb.velocity.x, _rb.velocity.y);
                else if (hit.point.y <= hit.collider.bounds.min.y || hit.point.y >= hit.collider.bounds.max.y)
                    _rb.velocity = new Vector2(_rb.velocity.x, -_rb.velocity.y);
            }
        }
        else if (other.gameObject.CompareTag("BoundaryLeft") || other.gameObject.CompareTag("BoundaryRight"))
            _rb.velocity = new Vector2(-_rb.velocity.x, _rb.velocity.y);

        else if (other.gameObject.CompareTag("BoundaryTop"))
            _rb.velocity = new Vector2(_rb.velocity.x, -_rb.velocity.y);

        else if (other.gameObject.CompareTag("BoundaryBottom") && _keepAlive)
            _rb.velocity = new Vector2(_rb.velocity.x, -_rb.velocity.y);

        else if (other.gameObject.CompareTag("Player"))
            _rb.velocity = new Vector2(_rb.velocity.x, -_rb.velocity.y);

        Debug.Log(string.Format("After Collision: {0},{1}", _rb.velocity.x, _rb.velocity.y));
    }
}
Title: Re: Kinematic Physics, Breakout, and the death of my sanity
Post by: ricke on June 10, 2016, 03:19:58 pm
While I'd still be very interested in knowing why this scenario doesn't work properly (as it would be educational for understanding kinematic scenarios), I've changed my direction on the game structure and have embraced the non-kinematic physics approach with 2D physics materials.  This solved all the collision issues I was having and with minimum effort... easily enough that I was frustrated to have spent so much time trying to get the kinematic approach working.  Oh well, I've learned some things in the process that I otherwise wouldn't have learned without the effort.  :)