I am very, very fresh to coding, and this is my first time posting on a forum, so I apologise if my formatting/etiquette is at all subpar! Basically, I have been studying a Udemy course to create a top down Zelda style RPG. I am currently on a lecture which has been teaching me to how make the sword sprite disappear, both in melee, but also when at full health, the sword becomes a long range projectile (only firing one at a time), before disappearing. Now I can fire out the swords, but the object is not being destroyed, and also I can spam them by pressing space bar, neither of which is the desired effect. I will post the code I have so far, which I realise is incomplete as it was when I was testing another segment I realised this problem arose. (There are only two files to consider thus far, the third one I do not believe would be relevant thus far)
The first is for the Player Character
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PlayerRPG : MonoBehaviour // All player variables - Public can be called on from other objects
{
public float speed; // assigns speed to Player Object
Animator anim; // enables animator
public Image[] Hearts; // enables heart images
public int MaxHealth; // assigns max health
int CurrentHealth; // assigns current health
public GameObject Sword; // rnables sword object
public float ThrustPower; // assigns Thrust power
public bool CanMove; // allows to call for disabled movement
public bool CanAttack; // allows to call to disable attack (limited attack)
// Start is called before the first frame update
void Start()
{
anim=GetComponent<Animator>();
CurrentHealth = MaxHealth;
GetHealth();
CanMove = true;
CanAttack = true;
}
//Establishing Health + Display Heart Icon
void GetHealth()
{
for(int i =0; i<Hearts.Length -1; i++)
{
Hearts[i].gameObject.SetActive(false);
}
for(int i = 0; i<= CurrentHealth - 1; i++)
{
Hearts[i].gameObject.SetActive(true);
}
}
// Update is called once per frame
void Update()
{
Movement();
if(Input.GetKeyDown(KeyCode.Space))
Attack();
if (CurrentHealth > MaxHealth)
CurrentHealth = MaxHealth;
GetHealth() ;
}
//Attack Function
void Attack()
{
if (!CanAttack)
return;
CanMove = false; //Stops movement to attack
CanAttack = false;
GameObject newSword = Instantiate(Sword, transform.position, Sword.transform.rotation);
if (CurrentHealth == MaxHealth)
{
newSword.GetComponent<Sword>().Special = true;
CanMove= true;
ThrustPower = 500;
}
#region //SwordRotation
int SwordDirection = anim.GetInteger("Direction");
anim.SetInteger("AttackDirection", SwordDirection);
if (SwordDirection == 0)
{
newSword.transform.Rotate(0, 0, 0);
newSword.GetComponent<Rigidbody2D>().AddForce(Vector2.up * ThrustPower);
}
else if (SwordDirection == 1)
{
newSword.transform.Rotate(0, 0, 180);
newSword.GetComponent<Rigidbody2D>().AddForce(Vector2.down * ThrustPower);
}
else if (SwordDirection == 2)
{
newSword.transform.Rotate(0, 0, 90);
newSword.GetComponent<Rigidbody2D>().AddForce(Vector2.left * ThrustPower);
}
else if (SwordDirection == 3)
{
newSword.transform.Rotate(0, 0, -90);
newSword.GetComponent<Rigidbody2D>().AddForce(Vector2.right * ThrustPower);
}
#endregion
}
//Movement Function
void Movement()
{
if (CanMove == false)
return; //If player is unable to move, restores movement if conditions allow
float movement = speed * Time.deltaTime;
if (Input.GetKey(KeyCode.W))
{ transform.Translate(0, movement, 0); anim.SetInteger("Direction", 0); anim.speed = 1; }
else if (Input.GetKey(KeyCode.S))
{ transform.Translate(0, -movement, 0); anim.SetInteger("Direction", 1); anim.speed = 1; }
else if (Input.GetKey(KeyCode.D))
{ transform.Translate(movement, 0, 0); anim.SetInteger("Direction", 3); anim.speed = 1; }
else if (Input.GetKey(KeyCode.A))
{ transform.Translate(-movement, 0, 0); anim.SetInteger("Direction", 2); anim.speed = 1; }
else
anim.speed = 0;
}
}
and the second is for the Sword itself
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Sword : MonoBehaviour
{
float Timer = .15f; //Time Sword animation exists - determines range before destruction
float SpecialTimer = 1f;
public bool Special; //Enables Special sword attack
public GameObject SwordParticle; // Enables Sword particle effect
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
Timer -= Time.deltaTime;
if (Timer < 0)
GameObject.FindGameObjectWithTag("Player").GetComponent<Animator>().SetInteger("AttackDirection", 5); //Assigns attack animation to direction
if(Special ==false )
if(Timer <= 0)
{
GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerRPG>().CanMove = true;//Searches for "Player" Tag, checks if they are able to move
GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerRPG>().CanAttack = true;//Searches for "Player" Tag, checks if they are able to attack
Destroy(gameObject);//Destroys sword
}
SpecialTimer -= Time.deltaTime;
if(SpecialTimer <= 0)
{
GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerRPG>().CanAttack = true;
Instantiate(SwordParticle, transform.position, transform.rotation);
Destroy(gameObject);
}
}
}
Note- I have “PlayerRPG” my name for my Player object tagged under player.
Again, I’m truly sorry if this is a lot to peel through, but I’m honestly I’m such a beginner I have no idea what the issue could be, and I’ve been pulling my hair out rewatching the same lecture over and over again. I would be very grateful for any assistance, making my own video game is a dream of mine I’ve recently decided to finally pursue, but a few of these early obstacles have me despairing!