#Data structures & projectile sytstems
1 messages · Page 1 of 1 (latest)
I mean, part of my intent with this project was to make weapons procedurally generated - which is why I've put so much effort into WeaponAbilities and ProjectileEndAbilities and the like (so I could assign point values to each of them and have some code select WeaponAttributes randomly)
but I presume this could be used to make defaults?
yeah! if you create a robust system that allows you to test stuff from the editor, creating weapons and populating them with WeaponAbilities via code should be a breeze
imo WeaponGeneration should be a separate system, even
it most likely will be a seperate system
doesn't seem the best idea to cram weapon generation in with the weapon functionality
About your suggestion that I dismantle Stat and StatManager though.. what would I replace it with? I'm not exactly sure how I'd split it up in a way that allows me to retain the flexibility of the existing system
so, stat can be something that adds to the damage as well, right?
I communicate to stats with seperate data containers, but it's usually just floats*
Here's the code that does the vast majority of the stuff behind pickup collection
[CreateAssetMenu]
public class WeaponData : ScriptableObject {
public float BaseDamage;
public List<WeaponAbility> Abilities; // Populate via inspector or code
public void Hit(Character shooter, Character target) {
target.TakeDamage(BaseDamage);
foreach (var ability in Abilities) { ability.OnHit(shooter, target); }
// Make sure you populate the `Abilities` list to contain damage abilities first, or the OnKill ones may not trigger
// You could easily add functionality that orders them to put OnKill ones last, though.
// ..or better, instead, add a special `Damage` value on each ability -- which could be 0, and a `OnPostHit` method.. and use, for example:
target.TakeDamage(BaseDamage + abilities.Sum(x => x.Damage)); // Single TakeDamage call.
foreach (var ability in Abilities) { ability.OnPostHit(shooter, target); } // OnKill events and Effects
}
}
public abstract class WeaponAbility : ScriptableObject {
public virtual float DamageModification { get; }
public abstract void OnHit(Character shooter, Character target);
}
[CreateAssetMenu]
public class DamageAbility : WeaponAbility {
[SerializeField] float Damage; // Assigned via inspector -- or code if you want..
public override void OnHit(Character shooter, Character target) {
target.TakeDamage(Damage);
// maybe special effect?
}
}
[CreateAssetMenu]
public class RefundAmmoOnKillAbility : WeaponAbility {
[SerializeField] int ammoAmount;
public override void OnHit(Character shooter, Character target) {
if (target.GetComponent<HealthSystem>().HP > 0) { return; } // Since it's an OnKill ability
shooter.GetComponent<WeaponSystem>().GetAmmo(ammoAmount);
// maybe special effect?
}
}
each non-abstract scriptable object class needs to be on a separate .cs file, though
and you can right click the project window and create a new instance of it
this shows the workflow in tldr perfectly https://www.youtube.com/watch?v=lJxy3oTZeCs
In this video we take a look at how to use scriptable objects, what they're for and why you might want to use them.
Be sure to LIKE and SUBSCRIBE if you enjoyed this guide! Share the video for extra love!
Here's a great post about ways you can use Scriptable Objects: https://blogs.unity3d.com/2017/11/20/making-cool-stuff-with-scriptableobjects...
np 🙂 check updated code though.. added some info on WeaponData.Hit()