Reputation: 133
I have something strange happening in my game.I use 3d models and a fixed camera to make a 2D platformer. I have a charactercontroller with the following script for movement and jumping:
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private CharacterController controller;
private Vector3 playerVelocity;
private bool groundedPlayer;
[SerializeField] private Animator _animator;
[SerializeField] private float playerSpeed = 2.0f;
[SerializeField] private float jumpHeight = 4.0f;
[SerializeField] private float gravityValue = -1f;
[SerializeField] private AudioSource _audioSource;
[SerializeField] private AudioClip _stepStone;
private void Start()
{
controller = GetComponent<CharacterController>();
_animator = GetComponent<Animator>();
_audioSource = GetComponent<AudioSource>();
}
void Update()
{
MovePlayer();
}
private void MovePlayer()
{
float x = Input.GetAxis("Horizontal");
groundedPlayer = controller.isGrounded;
if (groundedPlayer && playerVelocity.y < 0)
{
playerVelocity.y = 0f;
_animator.SetBool("Jumping", false);
}
Vector3 move = new Vector3(x, 0,0);
controller.Move(move * Time.deltaTime * playerSpeed);
if (move != Vector3.zero)
{
gameObject.transform.forward = move;
}
// Changes the height position of the player..
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
_animator.SetBool("Jumping", true);
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
}
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
if (groundedPlayer)
{
_animator.SetInteger("Speed", Convert.ToInt32(x));
}
}
public void playStoneStep()
{
_audioSource.PlayOneShot(_stepStone);
}
}
My character bounces if it jumps on platforms but not when falling on them. I tried a non bouncy material. how can I fix this? Here is a video showing it : https://youtu.be/ZhV8nHklsH8
Upvotes: 0
Views: 81
Reputation: 2598
I would do this by adding something that checks if you land on the floor. I did below split your functionality into different, more manageable parts. I've added a layer mask which you will need to configure with the layer of the ground.
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement: MonoBehaviour
{
private CharacterController controller;
private Vector3 playerVelocity;
private bool groundedPlayer;
[SerializeField] private Animator _animator;
[SerializeField] private float playerSpeed = 2.0f;
[SerializeField] private float jumpHeight = 4.0f;
[SerializeField] private float gravityValue = -1f;
[SerializeField] privateLayerMask groundMask;
[SerializeField] private AudioSource _audioSource;
[SerializeField] private AudioClip _stepStone;
private void Start()
{
controller = GetComponent<CharacterController>();
_animator = GetComponent<Animator>();
_audioSource = GetComponent<AudioSource>();
}
void Update()
{
HandleMovement();
HandleJump();
HandleGravity();
}
private void HandleMovement()
{
controller.Move(new Vector3(Input.GetAxis("Horizontal"), 0,0) * Time.deltaTime * playerSpeed);
if (groundedPlayer)
{
_animator.SetInteger("Speed", Convert.ToInt32(x));
}
}
private void HandleJump()
{
if (Input.GetButtonDown("Jump") && groundedPlayer)
{
_animator.SetBool("Jumping", true);
playerVelocity.y += Mathf.Sqrt(jumpHeight * -3.0f * gravityValue);
}
}
private void HandleGravity()
{
playerVelocity.y += gravityValue * Time.deltaTime;
controller.Move(playerVelocity * Time.deltaTime);
}
void OnCollisionEnter(Collision col)
{
if (IsInLayerMask(col.gameObject, groundMask))
{
playerVelocity.y = 0f;
_animator.SetBool("Jumping", false);
}
}
private bool IsInLayerMask(GameObject obj, LayerMask layerMask)
{
return ((layerMask.value & (1 << obj.layer)) > 0);
}
public void playStoneStep()
{
_audioSource.PlayOneShot(_stepStone);
}
}
Upvotes: 1