Hi guys i am really new at programming something. I am trying to make a boss ai system for my project but when i try to run my project its freezing because of instantiate loop. I can’t solve this problem could you help me.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BasicBossAI : MonoBehaviour
{
public enum BossMoves
{
Idle,
Move,
Jumpattack,
DashAttack,
LaserAttack
}
public BossMoves currentState = BossMoves.Idle;
public float distance = 10.0f;
public GameObject Player;
public GameObject Boss;
public GameObject MovePosition;
public float BossMoveSpeed = 10.0f;
private Transform target;
public int ObjCounter;
void Start()
{
}
void Update()
{
start:
if (Vector2.Distance(Player.transform.position, Boss.transform.position) > distance)
{
currentState = BossMoves.Move;
}
else
{
currentState = BossMoves.Idle;
}
if (currentState == BossMoves.Idle)
{
BossWaiting();
goto start;
}
if (currentState == BossMoves.Move)
{
Transform Playerpos = GameObject.FindGameObjectWithTag("Player").GetComponent<Transform>();
ObjCounter = GameObject.FindGameObjectsWithTag("Movepos").Length;
if (ObjCounter < 1)
{
Instantiate(MovePosition, Playerpos.position, Playerpos.rotation);
}
target = MovePosition.GetComponent<Transform>();
Boss.transform.position = Vector2.MoveTowards(transform.position, target.position, BossMoveSpeed * Time.deltaTime);
if (Vector2.Distance(MovePosition.transform.position, Boss.transform.position) > 3.0f)
{
transform.position = Vector2.MoveTowards(transform.position, target.position, BossMoveSpeed * Time.deltaTime);
}
else
{
Destroy(MovePosition);
currentState = BossMoves.Idle;
goto start;
}
}
}
IEnumerator BossWaiting()
{
//Boss waiting for another move
yield return new WaitForSeconds(3);
}
}
You probably don’t need your “goto” statements. The Update() function fires for every frame of your game, so it will naturally start over regularly. Just let you code naturally flow to the end. This will help you avoid accidental closed loops.
Try to avoid any “find” operations within your Update() function, as these are relatively slow. For example. avoid Transform Playerpos = GameObject.FindGameObjectWithTag(“Player”) and instead either define “Player” as a public gameobject and drag your player GameObject into it in the editor, or if you need to use find, do it in the Start() function where it is only done once.
Similar for your “ObjCounter = GameObject.FindGameObjectsWithTag(“Movepos”).Length;”. Instead, perhaps just define “objCounter” as a INT variable at the beginning, then increment it each time you instantiate an object and decrease it each time you destroy an object:
What do you need to achieve with Instantiate? At the moment, your code allows for multiple “MovePosition” game objects. Is that what you need to do?
DC
I’m not 100% clear why you are using Instantiate. Is it just to store the player’s position at the point the “missile” is launched at them, so the “missile” moves towards that stored position, rather than the player’s current position?
OK - then the instantiate is a long-way round to do that.
You can simply define a Vector3 Variable such as “lastPosition” and then when the missile is launched, store the player’s position at that moment with;
lastPosition=Player.transform.position;
You would then move your missile towards that position with;