Object in a rotate loop in Unity - c#

I was making a function so that my object can turn around. So I made this function:
void Drehen(){
if(Input.GetAxis("Horizontal") > 0.1){
transform.Rotate(new Vector3(0f, 0f, 0f));
vorne = true;
}
if(Input.GetAxis("Horizontal") > -0.1){
transform.Rotate(new Vector3(0f, 180f, 0f));
vorne = false;
}
}
The function checks the input if the player goes forwards or backwards and rotates him in the direction via transform.Rotate(new Vector3(0f, 180f, 0f));
Now, every time I start the game I am able to go forward but as soon as I go backward it flips every side every frame.

Well that's pretty obvious.
Rotate rotates the object from the current rotation about the given amount so
transform.Rotate(0, 0, 0);
does absolutely nothing at all and in
transform.Rotate(0, 180, 0);
you rotate it by 180° every frame.
In the second condition you have > -0.1 which is the case all the time while you don't press the negative key.
It should probably rather be < 0.1f.
What you want is probably rather e.g.
var horizontal = Input.GetAxis("Horizontal");
if(horizontal > 0.1f)
{
// or localRotation depending on your needs
transform.rotation = Quaternion.identity;
vorne = true;
}
else if(horizontal < 0.1f)
{
transform.rotation = Quaternion.Euler(0f, 180f, 0f);
vorne = false;
}
Or actually as alternative you could also do
var horizontal = Input.GetAxis("Horizontal");
if(Mathf.Abs(horizontal) > 0.1f)
{
transform.forward = new Vector3(0, 0, horizontal);
}

Try using
transform.eulerAngles = new Vector3(0f, 180f, 0f);

Related

How can I make the player flip when it touches ground

I have a gravity thing and when they touch the ceiling I want the player to flip, my code doesn't work and I wonder if there is a better way to do this. I'd also like to know how to make the player not rotate to those exact coordinates and just where the player is already facing.
IEnumerator GravitySwitch()
{
if (Input.GetMouseButtonDown(1) && grounded)
{
Physics.gravity = new Vector3(0, 10.0f, 0);
yield return new WaitForSeconds(0.2f);
if (grounded)
transform.localEulerAngles = new Vector3(0, 0, 180);
}
if (Input.GetMouseButtonDown(0) && grounded)
{
Physics.gravity = new Vector3(0, -10.0f, 0);
yield return new WaitForSeconds(0.2f);
if (grounded)
transform.localEulerAngles = new Vector3(0, 0, 0);
}
}
You could multiply the scale of your player's scale vector by:
new Vector3(1, -1, 1);
can try
transform.Rotate(0.0f, 0.0f, 180.0f, Space.Self);
https://docs.unity3d.com/ScriptReference/Transform.Rotate.html

Why is my GetKeyUp not being detected in c#?

basically i am trying to move a character around so when i press W it goes forward but when i let go it doesn't stop(only once in a while). I am on Update void and not fixed Update.
private void Update()
{
if (controller.isGrounded)
{
if(Input.GetKey(KeyCode.W))
{
anim.SetInteger("condition", 1);
moveDir = new Vector3(0, 0, 1);
moveDir *= speed;
moveDir = transform.TransformDirection(moveDir);
}
if(Input.GetKeyUp (KeyCode.W))
{
anim.SetInteger("condition", 0);
moveDir = new Vector3(0, 0, 0);
}
}
rot += Input.GetAxis("Horizontal") * rotSpeed * Time.deltaTime;
transform.eulerAngles = new Vector3(0, rot, 0);
moveDir.y -= gravity * Time.deltaTime;
controller.Move (moveDir * Time.deltaTime);
}
}
Try looking at your animator and checking that Apply Root Motion is checked off.
Animator in Inspector
What root motion does is that it moves your character through the animation instead of through code. Here is a detailed explanation on root motion. What's root motion and how it works
I think I was able to recreate your issue and I was getting the same results. After I unchecked Apply Root Motion, my character stopped once I let go of "W".

Rotate player on z axis while walking

i'm currently in progress of a new game where my character has to move. While my character walks forward and i'm rotating it on the z axis, it just rotates instead of walking down the new z axis.
void Update()
{
{
if (Input.GetKeyDown(KeyCode.W))
{
anim.SetInteger("Condition", 1);
moveDir = new Vector3(0, 0, 1);
moveDir *= speed;
moveDir = transform.TransformDirection(moveDir);
}
if (Input.GetKeyUp(KeyCode.W))
{
anim.SetInteger("Condition", 0);
moveDir = new Vector3(0, 0, 0);
}
moveDir.y -= gravity * Time.deltaTime;
controller.Move(moveDir * Time.deltaTime);
}
rot += Input.GetAxisRaw("Horizontal") * rotSpeed * Time.deltaTime;
transform.eulerAngles = new Vector3(0, rot, 0);
}
}
I want to be able to walk forward while changing the z axis instead of walking then stop and then walk again.
You can't do that using a CharacterController because your call to controller.move() overwrites the rotation ... you need to write a custom move function.

How to make 2d sprite move in a smooth wide arc in the direction of keypress?

I'm working on a small experimental project in Unity. I have a 2d sprite that moves forward with a velocity but I want it to turn left or right in a wide arc and keep moving in that direction on keypress.
I've tried to tweak its angular velocity to get the desired affect. Looks unnatural and it won't stop rotating.
Tried Lerping. Looks unnatural as well.
Code Snippet 1:
bool forward = true;
Vector3 movement;
void FixedUpdate()
{
if (forward)
{
//Moves forward
movement = new Vector3(0.0f, 0.1f, 0.0f);
rb.velocity = movement * speed;
}
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
forward = false;
movement = new Vector3(-0.05f, 0.05f, 0.0f);
rb.velocity = movement * speed;
rb.angularVelocity = 30;
}
if (transform.rotation.z == 90)
{
movement = new Vector3(-0.1f, 0.0f, 0.0f);
rb.velocity = movement * speed;
rb.angularVelocity = 0;
}
}
Code Snippet 2:
void Update(){
if (Input.GetKeyDown(KeyCode.LeftArrow))
{
Vector3 target = transform.position + new Vector3(-0.5f, 0.5f, 0);
transform.position
=Vector3.Lerp(transform.position,target,Time.deltaTime);
transform.eulerAngles = Vector3.Lerp(transform.rotation.eulerAngles,
new Vector3(0, 0, 90), Time.deltaTime);
}
}
Can anyone point me in the right direction of what is the actual correct way to implement this?
Not entirely sure if this is what youre trying to accomplish but here's some pseudo code of what I came up with to get you started...
Essentially, when a direction is pressed, you want to increase the velocity in that direction until all of the velocity is pointed that way. At the same time you want to decrease the velocity in the direction you were previously going until it is zero.
This is a simplified formula however - if you truly wanted the velocity to be constant throughout the entirety of the arc you would have to use some geometry, knowing that V=(velX^2 + velY^2)^.5 but this would get you pretty close...
float yvel = 1f, xvel;
float t;
void Update()
{
GetComponent<Rigidbody2D>().velocity = new Vector2(xvel, yvel);
t += Time.deltaTime;
if (Input.GetKeyDown(KeyCode.D))
{
t = 0;
StartCoroutine(Move());
}
}
private IEnumerator Move()
{
while (t < 2) // at time t, yvel will be zero and xvel will be 1
{
yvel = 1 - .5f * t; // decrease velocity in old direction
xvel = .5f * t; // increase velocity in new direction
yield return null;
}
}

Moving the camera in the direction it is facing

I've followed a tutorial on how to make a first person camera rotate and move in a 3D world in XNA on the Microsoft website. But when I rotate the camera along it's Y axis, it doesn't move the direction it is rotated/facing, instead it moves as if it was facing the direction it was originally faced.
Here's my code:
static Vector3 avatarPosition = new Vector3(0, 0, 0);
static Vector3 cameraPosition = avatarPosition;
Vector3 cameraReference = new Vector3(10, 0, 0);
// Create a vector pointing the direction the camera is facing.
Matrix world = Matrix.CreateWorld(new Vector3(0, -1, 0), Vector3.Forward, Vector3.Up);
Matrix rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(0));
int Rot = 0;
Vector3 worldVector = new Vector3(5,-2, 0);
Matrix view, proj;
Vector3 cameraLookat;
Update()
{
world = Matrix.CreateWorld(worldVector, Vector3.Forward, Vector3.Up);
if (IsKeyDown(Keys.W))
avatarPosition += new Vector3(0.2f, 0f, 0);
if (IsKeyDown(Keys.S))
avatarPosition += new Vector3(-0.2f, 0f, 0);
if (IsKeyDown(Keys.A))
avatarPosition += new Vector3(0f, 0f, -0.2f);
if (IsKeyDown(Keys.D))
avatarPosition += new Vector3(0f, 0f, 0.2f);
if (IsKeyDown(Keys.Left))
Rot += 1;
if (IsKeyDown(Keys.Right))
Rot += -1;
rotationMatrix = Matrix.CreateRotationY(MathHelper.ToRadians(Rot));
// Create a vector pointing the direction the camera is facing.
Vector3 transformedReference = Vector3.Transform(cameraReference, rotationMatrix);
// Calculate the position the camera is looking at.
cameraLookat = transformedReference + cameraPosition;
// Set up the view matrix and projection matrix.
view = Matrix.CreateLookAt(cameraPosition, cameraLookat, new Vector3(0.0f, 1.0f, 0.0f));
proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), graphics.GraphicsDevice.Viewport.AspectRatio,
0.1f, 1000);
cameraPosition = avatarPosition;
}
Can someone please tell me why the camera does not travel the way it is rotated? Or can someone please just give me the damn code to make one?
I appears the problem you are experiencing is coming from this area of the code:
if (IsKeyDown(Keys.W))
avatarPosition += new Vector3(0.2f, 0f, 0);
if (IsKeyDown(Keys.S))
avatarPosition += new Vector3(-0.2f, 0f, 0);
if (IsKeyDown(Keys.A))
avatarPosition += new Vector3(0f, 0f, -0.2f);
if (IsKeyDown(Keys.D))
avatarPosition += new Vector3(0f, 0f, 0.2f);
Instead of translating the avatarPosition directly along the x or z axis, it should be using the direction you're pointing which appears to be your transformedReference variable.
For instance, to move forward the way the camera is facing:
if (IsKeyDown(Keys.W))
avatarPosition += transformedReference;
However, since the transformedReference variable appears to be normalized, it may not move the avatar the distance you'd hoped. In that case simply multiply it by some constant MOVEMENT_SPEED for something like such:
if (IsKeyDown(Keys.W))
avatarPosition += transformedReference * MOVEMENT_SPEED;

Categories

Resources