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.
Related
the problem I am having is when I run full speed (i.e. pressing a and w and looking 45 degrees to the right it doesn't use .normalized on purpose) into a wall or anything else it allows the player to go through it, so my code is
Vector3 m_Input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
Vector3 moveDirection = m_Input;
moveDirection = transform.TransformDirection(moveDirection);
rb.MovePosition(transform.position + moveDirection * moveSpeed);
and moveSpeed is set to 0.2. I have checked and all of the colliders are not triggers. any help would be greatly appreciated
First off do double check
All your colliders & rigidbody are 3d
Everything is on the same layer (or your layers are set to interact with each other)
Your rigidbody is attached to the same game object as your collider
However, it seems that your issue is that your rigidbody is set to be kinematic (as Rigidbody.MovePosition is intended to be used by kinematic rigidbody's only)
If your rigidbody is set to kinematic then no forces (such as collider normal forces) will be applied to your object, so it will be able to pass through walls.
Solution
The easiest way to avoid this is by making sure your rigidbody is set to non-kinematic, and moving it via Rigidbody.velocity.
Something similar to:
Vector3 m_Input = new Vector3(Input.GetAxis("Horizontal"), 0,
Input.GetAxis("Vertical"));
Vector3 moveDirection = m_Input;
moveDirection = transform.TransformDirection(moveDirection);
rb.velocity = (moveDirection * moveSpeed);
This should move your character according to physics and allow for the correct interactions with colliders.
Also, you should be aware if you ever do want to move a rigidbody like that, you should be sure to do so in FixedUpdate and scale movement by Time.FixedDeltaTime.
now the jump is broken this is the full script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FPSMovement : MonoBehaviour
{
public Rigidbody rb;
public GameObject cam;
Vector2 rotation = Vector2.zero;
public float sensitivity = 10f;
public string xAxis = "Mouse X";
public string yAxis = "Mouse Y";
public float OmoveSpeed;
public float SprintSpeed;
public float moveSpeed;
public float jumpVar;
public bool Grounded = false;
public Vector3 slideScale;
public Vector3 normalScale;
public Vector3 dir;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
moveSpeed = OmoveSpeed;
slideScale = new Vector3(1, 0.5f, 1);
normalScale = new Vector3(1, 1, 1);
}
// Update is called once per frame
void FixedUpdate()
{
dir = rb.velocity;
// Should be cross platform movement
Vector3 m_Input = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
Vector3 moveDirection = m_Input;
moveDirection = transform.TransformDirection(moveDirection);
rb.velocity = (moveDirection * moveSpeed);
// Sprinting
if (Input.GetKey(KeyCode.LeftControl))
{
moveSpeed = SprintSpeed;
}
else
{
moveSpeed = OmoveSpeed;
}
// Jumping
if (Input.GetKey(KeyCode.Space))
{
if (Grounded)
{
rb.velocity += new Vector3(0, jumpVar, 0);
Grounded = false;
}
}
// TO-DO: Sliding
// Camera Rotation
rotation.x += Input.GetAxis(xAxis) * sensitivity;
rotation.y += Input.GetAxis(yAxis) * sensitivity;
rotation.y = Mathf.Clamp(rotation.y, -90, 90);
var xQuat = Quaternion.AngleAxis(rotation.x, Vector3.up);
var yQuat = Quaternion.AngleAxis(rotation.y, Vector3.left);
transform.localRotation = xQuat;
cam.transform.localRotation = yQuat;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.transform.tag == "Ground")
{
Grounded = true;
}
}
private void OnCollisionExit(Collision collision)
{
Grounded = false;
}
}
Here's my code. Currently, the player moves forwards relative to a fix plane. Rotating the player/camera has no affect on which direction they travel when I press the "go forward" key.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MainController : MonoBehaviour
{
public float speed;
float jumpSpeed = 0.5f;
bool isGrounded;
private Rigidbody rb;
public GameObject player;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
}
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
if (Input.GetButtonDown("Jump") || Input.GetAxis("Right Trigger") > 0f && isGrounded)
{
rb.AddForce(Vector3.up * jumpSpeed, ForceMode.Impulse);
isGrounded = false;
}
if (isGrounded)
{
rb.AddForce(movement * speed * Time.deltaTime);
}
else
{
rb.AddForce((movement/4) * speed * Time.deltaTime);
}
}
void OnCollisionStay()
{
isGrounded = true;
}
void OnCollisionExit()
{
isGrounded = false;
}
}
How do I make it so that the player moves relative to the camera's direction?
It's because RigidBody.AddForce() adds force in absolute direction, no matter which direction the gameobject is looking.
You should try using RigidBody.AddRelativeForce(), like:
if (isGrounded)
{
rb.AddRelativeForce(movement * speed * Time.deltaTime);
}
I think there is a better way to do this, but see if it results in the expected behavior:
void FixedUpdate()
{
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 looking = (transform.rotation * Vector3.forward).normalized;
Vector3 perpendicular = Vector2.Perpendicular(new Vector2(looking.x, looking.z));
perpendicular.z = perpendicular.y;
perpendicular.y = looking.y;
Vector3 vertical = moveVertical * looking;
Vector3 horizontal = moveHorizontal * perpendicular;
Vector3 movement = vertical - horizontal;
...
}
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.
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.
void Update ()
{
Vector3 input = new Vector3 (0, 0, 1);
Vector3 direction = input.normalized;
Vector3 velocity = direction * speed;
Vector3 moveAmount = velocity * Time.deltaTime;
transform.position += moveAmount;
if(Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
player.AddForce (Vector3.up * jumpForce, ForceMode.Impulse);
}
}
Since Time.deltaTime varies moveAmount also varies for every jump making the distance of the jump vary slightly.
The ball is to jump between blocks separated by a fixed gap and therefore the above behaviour causes problems.
Is there any way I can fix this and make fixed length jumps?
You can use CharacterController for this. Make sure you have a CharacterController and Collider attached to your gameobject. Also if you have a rigibody attached to your game object it may cause it to behave unexpectedly so you might have to contraint it.
public CharacterController controller;
private float verticalVelocity;
private float gravity = 25.0f;
private float jumpForce = 15.0f;
void Awake () {
controller = GetComponent<CharacterController>();
}
void Update () {
if( controller == null )
return;
if( controller.isGrounded)
{
verticalVelocity = -gravity * Time.deltaTime;
if( Input.GetKeyDown(KeyCode.Space) )
{
verticalVelocity = jumpForce;
}
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
float moveHorizontal = Input.GetAxis ("Horizontal");
float moveVertical = Input.GetAxis ("Vertical");
Vector3 moveVector = Vector3.zero;
moveVector.x = moveHorizontal * 5.0f;
moveVector.y = verticalVelocity;
moveVector.z = moveVertical * 5.0f;
controller.Move(moveVector * Time.deltaTime);
}
Check this tutorial for reference: https://www.youtube.com/watch?v=miMCu5796KM