Hello everyone,
While I faced this error countless times before in Unity editor and solving this error is quite easy. But this time I am getting this error inside Windows Standalone build, while this error is not happening in the Editor at all. And it’s really tough to understand exactly in which line this error is happening. How to debug Windows Standalone build?
Error:
Exception
NullReferenceException: Object reference not set to an instance of an object
ShipController.FindClosestEnemy () (at <c9e0c0710bef452d9c11c840866edbd3>:0)
ShipController+<DistanceFromTargetCarrier>d__80.MoveNext () (at <c9e0c0710bef452d9c11c840866edbd3>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <2031488213494187ad8fdf6a91d614ad>:0)
My full script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ShipController : MonoBehaviour
{
public bool isPlayerCarrier;
public bool isEnemyCarrier;
public bool isPlayerFighter;
public bool isEnemyFighter;
public bool isStation;
public bool isEnemyFreighter;
[HideInInspector] public enum Mode
{
Attack,
Idle
}
[HideInInspector] public Mode mode;
[HideInInspector] public float defaultSpeed;
public float minSpeed = 2;
public float maxSpeed = 4;
public float rotateSpeed;
[HideInInspector] public Vector3 target;
[HideInInspector] public Transform targetWaypoint;
[HideInInspector] public Quaternion carrierTargetRotation;
public int hull;
public int shield;
public int energy;
public float speed = 1.5f; // For Carrier Ships Set From Inspector
public int weaponSlots;
public int utilitySlots;
public int maxFighterShips;
[HideInInspector] public PageManager pageManager;
[HideInInspector] public GameObject gameOverPage;
[HideInInspector] public Transform closestEnemy;
[HideInInspector] public float distanceFromEnemy;
[HideInInspector] public float distanceFromWaypoint; // Only for Player Carriers
[HideInInspector] public ShipStats shipStats;
//For Carrier Ships
[HideInInspector] public Waypoints waypoints;
[HideInInspector] public Transform waypoint; // Waypoint marker
private Camera cam;
public int shipNumber = 0;
[HideInInspector] public TargetMover targetMover;
[HideInInspector] public Vector3 camTransformInStart;
[HideInInspector] public float camOrthoSizeInStart;
[HideInInspector] public Vector3 AILerpTransInStart;
[HideInInspector] public bool isPlayer = false;
[HideInInspector] public bool isFaction1 = false; // Filling in awake
[HideInInspector] public bool isFaction2 = false;
[HideInInspector] public bool isPirate = false;
[HideInInspector] public Reputation reputation;
// For Fighter Ships
private Vector3 zAxis;
private bool isChasing = true;
[HideInInspector] public FighterSpawner fighterSpawner; // Used by fighter ships. Dont fill from the Inspector
private int startOrbitingDistance;
private int z;
public float totalValue;
private string shipTag;
[HideInInspector] public string sortingLayer;
[HideInInspector] public int orderInLayer;
[HideInInspector] public bool preparingHyperJump = false;
[HideInInspector] public SpriteRenderer spriteRenderer;
[HideInInspector] public PirateHunt pirateHunt;
[HideInInspector] public DefenceMission defenceMission;
//[HideInInspector] public InterceptFreighter interceptFreighter;
//[HideInInspector] public DestroyAllPirates destroyAllPirates;
[HideInInspector] public MainScript2 mainScript2;
//public GameObject selectedImage;
private int rotateTowardOffset;
public Transform preferredEnemy;
[HideInInspector] public ShipSpawner shipSpawner; // Setting this while spawning from ShipSpawner
//[HideInInspector] public PlayerOptions playerOptions;
[HideInInspector] public Material nonSelectedMaterial;
public Material selectedOutlineMaterial;
//public Material playerOutline;
public Material enemyOutline;
public Material neutralOutline;
public Material allyOutline;
[HideInInspector] public bool isSelected;
[HideInInspector] public bool isAttackOn = true;
[HideInInspector] public bool isDefenceOn = true;
[HideInInspector] public bool isThrusterOn;
[HideInInspector] public bool isTargetingStation;
//public bool canAttackStation;
void Awake()
{
mode = Mode.Attack;
mainScript2 = GetComponent<MainScript2>();
shipStats = GetComponentInChildren<ShipStats>();
cam = Camera.main;
shipSpawner = GameObject.FindObjectOfType<ShipSpawner>();
Debug.Log("ShipSpawner: "+shipSpawner);
if(tag == "Player") //|| tag == "Faction1Station"
{
isPlayer = true;
}
else if(tag == "Faction1") //|| tag == "Faction1Station"
{
isFaction1 = true;
}
else if(tag == "Faction2") // || tag == "Faction2Station"
{
isFaction2 = true;
}
else if(tag == "Pirate")
{
isPirate = true;
}
spriteRenderer = GetComponent<SpriteRenderer>();
sortingLayer = spriteRenderer.sortingLayerName;
shipTag = tag;
if(isPlayerCarrier || isEnemyCarrier || isEnemyFreighter || isStation)
{
pageManager = GameObject.FindObjectOfType<PageManager>();
reputation = GameObject.FindObjectOfType<Reputation>();
}
Debug.Log("Page Manager: "+pageManager);
Debug.Log("Reputation: "+reputation);
nonSelectedMaterial = spriteRenderer.material;
if(isPlayerCarrier)
{
isSelected = true;
spriteRenderer.material = selectedOutlineMaterial;
waypoints = GameObject.FindObjectOfType<Waypoints>();
Debug.Log("Waypoint: "+waypoints);
waypoint = waypoints.transform;
defaultSpeed = speed;
if(!GameResources.isFirstScene && SceneManager.GetActiveScene().name != "Tutorial")
{
StartCoroutine(mainScript2.ExitHyperJump());
}
}
}
//[HideInInspector] public Reputation reputation;
private Vector3 freighterFirstWP; // Waypoint
private StationSpawner stationSpawner;
void Start()
{
if(!isStation)
{
if(isPlayerCarrier)
{
StartCoroutine(SendShipValue());
targetMover = pageManager.targetMover;
gameOverPage = pageManager.gameOverPage;
camTransformInStart = cam.transform.position;
camOrthoSizeInStart = cam.orthographicSize;
AILerpTransInStart = pageManager.aILerp.transform.position;
}
if(isEnemyFreighter)
{
defaultSpeed = speed;
targetMover = pageManager.targetMover;
//shipSpawner = pageManager.shipSpawner;
mode = Mode.Idle;
stationSpawner = shipSpawner.GetComponent<StationSpawner>();
int randomX = Random.Range(-10, 10);
int randomY = Random.Range(-10, 10);
freighterFirstWP = new Vector3(stationSpawner.station.transform.position.x+randomX,
stationSpawner.station.transform.position.y+randomY);
StartCoroutine(FreighterWaypoint());
}
// For Enemy Carrier
else if(isEnemyCarrier)
{
targetMover = pageManager.targetMover;
target = transform.position;
}
// For Fighter Ships
else if(isPlayerFighter || isEnemyFighter)
{
target = transform.position;
}
}
if(!isPlayerFighter && !isEnemyFreighter && !isPirate)
{
StartCoroutine(ChangeOutlineColor());
}
}
IEnumerator ChangeOutlineColor()
{
if(EnemyAllyList.playerEnemiesTmp.Contains(tag) || EnemyAllyList.playerEnemies.Contains(tag))
{
selectedOutlineMaterial = enemyOutline;
}
else if(EnemyAllyList.playerAllies.Contains(tag))
{
selectedOutlineMaterial = allyOutline;
}
else if(EnemyAllyList.playerNeutrals.Contains(tag))
{
selectedOutlineMaterial = neutralOutline;
}
while(true)
{
yield return new WaitForSeconds(5f);
if(isSelected)
{
if(EnemyAllyList.playerEnemiesTmp.Contains(tag) || EnemyAllyList.playerEnemies.Contains(tag))
{
selectedOutlineMaterial = enemyOutline;
}
else if(EnemyAllyList.playerAllies.Contains(tag))
{
selectedOutlineMaterial = allyOutline;
}
else if(EnemyAllyList.playerNeutrals.Contains(tag))
{
selectedOutlineMaterial = neutralOutline;
}
spriteRenderer.material = selectedOutlineMaterial;
}
}
}
void OnEnable()
{
tag = shipTag;
isKilled = false;
if(isPlayerCarrier)
{
StartCoroutine(DistanceFromTargetCarrier());
}
// For Enemy Carrier
else if(isEnemyCarrier)
{
StartCoroutine(DistFromTargetEnemyCarrier());
StartCoroutine(UpdateTargetOffset());
}
// For Fighter Ships
else if(isPlayerFighter || isEnemyFighter)
{
StartCoroutine(DistFromTargetFighters());
StartCoroutine(UpdateZAxisForFighters());
StartCoroutine(SendShipValue());
}
else if(isStation)
{
StartCoroutine(ClosestEnemyForStation());
}
}
IEnumerator SendShipValue()
{
if(isPlayerCarrier) // || isPlayerFighter
{
if(targetWaypoint == null) // *** For tutorial page
{
BuyShipButton.allSC.Add(this);
if(shipNumber == 1)
{
targetWaypoint = waypoints.firstShipPosition;
BuyShipButton.ship1SC = this;
}
else if(shipNumber == 2)
{
targetWaypoint = waypoints.secondShipPosition;
BuyShipButton.ship2SC = this;
}
}
yield return new WaitForSeconds(0.02f);
ShipSpawner.playerStrenght += totalValue;
}
}
private int targetOffset; // For Enemy Carrier
private WaitForSeconds wait4 = new WaitForSeconds(4f);
private WaitForSeconds wait1 = new WaitForSeconds(1f);
IEnumerator UpdateTargetOffset()
{
while(true)
{
targetOffset = Random.Range(20, 30);
yield return wait4;
}
}
IEnumerator UpdateZAxisForFighters()
{
while(true)
{
if(Random.value<0.5f)
{
z = 1;
}
else
{
z = -1;
}
zAxis = new Vector3(0, 0, z);
if(!isKilled)
{
speed = Random.Range(minSpeed, maxSpeed);
}
yield return wait4;
}
}
// For Carrier Ships
IEnumerator DistanceFromTargetCarrier()
{
while(true)
{
yield return wait1;
if(!isKilled) //mode == Mode.Attack
{
closestEnemy = FindClosestEnemy();
if(closestEnemy != null)
{
distanceFromEnemy = Vector3.Distance (transform.position, closestEnemy.position);
}
if(isPlayerCarrier && isThrusterOn && shipStats.energyShip > 0 && speed > 1f)
{
shipStats.energyShip -= 1;
shipStats.ChangeEnergy(""); //""
}
if(!isTargetingStation)
{
distanceFromWaypoint = Vector3.Distance (transform.position, targetWaypoint.position);
if(distanceFromWaypoint < 7 && !preparingHyperJump)
{
StartCoroutine(LerpSpeedCarrier(0, 2f));
}
else if(!preparingHyperJump)
{
StartCoroutine(LerpSpeedCarrier(defaultSpeed, 2f));
}
}
}
}
}
public IEnumerator LerpSpeedCarrier(float endValue, float duration)
{
float time = 0;
float startValue = speed;
while (time < duration)
{
speed = Mathf.Lerp(startValue, endValue, time / duration);
time += Time.deltaTime;
yield return null;
}
speed = endValue;
}
// For Fighter Ships and Enemy Carrier
IEnumerator DistFromTargetFighters()
{
while(true)
{
yield return wait1;
rotateTowardOffset = Random.Range(-100, 100);
if(mode == Mode.Attack)
{
closestEnemy = FindClosestEnemy();
if(closestEnemy != null)
{
target = closestEnemy.position;
distanceFromEnemy = Vector3.Distance (transform.position, target);
startOrbitingDistance = Random.Range(30, 40);
if(distanceFromEnemy < startOrbitingDistance)
{
isChasing = false;
}
else
{
isChasing = true;
}
}
}
else
{
FollowMotherShip();
yield return new WaitForSeconds(3f);
FindClosestEnemy();
}
}
}
void FollowMotherShip()
{
Transform motherShip = fighterSpawner.transform;
Vector3 pos = motherShip.position;
int randomDiff = Random.Range(10, 20);
target = new Vector3(pos.x+randomDiff, pos.y+randomDiff, 0);
}
// For enemy carriers only
IEnumerator DistFromTargetEnemyCarrier()
{
while(true)
{
if(mode == Mode.Attack)
{
yield return wait1;
if(mode == Mode.Attack)
{
closestEnemy = FindClosestEnemy();
if(closestEnemy != null)
{
if(!isStation)
{
target = new Vector3(closestEnemy.position.x+targetOffset, closestEnemy.position.y+targetOffset, 0);
}
distanceFromEnemy = Vector3.Distance (transform.position, closestEnemy.position);
}
}
}
else
{
yield return new WaitForSeconds(2f);
FindClosestEnemy();
}
}
}
IEnumerator ClosestEnemyForStation()
{
while(true)
{
if(mode == Mode.Attack)
{
yield return wait1;
if(mode == Mode.Attack)
{
closestEnemy = FindClosestEnemy();
if(closestEnemy != null)
{
distanceFromEnemy = Vector3.Distance(transform.position, closestEnemy.position);
}
}
}
else
{
yield return new WaitForSeconds(2f);
FindClosestEnemy();
}
}
}
private float curDistance;
private List <GameObject> gos;
Transform FindClosestEnemy()
{
if(isKilled)
{
Debug.Log("Killed");
return null;
}
Debug.Log(preferredEnemy.name);
if(preferredEnemy == null || !preferredEnemy.gameObject.activeInHierarchy)
{
gos = new List<GameObject>();
if(isPlayer)
{
gos = EnemyAllyList.playerAllTargetsTmp;
}
else if(isFaction1)
{
gos = EnemyAllyList.faction1AllTargets;
}
else if(isFaction2)
{
gos = EnemyAllyList.faction2AllTargets;
}
else if(isPirate)
{
gos = EnemyAllyList.pirateAllTargets;
}
Vector3 diff;
float distance = Mathf.Infinity;
//Debug.Log(gos.Count);
if(gos.Count != 0)
{
mode = Mode.Attack;
}
else
{
if(EnemyAllyList.playerAllTargets.Count == 0 && isPlayerCarrier && mode == Mode.Attack && SceneManager.GetActiveScene().name != "Tutorial")
{
SaveMidGame();
mode = Mode.Idle;
}
if(isEnemyCarrier)
{
diff = target - transform.position;
distance = diff.sqrMagnitude;
if(distance < 100)
{
target = new Vector3(transform.position.x+Random.Range(-100, 100), transform.position.y+Random.Range(-100, 100), 0);
}
mode = Mode.Idle;
}
return null;
}
GameObject closest = null;
Vector3 position = transform.position;
//Debug.Log("All GOS: "+gos.Count);
foreach (GameObject go in gos)
{
diff = go.transform.position - position;
curDistance = diff.sqrMagnitude;
if(curDistance < 300) // Problem with this. Opening repair while enemy present
{
continue;
}
if (curDistance < distance)
{
closest = go;
distance = curDistance;
}
}
if(closest != null)
{
return closest.transform;
}
else
{
if(isEnemyCarrier)
{
diff = target - transform.position;
distance = diff.sqrMagnitude;
if(distance < 100)
{
target = new Vector3(transform.position.x+Random.Range(-50, 50), transform.position.y+Random.Range(-50, 50), 0);
}
}
mode = Mode.Idle;
return null;
}
}
else
{
if(EnemyAllyList.playerEnemies.Contains(preferredEnemy.tag)) //EnemyAllyList.playerEnemiesTmp.Contains(preferredEnemy.tag) ||
{
return preferredEnemy;
}
else
{
return null;
}
}
}
void SaveMidGame()
{
shipStats.SaveHullNShied();
if(!pageManager.isAlreadySaved)
{
pageManager.SaveEverythingMidGame();
}
}
void FixedUpdate()
{
if(isPlayerCarrier)
{
MoveForward();
if(speed > 0.4f)
{
if(distanceFromWaypoint > 5)
{
RotateTowardTarget(targetWaypoint.position, transform.position);
}
else
{
transform.rotation = Quaternion.Slerp(transform.rotation, carrierTargetRotation, Time.deltaTime * rotateSpeed);
}
}
}
else if(isPlayerFighter || isEnemyFighter)
{
if(isChasing || mode == Mode.Idle)
{
MoveForward();
RotateTowardTarget(new Vector2(target.x, target.y+rotateTowardOffset), transform.position);
}
else if(mode == Mode.Attack)
{
transform.RotateAround(target, zAxis, Time.deltaTime * speed);
RotateTowardTarget(target, transform.position);
}
}
else if(isEnemyCarrier)
{
if(mode == Mode.Attack)
{
MoveForward();
RotateTowardTarget(target, transform.position);
}
else if(isEnemyFleeing)
{
StartCoroutine(mainScript2.HyperJumpEnemy());
isEnemyFleeing = false;
}
else if(mode == Mode.Idle)
{
MoveForward();
RotateTowardTarget(target, transform.position);
}
}
else if(isStation && !isKilled)
{
transform.Rotate(0, 0, -rotateSpeed * Time.deltaTime);
}
else if(isEnemyFreighter)
{
MoveForward();
RotateTowardTarget(target, transform.position);
}
}
IEnumerator FreighterWaypoint()
{
target = freighterFirstWP;
while(!isKilled)
{
distanceFromWaypoint = Vector3.Distance(transform.position, freighterFirstWP);
if(distanceFromWaypoint < 15) // && !preparingHyperJump
{
StartCoroutine(LerpSpeedCarrier(0, 2f));
break;
}
yield return new WaitForSeconds(2f);
}
yield return new WaitForSeconds(15f);
Vector3 currentPos = targetMover.aILerp.transform.position;
Transform nextNode = mainScript2.GetClosestNode(pageManager.mapNodes, currentPos);
ShipSpawner.enemyFleetJumpedToSceneName = nextNode.name;
Vector3 targetDirEnter = (nextNode.position - currentPos).normalized;
isEnemyFleeing = true;
target += targetDirEnter * 300;
StartCoroutine(mainScript2.HyperJumpEnemy());
}
[HideInInspector] public bool isEnemyFleeing = false;
void MoveForward()
{
if(isPlayerCarrier && isThrusterOn && shipStats.energyShip > 0)
{
transform.position += transform.right * speed * 2 * Time.deltaTime;
}
else
{
transform.position += transform.right * speed * Time.deltaTime;
}
}
void RotateTowardTarget(Vector2 targ, Vector2 pos)
{
Vector2 vectorToTarget = targ - pos;
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * rotateSpeed);
}
[HideInInspector] public bool isKilled = false;
public void Killed()
{
if(!isKilled)
{
tag = "Untagged";
isKilled = true;
if(!isStation)
{
StartCoroutine(LerpSpeedCarrier(0.5f, 3f));
}
StartCoroutine(mainScript2.DeathExplosion());
}
}
void OnDisable()
{
if((isPlayerFighter || isEnemyFighter) && fighterSpawner != null)
{
fighterSpawner.spawnedFighters.Remove(gameObject);
}
if(isKilled)
{
if(pirateHunt != null)
{
pirateHunt.pirateCount--;
if(pirateHunt.pirateCount == 0 && pirateHunt.numberOfWaypoints != 0)
{
pirateHunt.SpawnPirateNextBatch();
}
else if(pirateHunt.pirateCount == 0 && pirateHunt.numberOfWaypoints == 0)
{
pirateHunt.MissionCompleted();
}
}
else if(defenceMission != null)
{
defenceMission.enemyShipsCount--;
if(defenceMission.enemyShipsCount == 0)
{
defenceMission.MissionCompleted();
}
}
}
}
}