so first time learning C# for my team studio class. I found this video which I was able to get my player moving and jumping perfectly, https://www.youtube.com/watch?v=3GtQ2yQX2kU&t=569s however after I added a health/can die system to the script, now the player refuses to jump no matter what I do. Since I am a newbie at this, I am just going to post the whole thing here if anyone can point me in the right direction. I've played with the box colliders, added the layers to the platforms like the tutorial said... please, if anyone can help. I know I'm a newbie to this :(
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public HealthBar healthBar; //Communicates with the healthbar script
public float moveSpeed;
public float jumpForce;
public int jumpsAmount;
int jumpsLeft;
public Transform GroundCheck;
public LayerMask GroundLayer;
public int maxHealth = 3;
public int currentHealth;
bool isGrounded;
float moveInput;
Rigidbody2D rb2d;
float scaleX;
// Start is called before the first frame update
void Start()
{
healthBar.SetMaxHealth(maxHealth); //Sets healthbar to max health
currentHealth = maxHealth;
rb2d = GetComponent<Rigidbody2D>();
scaleX = transform.localScale.x;
}
public void TakeDamage(int damage)
{
currentHealth -= damage;
if (currentHealth <= 0) //When Health is zero the player is destroyed
{
Destroy(gameObject);
}
healthBar.SetHealth(currentHealth); //Updates Healthbar when damgage is taken
}
// Update is called once per frame
void Update()
{
moveInput = Input.GetAxisRaw("Horizontal");
Jump();
}
private void FixedUpdate()
{
Move();
}
public void Move()
{
Flip();
rb2d.velocity = new Vector2(moveInput * moveSpeed, rb2d.velocity.y);
}
public void Flip()
{
if (moveInput > 0)
{
transform.localScale = new Vector3(scaleX, transform.localScale.y, transform.localScale.z);
}
if (moveInput < 0)
{
transform.localScale = new Vector3((-1) * scaleX, transform.localScale.y, transform.localScale.z);
}
}
public void Jump()
{
if (Input.GetKeyDown(KeyCode.Space))
{
CheckIfGrounded();
if (jumpsLeft > 0)
{
rb2d.velocity = new Vector2(rb2d.velocity.x, jumpForce);
jumpsLeft--;
}
}
}
public void CheckIfGrounded()
{
isGrounded = Physics2D.OverlapCircle(GroundCheck.position, GroundCheck.GetComponent<CircleCollider2D>().radius, GroundLayer);
ResetJumps();
}
public void ResetJumps()
{
if (isGrounded)
{
jumpsLeft = jumpsAmount;// jumpsAmount =2;
}
}
}
I put the groundcheck collider where the video wanted me to, even played around having different locations too. Nothing is working... tried changing the jump force too to see if it needs to be higher. I am at a complete loss.
Related
I'm creating a 2D Top Down game for practice and I need a little bit of help. For context, it's a 2D Top Down Shooter game, where you can move and shoot enemies. The enemies have a basic radius system where if the player gets within the radius, it'll approach the player.
Now I'm making a game mechanic where the player can hide in a cardboard box, the player can press 'E' and he'll suddenly become a cardboard box, where if the player is in the cardboard box, the enemy doesn't detect him even if the player's within the radius. Yes, just like in Metal Gear. Now I've created the prefabs and everything and functionality-wise, it works perfectly. If you press 'E' the enemy cannot detect you.
Now the small problem is that the cardboard box didn't appear, so it's just the player disappearing entirely. I do not know what caused this problem.
For context, these are my scripts. Feel free to read them, or not :)
PlayerController:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float moveSpeed;
public GameObject bulletPrefab;
public GameObject player;
private Rigidbody2D rb2d;
private Vector2 moveDirection;
[SerializeField] private Camera cam;
[SerializeField] private GameObject gunPoint;
public bool isHiding = false;
[SerializeField] private GameObject cardboardBox;
[SerializeField] private GameObject gunSprite;
// Start is called before the first frame update
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
cardboardBox.SetActive(false); // Hide the cardboard box when the game starts
gunSprite.SetActive(true); // Show the gun sprite when the game starts
}
// Update is called once per frame
void Update()
{
CheckCursor();
ProcessInputs();
// Make the camera follow the player
cam.transform.position = new Vector3(player.transform.position.x, player.transform.position.y, cam.transform.position.z);
// Check if player pressed the "E" key to toggle the cardboard box
if (Input.GetKeyDown(KeyCode.E))
{
isHiding = !isHiding; // Toggle the isHiding variable
cardboardBox.SetActive(isHiding); // Show/hide the cardboard box accordingly
// If player is hiding, stop player movement
if (isHiding)
{
moveDirection = Vector2.zero;
player.GetComponent<SpriteRenderer>().enabled = false;
cardboardBox.GetComponent<SpriteRenderer>().enabled = true;
gunSprite.SetActive(false); // Hide the gun sprite when the player is hiding
}
else
{
player.GetComponent<SpriteRenderer>().enabled = true;
cardboardBox.GetComponent<SpriteRenderer>().enabled = false;
gunSprite.SetActive(true); // Show the gun sprite when the player is not hiding
}
}
}
private void FixedUpdate()
{
if (!isHiding) // Only allow player to move if they are not hiding in the cardboard box
{
Movement();
}
}
private void CheckCursor()
{
Vector3 mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
Vector3 characterPos = transform.position;
if (mousePos.x > characterPos.x)
{
this.transform.rotation = new Quaternion(0, 0, 0, 0);
}
else if (mousePos.x < characterPos.x)
{
this.transform.rotation = new Quaternion(0, 180, 0, 0);
}
}
private void Movement()
{
// TODO : Implementasi movement player
rb2d.velocity = new Vector2(moveDirection.x * moveSpeed, moveDirection.y * moveSpeed);
}
private void ProcessInputs()
{
float moveX = Input.GetAxisRaw("Horizontal");
float moveY = Input.GetAxisRaw("Vertical");
moveDirection = new Vector2(moveX, moveY);
if (Input.GetMouseButtonDown(0))
{
Shoot();
}
}
private void Shoot()
{
Vector3 mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
Vector3 gunPointPos = gunPoint.transform.position;
Vector3 direction = (mousePos - gunPointPos).normalized;
GameObject bullet = Instantiate(bulletPrefab, gunPointPos, Quaternion.identity);
bullet.GetComponent<Bullet>().Init(direction);
}
}
EnemyController script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyController : MonoBehaviour
{
public Transform player;
public float moveSpeed = 5f;
public float detectionRadius = 5f;
public int maxHealth = 1;
private int currentHealth;
private Rigidbody2D rb2d;
private Vector2 movement;
private void Start()
{
rb2d = this.GetComponent<Rigidbody2D>();
currentHealth = maxHealth;
}
private void Update()
{
float distanceToPlayer = Vector2.Distance(transform.position, player.position);
if (player != null && distanceToPlayer <= detectionRadius && !player.GetComponent<PlayerController>().isHiding)
{
Vector3 direction = player.position - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
rb2d.rotation = angle;
direction.Normalize();
movement = direction;
}
else
{
movement = Vector2.zero;
}
}
void FixedUpdate()
{
moveCharacter(movement);
}
private void moveCharacter(Vector2 direction)
{
rb2d.MovePosition((Vector2)transform.position + (direction * moveSpeed * Time.deltaTime));
}
public void DestroyEnemy()
{
Destroy(gameObject);
}
}
Bullet script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Bullet : MonoBehaviour
{
// Start is called before the first frame update
[SerializeField] private float speed;
[SerializeField] private Vector3 direction;
public void Init(Vector3 direction)
{
this.direction = direction;
this.transform.SetParent(null);
transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg);
}
// Update is called once per frame
void Update()
{
this.transform.position += transform.right * speed * Time.deltaTime;
}
// TODO : Implementasi behaviour bullet jika mengenai wall atau enemy
private void OnTriggerEnter2D(Collider2D other)
{
switch(other.gameObject.tag)
{
case "Wall":
Destroy(gameObject);
break;
case "Enemy":
Destroy(gameObject);
other.gameObject.GetComponent<EnemyController>().DestroyEnemy();
break;
}
}
}
I've tried tinkering my scripts, I've tried checking if there are any missing components in the cardboard box game object but to no avail. Although I might be wrong on the Unity part since I'm fairly certain that the script isn't the problem here, again might be wrong.
I appreciate all the help I can get, thank you for reading until here
I'm making a simple platformer with a rolling ball that rolls around and collects coins to win each level. I'm using Unity's System input from Unity's package manager to help me with controls and key binding and have successfully gotten my ball to roll around with ease and collect coins with a nice UI setup. However, I would like to implement harder levels where the ball jumps. I can not figure out how to make the ball jump. I know there are others ways to go about this but I just can't figure out how to make it work in the system inputs.
(I know an if statement is needed to test if the ball is grounded however again I'm new and still learning)
Gameplay | OnJump in player input is for jumping | KeyBindings
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;
public class PlayerController: MonoBehaviour
{
public float speed = 0;
public bool isGrounded;
public float jumpForce;
public TextMeshProUGUI countText;
public GameObject winTextObject;
private Rigidbody rb;
private int count;
private float movementX;
private float movementY;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
SetCountText();
winTextObject.SetActive(false);
}
private void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movementX = movementVector.x;
movementY = movementVector.y;
}
private void onJump(InputValue value)
{
}
void SetCountText()
{
countText.text = "Count: " + count.ToString();
if(count >= 12)
{
winTextObject.SetActive(true);
}
}
private void FixedUpdate()
{
Vector3 movement = new Vector3(movementX, 0.0f, movementY);
rb.AddForce(movement * speed);
}
private void OnTriggerEnter(Collider other)
{
if(other.gameObject.CompareTag("PickUp"))
{
other.gameObject.SetActive(false);
count = count + 1;
SetCountText();
}
}
}
Make sure you create a new tag called Ground and put it on everything you want your player to be able to jump on (the ground).
public float jumpHeight = 5f;
public bool isGrounded;
void Update()
{
if (isGrounded)//Checks if is on ground
{
if (Input.GetButtonDown("Jump"))//If the space is pressed
{
rb.AddForce(Vector3.up * jumpHeight)
}
}
}
void OnCollisionEnter(Collision other)//If touch other object
{
if (other.gameObject.tag == "Ground")//If other object has Ground tag
{
isGrounded = true;
}
}
void OnCollisionExit(Collision other)
{
if (other.gameObject.tag == "Ground")
{
isGrounded = false;
}
}
You can also do if (Input.GetButtonDown("Jump")) as
if (Input.GetKeyDown("space"))
or
if (Input.GetKeyDown(KeyCode.Space))
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am making a 2D game in Unity , for the first time. I'm writing a script, also for the first time, I watched some tutorials and I think it's not bad. However, I keep getting an error message and I have no idea what to do. Well, the error is displayed to me in a place where previously no error was displayed and everything worked. Only after typing in "void Update" :
if (Input.GetKeyDown(KeyCode.R))
{
Attack();
}
void Attack()
{
// Play an attack animation
animator.SetTrigger("Attack");
// Detect enemies in range of attack
// Damage them
}
}
(I wrote it the way the tutorial said to)
Suddenly when I wanted to see if it worked I got an error "Identifier expected". The error is located a line further down, here:
#if (grouned)
doubleJump = false;
anim.SetBool ("Grounded", grouned);
if(Input.GetKeyDown(KeyCode.W)&& grouned)
"If" displayed that something was wrong, so I added an "#" there, but now it shows that something should be/something is wrong after the word "grouned".
I have no idea what to do.
Here you have the whole script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public Animator animator;
public float moveSpeed;
public float jumpHeight;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask WhatIsGround;
private bool grouned;
private bool doubleJump;
private Animator anim;
// Start is called before the first frame update
void Start(){
anim = GetComponent<Animator> ();
}
void FixedUpdate(){
grouned = Physics2D.OverlapCircle (groundCheck.position, groundCheckRadius, WhatIsGround);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
Attack();
}
void Attack()
{
// Play an attack animation
animator.SetTrigger("Attack");
// Detect enemies in range of attack
// Damage them
}
}
#if (grouned)
doubleJump = false;
anim.SetBool ("Grounded", grouned);
if(Input.GetKeyDown(KeyCode.W)&& grouned)
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (0, jumpHeight);
}
if(Input.GetKeyDown(KeyCode.W)&& !grouned && !doubleJump)
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (0, jumpHeight);
doubleJump = true;
}
if(Input.GetKey(KeyCode.D))
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
}
if(Input.GetKey(KeyCode.A))
{
GetComponent<Rigidbody2D> ().velocity = new Vector2 (-moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
}
anim.SetFloat ("Speed", Mathf.Abs (GetComponent<Rigidbody2D> ().velocity.x));
if(GetComponent<Rigidbody2D>().velocity.x > 0)
{
transform.localScale = new Vector3 (3f, 3f, 3f);
}
else if (GetComponent<Rigidbody2D>().velocity.x < 0)
transform.localScale = new Vector3 (-3f, 3f, 3f);
}
}
Having tidied up your code, it's obvious that the code starting at #if... is not contained within a method.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public Animator animator;
public float moveSpeed;
public float jumpHeight;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask WhatIsGround;
private bool grouned;
private bool doubleJump;
private Animator anim;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
grouned = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, WhatIsGround);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
Attack();
}
void Attack()
{
// Play an attack animation
animator.SetTrigger("Attack");
// Detect enemies in range of attack
// Damage them
}
}
#if(grouned)
doubleJump = false;
anim.SetBool("Grounded", grouned);
if(Input.GetKeyDown(KeyCode.W)&& grouned)
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, jumpHeight);
}
if (Input.GetKeyDown(KeyCode.W) && !grouned && !doubleJump)
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, jumpHeight);
doubleJump = true;
}
if (Input.GetKey(KeyCode.D))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
}
if (Input.GetKey(KeyCode.A))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(-moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
}
anim.SetFloat("Speed", Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x));
if (GetComponent<Rigidbody2D>().velocity.x > 0)
{
transform.localScale = new Vector3(3f, 3f, 3f);
}
else if (GetComponent<Rigidbody2D>().velocity.x < 0)
transform.localScale = new Vector3(-3f, 3f, 3f);
}
}
The chances are that some of your closing braces } are in the wrong place.
Keeping your code well formatted would have helped you identify this error. Good formatting is not just good practice, it helps with reading the code and also helps spot errors like this.
Also, I'm not sure what you were hoping to achieve with #if, this isn't a razor view/page!
It looks like you've put your Attack function in the middle of the update function which is making your curly braces not line up properly and leaving a lot of code outside of a function.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public Animator animator;
public float moveSpeed;
public float jumpHeight;
public Transform groundCheck;
public float groundCheckRadius;
public LayerMask WhatIsGround;
private bool grouned;
private bool doubleJump;
private Animator anim;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
grouned = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, WhatIsGround);
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
Attack();
}
if(grouned)
doubleJump = false;
anim.SetBool("Grounded", grouned);
if (Input.GetKeyDown(KeyCode.W) && grouned)
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, jumpHeight);
}
if (Input.GetKeyDown(KeyCode.W) && !grouned && !doubleJump)
{
GetComponent<Rigidbody2D>().velocity = new Vector2(0, jumpHeight);
doubleJump = true;
}
if (Input.GetKey(KeyCode.D))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
}
if (Input.GetKey(KeyCode.A))
{
GetComponent<Rigidbody2D>().velocity = new Vector2(-moveSpeed, GetComponent<Rigidbody2D>().velocity.y);
}
anim.SetFloat("Speed", Mathf.Abs(GetComponent<Rigidbody2D>().velocity.x));
if (GetComponent<Rigidbody2D>().velocity.x > 0)
{
transform.localScale = new Vector3(3f, 3f, 3f);
}
else if (GetComponent<Rigidbody2D>().velocity.x < 0)
transform.localScale = new Vector3(-3f, 3f, 3f);
}
void Attack()
{
// Play an attack animation
animator.SetTrigger("Attack");
// Detect enemies in range of attac
// Damage them
}
}
Are you using some kind of editor with syntax highlighting? It would help you catch errors like this along with indenting your code properly which will help you spot missing/extra { braces.
I coded my player in my platform game so that he would attack with a sword when you press space. It attacks right when I run right. It attacks left when I run left. But when I stand still by default it attacks left. How do I make it attack right instead?
Below is all the code in my player controller script, and also an image of my blend tree.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public int moveSpeed;
private Animator anim;
public int playerJumpPower = 1250;
private float moveX;
public bool isGrounded;
public float fJumpWaitTime = 0.2f;
private float fJumpWait;
private object col;
private bool attacking;
public float attackTime;
private float attackTimeCounter;
// Start is called before the first frame update
void Start()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (!attacking)
{
if (Input.GetButtonDown("Jump"))
{
Jump();
}
if (Input.GetAxisRaw("Horizontal") > 0.5f || Input.GetAxisRaw("Horizontal") < -0.5f)
{
transform.Translate(new Vector3(Input.GetAxisRaw("Horizontal") * moveSpeed * Time.deltaTime, 0f, 0f));
}
void Jump()
{
//Jumping Code
GetComponent<Rigidbody2D>().AddForce(Vector2.up * playerJumpPower);
isGrounded = false;
}
void OnCollisionEnter2D(Collision2D col)
{
Debug.Log("Player has collided with " + col.collider.name);
if (col.gameObject.tag == "ground")
{
isGrounded = true;
}
}
}
anim.SetFloat("MoveX", Input.GetAxisRaw("Horizontal"));
if (Input.GetKeyDown(KeyCode.Space))
{
attackTimeCounter = attackTime;
attacking = true;
anim.SetBool("Attack", true);
}
if(attackTimeCounter > 0)
{
attackTimeCounter -= Time.deltaTime;
}
if(attackTimeCounter <= 0)
{
attacking = false;
anim.SetBool("Attack", false);
}
}
}
After having another look at your Blend Tree, I would check if your Threst is the problem.
What you have right now:
PlayerAttackLeft 0 -1
PlayerAttackRight 1 1
What you should probably have:
PlayerAttackLeft -0.01 -1
PlayerAttackRight 0 1
I started making a 2D game in Unity and I have a problem with my player. I add 2 buttons for left and right and jump just tapping the display . When I start the game just the buttons left and right works and the jump don't . I added from another script something for jump and now when I start the game the player goes automatically at right and don't respect the buttons action. (but jumping works) this is the 2 codes that I joined them :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
public float moveSpeed = 300;
public GameObject character;
private Rigidbody2D characterBody;
private float ScreenWidth;
void Start()
{
ScreenWidth = Screen.width;
characterBody = character.GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
int i = 0;
while (i < Input.touchCount)
{
if (Input.GetTouch(i).position.x > ScreenWidth / 2)
{
RunCharacter(1.0f);
}
if (Input.GetTouch(i).position.x < ScreenWidth / 2)
{
RunCharacter(-1.0f);
}
++i;
}
}
void FixedUpdate()
{
#if UNITY_EDITOR
RunCharacter(Input.GetAxis("Horizontal"));
}
private void RunCharacter(float horizontalInput)
{
characterBody.AddForce(new Vector2(horizontalInput * moveSpeed * Time.deltaTime, 0));
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Move2d : MonoBehaviour
{
public float playerSpeed; //allows us to be able to change speed in Unity
public Vector2 jumpHeight;
public bool isDead = false;
private Rigidbody2D rb2d;
private Score gm;
// Use this for initialization
void Start()
{
rb2d = GetComponent<Rigidbody2D>();
gm = GameObject.FindGameObjectWithTag("gameMaster").GetComponent<Score>();
}
// Update is called once per frame
void Update()
{
if (isDead) { return; }
transform.Translate(playerSpeed * Time.deltaTime, 0f, 0f); //makes player run
if (Input.GetMouseButtonDown(0) || Input.GetKeyDown(KeyCode.Space)) //makes player jump
{
GetComponent<Rigidbody2D>().AddForce(jumpHeight, ForceMode2D.Impulse);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("ground")) // this will return true if the collision gameobject has ground tag on it.
{
isDead = true;
rb2d.velocity = Vector2.zero;
GameController.Instance.Die();
}
}
void OnTriggerEnter2D(Collider2D col)
{
if( col.CompareTag("coin"))
{
Destroy(col.gameObject);
gm.score += 1;
}
}
}
If you know a better script please help
Try adding #endif for the #if UNITY_EDITOR