Hello, I’ve been trying to learn the basics of Javascript for a while, but I’m finding it impossibly difficult. I have decided to make a little tank game to try get the hang of it, and I need some assistance.
Here are some screenshots of my little project:
The green tank is the players tank, the camera is in a fixed position. My first task is to make the tank move around how I want it.
This is my script:
var speed : float = 0.3;
var rotSpeed : float = 100;
function Update ()
{
var x = Input.GetAxis("Horizontal") * Time.deltaTime * rotSpeed;
var z = Input.GetAxis("Vertical") * Time.deltaTime * speed;
transform.Translate(0,0,z);
transform.Rotate(0,x,0);
}
This moves the tank, and I can turn it. There are issues that will be obvious to some, for example, I cannot control the acceleration/de-acceleration. Also when it collides with objects, it bumps erratically, I assume this is because I’m adding constant movement to the object.
My question is, what is the most appropriate method for my tank control? Should I be adding force to the rigidbody to move it instead? How can I stop this erratic bumping behaviour, and how can I control acceleration?
I am a very visual learner, I learn by doing, I’ve tried over and over following written and visual tutorials but nothing seems to click. I hope that by asking here I will be able to follow the process more clearly and be able to break down what is going on.
As you can see as I demonstrate, colliding with walls and other objects with my tank causes erratic and undesired movement. I would rather handle the Tanks movement by applying force to the rigidbody. The problem is my knowledge is very limited, I have no idea how to approach it and it feels very daunting. I have tried reworking scripts from tutorials I have followed, yet I end up with undesired results.
I would like the movement of the tank to be almost as you see in the video, but with more refined and smooth handling of collisions. Any assistance in helping me get over this hurdle is most appreciated .
Have you considered using a Physic Material on the tank? I’ve tried to resolve this kind of issue before using a Physic Material with zero friction. Have a fiddle by creating a new Physic Material in your project and applying that to the physic material slot on your tank’s collider. Also check up the docs for them, Physics Material.
Also let me say your project is looking great, tank tracks are perfect! Can I ask, did you bake a lightmap to the environment?
Cool project maybe something like this is what you want? How do you wish for the tank to react when it hits a wall? just stop? turn to a good direction?
var speed : float = 0.3;
var rotSpeed : float = 100;
function Update ()
{
var x = Input.GetAxis("Horizontal") * Time.deltaTime * rotSpeed;
var z = Input.GetAxis("Vertical") * Time.deltaTime * speed;
rigidbody.AddRelativeForce(0,0,z);
transform.Rotate(0,x,0);
}
Alastair - I had a play around with Physic Materials, but I still didn’t manage to get a less erratic behaviour. Thank you for your kind comments, I just used some of the cube primitives and then baked a lightmap
Tyler - thank you for taking the time to help me! The issue I have using this script is that at 500 speed, the tank wont move a pixel, but if I bump that to 1000, the tank zooms around really fast. It also has a tendency to flip over face first driving into the ground mas soon as I push forwards. I tried using the ‘Ice’ physic material, but of course this makes it behave like its … well, on Ice. It also gets faster and faster with no max speed.
This seemingly simple movement I’m after seems so hard to create! Really I’d like it to behave just as it does with my current movement script, moving the transform, but to use physics instead, that way colliding with objects should look a bit cleaner. Id also like to be able to specific how fast it accelerates.
let me show you the game I’ve been influenced by :
Notice how fast the players Tank starts and stops, I’m not after a clone of this system but something similar and a bit more fluid so it doesn’t feel as static.
Bigmisterb - Sorry I didn’t see your message there, let me give that a try now!
Edit : Ok gave it a try, similar issue to the script Tyler suggested, no movement unless I uncheck gravity or use an Ice material. Also whilst moving forward or backwards, it won’t let me turn at the same time.
Give each tank 4 wheels and control them much like I have in my example. The difference is that you wouldnt be adding force to the tank, but simply rotation to the wheel.
If you pressed left or right, then the wheels would all be angled 45 degrees so that you can rotate.
If you press move and turn, then all teh wheels turn to 45 degrees in a turn.
forward or back you simply make them straight.
If you don’t press anything, add alot of brake to the wheels so that the tank stops.
You could Lerp the wheel angles so that they are not as overt. I think that would be nice. Physics is always a little hard when you make mathematical changes.
A standard wheel with no adjustment cannot slip sideways. So yes, this would be a decent approach to it. All the wheels cocked 45 degrees in a circle has no choice but to make the tank spin. So yeah, it will operate very similar.
You are, however, not building a tank, but a game based off of what they would do.
I may take some time this weekend to play with this idea. A very neat concept. I may even merge a couple of other projects together and see if I can make a game around it. (think this, minecraft and dungeon keeper) Oh yeah… lol
Oh, no, way too advanced for what you are doing. A full vehicle contoller is overkill for this. You dont want things to be springy, you want them sold.
You can do the whole thing by “sliding” the tank accross the ground. All you have to do is set all the physics materials to have no friction. (everything, not just the tank)
I achieved the results in my demo by this, setting the rotation mathematically (transform.Rotate()) and using rigidbody.velocity to just set the speed.
Forgive me for asking, but where do you think I should start then? When I look at the code you posted my head spins, if a full vehicle controller is overkill as you say, just how simple should this be? I’m trying to take baby steps here, its painful to think people can do this sort of stuff in less than an hour, when its taken me weeks to get to the point I’m at now!
Excellent, Bigmisterb this works perfectly. I altered it ever so slightly to get similar rotation to my original script, reversing and rotating felt weird, something was going on which I couldn’t put my finger on.
var speed : float = 3;
var rotSpeed : float = 100;
function Update () {
var move:float = Input.GetAxis("Vertical");
var x = Input.GetAxis("Horizontal") * Time.deltaTime * rotSpeed;
transform.Rotate(0,x,0);
//rot = move < 0 ? -rot : rot;
//transform.Rotate(0,rot * Time.deltaTime * 100, 0);
rigidbody.velocity = transform.forward * move * speed;
}
But I’d like to understand some things in this script. What was this line of code doing? the ‘?’ threw me off a little :
rot = move < 0 ? -rot : rot;
And as for the bullet ricochet, I have the temptation to ask you to post it, but because I’m trying to treat this as a learning project, could you give me some clues or hints as to how you achieved it?
Still a little confused as to what it was actually doing, but there are bigger fish to fry!
So this movement I have in place now is pretty much perfect, I just have to make sure it plays my movement sound. Could I do this by saying something like ‘if moving faster than 0.5 - play the sound’ ?
Now as for these bullets, my bullets use physics, and have a rigidbody attached. My script looks like this:
//speed of bullet
var speed :float = 15;
function Update () {
// move forward
transform.Translate(0,0,speed*Time.deltaTime);
}
var hitSound : AudioClip;
function OnCollisionEnter(theCollision : Collision){
Destroy(gameObject);
AudioSource.PlayClipAtPoint(hitSound, transform.position);
}
function OnTriggerEnter(theCollision : Collider){
if(theCollision.gameObject.name == "TankBase"){
Physics.IgnoreCollision(theCollision.collider, collider);
}
else{
Destroy(gameObject);
AudioSource.PlayClipAtPoint(hitSound, transform.position);
}
}
This is probably really messy, but it works and I’m proud that I actually wrote it. Would this ‘Reflect’ function still work as it does with yours? Or should I adopt a new bullet system with this ‘Linecast’?
Thank you, I really appreciate you taking the time to help me