I am working on a weapon system that uses scriptable objects, for my game, and the problem I am currently facing is checking for the array of scriptable objects and prioritising the layer assigned by the selected array element.
E1: So basically what I was trying to say was, the foreach function in my script would set the animation layer weight to zero on every iteration, and when the index matches the equipped weapon in the array, it’d set the weight of its assigned animation layer to 1.
The code where I tried to implement the foreach loop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
using Cinemachine;
using StarterAssets;
public class TPSController : MonoBehaviour
{
[Header("Aim Camera")]
[SerializeField] private CinemachineVirtualCamera aimCamera;
[SerializeField] private float normalSensitivity;
[SerializeField] private float aimSensitivity;
[Space]
[Header("Scriptable Objects")]
[SerializeField] private WeaponScriptableObject[] loadout;
[SerializeField] private Transform weaponParent;
private int equippedWeaponIndex;
[Space]
[SerializeField] private LayerMask aimColliderLayerMask = new LayerMask();
// [SerializeField] private Transform debugTransform;
[SerializeField] private Transform bulletProjectile;
[SerializeField] private Transform gunTip;
private ThirdPersonController controller;
private StarterAssetsInputs starterAssetsInputs;
private Animator animator;
private GameObject currentWeapon;
private void Awake()
{
controller = GetComponent<ThirdPersonController>();
starterAssetsInputs = GetComponent<StarterAssetsInputs>();
animator = GetComponent<Animator>();
}
// Start is called before the first frame update
void Start()
{
controller.SetRotateOnMove(false);
Equip(0);
}
void Equip(int p_ind)
{
if (currentWeapon != null) Destroy(currentWeapon);
GameObject t_newWeapon = Instantiate(loadout[p_ind].weaponModel, weaponParent.position, weaponParent.rotation, weaponParent) as GameObject;
t_newWeapon.transform.localPosition = Vector3.zero;
currentWeapon = t_newWeapon;
equippedWeaponIndex = p_ind;
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Alpha1)) Equip(0);
if (Input.GetKeyDown(KeyCode.Alpha2)) Equip(1);
if (Input.GetKeyDown(KeyCode.Alpha3)) Equip(2);
if (Input.GetKeyDown(KeyCode.Alpha4)) Equip(3);
// \/ \/ \/ \/ \/ Highlighted Code problem
// foreach(var item in loadout)
// {
// animator.SetLayerWeight(loadout[item].animLayer, Mathf.Lerp(animator.GetLayerWeight(loadout[item].animLayer), 1f, Time.deltaTime * 10f));
// if (loadout[item] == loadout[equippedWeaponIndex])
// {
// animator.SetLayerWeight(loadout[equippedWeaponIndex].animLayer, Mathf.Lerp(animator.GetLayerWeight(loadout[equippedWeaponIndex].animLayer), 1f, Time.deltaTime * 10f));
// }
// }
// /\ /\ /\ /\ /\ Highlighted Code problem
Vector3 mouseWorldPosition = Vector3.zero;
Vector2 screenCenterPoint = new Vector2(Screen.width / 2, Screen.height / 2);
Ray ray = Camera.main.ScreenPointToRay(screenCenterPoint);
Transform hitTransform = null;
if (Physics.Raycast(ray, out RaycastHit hit, 999f, aimColliderLayerMask))
{
mouseWorldPosition = hit.point;
hitTransform = hit.transform;
}
if (starterAssetsInputs.aim)
{
controller.SetSensitivity(aimSensitivity);
controller.SetRotateOnMove(false);
aimCamera.gameObject.SetActive(true);
// animator.SetLayerWeight(1, Mathf.Lerp(animator.GetLayerWeight(1), 1f, Time.deltaTime * 10f));
Vector3 worldAimTarget = mouseWorldPosition;
worldAimTarget.y = transform.position.y;
Vector3 aimDirection = (worldAimTarget - transform.position).normalized;
transform.forward = Vector3.Lerp(transform.forward, aimDirection, Time.deltaTime * 20f);
}
else
{
// animator.SetLayerWeight(1, Mathf.Lerp(animator.GetLayerWeight(1), 0f, Time.deltaTime * 20f));
controller.SetSensitivity(normalSensitivity);
controller.SetRotateOnMove(false);
aimCamera.gameObject.SetActive(false);
Vector3 worldAimTarget = mouseWorldPosition;
worldAimTarget.y = transform.position.y;
Vector3 aimDirection = (worldAimTarget - transform.position).normalized;
transform.forward = Vector3.Lerp(transform.forward, aimDirection, Time.deltaTime * 20f);
}
if (starterAssetsInputs.shoot)
{
if (hitTransform != null)
{
if (hit.transform.GetComponent<BulletTarget>() != null)
{
Instantiate(loadout[equippedWeaponIndex].impactVFXPlayer, hit.point, Quaternion.identity);
}
else
{
Instantiate(loadout[equippedWeaponIndex].impactVFX, hit.point, Quaternion.identity);
}
}
// Vector3 aimDir = (mouseWorldPosition - gunTip.position).normalized;
// Transform bulletproj = Instantiate(bulletProjectile, gunTip.position, Quaternion.LookRotation(aimDir, Vector3.up));
starterAssetsInputs.shoot = false;
}
}
}
And the scriptable object with the animation layer index:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[CreateAssetMenu(fileName = "New Weapon", menuName = "Weapon")]
public class WeaponScriptableObject : ScriptableObject
{
public string weaponName;
public GameObject weaponModel;
[Space]
public float fireRate;
public float damage;
[Space]
public int ammoCapacity;
[Space]
public float reloadTime;
public enum BulletType { Hitscan, Projectile }
[Space]
public BulletType bulletType;
[Header("Hitscan Settings")]
public float physForce = 10f;
[Header("Projectile Settings")]
public Transform projectile;
public Transform gunTip;
[Space]
public Transform muzzleFlash;
public Transform impactVFX;
public Transform impactVFXPlayer;
[Space]
public AudioClip shootSound;
public AudioClip reloadSound;
[Space]
[Header("Animations")]
public int animLayer;
}
Any help would be appreciated. Thanks.