The jump button is not working in my unity, as my player is not jumping. I followed a tutorial but it does not seem to work. Must be something wrong with my code but I cannot seem to work it out as there are no errors.
I am not sure but, I created an image in unity and placed it in canvas and named it "Fixed Joybutton", with the script Joybutton.cs, but when I run it and try to click it, it wont make my player jump. I thought the problem was the "joybutton = FindObjectOfType();" and changed it to "joybutton = GetComponent();" but still doesnt work.
This is the code for the jump button itself, Joybutton.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
{
[HideInInspector]
public bool Pressed;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void OnPointerDown(PointerEventData eventData)
{
Pressed = true;
}
public void OnPointerUp(PointerEventData eventData)
{
Pressed = false;
}
}
// and this is the code that is in my player, PlayerController.cs:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerController : MonoBehaviour
{
protected Joystick joystick;
protected Joybutton joybutton;
protected bool jump;
public float speed;
public Text playerDisplay;
public Text scoreDisplay;
public bool isFlat = true;
private Rigidbody rb;
public static int count = 0;
private void Start()
{
joystick = FindObjectOfType<Joystick>();
joybutton = FindObjectOfType<Joybutton>();//this is to find the object, I changed it to "joybutton = GetComponent<Joybutton>();" but still doesnt work
rb = GetComponent<Rigidbody>();
}
private void FixedUpdate()
{
rb.velocity = new Vector3(joystick.Horizontal * 5f, rb.velocity.y, joystick.Vertical * 5f); // joystick to move my player, its working
if (!jump && joybutton.Pressed)// this is for the jump, that is not working
{
jump = true;
rb.velocity += Vector3.up * 10f;
}
if (jump && !joybutton.Pressed)
{
jump = false;
}
}
public void OnTriggerEnter(Collider other)
{
GameObject gameControl = GameObject.Find("Timer");//name of my gameobject
Loading loading = gameControl.GetComponent<Loading>();
if (other.gameObject.CompareTag("Pick Up"))
{
other.gameObject.SetActive(false);
count = count + 1;
Awake();
}
else if (other.gameObject.CompareTag("Time Boost"))
{
other.gameObject.SetActive(false);
loading.sec += 10;
if (loading.sec > 60)
{
int sec1 = loading.sec - 60;
loading.sec = sec1;
loading.minutes ++;
}
Awake();
}
}
private void Awake()
{
if (DBManager.username == null)
{
UnityEngine.SceneManagement.SceneManager.LoadScene(0);
}
playerDisplay.text = "Player: " + DBManager.username;//display username
scoreDisplay.text = "Score: " + count.ToString();//display score
}
}
//Player is moving but cannot jump. Please show me the error in my code and solution. Thank you so much.
There's a lot to unpack here.
UI Events like OnPointerDown occur on the frame cycle. FixedUpdate happens on the fixed cycle. There is a good chance that you have a very high framerate, resulting in 5-6 frames per fixed cycle. Your joybutton will only be set to "pressed" for one frame, so there is a very high chance that the joybutton triggers OnPointerUp before the jump can occur.
The quickest solution to this problem would be to not "reset" the joybutton's pressed state using OnPointerUp, and instead reset it when the jump is processed in your PlayerController. That being said, can you help me understand why these 2 scripts are separated?
Rather than set the .Pressed state to false in the JoyButton script, reset it after you consume it in your PlayerController:
if (!jump && joybutton.Pressed)// this is for the jump, that is not working
{
jump = true;
joybutton.Pressed = false; //Add this line of code
rb.velocity += Vector3.up * 10f;
}
How do yo do for avoiding the player to jump twice in the air?
private void FixedUpdate()
{
rb.velocity = new Vector3(
joystick.Horizontal * 5f, rb.velocity.y,
joystick.Vertical * 5f);
if (!jump && joybutton.Pressed)
{
jump = true;
rb.velocity += Vector3.up * 10f;
}
if (jump && !joybutton.Pressed)
{
jump = false;
}
}
Related
https://www.youtube.com/watch?v=gB1F9G0JXOo&t=11865s
I'm watching this tutorial and I did everything the same as the guy in the video did until the "Player Jumping" part, when his character can jump whenever he presses the space button, but for me it doesn't work the same way. Can somebody help or tell me what is the problem?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
[SerializeField]
private float moveForce = 10f;
[SerializeField]
private float jumpForce = 11f;
private float movementX;
private Rigidbody2D myBody;
private SpriteRenderer sr;
private Animator anim;
private string WALK_ANIMATION = "Walk";
private void Awake()
{
myBody = GetComponent<Rigidbody2D>();
anim = GetComponent<Animator>();
sr = GetComponent<SpriteRenderer>();
}
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
PlayerMoveKeyboard();
AnimatePlayer();
}
private void FixedUpdate()
{
PlayerJump();
}
void PlayerMoveKeyboard()
{
movementX = Input.GetAxisRaw("Horizontal");
transform.position += new Vector3(movementX, 0f, 0f) * moveForce * Time.deltaTime;
}
void AnimatePlayer()
{
// we are going to the right side
if (movementX > 0)
{
anim.SetBool(WALK_ANIMATION, true);
sr.flipX = false;
}
// we are going to the left side
else if (movementX < 0)
{
anim.SetBool(WALK_ANIMATION, true);
sr.flipX = true;
}
else
{
anim.SetBool(WALK_ANIMATION, false);
}
}
void PlayerJump()
{
if (Input.GetButtonDown("Jump"))
{
myBody.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
}
}
} // class
Try moving your jump function from the FixedUpdate into the normal Update Function.
That should fix it.
Update gets called every frame and thus captures every input while FixedUpdate gets called in a fixed offset to update the physics logic of the engine. Now when you are looking for keyboard input, you want to always do that in Update, never in FixedUpdate because you'll miss input that was given to the player between the fixed update frames.
But since you want to do physics related changes only in FixedUpdate, you want to split the code between the two methods.
bool shouldJump = false;
void Update()
{
if (Input.GetButtonDown("Jump"))
shouldJump = true;
}
void FixedUpdate()
{
if (shouldJump)
{
myBody.AddForce(new Vector2(0f, jumpForce), ForceMode2D.Impulse);
shouldJump = false;
}
}
I have looked into the code in the video and he does the jump-logic in FixedUpdate. It seems weird to me and this is definitely bad practice. But one of the comments below addresses your issue as well and proposes a similar solution.
So i made a little side scroller that uses a prefab to spawn bullets.
My problem is that it only shoots to one side... the Right.
I need it to fire to the left as well. I've already made a variable to see if the player is looking to the right or left.
I've tried to put the Speed to -20 and i've tried to rotate it 180 degrees on it's Z axis. I tested if the bullet script even picked up the change from the player movement script and it does.
Player Movement script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
public GameObject bullet;
private Rigidbody2D myRigidbody;
private float speed = 15;
private bool facingRight;
private bool ground = false;
private float jump = 23;
// Start is called before the first frame update
void Start()
{
facingRight = true;
myRigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void FixedUpdate()
{
float horizontal = Input.GetAxis("Horizontal");
Movement(horizontal);
Flip(horizontal);
if (Input.GetKey("w"))
{
if (ground)
{
GetComponent<Rigidbody2D>().velocity = new Vector2(GetComponent<Rigidbody2D>().velocity.x, jump);
}
}
if(facingRight == false)
{
bullet.GetComponent<bullet>().left = true;
}
if (facingRight == true)
{
bullet.GetComponent<bullet>().left = false;
}
}
void OnTriggerEnter2D()
{
ground = true;
}
void OnTriggerExit2D()
{
ground = false;
}
private void Movement(float horizontal)
{
myRigidbody.velocity = new Vector2(horizontal * speed,myRigidbody.velocity.y);
}
private void Flip(float horizontal)
{
if (horizontal > 0 && !facingRight || horizontal < 0 && facingRight)
{
facingRight = !facingRight;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
}
Weapon script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class weapon : MonoBehaviour
{
// Start is called before the first frame update
public bool right;
public Transform firepointR;
public GameObject bulletPrefab;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown("space"))
{
Debug.Log("Oh well");
Shoot();
}
}
void Shoot()
{
Instantiate(bulletPrefab, firepointR.position, firepointR.rotation);
}
}
bullet script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class bullet : MonoBehaviour
{
public bool left;
public float speed = 20;
public Rigidbody2D rb;
// Start is called before the first frame update
void Start()
{
rb.velocity = transform.right * speed;
}
// Update is called once per frame
void FixedUpdate()
{
Debug.Log(speed);
if (left == false)
{
transform.Rotate(0, 0, 180);
}
}
}
As i previously said i need my bullet (prefab) to go the opposite direction but whatever i do right now it will always go right.
Expanding on my comment:
Did you try reversing the velocity?
rb.velocity = -(transform.right * speed);
Note: There are instances when using a negative float wont return the opposite of the positive result. However, in this example, it will work just fine.
I imagine this will work also (and is probably the correct way of doing it):
rb.velocity = transform.left * speed;
Yes, I read through about 30 different similar titles before posting this. However, there wasn't anything relevant to what I need. I'm trying to set my camera's Y-axis to follow the player as it moves through the level; however, I don't want the camera to move up and down whilst jumping so I follow the camera's transform.position.y and NOT the player's.
void Pjump()
{
if (Input.GetKeyDown(KeyCode.Space) && onFloor==true
|| Input.GetKeyDown(KeyCode.W) && onFloor==true)
{
player.velocity = new Vector2(0, jump);
onFloor = false;
isJumping = true; // Static Variable to pass onto CamFollow script
}
}
isJumping is set false inside an OnCollisionEnter2d() and called inside of a FixedUpdate().
Now for the CamFollow script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamFollow : MonoBehaviour
{
private GameObject p1;
private bool isFollow;
[Header("Camera Offset Values")]
[SerializeField]
private float xOff;
[SerializeField]
private float yOff;
void Start()
{
p1 = GameObject.FindWithTag("Player");
isFollow = true;
}
void FixedUpdate()
{
if (isFollow)
{
if (Pmove.isJumping == false) // This code works fine
{
transform.position = new Vector3(p1.transform.position.x + xOff, p1.transform.position.y + yOff,
transform.position.z);
}
if(Pmove.isJumping == true) // This is where the problem is: Y-Axis
{
transform.position = new Vector3(p1.transform.position.x + xOff, transform.position.y + yOff,
transform.position.z);
}
}
}
}
When the player jumps, the player and all non-UI objects vanish until the player touches the ground.
I'm making a 2D platformer. Here's my code so far. The character jumps only when touching the ground as it should - but the code for double jumping doesn't work. Any help is appreciated. I'm new at scripting and I don't understand what I did wrong?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour {
public float speed = 12f, jumpHeight = 30f;
Rigidbody2D playerBody;
Transform playerTrans, tagGround;
bool isGrounded = false;
public LayerMask playerMask;
public float maxJumps = 2;
public float jumpsLeft = 2;
// Use this for initialization
void Start ()
{
playerBody = this.GetComponent<Rigidbody2D>();
playerTrans = this.transform;
tagGround = GameObject.Find(this.name + "/tag_Ground").transform;
}
// Update is called once per frame
public void FixedUpdate ()
{
isGrounded = Physics2D.Linecast(playerTrans.position, tagGround.position, playerMask);
Move();
Jump();
DoubleJump();
}
private void Move()
{
float move = Input.GetAxisRaw("Horizontal") * speed;
playerBody.velocity = new Vector2(move, playerBody.velocity.y);
}
private void Jump()
{
if (isGrounded)
{
if (Input.GetButtonDown("Jump"))
{
playerBody.velocity = new Vector2(playerBody.velocity.x, jumpHeight);
}
}
}
private void DoubleJump()
{
if (Input.GetButtonDown("Jump") && jumpsLeft > 0)
{
Jump();
jumpsLeft--;
}
if (isGrounded)
{
jumpsLeft = maxJumps;
}
}
}
Your code doesn't make much sense. You should handle your jumping in one method and handle it something like this:
private void HandleJump()
{
if(isGrounded) {
jumpsLeft = maxJumps;
}
if(Input.GetButtonDown("Jump") && jumpsLeft > 0) {
playerBody.velocity = new Vector2(playerBody.velocity.x, jumpHeight);
jumpsLeft--;
}
}
This way you can make triple jumps or however many jumps you want.
Try replacing your Jump method code with the DoubleJump method's code and remove the check for IsGrounded before applying the jump. Otherwise your character has to be on the ground every time. Then remove the DoubleJump method as it is no longer needed. If you're utilizing the DoubleJump as an added skill later in your game then just increase maxJumps as your player earns the skill. Set it to 1 initially so that they have to hit the ground every time.
private void Jump() {
if (isGrounded) {
jumpsLeft = maxJumps;
}
if (Input.GetButtonDown("Jump") && jumpsLeft > 0) {
playerBody.velocity = new Vector2(playerBody.velocity.x, jumpHeight);
jumpsLeft--;
}
}
EDIT : Apparently when I select Windowed, the buttons work. Why is this? Why doesn't it work without that box selected?
I created a game in Unity and everything works fine in Unity itself. When I build and run the game, my buttons no longer recognize my mouse clicks. Why is this?
This is a basic pong game. I don't know why it would work in Unity and not outside of Unity if it was the code but here is the code.
Code :
paddle script:
using UnityEngine;
using System.Collections;
public class paddle : MonoBehaviour {
public float paddleSpeed = 1;
public Vector3 playerPos = new Vector3(0,0,0);
// Update is called once per frame
void Update () {
float yPos = gameObject.transform.position.y + (Input.GetAxis ("Vertical") * paddleSpeed);
playerPos = new Vector3 (-20,Mathf.Clamp(yPos, -13F,13F),0);
gameObject.transform.position = playerPos;
}
}
ball script:
using UnityEngine;
using System.Collections;
public class Ball : MonoBehaviour {
public float ballVelocity = 1500;
private Rigidbody rb;
private bool isPlay; //false by default
int randInt; //random ball directon when game begins
// Use this for initialization
void Awake () {
rb = gameObject.GetComponent<Rigidbody> ();
randInt = Random.Range (1,3);
}
// Update is called once per frame
void Update () {
if(Input.GetMouseButton(0) == true && isPlay == false){
transform.parent = null;
isPlay = true;
rb.isKinematic = false;
if(randInt == 1){
rb.AddForce(new Vector3(ballVelocity,ballVelocity,0));
}
if(randInt == 2){
rb.AddForce(new Vector3(-ballVelocity,-ballVelocity,0));
}
}
}
}
enemy script:
using UnityEngine;
using System.Collections;
public class Enemy : MonoBehaviour {
public float speed = 8;
private Vector3 targetPos;
private Vector3 playerPos;
private GameObject ballObj;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
ballObj = GameObject.FindGameObjectWithTag ("ball");
if (ballObj != null) {
targetPos = Vector3.Lerp (gameObject.transform.position, ballObj.transform.position, Time.deltaTime * speed);
playerPos = new Vector3 (-20, Mathf.Clamp (targetPos.y, -13F, 13F), 0);
gameObject.transform.position = new Vector3 (20, playerPos.y, 0);
}
}
}
score script:
using UnityEngine;
using System.Collections;
public class Score : MonoBehaviour {
public TextMesh currScore;
public GameObject ballPref;
public Transform paddleObj;
GameObject ball;
private int score;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
ball = GameObject.FindGameObjectWithTag("ball");
currScore.text = "" + score;
}
void OnTriggerEnter(Collider other) {
if(other.tag == "ball"){
score += 1;
Destroy(ball);
(Instantiate(ballPref, new Vector3(paddleObj.transform.position.x + 1, paddleObj.transform.position.y,0), Quaternion.identity) as GameObject).transform.parent = paddleObj;
}
}
}
title screen script:
#pragma strict
function Start () {
}
function Update () {
}
function StartGame () {
Application.LoadLevel("Main");
}
function ExitGame () {
Application.Quit();
}
From what I am understanding, you want Unity to recognize your mouse button event even when the mouse pointer is not inside the game Window.
There could be 2 ways to achieve this:
1. The easy way, make your game full screen.
2. If you want your game in a window box, you must check "Run In Background" option in Player settings -> Resolution. And then, learn how to hook mouse event: http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C
Please note that the hooking mouse event tutorial only works on Windows, not Mac nor Linux. I do not know how to do it with Mac or Linux.