Dev Log #9 - Collisions and Epic Battles

Unity uses state machines for controlling NPCs. I have two states on the enemy at the moment: if the player is a long way away then keep on your course, if the player is close the steer RIGHT AT IT!

That's not a very interesting bit of AI but it helps to test a whole range of things, including collision. Unity uses low poly collision meshes that are generated from your models automatically, which saved me a ton of work.

If two objects have physics components attached to them (called Rigidbody) then when mesh colliders intersect, it applies a physics force at a point, which not only pushes the object but applies torque too.

Before this update, I froze the pitch and roll rotations, so that when you turned at speed, the thing wouldn't tip over. Now I needed the self-righting force (I call buoyancy) because the collision looked weird. I started by turning it off to see what happened. Have a look at the first part of the video and you'll see the collision going, well, not so well.

I knew that I wanted to apply a torque pushing toward the world "Up". I experimented a lot (without reading docs, silly boy) with subtracting vectors and applying them as a torque but that's not how torque works. You pick an axis to rotate around (a 3D vector) and give that vector a magnitude and apply that as torque. The axis you rotate around is the cross product of the world "Up" and the Cloudship's actual "Up". Add some scaling factors to account for the game's internal time and how effective the balloons are (I call lift) and you have a disarmingly simple bit of code.

I buggered about with damping so that it would rock nicely under large collisions and that was it! I was well pleased with myself (second half of the video).

Shooting

I had a rudimentary shooting script worked out before. You instantiate a cannonball and give it "impulse" force. The cannonball has its own code to detect "colliding with the thing that didn't shoot me" and destroys itself if it does. It will apply damage too but that's for later.

I'm currently just shooting directly at the only enemy at 45 degrees elevation. It's super simple and means you need to keep your distance. When I do Cloudship building, then I want to be able to set where the canons are and the upgrades for the people living on it. That's a way off.

Two Cloudships facing off with cannonballs in mid-air!

It works for now. To apply the script to the enemy, I needed to produce some of the dirtiest code with fat, nasty if statements. It will all be stripped out but it exists for a while as a nasty pustule (I can't link to it yet as I didn't push the code up).

Next up

Taking damage, dying and a very simple menu system. Then, I could argue... it's a game.

Comments

Prysics question. Looking at the piccie the cannonballs are pretty big. Do they apply equal and opposite force to the cloudship?

...a gun is just an engine pointing at the enemy!

babychaos's picture

Ah, yes. The balls are big. Too big but easy to see for testing. And a bit cartoony. If they were small, I think it would be difficult to see where your aim is.

They don't have physics attached to them so would not produce a force... but they could as they are just game objects like anything else. I think that would be pretty cool: when you get hit by a ball, the Cloudship rocks back. Given that it's not a lot of work to do such things, I'll give it a go.

Thinking out loud - if I am going to reduce the number of cannonballs "in flight" at any given time then that would keep the number of physics calculations down, so adding physics to them shouldn't add too much process requirement.

brainwipe's picture

This morning I added health (it's just a number that decreases when a cannonball hits) and then Death for the Enemy.

DEATH TO THE ENEMY!

I hit another problem with one of the shortcuts I took: gravity. Until now, I had switched off movement in the vertical axis. As simple as ticking a box! However, I wanted the bad guy to slowly fall the ground when dead. In the future, I'll have the Cloudship break apart and then be harvested by the player but for now, I wanted it to sink. If I turned off "Freeze Y", then everything just falls to the ground!

So I needed to add a force in the buoyancy function. As I have physics turned on, I can just ask the engine for the direction and magnitude of gravity: Physics.gravity invert it, -Physics.gravity and then give it the mass of the Cloudship (which is on the physics component) -Physics.gravity * rigidBody.mass. The result of that (I call buoyancy force) gets applied to the rigid body physics component along with all the forces I put on it. THAT'S IT.

It may have taken me five minutes to find the Physics object but the joy is that the code I wrote - and have to maintain - is tiny and makes sense. To make the Cloudship fall from the sky, I set it to 0. To make it fall slower, set it to something between 0 and 1. This is all GCSE physics stuff.

You can see now that the Cloudships are at different heights. That's because I had collided earlier in this test before I started recording and that pushed the enemy up and the Cloudship down in a pleasing sort of way. I do want all of the Cloudships to sit at the same altitude for now, so I will add a multiplicative term into the buoyancy force that will take the difference between the altitude I set and the Cloudship's actual altitude. That should make the Cloudships gently return to the altitude.

You can also see from the video that the enemy is still sliding along the floor. That's a combination between the floor having no friction (solved by adding a Physics Material) and the wind still having an effect. I'm not doing harvesting yet so I think that I'll have it sink into the floor and fade out; ready to spawn another.

More thoughts

Working before anyone else has got up is really working for me. As long as I have a clear goal and a set time span then I can make some progress each morning. I've made quite a lot of progress, don't you agree?

Also, the programming isn't hard. It really isn't. The stuff I do during the day is so much easier. There's some learning about the UI and understanding how things fit together but that's not coding per se. You attach code to 3D objects and let the engine do as much as it can. Bloody clever. I'm glad I started this!

brainwipe's picture