Making a character walk instead topples/flys away - c#

My character (I tried a bunch of types even cubes, but none seem to work) always topple or fly away, I have no idea what part of this code is wrong.
I tried changing the character, the physics, and restrictions (even restrict y-axis movement (both y-axis) and the character still flys away).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class walk : MonoBehaviour
{
private string MoveInputAxis = "Vertical";
private string TurnInputAxis = "Horizontal";
// rotation that occurs in angles per second holding down input
public float rotationRate = 360;
// units moved per second holding down move input
public float moveRate = 10;
private Rigidbody rb;
private void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
private void Update()
{
float moveAxis = Input.GetAxis(MoveInputAxis);
float turnAxis = Input.GetAxis(TurnInputAxis);
ApplyInput(moveAxis, turnAxis);
}
private void ApplyInput(float moveInput, float turnInput)
{
Move(moveInput);
Turn(turnInput);
}
private void Move(float input)
{
// Make sure to set drag high so the sliding effect is very minimal
// (5 drag is acceptable for now)
// mention this trash function automatically converts to local space
rb.AddForce(transform.forward * input * moveRate, ForceMode.Force);
}
private void Turn(float input)
{
transform.Rotate(0, input * rotationRate * Time.deltaTime, 0);
}
}
I expected it to turn with A and D and move with W and S, instead, it topples over and/or flys away.

Disable gravity (or freeze Y position), freeze rotation on all axes except Y (or whichever is your up axis), and ensure the collider is not spawning already in a collision with the ground (may be clipping when it spawns, causing it to shoot itself away).
Failing this, you could make the rigidbody kinematic, leaving gravity and collisions enabled, and use transform.Translate() to move your character isntead of rigidbody.AddForce()

Related

How do i assign left and right movement to my 2d game

So I'm new to Csharp, and I am working on this script for a game. It's a 2D game. Ive already assigned jump movement to the game, however, I'm stuck on fixing the movement along the x axis.
I'd really appreciate your help.
using UnityEngine;
// this code uses physics to make player jump
public class Movement2d : MonoBehaviour
{
private bool jumpKeyWasPressed;
private bool movementRight;
private CharacterController characterController;
private Rigidbody2D rigidbodyComponent;
private Vector3 moveSpeed;
// Start is called before the first frame update
void Start()
{
rigidbodyComponent = GetComponent<Rigidbody2D>();
characterController = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
//Check if space key is pressed down
if (Input.GetKeyDown(KeyCode.Space))
{
jumpKeyWasPressed = true;
}
if (Input.GetKeyDown(KeyCode.RightArrow))
{
movementRight = true;
}
}
private void FixedUpdate()
{
if (jumpKeyWasPressed)
{
//jump action assigned to space key
rigidbodyComponent.AddForce(new Vector2(0, 10), ForceMode2D.Impulse);
jumpKeyWasPressed = false;
}
if (movementRight)
{
//moving right assigned to right arrow
Rigidbody.MovePosition();
}
}
}
If you're using RigidBody.MovePosition, you'll want to move the player according to your speed and the time elapsed since the last frame (to account for frame stutters).
Assuming your horizontal speed is stored in the x-coordinate of your speed vector, you'll want to write:
rigidBodyComponent.MovePosition(new Vector2(moveSpeed.x * Time.deltaTime, 0));
To perform left movement, use the same code, but use -moveSpeed.x instead. In both cases, don't forget to set the movement bool to false afterwards.
Keep in mind, however, that using RigidBody.MovePosition could cause your character to go through walls at high speeds. Consider using RigidBody.AddForce() as you did for jumping if you want to avoid that.
Sources:
https://docs.unity3d.com/ScriptReference/Rigidbody2D.MovePosition.html
https://docs.unity3d.com/ScriptReference/Rigidbody2D.AddForce.html

How can I reduce my character from sliding?

using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed;
public float jump;
private Rigidbody2D rb;
private void Start()
{
rb = GetComponent<Rigidbody2D>();
}
private void Update()
{
rb.position += new Vector2(Input.GetAxis("Horizontal"), 0) * Time.deltaTime * speed;
if(Mathf.Abs(rb.velocity.y) < 0.001f && Input.GetKeyDown(KeyCode.W))
{
rb.AddForce(new Vector2(0, jump), ForceMode2D.Impulse);
}
}
So I have this code for my player movement. I am wondering how can I reduce my character from sliding that much. I don't want to stop instantly after I release the key.
You could add counter-movement to make the movement to feel more responsive, or you could change the friction by adding a physics material. Counter-movement makes the player stop by adding a force opposite to the wanted direction of the movement. It will stop the player from sliding too much. Another approach is to add a physics material and up the friction a bit. This will make the player stop faster. I hope you find this helpful!
Inside of the Input Manager, Edit->Project Settings->Input Manager, there is a property called gravity.
Gravity: Speed in units per second that the axis falls toward neutral when no input is present.
Decreasing this value will cause the input to fall quicker, resulting in less/no sliding.
You can debug your input value to confirm this. You should notice a ramp up from 0 to 1/-1 when you first hold the horizontal input. Once you let go of the input, you should see the value fall back down to 0.
var inputHorz = Input.GetAxis("Horizontal");
Debug.Log(inputHorz);
Lower the value until it feel correct. This can be changed while you are playing the game, but you will need to paste that value back in after pressing stop.

How to turn off inertia when player stops moving?

When I release the character control button, character itself continues to move for about half a second. I want the character to stop right after I release the control button. I’ve tried diffirent methods: AddForce and velocity, but it’s all in vain.
Also, I tried to adjust the mass and drag momentum in Inspector of the character, but it didn’t help.
public class CapsuleMovement : MonoBehaviour
{
Rigidbody rb;
Vector3 playerMovement;
[SerializeField] float speed = 50;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
ProccessCapsuleMovement();
}
void ProccessCapsuleMovement ()
{
playerMovement = new Vector3 (Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
playerMovement.Normalize();
rb.velocity = playerMovement * speed * Time.deltaTime;
}
}
Don't normalize! If the Input magnitude is actually smaller than 1 you still normalize it always to a magnitude 1!
Rather use Vector3.ClampMagnitude which only limits the magnitude in the upper bound but allows it to be smaller
The other point might be that GetAxis is actually "smoothed" and not applied immediately! After releasing the button it is actually decreased over time. So since you normalized the vector it keeps having a magnitude of 1 for a while after releasing the buttons.
You might rather want to use GetAxisRaw for this.
Then when assigning a velocity you do not want to multiply by Time.deltaTime! This only is needed where you want to convert a value from a fixed value per frame into a frame-rate-independent value per second. A velocity already is a vector per second so remove the * Time.deltaTime.
so something like e.g.
playerMovement = Vector3.ClampMagnitude(new Vector3 (Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")), 1f);
rb.velocity = playerMovement * speed;

My model does not stay constant when I try to make it levitate up/down

people of the stack overflow. I wanted to make a drone game for my personal project for school. Everything has been going well but I am facing a problem now. My script for my drone won't makes the drone stay at a constant height when I press the selected button. In other words when I press E or Q the drone goes continuously up or continuously down. I want it to go up as long as I am pressing the selected key. How would I do that?
code ->
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Levitating : MonoBehaviour
{
Rigidbody ourDrone;
private void Awake()
{
ourDrone = GetComponent<Rigidbody>();
}
// Make the drone default velocity the same value of the gravity acceleration, with opposite direction
private Vector3 DRONE_DEFAULT_VELOCITY = new Vector3(0, 9.81f, 0);
public float upForce;
private void Update()
{
MovementUpDown();
}
private void FixedUpdate()
{
ourDrone.AddRelativeForce(DRONE_DEFAULT_VELOCITY * upForce);
}
void MovementUpDown()
{
if (Input.GetKey(KeyCode.E))
{
upForce = 15;
}
else if (Input.GetKey(KeyCode.Q))
{
upForce = -3;
}
else
{
// Resetting the force muultiplier
upForce = 1;
}
}
}
The problem is that your physics are wrong.
In the default mode (upForce = 1) you're cancelling out gravity so no acceleration will be applied to your rb.
However, when you're pressing one of your control buttons, you're adding a force, and thus, per Newtons law, you're adding an acceleration, which will result in a velocity that will persist even after you've stopped pressing the button.
Now, I don't know exactly why you've modeled it as you have, but the easiest solution to your problem would be to disable gravity on your rigidbody and modify the velocity of the rb directly. Or use a different forceMode in your AddForce. https://docs.unity3d.com/ScriptReference/ForceMode.html use Velocity change.
If you want to model an actual drone, as one would in real life, you should look into control systems, such as PID, but that might be overkill.
Best of luck

Object kept falling as opposed to shooting trajectory (Unity)

everyone! I am new to Unity and try to create a 2D arcade game by allowing my character to jump up at a trajectory motion to reach something then fall down. I use gravity scale equal to 1 and move_speed 1000 and rest_speed 500 but as soon as I hit space, the character just fell down instead of going up.
Also, walk.IsWalk is an int from Walking class(as soon as I hit right arrow, set IsWalk to 2 for example). My expected result would be as soon as we hold both space and right arrow key, the character should move upwards follow a curved motion. I dont know what is going on here, can anyone kindly point me to a direction? Thanks!
My code as follows:
using UnityEngine;
using System.Collections;
public class Jumping : MonoBehaviour
{
Rigidbody2D rb2D;
Animator anim;
Walking walk = new Walking();
public float move_speed;
public float rest_speed;
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
//float xmove = Input.GetAxis("Horizontal");
//float ymove = Input.GetAxis("Vertical");
//var curr = new Vector2(xmove, ymove);
if (Input.GetKey("space"))
{
anim.SetTrigger("JumpButtonPres");
rb2D.gravityScale = 1;
if (walk.isWalk == 2)
{
rb2D.AddForce(rb2D.position * move_speed);
}
else if (walk.isWalk == 1)
{
//rb2D.velocity += (Vector2.up * (-rb2D.velocity.x));
rb2D.AddForce(-rb2D.position * move_speed);
}
else
{
rb2D.AddForce(rb2D.position * rest_speed);
}
}
}
}
partial code for rigidbody2D.AddForce
It seems your problem is that whenever you are adding force to your rigidbody, you are multiplying it by the position where it's located, so by this i'm guessing your character is placed at a negative y component coordenate, and this is why rb2D.position * rest_speed will result on your playing falling. Change it for vector2.up * rest_speed and you should be fine.
Hope I was able to help.
Noé

Categories