So I’m making LockOn to Enemy like eldenring,
I’m using
[SerializeField] List targetEnemy = new List();
to store while using new InputSystem. (rightClick)
the problem is IT’S WORKING But not always
when i click the rightmousebtn too quick
InvalidOperationException, ObjectDisposedException Error Occurs like last picture
Or when i got out of my lockOnRadius too fast the Error Occurs
but when i go back in and click the right mouse btn 3times over it works, but i want to handle with no bugs,
I spend my whole day trying out what was the problem and trying to catch the exception,
but i didn’t make it,
please help me with my code,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine;
using Unity.VisualScripting;
public class LockOn : MonoBehaviour
{
[SerializeField] float lockOnRadius = 12;
[SerializeField] LayerMask targetLayer;
[SerializeField] float minViewAngle = 0f;
[SerializeField] float maxViewAngle = 360f;
[SerializeField] List<EnemyAttributesManager> targetEnemy = new List<EnemyAttributesManager>();
[SerializeField] Transform lockOnImage;
[SerializeField] CinemachineFreeLook playerCam;
[SerializeField] CinemachineFreeLook enemyCam;
EnemyAttributesManager currentTarget;
Vector3 currentTargetPosition;
public bool isFindTarget = false;
private Transform cameraTransform;
// Start is called before the first frame update
void Awake()
{
cameraTransform = Camera.main.transform;
}
private void Start()
{
lockOnImage.gameObject.SetActive(false);
enemyCam.Priority = 0;
}
private void Update()
{
if (isFindTarget && isTargetRange())
{
if (currentTarget != null && targetEnemy.Count > 0)
{
LookAtTarget();
}
else
{
ResetTarget();
}
}else if (!isTargetRange())
{
ResetTarget();
}
}
private void OnDrawGizmos()
{
Gizmos.DrawWireSphere(transform.position, lockOnRadius);
}
public void FindLockOnTarget()
{
Collider[] findTarget = Physics.OverlapSphere(transform.position, lockOnRadius, targetLayer);
for (int i = 0; i < findTarget.Length; i++)
{
EnemyAttributesManager target = findTarget[i].GetComponent<EnemyAttributesManager>();
if (target != null)
{
Vector3 targetDir = target.transform.position - transform.position;
float viewAngle = Vector3.Angle(targetDir, cameraTransform.forward);
if (viewAngle > minViewAngle && viewAngle < maxViewAngle)
{
RaycastHit hit;
if(Physics.Linecast(transform.position,
target.transform.position,out hit, targetLayer))
{
targetEnemy.Add(target);
}
}
else
{
ResetTarget();
}
}
}
if (targetEnemy.Count > 0 && isTargetRange())
{
LockOnTarget();
}
else
{
ResetTarget();
}
}
private void LockOnTarget()
{
if(targetEnemy == null || targetEnemy.Count == 0)
{
ResetTarget();
return;
}
float shortDistance = Mathf.Infinity;
for (int i = 0; i < targetEnemy.Count; i++)
{
float distanceFromTarget = Vector3.Distance(transform.position, targetEnemy[i].transform.position);
if(distanceFromTarget < shortDistance)
{
shortDistance = distanceFromTarget;
currentTarget = targetEnemy[i];
}
}
if(currentTarget != null)
{
enemyCam.Priority = 11;
enemyCam.m_LookAt = targetEnemy[0].transform;
FindTarget();
}
}
private void LookAtTarget()
{
if(currentTarget == null)
{
ResetTarget();
return;
}
if (!isTargetRange())
{
isFindTarget = false;
ResetTarget();
return;
}
currentTargetPosition = currentTarget.transform.position;
lockOnImage.position = Camera.main.WorldToScreenPoint(currentTargetPosition + new Vector3(0, 1f, 0)); ;
Vector3 dir = (currentTargetPosition - transform.position).normalized;
dir.y = transform.position.y;
transform.forward = Vector3.Lerp(transform.forward, dir, Time.deltaTime * 20f);
}
private void FindTarget()
{
isFindTarget = true;
lockOnImage.gameObject.SetActive(true);
}
private bool isTargetRange()
{
float distance = (transform.position - currentTargetPosition).magnitude;
if(distance > lockOnRadius)
{
ResetTarget();
return false;
}
else
{
return true;
}
}
public void ResetTarget()
{
targetEnemy.Clear();
isFindTarget = false;
currentTarget = null;
lockOnImage.gameObject.SetActive(false);
enemyCam.Priority = 0;
}
}
and this is what i use in new input system in my characterController
public void LockOn(InputAction.CallbackContext context)
{
if (context.performed)
{
_lockOn = !_lockOn;
if (_lockOn)
{
lockOn.ResetTarget();
lockOn.FindLockOnTarget();
}
else
{
lockOn.ResetTarget();
}
}
}