- Home /
[BUG?] Game freezes or I get error. C#
Hello, all!
Could you guys help me?
I'am scripting a IA (FSM) for my enemy: A simple follow and idle FSM.
Here's the code:
using UnityEngine;
using System.Collections;
public class enemy_IA : MonoBehaviour {
// Use this for initialization
public GameObject particleHit;
public GameObject particleDead;
public float life = 10.0f;
private GameObject player;
public float minDist = 3.0f;
public enum States
{
Idle,
FollowChar
}
private States state;
void Start () {
state=States.Idle;
StartCoroutine(UpdateFSM());
//player = GameObject.FindWithTag("Player");
}
// Update is called once per frame
void Update () {
player = GameObject.FindWithTag("Player");
}
void Idle(){
Debug.Log("to parado");
}
void FollowChar(){
Debug.Log("to te seguindo");
}
void ApplyHit(){
}
void ApplyDamage(float dano){
life=life-dano;
GameObject particula1;
particula1 = Instantiate(particleHit, transform.position , transform.rotation) as GameObject;
if(life <= 0.0f){
life=0.0f;
Morto();
}
}
void Morto(){
GameObject particula2;
particula2 = Instantiate(particleDead, transform.position , transform.rotation) as GameObject;
Destroy(gameObject);
}
IEnumerator UpdateFSM(){
while(true){
if(state==States.Idle){
if(jogador_perto())
state=States.FollowChar;
else Idle();
}else if(state==States.FollowChar){
if(jogador_longe())
state=States.Idle;
else FollowChar();
}
}
yield return new WaitForSeconds(0.1f);
}
bool jogador_perto(){
Vector3 distancia = gameObject.transform.position - player.gameObject.transform.position;
if(distancia.magnitude <= minDist)return true;
else return false;
}
bool jogador_longe(){
Vector3 distancia = transform.position - player.transform.position;
if(distancia.magnitude >= minDist*2.0f)return true;
else return false;
}
}
If I press PLAY, I'll get this error:
NullReferenceException enemy_IA.jogador_perto () (at Assets/Standard Assets/Scripts/With_Love_Scripts/enemy_IA.cs:78) enemy_IA+c__Iterator0.MoveNext () (at Assets/Standard Assets/Scripts/With_Love_Scripts/enemy_IA.cs:66) UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator) enemy_IA:Start() (at Assets/Standard Assets/Scripts/With_Love_Scripts/enemy_IA.cs:23)
If I change the GameObject player to PUBLIC, and set it thru code or manually, the game freezes.
What do I do? What I'm doing worng?
Problem solved! I had to do BOTH things you guys said, AND set the GameObject player as Public. I voted tanoshimi as correct answer because he answered first.
Answer by tanoshimi · Nov 23, 2013 at 12:32 AM
player = GameObject.FindWithTag("Player") should not be called in Update (). Instead, set it once in Start () (which you have, but commented out), which will ensure the reference is assigned before the UpdateFSM coroutine runs.
I tried what you said, but it didn't fix the problem.
Still got the same error:
NullReferenceException enemy_IA.jogador_perto () (at Assets/Standard Assets/Scripts/With_Love_Scripts/enemy_IA.cs:78) enemy_IA+c__Iterator0.$$anonymous$$oveNext () (at Assets/Standard Assets/Scripts/With_Love_Scripts/enemy_IA.cs:66) UnityEngine.$$anonymous$$onoBehaviour:StartCoroutine(IEnumerator) enemy_IA:Start() (at Assets/Standard Assets/Scripts/With_Love_Scripts/enemy_IA.cs:23)
I even commented the whole if(jogador_perto()) and the game froze.
Answer by clunk47 · Nov 23, 2013 at 03:12 AM
Check if object tagged as "Player" exists before you define your variable using the tag.
Check if "player" is null before using any of its properties in the code: if(player != null).
You had your yield in the wrong place in a couroutine causing Unity to hang. Try this.
using UnityEngine; using System.Collections;
public class enemy_IA : MonoBehaviour { public GameObject particleHit; public GameObject particleDead; public float life = 10.0f; private GameObject player; public float minDist = 3.0f; Vector3 distancia;
enum States { Idle, FollowChar } States state; void Start () { state=States.Idle; StartCoroutine(UpdateFSM()); if(GameObject.FindWithTag ("Player")) player = GameObject.FindWithTag("Player"); else print ("GameObject tagged Player not found!"); } void Idle() { Debug.Log("to parado"); } void FollowChar() { Debug.Log("to te seguindo"); } void ApplyHit() { } void ApplyDamage(float dano) { life=life-dano; GameObject particula1; particula1 = Instantiate(particleHit, transform.position , transform.rotation) as GameObject; if(life <= 0.0f) { life=0.0f; Morto(); } } void Morto() { GameObject particula2 = (GameObject)Instantiate(particleDead, transform.position, transform.rotation); Destroy(gameObject); } IEnumerator UpdateFSM() { while(true) { if(state==States.Idle) { if(jogador_perto()) state=States.FollowChar; else Idle(); } else if(state==States.FollowChar) { if(jogador_longe()) state=States.Idle; else FollowChar(); } yield return new WaitForSeconds(0.1f); } } bool jogador_perto() { if(player != null) distancia = gameObject.transform.position - player.gameObject.transform.position; else print ("Player is NULL!"); if(distancia.magnitude <= minDist)return true; else return false; } bool jogador_longe() { if(player != null) distancia = transform.position - player.transform.position; else print ("Player is NULL!"); if(distancia.magnitude >= minDist*2.0f)return true; else return false; } }
Answer by jovino · Nov 23, 2013 at 12:41 AM
You can try also to add yield return null; like this:
IEnumerator UpdateFSM(){
while(true){
if(state==States.Idle){
if(jogador_perto())
state=States.FollowChar;
else Idle();
}else if(state==States.FollowChar){
if(jogador_longe())
state=States.Idle;
else FollowChar();
}
yield return null; //Add this
}
yield return new WaitForSeconds(0.1f);
}
This is going to fix the freeze, not the exception, which is fixed like tanoshimi said.
Your answer
Follow this Question
Related Questions
Enemy follows the only player in rotation 2 Answers
Enemy reorienting for player 1 Answer
teleportation problems (2d) 1 Answer
Enemy AI Help,Help on EnemyAI 2D 0 Answers
Unity Enemy Range detection 3 Answers