Simple Damage Modifier System for Invector Melee Controller.
Nov 29, 2020 5:32:01 GMT
uberwiggett, rolfy, and 1 more like this
Post by eldv on Nov 29, 2020 5:32:01 GMT
Hi all,
I have cobbled together a simple modifier system for Invector Melee Controller.
It will allow both players and NPC/AIs to have damage type resistances or weaknesses. For instance you could have a fire monster that was immune to Fire damage, but very weak against Ice attacks. Or your player can be resistant to poison, but vulnerable to Lightning Attacks. There are 10 types of common damage coded into the script. However it can be extended however you like. One of these days I will need to make it a lot less hard coded. But I have tested it, and it works!
There is a primary script, and two support scripts for labeling to make things not confusing.
DamageModifier.cs - this script is added to your player or your NPC.
LabelOverride.cs - Add file to scripts folder. This will change the variable labels to something that makes human sense.
NamedArrayAttribute.cs - Allows to change the name of Array elements to make them easier to read and use.
NamedArrayDrawer.cs - Add this to a folder named "Editor" in your scripts folder. This controls the Custom Property Drawer for the NamedArrayAttribute script.
MeleeAttackObject: The modifications needed for the MeleeAttackObject.cs.
1. Add two variables in the variable declarations at the top of the script.
2. Replace the ApplyDamage function with the following:
This works with the current version of the Invector MeleeController. I have not tested with the Shooter Controller, as I am not currently using that one in my project.
How to use:
DAMAGE TYPES FOR DAMAGE MODIFIER SCRIPT
The Damage Type indexes are as follows:
Fire Damage: 0
Ice Damage: 1
Impact Damage: 2
Lightning Damage: 3
Poison Damage: 4
Acid Damage: 5
Radiant Damage: 6
Shadow Damage: 7
Necrotic Damage: 8
Assign each index a float value between -100 and 100:
Negative values between -100 and 0 indicate a resistance.
Positive values between 0 and 100 indicate vulnerability.
A Neutral value of 0 will calculate no modifier + or -.
Additional damage types can be added as you like, and just need to be added to the Case statement and the named array label in the variable declaration of DamageModifier.cs .
I have cobbled together a simple modifier system for Invector Melee Controller.
It will allow both players and NPC/AIs to have damage type resistances or weaknesses. For instance you could have a fire monster that was immune to Fire damage, but very weak against Ice attacks. Or your player can be resistant to poison, but vulnerable to Lightning Attacks. There are 10 types of common damage coded into the script. However it can be extended however you like. One of these days I will need to make it a lot less hard coded. But I have tested it, and it works!
There is a primary script, and two support scripts for labeling to make things not confusing.
DamageModifier.cs - this script is added to your player or your NPC.
using System.Collections;
using System.Collections.Generic;
using Invector.vCharacterController;
using Invector.vMelee;
using UnityEngine;
namespace Invector {
public class DamageModifier : MonoBehaviour {
[Header("For each index, add a percentage value for damage type:")]
[Tooltip("See the vComment above for the corresponding damage type for each index.")]
[LabelOverride("Damage Type:")] public string dmgType;
[NamedArrayAttribute(new string[] { "Fire Damage:", "Ice Damage:", "Impact Damage:", "Lightning Damage:", "Poison Damage:", "Acid Damage:", "Radiant Damage:", "Shadow Damage:", "Necrotic Damage:"})]
public float[] dmgAmt;
[HideInInspector]public float dmgMod;
[HideInInspector]public int dmgIndex;
private vThirdPersonController controller;
private vMeleeWeapon weapon;
private vMeleeManager manager;
private vHealthController healthcontroller;
// Start is called before the first frame update
void Start () {
controller = FindObjectOfType<vThirdPersonController> ();
manager = controller.GetComponent<vMeleeManager> ();
}
public void GetDamageType (string damageType) {
dmgType = damageType;
if (dmgType != null)
{
switch (dmgType)
{
case "FireDamage":
dmgIndex = 0;
dmgMod = dmgAmt[dmgIndex]/100;
break;
case "IceDamage":
dmgIndex = 1;
dmgMod = dmgAmt[dmgIndex] / 100;
break;
case "ImpactDamage":
dmgIndex = 2;
dmgMod = dmgAmt[dmgIndex] / 100;
break;
case "LightningDamage":
dmgIndex = 3;
dmgMod = dmgAmt[dmgIndex] / 100;
break;
case "PoisonDamage":
dmgIndex = 4;
dmgMod = dmgAmt[dmgIndex] / 100;
break;
case "AcidDamage":
dmgIndex = 5;
dmgMod = dmgAmt[dmgIndex] / 100;
break;
case "RadiantDamage":
dmgIndex = 6;
dmgMod = dmgAmt[dmgIndex] / 100;
break;
case "ShadowDamage":
dmgIndex = 7;
dmgMod = dmgAmt[dmgIndex] / 100;
break;
case "DeathDamage":
dmgIndex = 8;
dmgMod = dmgAmt[dmgIndex] / 100;
break;
default:
dmgMod = 0;
break;
}
}
else { dmgMod = 0; }
}
}
}
LabelOverride.cs - Add file to scripts folder. This will change the variable labels to something that makes human sense.
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
public class LabelOverride : PropertyAttribute
{
public string label;
public LabelOverride(string label)
{
this.label = label;
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(LabelOverride))]
public class ThisPropertyDrawer : PropertyDrawer
{
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
try
{
var propertyAttribute = this.attribute as LabelOverride;
if (IsItArray(property) == false)
{
label.text = propertyAttribute.label;
}
else
{
Debug.LogWarningFormat(
"{0}(\"{1}\") doesn't support arrays ",
typeof(LabelOverride).Name,
propertyAttribute.label
);
}
EditorGUI.PropertyField(position, property, label);
}
catch (System.Exception ex) { Debug.LogException(ex); }
}
bool IsItArray(SerializedProperty property)
{
string path = property.propertyPath;
int idot = path.IndexOf('.');
if (idot == -1) return false;
string propName = path.Substring(0, idot);
SerializedProperty p = property.serializedObject.FindProperty(propName);
return p.isArray;
//CREDITS: https://answers.unity.com/questions/603882/serializedproperty-isnt-being-detected-as-an-array.html
}
}
#endif
}
NamedArrayAttribute.cs - Allows to change the name of Array elements to make them easier to read and use.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NamedArrayAttribute : PropertyAttribute
{
public readonly string[] names;
public NamedArrayAttribute(string[] names) { this.names = names; }
}
NamedArrayDrawer.cs - Add this to a folder named "Editor" in your scripts folder. This controls the Custom Property Drawer for the NamedArrayAttribute script.
using UnityEngine;
using UnityEditor;
[CustomPropertyDrawer(typeof(NamedArrayAttribute))]
public class NamedArrayDrawer : PropertyDrawer
{
public override void OnGUI(Rect rect, SerializedProperty property, GUIContent label)
{
try
{
int pos = int.Parse(property.propertyPath.Split('[', ']')[1]);
EditorGUI.PropertyField(rect, property, new GUIContent(((NamedArrayAttribute)attribute).names[pos]));
}
catch
{
EditorGUI.PropertyField(rect, property, label);
}
}
}
MeleeAttackObject: The modifications needed for the MeleeAttackObject.cs.
1. Add two variables in the variable declarations at the top of the script.
[HideInInspector] DamageModifier dmgmodifier;
[HideInInspector] float dmgMod = 0;
2. Replace the ApplyDamage function with the following:
public void ApplyDamage(vHitBox hitBox, Collider other, vDamage damage)
{
vDamage _damage = new vDamage(damage);
_damage.receiver = other.transform;
dmgmodifier = other.GetComponent<DamageModifier>();
if (damage.damageType != null && dmgmodifier != null)
{
dmgmodifier.GetDamageType(damage.damageType);
dmgMod = dmgmodifier.dmgMod;
}
else if (damage.damageType == null || dmgmodifier == null){dmgMod = 0;}
_damage.damageValue = (int)Mathf.RoundToInt(((float)((damage.damageValue*dmgMod)+damage.damageValue) + damageModifier) * (((float)hitBox.damagePercentage) * 0.01f));
_damage.hitPosition = hitBox.transform.position;
other.gameObject.ApplyDamage(_damage, meleeManager.fighter);
}
This works with the current version of the Invector MeleeController. I have not tested with the Shooter Controller, as I am not currently using that one in my project.
How to use:
DAMAGE TYPES FOR DAMAGE MODIFIER SCRIPT
The Damage Type indexes are as follows:
Fire Damage: 0
Ice Damage: 1
Impact Damage: 2
Lightning Damage: 3
Poison Damage: 4
Acid Damage: 5
Radiant Damage: 6
Shadow Damage: 7
Necrotic Damage: 8
Assign each index a float value between -100 and 100:
Negative values between -100 and 0 indicate a resistance.
Positive values between 0 and 100 indicate vulnerability.
A Neutral value of 0 will calculate no modifier + or -.
Additional damage types can be added as you like, and just need to be added to the Case statement and the named array label in the variable declaration of DamageModifier.cs .