Here are a few code samples from my most recent 3D game which you can read about on the Untitled Movement Shooter page.
A simple damage number script which pops the number out when firing:
void Start()
{
// References
rb = GetComponent<Rigidbody>();
target = GameObject.FindWithTag("Player");
hitNumber = GetComponentInChildren<TMP_Text>();
// Dynamic sizing
initScale = transform.localScale;
// Crit coloring
damageColor = critHit ? critColor : normalColor;
// Shoots off damage number in a random direction.
rb.AddForce(new Vector3(randDir(), 1.5f, randDir()), ForceMode.Impulse);
// Destroy timer
Destroy(this.gameObject, timeToDestroy);
}
void Update()
{
// If there's a player in the scene, look at them
if(target != null)
transform.LookAt(target.transform);
// Fade text with countdown of destroy timer.
if(timeToDestroy > destroyCurTime)
{
destroyCurTime += Time.deltaTime;
hitNumber.color = new Color (damageColor.r, damageColor.g, damageColor.b, (timeToDestroy / destroyCurTime) - 1f);
}
// Dynamic sizing
float distance = (target.transform.position - transform.position).magnitude;
float size = distance * fixedSize / 12.5f;
transform.localScale = Vector3.one * size;
}
// The scrunkly (color fade)
public void updateDamageText(float damage, bool crit, float critHitMult)
{
// Pass the crit outside of the referenced script (for color).
critHit = crit;
// Make sure that the other functions fire first
Start();
Update();
// Update the text.
hitNumber.text = "-" + System.Math.Round(damage,2).ToString();
}
I reference that inside of a interface for damageable items!
public interface IDamagable
{
public void Damage(float damage, bool crit, float critHitMult, string gunName);
public static void spawnHitNumber(float damage, bool crit, float critHitMult, Vector3 spawnLoc)
{
GameObject curHitNumber = GameObject.Instantiate(Resources.Load<GameObject>("Prefabs/HitCanvas"), spawnLoc, Quaternion.identity);
curHitNumber.GetComponent<HitNumberScript>().updateDamageText(damage, crit, critHitMult);
}
}
Utilizing Unity’s prefab system, I can very easily prototype this out and reference it inside of gun scripts.
Speaking of gun scripts…
[CreateAssetMenu(fileName="Gun", menuName="Weapon/Gun")]
public class GunData : ScriptableObject
{
public enum GunType {
Automatic,
SingleShot,
Projectile
}
[Header("Stats")]
public string gunName;
public float damage;
public float critHitMult;
public float maxDistance;
[Space(5)]
[Header("Weapon Type Data")]
public GunType weaponType;
// Automatic
public int automaticFireRate;
// Projectile
public float projectileSpeed;
public GameObject projectilePrefab;
// Single shot
public float singleShotDelay;
[Space(5)]
[Header("Weapon Sounds")]
public List<AudioClip> fireSounds = new List<AudioClip>();
}
I can create scriptable objects in Unity to rapidly prototype new weapon ideas, though any special gimics would have to be coded into the weapons themselves.