OK I fixed the Shield visibility issue on my own (along with some help from Thomas, which ultimately leads back to you, so thanks again ), now that my laptop is back from repairs, and here’s how I did it:
Here is my ‘ShieldConfig.cs’ script:
using System.Collections.Generic;
using UnityEngine;
using GameDevTV.Inventories;
using RPG.Stats;
namespace RPG.Combat {
[CreateAssetMenu(fileName = "Shield", menuName = "Defence/Shield", order = 0)]
public class ShieldConfig : EquipableItem, IModifierProvider
{
[SerializeField] Shield equippedPrefab;
[SerializeField] bool isRightHanded;
[SerializeField] float defenseBonus = 0;
[SerializeField] float percentageBonus = 0;
const string shieldName = "Shield";
public Shield SpawnEquipableItem(Transform rightHand, Transform leftHand) {
DestroyOldEquipableItem(rightHand, leftHand);
Shield shield = null;
if (equippedPrefab != null) {
Transform handTransform = GetTransform(rightHand, leftHand);
shield = Instantiate(equippedPrefab, handTransform);
shield.gameObject.name = shieldName;
}
return shield;
}
public Transform GetTransform(Transform rightHand, Transform leftHand) {
Transform handTransform;
if (isRightHanded) handTransform = rightHand;
else handTransform = leftHand;
return handTransform;
}
void DestroyOldEquipableItem(Transform rightHand, Transform leftHand) {
Transform oldWeapon = rightHand.Find(shieldName);
if (oldWeapon == null) {
oldWeapon = leftHand.Find(shieldName);
}
if (oldWeapon == null) return;
oldWeapon.name = "DESTROYING";
Destroy(oldWeapon.gameObject);
}
// Added Armor to 'Stats.cs'
public IEnumerable<float> GetAdditiveModifiers(Stat stat)
{
if (stat == Stat.Defence) yield return defenseBonus;
}
public IEnumerable<float> GetPercentageModifiers(Stat stat)
{
if (stat == Stat.Defence) yield return percentageBonus;
}
}
}
And here is my ‘Shield.cs’ script (which I have no intentions of assigning anything to it’s Unity Event for now, but similar to ‘Weapon.cs’, I created it, just in case I change my mind down the line):
using UnityEngine;
using UnityEngine.Events;
namespace RPG.Combat {
public class Shield : MonoBehaviour {
[SerializeField] UnityEvent onHit;
public void OnHit() {
onHit.Invoke();
}
}
}
And I also added these into ‘Fighter.cs’:
// Variables:
ShieldConfig defaultShield;
ShieldConfig currentShield;
LazyValue<Shield> currentEquippedShield;
// in 'void Awake()':
currentShield = defaultShield;
currentEquippedShield = new LazyValue<Shield>(null);
// Support functions for the Shield Equipment:
public void EquipShield (ShieldConfig shield) {
currentShield = shield;
currentEquippedShield.value = AttachShield(shield);
}
private Shield AttachShield(ShieldConfig shield) {
return shield.SpawnEquipableItem(rightHandTransform, leftHandTransform);
}
private void DestroyOffHandItem() {
Shield offHandWeapon = leftHandTransform.GetComponentInChildren<Shield>();
if (offHandWeapon == null) return;
DestroyImmediate(offHandWeapon.gameObject);
}
And in ‘Fighter.cs’, I updated the ‘UpdateWeapon()’ function to consider the shield as well:
private void UpdateWeapon() {
var weapon = equipment.GetItemInSlot(EquipLocation.Weapon) as WeaponConfig;
var shield = equipment.GetItemInSlot(EquipLocation.Shield) as ShieldConfig;
if (weapon == null) EquipWeapon(defaultWeapon);
else EquipWeapon(weapon);
if (shield != null) EquipShield(shield);
else DestroyOffHandItem();
}
Finally, I went to the Shield.cs Script Holder and reset the position transforms, placed y = 0.03 (so that the shield doesn’t go through the Players’ skin) and Rotated X by -90 degrees, and the shield looks perfect in the Players’ hand now (and obviously you can’t forget the Synty Scaling bug, so your hand transforms are all scaled by 100).
I still have 3 minor issues though:
- On my death, the shield disappears from my equipment system, but the item itself does not visibly disappear from my players’ hand for some reason… What went wrong here?
For this one, I tried solving it on my own as well, but failed. This is my attempt with ‘ShieldConfig.cs’:
private float health;
private Transform rightHandTransform;
private Transform leftHandTransform;
private void Awake() {
health = GameObject.FindWithTag("Player").GetComponent<Health>().GetHealthPoints();
rightHandTransform = GameObject.FindWithTag("Player").GetComponent<Fighter>().GetRightHandTransform();
leftHandTransform = GameObject.FindWithTag("Player").GetComponent<Fighter>().GetLeftHandTransform();
}
private void Update() {
if (health <= 0) DestroyOldEquipableItem(rightHandTransform, leftHandTransform);
}
[PLEASE HELP… ]
- The bow and the shield go to the same hand, so if we put either on… they both appear on the same hand. We should solve this when we go to the “2h” transition, right?
- [SOLVED THIS ONE ON MY OWN] I forgot this one, so… how do we get this shield config script to display the bonuses on the shield in the tooltip? Again, I just don’t remember how (apologies)
Here is my solution for the third problem, on my own:
public override string GetDescription()
{
string result = "Protection Shield"; // definition
result += $"\n\n{GetRawDescription()}\n"; // description of the gameObject
if ((int) defenseBonus != 0) { // color change of bonus, based on positive or negative
string bonus = defenseBonus > 0 ? "<color=#8888ff>bonus</color>" : "<color=#ff8888>penalty</color>";
if ((int) defenseBonus > 0) result += $"\n{(int)defenseBonus} point {bonus} to Defence";
else if ((int) defenseBonus <= 0) result += $"\n{(int)defenseBonus * -1} point {bonus} to Defence";
}
if ((int) percentageBonus != 0) {
string bonus = percentageBonus > 0 ? "<color=#8888ff>bonus</color>" : "<color=#ff8888>penalty</color>";
if ((int) percentageBonus > 0) result += $"\n{(int)percentageBonus} percentage {bonus} to Defence";
else if ((int) percentageBonus <= 0) result += $"\n{(int) percentageBonus * -1} percentage {bonus} to Defence";
}
return result;
}
Apart from that, we can move on to the 2h weapons issue, prior to trying out the dual weapon issue