This is the script, it's a simple horizontal movement script.
private Rigidbody2D rb;
public float speed;
private float moveHori;
void Start()
{
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
moveHori = Input.GetAxisRaw("Horizontal");
}
void FixedUpdate()
{
rb.velocity = new Vector2(moveHori * speed, 0) * Time.deltaTime;
}
I don't know why is the gravity slowing down.
because you set the Y component of the velocity to 0 in
rb.velocity = new Vector2(moveHori * speed, 0) * Time.deltaTime;
rather keep your current Y velocity like
rb.velocity = new Vector2(moveHori * speed, rb.velocity.y);
Note btw that a velocity is framerate independent and you do not want to multiply by Time.deltaTime here! Rather adjust your speed so it is the desired Unity units per seconds.
Related
I'm working on a 2D game in Unity attempting to make my player jump. Despite watching tons of videos and adjusting the code many times, he simply won't jump when I press the space bar. After even checking the input manager in Unity, I'm sure it's a simple fix I'm missing somewhere but I don't see where it could be.
public class FoxyController : MonoBehaviour
{
Rigidbody2D rigidbody2d;
float horizontal;
float vertical;
public float jumpVelocity = 10f;
void Start()
{
rigidbody2d = GetComponent<Rigidbody2D>();
}
void Update()
{
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
if (Input.GetKey(KeyCode.Space))
{
Jump();
}
}
void FixedUpdate()
{
Vector2 position= rigidbody2d.position;
position.x = position.x + 4f * horizontal * Time.deltaTime;
position.y = position.y + 4f * vertical * Time.deltaTime;
rigidbody2d.MovePosition(position);
}
void Jump()
{
rigidbody2d.velocity = Vector2.up * jumpVelocity;
}
}
Use -> rb.AddForce(Vector2.up * jumpAmount, ForceMode2D.Impulse); where jumpAmount can be multiplayer, you can use 10f as jumpAmount value.
if (Input.GetKey(KeyCode.Space))
{
rb.AddForce(Vector2.up * jumpAmount, ForceMode2D.Impulse);
}
Add Above code in update method instead of jump() method.
whenever I turn my bike it feels like it's sliding. Here's the script
[SerializeField] float turn;
[SerializeField] float maxSpeed;
[SerializeField] GameObject bikeParts;
[SerializeField] float tilt = 20f;
Rigidbody rb;
float lastY;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
float straightMov = Input.GetAxis("Vertical");
float horizontalMov = Input.GetAxis("Horizontal");
ControlStraightMov(straightMov);
ControlWeightTurning(horizontalMov);
lastY = transform.position.y;
}
private void ControlWeightTurning(float horizontalMov)
{
Vector3 bikePartsRot = bikeParts.transform.eulerAngles;
bikePartsRot.x = tilt * horizontalMov;
bikeParts.transform.eulerAngles = bikePartsRot;
transform.Rotate(0f, (turn * Time.deltaTime) * horizontalMov, 0f);
}
private void ControlStraightMov(float straightMov)
{
if (straightMov > 0)
{
rb.AddRelativeForce((accel * Time.deltaTime) * -straightMov, 0f, 0f);
}
else if (straightMov < 0)
{
rb.AddRelativeForce(((accel / 1.3f * Time.deltaTime) * -straightMov), 0f, 0f);
}
}
Whenever the bike picks up speed, it becomes very difficult to turn the bike because the force that was added keeps moving the bike in a different direction than the direction the bike's facing, how do I apply that force it was facing before on the direction it is facing now so that it doesn't feel like sliding?
I have tried fixing this problem but i just can't because i am pretty new to unity.
how do I apply that force it was facing before on the direction it is facing now
Not sure if this would feel right but you could probably do it like e.g.
private void Update ()
{
...
rb.velocity = transform.forward * rb.velocity.magnitude;
}
Which will keep the current speed and just redirect it into the new forward direction.
In general note: Whenever there is a Rigidbody involved you don't want to set any manipulation through the Transform component but only via the Rigidbody.
So you should not do
bikeParts.transform.eulerAngles = bikePartsRot;
transform.Rotate(0f, (turn * Time.deltaTime) * horizontalMov, 0f);
but both times rather calculate the target rotation and go through e.g. rb.MoveRotation in FixedUpdate.
Which might look somewhat like
float horizontalMove;
void Update()
{
var straightMove = Input.GetAxis("Vertical");
// Get and store the input in Update
horizontalMove = Input.GetAxis("Horizontal");
ControlStraightMov(straightMove);
lastY = transform.position.y;
}
private void FixedUpdate ()
{
// Handle it in FixedUpdate
ControlWeightTurning(horizontalMove);
}
private void ControlWeightTurning(float horizontalMove)
{
var bikePartsRot = bikeParts.transform.eulerAngles;
bikePartsRot.x = tilt * horizontalMove;
// Calculate the new final rotation
var newRotation = Quaternion.Euler(bikePartsRot) * Quaternion.Euler(Vector3.up * (turn * Time.deltaTime) * horizontalMove));
// Apply it only via the Rigidbody
rb.MoveRotation(newRotation);
}
this is currently my code. The object moves at the desired speed but using [rb.velocity = movement * speed] if it jump it remains glued to the ground. I can't understand how I can fix things
private Vector3 movement;
private float speed = 3;
public bool isGrounded;
void Start()
rb = GetComponent<Rigidbody>();
void Update()
{
float Horizontal = Input.GetAxis("Horizontal");
float Vertical = Input.GetAxis("Vertical");
movement = transform.right * Horizontal + transform.forward * Vertical;
float origMagnitude = movement.magnitude;
movement.y = 0.0f;
movement = movement.normalized * origMagnitude;
if(isGrounded && Input.GetKeyDown(KeyCode.Space))
rb.AddForce((Vector3.up + movement) * JumpForce, ForceMode.Impulse);
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.down), out hit, rayDistance, layer)) isGrounded = true;
else isGrounded = false;
}
private void FixedUpdate ()
{
rb.velocity = movement * speed;
}
First of all, "AddForce" adds a force to the rigidbody. That means that the rigidbody will keep on moving in this direction (the force vector) until something stops it (friction or other objects). If you keep adding forces to the rigidbody, the total force will increase and, as a result, the speed will keep growing.
There is a simple way to move a rigidbody, just use its position property:
For example:
rb = GetComponent<Rigidbody>(); \\ From your program
rb.position = rb.position + movement * speed * Time.fixedDeltaTime; \\ Instead of MovePosition
As far as I knew (from unity scripting API) MoveRotation works on a non kinematic rigidbody.
If it doen't work, you can do the same as the movement (use the rotation property).
For more information, you can see: Unity Scripting API - Rigidbody
just try to ask for the speed:
like
void FixedUpdate()
{
if(rb.velocity.magnitude < "set here your speed variable" )
rb.velocity = movement * speed;
}
Soo, I'm trying to code a simple Platformer as a work for class, and I'm having problems with the jumping, the character actually jumps but it seems as a teleport since it instantly reaches the peak of the jump and then gradually falls, I'd like to make it smoother.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class playerMovement : MonoBehaviour {
public float speed;
public float jumpForce;
public bool grounded;
public Transform groundCheck;
private Rigidbody2D rb2d;
// Use this for initialization
void Start () {
rb2d = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update () {
}
private void FixedUpdate()
{
float moveVertical = 0;
float moveHorizontal = Input.GetAxis("Horizontal") * speed;
moveHorizontal *= Time.deltaTime;
grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
if (grounded && Input.GetKeyDown("space"))
{
moveVertical = Input.GetAxis("Jump") * jumpForce;
moveVertical *= Time.deltaTime;
}
Vector2 move = new Vector2(moveHorizontal, moveVertical);
transform.Translate(move);
}
}
The answer to the question is below, however, for future questions related to Unity ask on the Unity forum. You will get a better answer quicker as more people are focused on Unity itself.
To fix your jump, rather split your vertical and horizontal movement in two parts and use your rigidbody you assigned in in your Start() function to handle jumping. Use ForceMode.Impulse to get an instant burst of speed/acceleration.
private void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal") * speed;
moveHorizontal *= Time.deltaTime;
grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground"));
if (grounded && Input.GetKeyDown("space"))
{
rb2d.AddForce(transform.up * jumpForce, ForceMode.Impulse);
}
Vector2 move = new Vector2(moveHorizontal, 0);
transform.Translate(move);
}
Instead of setting the position when you jump, add a vertical impulse to the character's rigidbody with:
if (grounded && Input.GetKeyDown("space"))
{
moveVertical = Input.GetAxis("Jump") * jumpForce;
moveVertical *= Time.fixedDeltaTime;
rb2d.AddForce(moveVertical, ForceMode.Impulse);
}
Vector2 move = new Vector2(moveHorizontal, 0f);
This will let Rigidbody2D handle the work of altering the vertical velocity on each frame.
Also, since you are doing all of these calculations in FixedUpdate, instead of Update, there is no sense in using Time.deltaTime. You should be using Time.fixedDeltaTime instead.
The function SetFloat() does not recognize the speed when my character moves in the x axis, but still recognizes the y axis.
I don't understand why the player´s x velocity is not signed to the "Speed" float created in the animator
public float acceleration;
public bool isGrounded = true;
public float jumpHeight;
Animator anim;
// Use this for initialization
void Start () {
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
if(Input.GetKey(KeyCode.Space) && isGrounded == true){
GetComponent<Rigidbody2D>().velocity = new Vector2 (0 , jumpHeight);
isGrounded = false;
}
if(GetComponent<Rigidbody2D>().velocity.y == 0){
isGrounded = true;
}
anim.SetFloat("Speed", Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x));
if(Input.GetKey(KeyCode.D)){
transform.position += new Vector3 (acceleration * Time.deltaTime , 0.0f, 0.0f);
transform.localScale = new Vector3 (5,5,5);
}
if(Input.GetKey (KeyCode.A)){
transform.localScale = new Vector3 (-5,5,5);
transform.position -= new Vector3 (acceleration * Time.deltaTime , 0.0f , 0.0f);
}
}
I don't know if this question is still relevant but, if you want to set a float in the animator, you can't use transform.position. transform.position doesn't change any Rigidbody values, in order to do that you would want to move the Rigidbody using rigidbody.MovePosition or rigidbody.AddForce.
I suggest using rigidbody.MovePosition because you don't have to write much code.
The way i do it is i don't use Input.GetKey because it's quite sloppy and doesn't work as well as Input.GetAxis:
function Update()
{
float keyboardX = Input.GetAxis("Horizontal") * acceleration * Time.deltaTime;
rigid.MovePosition(keyboardX);
anim.SetFloat("Speed", Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x));
}
This should work. Again, i'm not sure how relevant this is.