After the refactor the game breaks when i try to launch it with this error:
InvalidCastException: Specified cast is not valid.
(wrapper castclass) System.Object.__castclass_with_cache(object,intptr,intptr)
UnityEngine.Object.Instantiate[T] (T original, UnityEngine.Transform parent, System.Boolean worldPositionStays) (at <c2d036c16ca64e0eb93703a3b13e733a>:0)
UnityEngine.Object.Instantiate[T] (T original, UnityEngine.Transform parent) (at <c2d036c16ca64e0eb93703a3b13e733a>:0)
RPG.Combat.WeaponConfig.Spawn (UnityEngine.Transform rightHandTransform, UnityEngine.Transform leftHandTransform, UnityEngine.Animator animator, RPG.Combat.SkeletonType type) (at Assets/Scripts/Combat/WeaponConfig.cs:33)
RPG.Combat.Fighter.SetupDefaultWeapon () (at Assets/Scripts/Combat/Fighter.cs:130)
GameDevTV.Utils.LazyValue`1[T].ForceInit () (at Assets/AssetPacks/GameDev.tv Assets/Scripts/Utils/LazyValue.cs:56)
RPG.Combat.Fighter.Start () (at Assets/Scripts/Combat/Fighter.cs:45)
So, following the call stack (at least to the point where I can reach, inside my scripts), we have line 45 of Fighter, which is inside Fighter.Start, which is
currentWeapon.ForceInit();
currentWeapon being
LazyValue<WeaponConfig> currentWeapon = null;
We then go to internal LazyValue stuff, which I hope it’s not broken because I wouldn’t know where to fix it since I didn’t write it, and we pass to line 130 again in Fighter.
private WeaponConfig SetupDefaultWeapon()
{
previousWeapon = defaultWeapon;
defaultWeapon.Spawn(rightHandTransform, leftHandTransform, animator, skeletonType); //This > is line 130
return defaultWeapon;
}
defaultWeapon being of the correct WeaponConfig type, I checked that.
[SerializeField] private WeaponConfig defaultWeapon = null;
So we finally reach the last call, which is line 33 of WeaponConfig
public void Spawn(Transform rightHandTransform, Transform leftHandTransform, Animator animator, SkeletonType type)
{
DestroyOldWeapon(rightHandTransform, leftHandTransform);
if (equippedWeaponPrefab != null)
{
Transform handTransform = GetHandTransform(rightHandTransform, leftHandTransform);
Weapon weapon = Instantiate(equippedWeaponPrefab[(int)type], handTransform); //this is line 33
weapon.gameObject.name = WEAPON_NAME;
}
AnimatorOverrideController overrideController = animator.runtimeAnimatorController as AnimatorOverrideController;
if (weaponAnimationOverride != null)
{
animator.runtimeAnimatorController = weaponAnimationOverride;
}
else if (overrideController != null)
{
animator.runtimeAnimatorController = overrideController.runtimeAnimatorController;
}
}
This method is a bit more convoluted than what is presented in the course because I’m using a mix of different free low poly models assets rather than the ones provided with the course, or even the rest of the paid package from Sinty. So I came up with the idea to make equippedWeapoPrefab an array of different prefabs tailored to each skeleton, and pass a SkeletonType enum variable so that the method chooses the right one and spawn the weapons in the right place and with the right orientation, because each model does its own thing in those departments. It worked reasonably well up until this moment and anyway it’s not part of the problem, I reckon. For what I can see, all the relevant variables are of the correct type. I’m not casting anything except the SkeletonTpe enum.
The call stack continues to internal Unity stuff that I cannot control whatsoever, so I’m hoping the mistake is somewhere in these bits. If not (like ho suspect), I can’t see how I could start to fix it.
I so far found that the culprit is changing the weaponprefab into a Weapon type. If I revert back to GameObject it does not complain anymore. So I think it’s Instantiate which doesn’t like being passed a Weapon object as prefab.
I’m at a loss, can anyone spot where the mistake is? How to fix it? Thanks!