I'm not sure why my character is falling through the floor.
My Rigidbody: has use gravity, no kinematic and Continuous Detection is set to Continuous.
My character is in the sky but the isgrounded bool ticks to true when it touches the floor but falls through anyways
My cube which is my floor has a box collider
void Update()
{
Move();
isGrounded = Physics.CheckSphere(GroundCheck.position, groundRadius, (int)whatisGround);
if (isGrounded == true)
{
velocity.y = -1f;
if (Input.GetKeyDown(KeyCode.Space))
{
velocity.y = JumpForce;
}
}
else
{
velocity.y -= Gravity * -2f * Time.deltaTime;
}
}
void Move()
{
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized;
if (direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + playerCamera.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
}
Looks like your code tests for the isgrounded value, and if it is true, changes the vertical velocity to -1, which is down. Since you don't tell it to zero it's vertical speed, and I assume it has no collider, it keeps falling down.
You need to either use a collider or, if isgrounded is true, set the y velocity to 0.
Related
I almost made a 3D horror game in which the Player can walk, run and jump, but I noticed that jump depends on FPS. The more FPS, the higher the jump. I want to Player jump doesn't depend on FPS. How to solve the problem?
Script Player (just Update):
void Update{
// Jump when Player is on the Ground
Ground = Physics.CheckSphere(GroundCheck.position, groundDistance, Groundmask);
if (Ground && velocity.y < 0) { velocity.y = -0.5f; }
posX = Input.GetAxis("Horizontal"); posZ = Input.GetAxis("Vertical");
Vector3 Move = transform.right * posX + transform.forward * posZ;
controller.Move(Move * speed * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity);
if ((Input.GetMouseButton(0) || Input.GetKey(KeyCode.Return)) && Ground)
{
{ velocity.y = Mathf.Sqrt(3 - gravity); }
}
}
I'm trying to make my player dash at where he's looking. The code below works but it gives 2 different result.
If the player dash and move at the same time, the player gets pushed a few units.
If the player dash only, the player gets pushed 4/5 times the one above.
How do I get result 1 for both of them whether they are moving or standing still.
private void Start() {
rb = GetComponent<Rigidbody>();
}
private void Update()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
direction = new Vector3(horizontalInput, 0f, verticalInput).normalized;
if(Input.GetKeyDown(KeyCode.Space)){
isDashing = true;
}
}
private void FixedUpdate() {
Move();
if(isDashing){
Dash();
}
}
void Move()
{
if(direction.magnitude >= 0.1f)
{
float targetAngle = Mathf.Atan2(direction.x, direction.z) * Mathf.Rad2Deg + camera.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, 0.1f);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDirection = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
moveDirection.y = rb.velocity.y;
rb.velocity = moveDirection * currentSpeed * Time.deltaTime;
}
}
void Dash()
{
rb.AddForce(transform.forward * dashForce, ForceMode.Impulse);
isDashing = false;
}
I'm quite new to coding and making games. I created this script with the help of some YT tutorials and I was wondering how to make my character jump higher while holding doing the space bar. I tried different things but non worked properly. Here's my character code. Thanks!
using System;
using UnityEngine;
using UnityEngine.UI;
public class TPMovementScript : MonoBehaviour
{
public CharacterController controller;
public Transform cam;
public float speed = 6f;
public float jump = 10f;
public float gravity = -9.81f;
public Transform groundCheck;
public float groundDistance = 0.4f;
public LayerMask groundMask;
public float jumpHeight = 3f;
Vector3 velocity;
bool isGrounded;
public float turnSmoothTime = 0.1f;
float turnSmoothVelocity;
// Update is called once per frame
void Update()
{
//Checks if player is grounded & resets velocity
isGrounded = Physics.CheckSphere(groundCheck.position, groundDistance, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
//Makes Player move Using WASD or upDownLeftRight
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 direction = new Vector3(horizontal, 0f, vertical).normalized.normalized;
if (isGrounded && Input.GetKey(KeyCode.Space))
{
velocity.y = Mathf.Sqrt(jumpHeight * -2f * gravity);
}
//Makes Character face direction and makes forward to camera position
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 = Quaternion.Euler(0f, angle, 0f);
Vector3 moveDir = Quaternion.Euler(0f, targetAngle, 0f) * Vector3.forward;
controller.Move(moveDir.normalized * speed * Time.deltaTime);
}
}
}
This looks like answer to your problem https://www.youtube.com/watch?v=j111eKN8sJw and code is similar.
Good day everyone!
I was trying to make my player face the direction he's walking towards, but then weird things started happening. Whenever I now let go of my input keys, the player slowly gets sucked to his local z-axis. Sometimes he does this while standing up, sometimes he does this flipped.
Any help would be highly appreciated!
Thanks in advance!
I'll provide you with my script:
public class JackMovement3D : MonoBehaviour {
public float speed = 6.0F;
public float VerticalSpeed = 10f;
public float HorizontalSpeed = 60f;
public float rotationSpeed = 5f;
public float jumpSpeed = 8.0F;
public float gravity = 20.0F;
private Vector3 moveDirection = Vector3.zero;
private Animator animator;
private void Start()
{
animator = GetComponent<Animator>();
}
void Update()
{
CharacterController controller = GetComponent<CharacterController>();
// is the controller on the ground?
if (controller.isGrounded)
{
float horizontal = Input.GetAxis("Horizontal") * HorizontalSpeed;
float vertical = Input.GetAxis("Vertical") * VerticalSpeed;
//Feed moveDirection with input.
moveDirection = new Vector3(horizontal, 0, vertical);
moveDirection = transform.TransformDirection(moveDirection);
//Multiply it by speed.
moveDirection *= speed;
}
//Applying gravity to the controller
moveDirection.y -= gravity * Time.deltaTime;
animator.SetFloat("Blend", controller.velocity.magnitude);
//Look at walking direction
Quaternion newRotation = Quaternion.LookRotation(moveDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, rotationSpeed);
// CharacterController.Move to move the player in target direction
controller.Move(moveDirection * Time.deltaTime);
}
private void LateUpdate()
{
transform.localEulerAngles = new Vector3(0, transform.localEulerAngles.y, transform.localEulerAngles.z);
}
}
Not sure if this is the issue you describe but it might be related to
Quaternion.LookRotation(moveDirection);
since if there is no Input the moveDirection is a Vector3(0,0,0) and Quaternion.LookRotation
Returns identity if forward or upwards magnitude is zero.
so you could probably avoid that resetting the rotation to idendity by adding a check like
// if movement is 0 do nothing else
if(Mathf.Approximately(moveDirection.sqrMagnitude, 0)) return;
this should be before adding the gravity.
Actually not sure again but I guess the gravity should be added after
void Update()
{
CharacterController controller = GetComponent<CharacterController>();
// is the controller on the ground?
if (controller.isGrounded)
{
float horizontal = Input.GetAxis("Horizontal") * HorizontalSpeed;
float vertical = Input.GetAxis("Vertical") * VerticalSpeed;
//Feed moveDirection with input.
moveDirection = new Vector3(horizontal, 0, vertical);
moveDirection = transform.TransformDirection(moveDirection);
//Multiply it by speed.
moveDirection *= speed;
}
animator.SetFloat("Blend", controller.velocity.magnitude);
// if movement is 0 do nothing else
if(Mathf.Approximately(moveDirection.sqrMagnitude, 0))
{
return;
}
moveDirection.y -= gravity * Time.deltaTime;
//Look at walking direction
var newRotation = Quaternion.LookRotation(moveDirection);
transform.rotation = Quaternion.Slerp(transform.rotation, newRotation, rotationSpeed);
// CharacterController.Move to move the player in target direction
controller.Move(moveDirection * Time.deltaTime);
}
I'm using the Charactercontroller component for the movement of my character.
The thing I'm trying to achieve is for the character to go when I'm clicking with the mouse. For that, I'm rotating where I click and then going forward to the point where the ray collider with my terrain.
The character does move and goes to the point I want.
The problem is when walking into a ramp, for example, the character keeps walking in the air and does not go down (gravity problem as far as I can understand although when I test putting the character in the air when the editor it does go down) it stops above when it supposed to go and starts spinning really fast.
Here's my movement script
private float gravity = 1f;
Animator anim;
CharacterController charController;
private float mvtSpeed = 3f;
private float distanceToPoint;
Vector3 playerMvt;
bool canMove = false;
CollisionFlags collisionFlags;
Ray ray;
RaycastHit hit;
Vector3 PlayerTarget;
float height;
private void Awake()
{
anim = GetComponent<Animator>();
charController = GetComponent<CharacterController>();
}
void MoveThePlayer()
{
if (Input.GetMouseButton(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit)) {
if (hit.collider is TerrainCollider)
{
if (Vector3.Distance(transform.position, hit.point) >= 0.5f)
{
canMove = true;
anim.SetFloat("Walk", 1.0f);
PlayerTarget = hit.point;
}
}//terrain collider
}//raycast
}//mouse Down
if (canMove)
{
Vector3 targetTemp = new Vector3(PlayerTarget.x, transform.position.y, PlayerTarget.z);
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(targetTemp - transform.position), 15.0f * Time.deltaTime);
playerMvt = transform.forward * mvtSpeed * Time.deltaTime;
if (Vector3.Distance(transform.position, PlayerTarget) <= 0.1f)
{
anim.SetFloat("Walk", 0f);
playerMvt.Set(0f, 0f, 0f);
}
}//canMove
}
private void Update()
{
MoveThePlayer();
charController.Move(playerMvt);
if (!charController.isGrounded)
{
playerMvt.y -= gravity * Time.deltaTime;
}
}
A few things.
canMove is never reset to false, it should probably reset in here
if (Vector3.Distance(transform.position, PlayerTarget) <= 0.1f)
{
anim.SetFloat("Walk", 0f);
playerMvt.Set(0f, 0f, 0f);
}
This code has no impact where its located right now:
if (!charController.isGrounded)
{
playerMvt.y -= gravity * Time.deltaTime;
}
You apply gravity to playerMvt.y after you have already moved the player, and the next frame you will re-assign playerMvt here:
playerMvt = transform.forward * mvtSpeed * Time.deltaTime;
So change it up to this
private void Update()
{
MoveThePlayer();
if (!charController.isGrounded)
{
playerMvt.y -= gravity * Time.deltaTime;
}
charController.Move(playerMvt);
}