I'm new to unity and have been trying to get the 2D Playermovement right for quite some time. Yet for some reason this error keeps popping up, anyone have any ideas?
this is the code I've been using:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private Rigidbody2d rb2D;
private float MovementSpeed;
private float JumpForce;
private bool IsJumping;
private float moveHorizontal;
private float moveVertical;
// Start is called before the first frame update
void Start()
{
rb2D = gameObject.GetComponent<Rigidbody2d>();
MovementSpeed = 3f;
JumpForce = 60f;
IsJumping = false;
}
// Update is called once per frame
void Update()
{
moveHorizontal = Input.GetAxisRaw("Horizontal");
moveVertical = Input.GetAxisRaw("Vertical");
}
void FixedUpdate ()
{
if(moveHorizontal > 0.1f || moveHorizontal < -0.1f)
{
rb2D.AddForce(new Vector2(moveHorizontal * MovementSpeed, 0f), ForceMode2D.Impulse);
}
}
}
Typo: It should be Rigidbody2D and not Rigidbody2d
Related
Currently, I'm making a game in unity, and I made a simple script to make the enemy follow the player but I can't change the animation of the enemy to the other side
gameplay:
EnemyController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
[Header("References")]
private Animator animator;
// The target to follow.
private Transform target;
private Rigidbody2D rb;
[Header("Movement")]
public float speed;
public float range;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
rb = GetComponent<Rigidbody2D>();
target = FindObjectOfType<PlayerMovement>().transform;
}
// Update is called once per frame
void Update()
{
FollowPlayer();
}
private void FollowPlayer()
{
animator.SetBool("isRunning", true);
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
}
I fix it by using blend tree
Blend Tree:
Script:
private void FollowPlayer()
{
animator.SetBool("isRunning", true);
animator.SetFloat("Horizontal", target.position.x - transform.position.x);
transform.position = Vector3.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
I'm making a platformer controller using the new Input System and trying to control the curve for jumping... I've figured out how to add a damp for the horizontal movement which give the horizonal movement a bit of a slippery feel. But I cannot figure out how to control curve for the Jump. The problem now is I'm using a Player Input Component and Unity Events to control the Move and Jump. And the jump is using rb.velocity.y.
How do I control my Jump curve?
Here is the current curve:
I want to controle the acceleration and deacceleration of the curve:
Here is the curve I'd like to achieve with jumping
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovement : MonoBehaviour
{
private const float GroundedRadius = 0.2f;
[SerializeField] private float smoothInputSpeed = .2f;
[SerializeField] private float speed = 8f;
[SerializeField] private float jumpingPower = 12f;
[SerializeField] private float fallPower = 2f;
[SerializeField] private Rigidbody2D rb;
[SerializeField] private Transform groundCheck;
[SerializeField] private LayerMask groundLayer;
private Vector2 _smoothMove = Vector2.zero;
private Vector2 _smoothInputVelocity = Vector2.zero;
private Vector2 _move = Vector2.zero;
private bool _isFacingRight = true;
void Update()
{
_smoothMove = Vector2.SmoothDamp(_smoothMove, _move, ref _smoothInputVelocity, smoothInputSpeed);
rb.velocity = new Vector2(_smoothMove.x * speed, rb.velocity.y);
if (!_isFacingRight && _move.x > 0f || _isFacingRight && _move.x < 0f)
{
Flip();
}
}
public void Move(InputAction.CallbackContext context)
{
_move = context.ReadValue<Vector2>();
}
public void Jump(InputAction.CallbackContext context)
{
if (context.performed && IsGrounded())
{
rb.velocity = new Vector2(rb.velocity.x, jumpingPower);
}
if (context.canceled && rb.velocity.y > 0f)
{
var velocity = rb.velocity;
var gravity = rb.gravityScale;
velocity = new Vector2(velocity.x, (velocity.y * gravity * fallPower)); // fall faster if cancelled
rb.velocity -= velocity;
}
}
private bool IsGrounded()
{
return Physics2D.OverlapCircle(groundCheck.position, GroundedRadius, groundLayer);
}
private void Flip()
{
_isFacingRight = !_isFacingRight;
var transform1 = transform;
Vector3 localScale = transform1.localScale;
localScale.x *= -1f;
transform1.localScale = localScale;
}
}
There is my current code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMovementScript : MonoBehaviour
{
[SerializeField] float runSpeed = 10f;
Vector2 moveInput;
Rigidbody2D rigidbody;
void Start()
{
rigidbody = GetComponent<Rigidbody2D>();
}
void Update()
{
Run();
}
void OnMove(InputValue value){
moveInput = value.Get<Vector2>();
Debug.Log(moveInput);
}
void Run()
{
Vector2 playerVelocity = new Vector2(moveInput.x * runSpeed, rigidbody.velocity.y);
rigidbody.velocity = moveInput;
}
}
But my character still mowing with speed of 2f and can fly up and down (i did it in first version of my code).
It looks like game not loaded newest code and don't know how to fix it.
I have selected auto refresh.
im starting a new proyect in Unity and I want my character to jump and move at the same time but the codes don't work well together. the character finds it difficult to move. both work perfectly separately
this is the code im using to move around:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float speed = 30f;
public float turnSpeed = 80f;
private float horizontalInput;
private float verticalInput;
// Update is called once per frame
void Update()
{
horizontalInput = Input.GetAxis("Horizontal"); //teclas
verticalInput = Input.GetAxis("Vertical");
transform.Translate(speed*Time.deltaTime*Vector3.forward*verticalInput); //movimiento
transform.Rotate(turnSpeed*Time.deltaTime*Vector3.up*horizontalInput); //rotar
}
}
and this one is a tutorial i found for jumping:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class JumpControl : MonoBehaviour
{
private CharacterController controller;
private float verticalVelocity;
private float gravity = 14.0f;
private float jumpForce = 10.0f;
void Start()
{
controller = GetComponent<CharacterController>();
}
private void Update(){
if (controller.isGrounded)
{
verticalVelocity = -gravity * Time.deltaTime;
if (Input.GetKeyDown(KeyCode.Space))
{
verticalVelocity = jumpForce;
}
}
else
{
verticalVelocity -= gravity * Time.deltaTime;
}
Vector3 moveVector = new Vector3(0, verticalVelocity, 0);
controller.Move(moveVector * Time.deltaTime);
}
}
The CharacterController is physics-based. You never want to mix a physics-based movement with applying transformations via the Transform component. This breaks the physics, collision detection and causes all kind of unexpected behaviour and strange looking movements.
So instead of
transform.Translate(speed*Time.deltaTime*Vector3.forward*verticalInput);
you would rather want to do
[SerializeField] private CharacterController controller;
private void Awake()
{
if(!controller) controller = GetComponent<CharacterController>();
}
void Update()
{
horizontalInput = Input.GetAxis("Horizontal"); //teclas
verticalInput = Input.GetAxis("Vertical");
transform.Rotate(turnSpeed * Time.deltaTime * Vector3.up * horizontalInput);
controller.Move(speed * Time.deltaTime * Vector3.forward * verticalInput);
}
This code
transform.Translate(speedTime.deltaTimeVector3.forward*verticalInput);
prevents the jump action.
So you can replace it with
rb.AddForce(new Vector3(horizontalInput , o, verticalInput) * speed);
This is my player movement code:
Footage of bug and inspector elements:
https://imgur.com/a/bmGqL1M
As you can see in this Imgur video, for some reason my player character, and also a pushable crate, can clip into this tilemap for a few pixels. I'm not quite sure why this is happening, since I've added a composite collider2D to the tilemap, to get rid of the very common "getting stuck in tilemap" bug, which isn't the case here, the clipping doesn't actually alter the movement in any way.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[Header("Movement")]
[SerializeField] private float movementSpeed;
[SerializeField] private float jumpForce;
[Header("Jumping")]
private bool isGrounded;
[SerializeField] private Transform feetPos;
[SerializeField] private float checkRadius;
[SerializeField] private LayerMask whatIsGround;
[SerializeField] private float hangTime;
private float hangCounter;
private Rigidbody2D rb;
private SpriteRenderer sr;
private float moveX;
void Start()
{
rb = GetComponent<Rigidbody2D>();
sr = GetComponent<SpriteRenderer>();
}
void Update()
{
GetInput();
BetterJump();
}
void BetterJump()
{
isGrounded = Physics2D.OverlapCircle(feetPos.position, checkRadius, whatIsGround);
if (isGrounded)
{
hangCounter = hangTime;
} else
{
hangCounter -= Time.deltaTime;
}
if (hangCounter > 0 && Input.GetKeyDown(KeyCode.Space))
{
rb.velocity = Vector2.up * jumpForce;
}
if (Input.GetButtonUp("Jump") && rb.velocity.y > 0)
{
rb.velocity = new Vector2(rb.velocity.x, rb.velocity.y * .5f);
}
}
void FixedUpdate()
{
Move();
}
void Move()
{
rb.position += new Vector2(moveX, 0) * Time.deltaTime * movementSpeed;
}
void GetInput()
{
moveX = Input.GetAxisRaw("Horizontal");
if(moveX < 0)
{
sr.flipX = true;
}
else if (moveX > 0)
{
sr.flipX = false;
}
}
}