Unity crashes when I destroy an object - c#

I've made this code myself so I'm not sure what I've done wrong, I have a colider for my sword but whenever I get in range and swing my whole unity crashes
using System;
using UnityEngine;
public class Attack : MonoBehaviour
{
private CircleCollider2D cc2;
private float x = 3;
private Boolean timer = true;
private Boolean hasAttacked = false;
private void Start()
{
cc2.isTrigger = true;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if(hasAttacked == false)
{
hasAttacked = true;
if (Input.GetKey(KeyCode.Mouse0))
{
while (timer == true)
{
x -= Time.deltaTime;
}
while (x >= 1)
if (collision.gameObject.name == "Enemy")
{
Destroy(GameObject.Find("Enemy"));
}
if (x == 0)
{
hasAttacked = false;
x = 3;
}
}
}
}
}
The Player is the parent of the sword if it makes a difference
It could be that they both try to destroy each other because the enemy is made to destroy the player

The problem is with the while (timer == true). If it's true, then it will stuck in there. Also when you decreasing x by Time.deltaTime, there is a little chance it will equals with 0, you should check with x <= 0.
Also you should check for input in Update.
I would save the reference of the enemy in OnCollisionEnter2D, and clear that in OnCollisionExit, and handle the attack in the Update. Something like that:
private GameObject _enemy;
private float _actCooldown = 3.0f;
private void Update()
{
if (Input.GetKeyDown(KeyKode.Mouse0) && _actCooldown <= 0.0f)
{
if (_enemy != null)
{
Destroy(_enemy);
_enemy = null;
}
_actCooldown = 3.0f;
}
_actCooldown -= Time.deltaTime;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.name.Equals("Enemy")) _enemy = collision.gameObject;
}
private void OnCollisionExit2D(Collision2D collision)
{
if (collision.gameObject == _enemy) _enemy = null;
}
Of course if there are more enemies, you'll have to add more logic to it.

Related

Optimize the game in unity

Optimization script doesn`t work. I made a script to optimize my game in unity, when the player is standing, everything is fine, But once it starts to go... Framerate Per Second starts to decrease to zero, tell me what should I do? After all, the player does not perform heavy operations, how can this load something? (I tried OnBecameVisible and OnBecameInvisible they don't work)
~Scripts~
using UnityEngine;
[RequireComponent(typeof(ObjectParameters))]
public class ObjectManager : MonoCache
{
public SpriteRenderer[] spriteRenderers;
[Space]
public ObjectParameters objectParameters;
[Space]
[SerializeField] bool freezeRotation;
bool isBuilded;
[Space]
public bool usingDragging = true;
[Space]
[SerializeField] bool usingRigidBody;
Rigidbody2D rb2D;
float gS;
[Space]
[SerializeField] bool usingSheetDrop;
SheetDrop sheetDrop;
void Start()
{
rb2D = GetComponent<Rigidbody2D>();
objectParameters = GetComponent<ObjectParameters>();
sheetDrop = GetComponent<SheetDrop>();
if (usingRigidBody == true)
{
rb2D.constraints = RigidbodyConstraints2D.FreezeAll;
gS = rb2D.gravityScale;
}
if (usingSheetDrop == true)
{
sheetDrop.enabled = false;
}
objectParameters.enabled = false;
for (int i = 0; i < spriteRenderers.Length; i++)
{
spriteRenderers[i].enabled = false;
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.tag == "PlayerDrawing")
{
if (usingRigidBody == true)
{
if (rb2D == null)
{
rb2D = GetComponent<Rigidbody2D>();
}
if (freezeRotation == false)
{
rb2D.constraints = RigidbodyConstraints2D.None;
}
}
if (usingSheetDrop == true)
{
sheetDrop.enabled = true;
}
objectParameters.enabled = true;
for (int i = 0; i < spriteRenderers.Length; i++)
{
spriteRenderers[i].enabled = true;
}
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.tag == "PlayerDrawing")
{
if (usingRigidBody == true)
{
if (rb2D == null)
{
rb2D = GetComponent<Rigidbody2D>();
}
if (rb2D.constraints != RigidbodyConstraints2D.FreezeAll || rb2D.bodyType != RigidbodyType2D.Kinematic)
{
rb2D.constraints = RigidbodyConstraints2D.FreezeAll;
}
}
}
if (usingSheetDrop == true)
{
sheetDrop.enabled = false;
}
objectParameters.enabled = false;
for (int i = 0; i < spriteRenderers.Length; i++)
{
spriteRenderers[i].enabled = false;
}
}
}
and ObjectParameters
using UnityEngine;
public class ObjectParameters : MonoCache
{
public Dragging dragging;
public Rigidbody2D rb;
public Vector3 position;
public Quaternion rotation;
ObjectManager objectManager;
Transform transform_;
void Start()
{
objectManager = GetComponent<ObjectManager>();
transform_ = transform;
rb = GetComponent<Rigidbody2D>();
}
public override void OnTick()
{
position = transform_.position;
rotation = transform_.rotation;
}
}
I wanted the script to work like this: When an object touches the Player Drawing, it turns on physic and SpriteRenderer, otherwise everything would happen in reverse. BUT IT DOESN'T WORK.
help please
Make sure you don't have any exceptions spamming into the console when you walk.
Also make sure to use the Profiler to see what method-calls are using the most of your framerate, you might have to turn on the deep profiler to see the exact methods.

OnPointerEnter and OnPointerExit not being triggered Unity

Alright so basically the issue that I've been having is that for some reason a GameObject is interfering with the OnPointerEnter function. I'm pretty sure that OnPointerEnter detects only UI. So that's why I'm extremely confused when seeing that a specific GameObject in this case the PlayerLogic GameObject (which you can see in the screenshot) is for some reason interfering with the detection of UI elements. The reason I believe it is this specific GameObject is because once I do PlayerLogic.SetActive(false); OnPointerEnter starts to work again, and I'm also sure that it isn't any of the children of PlayerLogic because I've tried turning them off specifically and it still didn't work.
Inspector of the PlayerLogic object
Hierarchy
The code I'm using to test OnPointerEnter
After some testing I've realized that its the specific issue lies within the Player script on the PlayerLogic GameObject. Now what confuses me is that once I turn off the Player component OnPointer doesn't work, but if I were to remove the Player component completely from the PlayerLogic GameObject OnPointerEnter works.
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System.Collections;
using System.Collections.Generic;
public class Player : MonoBehaviour, TakeDamage {
[SerializeField] private Animator playerAnimator;
[SerializeField] private Transform mainCameraTransform;
private bool isRunning = false;
[SerializeField] private CharacterController controller;
public float speed = 10f;
[SerializeField] private float jumpForce = 3f;
[SerializeField] private float gravity = -10000.81f;
Vector3 velocity;
Vector3 desiredMoveDirection;
private float dashSpeed = 30f;
private float mouseX;
private float mouseY;
[SerializeField]
private Transform Target;
[SerializeField]
private Transform player;
private float turnSmoothVelocity;
private float time = 0f;
public bool playerIsAttacking = false;
[SerializeField] private Slider playerHealth, playerMana;
[SerializeField] private TextMeshProUGUI healthText, manaText;
private Vector3 originalSpawnPos;
private bool playerIsDead = false;
[SerializeField] private LayerMask enemyLayerMask;
[SerializeField] private Transform playerLook;
private ShowHPBar obj;
private bool HPBarShown = false;
private bool unshowingHPBar = false;
public bool lookingAtEnemy = false;
public RaycastHit hit;
[SerializeField] private Canvas abilityCanvas;
[SerializeField] private Slider CD1;
[SerializeField] private Slider CD2;
[SerializeField] private Slider CD3;
public List<Ability> currentlyEquippedAbilites = new List<Ability>();
public List<string> abilityTexts = new List<string>();
public float[] abilityCooldowns = new float[3];
private float manaRegenTime;
//public List<Image> abilityImages = new List<Image>();
private void Awake() {
Cursor.visible = false;
Cursor.lockState = CursorLockMode.Locked;
}
private void Start() {
playerHealth.onValueChanged.AddListener(delegate {OnValueChangedHealth(); });
playerMana.onValueChanged.AddListener(delegate {OnValueChangedMana(); });
originalSpawnPos = transform.position;
}
private void Update() {
if (!playerIsDead) {
PlayerMovementAndRotation();
}
PlayerDash();
PlayerRun();
PlayerSeeEnemyHealth();
PlayerActivateAbility();
if (manaRegenTime > 0.5f) {
playerMana.value += playerMana.maxValue/100;
manaRegenTime = 0;
}
playerLook.rotation = mainCameraTransform.rotation;
time += Time.deltaTime;
manaRegenTime += Time.deltaTime;
#region Ability Cooldowns
if (currentlyEquippedAbilites.Count > 0) {
if (currentlyEquippedAbilites[0].cooldown <= abilityCooldowns[0])
{
currentlyEquippedAbilites[0].isOnCooldown = false;
abilityCooldowns[0] = 0;
CD1.value = 0;
}
else if (currentlyEquippedAbilites[0].isOnCooldown) {
abilityCooldowns[0] += Time.deltaTime;
CD1.value = currentlyEquippedAbilites[0].cooldown - abilityCooldowns[0];
}
}
if (currentlyEquippedAbilites.Count > 1) {
if (currentlyEquippedAbilites[1].cooldown <= abilityCooldowns[1])
{
currentlyEquippedAbilites[1].isOnCooldown = false;
abilityCooldowns[1] = 0;
CD2.value = 0;
}
else if (currentlyEquippedAbilites[1].isOnCooldown) {
abilityCooldowns[1] += Time.deltaTime;
CD2.value = currentlyEquippedAbilites[1].cooldown - abilityCooldowns[1];
}
}
if (currentlyEquippedAbilites.Count > 2) {
if (currentlyEquippedAbilites[2].cooldown <= abilityCooldowns[2])
{
currentlyEquippedAbilites[2].isOnCooldown = false;
abilityCooldowns[2] = 0;
CD3.value = 0;
}
else if (currentlyEquippedAbilites[2].isOnCooldown) {
abilityCooldowns[2] += Time.deltaTime;
CD3.value = currentlyEquippedAbilites[2].cooldown - abilityCooldowns[2];
}
}
#endregion
}
private void PlayerRun() {
if (Input.GetKey(KeybindsScript.RunKey) && (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0)) {
playerAnimator.SetInteger("isRunning", 1);
playerAnimator.SetInteger("isIdle", 0);
playerAnimator.SetInteger("isWalking", 0);
speed = 15f;
}
else if (Input.GetAxisRaw("Horizontal") != 0 || Input.GetAxisRaw("Vertical") != 0) {
playerAnimator.SetInteger("isWalking", 1);
playerAnimator.SetInteger("isIdle", 0);
playerAnimator.SetInteger("isRunning", 0);
speed = 10f;
}
else {
playerAnimator.SetInteger("isRunning", 0);
playerAnimator.SetInteger("isWalking", 0);
playerAnimator.SetInteger("isIdle", 1);
speed = 10f;
}
}
private void PlayerMovementAndRotation() {
bool isGrounded = controller.isGrounded;
if (isGrounded && velocity.y < 0) {
velocity.y = -2f;
}
float horizontal = Input.GetAxisRaw("Horizontal");
float vertical = Input.GetAxisRaw("Vertical");
Vector3 moveDir = (transform.right*horizontal+transform.forward*vertical).normalized;
controller.Move(moveDir*Time.deltaTime*speed);
transform.eulerAngles = new Vector3(0f, mainCameraTransform.eulerAngles.y, 0f);
if (Input.GetKeyDown(KeybindsScript.JumpKey) && isGrounded) {
velocity.y = Mathf.Sqrt(jumpForce * -2f * gravity);
}
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
private void PlayerDash() {
if (Input.GetKeyDown(KeybindsScript.DashKeybind) && isRunning == false) {
if (Input.GetKey(KeybindsScript.MovementKeyBackward)) {
StartCoroutine(PlayerDashTiming(2));
}
else if (Input.GetKey(KeybindsScript.MovementKeyRight)) {
StartCoroutine(PlayerDashTiming(3));
}
else if (Input.GetKey(KeybindsScript.MovementKeyLeft)) {
StartCoroutine(PlayerDashTiming(4));
}
else {
StartCoroutine(PlayerDashTiming(1));
}
}
}
private void PlayerSeeEnemyHealth() {
if (Physics.Raycast(playerLook.position, playerLook.forward, out hit, 1000f, enemyLayerMask)) {
obj = hit.transform.gameObject.GetComponent<ShowHPBar>();
if (obj != null && !HPBarShown && !unshowingHPBar) {obj.ShowHPBarFunction(); HPBarShown = true;}
lookingAtEnemy = true;
}
else {
if (obj != null && HPBarShown) {StartCoroutine(UnShowHPBar(obj)); HPBarShown = false;}
}
}
public void PlayerEquipAbility(Ability ability, int place) {
if (currentlyEquippedAbilites.Count < place) {currentlyEquippedAbilites.Add(ability);}
else {currentlyEquippedAbilites[place-1] = ability;}
//if (abilityImages.Count < place) {abilityImages.Add(ability.icon);}
//else {abilityImages.Add(ability.icon);}
if (abilityTexts.Count < place) {abilityTexts.Add(ability.name);}
else {abilityTexts[place-1] = ability.name;}
for (int i=0;i < abilityTexts.Count;++i) {
abilityCanvas.transform.GetChild(i).GetChild(0).GetComponent<TextMeshProUGUI>().text = abilityTexts[i];
abilityCanvas.transform.GetChild(i).GetChild(1).GetComponent<Slider>().maxValue = ability.cooldown;
}
}
private void PlayerActivateAbility() {
if (Input.GetKeyDown(KeyCode.Alpha1)) {
if (currentlyEquippedAbilites[0] != null) {
if (currentlyEquippedAbilites[0].manaCost <= playerMana.value && !currentlyEquippedAbilites[0].isOnCooldown) {
ParticleEffect pe = currentlyEquippedAbilites[0].script.gameObject.GetComponent<ParticleEffect>();
playerMana.value -= currentlyEquippedAbilites[0].manaCost;
currentlyEquippedAbilites[0].isOnCooldown = true;
if (pe != null) {pe.PlayAnimation();}
}
}
}
}
public void OnValueChangedHealth() {
healthText.text = playerHealth.value + "/" + PlayerStats.HealthPoints;
}
public void OnValueChangedMana() {
manaText.text = playerMana.value + "/" + PlayerStats.ManaAmount;
}
public void TakeDamageFunction(float damage) {
playerHealth.value -= damage;
if (playerHealth.value <= 0) {
StartCoroutine(PlayerDeath());
}
}
IEnumerator PlayerDashTiming(int x) {
isRunning = true;
float time = 0f;
Vector3 savedVector = Vector3.zero;
switch (x) {
case 1:
savedVector = transform.forward;
break;
case 2:
savedVector = -transform.forward;
break;
case 3:
savedVector = transform.right;
break;
case 4:
savedVector = -transform.right;
break;
}
while(time < .3f)
{
time += Time.deltaTime;
controller.Move(savedVector * dashSpeed * Time.deltaTime);
yield return null;
}
yield return new WaitForSeconds(1.5f);
isRunning = false;
}
IEnumerator PlayerDeath() {
//Respawn
playerIsDead = true;
playerAnimator.enabled = false;
yield return new WaitForSeconds(1f);
playerHealth.value = 100;
transform.position = originalSpawnPos;
yield return new WaitForSeconds(0.1f);
playerIsDead = false;
playerAnimator.enabled = true;
}
IEnumerator UnShowHPBar(ShowHPBar obj) {
unshowingHPBar = true;
yield return new WaitForSeconds(1.5f);
obj.ShowHPBarFunction();
unshowingHPBar = false;
}
}
This is the Player.cs script.
I'm pretty sure that OnPointerEnter detects only UI.
No.
It works "out of the box" on UI because by default every Canvas contains a GraphicsRaycaster component which is then used and handled by the EventSystem.
For non-UI 3D objects you have to make sure
your objects have 3D Colliders
the Colliders are on the same object as the IPointerXY interfaces
on your Camera there is a PhysicsRayster component
For non-UI 2D objects quite similar
your objects have a 2D Collider
the colliders are on the same object as the IPointerXY interfaces
the Camera has a Physics2DRaycaster component
Note that it is possible that any other collider or in general raycast blocking object is between your input and the target object which would also prevent the OnPointerXY to be triggered on your objects.
The CharacterController
is simply a capsule shaped Collider
which can be told to move in some direction from a script.
which is probably blocking the input.
Now with your Player code:
You do
Cursor.lockState = CursorLockMode.Locked;
in Awake so even if you turn it off afterwards this already took effect.

Game Freezes When Ever Lives Get Removed In Unity [duplicate]

This question already has answers here:
How to make the script wait/sleep in a simple way in unity
(7 answers)
Closed 1 year ago.
Whenever lives get removed by an enemy in my game in unity, the game temporarily freezes. I think it has to do with the line "Thread.Sleep(3000);" but I am not sure of an alternative wait that will not freeze the entire game temporarily.
I would greatly appreciate if you could help me!
Thanks.
using System.Collections;
using System.Collections.Generic;
using System;
using System.Threading;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public Transform attackPoint;
public float attackrange = 0.5f;
public LayerMask playerlayers;
public float speed = 3f;
private Transform target;
bool hitID = false;
private void Update()
{
if (target != null)
{
float step = speed * Time.deltaTime;
transform.position = Vector2.MoveTowards(transform.position, target.position, step);
Collider2D[] hitplayers = Physics2D.OverlapCircleAll(attackPoint.position, attackrange, playerlayers);
foreach (Collider2D player in hitplayers)
{
if (hitID == false)
{
hitID = true;
player.GetComponent<HeartSystem>().TakeDamage(1);
Thread.Sleep(3000);
hitID = false;
}
}
}
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
target = other.transform;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.tag == "Player")
{
target = null;
}
}
void OnDrawGizmosSelected()
{
if (attackPoint == null)
return;
Gizmos.DrawWireSphere(attackPoint.position, attackrange);
}
}
Enemy.cs
using System.Collections;
using UnityEngine;
public class Enemy : MonoBehaviour
{
public Transform attackPoint;
public float attackrange = 0.5f;
public LayerMask playerlayers;
public float speed = 3f;
private Transform _target;
private bool _hitID;
private void Update()
{
if (_target != null)
{
var step = speed * Time.deltaTime;
transform.position = Vector2.MoveTowards(transform.position, _target.position, step);
var hitPlayers = new Collider2D[10];
Physics2D.OverlapCircleNonAlloc(attackPoint.position, attackrange, hitPlayers, playerlayers);
foreach (var player in hitPlayers)
{
if (_hitID == false)
{
StartCoroutine(HitCoroutine(player));
}
}
}
}
private IEnumerator HitCoroutine(Collider2D player)
{
_hitID = true;
player.GetComponent<HeartSystem>().TakeDamage(1);
yield return new WaitForSeconds(3);
_hitID = false;
}
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
_target = other.transform;
}
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.CompareTag("Player"))
{
_target = null;
}
}
private void OnDrawGizmosSelected()
{
if (attackPoint == null)
return;
Gizmos.DrawWireSphere(attackPoint.position, attackrange);
}
}
Try this.
In a case like this you want to use a coroutine.
You can read about coroutines here:
https://docs.unity3d.com/Manual/Coroutines.html
Unity is single threaded, so you are actually suspending the entire thread the game is running on. Since the frames are updated on this thread, you're even freezing the visual frame updates.
You have a few ways to manage "waiting" in game.
Coroutines:
A process that can be suspended until a later condition is met (including time)
void Update()
{
//Your other code goes here
if (hitID == false)
{
hitID = true;
player.GetComponent<HeartSystem>().TakeDamage(1);
StartCoroutine(ResetHitIDAfterSeconds(3))
}
}
IEnumerator ResetHitIDAfterSeconds(float seconds)
{
yield return new WaitForSeconds(seconds);
hitID = false;
}
The above code allows you to have the same logic, and will kick off a coroutine that waits for 3 seconds before setting hitID back to false.
Time.deltaTime:
You can also track the elapsed time in your Update method and manage your variables actively based on the elapsed time. Time.deltaTime returns the amount of time that elapsed since the previous frame.
public class ConstantRotation : MonoBehaviour
{
public float timeElapsed = 0f;
void Update()
{
//Your other code goes here
if (hitID == false)
{
hitID = true;
player.GetComponent<HeartSystem>().TakeDamage(1);
timeElapsed = 0f;
}
else
{
timeElapsed += Time.deltaTime
if(timeElapsed >= 3.0f)
{
hitId = false;
}
}
}
}
You would likely want to modify the above code a bit to avoid having the logic run on every frame, and only run it on hit.

How to check for collision in an if statement in Unity 2D

I have a script that counts down from 20 to 0, then when it reaches 0 a boolean is set to true. What I want that boolean to do is write something on the console when the player is collided with the sprite the script is on, but I only want this to happen if it's true. Here's the code:
public float timeLeft = 10f;
public bool canHarvest;
public void Start()
{
canHarvest = false;
}
public void Update()
{
timeLeft -= Time.deltaTime;
if (timeLeft < 0)
{
Debug.Log("IM READY TO HARVEST");
canHarvest = true;
}
if (canHarvest = true)
{
public void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.tag == "Player")
{
Debug.Log("true");
}
}
}
}
}
What I want this code to do is set canHarvest to false at the start (meaning that if the player collides with the object the script is on nothing will happen), and once timeLeft reaches 0 it should set canHarvest to true, meaning that if the player collides with the object the script is on, the object the script is on will disappear. This is not working as I can't have the if statement checking if the player collides inside the if statement checking if canHarvest is true. Please help!
You should move the OnTriggerEnter2D definition outside the Update() method and conditional check should be inside the function:
public float timeLeft = 10f;
public bool canHarvest;
public void Start()
{
canHarvest = false;
}
public void Update()
{
timeLeft -= Time.deltaTime;
if (timeLeft < 0)
{
Debug.Log("IM READY TO HARVEST");
canHarvest = true;
}
}
public void OnTriggerEnter2D(Collider2D col)
{
if (canHarvest && col.gameObject.tag == "Player")
{
Debug.Log("true");
}
}

I'm creating a patrolling AI that aggros to the player and follows them in Unity 3D

I'm having trouble keeping this method running. It runs for 1 frame them shuts itself off. I am having trouble working out the logic to keep it running. Yes, the enemy does detect if the player is within a field of view, and it does stop when it collides with walls, it also stops detecting the player when they leave the fov.
I've tried changing around if statements, but it's overall very important that the code runs based on the player existing in the FOV collider. The problem is pretty specific, so I don't know what research to do.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
[RequireComponent(typeof(Animator))]
[RequireComponent(typeof(NavMeshAgent))]
[RequireComponent(typeof(AudioSource))]
public class EnemyAI : MonoBehaviour
{
public float patrolSpeed, chaseSpeed, chaseWaitTime, patrolWaitTime, castRadius;
public Transform[] wayPoints, wayPOI;
public Transform player;
public Animation flinch, die;
public AudioClip grunt, callOut, death;
public LayerMask mask;
public PlayerCheck check;
private float chaseTimer, patrolTimer, wanderTimer;
private int destIndex, destInit, destStart, health;
private bool playerIn;
protected string aggro, resting, warned, sawPlayer;
protected bool patroling;
public bool aggress;
private NavMeshAgent agent;
private Transform playerLP;
private Vector3 startPos;
private Animator anim;
private AudioSource aud;
MeshCollider fieldOfView;
void Awake()
{
//patroling = true;
startPos = transform.position;
destInit = destIndex;
agent = GetComponent<NavMeshAgent>();
agent.autoRepath = true;
agent.autoBraking = true;
fieldOfView = transform.GetChild(0).GetComponent<MeshCollider>();
if (fieldOfView == null)
{
Debug.LogError("The first object MUST be FOV, otherwise the script will not work correctly. 1");
}
check = GameObject.FindObjectOfType<PlayerCheck>();
anim = GetComponent<Animator>();
}
void FixedUpdate()
{
if (check == null)
{
check = GameObject.FindObjectOfType<PlayerCheck>();
}
playerIn = check.playerIn;
RaycastHit hit;
if (Physics.Linecast(transform.position, player.position, out hit, ~mask))
{
if (!playerIn)
{
Debug.DrawLine(transform.position, hit.point, Color.red);
}
else if (hit.collider.gameObject != null)
{
if (!hit.collider.CompareTag("Player"))
{
Debug.DrawLine(transform.position, hit.point, Color.blue);
return;
}
else
{
Debug.DrawLine(transform.position, hit.point, Color.green);
aggress = true;
}
}
}
if (aggress)
{
Aggro(sawPlayer);
}
if (patroling)
{
GoToNext();
}
}
void GoToNext()
{
patroling = true;
aggress = false;
if (wayPoints.Length == 0)
return;
if (playerIn)
return;
if (agent.remainingDistance < .7f)
{
agent.SetDestination(wayPoints[destIndex].position);
destIndex = (destIndex + 1) % wayPoints.Length;
}
}
void Aggro(string condition)
{
if (condition == sawPlayer)
{
Chase(player);
}
}
void Chase(Transform transform)
{
patroling = false;
if (playerIn)
{
agent.SetDestination(transform.position);
print("Chasing");
}
else
{
**Wander(sawPlayer, 15);**
print("Wander, please");
}
}
**void Wander(string condition, float time)**
{
patroling = false;
print(time);
wanderTimer += Time.deltaTime;
print("Wandering");
//this is where I'm having the most trouble, it will print wandering for 1 //frame then stop and go back to patroling
//once the player leaves the fov. I'm trying to figure out where the method //stops and why.
if (condition == sawPlayer)
{
if (wanderTimer >= time)
{
wanderTimer = 0;
if (!agent.pathPending && agent.remainingDistance < .5f)
{
GoToNext();
}
}
else
{
Vector3 vec;
vec = new Vector3(Random.Range(agent.destination.x - 10, agent.destination.x), Random.Range(agent.destination.y - 10, agent.destination.y), Random.Range(agent.destination.z - 10, agent.destination.z));
agent.destination = transform.InverseTransformDirection(vec);
if (agent.remainingDistance < .3f || wanderTimer > time)
{
GoToNext();
}
}
}
}
}

Categories