I am working on a rigidbody controller and as of right now it has some issues I cant solve. I would like my movement to be continous and if though i am checking if the player is grounded it is still jumping while in the air. Thanks in advance for any feedback its greatly appreciated!
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
private Rigidbody _playerRB;
private PlayerInputSystem _playerInput;
private float playerIdNumber;
private string uniquePlayName;
private float jumpForce = 10.0f;
[Header("IsGounded")]
public LayerMask whatIsGround;
public Transform groundCheck;
private float groundCheckRadius = 0.1f;
private float speed = 10.0f;
private float acceleration = 1.0f;
private float currentSpeed;
private void Awake()
{
_playerRB = GetComponent<Rigidbody>();
_playerInput = new PlayerInputSystem();
_playerInput.Player.Enable();
}
private void OnEnable()
{
_playerInput.Player.Jump.performed += Jump;
_playerInput.Player.Move.performed += Move;
}
private void OnDisable()
{
_playerInput.Player.Jump.performed -= Jump;
_playerInput.Player.Move.performed -= Move;
}
private void Jump(InputAction.CallbackContext obj)
{
if (Physics.CheckSphere(groundCheck.position, groundCheckRadius, whatIsGround))
{
_playerRB.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
private void Move(InputAction.CallbackContext obj)
{
float horizontal = obj.ReadValue<Vector2>().x;
float vertical = obj.ReadValue<Vector2>().y;
transform.rotation *= Quaternion.Euler(new Vector3(0, horizontal, 0));
currentSpeed += vertical * acceleration * Time.deltaTime;
currentSpeed = Mathf.Clamp(currentSpeed, 0, speed);
transform.position += transform.right * currentSpeed * Time.deltaTime;
}
}
Again thanks in advance for the help.
Related
I'm trying to make move script but it seems impossible to me because I stared at code for like an hour I even rewrote it but same problem. It appears that after I added gravity and groundcheck things, my character cant run or even walk at set speed (he is moving very slow). Can someone please help me with it please cuz' I'm lost
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
//VARIABLES
[SerializeField] private float moveSpeed;
[SerializeField] private float walkSpeed;
[SerializeField] private float runSpeed;
private Vector3 moveDirection;
private Vector3 velocity;
[SerializeField] private bool isGrounded;
[SerializeField] private float groundCheckDistance;
[SerializeField] private LayerMask groundMask;
[SerializeField] private float gravity;
//REFERENCES
private CharacterController controller;
private void Start()
{
controller = GetComponent<CharacterController>();
}
private void Update()
{
Move();
}
private void Move()
{
isGrounded = Physics.CheckSphere(transform.position, groundCheckDistance, groundMask);
if(isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float moveZ = Input.GetAxis("Vertical");
moveDirection = new Vector3(0, 0, moveZ);
if(isGrounded)
{
if(moveDirection != Vector3.zero && !Input.GetKey(KeyCode.LeftShift))
{
Walk();
}
else if(moveDirection != Vector3.zero && Input.GetKey(KeyCode.LeftShift))
{
Run();
}
else if(moveDirection == Vector3.zero)
{
Idle();
}
moveDirection *= moveSpeed;
}
controller.Move(moveDirection * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
private void Idle()
{
}
private void Walk()
{
moveSpeed = walkSpeed;
}
private void Run()
{
moveSpeed = runSpeed;
}
}
I found the problem. Problem was with spawn area or call it how you want. If you'll move further the problem is no longer there.
Look at this video here: https://youtu.be/xfxgwmuPQsA
I'm using Unity New Input System for my FPS game and I have figured out the movement and the mouselook. However, I'm trying to add a crawling feature to my moving script. I don't want the player to be holding down a button for crawling, it would be better to click a button to change the status from walking to crawling and then just move accordingly. and of course, the mouselook will differ in every state. How would I achieve that with the minimal code changes?
Movement class:
public class Movement : MonoBehaviour
{
[SerializeField] CharacterController controller;
[SerializeField] float walkSpeed = 10f;
[SerializeField] float runSpeed = 35f;
float moveSpeed;
Vector2 horizontalInput;
[SerializeField] float jumpHeight = 3.5f;
bool jump, running;
[SerializeField] float gravity = -30f; //-9.81
Vector3 verticalVelocity = Vector3.zero;
[SerializeField] LayerMask groundMask;
bool isGrounded;
Vector3 horizontalVelocity;
private void Update()
{
isGrounded = Physics.CheckSphere(transform.position, 0.1f, groundMask);
if (isGrounded)
{
verticalVelocity.y = 0;
}
// Jump: v = sqrt(-2 * jumpheight* gravity)
if (jump)
{
if (isGrounded)
{
verticalVelocity.y = Mathf.Sqrt(-2f * jumpHeight * gravity);
}
jump = false;
}
verticalVelocity.y += gravity * Time.deltaTime;
controller.Move(verticalVelocity * Time.deltaTime);
if (running)
{
moveSpeed = runSpeed;
horizontalVelocity = (transform.right * horizontalInput.x + transform.forward * horizontalInput.y) * moveSpeed;
controller.Move(horizontalVelocity * Time.deltaTime);
}
else
{
moveSpeed = walkSpeed;
horizontalVelocity = (transform.right * horizontalInput.x + transform.forward * horizontalInput.y) * moveSpeed;
controller.Move(horizontalVelocity * Time.deltaTime);
}
}
public void ReceiveInput(Vector2 _horizontalInput)
{
horizontalInput = _horizontalInput;
}
public void OnJumpPressed()
{
jump = true;
}
public void OnRunningPressed() {
running = true;
}
}
MouseLook class:
public class MouseLook : MonoBehaviour
{
[SerializeField] float sensitivityX = 8f;
[SerializeField] float sensitivityY = 0.5f;
float mouseX, mouseY;
[SerializeField] Transform playerCamera;
[SerializeField] float xClamp = 75f;
float xRotataion = 0f;
private void Update()
{
transform.Rotate(Vector3.up, mouseX * Time.fixedDeltaTime);
xRotataion -= mouseY;
xRotataion = Mathf.Clamp(xRotataion, -xClamp, xClamp);
Vector3 targetRotation = transform.eulerAngles;
targetRotation.x = xRotataion;
playerCamera.eulerAngles = targetRotation;
}
public void ReceiveInput(Vector2 mouseInput)
{
mouseX = mouseInput.x * sensitivityX;
mouseY = mouseInput.y * sensitivityY;
}
}
InputManager class:
public class InputManager : MonoBehaviour
{
[SerializeField] Movement movement;
[SerializeField] PlayerInteractions playerInteractions;
[SerializeField] MouseLook mouseLook;
PlayerControls controls;
PlayerControls.GroundMovementActions groundMovement;
Vector2 horizontalInput;
Vector2 mouseInput;
private void Awake()
{
controls = new PlayerControls();
groundMovement = controls.GroundMovement;
// groundMovement.[action].performed += context => do something
groundMovement.HorizontalMovement.performed += ctx => horizontalInput = ctx.ReadValue<Vector2>();
groundMovement.Jump.performed += _ => movement.OnJumpPressed();
groundMovement.Running.performed += _ => movement.OnRunningPressed();
groundMovement.PickingUp.performed += _ => playerInteractions.OnPickingUp();
groundMovement.MouseX.performed += ctx => mouseInput.x = ctx.ReadValue<float>();
groundMovement.MouseY.performed += ctx => mouseInput.y = ctx.ReadValue<float>();
groundMovement.Open.performed += _ => playerInteractions.OnOpenPressed();
}
private void Update()
{
movement.ReceiveInput(horizontalInput);
mouseLook.ReceiveInput(mouseInput);
}
private void OnEnable()
{
controls.Enable();
}
private void OnDestroy()
{
controls.Disable();
}
}
I failed to find anything like this online and I don't know how to achieve it using the new input system but here is my attempt:
public class crawlScript : MonoBehaviour
{
CapsuleCollider playerCol;
float originalHeight;
public float reducedHeight;
bool crawl = false;
void Start()
{
playerCol= GetComponent<CapsuleCollider>();
originalHeight= playerCol.height;
}
// Update is called once per frame
void Update()
{
if (crawl)
{
OnCrouch();
}
else if (!crawl)
{
GoUp();
}
}
public void OnCrouch()
{
playerCol.height= reducedHeight;
}
void GoUp()
{
playerCol.height = originalHeight;
}
public void OnCrawl()
{
crawl= true;
}
And added this to the InputManager class:
groundMovement.Crawl.performed += _ => crawlscript.OnCrawl();
You will need to
Create a public boolean variable for whether the player is crawling or not, because this will almost certainly be needed in the future by this script or other scripts.
Create a crawling animation
Create two functions for enabling and disabling crawl, that will toggle the animation, change the players walk speed, and do other things that you may want to add (like toggle the visibility of any objects in the player's hands until they get back up).
The code should look something like this:
public String crawlkey = "left shift";
public bool iscrawling = false;
// put in Update()
if(!crawling){
if(Input.GetKeyDown(crawlkey)){
iscrawling = true;
handleCrawlStart();
}
} else if(Input.GetKeyDown(crawlkey)){
iscrawling = false;
handleCrawlEnd;
}
The problem is that when I import the code to the character it does not add the Player Input automatically and also it doesnt move at all when I press neither the controller nor the keyboard, Ive checked the code so many times but ill paste it here, it doesnt work if I add the player input manually either :(
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
[RequireComponent(typeof(CharacterController))]
[RequireComponent(typeof(PlayerInput))]
public class TwinStickMovement : MonoBehaviour
{
[SerializeField] private float playerSpeed = 5f;
[SerializeField] private float gravityValue = -9.81f;
[SerializeField] private float controllerDeadzone = 0.1f;
[SerializeField] private float gamepadRotateSmoothing = 1000f;
[SerializeField] private bool isGamepad;
private CharacterController controller;
private Vector2 movement;
private Vector2 aim;
private Vector3 playerVelocity;
private PlayerControls playerControls;
private PlayerInput playerInput;
private void Awake()
{
controller = GetComponent<CharacterController>();
playerControls = new PlayerControls();
playerInput = GetComponent<PlayerInput>();
}
private void OnEnable()
{
playerControls.Enable();
}
private void OnDisable()
{
playerControls.Disable();
}
void Update()
{
HandleInput();
HandleMovement();
HandleRotation();
}
void HandleInput()
{
movement = playerControls.Controls.Movement.ReadValue<Vector2>();
aim = playerControls.Controls.Aim.ReadValue<Vector2>();
}
void HandleMovement()
{
Vector3 move = new Vector3(movement.x, 0, movement.y);
controller.Move(move * Time.deltaTime * playerSpeed);
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
void HandleRotation()
{
}
}```
Im trying to make a 3d game with unity, but i dont know how to implement gravity, so i turned gravity for the rigidbody on. Also how could i implement jumping and wallrunning into this code?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
float playerHeight = 2f;
public float moveSpeed = 6f;
float horizontalMovement;
float verticalMovement;
Vector3 moveDirection;
Rigidbody rb;
private void Start()
{
rb = GetComponent <Rigidbody>();
rb.freezeRotation = true;
}
bool isGrounded;
private void Update()
{
isGrounded = Physics.Raycast(transform.position, Vector3.down, playerHeight / 2 + 0.01f);
print (isGrounded);
MyInput();
}
void MyInput()
{
horizontalMovement = Input.GetAxisRaw("Horizontal");
verticalMovement = Input.GetAxisRaw("Vertical");
moveDirection = transform.forward * verticalMovement + transform.right * horizontalMovement;
}
private void FixedUpdate()
{
MovePlayer();
}
void MovePlayer()
{
rb.AddForce(moveDirection.normalized * moveSpeed, ForceMode.Acceleration);
}
}
I've been having problems with getting my character to jump Forward. I've got it set to jump in place but I can't seem to get the JumpFor() to move forward as it jumps. I've tried Vector3 but it only works in 1 direction and transform.forward doesn't seem to work at all.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
//VARIABLES
[SerializeField] private float moveSpeed;
[SerializeField] private float walkSpeed;
[SerializeField] private float runSpeed;
private Vector3 moveDirection;
private Vector3 velocity;
[SerializeField] private bool isGrounded;
[SerializeField] private float groundCheckDistance;
[SerializeField] private LayerMask groundMask;
[SerializeField] private float gravity;
[SerializeField] private float jumpHeight;
//REFERENCES
private CharacterController controller;
private Animator anim;
private Collider Collider;
private void Start()
{
controller = GetComponent();
anim = GetComponentInChildren();
Collider = GetComponent(); ;
}
private void Update()
{
Move();
}
private void Move()
{
isGrounded = Physics.CheckBox(Collider.bounds.center, Collider.bounds.extents, transform.rotation, groundMask);
if (isGrounded && velocity.y < 0)
velocity.y = -2f;
float moveZ = Input.GetAxis("Vertical");
moveDirection = new Vector3(0, 0, moveZ);
moveDirection = transform.TransformDirection(moveDirection);
if (isGrounded)
{
if (moveDirection != Vector3.zero && !Input.GetKey(KeyCode.LeftShift))
{
Walk();
}
else if (moveDirection != Vector3.zero && Input.GetKey(KeyCode.LeftShift))
{
Run();
}
else if (moveDirection == Vector3.zero)
{
Idle();
}
moveDirection *= moveSpeed;
if (isGrounded && Input.GetKeyDown(KeyCode.Space) && moveDirection == Vector3.zero )
{
Jump();
}
if (isGrounded && Input.GetKeyDown(KeyCode.Space) && Input.GetKey(KeyCode.W) && moveDirection != Vector3.zero)
{
JumpFor();
}
anim.SetBool("Jump", false);
anim.SetBool("JumpUp", false);
}
if (!isGrounded)
anim.SetBool("Jump", true);
controller.Move(moveDirection * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
private void Idle()
{
anim.SetFloat("Speed", 0, 0.02f, Time.deltaTime);
}
private void Walk()
{
moveSpeed = walkSpeed;
anim.SetFloat("Speed", 0.6f, 0.1f, Time.deltaTime);
}
private void Run()
{
moveSpeed = runSpeed;
anim.SetFloat("Speed", 1, 0.1f, Time.deltaTime);
}
private void Jump()
{
velocity.y = Mathf.Sqrt(jumpHeight * -2 * gravity);
}
private void JumpFor()
{
velocity.y = Mathf.Sqrt(jumpHeight * -2 * gravity);
}
}
I Solved it. I ended up using the velocity vector in JumpFor() and gave it a new Vector3 Then I put velocity= transform.TransformDirection(velocity) so it uses the local axis instead of the global one. After that is et it so velocity = Vector3.zero when the player grounds.
Blockquote
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
//VARIABLES
[SerializeField] private float moveSpeed;
[SerializeField] private float walkSpeed;
[SerializeField] private float runSpeed;
[SerializeField] private float JumpDist;
private Vector3 moveDirection;
private Vector3 velocity;
[SerializeField] private bool isGrounded;
[SerializeField] private float groundCheckDistance;
[SerializeField] private LayerMask groundMask;
[SerializeField] private float gravity;
[SerializeField] private float jumpHeight;
//REFERENCES
private CharacterController controller;
private Animator anim;
private Collider Collider;
private Rigidbody rb;
private Transform tran;
private void Start()
{
controller = GetComponent<CharacterController>();
anim = GetComponentInChildren<Animator>();
Collider = GetComponent<BoxCollider>(); ;
rb = GetComponent<Rigidbody>();
tran = GetComponent<Transform>();
}
private void Update()
{
Move();
}
private void Move()
{
isGrounded = Physics.CheckBox(Collider.bounds.center, Collider.bounds.extents, transform.rotation, groundMask);
if (isGrounded && velocity.y < 0)
{
velocity.y = -2f;
}
float moveZ = Input.GetAxis("Vertical");
moveDirection = new Vector3(0, 0, moveZ);
moveDirection = transform.TransformDirection(moveDirection);
if (isGrounded)
{
velocity = Vector3.zero;
if (moveDirection != Vector3.zero && !Input.GetKey(KeyCode.LeftShift))
{
Walk();
}
else if (moveDirection != Vector3.zero && Input.GetKey(KeyCode.LeftShift))
{
Run();
}
else if (moveDirection == Vector3.zero)
{
Idle();
}
moveDirection *= moveSpeed;
if (isGrounded && Input.GetKeyDown(KeyCode.Space) && moveDirection == Vector3.zero )
{
Jump();
}
if (isGrounded && Input.GetKeyDown(KeyCode.Space) && Input.GetKey(KeyCode.W) && moveDirection != Vector3.zero)
{
JumpFor();
}
anim.SetBool("Jump", false);
anim.SetBool("JumpUp", false);
}
if (!isGrounded)
{
anim.SetBool("Jump", true);
}
controller.Move(moveDirection * Time.deltaTime);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
private void Idle()
{
anim.SetFloat("Speed", 0, 0.02f, Time.deltaTime);
}
private void Walk()
{
moveSpeed = walkSpeed;
anim.SetFloat("Speed", 0.6f, 0.1f, Time.deltaTime);
}
private void Run()
{
moveSpeed = runSpeed;
anim.SetFloat("Speed", 1, 0.1f, Time.deltaTime);
}
private void Jump()
{
velocity.y = Mathf.Sqrt(jumpHeight * -2 * gravity);
}
private void JumpFor()
{
velocity = new Vector3(0, Mathf.Sqrt(jumpHeight * -2 * gravity), Mathf.Sqrt(jumpHeight * -2 * gravity));
velocity= transform.TransformDirection(velocity);
}
}
Blockquote