Upload your character to mixamo and download 3 differents spell magic animation, if you haven rig your player download with skin.
if you have rig before then just download without skin, the format should choose fbx for unity
change different animation
drag and drop your animation to your unity project and open a folder to make them more organize
select your animation file in asset there, change the animation type to humanoid and remember to click apply
do this steps to all the spell animation file that you import to unity
select your player, inspector there you will see the player animator, double click the starterAssetsThirdPerson to open the animator
drag your spell animation to your player animator
drag all 3 spell animations to your animator
rightclick the anystate (green color) right click, make transition
final player animator will look like this
p/s: the "Any State" node in the Animator Controller is a special state that allows transitions to any animation state in your Animator, without needing to be triggered from a specific preceding state.
Select the parameter tab, + button, trigger
Add this 3 paramters for triggers.
CastFire
CastIce
CastLightning
Edit >> project settings
to allow the old and new input handling can be used
Player >> other settings> active input handling change to both
change to both, Remember to click apply
Make sure your trigger parameter is not check
Create empty SpellManager
Attach your script to SpellManager
using UnityEngine;
public class SwitchSpell : MonoBehaviour
{
public enum spellType { Fire, Ice, Lightning};
private spellType currentSpell = spellType.Fire;
Animator animator;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
animator = GameObject.FindWithTag("Player").GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.Alpha1))
{
currentSpell = spellType.Fire;
CastSpell();
}
if(Input.GetKeyDown(KeyCode.Alpha2))
{
currentSpell = spellType.Ice;
CastSpell();
}
if (Input.GetKeyDown(KeyCode.Alpha3))
{
currentSpell = spellType.Lightning;
CastSpell();
}
}
public void CastSpell()
{
switch(currentSpell)
{
case spellType.Fire:
animator.SetTrigger("CastFire");
break;
case spellType.Ice:
animator.SetTrigger("CastIce");
break;
case spellType.Lightning:
animator.SetTrigger("CastLightning");
break;
}
}
}
This script is about to change the animation of spell magic
Press 1 for skill1 and 2 for skill 2 and 3 for skill 3
Free RPG Icons Pack | 2D Icons | Unity Asset Store
download this from unity asset store
use button to change different spelling animation
On the 2d view button to adjust the ui canvas
Select the ui_canvas_starterAssetpack, remember to enable it
Duplicate your button sprint.
Duplicate 3 times
Change the source image for three of the button
Rename your spell icon
remove this script for all buttons
Update your script for switchspell
using UnityEngine;
public class SwitchSpell : MonoBehaviour
{
public enum spellType { Fire, Ice, Lightning };
private spellType currentSpell = spellType.Fire;
Animator animator;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
animator = GameObject.FindWithTag("Player").GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
CastSpell(0);
}
if (Input.GetKeyDown(KeyCode.Alpha2))
{
CastSpell(1);
}
if (Input.GetKeyDown(KeyCode.Alpha3))
{
CastSpell(2);
}
}
public void CastSpell(int spellNo)
{
currentSpell = (spellType)spellNo;
switch (currentSpell)
{
case spellType.Fire:
animator.SetTrigger("CastFire");
break;
case spellType.Ice:
animator.SetTrigger("CastIce");
break;
case spellType.Lightning:
animator.SetTrigger("CastLightning");
break;
}
}
}
Add spell manager to it
add castspell function to all button with the different id from 0 to 1
Get 3 type of particle effect from unity asset store
Fire, Ice, Lightning
https://assetstore.unity.com/packages/vfx/free-15-full-opaque-spell-317208
Area of Effect Spell FREE | Spells | Unity Asset Store
Import your particle effect to unity project
Add this script to SwitchSpell
public GameObject[] spellfxPrefab;
And you will see this in your spell manager.
Edit the 0 to 3 (we have 3 spell effects)
Add your particle effect to spellfx prefab
Open your human (player armature), find his hand
create empty object call spellspawnpoint
Add this code to SwitchSpell
public Transform spellSpawnPoint;
spellmanager there
Add the spell spawn point to it, mean the spell will spawn from this point
Now add enemy to our scene
Remember to extract texture and change the animation type to humanoid
Drag and drop your enemy to scene
Select add tag
Click add button
Key in the Enemy
Change the untagged to Enemy
using UnityEngine;
public class MagicProjectile : MonoBehaviour
{
public float speed = 10f;
private Transform target;
public void SetTarget(Transform newTarget)
{
target = newTarget;
}
void Update()
{
if (target == null)
{
Destroy(gameObject);
return;
}
Vector3 dir = (target.position - transform.position).normalized;
transform.position += dir * speed * Time.deltaTime;
transform.LookAt(target);
}
private void OnTriggerEnter(Collider other)
{
if (other.transform == target)
{
// Optional: Deal damage here
Destroy(gameObject);
}
}
}
Select the spell prefab that you are using. Add the MagicProjectile script
using UnityEngine;
public class SwitchSpell : MonoBehaviour
{
public enum spellType { Fire, Ice, Lightning };
private spellType currentSpell = spellType.Fire;
public GameObject[] spellfxPrefab;
public Transform spellSpawnPoint;
Animator animator;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
animator = GameObject.FindWithTag("Player").GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
CastSpell(0);
}
if (Input.GetKeyDown(KeyCode.Alpha2))
{
CastSpell(1);
}
if (Input.GetKeyDown(KeyCode.Alpha3))
{
CastSpell(2);
}
}
public void CastSpell(int spellNo)
{
currentSpell = (spellType)spellNo;
GameObject selectedParticle = spellfxPrefab[spellNo];
switch (currentSpell)
{
case spellType.Fire:
animator.SetTrigger("CastFire");
break;
case spellType.Ice:
animator.SetTrigger("CastIce");
break;
case spellType.Lightning:
animator.SetTrigger("CastLightning");
break;
}
// Get closest enemy or aimed target
GameObject target = FindClosestEnemy(); // Write this function
if (target != null && selectedParticle != null)
{
GameObject spell = Instantiate(selectedParticle, spellSpawnPoint.position, Quaternion.identity);
spell.GetComponent<MagicProjectile>().SetTarget(target.transform);
}
}
GameObject FindClosestEnemy()
{
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
GameObject closest = null;
float minDist = Mathf.Infinity;
Vector3 currentPos = transform.position;
foreach (GameObject enemy in enemies)
{
float dist = Vector3.Distance(enemy.transform.position, currentPos);
if (dist < minDist)
{
closest = enemy;
minDist = dist;
}
}
return closest;
}
}
Inside it, add a child Image (e.g., CooldownOverlay) with an alpha color and Image Type = Filled (Radial 360 or Horizontal).
Make sure CooldownOverlay.fillAmount = 1 means full cooldown, and 0 means ready.
Add child image (semi transparent image)
Change the child image width to 180 and height 180
Change a image then the color change to grey and alpha is semi transparent
Attach this code to each of your skill
using UnityEngine;
using UnityEngine.UI;
public class SkillCooldown : MonoBehaviour
{
public Button skillButton; // Reference to your skill button
public Image cooldownOverlay; // The fill image overlay
public float cooldownTime = 5f; // Cooldown duration in seconds
private bool isCooldown = false;
private float cooldownTimer = 0f;
void Start()
{
skillButton.onClick.AddListener(UseSkill);
cooldownOverlay.fillAmount = 0f; // Skill is ready at start
}
void Update()
{
if (isCooldown)
{
cooldownTimer -= Time.deltaTime;
cooldownOverlay.fillAmount = cooldownTimer / cooldownTime;
if (cooldownTimer <= 0f)
{
isCooldown = false;
skillButton.interactable = true;
cooldownOverlay.fillAmount = 0f;
}
}
}
void UseSkill()
{
if (!isCooldown)
{
Debug.Log("Skill Used!");
isCooldown = true;
cooldownTimer = cooldownTime;
skillButton.interactable = false;
cooldownOverlay.fillAmount = 1f;
// Place your skill action code here
}
}
}
Attach this health code to your enemy
// Health.cs
using UnityEngine;
public class Health : MonoBehaviour
{
public float maxHealth = 100f;
private float currentHealth;
public delegate void OnDeathDelegate();
public event OnDeathDelegate OnDeath;
void Start()
{
currentHealth = maxHealth;
}
public void TakeDamage(float amount)
{
currentHealth -= amount;
Debug.Log(gameObject.name + " took damage: " + amount);
if (currentHealth <= 0)
{
Die();
}
}
private void Die()
{
Debug.Log(gameObject.name + " has died.");
OnDeath?.Invoke();
// Optional: destroy object or play animation
Destroy(gameObject);
}
public float GetHealth() => currentHealth;
}
Update your caseSpell cs
using UnityEngine;
public class SwitchSpell : MonoBehaviour
{
public enum spellType { Fire, Ice, Lightning };
private spellType currentSpell = spellType.Fire;
public GameObject[] spellfxPrefab;
public Transform spellSpawnPoint;
Animator animator;
public float damageValue =0;
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
animator = GameObject.FindWithTag("Player").GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1))
{
CastSpell(0);
}
if (Input.GetKeyDown(KeyCode.Alpha2))
{
CastSpell(1);
}
if (Input.GetKeyDown(KeyCode.Alpha3))
{
CastSpell(2);
}
}
public void CastSpell(int spellNo)
{
currentSpell = (spellType)spellNo;
GameObject selectedParticle = spellfxPrefab[spellNo];
switch (currentSpell)
{
case spellType.Fire:
animator.SetTrigger("CastFire");
damageValue = 50;
break;
case spellType.Ice:
animator.SetTrigger("CastIce");
damageValue = 30;
break;
case spellType.Lightning:
animator.SetTrigger("CastLightning");
damageValue = 20;
break;
}
// Get closest enemy or aimed target
GameObject target = FindClosestEnemy(); // Write this function
if (target != null && selectedParticle != null)
{
GameObject spell = Instantiate(selectedParticle, spellSpawnPoint.position, Quaternion.identity);
spell.GetComponent<MagicProjectile>().SetTarget(target.transform);
Health enemyHealth = target.GetComponent<Health>();
if (enemyHealth != null)
{
enemyHealth.TakeDamage(damageValue);
}
}
}
GameObject FindClosestEnemy()
{
GameObject[] enemies = GameObject.FindGameObjectsWithTag("Enemy");
GameObject closest = null;
float minDist = Mathf.Infinity;
Vector3 currentPos = transform.position;
foreach (GameObject enemy in enemies)
{
float dist = Vector3.Distance(enemy.transform.position, currentPos);
if (dist < minDist)
{
closest = enemy;
minDist = dist;
}
}
return closest;
}
}
add collider to your enemy
Add health bar to your enemy
Canvas render mode change to world space
Canvas position
Slider position and scaling
Remember your slider must put as a children for enemy
Hide or delete the handle
Slider background change to red
Fill change to green
Attach your healthUI.cs to canvas and fill in the slot
using UnityEngine;
using UnityEngine.UI;
public class HealthUI : MonoBehaviour
{
public Health enemyHealth;
public Slider healthSlider;
void Update()
{
if (enemyHealth != null)
{
healthSlider.value = enemyHealth.GetHealth() / enemyHealth.maxHealth;
}
}
}