I'm working on this tank game where you move a tank using the keyboard input and aiming its turret using the mouse input.
For the tank movement I use this code in the update method:
x = Input.GetAxis("Horizontal") * Time.deltaTime * rotationSpeed;
z = Input.GetAxis("Vertical") * Time.deltaTime * speed;
transform.Rotate(0, x, 0);
transform.Translate(0, 0, z);
But I get results similar to this video (even when locking the rotation of the axes):
https://streamable.com/tm33b
Is there anyway to prevent such irritability with the movement of the tank, also is there anyway to attach both the body and the turret of the tank while making each rotate independently, also the tank to climb the terrain appropriately.
I'm a beginner to unity, I'm sorry if my questions were obvious or easy. I will be so thankful if I get any direct solution to this.
Note that both Translate and Rotate have a last optional parameter Space relativeTo = Space.Self. This means by default always Space.Self is used:
If relativeTo is left out or set to Space.Self the movement is applied relative to the transform's local axes. (the x, y and z axes shown when selecting the object inside the Scene View.) If relativeTo is Space.World the movement is applied relative to the world coordinate system.
Your tank opject starts "flying" and "tilting" because you rotate and translate in its own local coordinates instead of world coordinates. You should instead use
transform.Rotate(0, x, 0, Space.World);
transform.Translate(0, 0, z, Space.World);
to perform the translate and rotate in workd space.
Related
I have a camera, it is attached to the capsule, and rotates independently of it.
But I need the capsule to rotate along the Y axis following the camera. How to get the Y-axis rotation values of the camera? Tried through transform.rotation.y. But it gives an error.
Transform.rotation returns a Quaternion (see also Wikipedia - Quaternion) - it has not 3 but 4 components x, y, z and w!
=> Unless you know exactly what you are doing - which is almost never the case ^^ - you do never want to touch any of its components directly.
Unfortunately also the Transform.eulerAngles are not really reliable for your use case.
So what I would do is rely on Vector3 instead.
// take camera's forward vector
private forward = yourCamera.transform.forward;
// erase the Y axis => vector is now only on the XZ plane rotating around Y
forward.y = 0;
// rotate the capsule so its forward vector aligns with "forward"
yourCapsule.transform.rotation = Quaternion.LookRotation(forward);
// could also do
//yourCapsule.transform.forward = forward;
see also Quaternion.LookRotation
I want to make my character jump by drawing lines.
But while my code is going towards the x-axis direction in 2D, when I switch to 3D, it always turns upwards regardless of the direction of the line. There is no change in the X-axis. My code is as follows:
if (other.gameObject.CompareTag("Line"))
{
rb.AddForce(Vector3.up * speed * Time.deltaTime, ForceMode.Impulse);
/ / Destroy(other.gameObject);
}
Could someone suggest how to correct my code?
Currently you're passing in Vector3.up as the force's direction, meaning that the character will always jump straight up.
If you want the character to jump in the line's direction, maybe try using the line's transform to send the player the right way, like this:
if (other.gameObject.CompareTag("Line"))
{
Vector3 jumpDir = other.gameObject.transform.up;
rb.AddForce(jumpDir * speed * Time.deltaTime, ForceMode.Impulse);
}
Now you'd need to point the "Line" GameObject in the direction you want the player to jump when they collide. (In the scene view, the Line transform's green arrow should be the character's jump direction)
You could switch it to the red or blue arrows (x or z axes) with
jumpDir = other.gameObject.transform.right;
or
jumpDir = other.gameObject.transform.forward; respectively.
You need to get the direction depending on the line you drew.
Depending on how you implemented your lines, you can get the directions from the transform via
Transform.up
Transform.forward
Transform.right
If you need the other directions, you can simply invert the Vectors.
Also you don't need to use Time.deltaTime while using rb.AddForce(), because the physic-system is taking care of it.
I'm playing with some Unity code to expand my horizons.
I have the following code, which launches a bullet from the character that flies in a direction set by 'this.angle' which is the angle the gun is pointing to the target.
What I'm trying to accomplish is to make the bullet leave the gun and travel 360 degrees right around and shoot the player (actually the gun really) from behind.
I'm not fully understanding quarternions, but I don't think I need to, to solve this.
Could someone please give me a pointer?
base.transform.rotation = Quaternion.Euler(0f, Mathf.MoveTowardsAngle(base.transform.rotation.eulerAngles.y, this.angle, 9.3f * Time.deltaTime), 0f);
Vector3 cposition = base.transform.position;
base.transform.position = Vector3.MoveTowards(base.transform.position, cposition, Time.deltaTime * 2f);
this.pos.set(base.transform.position);
this.rot.set(base.transform.rotation);
Okay so if you want to stick with your original idea, you could make it like this:
Code for the bullet
void Update(){
transform.Rotate(degTurnRate, 0, 0);
transform.position += transform.forward * Time.deltaTime * bulletSpeed
}
You can make the code much simple if you just use the Transform.RotateAround
this enables you to rotate the object around the specified targt for the x amount on any of the axes.
In Unity3D, I'm working on simply controlling a ball. My goals are as follows:
Allow the ball to rotate
Move in the direction the ball is facing
Ensure the ball is visually rotating as the ball is moving
What I am attempting to do is almost accomplished with this character controller script I wrote:
transform.Rotate (new Vector3(-Input.GetAxis ("Horizontal") * rotationSpeed, 0, 0));
Vector3 forward = Input.GetAxis ("Vertical") * transform.forward * moveSpeed;
controller.Move (forward);
controller.SimpleMove (Physics.gravity);
My problem with this script is that the ball does not visually "roll".
I attempted to solve this by using a Rigidbody:
float movementHorizontal = Input.GetAxis("Horizontal");
float movementVertical = Input.GetAxis("Vertical");
Vector3 movementVector = new Vector3(movementHorizontal, 0.0f, movementVertical);
GetComponent<Rigidbody>().AddForce(movementVector * moveSpeed * Time.deltaTime);
But in this case, you are unable to rotate anymore then 180 degrees using WAD like the first example. Although it does solve the visual problem.
How is it that I can allow my ball to rotate with the "A" and "D" keys, and then go in the direction the ball is facing with "W" while also visually rotating?
Take a look a this example:
http://unity3d.azurewebsites.net/Labyrinth/
move the ball with the arrow keys
move the camera with the keypad (#5 will chase)
zoom in/out with - + keys
change perspective with V key
The code behind the movement is here:
https://github.com/heldersepu/hs-unity/blob/master/Labyrinth/Assets/Movement.cs
Actually, i'm programming a little spaceshooter game (2.5D, Topdown View). The player can move along the XZ Axies and rotate the spaceship via right ministick (gamepad) or look to the cursor position (keyboard + mouse).
So, the movement and rotation (Y-Axies, Yaw) are seperated.
The whole thing works fine and looks good - but now i want to do the following:
If the spaceship moves sideways, it should rotate around the X / Pitch axies / lean left and right a bit, dependent on the sideways speed.
So, i have to compute the sideways speed from the following, given input:
Velocity Vector (Movement on X and Z Axies, Y is always '0')
Direction Vector (Rotation on Y Axies, X and Z are always '0')
And with the amount of sideways speed, i could rotate my spaceship around the X axies and multiply the resulting quaternion by the rotation around the y axies.
Anyone who has a solution for this?
Solution: Just "rotate" the velocity vector by the heading of the spaceship and use the "roll/z" axis as the sideways rotation about the X axis (the axis, where your ships nose points towards):
Quaternion Rotation = Quaternion.Euler(0, mHeading.y, 0);
Vector3 RealVeloctiy = Quaternion.Euler(0, -mHeading.y, 0) * Velocity;
float Angle = RealVeloctiy.z * 2.5f;
Rotation = Rotation * Quaternion.Euler(Angle, 0, 0);
A couple of possibilities:
Compare the velocity vector with local left direction of the spaceship (make sure they're in the same coordinate space first). You could use the Vector3.Angle function, or a dot product to do the comparison. Scale the result appropriately, and apply a local rotation around the forward axis.
Take user input directly. If the user is strafing in a direction, apply a roll value. You could use a float between -1 and +1, along with a rate of change. If they're strafing left, move the value towards -1 at that rate, or if they're strafing left, to +1. If neither key is being pressed, move the value back towards 0. (You might like to play around with the Lerp, SmoothStep and SmoothDamp functions too). Scale the value to apply an appropriate rotation about the relevant axis.