Eugh. Physics. For those not following I took a bit of a side turn to learn Unity and am doing some simple 2D projects to get my head around it, then some 3D, then back to Mega-Lo-Monger. Right now I'm doing a Breakout clone.
So I've had a bit of time doing other things but got back to it today, trying to get the damn game working. So I've got the basic objects to get the job done.
- A camera. It has an AudioListener.
- A single brick which I've not yet done any actual work on but it'll form the blueprint for other bricks once I'm happy with its behaviour.
- A bat which moves left and right with the mouse (a script attached simply runs camera.ScreenToWorldPoint(Input.mousePosition) to get the position and I apply it to the gameObject.transform.position). I also added some tools to change the bat size since I expect that to happen with power-ups. It has a sprite renderer which loads a 9-sliced sprite allowing for resizing without losing quality. It has a RigidBody2D. I have my suspicions that this is a bad idea.
- A ball. It has the most complex script. It has a RigidBody2D and a CircleCollider2D. Again I feel like the RigidBody2D may be a bad idea. The SpriteRenderer is simply rendering a ball.
Unity professionals would probably look at what I've done and call it shite, and they'd be right, but this is early learning shit code. I'll find more efficient ways to do things in due course. The ball was happily bouncing off the walls, and has now decided it no longer wishes to do so. The event triggers, it's in my logs, but though I change the ball's RigidBody2D's velocity it still keeps moving the exact same direction. This is a pain in the balls.
Now I'm avoiding tutorials to keep out of the trap of following people's code and learning nothing, so I've been googling questions when I have them (how to check what an object is colliding with, how to get the position on screen without things exploding when window size changes, etc). This means I'm making a lot of stupid mistakes, but they're useful as I'm learning from them.
My gut feeling is I've got this quite badly wrong. Breakout doesn't really have physics in a real sense. Objects don't have weight, so when they collide energy is not absorbed, the bat isn't moved when the ball rams into it for instance. The edges of the screen don't absorb the impact at all so the ball just bounces perfectly off it. The bricks will do the same. Real physics will try to split the energy between the collider and collided objects, which isn't what I want. So, google time.
Looked around at some tutorials as I concluded I've done this horribly wrong and came to realise everyone's using PhysicsMaterials which actually let you do some fairly unrealistic things with your physics objects. Not so far off after all. Turns out I've been scripting far too much of this behaviour too - I suspect my scripting is fighting with the physics and I need to do one or the other, not both. Ultimately I've carried LibGDX habits into Unity, as in Java I have to build everything, but Unity expects you to work with what it provides, and that's taking a little bit of getting used to.
Taking that physics approach I now have a ball bouncing around the screen in a fairly Breakout-y way, but I'm dissatisfied with how the deflections off the bat are handled. I want it to go different directions depending on where you hit the bat as in traditional breakout. I've seen an approach of a polygonal sloped collider but all that does is go left on the left and right on the right, with no nuance as to how far along you hit it. An oval collider would be lovely, sadly it looks like you can only have polygon, rectangle or circle colliders (and you can't distort the circle). A pill is available, it's not perfect, but for now it'll do so I can get on with more important things. No point getting bogged down.
Onwards and upwards.