Hello, I’m making a 2D Endless runner and for now everything works fine with the jump (Regulable jump maded with custom character controller).
But now I’m trying to do the same with a touchable UI button and I’m desperate. I’d try everything I know so far and I achieve that the button enable to jump but never like a GetButtonDown.
It jumps the entire time that I hold the button, or it just jump each time I press the button or it jump only the small part of the “entire” jump when you hold the physical key.
This is the Player.cs the main script and the other is the button script called JumpButton.cs :
Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Player : MonoBehaviour
{
[Header("General properties")]
[Tooltip("If checked, the controls of the player are completely disabled.")]
public bool blockControls = false;
[Header("Eddless Runner.")]
[Tooltip("Makes the character move automatically.")]
public bool automaticMove = false;
[Range(-7.1f,7.1f)]
[Tooltip("Positive values go right and negative go left.")]
public float automaticSpeed = 0f;
[Header("Horizontal Movement.")]
[Tooltip("The amount of normal speed. Don't worry if you reach the max speed set below.")]
public float moveSpeed = 10f;
[HideInInspector]
public Vector2 direction;
private bool facingRight = true;
[Header("Vertical Movement")]
[Tooltip("The amount of jumpSpeed. Gravity will affect the formula too.")]
public float jumpSpeed = 8f;
[Tooltip("The time window that you are allowed to pre-jump before the character touches the ground.")]
public float jumpDelay = 0.25f;
private float jumpTimer;
[Header("Joystick support")]
public bool jumpPad = false;
public JumpButton jumpButton;
[Header("Components.")]
[Tooltip("The rigidbody of the player. Normally it will be the main gameobject.")]
public Rigidbody2D rb;
[Tooltip("The animator is the Gameobject that has the animator in components, it will be the child of the character holder")]
public Animator anim;
[Tooltip("The chosen layer will be the ground for our character.")]
public LayerMask groundLayer;
[Tooltip("Will be the child of the main gameobject and the parent of the animator character.")]
public GameObject characterHolder;
[Tooltip("This game manager is unique only to the script GameController, used for interactions.")]
public GameController theGameManager;
//[Tooltip("A integration with the joystick pack of unity assets.")]
//public VariableJoystick variableJoystick;
[Header("Physics")]
[Tooltip("It sets the max reachable speed for the character.")]
public float maxSpeed = 6f;
[Tooltip("It sets the amount of the character linearDrag.")]
public float linearDrag = 8f;
[Tooltip("It sets the gravity scale for the player.")]
public float gravity = 1;
[Tooltip("It is used in the fall formula for our character.")]
public float fallMultiplier = 6f;
[Header("Collision")]
[Tooltip("If the raycast touches the ground, this will be true.")]
public bool onGround = false;
[Tooltip("This will be the raycast lenght, it is pointing to the negative y value.")]
public float GroundLenght = 1.1f;
[Tooltip("The offset for the double raycast. And we split it for the two legs of our character.")]
public Vector3 colliderOffset;
void Update()
{
bool wasGround = onGround;
onGround = Physics2D.Raycast(transform.position + colliderOffset, Vector2.down, GroundLenght, groundLayer) || Physics2D.Raycast(transform.position - colliderOffset, Vector2.down, GroundLenght, groundLayer);
if (Input.GetButtonDown("Jump"))
{
jumpTimer = Time.time + jumpDelay;
}
if (jumpButton.finallyJump)
{
jumpTimer = Time.time + jumpDelay;
}
direction = new Vector2(Input.GetAxisRaw("Horizontal")/* + variableJoystick.Horizontal*/, Input.GetAxisRaw("Vertical"));
}
void FixedUpdate()
{
if (!blockControls)
{
if (!automaticMove)
{
moveCharacter(direction.x);
}
else if (automaticMove == true)
{
moveCharacter(automaticSpeed);
}
if(jumpTimer > Time.time && onGround)
{
Jump();
}
modifyPhysics();
}
else
{
rb.gravityScale = 1;
}
}
void moveCharacter(float horizontal)
{
rb.AddForce(Vector2.right * horizontal * moveSpeed);
anim.SetFloat("horizontal", Mathf.Abs(rb.velocity.x));
anim.SetFloat("vertical", rb.velocity.y);
if((horizontal > 0 && !facingRight) || (horizontal < 0 && facingRight))
{
Flip();
}
if (Mathf.Abs(rb.velocity.x) > maxSpeed)
{
rb.velocity = new Vector2(Mathf.Sign(rb.velocity.x) * maxSpeed, rb.velocity.y);
}
}
void Jump()
{
rb.velocity = new Vector2(rb.velocity.x, 0); //Stops vertical movement.
rb.AddForce(Vector2.up * jumpSpeed, ForceMode2D.Impulse);
jumpTimer = 0;
StartCoroutine(JumpSqueeze(1.2f, 0.8f, 0.1f));
}
private void modifyPhysics()
{
bool changeDirection = (direction.x > 0 && rb.velocity.x < 0) || (direction.x < 0 && rb.velocity.x > 0);
if(onGround)
{
if(Mathf.Abs(direction.x) < 0.4f || changeDirection)
{
rb.drag = linearDrag;
}
else
{
rb.drag = 0f;
}
rb.gravityScale = 0;
}
else
{
rb.gravityScale = gravity;
rb.drag = linearDrag * 0.15f;
if(rb.velocity.y < 0)
{
rb.gravityScale = gravity * fallMultiplier;
}
else if(rb.velocity.y > 0 && !Input.GetButton("Jump"))
{
rb.gravityScale = gravity * (fallMultiplier / 2);
}
}
}
private void Flip()
{
// Switch the way the player is labelled as facing.
facingRight = !facingRight;
// Multiply the player's x local scale by -1.
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
IEnumerator JumpSqueeze(float xSqueeze, float ySqueeze, float seconds) {
Vector3 originalSize = Vector3.one;
Vector3 newSize = new Vector3(xSqueeze, ySqueeze, originalSize.z);
float t = 0f;
while (t <= 1.0) {
t += Time.deltaTime / seconds;
characterHolder.transform.localScale = Vector3.Lerp(originalSize, newSize, t);
yield return null;
}
t = 0f;
while (t <= 1.0) {
t += Time.deltaTime / seconds;
characterHolder.transform.localScale = Vector3.Lerp(newSize, originalSize, t);
yield return null;
}
}
private void OnDrawGizmos()
{
Gizmos.color = Color.blue;
Gizmos.DrawLine(transform.position + colliderOffset, transform.position + colliderOffset + Vector3.down * GroundLenght);
Gizmos.DrawLine(transform.position - colliderOffset, transform.position - colliderOffset + Vector3.down * GroundLenght);
}
//This is only for the spikes.
void OnCollisionEnter2D(Collision2D other)
{
if(other.gameObject.tag == "Bar")
{
theGameManager.WhenCharDies();
}
}
public void WhenDeath(bool dead)
{
blockControls = dead;
}
}
JumpButton.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class JumpButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
public bool allowJump = false;
public float timerJump;
public float delayJump = .25f;
public Player player;
public bool finallyJump = false;
//Detect current clicks on the GameObject (the one with the script attached)
public void OnPointerDown(PointerEventData pointerEventData)
{
//Output the name of the GameObject that is being clicked
Debug.Log(name + "Game Object Click in Progress");
//yield return new WaitForEndOfFrame();
//if (timerJump > Time.time && player.onGround)
//{
allowJump = true;
//}
}
//Detect if clicks are no longer registering
public void OnPointerUp(PointerEventData pointerEventData)
{
Debug.Log(name + "No longer being clicked");
allowJump = false;
}
void Update()
{
timerJump = Time.time + delayJump;
if (allowJump && timerJump > Time.time)
{
finallyJump = true;
}
else
{
finallyJump = false;
}
}
}
Feel free to say anything, maybe I miss something or wathever, but I was trying this for a 2 days now and I want to finish it, have to be a way without modify so much the code of Player.cs
Thanks in advance, appreciate the help.