How to make crouch/uncrouch smooth? - unity3d

I'm trying to make the crouching/standing-up smoother and slower, as currently crouching/uncrouching is so quick(I mean transition between crouching/uncrouching)
private void Start()
{
startYScale = transform.localScale.y;
mainCamera = Camera.main;
}
private void PlayerMovement()
{
currentSpeed = moveSpeed;
move = controls.Player.Movement.ReadValue<Vector2>();
movement = (move.y * transform.forward) + (move.x * transform.right);
if (isRunning)
{
//run = controls.Player.Run.ReadValue<float>();
currentSpeed = runSpeed;
Vector3 running = (move.y * transform.forward) + (move.x * transform.right);
controller.Move(running * currentSpeed * Time.deltaTime);
}
if (crouching)
{
currentSpeed = crouchSpeed;
isRunning = false;
transform.localScale = new Vector3(transform.localScale.x, crouchYScale, transform.localScale.z);
// controller.radius = 0.2f;
}
else
{
currentSpeed = moveSpeed;
transform.localScale = new Vector3(transform.localScale.x, startYScale, transform.localScale.z);
}
controller.Move(movement * currentSpeed * Time.deltaTime);
}
How would I fix that? is there a way to make the transition slower and smoother? please help.
Edit:
I tried changing the position of the camera too when crouching to make the transition from standing up to crouching smoother.
private void FixedUpdate()
{
var desierdHeight = crouching ? crouchYScale : startYScale;
if (controller.height != desierdHeight)
{
AdjustHeight(desierdHeight);
/* var camPos = playerCamera.transform.position;
camPos.y = controller.height;
playerCamera.transform.position = camPos;*/
playerCamera.transform.localPosition = new Vector3(0,controller.height, 0);
}
}
private void AdjustHeight(float height)
{
float center = height / 2;
controller.height = Mathf.Lerp(controller.height, height, crouchSpeed);
controller.center = Vector3.Lerp(controller.center, new Vector3(0, center,0), crouchSpeed);
}
but the transition is still fast.

Related

Player jumps a second time by itself after hitting the ground

I'm trying to make a First Person Controller and after I jump, right as the player is about to hit the ground, it jumps a second time by itself. This doesn't seem to be the case when the player lands on ground higher or lower than the ground it originally jumped on.
This is my Player code:
`
using System;
using UnityEngine;
using UnityEngine.InputSystem;
public class Player : MonoBehaviour
{
[SerializeField] float mouseSensitivity = 3f;
[SerializeField] float walkingSpeed = 10f;
[SerializeField] float flyingSpeed = 15;
[SerializeField] float climbingSpeed = 5f;
[SerializeField] float mass = 1f;
[SerializeField] float acceleration = 20f;
[SerializeField] float worldBottomBoundary = -100f;
public Transform cameraTransform;
public bool IsGrounded => controller.isGrounded;
public float Height
{
get => controller.height;
set => controller.height = value;
}
public event Action OnBeforeMove;
public event Action<bool> OnGroundStateChange;
internal float movementSpeedMultiplier;
State _state;
public State CurrentState
{
get => _state;
set
{
_state = value;
velocity = Vector3.zero;
}
}
public enum State
{
Walking,
Flying,
Climbing
}
CharacterController controller;
internal Vector3 velocity;
Vector2 look;
(Vector3, Quaternion) initialPositionAndRotation;
bool wasGrounded;
PlayerInput playerInput;
InputAction moveAction;
InputAction lookAction;
InputAction flyUpDownAction;
void Awake()
{
controller = GetComponent<CharacterController>();
playerInput = GetComponent<PlayerInput>();
moveAction = playerInput.actions["move"];
lookAction = playerInput.actions["look"];
flyUpDownAction = playerInput.actions["flyUpDown"];
}
void Start()
{
Cursor.lockState = CursorLockMode.Locked;
initialPositionAndRotation = (transform.position, transform.rotation);
}
public void Teleport(Vector3 position, Quaternion rotation)
{
transform.position = position;
Physics.SyncTransforms();
look.x = rotation.eulerAngles.y;
look.y = rotation.eulerAngles.z;
velocity = Vector3.zero;
}
void Update()
{
movementSpeedMultiplier = 1f;
switch (CurrentState)
{
case State.Walking:
UpdateGround();
UpdateGravity();
UpdateMovement();
UpdateLook();
CheckBounds();
break;
case State.Flying:
UpdateMovementFlying();
UpdateLook();
break;
case State.Climbing:
UpdateMovementClimbing();
UpdateLook();
break;
}
}
void CheckBounds()
{
if (transform.position.y < worldBottomBoundary)
{
var (position, rotation) = initialPositionAndRotation;
Teleport(position, rotation);
}
}
void UpdateGround()
{
if (wasGrounded != IsGrounded)
{
OnGroundStateChange?.Invoke(IsGrounded);
wasGrounded = IsGrounded;
}
}
void UpdateGravity()
{
var gravity = Physics.gravity * mass * Time.deltaTime;
velocity.y = IsGrounded ? -1f : velocity.y + gravity.y;
}
Vector3 GetMovementInput(float speed, bool horizontal = true)
{
var moveInput = moveAction.ReadValue<Vector2>();
var flyUpDownInput = flyUpDownAction.ReadValue<float>();
var input = new Vector3();
var referenceTransform = horizontal ? transform : cameraTransform;
input += referenceTransform.forward * moveInput.y;
input += referenceTransform.right * moveInput.x;
if (!horizontal)
{
input += transform.up * flyUpDownInput;
}
input = Vector3.ClampMagnitude(input, 1f);
input *= speed * movementSpeedMultiplier;
return input;
}
void UpdateMovement()
{
OnBeforeMove?.Invoke();
var input = GetMovementInput(walkingSpeed);
var factor = acceleration * Time.deltaTime;
velocity.x = Mathf.Lerp(velocity.x, input.x, factor);
velocity.z = Mathf.Lerp(velocity.z, input.z, factor);
controller.Move(velocity * Time.deltaTime);
}
void UpdateMovementFlying()
{
var input = GetMovementInput(flyingSpeed, false);
var factor = acceleration * Time.deltaTime;
velocity = Vector3.Lerp(velocity, input, factor);
controller.Move(velocity * Time.deltaTime);
}
void UpdateMovementClimbing()
{
var input = GetMovementInput(climbingSpeed, false);
var forwardInputFactor = Vector3.Dot(transform.forward, input.normalized);
if (forwardInputFactor > 0)
{
input.x = input.x * .5f;
input.z = input.z * .5f;
if (Mathf.Abs(input.y) > .2f)
{
input.y = Mathf.Sign(input.y) * climbingSpeed;
}
}
else
{
input.y = 0;
input.x = input.x * 3f;
input.z = input.z * 3f;
}
var factor = acceleration * Time.deltaTime;
velocity = Vector3.Lerp(velocity, input, factor);
controller.Move(velocity * Time.deltaTime);
}
void UpdateLook()
{
var lookInput = lookAction.ReadValue<Vector2>();
look.x += lookInput.x * mouseSensitivity;
look.y += lookInput.y * mouseSensitivity;
look.y = Mathf.Clamp(look.y, -90, 90f);
cameraTransform.localRotation = Quaternion.Euler(-look.y, 0, 0);
transform.localRotation = Quaternion.Euler(0, look.x, 0);
}
void OnToggleFlying()
{
CurrentState = CurrentState == State.Flying ? State.Walking : State.Flying;
}
}
`
And this is my PlayerJumping code:
`
using UnityEngine;
[RequireComponent(typeof(Player))]
public class PlayerJumping : MonoBehaviour
{
[SerializeField] float jumpSpeed = 5f;
[SerializeField] float jumpPressBufferTime = .05f;
[SerializeField] float jumpGroundGraceTime = .2f;
[SerializeField] int maxJumps = 1;
Player player;
bool tryingToJump;
float lastJumpPressTime;
float lastGroundedTime;
int jumps;
void Awake()
{
player = GetComponent<Player>();
}
void OnEnable()
{
player.OnBeforeMove += OnBeforeMove;
player.OnGroundStateChange += OnGroundStateChange;
}
void OnDisable()
{
player.OnBeforeMove -= OnBeforeMove;
player.OnGroundStateChange -= OnGroundStateChange;
}
void OnJump()
{
tryingToJump = true;
lastJumpPressTime = Time.time;
}
void OnBeforeMove()
{
if (player.IsGrounded) jumps = 0;
var wasTryingToJump = Time.time - lastJumpPressTime < jumpPressBufferTime;
var wasGrounded = Time.time - lastGroundedTime < jumpGroundGraceTime;
var isOrWasTryingToJump = tryingToJump || (wasTryingToJump && player.IsGrounded);
var isOrWasGrounded = player.IsGrounded || wasGrounded;
var jumpAllowed = jumps < maxJumps;
if (
jumpAllowed && isOrWasTryingToJump && isOrWasGrounded
|| jumpAllowed && tryingToJump
)
{
player.velocity.y += jumpSpeed;
jumps++;
}
tryingToJump = false;
}
void OnGroundStateChange(bool isGrounded)
{
if (!isGrounded) lastGroundedTime = Time.time;
}
}
`
Although to be honest, I've checked a million times and I'm starting to believe the problem isn't in the code but in the inspector, but don't let that cloud your judgement because I can be pretty stupid at times. Do you have any ideas?

how do i stop my character moving to far after slope

after my character goes up a slope or stairs while sprinting it keeps the momentum and usually flies over the platform at the top because hes moving too fast how would i get him to stay on the ground coming out of a slope but still be able to jump
im using a rigid body and heres the script im using to move the character
{
[Header("Movement")]
private float moveSpeed;
public float walkSpeed;
public float sprintSpeed;
public float slideSpeed;
private float desiredMoveSpeed;
private float lastDesiredMoveSpeed;
public float speedIncreaseMultiplier;
public float slopeIncreaseMultiplier;
public float groundDrag;
[Header("Jumping")]
public float jumpForce;
public float jumpCooldown;
public float airMultiplier;
bool readyToJump;
[Header("Crouching")]
public float crouchSpeed;
public float crouchYScale;
private float startYScale;
[Header("Keybinds")]
public KeyCode jumpKey = KeyCode.Space;
public KeyCode sprintKey = KeyCode.LeftShift;
public KeyCode crouchKey = KeyCode.LeftControl;
[Header("Ground Check")]
public float playerHeight;
public LayerMask whatIsGround;
bool grounded;
[Header("Slope Handling")]
public float maxSlopeAngle;
private RaycastHit slopeHit;
private bool exitingSlope;
public Rigidbody playerRb;
public Transform orientation;
float horizontalInput;
float verticalInput;
Vector3 moveDirection;
Rigidbody rb;
public MovementState state;
public enum MovementState
{
walking,
sprinting,
crouching,
sliding,
air
}
public bool sliding;
private void Start()
{
rb = GetComponent<Rigidbody>();
rb.freezeRotation = true;
readyToJump = true;
startYScale = transform.localScale.y;
}
private void Update()
{
// ground check
grounded = Physics.Raycast(transform.position, Vector3.down, playerHeight * 0.5f + 0.2f, whatIsGround);
MyInput();
SpeedControl();
StateHandler();
// handle drag
if (grounded)
rb.drag = groundDrag;
else
rb.drag = 0;
}
private void FixedUpdate()
{
MovePlayer();
}
private void MyInput()
{
horizontalInput = Input.GetAxisRaw("Horizontal");
verticalInput = Input.GetAxisRaw("Vertical");
// when to jump
if (Input.GetKey(jumpKey) && readyToJump && grounded)
{
readyToJump = false;
Jump();
Invoke(nameof(ResetJump), jumpCooldown);
}
// start crouch
if (Input.GetKeyDown(crouchKey))
{
transform.localScale = new Vector3(transform.localScale.x, crouchYScale, transform.localScale.z);
rb.AddForce(Vector3.down * 5f, ForceMode.Impulse);
}
// stop crouch
if (Input.GetKeyUp(crouchKey))
{
transform.localScale = new Vector3(transform.localScale.x, startYScale, transform.localScale.z);
}
}
private void StateHandler()
{
// Mode - Sliding
if (sliding)
{
state = MovementState.sliding;
if (OnSlope() && rb.velocity.y < 0.1f)
desiredMoveSpeed = slideSpeed;
else
desiredMoveSpeed = sprintSpeed;
}
// Mode - Crouching
else if (Input.GetKey(crouchKey))
{
state = MovementState.crouching;
desiredMoveSpeed = crouchSpeed;
}
// Mode - Sprinting
else if (grounded && Input.GetKey(sprintKey))
{
state = MovementState.sprinting;
desiredMoveSpeed = sprintSpeed;
}
// Mode - Walking
else if (grounded)
{
state = MovementState.walking;
desiredMoveSpeed = walkSpeed;
}
// Mode - Air
else
{
state = MovementState.air;
}
// check if desiredMoveSpeed has changed drastically
if (Mathf.Abs(desiredMoveSpeed - lastDesiredMoveSpeed) > 4f && moveSpeed != 0)
{
StopAllCoroutines();
StartCoroutine(SmoothlyLerpMoveSpeed());
}
else
{
moveSpeed = desiredMoveSpeed;
}
lastDesiredMoveSpeed = desiredMoveSpeed;
}
private IEnumerator SmoothlyLerpMoveSpeed()
{
// smoothly lerp movementSpeed to desired value
float time = 0;
float difference = Mathf.Abs(desiredMoveSpeed - moveSpeed);
float startValue = moveSpeed;
while (time < difference)
{
moveSpeed = Mathf.Lerp(startValue, desiredMoveSpeed, time / difference);
if (OnSlope())
{
float slopeAngle = Vector3.Angle(Vector3.up, slopeHit.normal);
float slopeAngleIncrease = 1 + (slopeAngle / 90f);
time += Time.deltaTime * speedIncreaseMultiplier * slopeIncreaseMultiplier * slopeAngleIncrease;
}
else
time += Time.deltaTime * speedIncreaseMultiplier;
yield return null;
}
moveSpeed = desiredMoveSpeed;
}
private void MovePlayer()
{
// calculate movement direction
moveDirection = orientation.forward * verticalInput + orientation.right * horizontalInput;
// on slope
if (OnSlope() && !exitingSlope)
{
rb.AddForce(GetSlopeMoveDirection(moveDirection) * moveSpeed * 20f, ForceMode.Force);
if (rb.velocity.y > 0)
rb.AddForce(Vector3.down * 80f, ForceMode.Force);
}
// on ground
else if (grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f, ForceMode.Force);
// in air
else if (!grounded)
rb.AddForce(moveDirection.normalized * moveSpeed * 10f * airMultiplier, ForceMode.Force);
// turn gravity off while on slope
rb.useGravity = !OnSlope();
}
private void SpeedControl()
{
// limiting speed on slope
if (OnSlope() && !exitingSlope)
{
if (rb.velocity.magnitude > moveSpeed)
rb.velocity = rb.velocity.normalized * moveSpeed;
}
// limiting speed on ground or in air
else
{
Vector3 flatVel = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
// limit velocity if needed
if (flatVel.magnitude > moveSpeed)
{
Vector3 limitedVel = flatVel.normalized * moveSpeed;
rb.velocity = new Vector3(limitedVel.x, rb.velocity.y, limitedVel.z);
}
}
}
private void Jump()
{
exitingSlope = true;
// reset y velocity
rb.velocity = new Vector3(rb.velocity.x, 0f, rb.velocity.z);
rb.AddForce(transform.up * jumpForce, ForceMode.Impulse);
}
private void ResetJump()
{
readyToJump = true;
exitingSlope = false;
}
public bool OnSlope()
{
if (Physics.Raycast(transform.position, Vector3.down, out slopeHit, playerHeight * 0.5f + 0.3f))
{
float angle = Vector3.Angle(Vector3.up, slopeHit.normal);
return angle < maxSlopeAngle && angle != 0;
}
return false;
}
public Vector3 GetSlopeMoveDirection(Vector3 direction)
{
return Vector3.ProjectOnPlane(direction, slopeHit.normal).normalized;
}
}```

Character Controller. Jumping Does not work Correctly. Lands In Air

Can Anyone Tell me what's wrong with this script. Whenever I try to get my character to jump, the animation is delayed for a second. When I land, he lands above the ground and then drops down. It looks like the character controller is hitting the ground first, so he hovers above the ground before actually dropping onto it.
using UnityEngine;
public class JumpingState : State
{
bool grounded;
float gravityValue;
float jumpHeight;
float playerSpeed;
Vector3 airVelocity;
public JumpingState(Character _character, StateMachine _stateMachine) : base(_character, _stateMachine)
{
character = _character;
stateMachine = _stateMachine;
}
public override void Enter()
{
base.Enter();
grounded = false;
gravityValue = character.gravityValue;
jumpHeight = character.jumpHeight;
playerSpeed = character.playerSpeed;
gravityVelocity.y = 0;
character.animator.SetFloat("speed", 0);
character.animator.SetTrigger("jump");
Jump();
}
public override void HandleInput()
{
base.HandleInput();
input = moveAction.ReadValue<Vector2>();
}
public override void LogicUpdate()
{
base.LogicUpdate();
if (grounded)
{
stateMachine.ChangeState(character.landing);
}
}
public override void PhysicsUpdate()
{
base.PhysicsUpdate();
if (!grounded) // if not in landing state
{
velocity = character.playerVelocity;
airVelocity = new Vector3(input.x, 0, input.y);
// velocity = velocity.x * character.cameraTransform.right.normalized + velocity.z * character.cameraTransform.forward.normalized;
velocity.y = 0f;
// airVelocity = airVelocity.x * character.cameraTransform.right.normalized + airVelocity.z * character.cameraTransform.forward.normalized;
airVelocity.y = 0f;
character.controller.Move(gravityVelocity * Time.deltaTime +
(airVelocity * character.airControl + velocity * (1 - character.airControl)) *
playerSpeed * Time.deltaTime);
}
gravityVelocity.y += gravityValue * Time.deltaTime;
grounded = character.controller.isGrounded;
}
void Jump()
{
gravityVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
}
}

My playable character turns left or right when it meets an obstacle

My playable character turns left or right when it meets an obstacle with a collider. It's normal but I want to know if there is a way to disable it.
this is the script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMotor : MonoBehaviour
{
public Vector3 startPosition;
private const float LANE_DISTANCE = 3.0f;
private const float TURN_SPEED = 0.5f;
//Functionality
private bool isRunning = false;
public bool isClimbing = false;
private readonly object down;
private CharacterController controller;
[SerializeField]
private float jumpForce = 5.0f;
private float verticalVelocity = 0.0f;
private float gravity = 10.0f;
//Speed
private float originalSpeed = 4.0f;
private float speed = 4.0f;
private float speedIncreaseLastTick;
private float speedIncreaseTime = 2.5f;
private float speedIncreaseAmount = 0.1f;
private float climbingSpeed = 1.0f;
private int desiredLane = 0; //0 = left, 1 = middle, 2 = right
private Animator anim;
// Start is called before the first frame update
void Start()
{
speed = originalSpeed;
controller = GetComponent<CharacterController>();
anim = GetComponent<Animator>();
transform.position = startPosition;
}
// Update is called once per frame
void Update()
{
if (isClimbing)
{
transform.Translate(Vector3.up * climbingSpeed * Time.deltaTime);
}
if (!isRunning)
return;
if (Time.time - speedIncreaseLastTick > speedIncreaseTime)
{
speedIncreaseLastTick = Time.time;
speed += speedIncreaseAmount;
//GameManager.Instance.UpdateScores();
}
// Gather the inputs on wich lane we should be
if (MobileInput.Instance.SwipeLeft)
{
MoveLane(false);
}
if (MobileInput.Instance.SwipeRight)
{
MoveLane(true);
}
// Calculate where we should be horizontally
Vector3 targetPosition = transform.position.z * Vector3.forward;
int posX = Mathf.Abs(desiredLane);
if (desiredLane < 0)
targetPosition += Vector3.left * posX * LANE_DISTANCE;
else if (desiredLane > 0)
targetPosition += Vector3.right * posX * LANE_DISTANCE;
//Calculate move delta
Vector3 moveVector = Vector3.zero;
moveVector.x = (targetPosition - transform.position).normalized.x * speed;
bool isGrounded = IsGrounded();
anim.SetBool("Grounded", isGrounded);
//Calculate y
if (isGrounded) //If grounded
{
verticalVelocity = -0.1f;
if (MobileInput.Instance.SwipeUp)
{
//Jump
anim.SetTrigger("Jump");
verticalVelocity = jumpForce;
}
else if (MobileInput.Instance.SwipeDown)
{
//Slide
StartSliding();
Invoke("StopSliding", 1.0f);
}
}
else
{
verticalVelocity -= (gravity * Time.deltaTime);
//Fast falling machanics
if (MobileInput.Instance.SwipeDown)
{
verticalVelocity = -jumpForce;
}
}
moveVector.y = verticalVelocity;
moveVector.z = speed;
//Move the character
controller.Move(moveVector * Time.deltaTime);
//Rotate the player where is going
Vector3 dir = controller.velocity;
if (dir!= Vector3.zero)
{
dir.y = 0;
transform.forward = Vector3.Lerp(transform.forward, dir, TURN_SPEED);
}
}
// This function (MoveLane) allows the player to move to the left and to the right
private void MoveLane(bool goingRight)
{
if (!goingRight)
{
desiredLane--;
if (desiredLane == -6)
desiredLane = -5;
}
if (goingRight)
{
desiredLane++;
if (desiredLane == 6)
desiredLane = 5;
}
/* We wan rewrite the above function like this below
desiredLane += (goingRight) ? 1 : -1;
Mathf.Clamp(desiredLane, -5, 5);
*/
}
private bool IsGrounded()
{
Ray groundRay = new Ray(new Vector3(controller.bounds.center.x, (controller.bounds.center.y - controller.bounds.extents.y) + 0.2f,
controller.bounds.center.z), Vector3.down);
Debug.DrawRay(groundRay.origin, groundRay.direction, Color.cyan, 1.0f);
return (Physics.Raycast(groundRay, 0.2f + 0.1f));
}
public void StartRunning ()
{
isRunning = true;
anim.SetTrigger("StartRunning");
}
private void StartSliding()
{
anim.SetBool("Sliding", true);
controller.height /= 2;
controller.center = new Vector3(controller.center.x, controller.center.y / 2, controller.center.z);
}
private void StopSliding()
{
anim.SetBool("Sliding", false);
controller.height *= 2;
controller.center = new Vector3(controller.center.x, controller.center.y * 2, controller.center.z);
}
private void Crash()
{
anim.SetTrigger("Death");
isRunning = false;
}
private void OnControllerColliderHit(ControllerColliderHit hit)
{
switch(hit.gameObject.tag)
{
case "Obstacle":
Crash();
break;
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Ladder")
{
isRunning = false;
isClimbing = true;
anim.SetBool("ClimbingLadder", true);
}
else if (other.gameObject.tag == "LadderCol2")
{
isClimbing = false;
anim.SetBool("ClimbingLadder", false);
transform.Translate(Vector3.forward * 1);
isRunning = true;
}
}
}
I see the problem. It's from these lines
Vector3 dir = controller.velocity;
if (dir!= Vector3.zero)
{ dir.y = 0;
transform.forward =
Vector3.Lerp(transform.forward, dir,
TURN_SPEED);
}
I added them to rotate a bit the player when it turns left or right.

Player Swipe Movement Controller like subway surfer using Character Controller in Unity3D?

I am trying to make a player movement controller like subway surfer using Character Controller, every thing is working fine with keyboard but I am getting an issue in swipe. When I swipe its moving only one frame. And also I want player to go left and right while player in air(Jumping). Please help.
Here is my code:
using UnityEngine;
using System.Collections;
public class PlayerControllerScript : MonoBehaviour
{
public float speed = 8.0F;
public float jumpSpeed = 16.0F;
public float gravity = 80.0F;
private Vector3 moveDirection = Vector3.zero;
public int laneNumber = 1;
public int lanesCount = 3;
bool didChangeLastFrame = false;
public float laneDistance = 2;
public float firstLaneXPos = -2;
public float deadZone = 0.1f;
public float sideSpeed = 12;
private bool Right = false;
private bool Left = false;
void Update()
{
CharacterController controller = GetComponent<CharacterController>();
float input = Input.GetAxis("Horizontal");
if (controller.isGrounded) {
if (Mathf.Abs(input) > deadZone)
{
if (!didChangeLastFrame)
{
didChangeLastFrame = true;
laneNumber += Mathf.RoundToInt(Mathf.Sign(input));
if (laneNumber < 0) laneNumber = 0;
else if (laneNumber >= lanesCount) laneNumber = lanesCount - 1;
}
}
else
{
didChangeLastFrame = false;
moveDirection = new Vector3(0, 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton("Jump") || SwipeManager.IsSwipingUp())
moveDirection.y = jumpSpeed;
}
}
if (Left)
moveDirection.x = -jumpSpeed;
if (Right)
moveDirection.x = jumpSpeed;
if (SwipeManager.IsSwipingLeft())
{
Left = true;
Right = false;
}
if (SwipeManager.IsSwipingRight())
{
Right = true;
Left = false;
}
Vector3 pos = transform.position;
pos.x = Mathf.Lerp(pos.x, firstLaneXPos + laneDistance * laneNumber, Time.deltaTime * sideSpeed);
transform.position = pos;
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
}
I think,
if (Input.GetButton("Jump") || SwipeManager.IsSwipingUp())
moveDirection.y = jumpSpeed;
must be outside the if(controller.isGrounded) block. So, you jump regardless of gravity.
This is the final code;
using UnityEngine;
using System.Collections;
public class PlayerControllerScript : MonoBehaviour
{
public float speed = 8.0F;
public float jumpSpeed = 16.0F;
public float gravity = 80.0F;
private Vector3 moveDirection = Vector3.zero;
public int laneNumber = 1;
public int lanesCount = 3;
bool didChangeLastFrame = false;
public float laneDistance = 2;
public float firstLaneXPos = -2;
public float deadZone = 0.1f;
public float sideSpeed = 12;
private bool Right = false;
private bool Left = false;
void Update()
{
CharacterController controller = GetComponent<CharacterController>();
float input = Input.GetAxis("Horizontal");
if (controller.isGrounded) {
if (Mathf.Abs(input) > deadZone)
{
if (!didChangeLastFrame)
{
didChangeLastFrame = true;
laneNumber += Mathf.RoundToInt(Mathf.Sign(input));
if (laneNumber < 0) laneNumber = 0;
else if (laneNumber >= lanesCount) laneNumber = lanesCount - 1;
}
}
else
{
didChangeLastFrame = false;
moveDirection = new Vector3(0, 0, Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
}
}
if (Input.GetButton("Jump") || SwipeManager.IsSwipingUp())
moveDirection.y = jumpSpeed;
if (Left)
moveDirection.x = -jumpSpeed;
if (Right)
moveDirection.x = jumpSpeed;
if (SwipeManager.IsSwipingLeft())
{
Left = true;
Right = false;
}
if (SwipeManager.IsSwipingRight())
{
Right = true;
Left = false;
}
Vector3 pos = transform.position;
pos.x = Mathf.Lerp(pos.x, firstLaneXPos + laneDistance * laneNumber, Time.deltaTime * sideSpeed);
transform.position = pos;
moveDirection.y -= gravity * Time.deltaTime;
controller.Move(moveDirection * Time.deltaTime);
}
}