[SOLVED] Difficulty wiring scripts, resetting health and position

As the title suggests, I am having a few issues with wiring up particular scripts, wiring the PlayerController to the Healthbar script that I’ve learnt to build myself. So far the Healthbar follows the player and shows the %, but it fails to update whenever damage from incoming fire.

PlayerController:

{
public float speed = 15.0f;
public float padding = 1f;
public bool autoPlay = false;
float xmin;
float xmax;
public GameObject Lazer1;
public GameObject Lazer2;
public float LazerSpeed = 10;
public float LazerRepeatRate = 0.2f;
public float Health = 500f;
public AudioClip boom1;
private GameManager _gameManager;
private bool Alive = true;

private void Awake()
{
    _gameManager = GameObject.FindObjectOfType<GameManager>();
}

void Start()
{
    float distance = transform.position.z - Camera.main.transform.position.z;
    Vector3 Leftmost = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, distance));
    Vector3 Rightmost = Camera.main.ViewportToWorldPoint(new Vector3(1, 0, distance));
    xmin = Leftmost.x + padding;
    xmax = Rightmost.x - padding;
}
void Fire()
{
    Vector3 StartPosition1 = transform.position + new Vector3(0.39f, 0.39f, 0);
    GameObject Laz1 = Instantiate(Lazer1, StartPosition1, Quaternion.identity) as GameObject;
    Laz1.GetComponent<Rigidbody2D>().velocity = new Vector3(0, LazerSpeed, 0);
    Vector3 StartPosition2 = transform.position + new Vector3(-0.39f, 0.39f, 0);
    GameObject Laz2 = Instantiate(Lazer2, StartPosition2, Quaternion.identity) as GameObject;
    Laz2.GetComponent<Rigidbody2D>().velocity = new Vector3(0, LazerSpeed, 0);
}

void Update()
{
    if (Input.GetKeyDown(KeyCode.Space))
    {
        InvokeRepeating("Fire", 0.0001f, LazerRepeatRate);
    }
    if (Input.GetKeyUp(KeyCode.Space))
    {
        CancelInvoke("Fire");
    }
    if (Input.GetKey(KeyCode.LeftArrow))
    {
        //transform.position += new Vector3(-speed * Time.deltaTime, 0, 0); This is a longer version of the same thing below. The right way is + instead of -.
        //Deltatime is used to get speed independent of framerate.
        transform.position += Vector3.left * speed * Time.deltaTime;
    }
    else if (Input.GetKey(KeyCode.RightArrow))
    {
        transform.position += Vector3.right * speed * Time.deltaTime;
    }
    //Restricts player to Gamespace
    float newX = Mathf.Clamp(transform.position.x, xmin, xmax);
    transform.position = new Vector3(newX, transform.position.y, transform.position.z);
    //Vector3 is for 3D games generally, but can still work in 2D games.   
}
public void OnTriggerEnter2D(Collider2D collider)
{
    Projectile EnemyFire = collider.gameObject.GetComponent<Projectile>();
    if (EnemyFire)
    {
        Health -= EnemyFire.GetDamage();
        EnemyFire.Hit();
        if (Health <= 0)
        {
            AudioSource.PlayClipAtPoint(boom1, transform.position, volume: 10f);
            _gameManager.PlayerLosesLife();
            Alive = false;
        }
    }

}
private void Respawn()
{
    if (Alive != true) {
        SpawnLocation();
    }
}
private void SpawnLocation() {
    this.transform.position = new Vector3(0f, -4.28f,0f);
}

}

I have been attempting to wire this to the player script. I also hope to wire this to the boss script so that bosses display a bar and the player knows that they are actually doing damage. Afterall, what would Dark Souls be like if you removed the health bar? You’d have no idea if you did any damage at all let alone how close you were with each new technique. I’m certainly not making this game anywhere near as good or complex as those games, but I hope you see my point.
HealthBar:

public class HealthBar : MonoBehaviour {

public Image healthpoints;
public Text ratioHealth;

private float Health = 500;
private float MaxHealth = 500;
private PlayerController playerlife;

private void Awake()
{
    playerlife = GameObject.FindObjectOfType<PlayerController>();
}

private void Start()
{
    HealthPoints();

    
}

private void HealthPoints() {
    float ratio = Health / MaxHealth;
    healthpoints.rectTransform.localScale = new Vector3(ratio, 1, 1);
    ratioHealth.text = (ratio*100).ToString("0") + '%';

}

private void TakeDamage(float damage) {
    Health -= damage;
    if (Health < 0)
    {
        Health = 0;
        Debug.Log("Dead");

    }
    HealthPoints();

}

This script below I took my time to attempt to write it to the player and respawn the player to that point after he loses a life, however for the moment all that happens it that is respawns where it is the health remains at 0 so single attacks cause another death so I want to find out how to have the hitpoints fill up after the player has been spawned.
Spawning Script:

public class RespawnPoint : MonoBehaviour {

public Transform player;
public Transform respawnPoint;

public void Respawn()
{
    player.transform.position = respawnPoint.transform.position;
}

}

I have managed to build some new scripts thanks to help online, but appear to be having difficulty wiring them up. Can anyone suggest how to fix these scripts? After that all I need to do is add visual explosions, dialog boxes and then I’ll start building more units and modified boss units too.

Laser Defender 0.7

Thank you for any help you can offer :slight_smile:

1 Like

Is there some code missing, I never see you use playerlife later on in the HealthBar script?

1 Like

That was a poor attempt for me to attempt to link the two scripts together, much like I already have going with GameManager and LevelManager being able to reference for lives count down and etc.

It’s one of many attempts I’ve tried to connect the two together so that the healthbar goes down everytime the player gets hit.

1 Like

I feel like you are close to getting it, so don’t beat yourself too much.

Hope I can give you some inspiration on connecting the two scripts. Lets keep all the code as it is.

On the HealthScript, you have a float variable Health.

There is a private method called TakeDamage where health is deducted (on taking damage). Why don’t you have some code here that sends the data from Health in the HealthScript to the PlayerController?

private void TakeDamage(float damage) {
Health -= damage;
playerlife.Health = Health;
if (Health < 0)
{
Health = 0;
Debug.Log("Dead");
}

Theres a lot of other code involved, but hopefully this could be a starting point for you to kick off on?

2 Likes

How about making your TakeDamage function public and calling it from the OnTriggerEnter2D function of the PlayerController?

2 Likes

To be honest, while Sebastian’s solution will probably work, I wouldn’t recommend duplicating data as you have done, I would probably make the healthbar script only responsible for updating the slider/health bar, it doesn’t need to know anything about total health and actual health, those data should only be within the actual PlayerController IMO, you should be ready to go with something as simple as this:

public class HealthBar : MonoBehaviour {

public Image healthpoints;
public Text ratioHealth;


private void Start()
{
    HealthPoints(1f);
}

public void HealthPoints(float ratio) 
{
    healthpoints.rectTransform.localScale = new Vector3(ratio, 1, 1);
    ratioHealth.text = (ratio*100).ToString("0") + '%';
}
}

and within the player controller you make this:

//variable initializations

float maxHealth;
HealthBar healthBar;

private void Awake()
{
healthBar = FindObjectOfType<HealthBar>();
maxHealth = Health;
_gameManager = GameObject.FindObjectOfType<GameManager>();
}

// and within the OnTriggerEnter2D:

public void OnTriggerEnter2D(Collider2D collider)
{
    Projectile EnemyFire = collider.gameObject.GetComponent<Projectile>();
    if (EnemyFire)
    {
        Health -= EnemyFire.GetDamage();
        healthBar.HealthPoints(Health/maxHealth);
        EnemyFire.Hit();
        if (Health <= 0)
        {
            AudioSource.PlayClipAtPoint(boom1, transform.position, volume: 10f);
            _gameManager.PlayerLosesLife();
            Alive = false;
        }
    }
}

This way you won’t be duplicating data and you are making the HealthBar script only resposible for updating the actual bar.

3 Likes

Wow, thanks for that solution it really helped! Now I’m going to attempt to add the same thing to the enemies, especially bosses so that the player knows that they are making a dent into the damage of the craft.

Glad for being able to help :slight_smile:
Btw, awesome job you are doing by incrementing the actual game structure, we learn a lot in the process, keep it up :muscle:

1 Like

Thanks :slight_smile: I’ve been altering my projects each time with some new ideas to improve my learning instead of simply copy/pasting the original project, which has been very useful, like learning how to do lives when I made my BlockBreaker game and then tried to instantiate within this game too.

Got a few more ideas to alter the later projects, such as with Glitch Garden and 10-pin bowling.

1 Like