Unity new input system
Hello, I am currently learning how to use the new unity input system as I am new yo unity.
I have been trying to update my shooting script with the new system and I am having trouble with setting my shoot key that I have setup up in the Input Actions
to a KeyCode
in unity. Is there anyone that could help me with this because I have searched everywhere but everything I have seen has not helped me out. Any help would be appreciated :)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
public enum FireMode {Single, Burst, Auto}
public class M4CARBINE : MonoBehaviour
{
[Header("KeyBinds")]
[SerializeField] private KeyCode _ShootKey = KeyCode.Mouse0;
[SerializeField] private KeyCode _ReloadKey = KeyCode.R;
[Space]
[Header("Enums")]
[SerializeField] private FireMode _fireMode = FireMode.Single;
[Space]
[Header("Refrences")]
[SerializeField] private Animator Anim;
[SerializeField] private Text Ammo;
[SerializeField] private GameObject BulletPrefab;
[SerializeField] private Transform BulletSpawnPos;
[SerializeField] private GameObject ShootPos;
[Space]
[Header("Gun Values")]
[SerializeField] private float FireRate;
[SerializeField] private float NextTimeToFire;
[SerializeField] private int CurrentAmmo = 40;
[SerializeField] private int MagCapacity = 140;
[SerializeField] private int MaxAmmo = 40;
[SerializeField] private float ReloadTime;
[SerializeField] private float BulletSpeed;
[SerializeField] private float BulletLife;
[SerializeField] private float TimeAfterReload;
[SerializeField] private float RayDist;
[Space]
[Header("Layers")]
[SerializeField] private LayerMask ShootAble;
[Space]
[Header("Strings")]
[SerializeField] private string ReloadAnimName;
[Space]
[Header("Bools")]
[SerializeField] private bool _ShootInput;
[SerializeField] private bool CanShoot;
[SerializeField] private bool ReloadPressed;
[SerializeField] private bool CanReload;
private InputMaster playerControls;
// private bool InputKey = playerControls.Player.Shoot.ReadValue();
private void Awake()
{
CanShoot = true;
_ShootInput = false;
ReloadPressed = false;
NextTimeToFire = 0f;
CurrentAmmo = MaxAmmo;
}
public void Update()
{
switch (_fireMode)
{
case FireMode.Auto:
_ShootInput = Input.GetKey(_ShootKey);
break;
case FireMode.Burst:
_ShootInput = Input.GetKeyDown(_ShootKey);
break;
case FireMode.Single:
_ShootInput = Input.GetKeyDown(_ShootKey);
break;
}
if(Input.GetKeyDown(_ReloadKey) && CurrentAmmo < MagCapacity && !ReloadPressed && CanReload)
{
StartCoroutine(Reload());
ReloadPressed = true;
}
if(CurrentAmmo <= 0)
{
CanShoot = false;
}
if(_ShootInput && Time.time >= NextTimeToFire && CanShoot)
{
Shoot();
NextTimeToFire = Time.time + 1f/FireRate;
}
Ammo.text = CurrentAmmo.ToString("0") + " / " + MagCapacity.ToString("0");
if (CurrentAmmo < MaxAmmo)
CanReload = true;
else if (CurrentAmmo == MaxAmmo)
CanReload = false;
}
IEnumerator Reload()
{
ReloadPressed = true;
CanShoot = false;
Anim.SetBool(ReloadAnimName, true);
Debug.Log("Reloading!");
yield return new WaitForSeconds(ReloadTime);
int ReloadAmount = MaxAmmo - CurrentAmmo;
if(MagCapacity >= MaxAmmo)
{
CurrentAmmo = MaxAmmo;
MagCapacity -= ReloadAmount;
}
else
{
CurrentAmmo = MagCapacity;
MagCapacity = 0;
}
Debug.Log("Done Reloading!");
Anim.SetBool(ReloadAnimName, false);
ReloadPressed= false;
yield return new WaitForSeconds(TimeAfterReload);
CanShoot = true;
}
private void Shoot()
{
CurrentAmmo --;
Debug.Log("Boom!");
var Bullet = Instantiate(BulletPrefab, BulletSpawnPos.position, BulletSpawnPos.rotation);
Bullet.GetComponent<Rigidbody>().velocity = BulletSpawnPos.forward * BulletSpeed;
RaycastHit hit;
if(Physics.Raycast(ShootPos.transform.position, ShootPos.transform.TransformDirection(Vector3.forward), out hit, RayDist, ShootAble))
{
//Debug.Log("Hit something!");
Destroy(Bullet, 0.5f);
}else
{
//Debug.Log("Hit nothing!");
Destroy(Bullet, 2.5f);
}
}
}
EDIT
How I could set a key code value from the old input system to another key code using the new input system, so basically I am asking how I can do this:
KeyCode _ShootKey = KeyCode.Mouse0;
And i want to do this with the new input so it would look something like this example:
KeyCode _ShootKey = controls.player.shoot.ReadValue();
So problem is, whenever I try and do this with the new input system I cannot because it keeps on giving me errors saying that I cannot do this. Would there be any method that I could use to get passed this but make sure that it still does the same thing?
@andrew-lukasik i saw that you put in new code But I cannot see it anymore because it says it deleted, could you possibly resend it ?
Ah yes, there was an error there but code from the the new post should work now.
Answer by andrew-lukasik · 3 days ago
I ported your code to the UnityEngine.InputSystem
. No KeyCode
here but InputActionReference
instead:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
public class M4CARBINE : MonoBehaviour
{
[Header("KeyBinds")]
[SerializeField] InputActionReference _shootActionRef;
[SerializeField] InputActionReference _reloadActionRef;
[SerializeField] InputActionReference _fireModeActionRef;
[Space]
[Header("References")]
[SerializeField] Animator _animator;
[SerializeField] Text _ammoText;
[SerializeField] GameObject _bulletPrefab;
[SerializeField] Transform _bulletSpawn;
[SerializeField] Transform _raycastSource;
[SerializeField] LayerMask ShootAble = ~0;
[SerializeField] string ReloadAnimName;
[Space]
[Header("Gun Parameters")]
[SerializeField] EFireMode _fireMode = EFireMode.Single;
[SerializeField] int CurrentAmmo = 40;
[SerializeField] int MagCapacity = 140;
[SerializeField] int MaxAmmo = 40;
[SerializeField] float FireRate = 1;
[SerializeField] float ReloadTime = 1;
[SerializeField] float BulletSpeed = 10;
[SerializeField] float BulletLife = 3;
[SerializeField] float TimeAfterReload = 1;
[SerializeField] float RayDist = 100;
float _lastShotTime = float.MinValue;
bool _reloadInProgress = false;
WaitForSeconds _reloadWait, _burstFireWait, _autoFireWait;
void Awake ()
{
CurrentAmmo = MaxAmmo;
UpdateAmmoText();
_reloadWait = new WaitForSeconds( ReloadTime + TimeAfterReload );
_burstFireWait = new WaitForSeconds( 1f/FireRate );
_autoFireWait = new WaitForSeconds( 1f/FireRate );
RegisterShootAction( _shootActionRef.action );
RegisterReloadAction( _reloadActionRef.action );
RegisterFireModeAction( _fireModeActionRef.action );
}
void OnDestroy ()
{
UnregisterShootAction( _shootActionRef.action );
UnregisterReloadAction( _reloadActionRef.action );
UnregisterFireModeAction( _fireModeActionRef.action );
}
void RegisterShootAction ( InputAction action )
{
action.started += OnShootStarted;
action.canceled += OnShootCanceled;
action.Enable();
}
void UnregisterShootAction ( InputAction action )
{
action.started -= OnShootStarted;
action.canceled -= OnShootCanceled;
action.Disable();
}
void RegisterReloadAction ( InputAction action )
{
action.started += OnReloadStarted;
action.Enable();
}
void UnregisterReloadAction ( InputAction action )
{
action.started -= OnReloadStarted;
action.Disable();
}
void RegisterFireModeAction ( InputAction action )
{
action.started += OnFireModeStarted;
action.Enable();
}
void UnregisterFireModeAction ( InputAction action )
{
action.started -= OnFireModeStarted;
action.Disable();
}
void OnShootStarted ( InputAction.CallbackContext ctx )
{
Debug.Log("shoot button pressed");
if( Time.time>(_lastShotTime+(1f/FireRate)) && CurrentAmmo>0 )
{
if( _fireMode==EFireMode.Single ) FireABullet();
else if( _fireMode==EFireMode.Burst ) StartCoroutine( BurstFireRoutine() );
else if( _fireMode==EFireMode.Auto ) StartCoroutine( AutoFireRoutine(ctx.action) );
}
}
void OnShootCanceled ( InputAction.CallbackContext ctx )
{
Debug.Log("shoot button released");
}
void OnReloadStarted ( InputAction.CallbackContext ctx )
{
Debug.Log("reload button pressed");
if( CurrentAmmo<MaxAmmo && !_reloadInProgress )
StartCoroutine( ReloadRoutine() );
}
void OnFireModeStarted ( InputAction.CallbackContext ctx )
{
Debug.Log("fire mode button pressed");
if( _fireMode==EFireMode.Single ) _fireMode = EFireMode.Burst;
else if( _fireMode==EFireMode.Burst ) _fireMode = EFireMode.Auto;
else _fireMode = EFireMode.Single;
Debug.Log($"FireMode changed to {_fireMode}");
}
IEnumerator ReloadRoutine ()
{
Debug.Log("Reloading!");
_reloadInProgress = true;
_animator.SetBool( ReloadAnimName , true );
yield return _reloadWait;
if( MagCapacity>=MaxAmmo )
{
CurrentAmmo = MaxAmmo;
MagCapacity -= MaxAmmo - CurrentAmmo;
}
else
{
CurrentAmmo = MagCapacity;
MagCapacity = 0;
}
_reloadInProgress = false;
_animator.SetBool( ReloadAnimName , false );
Debug.Log("Done Reloading!");
}
IEnumerator BurstFireRoutine ()
{
const int BURST_LENGTH = 3;
int i = 0;
while( i++<BURST_LENGTH )
{
FireABullet();
yield return _burstFireWait;
}
}
IEnumerator AutoFireRoutine ( InputAction action )
{
while( CurrentAmmo>0 && ( action.phase==InputActionPhase.Started || action.phase==InputActionPhase.Performed ) )
{
FireABullet();
yield return _autoFireWait;
}
}
void FireABullet ()
{
if( CurrentAmmo<=0 )
{
Debug.Log("no ammo, need to reload");
return;
}
Debug.Log("Boom!");
_lastShotTime = Time.time;
CurrentAmmo--;
UpdateAmmoText();
var bullet = Instantiate( _bulletPrefab , _bulletSpawn.position , _bulletSpawn.rotation );
bullet.GetComponent<Rigidbody>().velocity = _bulletSpawn.forward * BulletSpeed;
if( Physics.Raycast( _raycastSource.position , _raycastSource.forward , out var hit , RayDist , ShootAble ) )
{
//Debug.Log("Hit something!");
Destroy( bullet , 0.5f );
}
else
{
//Debug.Log("Hit nothing!");
Destroy( bullet , 2.5f );
}
}
void UpdateAmmoText () => _ammoText.text = $"{CurrentAmmo:0} / {MagCapacity:0}";
}
public enum EFireMode { Single , Burst , Auto }
@andrew-lukasik thank you for this so much!!
For the _fireModeActionRef do I just make a new input in my input actions or its something else?
Sorry for bothering.
Your answer
Follow this Question
Related Questions
How to double jump? i just can jump once when it touch the ground.. help me guys =D 1 Answer
How do I completely remove Unity Collaborate from a project? 0 Answers
Change script variable of object in hierarchy using c# 2 Answers
How do I make an external text document show only between certain lines in UI Text 1 Answer