I am trying to implement a “FarmPlot” class that will perform certain interactions depending on the weapon the player has equipped. The problem is that I am not entirely sure how to reference the currently equipped item. I am trying to access it using the Equipment and Weapon config class, similar to how you made Fighter.UpdateWeapon() work:
FarmPlot Class:
using System.Collections;
using System.Collections.Generic;
using RPG.Control;
using UnityEngine;
using RPG.Combat;
using GameDevTV.Inventories;
namespace RPG.Farming
{
public class FarmPlot : MonoBehaviour
{
[SerializeField] bool isTilled = false;
[SerializeField] bool isPlanted = false;
[SerializeField] bool isWatered = false;
[SerializeField] Material tilledSoilTexture = null;
Equipment equipment;
private void Awake()
{
equipment = GetComponent<Equipment>();
}
void Update()
{
if (Input.GetMouseButton(0))
{
HandleRaycast();
}
}
public void HandleRaycast()
{
RaycastHit hit;
if (Physics.Raycast(GetMouseRay(), out hit))
{
if (hit.collider.gameObject.tag == "Farm")
{
FarmPlot soil = hit.collider.gameObject.GetComponent<FarmPlot>();
TillFarmPlot(soil);
}
}
}
public void TillFarmPlot(FarmPlot soil)
{
if (equipment.GetItemInSlot(EquipLocation.Weapon) == null) return;
var weapon = equipment.GetItemInSlot(EquipLocation.Weapon) as WeaponConfig;
Vector3 soilLocation = soil.transform.position;
if (soil.isTilled) return;
if (!soil.isTilled && weapon.GetTool() == "Hoe")
{
soil.isTilled = true;
soil.GetComponent<MeshRenderer>().material = tilledSoilTexture;
print("Tilling this farm plot");
}
}
public void WaterFarmPlot()
{
}
public void PlantinFarmPlot()
{
}
private static Ray GetMouseRay()
{
return Camera.main.ScreenPointToRay(Input.mousePosition);
}
}
}
WeaponConfig class (added a series of bools and a GetTool() method)
using UnityEngine;
using RPG.Attributes;
using GameDevTV.Inventories;
using RPG.Stats;
using System.Collections.Generic;
namespace RPG.Combat
{
[CreateAssetMenu(fileName = "Weapon", menuName = "Weapons/Make New Weapon", order = 0)]
public class WeaponConfig : EquipableItem, IModifierProvider
{
[SerializeField] AnimatorOverrideController animatorOverride = null;
[SerializeField] Weapon equippedPrefab = null;
[SerializeField] float weaponDamage = 5f;
[SerializeField] float percentageBonus = 0;
[SerializeField] float weaponRange = 2f;
[SerializeField] bool isRightHanded = true;
[SerializeField] Projectile projectile = null;
[SerializeField] bool canTill = false;
[SerializeField] bool canPlant = false;
[SerializeField] bool canWater = false;
[SerializeField] bool canChop = false;
[SerializeField] bool canMine = false;
const string weaponName = "Weapon";
public Weapon Spawn(Transform rightHand, Transform leftHand, Animator animator)
{
DestroyOldWeapon(rightHand, leftHand);
Weapon weapon = null;
if (equippedPrefab != null)
{
Transform handTransform = GetTransform(rightHand, leftHand);
weapon = Instantiate(equippedPrefab, handTransform);
weapon.gameObject.name = weaponName;
}
var overrideController = animator.runtimeAnimatorController as AnimatorOverrideController;
if (animatorOverride != null)
{
animator.runtimeAnimatorController = animatorOverride;
}
else if (overrideController != null)
{
animator.runtimeAnimatorController = overrideController.runtimeAnimatorController;
}
return weapon;
}
private void DestroyOldWeapon(Transform rightHand, Transform leftHand)
{
Transform oldWeapon = rightHand.Find(weaponName);
if (oldWeapon == null)
{
oldWeapon = leftHand.Find(weaponName);
}
if (oldWeapon == null) return;
oldWeapon.name = "DESTROYING";
Destroy(oldWeapon.gameObject);
}
private Transform GetTransform(Transform rightHand, Transform leftHand)
{
Transform handTransform;
if (isRightHanded) handTransform = rightHand;
else handTransform = leftHand;
return handTransform;
}
public bool HasProjectile()
{
return projectile != null;
}
public void LaunchProjectile(Transform rightHand, Transform leftHand, Health target, GameObject instigator, float calculatedDamage)
{
Projectile projectileInstance = Instantiate(projectile, GetTransform(rightHand, leftHand).position, Quaternion.identity);
projectileInstance.SetTarget(target, instigator, calculatedDamage);
}
public float GetDamage()
{
return weaponDamage;
}
public float GetPercentageBonus()
{
return percentageBonus;
}
public float GetRange()
{
return weaponRange;
}
public IEnumerable<float> GetAdditiveModifiers(Stat stat)
{
if (stat == Stat.Damage)
{
yield return weaponDamage;
}
}
public IEnumerable<float> GetPercentageModifiers(Stat stat)
{
if (stat == Stat.Damage)
{
yield return percentageBonus;
}
}
public string GetTool()
{
if (canTill)
{
return "Hoe";
}
return "Not a tool";
}
}
}
The idea is that if the weapon scriptable object has “canTill” set to true, upon clicking on the farm plot prefab it will change the texture of the soil and mark the farm plot as “isTilled”. Currently this works if I remove any references to equipment and simply click the prefab, but I get the following null reference exception if I try to reference the item in the weapon slot: