Unity 2D - HP bar - unity3d

The value of my HP bar drops when my runner collides an obstacle. Of course, Value of HP drop nomally, but Image of HP bar does not change. Why do I get an error?
public class CsRunner : MonoBehaviour
{
public Vector2 jumpVelocity;
public float _hp = 100f;
public float _curHP;
bool isJump;
public Image _hpValue;
bool collision_box;
// Use this for initialization
void Start()
{
_hpValue = GameObject.Find("HPbar").GetComponent<Image>();
_curHP = _hp;
}
// Update is called once per frame
void Update()
{
_hpValue.fillAmount = _curHP / _hp;
if (Input.GetKeyDown(KeyCode.Space) && isJump)
{
isJump = false;
transform.GetComponent<Rigidbody2D>().AddForce(jumpVelocity/2, ForceMode2D.Impulse);
}
if ((Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButtonDown(0)) && collision_box)
{
isJump = true;
transform.GetComponent<Rigidbody2D>().AddForce(jumpVelocity, ForceMode2D.Impulse);
}
else
{
GetComponent<Animator>().SetTrigger("Run");
}
}
void OnTriggerEnter2D(Collider2D coll)
{
if (coll.transform.tag == "Enemy")
{
_curHP--;
_hpValue.fillAmount = _curHP / _hp;
}
}
}
Here is a screenshot of my scene :
Thank you !

Related

after adding animation to the player's code in the play mode, he stopped moving

When creating the game, I came across the problem that after adding animation to the player's code in the play mode, he stopped moving.
I did everything as usual, went into the animator, made an animation, and then set up and added everything necessary to the code in the animator, but after that the player stopped moving although before that everything was fine.
Help me, I hope it's not difficult.
Here is the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[Header("Controlled player")]
public Rigidbody2D rb;
[Header("Tinctures of movement")]
public float PSpeed = 1f;
public float jumpForce = 1f;
[Header("Variable Reduction parameters")]
public float LowingPSPeed;
public float FormedPSpeed;
[Header("Traffic Statuses")]
public bool Move;
public bool Jump;
[Header("")]
[Header("Checking the ground under the player")]
public bool OnGround;
private bool doJump = false;
private bool GOright = false;
private bool GOleft = false;
[Header("Ground Check Settings")]
private float groundRadius = 0.3f;
public Transform groundCheck;
public LayerMask groundMask;
private Animator anim;
void Math()
{
FormedPSpeed = PSpeed / LowingPSPeed;
}
void Start()
{
anim = GetComponent<Animator>();
}
void Update()
{
Math();
if (Input.GetKeyDown(KeyCode.Space))
{
doJump = true;
}
if (Input.GetKey("d"))
{
GOright = true;
}else
{
GOright = false;
}
if (Input.GetKey("a"))
{
GOleft = true;
}
else
{
GOleft = false;
}
}
void FixedUpdate()
{
OnGround = Physics2D.OverlapCircle(groundCheck.position, groundRadius, groundMask);
if (GOright && Move)
{
transform.position += new Vector3(FormedPSpeed, 0, 0);
GetComponent<SpriteRenderer>().flipX = false;
}
if (GOleft && Move)
{
transform.position += new Vector3(-(FormedPSpeed), 0, 0);
GetComponent<SpriteRenderer>().flipX = true;
}
if (doJump && Jump && OnGround)
{
rb.AddForce(new Vector2(0, (jumpForce * 10)));
anim.SetTrigger("takeOf");
doJump = false;
}
if (OnGround)
{
anim.SetBool("isJump", false);
}else
{
anim.SetBool("isJump", true);
}
if (!GOleft && !GOright)
{
anim.SetBool("isRun", false);
}else
{
anim.SetBool("isRun", true);
}
}
I don't understand why this is happening

I can't jump and move at the same time unity2d

i made 2d character and 3 ui buttons and they worked well
but the problem is when moving to the right or left by the ui buttons i can't jump however when jump from the ui button i can move to right and left
this is the script
public class PlayerWalk : MonoBehaviour {
private PlayerAnimation playerAnim;
private Rigidbody2D myBody;
private SpriteRenderer spriteRenderer;
public float speed = 7f;
public float jumpForce = 7f;
private bool moveLeft; // determine if we move left or right
private bool dontMove; // determine if we are moving or not
private bool canJump; // we will test if we can jump
void Start () {
playerAnim = GetComponent<PlayerAnimation>();
myBody = GetComponent<Rigidbody2D>();
dontMove = true;
}
void Update () {
//DetectInput();
HandleMoving();
}
void HandleMoving() {
if (dontMove) {
StopMoving();
} else {
if (moveLeft) {
MoveLeft();
} else if (!moveLeft) {
MoveRight();
}
}
} // handle moving
public void AllowMovement(bool movement) {
dontMove = false;
moveLeft = movement;
}
public void DontAllowMovement() {
dontMove = true;
}
public void Jump() {
if(canJump) {
myBody.velocity = new Vector2(myBody.velocity.x, jumpForce);
//myBody.AddForce(Vector2.right * jumpForce);
}
}
// PREVIOUS FUNCTIONS
public void MoveLeft() {
myBody.velocity = new Vector2(-speed, myBody.velocity.y);
playerAnim.ZombieWalk(true, true);
}
public void MoveRight() {
myBody.velocity = new Vector2(speed, myBody.velocity.y);
playerAnim.ZombieWalk(true, false);
}
public void StopMoving() {
playerAnim.ZombieStop();
myBody.velocity = new Vector2(0f, myBody.velocity.y);
}
void DetectInput() {
float x = Input.GetAxisRaw("Horizontal");
if (x > 0)
{
MoveRight();
}
else if (x < 0)
{
MoveLeft();
}
else
{
StopMoving();
}
}
void OnCollisionEnter2D(Collision2D collision) {
if(collision.gameObject.tag == "Ground") {
canJump = true;
}
}
void OnCollisionExit2D(Collision2D collision) {
if (collision.gameObject.tag == "Ground") {
canJump = false;
}
}
} // class
the 2d character moves well and there is no bugs or problems with scripts
Any help??
I don't know where is the problem??
**Note ** i used unity5.6
I would say onTriggerEnter2D instead of using onCollisionEnter2D would be a better option in this scenario. You can read more about that here.
https://answers.unity.com/questions/875770/ontriggerenter-or-oncollisionenter-1.html#:~:text=OnCollisionEnter%20is%20called%20when%20two,with%20%22IsTrigger%22%20set).
Did you try to debug the value of canJump while you are trying to move left or right?

Compiler generates "error CS1513: } expected", but } is there

I am following a tutorial where I build my first 2D game in Unity.
I added a flipX function to flip my Sprite when I change my direction (pressing A or D)
I tried to use the same script, and tried to compile it there are 2 errors:
Assets\Scripts\Player.cs(83,25): error CS1002: ; expected
Assets\Scripts\Player.cs(83,25): error CS1513: } expected
I know what they mean and checked my script. I'm sure they are there where they are not. I just can't figure out the error.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
private Rigidbody2D _rigid;
[SerializeField]
private float _jumpForce = 5.0f;
private bool _resetJump = false;
[SerializeField]
private float _speed = 3.5f;
private PlayerAnimation _playerAnim;
private SpriteRenderer _playerSprite;
// Start is called before the first frame update
void Start()
{
_rigid = GetComponent<Rigidbody2D>();
_playerAnim = GetComponent<PlayerAnimation>();
_playerSprite = GetComponentInChildren<SpriteRenderer>();
}
// Update is called once per frame
void Update()
{
Movement();
}
void Movement()
{
float horizontalInput = Input.GetAxisRaw("Horizontal");
if (horizontalInput > 0)
{
Flip(true);
}
else if (horizontalInput < 0)
{
Flip(false);
}
if (Input.GetKeyDown(KeyCode.Space) && IsGrounded() == true)
{
Debug.Log("Jump!");
_rigid.velocity = new Vector2(_rigid.velocity.x, _jumpForce);
StartCoroutine(ResetJumpRoutine());
}
_rigid.velocity = new Vector2(horizontalInput * _speed, _rigid.velocity.y);
_playerAnim.Move(horizontalInput);
}
bool IsGrounded()
{
RaycastHit2D hitInfo = Physics2D.Raycast(transform.position, Vector2.down, 0.6f, 1 << 8);
if (hitInfo.collider != null)
{
if (_resetJump == false)
return true;
}
return false;
}
void Flip(bool faceRight)
{
if (faceRight == true)
{
_playerSprite.flipX = false;
}
else if (faceRight == false)
{
_playerSprite,flipX = true;
}
}
IEnumerator ResetJumpRoutine()
{
_resetJump = true;
yield return new WaitForSeconds(0.1f);
_resetJump = false;
}
}
It's a simple mistake, replace _playerSprite,flipX = true; with _playerSprite.flipX = true;.
You have a comma instead of a dot.

Can't figure out how to stop zombie from dealing damage when no longer colliding with player

I am creating a top down zombie shooter and I have made the zombie do damage to the player when it is touching the player. However when the player backs away from the zombie after taking damage, the players health will continue to drop. Any ideas on how to fix this would be appreciated.
public float moveSpeed= 5f;
public Rigidbody2D rb;
public Camera cam;
public float playerHealth = 100;
public float enemyDamage = 25;
public GameObject gameOverScreen;
Vector2 movement;
Vector2 mousePos;
// Update is called once per frame
void Update()
{
movement.x = Input.GetAxisRaw("Horizontal");
movement.y = Input.GetAxisRaw("Vertical");
mousePos = cam.ScreenToWorldPoint(Input.mousePosition);
if(playerHealth == 0)
{
gameOverScreen.SetActive(true);
}
}
void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
Vector2 lookDir = mousePos - rb.position;
float angle = Mathf.Atan2(lookDir.y, lookDir.x) * Mathf.Rad2Deg - 90f;
rb.rotation = angle;
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
StartCoroutine(DamagePlayer());
}
else
{
StopCoroutine(DamagePlayer());
}
}
IEnumerator DamagePlayer()
{
while(true)
{
yield return new WaitForSeconds(1);
playerHealth -= enemyDamage;
}
}
First of all for doing something if it is not colliding anymore you should use OnCollisionExit2D
Then you can either use it the way you did using
StopCoroutine(DamagePlayer());
Or if want to be sure you could either store a reference to your routine
private Coroutine routine;
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
if(routine == null)
{
routine = StartCoroutine(DamagePlayer());
}
}
else
{
if(routine != null) StopCoroutine(routine);
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
if(routine != null) StopCoroutine (routine);
}
or use a bool flag in order to terminate it
private bool cancelRoutine = true;
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
if(cancelRoutine) routine = StartCoroutine(DamagePlayer());
}
else
{
cancelRoutine = true;
}
}
private void OnCollisionEnter2D(Collision2D collision)
{
cancelRoutine = true;
}
IEnumerator DamagePlayer()
{
cancelRoutine = false;
while(! cancelRoutine)
{
yield return new WaitForSeconds(1);
playerHealth -= enemyDamage;
}
}
In general you could solve this without a routine by directly using OnCollisionStay2D like e.g.
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
timer = 1;
}
}
void OnCollisionStay2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
timer -= Time.deltaTime;
if(timer <= 0)
{
timer = 1;
playerHealth -= enemyDamage;
}
}
}

When the player shoots it is losing life

I'm making a multiplayer game2d and when my player shoots (the gun has a collider too )it's affecting his life and I don't know why.Probably because when the target "hurt" has RPCtarget.all but I don't know with what to change just to affect the others players in the game , not mine. With what I can replace all?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;
using Photon.Pun;
using Photon.Realtime;
using Photon;
using UnityEngine.UI;
public class Character : MonoBehaviourPun,IPunObservable
{
Rigidbody2D rb;
float dirX;
[SerializeField]
float moveSpeed = 5f, jumpForce = 400f, bulletSpeed = 500f;
[SerializeField] private float health = 100;
[SerializeField] private Slider slider;
[SerializeField] private Gradient gradient;
[SerializeField] private Image fill;
public Rigidbody2D bulletPrefabs;
Vector3 localScale;
public DeathsCount myCounts;
public Transform barrel;
public Rigidbody2D bullet;
// Use this for initialization
void Start()
{
localScale = transform.localScale;
rb = GetComponent<Rigidbody2D>();
if (photonView.IsMine)
{
myCounts = FindObjectOfType<DeathsCount>();
}
else
{
}
}
public float Health
{
get { return health; }
set
{
health = value;
slider.value = health;
// fill.color = gradient.Evaluate(slider.normalizedValue);
}
}
private void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.CompareTag("Hurt"))
{
if (photonView.IsMine)
{
photonView.RPC("Damage", RpcTarget.All);
}
}
if (col.gameObject.tag == "PowerUp")
{
if (photonView.IsMine)
{
var powerup = col.GetComponent<PowerUp>();
powerup.Pickup(this);
}
else
{
}
}
if (col.gameObject.CompareTag("Bullet"))
{
if (photonView.IsMine)
{
photonView.RPC("Damage", RpcTarget.All);
bullet = bulletPrefabs;
}
}
else
{
}
}
[PunRPC]
void Damage()
{
if (Health > 0)
{
Health -= 20;
}
if (Health <= 0) // check health status
{
Health = 0; // make that Heath don't be < 0
if (photonView.IsMine)
{
myCounts.RpcRespawn(); //Here you should to call counter
photonView.transform.position = Vector2.zero;
Health = 100;
}
}
}
// Update is called once per frame
void Update()
{
if (photonView.IsMine)
{
dirX = CrossPlatformInputManager.GetAxis("Horizontal");
if (dirX != 0)
{
barrel.up = Vector3.right * Mathf.Sign(dirX);
}
if (CrossPlatformInputManager.GetButtonDown("Jump"))
Jump();
if (CrossPlatformInputManager.GetButtonDown("Fire1"))
Fire();
}
else
{
}
}
void FixedUpdate()
{
if (photonView.IsMine)
{
rb.velocity = new Vector2(dirX * moveSpeed, rb.velocity.y);
}
}
void Jump()
{
if (photonView.IsMine)
{
if (rb.velocity.y == 0)
rb.AddForce(Vector2.up * jumpForce);
}
}
void Fire()
{
var firedBullet = PhotonNetwork.Instantiate(bullet.name, barrel.position, barrel.rotation).GetComponent<Rigidbody2D>();
firedBullet.AddForce(barrel.up * bulletSpeed);
}
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
stream.SendNext(Health);
}
else if (stream.IsReading)
{
Health = (float)stream.ReceiveNext();
}
}
public void SetMaxHealth(int value)
{
if (photonView.IsMine)
{
slider.maxValue = value;
// The property handles the rest anyway
Health = value;
}
}
}
I think you don't really need RPC in this case.
I see your character IPunObservable and, I guess, added to PhotonView. So its health will sync automatically.
You also instantiate bullets with PhotonNetwork, which means, they will sync too and have PhotonView.
So every player has all synchronized bullets and other players.
It means, all that you need is to check if bullet is from other player and set damage locally (don't worry, result will sync) like this :
. . .
private void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.CompareTag("Hurt"))
{
// if hurt object is not mine, take damage
if (!col.gameObject.GetPhotonView().isMine)
Damage();
}
if (col.gameObject.tag == "PowerUp")
{
if (photonView.IsMine)
{
var powerup = col.GetComponent<PowerUp>();
powerup.Pickup(this);
}
else
{
}
}
if (col.gameObject.CompareTag("Bullet"))
{
// if bullet is not mine, take damage
if (!col.gameObject.GetPhotonView().isMine)
Damage();
}
else
{
}
}
// no rpc
void Damage()
{
if (!photonView.IsMine) // only player can change his life
return;
if (Health > 0)
{
Health -= 20;
}
if (Health <= 0) // check health status
{
myCounts.RpcRespawn(); //Here you should to call counter
photonView.transform.position = Vector2.zero;
Health = 100;
}
}