Like the title says when i walk into a wall i start to vibrate. It doesn't affect gameplay just graphics i believe. The game is a 2D platformer using rigidbody 2D. I am new to game dev so what you fixed could you please tell me how you fix it. Thank you.
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public float MovementSpeed = 1;
public float JumpForce = 1;
private Rigidbody2D _rigidbody;
private float coyoteTime = 0.2f;
private float coyoteTimeCounter;
private float jumpBufferTime = 0.05f;
private float jumpBufferCounter;
[SerializeField] private Rigidbody2D rigidbody2D;
[SerializeField] private Transform groundCheck;
[SerializeField] private LayerMask groundLayer;
private bool isGrounded()
{
return Physics2D.OverlapCircle(groundCheck.position, 0.2f, groundLayer);
}
private void Start()
{
_rigidbody = GetComponent<Rigidbody2D>();
}
private void Update()
{
if (isGrounded())
{
coyoteTimeCounter = coyoteTime;
}
else
{
coyoteTimeCounter -= Time.deltaTime;
}
if (Input.GetButtonDown("Jump"))
{
jumpBufferCounter = jumpBufferTime;
}
else
{
jumpBufferCounter -= Time.deltaTime;
}
var movement = Input.GetAxis("Horizontal");
transform.position += new Vector3(movement, 0, 0) * Time.deltaTime * MovementSpeed;
if (coyoteTimeCounter > 0f && jumpBufferCounter > 0f)
{
_rigidbody.velocity = new Vector2(_rigidbody.velocity.x, JumpForce);
jumpBufferCounter = 0f;
}
if (Input.GetButtonUp("Jump") && _rigidbody.velocity.y > 0f)
{
_rigidbody.velocity = new Vector2(_rigidbody.velocity.x, _rigidbody.velocity.y * 0.5f);
coyoteTimeCounter = 0f;
}
}
}
Sorry if the code is sort of sloppy. I am using multiple tutorials to make the movement perfect for me.
Ah! I have had this problem before.
The reason the vibration is happening, is because you are adding a force manually through rigidbody.velocity. The better (And more efficient) way to do it is through rigidbody.AddForce(). This should allow for the rigidbody to calculate physics much smoother.
The only issue that may arise is if you plan for the player to have a constant speed. If you AddForce(1000) with no other arguments, the character will start accelerating, instead of moving at a constant speed.
If you need the player to move at a constant speed, you can append a ForceMode to! I am not sure what one you would use, but that my idea. One example would be rigidbody.AddForce(1000, ForceMode.VelocityChange),
Related
In my game, I have a vehicle using a rigidbody that moves forward (relative to the front of the vehicle) at a constant rate using the rigidbody velocity function. The vehicle also may turn 90 degrees to the right and back, of course causing the direction it is moving to rotate. The vehicle drives on a floating platform, and if driven off, the velocity function is stopped so that the car may properly fall off using rigidbody physics.
I want to have slopes at various points in the game, and since the vehicle moves at a constant speed, the vehicle should be able to drive up and down a slope automatically. The issue is that I have to directly control the rigidbody's velocity to make it drive at a constant speed, so when the vehicle drives into a slope, the velocity function keeps pushing it forward without properly rotating, not letting it properly drive up the slope. How should I go about fixing this? Should I be using the rigidbody velocity function at all in this case?
For reference, here is the script I am using for vehicle movement:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
[SerializeField] private GameObject followCamera;
[SerializeField] private AnimationCurve lerpCurve;
[SerializeField] private float turnSpeed;
[SerializeField] private float speed;
private static float turnTimer = 2f;
private float turnTimeElapsed;
private float clampedTimeElapsed;
private float lerpTimer;
Rigidbody ridgy;
LayerMask groundLayer;
private void Start()
{
groundLayer = LayerMask.GetMask("Ground");
ridgy = this.GetComponent<Rigidbody>();
turnTimeElapsed = 0f;
Quaternion endRot = Quaternion.Euler(0f, 90f, 0f);
}
private void Update()
{
if (Input.GetKey(KeyCode.Space) && turnTimeElapsed < turnTimer)
{
turnTimeElapsed += turnSpeed * Time.deltaTime;
}
else if (!Input.GetKey(KeyCode.Space) && turnTimeElapsed > 0)
{
turnTimeElapsed -= turnSpeed * Time.deltaTime;
}
clampedTimeElapsed = Mathf.Clamp(turnTimeElapsed, 0f, turnTimer);
lerpTimer = clampedTimeElapsed / turnTimer;
lerpTimer = lerpCurve.Evaluate(lerpTimer);
}
private void FixedUpdate()
{
if (Physics.CheckBox(transform.position, new Vector3(.5f, .5f, .5f), Quaternion.identity, groundLayer))
{
if (lerpTimer > 0f && lerpTimer < .75f)
{
speed = 45;
}
else
{
speed = 15;
}
ridgy.rotation = new Quaternion
(
0,
Mathf.Sin(lerpTimer * Mathf.PI / 4f),
0,
Mathf.Cos(lerpTimer * Mathf.PI / 4f)
);
ridgy.velocity = transform.forward * speed;
}
else
{
followCamera.GetComponent<CameraFollow>().enabled = false;
return;
}
}
}
FIRST : SORRY FOR MY ENGLISH !!!
Hello everyone, i'm very new into Unity (5 days).
Today i've make a script for the basics movements with a rigid-bodie, BUT the diagonal movements are faster than the normal movements.. I search on Internet but I don't find a post that i can understand.
So here my script.
Also if you know how to not move when we jump, or when we jump into a direction, it follow this direction, tell me. (I know my english is terrible.) Also, i'm new into this website.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovements : MonoBehaviour
{
[SerializeField] private float walkingSpeed;
[SerializeField] private float runningSpeed;
[SerializeField] private float jumpForce;
[SerializeField] private float jumpRaycastDistance;
private Rigidbody rb;
float speed;
Vector3 movement;
/////////////////////////////////////////////////////
void Start()
{
rb = GetComponent<Rigidbody>();
}
/////////////////////////////////////////////////////
void Update()
{
Jumping();
}
/////////////////////////////////////////////////////
private void FixedUpdate()
{
Movements();
}
/////////////////////////////////////////////////////
private void Movements()
{
float hAxis = Input.GetAxisRaw("Horizontal");
float vAxis = Input.GetAxisRaw("Vertical");
if(Input.GetButton("Run"))
{
Vector3 movement = new Vector3(hAxis, 0, vAxis) * runningSpeed * Time.deltaTime;
Vector3 newPosition = rb.position + rb.transform.TransformDirection(movement);
rb.MovePosition(newPosition);
}
else
{
Vector3 movement = new Vector3(hAxis, 0, vAxis) * walkingSpeed * Time.deltaTime;
Vector3 newPosition = rb.position + rb.transform.TransformDirection(movement);
rb.MovePosition(newPosition);
}
}
/////////////////////////////////////////////////////
private void Jumping()
{
if(Input.GetButtonDown("Jump"))
{
if (isGrounded())
{
rb.AddForce(0, jumpForce, 0, ForceMode.Impulse);
}
}
}
/////////////////////////////////////////////////////
private bool isGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, jumpRaycastDistance);
}
}
You need to clamp your velocity in order to keep it same. Look into Vector3.ClampMagnitude()
velocity = Vector3.ClampMagnitude(velocity, _movementSpeed);
velocity.y = playerVelocity.Y; // keeping your Y velocity same since you have jumping.
playerVelocity = velocity;
EDIT: in your case it should be something like this.
_maxSpeed is the speed limit.
private void FixedUpdate()
{
Movements();
var clampedVelocity = Vector3.ClampMagnitude(rb.velocity, _maxSpeed);
clampedVelocity.y = rb.velocity.y;
rb.velocity = clampedVelocity;
}
Try normalizing the vector. (more info is on unity docs, but normalize() will make sure that the sum of all the vector's values isnt above 1.
Here's my code, and, before anybody says it, I do not want to use translate or a character controller or any of that. Basically, with my current code, as soon as I stop holding any of the input keys, my character slides all over the place. How can I counteract this? By the way, a lot of these values defined at the beginning I have changed in the editor.
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
[SerializeField] Rigidbody rb;
[SerializeField] float speed = 10f;
[SerializeField] float jumpForce = 1;
[SerializeField] float distanceFromGround = .5f;
[SerializeField] float maxSpeed = 1;
float currSpeed;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
float x = Input.GetAxisRaw("Horizontal") * currSpeed;
float y = Input.GetAxisRaw("Vertical") * currSpeed;
if(Input.GetAxisRaw("Jump") == 1 && Grounded())
{
rb.AddForce(Vector3.up * jumpForce);
}
Vector3 movePos = transform.right * x + transform.forward * y;
Vector3 newMovePos = new Vector3(movePos.x, 0, movePos.z);
rb.AddForce(newMovePos);
}
private void FixedUpdate()
{
currSpeed = speed;
if (!Grounded())
{
currSpeed = speed / 2;
}
if (Input.GetAxisRaw("Horizontal") != 0 && Input.GetAxisRaw("Vertical") != 0)
{
currSpeed = speed * .75f;
}
if(rb.velocity.magnitude > maxSpeed)
{
rb.velocity = Vector3.ClampMagnitude(rb.velocity, maxSpeed);
}
}
bool Grounded()
{
return Physics.Raycast(transform.position, Vector3.down, distanceFromGround);
}
}
You can stop all movements by making rigidbody kinematic if condition is met by simply adding rb.isKinematic =true/false;
Or directly affect rb velocity in update.
Sor example you'd have in your update
rb.velocity=slowedVelocity;
so whenever you'd not be adding any velocity you are reducing it.
Another thing you migth be asking is to jsut add constraints in your editor so player is not moving and rotating in ways you do not waint it to do.
I am quite new to unity and I have two scripts, one for gravity and one for player movement as the names suggest. The reason I am using a gravity script is that the third person movement doesn't support using a rigidbody with position and rotation enabled, so I have frozen the position and the rotation inside the rigidbody (which turns off gravity in the rigidbody). I made the Gravity script myself but I followed a tutorial on the player movement script because I have no idea how to make third person movement so I don't really know what is going on in the movement script.
Movement script:
public class ThirdPersonMovement : MonoBehaviour
{
public CharacterController controller;
public Transform cam;
public float speed = 6f;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;
void Update()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
UnityEngine.Vector3 direction = new UnityEngine.Vector3(horizontal, 0f, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + cam.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = UnityEngine.Quaternion.Euler(0f, angle, 0f);
UnityEngine.Vector3 moveDir = UnityEngine.Quaternion.Euler(0f, targetAngle, 0f) * UnityEngine.Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
}
Gravity script:
public class gravityScript : MonoBehaviour
{
public float GravitySpeed = -0.03f;
public bool GravityCheck = false;
void OnCollisionEnter(Collision col)
{
if (col.gameObject.name == "Terrain0_0")
{
GravityCheck = true;
}
}
void OnCollisionExit(Collision col)
{
GravityCheck = false;
}
void Update()
{
if (GravityCheck == false)
{
transform.Translate(0, GravitySpeed, 0);
}
}
}
Thank you in advance :)
I don't know what happened but when I opened it today (the day after posting) it was working fine. It was likely just a bug that got fixed after a restart.
Okay im trying to make my object (player) to jump everything is okay until i go against a wall and keep going against (still W is down) i cant jump wen im hitting a wall if i stop walking he will be enable to jump i tried making the walls on touch to make the player to have velocity = zero but it does not work,
i tried to add rigid body to the walls and freezing them in place, trying to make them kinematic does not work too .
I wish wen i go against walls and keep walking against them to be enable to jump.
If you know how i can do that please share thanks .
Here is the move script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveScript : MonoBehaviour {
private float speed;
private float jumpHight;
private float straffeSpeed;
private float fallMultiplier;
private Rigidbody rig;
private Collider coll;
// Use this for initialization
private void Awake()
{
rig = GetComponent<Rigidbody>();
coll = GetComponent<Collider>();
straffeSpeed = 1.5f;
fallMultiplier = 2.5f;
speed = 10f;
jumpHight = 4f;
}
void Start () {
GroundCheck();
}
// Update is called once per frame
void Update () {
Move();
GroundCheck();
BetterFall();
}
private void Move()
{
float hAxis = Input.GetAxis("Horizontal") * straffeSpeed;
float vAxis = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(hAxis, 0, vAxis) * speed * Time.deltaTime;
rig.MovePosition(transform.position + movement);
if (Input.GetKey(KeyCode.Space) && GroundCheck())
{
rig.velocity = Vector3.up * jumpHight;
}
}
private bool GroundCheck()
{
return Physics.Raycast(transform.position, -Vector3.up, coll.bounds.extents.y + 0.2f);
}
private void BetterFall()
{
if(rig.velocity.y < 0)
{
rig.velocity += Vector3.up * Physics.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
}
}
if (Input.GetKeyDown(KeyCode.Space) && GroundCheck())
{
rig.velocity = Vector3.up * jumpHight;
}
I don't think you are doing this quite right. Try this:
if (Input.GetKeyDown(KeyCode.Space) && GroundCheck())
{
rig.AddForce(Vector3.up * jumpHight, ForceMode.Impulse);
}
:-)