@NickName7331

Unity3D(C#) — Почему не восстанавливается здоровье персонажа?

Я делал "систему" здоровья персонажа, и наткнулся на проблему: когда персонаж пытается восстановить последнее "сердечко" - оно не восстанавливается(хотя первые 4 восстанавливаются). Вот код персонажа:
spoiler
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using UnityEngine.SceneManagement;
using System;

public class Character : Unit
{
	[SerializeField]
	private float speed = 3.0F;
	[SerializeField]
	private int lives = 5;
	[SerializeField]
	private int fallController = -10;

	private int coins = 0;

	public int Lives
	{
		get { return lives; }
		set 
		{
			if (value < 5) lives = value;
			livesBar.Refresh ();
		}
	}

	public int Coins
	{
		get { return coins; }
	}

	private LivesBar livesBar;


	[SerializeField]
	private float jumpForce = 15.0F;

	private bool isGrounded = false;

	private Bullet bullet;

	private CharState State
	{
		get { return (CharState)animator.GetInteger ("State"); }
		set { animator.SetInteger("State", (int)  value); }
	}


	new private Rigidbody2D rigidbody;
	private Animator animator;
	private SpriteRenderer sprite;

	private void Awake()
	{
		livesBar = FindObjectOfType<LivesBar> ();
		rigidbody = GetComponent<Rigidbody2D> ();
		animator = GetComponent<Animator> ();
		sprite = GetComponentInChildren<SpriteRenderer> ();

		bullet = Resources.Load<Bullet> ("Bullet");
	}

	private void FixedUpdate()
	{
		CheckGround ();
	}

	private void Update()
	{
		if (isGrounded) State = CharState.Idle;

		if (Input.GetButtonDown ("Fire1")) Shoot ();
		if (Input.GetButton ("Horizontal")) Run ();
		if (isGrounded && Input.GetButtonDown ("Jump")) Jump ();
		if (gameObject.transform.position.y < fallController)
		{
			Debug.Log("Player Dead");
			SceneManager.LoadScene (SceneManager.GetActiveScene ().name);
		}
	}

	private void Run()
	{
		Vector3 direction = transform.right * Input.GetAxis ("Horizontal");

		transform.position = Vector3.MoveTowards (transform.position, transform.position + direction, speed * Time.deltaTime);

		sprite.flipX = direction.x < 0.0F;

		if (isGrounded) State = CharState.Run;
	}

	private void Jump()
	{
		
		rigidbody.AddForce (transform.up * jumpForce, ForceMode2D.Impulse);


	}

	private void Shoot()
	{
		Vector3 position = transform.position;   position.y += 0.8F;
		Bullet newBullet = Instantiate (bullet, position, bullet.transform.rotation) as Bullet;

		newBullet.Parent = gameObject;
		newBullet.Direction = newBullet.transform.right * (sprite.flipX ? -1.0F : 1.0F);
	}

	public override void ReceiveDamage()
	{
		
		Lives--;
		if (lives == 0)
		{
			ReloadScene();
		}
		rigidbody.velocity = Vector3.zero;
		rigidbody.AddForce(transform.up * 12.0F, ForceMode2D.Impulse);
	}

    private void CheckGround()
	{
		Collider2D[] colliders = Physics2D.OverlapCircleAll (transform.position, 0.3F);

			isGrounded = colliders.Length > 1;

		if (!isGrounded) State = CharState.Jump;
	}

	private void OnTriggerEnter2D(Collider2D collider)
	{
		Bullet bullet = collider.gameObject.GetComponent<Bullet> ();
		if (bullet && bullet.Parent != gameObject) 
		{
			ReceiveDamage ();
		}
	}
	private void ReloadScene()
	{
		Thread.Sleep (500);
		SceneManager.LoadScene (SceneManager.GetActiveScene ().name);
	}
}

public enum CharState
{
	Idle,
	Run,
	Jump
}


Вот код пополнения "сердечек":
spoiler
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Heart : MonoBehaviour 
{
	private void OnTriggerEnter2D(Collider2D collider)
	{
		Character character = collider.GetComponent<Character> ();

		if (character) 
		{
			character.Lives++;
			Destroy (gameObject);
		}
	}
}


Вот код "отображения сердечек персонажа":
spoiler
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LivesBar : MonoBehaviour 
{
	private Transform[] hearts = new Transform[5];

	private Character character;

	private void Awake()
	{
		character = FindObjectOfType<Character> ();

		for (int i = 0; i < hearts.Length; i++)
		{
			hearts[i] = transform.GetChild(i);
		}
	}

	public void Refresh()
	{
		for (int i = 0; i < hearts.Length; i++)
		{
			if (i < character.Lives)
				hearts [i].gameObject.SetActive (true);
			else
				hearts [i].gameObject.SetActive (false);
		}
	}
}



За ранее рад помощи.
  • Вопрос задан
  • 386 просмотров
Решения вопроса 2
MrMureno
@MrMureno Куратор тега Unity
VR for all
судя по коду у вас должно быть пять жизней и пять сердечек (и кстати советовал бы ввести одну переменную под КОЛИЧЕСТВО ЖИЗНЕЙ и везде использовать именно её.

а так вам могу только предложить отладку включить и посмотреть что происходит на момент пополнения сердец

но если не хотите сами искать то вот вам так сказать споилер-наводка
if (i < character.Lives) - а от какого до какого значения меняется у вас жизнь? я так вижу от 0 до 4.
то есть полные 5 жизней у вас когда Lives == 4
а при проверке будет только для i равное 0,1,2,3 - включаться.
тоесть вам или жизни считать от 1 до 5. и условие в свойстве Lives менять. или по массиву проходите с другим условием))
Ответ написан
OKyJIucT
@OKyJIucT
Sunshine reggae
Вообще не спец в C#, но подозреваю, что проблема в условии работы цикла, возможно, вместо "меньше" надо использовать "меньше или равно".
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@NonameProgrammer
Мне кажется, (в юнити не спец), что это происходит из-за того, что вы всегда создаёте новый объект
>Вот код пополнения "сердечек":
spoiler

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Heart : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D collider)
{
Character character = collider.GetComponent ();

if (character)
{
character.Lives++;
Destroy (gameObject);
}
}
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы