AddForce to local transform - c#

I'm currently trying to make a game to put my relatively new coding knowledge to test. I figured I learn a lot quicker by just doing things and seeing what happens. I'm currently working on a plane and the last couple of days I made a functional camera system (to rotate around the player based on the mouse) and some animations of the plane. I'm currently trying to create a movement system in which the down key rotates the player up. I noticed however that my AddForce function doesn't do what I want it to do. I'd like the plane to move in the Z axis depending on the current rotation of said plane instead of it just heading into the Z angle of the world.
I'm currently working on this snippet:
//Acceleration
if (gameObject.CompareTag("Player") && playerRb.velocity.z > -349)
{
playerRb.AddRelativeForce(0, 0, -playerSpeed, ForceMode.Acceleration);
}
else if (gameObject.CompareTag("Player") && playerRb.velocity.z < -349)
{
playerRb.velocity = new Vector3(playerRb.velocity.x, playerRb.velocity.y, -350);
}
//
//Movement
//Up/down controls
if (gameObject.CompareTag("Player") && Input.GetKey(KeyCode.DownArrow))
{
transform.Rotate((0.07f * playerSpeed) * Time.deltaTime, 0, 0);
}
As you can see I already tried AddRelativeForce as another topic mentioned but that doesn't seem to work for me. The moment it hits an edge it just falls down into the abyss regardless of it's rotation.
Additionally, I was considering using another AddForce function on the rotate as it doesn't leave the ground (considering it keeps hitting the floor with its tail), is there any way to apply a force on an object from a specific position/angle? (such as the front of the plane).
Thanks in advance!

I think the reason your plane is acting strange is not because of your addrelative force call -- it's because you are setting velocity. playerRb.velocity = new Vector3(playerRb.velocity.x, playerRb.velocity.y, -350); assigns the velocity to push you -350 in the world's z axis, which probably isn't what you want. Velocity is in the global space. Remove that and see what happens.
On a more general note, If you're using physics, try to use only forces and torquees. Using transform.Rotate to change a rigidbody's rotation while physics is active will just make your life difficult, and make the rigidbody do strange things. I do change the velocity of rigidbodies sometimes, but not in every frame. I just don't know enough about physics to mess with velocities that way.
Also, make sure you're doing these things in a FixedUpdate function, since that is where input that affects physics is supposed to be checked.

Related

Unity 3D rotating a game object with the left stick causes object to Jitter back and forth

So I'm trying to make a third person controller that uses the PS4 controller with the left stick controlling the rotation and movement and the right stick controlling the camera separately. my problem right now is that when I apply this script to my game object it causes the player to Jitter back and forth. Any thoughts as to why or how I can fix it thanks.
void Update ()
{
//Defaults to the left Stick
float hAxis = Input.GetAxis("Horizontal");
float vAxis = Input.GetAxis("Vertical");
Vector3 NextDir = new Vector3(hAxis, 0, vAxis);
if (NextDir != Vector3.zero)
{
transform.rotation = Quaternion.LookRotation(NextDir); //this rotates the character correclty but causes jitter
transform.Translate(NextDir.x * Time.deltaTime * 5, NextDir.y * Time.deltaTime * 5, NextDir.z * Time.deltaTime * 5, Space.Self);
}
}
}
Perhaps the "jitter" you see is the game code accurately rotating the object according to the data it is getting from the joystick. I am guessing that by "jitter" you mean the rotation is bouncing back and forth between clockwise and counter-clockwise sporadically, when you think that you are smoothly rotating the joystick in one direction (clockwise or counter-clockwise). (If not, please describe the jitter.)
If this is the case, since you are reading the joystick at every frame, the joystick is probably picking up values that cause the vector to bounce back and forth. So, try adding a tolerance and only taking action if the vector changes by a certain amount. Or, only accept vectors that cause the rotation to continue in the same direction (CW or CCW) as the previous frame, unless the change is more than some certain amount, which would indicate that the player really does want to start turning back in the other direction.
Try increasing the value of the dead property in the horizontal and vertical axis. This should mean the joystick has to be moved further out of it's resting position before reporting a value.
It's located in Edit->Project Settings->Input modify the value for the second occurrences of those two properties ( the first two are for the keyboard )

most efficient way to get a very smooth player movement in unity5

So I am making a simple 2d endless mobile game. In the game, the player object (spaceship) moves upwards continuously and then the player can use either left or right to move the player to avoid obstacles.
As a newbie I am finding it very difficult to achieve a very smooth motion in the player movement. I have watched many tutorials including the unity official tutorials about moving an object. They all use simple techniques like:
rigidbody.velocity = (new Vector2 (0.0f, 1.0f)) * speed in the fixedupdate function
or transform.Translate (velocity * Time.deltaTime * speed) in the update function
or rigidBody.MovePosition (rigidbody.position + velocity * Time.fixedDeltaTime) in the fixed update or
just just changing the transform.position over time in the update function.
But none of these techniques or code that I have used have helped me to achieve that very smooth motion in the player movement that I want. No matter what I try I still get lags in the player movement. I have also tried switching the rigidbody.iskinematic on and of and changing the rigidbody interpolation but I am still not able to achieve a smooth movement in in 2d games that we see such as ios games shredd or split the dot. I thought that it might be my computer that was very slow or something that is why I am not getting a smooth movement but I transported my project onto my friends computer which is twice as fast and I still have the same results. I also striped all that decided to erase all the code that is in the player controller scripts and just focus on the code for moving the player but the results has not changed.
I am thinking that it is because I am just using a very simple and inefficient code to move the player or it might have something to do with changing some settings in unity. So the question is what is the most efficient way to achieve a very smooth player movement in unity. (Codebase and unity settings.)
Currently I am just using rigidbody.velocity = (new Vector2 (0.0f, 1.0f)) * speed to move the player and I have made the camera a child object of the player for simplicity.
Thank you.
I would use Vector3.Lerp to interpolate the transform.position. This essentially mathematically smooths out the translation between the two positions.
Something else I've experienced is that the editor is sometimes more laggy than the end product, so I recommend building the game and testing it out to see if that is the case.
Finally, if you are using transform.position to move the object, ensure that the numbers are fairly small. Big numbers obviously make the object jump around a lot more.

How can I make a gameObject rotate while jumping, then once it collides with another gameObject, return smoothly to its original rotation?

How can I make a gameObject rotate while jumping "in the air", then once it collides with another gameObject, return smoothly to its original rotation like shown in the following video: https://youtu.be/iOV0Apuwj94
I do not want the cube to abruptly return to its original rotation once it has collided with something. Like in the video, the cube's rotation is just right when it collides (when it hits the ground, it feels natural). I also want the cube to know where the future collision is, so that it can modify speed, rotation etc. depending on the positions of each gameObject (this way, the rotation would be always correct too).
I have tried many times fine tuning the rotation, but I always fail to get it just right (+predicting future collisions is unknown to me). I do not have the experience to accomplish such a task and searching the Web did not help either. I would appreciate any lines of code, guidance or help from the community. Thank you for your answers.
Here is a pseudocode I can think of which might work for you:
while(cube.y> 0)//or greater than the right value of y
{
if(cube.y= 0)//or the right value of y
{//stop performing rotation}
//perform rotation
}
This might just solve all your problems, since you are using a RigidBody for the cube which has a collider and it should automatically align to the ground due to gravity, in my opinion, making it feel even more natural.

(Unity) Issue with rotation when transform.up is aligning to a direction

I am testing out some ideas in Unity where a player can walk around a circle while staying on it (so the circle has its own gravity) and also being oriented properly. This game is currently being done in 2D, so all objects are sprites.
I do hope I can explain myself properly. Please ask if you need any further clarification...
It appeared that I succeeded with my idea until I noticed something odd.
So as expected, the player moves around the circle without falling off (custom gravity worked just fine) and its Z rotation is affected as it aligns itself with a direction:
// Align code:
// We reverse the direction so the object is standing up the right way.
private void Update()
{
transform.up = -(planet.position - transform.position);
}
It works... mostly. However, when the player object's rotation Z naturally reaches 180, it appears to flip horizontally (like a mirror effect) and then it returns to normal as rotation Z leaves 180. The visual flip happens because for some reason the object's Y becomes 180 at the same time too. At no other point does X or Y change in regards to rotation. Only Z. So the moment Z hits 180, Y is affected and the moment we leave Z 180, Y returns to 0.
I'm happy to provide a quick video of it happening in-game if anybody needs some visual understanding of what's going on.
The visibility of this bug tends to rely on how fast you're moving around the circle. If you're moving fast enough, you can probably skip over 180 and not see it happen at all, however if you move slow enough there's no denying it's there. It's also problematic for the fact that I simply make the camera a child of the player so when the player flips, so does the camera causing the entire scene to flip which can look extremely glitchy for a player to see.
I really have no idea how to tackle this issue as I have no clue why it would do such a thing. At every other rotation value it behaves just fine. It's only at Z = 180 (so the object is exactly upside down) does it decide to rotate in the wrong ways.
EDIT: Changed tag to Unity3D
It's probably because of converting quaternions (which is what's actually used internally for rotations) to euler angles for display. Can you try to use Quaternion.Slerp to rotate?

Unity v. 4: Rotation Causing Jumping

I have a very simple model for a plane that can move around in the x and y directions, while an ocean scrolls by to make it look as though the plane is flying. Whenever the plane moves, I adjust its roll and pitch.
I compute and maintain the position, roll and pitch, inside the object script. Every update step I re-assign them to the Unity properties of the object.
The problem comes where I tried to add a barrel-roll effect. This code works fine:
transform.Translate(position - transform.position);
Vector3 rotChange = new Vector3 (-pitch, 0, -roll) -
transform.rotation.eulerAngles;
transform.Rotate (rotChange);
So long as I'm keeping all the rotation within +- 30 degrees. When the plane is doing a barrel roll, it updates each step with the following:
velocity = new Vector3 (barrelRollDirections.x * barrelRollXSpeed,
barrelRollDirections.y * barrelRollYSpeed, 0);
roll += barrelRollTurnSpeed * Time.deltaTime;
if (roll < -(fullRotation/2)) {
roll += fullRotation;
}
if (roll > (fullRotation/2)) {
roll -= fullRotation;
}
The funny thing is that spinning the plane around actually works properly if the plane isn't moving along the x or y axis when I do it. But if it is, it jumps all over the place and only reappears in the proper final position once the roll is over.
I tried a number of ways to fix this problem:
-Convert my desired orientation to a quaternion using Quaternion.Euler and assigning that directly to transform.rotate. This didn't solve anything, and it also causes the plane to jitter and shake while at the bounds of its movement.
-Save the initial orientation of the plane in a quaternion, then, every update step, reassign that initial rotation to the plane and THEN call Transform.Rotate(new Vector3(-pitch,0,-roll)). I thought this would solve my problem if it was something like gimbal lock, since then I would just, every step, be applying rotations that were less than 180 degrees. But no dice.
EDIT: I found it! After asking this question, I figured I'd go work on different objects since I was waiting for an answer. There I discovered that the transform.Translate function moves objects in a different direction based on their rotation. When I changed to simply reassigning the position, it worked fine. As per usual, the act of talking to someone else helped to resolve the issue.

Categories