Lost reference after method execution - c#

I followed this video on how to create health bars automatically for units.
This is my HealthBar class.
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
public class HealthBar : MonoBehaviour
{
#region SerializeFields
[SerializeField] private Image foregroundImage;
[SerializeField] private float updateSpeedInSec = 0.5f;
[SerializeField] private float positionOffset = 1f;
#endregion
#region NonSerializeFields
private Health health;
#endregion
public void SetHealth(Health healthToSet)
{
health = healthToSet;
healthToSet.OnHealthPctChanged += HandleHealthChanged;
}
private void HandleHealthChanged(float pct)
{
StartCoroutine(ChangeToPct(pct));
}
private IEnumerator ChangeToPct(float pct)
{
float preChangedPct = foregroundImage.fillAmount;
float elapsedTime = 0f;
while (elapsedTime < updateSpeedInSec)
{
elapsedTime += Time.deltaTime;
foregroundImage.fillAmount = Mathf.Lerp(preChangedPct, pct, elapsedTime / updateSpeedInSec);
yield return null;
}
foregroundImage.fillAmount = pct;
}
private void LateUpdate()
{
var worldToScreenPoint = Camera.main.WorldToScreenPoint(health.transform.position + (Vector3) Vector2.up * positionOffset);
transform.position = worldToScreenPoint;
}
private void OnDestroy()
{
health.OnHealthPctChanged -= HandleHealthChanged;
}
}
So this is my HealthBarController class, which is where the SetHealth method is called, put on a canvas.
using System.Collections.Generic;
using UnityEngine;
public class HealthBarController : MonoBehaviour
{
#region SerializeFields
[SerializeField] private HealthBar healthBar;
#endregion
#region NonSerializeFields
private Dictionary<Health, HealthBar> healthBars = new Dictionary<Health, HealthBar>();
#endregion
private void Awake()
{
Health.OnHealthAdded += AddHealthBar;
Health.OnHealthRemoved += RemoveHealthBar;
}
private void AddHealthBar(Health health)
{
if (healthBars.ContainsKey(health)) return;
var newHealthBar = Instantiate(healthBar, transform);
healthBars.Add(health, newHealthBar);
healthBar.SetHealth(health);
}
private void RemoveHealthBar(Health health)
{
if (!healthBars.ContainsKey(health)) return;
Destroy(healthBars[health].gameObject);
healthBars.Remove(health);
}
}
And this is my Health class on a player character.
using System;
using UnityEngine;
public class Health : MonoBehaviour, IDamageable
{
#region SerializeFields
[SerializeField] protected int maxHealth = 100;
public static event Action<Health> OnHealthAdded = delegate { };
public static event Action<Health> OnHealthRemoved = delegate { };
public event Action<float> OnHealthPctChanged = delegate { };
#endregion
#region NonSerializeFields
protected int currentHealth;
#endregion
private void OnEnable()
{
currentHealth = maxHealth;
OnHealthAdded(this);
}
public void TakeDamage(int damage)
{
currentHealth -= damage;
float currentHealthPct = (float) currentHealth / maxHealth;
OnHealthPctChanged(currentHealthPct);
if (currentHealth <= 0)
{
Die();
}
}
protected void Die()
{
OnHealthRemoved(this);
Destroy(gameObject);
}
}
The problem I'm having is in the LateUpdate method, the health field is null, even though in the SetHealth method, it was set properly.

In the AddHealthBar method of your HealthBarController.cs script you are assigning the Health class of your character to the Prefab healthBar rather than the newly created Health instance newHealthBar.
Simply replace healthBar.SetHealth(health); with newHealthBar.SetHealth(health); (line 30).

Related

How to check the motion of an object

does anyone know how to improve this code?
I have this mechaniс : ball player creates a bullet ball in front of him and reduces his size, need to disable the reduction of the player's ball if the bullet is already created and flies forward.
I will be glad to any ideas
using UnityEngine;
public class DecreasePlayerBall : MonoBehaviour
{
[SerializeField] private float speedDecrease;
[SerializeField] private int healthPlayer;
public GameOver gameOver;
void Update()
{
if (GameObject.FindWithTag("ballBullet").transform.position.z <= 25.3481f)
{
if (Input.GetMouseButton(0))
{
Decrease();
healthPlayer--;
if (healthPlayer <= 0)
{
Destroy(gameObject);
gameOver.GameOverScreen();
}
}
}
}
void Decrease()
{
transform.localScale -= new Vector3(speedDecrease, speedDecrease, speedDecrease) * Time.deltaTime;
}
}
You can keep the position of the object in a variable and check if the position changes to check if it has moved or use Transform.hasChanged or a boolean of your choice to handle "hasMoved" state.
I'd try something like (not debuggued):
using UnityEngine;
public class DecreasePlayerBall : MonoBehaviour
{
[SerializeField] private float speedDecrease;
[SerializeField] private int healthPlayer;
public GameOver gameOver;
void Start() {
transform.hasChanged = false; // its false by default probably
}
void Update()
{
// if (GameObject.FindWithTag("ballBullet").transform.position.z <= 25.3481f)
if (!transform.hasChanged) {
if (Input.GetMouseButton(0))
{
Decrease();
healthPlayer--;
if (healthPlayer <= 0)
{
Destroy(gameObject);
gameOver.GameOverScreen();
}
}
}
}
void Decrease()
{
transform.localScale -= new Vector3(speedDecrease, speedDecrease, speedDecrease) * Time.deltaTime;
transform.hasChanged = true;
}
}

My if statement is On constant use and doesn't do the statement

So I have Ctr C Ctr V an Interaction System from YT channel.
I have perfectly copied line by line But the only issue was that he was using the old input system and used KeyPressedDown and keyPressedUp to make 2 boolean's which change according what state is the keypressed, I tried to mimic it with new Input system by making it from a button to a Axis value which follows the logic of if its ClickedAxis>0.4 its true and ClockedAxis==0 false, as a quick press it worked so I was happy BUT here comes the bug
My if statement is Being Spammed Constantly like none stop. My statement basically say's that if the Interacting is true Do :
bool interacting;
If(interacting)
{
float HoldingDownTimer+=Time.DeltaTime;
if(HoldingDownTimer>=5)
{
//Do your task;
}
}
but When I run the statement For some reason it prints 0.0110823 values which are stuck at that range of number's no lower no higher, My theory is that its been spam called.
Here's the Script
If your interested for all the components the YT channel is this guy's VeryHotShark
using UnityEngine;
using NaughtyAttributes;
public class LocomotionScript : MonoBehaviour
{
#region Data
[BoxGroup("Animation Handling Data")]
Animator animator;
int isWalkingHash;
[SerializeField] bool movementPressed;
[BoxGroup("Input Handling Data")]
private CharacterController controller;
public MovementInput input;
Vector2 currentMovement;
[SerializeField] float speed = 1;
private Vector3 velocity;
private float gravity = -9.81f;
public Transform ground;
public float distanceToGround = 0.4f;
public LayerMask groundMask;
private Vector2 smoothinMovement;
private float smoothInputSpeed;
private Vector2 tempCurrentMovement;
private bool isGrounded;
public InteractionInputData interactionInput;
#endregion
private void Awake()
{
animator = GetComponent<Animator>();
input = new MovementInput();
controller = GetComponent<CharacterController>();
input.KeyBoard.ASWD.performed += ctx =>
{
currentMovement = ctx.ReadValue<Vector2>();
movementPressed = currentMovement.x != 0 || currentMovement.y != 0;
};
}
private void Start()
{
interactionInput.Reset();
}
void GetInteractionInputData()
{
interactionInput.InteractedClicked = input.KeyBoard.Interact.ReadValue<float>() > 0.1f;
interactionInput.InteractedReleased = input.KeyBoard.Interact.ReadValue<float>() == 0f;
}
private void Update()
{
LocoMotion();
Grav();
Interact();
GetInteractionInputData();
}
void Grav()
{
isGrounded = Physics.CheckSphere(ground.position, distanceToGround, groundMask);
if (isGrounded && velocity.y<0)
{
velocity.y = -2f;
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
void Interact()
{
}
void LocoMotion()
{
tempCurrentMovement=Vector2.SmoothDamp(tempCurrentMovement, currentMovement, ref smoothinMovement, smoothInputSpeed);
Vector3 movement = (tempCurrentMovement.y * transform.forward) + (tempCurrentMovement.x * transform.right);
WalkAnimation();
controller.Move(movement * speed * Time.deltaTime);
}
void WalkAnimation()
{
animator.SetBool("WalkingHush", movementPressed);
}
private void OnEnable()
{
input.KeyBoard.ASWD.Enable();
input.KeyBoard.Interact.Enable();
}
private void OnDisable()
{
input.KeyBoard.ASWD.Enable();
input.KeyBoard.Interact.Enable();
}
}
//
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace th
{
public class InteractionController : MonoBehaviour
{
#region Variables
[Header("Data")]
public InteractionData interactionData;
public InteractionInputData interactionInputData;
[Space]
[Header("RaySetting's")]
public float rayDistance;
public float raySphereRadius;
public LayerMask interactableLayer;
#endregion
#region Private
private Camera m_cam;
private bool m_interacting;
private float m_holderTimer = 0.0f;
#endregion
#region BuildIn
private void Awake()
{
m_cam = FindObjectOfType<Camera>();
}
private void Update()
{
CheckForInteractable();
CheckForInteractableInput();
}
#endregion
#region Crafted Methodds
void CheckForInteractable()
{
Ray _ray = new Ray(m_cam.transform.position, m_cam.transform.forward);
RaycastHit _hitInfo;
bool _hitSomething = Physics.SphereCast(_ray, raySphereRadius, out _hitInfo,
rayDistance,interactableLayer);
if (_hitSomething)
{
InteractableBase _interactable = _hitInfo.transform.GetComponent<InteractableBase>();
if (_interactable != null)
{
if (interactionData.isEmpty())
{
interactionData.Interactable = _interactable;
}
else
{
if (!interactionData.IsSameInteractible(_interactable))
interactionData.Interactable = _interactable;
}
}
}
else
{
interactionData.ResetData();
}
Debug.DrawRay(_ray.origin, _ray.direction * rayDistance, _hitSomething ? Color.green : Color.red);
}
void CheckForInteractableInput()
{
if (interactionData.isEmpty())
{
return;
}
if (interactionInputData.InteractedClicked)
{
m_interacting = true;
m_holderTimer = 0f;
}
if (interactionInputData.InteractedReleased)
{
m_interacting = false;
m_holderTimer = 0f;
}
if (m_interacting)
{
if (!interactionData.Interactable.IsInteractible)
return;
if (interactionData.Interactable.HoldInteract)
{
m_holderTimer += Time.deltaTime;
Debug.Log(m_holderTimer);
if (m_holderTimer >= interactionData.Interactable.holdDuration)
{
interactionData.Interact();
m_interacting = false;
}
}
else
{
interactionData.Interact();
m_interacting = false;
}
}
}
#endregion
}
}
///
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace th
{
[CreateAssetMenu(fileName ="Interaction Data",menuName = "InteractionSystem/InteractionData")]
public class InteractionData : ScriptableObject
{
private InteractableBase m_interactible;
public InteractableBase Interactable
{
get => m_interactible;
set => m_interactible = value;
}
public void Interact()
{
m_interactible.OnInteract();
ResetData();
}
public bool IsSameInteractible(InteractableBase _newInteractible) => m_interactible == _newInteractible;
public bool isEmpty() => m_interactible == null;
public void ResetData()=> m_interactible = null;
}
}
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "InteractionInputData", menuName = "InteractionSystem/InputData")]
public class InteractionInputData : ScriptableObject
{
private bool m_interactedClicked;
private bool m_interactRelease;
public bool InteractedClicked
{
get => m_interactedClicked;
set => m_interactedClicked = value;
}
public bool InteractedReleased
{
get => m_interactRelease;
set => m_interactRelease = value;
}
public void Reset()
{
m_interactedClicked = false;
m_interactRelease = false;
}
}
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace th
{
public interface IInteractible
{
float HoldDurration { get; }
bool HoldInteract { get; }
bool MultipleUse { get;}
bool IsInteractible { get; }
void OnInteract();
}
}
//
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace th{
public class InteractableBase : MonoBehaviour,IInteractible
{
#region Variables
[Header("Interactible Settings")]
public float holdDuration;
[Space]
public bool holdInteract;
public bool multipleUse;
public bool isInteractible;
#endregion
#region Properties
public float HoldDurration => holdDuration;
public bool HoldInteract => holdInteract;
public bool MultipleUse => multipleUse;
public bool IsInteractible => isInteractible;
#endregion
#region Methods
public void OnInteract()
{
Debug.Log("Interacted: " + gameObject.name);
}
#endregion
}
}
Well without parsing through your entire code:
once
HoldingDownTimer >= 5
is true you still keep adding more time in the next frame so the condition is still true in the next frame => you will keep calling it all the following frames as well.
You could introduce a flag somewhat like e.g.
private bool alreadyCalled;
and then
if(interacting)
{
if(!alreadyCalled)
{
HoldingDownTimer += Time.DeltaTime;
if(HoldingDownTimer >= 5)
{
alreadyCalled = true;
//Do your task;
}
}
}
else
{
alreadyCalled = false;
}
As far as I understood your code I think:
I found the issue in it actually you are checking if the 'm_holdTimer' >= 'holdDuration' then perform interaction and you are making it equal to 0 on click start and click end.
So it means if the player has continuously held the button then it will not reset 'm_holdTimer'... so it will continue to call the function recursively because player hasn't actually ended the click so there is not any single function which is reseting 'm_holdTimer' to 0. still if you didn't get my point just copy this function and paste it instead of your own and see if it works, if it do work then you can check the difference between line of code then you'll understand it for sure.
void CheckForInteractableInput()
{
if (interactionData.isEmpty())
{
return;
}
if (interactionInputData.InteractedClicked)
{
m_interacting = true;
m_holderTimer = 0f;
}
if (interactionInputData.InteractedReleased)
{
m_interacting = false;
m_holderTimer = 0f;
}
if (m_interacting)
{
if (!interactionData.Interactable.IsInteractible)
return;
if (interactionData.Interactable.HoldInteract)
{
m_holderTimer += Time.deltaTime;
Debug.Log(m_holderTimer);
if (m_holderTimer >= interactionData.Interactable.holdDuration)
{
m_holderTimer = 0f;
interactionData.Interact();
m_interacting = false;
}
}
else
{
interactionData.Interact();
m_interacting = false;
}
}
}
Hope it helps... Happy coding :)

How to change variable class in child class

I have class UnitComponent that contains references to every script of the unit. Every unit has scripts UnitUI and UnitStats. So I can access UnitUI methods from UnitStats using UnitComponent class (for example: unitComponent.unitUI.SetHealthUI()). Of course, every script has a reference to UnitComponent class as well to be able to use it. These three scripts have children (PlayerComponent, PlayerUI, PlayerStats). These classes have new methods, for example PlayerUI has SetManaUI() method. But I can't use SetManaUI() using PlayerComponent without creating new variable with PlayerUI class because UnitUI variable doesn't have this method. Is there any option to make new methods accessible through variable unitUI by changing class to PlayerUI or I have to create new PlayerUI variable and somehow get rid of unitUI.
I've tried to make virtual empty method SetManaUI() in UnitUI class and override it in PlayerUI class to make everything work, but it seems like a bad practise because UnitUI can become full of useless empty virtual methods.
Simplified version of scripts
Script that connects scripts together
using UnityEngine;
public class Collector : MonoBehaviour
{
public Stats stats;
public UI ui;
}
UI script
using UnityEngine;
public class UI : MonoBehaviour
{
Collector collector;
public void UIMethod()
{
Debug.Log("UI method");
}
}
Stats script
using UnityEngine;
public class Stats : MonoBehaviour
{
Collector collector;
public void StatsMethod()
{
Debug.Log("Stats method");
}
}
Child of collector script
public class ChildCollector : Collector
{
public string someNewData;
public string someNewData1;
public string someNewData2;
public void Start()
{
ui.ChildUIMethod(); //has to be executed and write "Child UI method"
stats.ChildStatsMethod(); //has to be executed and write "Child Stats method"
}
}
Child of UI script
using UnityEngine;
public class ChildUI : UI
{
ChildCollector childCollector;
public void ChildUIMethod()
{
Debug.Log("Child UI Method");
}
}
Child of Stats script
using UnityEngine;
public class ChildStats : Stats
{
ChildCollector childCollector;
public void ChildStatsMethod()
{
Debug.Log("Child Stats Method");
}
}
Full version of scripts
Unit Component script
using UnityEngine;
public class UnitComponent : MonoBehaviour
{
public Animator animator;
public UnitStats unitStats;
public UnitUI unitUI;
}
UnitStats script
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
public class UnitStats : MonoBehaviour
{
public UnitComponent unitComponent;
public float maxHealth;
public float health;
public List<GameObject> lootDrop;
protected virtual void Start()
{
if (health <= 0 || health > maxHealth)
health = maxHealth;
unitComponent.unitUI.SetHealthUI(health, maxHealth);
CheckDeath();
}
private void CreateDamagePopup(float takenDamage)
{
GameObject damagePopupCanvas = Instantiate(unitComponent.unitUI.damagePopupCanvasPref, transform.position, Quaternion.identity, transform);
damagePopupCanvas.GetComponentInChildren<Text>().text = takenDamage.ToString();
Vector3 randomPosOffset = new Vector3(Random.Range(-0.1f, 0.1f), Random.Range(-0.1f, 0.1f), 0f);
damagePopupCanvas.transform.position += randomPosOffset;
Destroy(damagePopupCanvas, 3f);
}
public float CalculateHealthPercentage()
{
return (health / maxHealth);
}
protected void CheckDeath()
{
if (health <= 0)
{
unitComponent.animator.SetTrigger("isDead");
DropLoot();
}
}
protected void CheckOverheal()
{
if (health > maxHealth)
{
health = maxHealth;
}
}
public void DealDamage(int damage)
{
unitComponent.unitUI.healthBar.SetActive(true);
health -= damage;
unitComponent.unitUI.SetHealthUI(health, maxHealth);
CheckDeath();
CreateDamagePopup(damage);
}
public void HealCharacter(int heal)
{
health += heal;
CheckOverheal();
unitComponent.unitUI.SetHealthUI(health, maxHealth);
}
public void DropLoot()
{
foreach (GameObject item in lootDrop)
Instantiate(item, transform.position, Quaternion.identity);
}
}
UnitUI script
using UnityEngine;
using UnityEngine.UI;
public class UnitUI : MonoBehaviour
{
public UnitComponent unitComponent;
public GameObject damagePopupCanvasPref;
public GameObject healthBar;
protected Slider healthBarSlider;
virtual public void Start()
{
healthBarSlider = healthBar.GetComponent<Slider>();
}
public virtual void SetHealthUI(float health, float maxHealth)
{
if (healthBarSlider)
healthBarSlider.value = health / maxHealth;
}
public virtual void SetCoinsUI(int coinAmount) { } //Necessary for PlayerUI script working
public virtual void SetManaUI(float mana, float maxMana) { } //Necessary for PlayerUI script working
}
PlayerComponent script
using UnityEngine;
public class PlayerComponent : UnitComponent
{
public PlayerMovement playerMovement;
public PlayerSlot playerSlot;
public Rigidbody2D rb;
}
PlayerStats script
using UnityEngine;
public class PlayerStats : UnitStats
{
protected int coins;
public float mana;
public float maxMana;
public float manaRegenPerSec;
protected override void Start()
{
UI = gameObject.GetComponent<PlayerUI>();
animator = gameObject.GetComponent<Animator>();
if (health <= 0 || health > maxHealth)
health = maxHealth;
UI.SetHealthUI(health, maxHealth);
UI.SetManaUI(mana, maxMana);
CheckDeath();
}
public void Update()
{
if (mana < maxMana)
{
mana += manaRegenPerSec * Time.deltaTime;
UI.SetManaUI(mana, maxMana);
}
}
private void Awake()
{
DontDestroyOnLoad(this);
}
public void AddCoins(int amount)
{
coins += amount;
UI.SetCoinsUI(amount);
}
}
PlayerUI script
using System;
using UnityEngine;
using UnityEngine.UI;
public class PlayerUI : UnitUI
{
[SerializeField] protected GameObject manaBar;
[SerializeField] protected Text manaValue;
[SerializeField] protected Text healthValue;
[SerializeField] protected Text coinValue;
protected Slider manaBarSlider;
public override void Start()
{
healthBarSlider = healthBar.GetComponent<Slider>();
manaBarSlider = manaBar.GetComponent<Slider>();
}
public override void SetHealthUI(float health, float maxHealth)
{
healthBarSlider.value = health / maxHealth;
healthValue.text = health.ToString() + "/" + maxHealth.ToString();
}
public override void SetManaUI(float mana, float maxMana)
{
manaBarSlider.value = mana / maxMana;
manaValue.text = Math.Round(mana).ToString() + "/" + Math.Round(maxMana).ToString();
}
public override void SetCoinsUI(int coinAmount)
{
coinValue.text = coinAmount.ToString();
}
}

Can't add script to GameObject

I have been repeatedly getting an error, when trying to add a script to a gameObject. I have so far tried changing the MonoBehavior class name to what I had as the scripts name, and checked my code for errors, though none are shown in the terminal. Here`s my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace LE
{
public class InputHandler : MonoBehaviour
{
public float horizontal;
public float vertical;
public float moveAmountl;
public float mouseX;
public float mouseY
PlayerControls inputActions;
Vector2 movementInput;
Vector2 cameraInput
public void private void OnEnable() {
{
if (inputActions == null)
{
inputActions = new PlayerControls();
inputActions.PlayerMovement.Movement.performed += inputActions => movementInput = inputActions.ReadValue<Vector2>();
inputActions.PlayerMovement.Camera.performed += i => cameraInput = i.ReadValue<Vector2>();
}
inputActions.Enable();
}
private void private void OnDisable()
{
inputActions.Disable();
}
}
public void TickInput(float delta)
{
MoveInput(delta);
}
private void MoveInput(float delta)
{
horizontal = movementInput.x;
vertical = movementInput.y;
moveAmountv= Mathf.Clamp01(Mathf.Abs(horizontal) + Mathf.abs(vertical));
mouseX = cameraInput.x;
mouseY = cameraInput.y;
}
}
}
It could be this (note typed twice private and public void):
public void private void OnEnable() {
private void private void OnDisable()
{
inputActions.Disable();
}
should be
private void OnEnable() {
private void OnDisable()
{
inputActions.Disable();
}

Connecting Health Bar to Damage dealt

I'm new to Unity and together with a few friends, I try to make a game. I was trying to connect the healthbar I made to the damage u can deal by shooting knifes. First to test this I used:
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse1))
{
TakeDamage(25);
}
}
Everything worked fine and when I pressed Mouse1 the healthbar worked.My goal was, that when a knife hits the enemy 25 damage is dealt and the healthbar shows that the enemy lost health. However, when the knifes hit the enemy nothing happens. Can you please help me because I tried fixing this for like 3 hours and I'm getting kinda frustrated. Thank you.
Here's the code for the healthbar:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class healthbar : MonoBehaviour
{
public Slider slider;
public void SetMaxHealth(int health)
{
slider.maxValue = health;
slider.value = health;
}
public void SetHealth(int health)
{
slider.value = health;
}
}
And here's the code for the enemy:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy_Follow : MonoBehaviour
{
public float speed;
public Transform target;
public int damage = 25;
public int maxHealth = 100;
public int currentHealth;
public healthbar healthBar;
// Start is called before the first frame update
void Start()
{
currentHealth = maxHealth;
healthBar.SetMaxHealth(maxHealth);
target = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse1))
{
TakeDamage(25);
}
transform.position = Vector2.MoveTowards(transform.position, target.position, speed * Time.deltaTime);
}
public void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Knife")
{
TakeDamage(25);
}
}
public void TakeDamage(int damage)
{
currentHealth -= damage;
healthBar.SetHealth(currentHealth);
}
}
After finding out that your colliders are not triggers it should rather be OnCollisionEnter2D like e.g.
public void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Knife"))
{
TakeDamage(25);
}
}
See also Colliders -> Collision Action Matrix
You may try this code to look if the slider works at all. If this code does work (You can change things with the inspector) then it should be an error with the collision/trigger detection and nothing else.
public class SliderTest : MonoBehaviour {
public Slider slider;
public int maxHealth = 100;
private int currentHealth = 100;
public bool resetHealth = false;
public bool damage = false;
void Start() {
slider = GetComponent<Slider>();
SetMaxHealth(maxHealth);
}
void Update() {
if(resetHealth) {
resetHealth = false;
SetHealth(maxHealth);
}
if(damage) {
damage = false;
SetHealth(currentHealth-10);
}
}
public void SetMaxHealth(int health) {
slider.maxValue = health;
slider.value = 100;
}
public void SetHealth(int health) {
currentHealth = health;
slider.value = currentHealth;
}
}
}

Categories

Resources