I should first volunteer I’m pretty new to both unity and programming in general (not to mention c# in specific), so apologies if I’m missing something obvious.
I’m creating a simple 2d platformer very much in the Mario style and am running into some bugs when making my character jump. I’ve written two scripts, one for controlling left/right movement and adding force to make the character jump, and a second using raycasting to determine if the player is grounded (and hence able to jump). Please see the code below.
I have two issues. One, between pressing play and entering the game state I seem to be able to store several jump inputs, such that my character jumps much higher at initialization. I assume this is the case because for some reason my grounding script is kicking in later than my movement script. Any advice on how to avoid this and if the player would experience the same or its just a quirk of the editor? I have noticed this same ability to store several inputs occurring randomly during gameplay as well, associated with a frame rate hitch usually (I’d note that I’m working on a high end machine and using only very low res sprites at this point, with few game objects in the scene).
Two, at seemingly random points my jump input doesn’t seem to register. I haven’t noticed any pattern, but have noticed it several times.
Any help the community could offer would be greatly appreciated.
Movement Script
using UnityEngine;
using System.Collections;
public class PlayerControllerMovement : MonoBehaviour {
public AudioClip jumpSmall;
private float moveSpeed = 1.6f;
private int jumpForce = 200;
private Animator animPlayer;
private PlayerGround playerGround;
void Movement() {
animPlayer.SetFloat("speed", Mathf.Abs(Input.GetAxis("Horizontal")));
if(Input.GetAxisRaw("Horizontal") > 0) {
transform.Translate(Vector2.right * moveSpeed * Time.deltaTime);
transform.eulerAngles = new Vector2 (0,0);
}
if(Input.GetAxisRaw("Horizontal") < 0) {
transform.Translate(Vector2.right * moveSpeed * Time.deltaTime);
transform.eulerAngles = new Vector2 (0,180);
}
}
void Jump() {
animPlayer.SetBool("isGrounded", playerGround.isGrounded);
if(playerGround.isGrounded == true && Input.GetButtonDown("Jump")) {
rigidbody2D.AddForce(Vector2.up * jumpForce);
audio.PlayOneShot(jumpSmall);
}
}
void Start () {
animPlayer = GetComponent<Animator>();
playerGround = GetComponent<PlayerGround>();
}
void Update () {
Movement();
}
void FixedUpdate () {
Jump();
}
}
Ground Script
using UnityEngine;
using System.Collections;
public class PlayerGround : MonoBehaviour {
public bool isGrounded;
public float jumpRayLength = 0.025f;
public Transform leftGCheck;
public Transform rightGCheck;
public Transform midGCheck;
void Raycasting() {
RaycastHit2D hit1 = Physics2D.Raycast(leftGCheck.position, -Vector2.up, jumpRayLength);
RaycastHit2D hit2 = Physics2D.Raycast(rightGCheck.position, -Vector2.up, jumpRayLength);
RaycastHit2D hit3 = Physics2D.Raycast(midGCheck.position, -Vector2.up, jumpRayLength);
Debug.DrawRay(leftGCheck.position, -Vector2.up * jumpRayLength, Color.yellow);
Debug.DrawRay(rightGCheck.position, -Vector2.up * jumpRayLength, Color.yellow);
Debug.DrawRay(midGCheck.position, -Vector2.up * jumpRayLength, Color.yellow);
if(hit1.collider != null || hit2.collider != null || hit3.collider != null) {
isGrounded = true;
} else {
isGrounded = false;
}
}
void FixedUpdate () {
Raycasting();
}
}