Search Unity

Weird NullPointerException in Xcode than in script with more than 500 lines?

Discussion in 'iOS and tvOS' started by skoteskote, Oct 4, 2018.

  1. skoteskote

    skoteskote

    Joined:
    Feb 15, 2017
    Posts:
    87
    I have a strange NullReferenceException in XCode, basically one of my scripts seem to loose assigned classes after ca 500 lines of code? Classes declared and assigned to at the start, which works as normal through the whole script, but after the 500 mark they start throwing NullReferenceException. This only happen in Xcode, all works well when I run it in Unity. All works if I reassign these classes at the places where they threw errors.

    Sort of like this:
    Code (CSharp):
    1. private Manager manager;
    2.  
    3. void Start(){
    4. manager = GameObject.Find("_Manager").GetComponent<Manager>();
    5. }
    6.  
    7. // 500 lines of code with this class called ca 20 times and no errors
    8. // The class is not nullified or reassigned
    9.  
    10. public void DoSomething(){
    11. manager.Something(); // this one throws an NullReferenceException in xcode
    12. GameObject.Find("_Manager").GetComponent<Manager>().Something(); // this one throws no error
    13. }
     
    Last edited: Oct 4, 2018
  2. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    826
    Did you try to build other build targets, or is it really iOS specific?
    Maybe check the following:
    - Is start called before DoSomething? The call order might be a bit different with builds.
    - Do you have #if UNITY_EDITOR in your script where you might handle stuff with the manager?
    - Are you setting the manager to another value in the script?
    - Is your manager really unique (so there is just one object of the manager) and does this object never change (so make sure you don't destroy and create the manager again)?

    As a starting point I would recommend testing the following:
    Code (CSharp):
    1.     private Manager manager;
    2.     private bool initialized;
    3.     void Start() {
    4.         if(!initialized) {
    5.             Initialize();
    6.         }
    7.     }
    8.     private void Initialize() {
    9.         manager = GameObject.Find("_Manager").GetComponent<Manager>();
    10.         initialized = true;
    11.     }
    12.     // 500 lines of code with this class called ca 20 times and no errors
    13.     // The class is not nullified or reassigned
    14.    
    15.     public void DoSomething() {
    16.         if(!initialized) {
    17.             Initialize();
    18.         }
    19.         manager.Something();
    20.     }
    21.  
    This problem does not look like an ios specific one, I guess checking the code, call order and the life cycle of the manger object would be good starting points.
     
  3. skoteskote

    skoteskote

    Joined:
    Feb 15, 2017
    Posts:
    87
    Thanks for your comment! The weird thing is that all calls to the manager works well throughout the script (it's called around 20 times at various points), until around 500 lines in, it's first after then I get a NullReference. My workaround now is to just reassign all my managers around the 500 mark, which works but shouldn't really be necessary. The script itself is instantiated a few minutes in the game (a controller for a character) so there shouldn't be any collision with the start function call order really.
     
  4. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    826
    Did you try the code I posted? My strongest guess still is that you're accidentally calling DoSomething before the start method. The line count shouldn't be an issue at all. :)

    Otherwise (I'm not sure how much you're into programming), it would be really easy to set a conditional breakpoint for when DoSomething is called with the manager not set and then check why this is happening.
     
  5. JeffDUnity3D

    JeffDUnity3D

    Joined:
    May 2, 2017
    Posts:
    14,446
    What exactly is the error? Show the code where it is occurring.
     
    skoteskote likes this.
  6. skoteskote

    skoteskote

    Joined:
    Feb 15, 2017
    Posts:
    87
    Sorry for the delay in getting back to this, work has been killing me lately. Here is the code, it's quite messy but if you look at lines 528, 534, 537 and 557 you see where I need to reassign my managers. This code is itself instantiated a couple of minutes into the game, well after all my managers.

    Thanks for the help!

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEngine.AI;
    5. using UnityEngine.UI;
    6. using UnityEngine.SceneManagement;
    7. using Greyman;
    8.  
    9. public class AnimalController : MonoBehaviour
    10. {
    11.     private GameObject manager;
    12.  
    13.     private FoodController foodCon;
    14.     private MixAnimalManager mixAnimMan;
    15.     private InfoManager infoMan;
    16.     private SpeechManager speeMan;
    17.     private DestinationManager destMan;
    18.     private AnimalManager animMan;
    19.     private TorchHandler torch;
    20.     private SaveManager saveMan;
    21.  
    22.     private OffScreenIndicator offScreenArrow;
    23.  
    24.     //about this specific animal
    25.     private Animator anim;
    26.     private Animator[] animators;
    27.  
    28.     public string[] animalNames = new string[] { "Deer", "Fox", "Eagle", "Bear", "Wolf", "Moose", "Hare", "Buck", "MixAnimal" }; //strings of the names
    29.     private float[] stoppingDist = new float[] { 0.4f, 0.3f, 0.3f, 0.7f, 0.5f, 0.5f, 0.2f, 0.5f, 0.3f, 0.1f }; //The individual distance an animal should stop from food etc to look correct;
    30.     private int thisAnimal;
    31.     private bool mixAnimal = false; // false = normal animal, true = mixanimal
    32.     private bool canFly = false;
    33.     private float stoppingDistanceShowcase = 1f;
    34.     NavMeshAgent agent;
    35.  
    36.     private string state = "idle";
    37.  
    38.     public Transform destination;
    39.     private Transform cam;
    40.     private Transform rotDir;
    41.     private Transform mouth;
    42.  
    43.     private GameObject food = null;
    44.     private GameObject partner;
    45.  
    46.     private Vector3 followPoint;
    47.     private Vector3 currPoint;
    48.  
    49.     //positionsings
    50.     private float[] ranPos;
    51.     private int ranPosX;
    52.     private int ranPosZ;
    53.     private float mad = 2f;
    54.     private float mid = 1f;
    55.  
    56.     public bool fertile = true;
    57.     public bool askForNew = true;
    58.     public bool alwaysFollowUser = false;
    59.  
    60.     private bool testMode;// = false;
    61.     private bool allowFertility;//  = true;
    62.     private bool allowFood;//  = true;
    63.  
    64.     public bool NRM = true;
    65.     private bool fromSaved = false;
    66.  
    67.     // In NRM bools
    68.     private bool hasFood = false;
    69.     public bool canCuddle = false;
    70.     private bool initialize = true;
    71.     private bool onScreen = false;
    72.     private bool seenPlayed = false;
    73.     private bool firstSeen = false;
    74.     private bool canFood = false;
    75.     private bool startFoodPS = true;
    76.     private bool onScreenForSeconds;
    77.     private bool waitForUser;
    78.     private bool hasWaitedForUser = false;
    79.     private bool shownHideButton = false;
    80.     private bool waitText = false;
    81.     private bool addedIndicator = false;
    82.     public bool leadAnimal = true;
    83.     private bool hasAskedForNewAnimals = false;
    84.     private bool followP = true;
    85.  
    86.     private float time;
    87.     private float time2;
    88.     private bool setTime2 = true;
    89.     private float waitToLeave;
    90.     private float seenTime = -1f;
    91.  
    92.     // Sets from speech manager
    93.     private float waitTime;
    94.     private float waitToLeaveTime;
    95.     private float eatTime;
    96.     private float waitTimeFood;
    97.     private float askForFoodTime;
    98.     private float thankTime;
    99.     private float firstSeenPlayTime;
    100.     private float longerWaitTime;
    101.     private float timeSeen;
    102.     private float maxDistanceToUser;
    103.     private float followDistance;
    104.     private float waitAskToShowAnimals;
    105.     private float waitGoToNewDest;
    106.     private float waitForReply;
    107.     private float fertileTime;
    108.  
    109.     private bool haseBeenFertile = false;
    110.     public bool canAskForMoreAnimals = true;
    111.  
    112.     void Start()
    113.     {
    114.         cam = GameObject.FindGameObjectWithTag("MainCamera").transform;
    115.         agent = gameObject.GetComponent<NavMeshAgent>();
    116.  
    117.         for (int i = 0; i < animalNames.Length; i++) { if (gameObject.tag == animalNames[i]) { thisAnimal = i; } }
    118.  
    119.         if (thisAnimal == 2) { canFly = true; }
    120.  
    121.         if (gameObject.layer == 12) { anim = gameObject.GetComponent<Animator>(); } // assigns animator if normal animal
    122.         else if (gameObject.layer == 15) { mixAnimal = true; animators = GetComponentsInChildren<Animator>(); } // checks if this is mixanimal or normal animal, assigns animators
    123.  
    124.         // POSITIONS FOR FOLLOWING
    125.         ranPos = new float[] { Random.Range(mid, mad), Random.Range(mid, mad), Random.Range(-mid, -mad), Random.Range(-mid, -mad) };
    126.         ranPosX = Random.Range(0, 4);
    127.         ranPosZ = Random.Range(0, 4);
    128.         currPoint = new Vector3(cam.position.x + ranPos[ranPosX], cam.position.y, cam.position.z + ranPos[ranPosZ]);
    129.         followPoint = currPoint;
    130.  
    131.         //ASSIGNS ALL MANAGERS
    132.         manager = GameObject.FindGameObjectWithTag("Manager");
    133.         foodCon = manager.GetComponent<FoodController>(); //add the gameobject here to get right food type in animal controller
    134.         mixAnimMan = GameObject.Find("_MixedAnimalManager").GetComponent<MixAnimalManager>(); //adds this animal to the list of Animals
    135.         infoMan = manager.GetComponent<InfoManager>();
    136.         speeMan = manager.GetComponent<SpeechManager>();
    137.         destMan = manager.GetComponent<DestinationManager>();
    138.         animMan = manager.GetComponent<AnimalManager>();
    139.         offScreenArrow = GameObject.Find("OffScreenIndicator2").GetComponent<OffScreenIndicator>();
    140.         torch = manager.GetComponent<TorchHandler>();
    141.         saveMan = manager.GetComponent<SaveManager>();
    142.  
    143.         //ASSIGNS ALL FLOATS AND BOOLS
    144.         NRM = speeMan.NRM;
    145.         fromSaved = saveMan.CheckIfFromSaved(mixAnimal,thisAnimal);
    146.         testMode = speeMan.testMode;
    147.         if (!testMode) { fertile = false; }  //sets fertility false start
    148.         allowFertility = speeMan.allowFertility;
    149.         allowFood = speeMan.allowFood;
    150.         waitTime = speeMan.waitTime;
    151.         waitToLeaveTime = speeMan.waitToLeaveTime;
    152.         eatTime = speeMan.eatTime;
    153.         waitTimeFood = speeMan.waitTimeUntilFood;
    154.         askForFoodTime = speeMan.askForFoodTime;
    155.         thankTime = speeMan.thankTime;
    156.         firstSeenPlayTime = speeMan.firstSeenPlayTime;
    157.         longerWaitTime = speeMan.longerWaitTime;
    158.         timeSeen = speeMan.intitalTimeSeen;
    159.         maxDistanceToUser = speeMan.maxDistanceToUser;
    160.         followDistance = speeMan.followDistance;
    161.         waitAskToShowAnimals = speeMan.waitAskToShowNewAnimals;
    162.         waitGoToNewDest = speeMan.waitGoToNewDest;
    163.         waitForReply = speeMan.waitForReply;
    164.         fertileTime = speeMan.waitForInfertility;
    165.  
    166.         //mouth = TransformDeepChildExtension.FindDeepChild(gameObject.transform, "b_Jaw_nub");
    167.     }
    168.  
    169.  
    170.     void Update()
    171.     {
    172.         // print(state);
    173.         //if (!mixAnimal) { print("is playing is: " + anim.GetBool("isPlaying") + ", is walking is: " + anim.GetBool("isWalking") + ", is cuddling is: " + anim.GetBool("isCuddling") + ", is eating is: " + anim.GetBool("isPlaying"));}
    174.  
    175.         if (alwaysFollowUser) { state = "followUser"; }
    176.  
    177.         if (initialize) // ONLY DO THIS FIRST ROUND
    178.         {
    179.             if ((!NRM || fromSaved) && !mixAnimal) { print("loc 2 added this normal animal"); animMan.AddAnimal(gameObject, thisAnimal, true, false); }
    180.             time = Time.fixedTime + waitTime; // wait until show "seen marker"
    181.             mixAnimMan.hasAskedBirth = false; // to allow new pregnancy
    182.             if (mixAnimal) { animMan.AddAnimal(gameObject, thisAnimal, false, !fromSaved); print("added mixanimal to list"); } // adds to animal manager if this is a mixanimal
    183.             if (!mixAnimal && !fromSaved) { infoMan.SeenMarker(gameObject); }// show seen marker info
    184.             initialize = false;
    185.             time = Time.fixedTime + waitTime;
    186.         }
    187.  
    188.         //if (!firstSeen && !addedIndicator && time < Time.fixedTime)
    189.         //{
    190.         //    // offScreenArrow.AddIndicator(gameObject.transform,0); addedIndicator = true;
    191.         //}
    192.  
    193.         // checks if animal has been seen for one second before starting play
    194.         if (!firstSeen)
    195.         {
    196.             if (Camera.main != null)
    197.             {
    198.                 Vector3 screenPoint = Camera.main.WorldToViewportPoint(gameObject.transform.position);
    199.                 onScreen = screenPoint.z > 0 && screenPoint.x > 0 && screenPoint.x < 1 && screenPoint.y > 0 && screenPoint.y < 1;
    200.             }
    201.         }
    202.  
    203.         if (!firstSeen)
    204.         {
    205.             if (onScreen && seenTime < 0f) { seenTime = Time.time; infoMan.animalSeen = true; } // turns of look-in-showcase info
    206.             else if (seenTime > 0f && (Time.time - seenTime) >= timeSeen) { onScreenForSeconds = true; }
    207.         }
    208.  
    209.         if (!mixAnimal && NRM) //only do below for normal animals
    210.         {
    211.             if (!seenPlayed && !testMode && onScreenForSeconds)            //animal has been seen for x seconds
    212.             {
    213.                 offScreenArrow.RemoveAllIndicators();
    214.                 playAnim("isPlaying", true);
    215.                 state = "play";
    216.                 if (!firstSeen) { time = Time.fixedTime + firstSeenPlayTime; } // plays initial play scene
    217.                 firstSeen = true; // to make sure this initial scene doesn't play forever
    218.             }
    219.  
    220.             if (firstSeen && time > 0 && time < Time.fixedTime && !seenPlayed && !testMode) //animal has played for firstSeenPlayTime seconds
    221.             { // AFTER INITIAL LITTLE "SCENE", READY FOR FOOD
    222.                 playAnim("isPlaying", false);
    223.                 if (allowFood) { speeMan.Speech(speeMan.ImHungry, askForFoodTime, gameObject); } //ASKS FOR FOOD
    224.                 state = "idle";
    225.                 seenPlayed = true;
    226.                 canFood = true;
    227.                 time = Time.fixedTime + waitTimeFood; //WAIT TIME UNTIL FOOD APPEAR
    228.             }
    229.  
    230.             if (time > 0 && time < Time.fixedTime && canFood && !hasFood)  // activates food
    231.             {
    232.                 if (allowFood) { foodCon.Activate(gameObject); }
    233.                 infoMan.currentInfo = 1;
    234.                 hasFood = true;
    235.             }
    236.         }
    237.         else if (!mixAnimal && !NRM)
    238.         {
    239.             state = "followUser";
    240.             Rotate();
    241.             canCuddle = true;
    242.         }
    243.  
    244.         if (!mixAnimal && canFood && state == "idle" && foodCon.foodActive == false && time < Time.fixedTime)
    245.         {
    246.             if (allowFood) { foodCon.Activate(gameObject); }
    247.             infoMan.currentInfo = 1;
    248.             hasFood = true;
    249.         }
    250.  
    251.         else if (mixAnimal)
    252.         { // only do below for mixanimals
    253.             if (!seenPlayed && onScreenForSeconds)
    254.             {
    255.                 playAnim("isDancing", true);
    256.                 state = "play";
    257.                 if (!firstSeen) { time = Time.fixedTime + firstSeenPlayTime; } // plays initial play scene
    258.                 firstSeen = true; // to make sure this initial scene doesn't play forever
    259.             }
    260.  
    261.             //animal has played for firstSeenPlayTime seconds
    262.             if (firstSeen && time > 0 && time < Time.fixedTime && !seenPlayed) // AFTER INITIAL LITTLE "SCENE", READY FOR FOOD
    263.             {
    264.                 playAnim("isDancing", false);
    265.  
    266.                 rotDir = cam; //looks at camera
    267.                 Rotate();
    268.                 if (!fromSaved)
    269.                 {
    270.                     speeMan.NewAnimal(gameObject); // starts "hi im a new animal" - speech
    271.                     mixAnimMan.MixAnimalList(gameObject); //adds this animal to mixAnimMans mixanmial list
    272.                 }
    273.                 canCuddle = true;
    274.                 state = "idle";
    275.                 seenPlayed = true;
    276.  
    277.                 time = Time.fixedTime + askForFoodTime; //wait until ask for more animals
    278.                 speeMan.birth = false; // set birth false so it can ask for new animals
    279.             }
    280.  
    281.             if (NRM && seenPlayed && !shownHideButton && time < Time.fixedTime) // after birth at NRM
    282.             {
    283.                 Rotate();
    284.                 shownHideButton = true;
    285.                 time = Time.fixedTime + waitGoToNewDest;
    286.                 state = "canGoToNew";
    287.             }
    288.             if (!NRM && seenPlayed && !shownHideButton && time < Time.fixedTime) // after birth at home
    289.             {
    290.                 Rotate();
    291.                 shownHideButton = true;
    292.                 state = "followUser";
    293.             }
    294.         }
    295.  
    296.         if (fertile && Time.fixedTime > fertileTime) { fertile = false; } // sets fertile false after 30 sec
    297.  
    298.         //STATES BELOW
    299.         if((state == "idle" || state == "canGoToNew" || state == "followUser") && leadAnimal){
    300.             if (setTime2) { time2 = Time.fixedTime + 10f; setTime2 = false; }
    301.             if (canCuddle && !setTime2 && time2 < Time.fixedTime && canAskForMoreAnimals) { speeMan.Speech(speeMan.ThereIsMoreAnimals, waitForReply, gameObject); print("animcontr ask more animals 2"); } //asks for more animals in case nothing happens
    302.         }
    303.  
    304.         if(state != "idle" && state != "canGoToNew" && state == "followUser"){
    305.             setTime2 = true;
    306.         }
    307.  
    308.         if (state == "followUser")
    309.         {
    310.             agent.SetDestination(SetFollowPoint());
    311.             agent.stoppingDistance = stoppingDist[thisAnimal];
    312.             goalReached();
    313.         }
    314.  
    315.         else if (state == "newPosition")
    316.         {
    317.             agent.enabled = false;
    318.             gameObject.transform.position = SetFollowPoint();
    319.             agent.enabled = true;
    320.             state = "followUser";
    321.         }
    322.  
    323.         else if (state == "play")
    324.         {
    325.             playAnim("isPlaying", true);
    326.         }
    327.  
    328.         else if (state == "flying")
    329.         {
    330.             //if(canFly){
    331.             playAnim("isFlying", true);
    332.         //}
    333.         }
    334.  
    335.         else if (state == "hasEaten")
    336.         {
    337.             Rotate();
    338.         }
    339.  
    340.         else if (state == "food" && food != null)
    341.         {
    342.             agent.SetDestination(food.transform.position);
    343.             agent.stoppingDistance = stoppingDist[thisAnimal];
    344.             goalReached();
    345.             if (food == null) { StartCoroutine(Eating(eatTime)); print("food was null so started eating anyhow"); }
    346.         }
    347.  
    348.         else if (state == "goToBirth")
    349.         {
    350.             agent.SetDestination(partner.transform.position);
    351.             agent.stoppingDistance = 2f;
    352.             goalReached();
    353.         }
    354.  
    355.         else if (state == "lookBirth")
    356.         {
    357.             // so speeman doesn't ask for new animals directly after birth
    358.             agent.SetDestination(new Vector3(partner.transform.position.x - 2, gameObject.transform.position.y, partner.transform.position.z - 4)); //sets a looking position a bit away
    359.             goalReached();
    360.             if (waitToLeave != 0 && waitToLeave < Time.fixedTime) //waits for a bit before leaving
    361.             {
    362.                 animMan.ToggleMe(gameObject);
    363.                 //gameObject.SetActive(false);
    364.             }
    365.         }
    366.  
    367.         else if (state == "leave")
    368.         {
    369.         }
    370.  
    371.         else if (state == "canGoToNew")
    372.         {
    373.             Rotate();
    374.             if (animMan.showAnimals.activeSelf == true || speeMan.shownCuddleInfo == false) { time = Time.fixedTime + waitAskToShowAnimals; }
    375.             if (time < Time.fixedTime && !hasAskedForNewAnimals && askForNew)
    376.             {
    377.                 print("animal controller ask for new animals 1"); // ONLY DO THIS ONCE
    378.                 if (canAskForMoreAnimals) { speeMan.Speech(speeMan.ThereIsMoreAnimals, waitForReply, gameObject); }//asks to go to new animals
    379.                 hasAskedForNewAnimals = true;
    380.             }
    381.  
    382.         }
    383.  
    384.         else if (state == "goToNew")
    385.         {
    386.             bool addedAgent = false;
    387.             if (!WaitForUser())
    388.             {
    389.                 canCuddle = false;
    390.                 agent.SetDestination(destination.position); // Calls current showcase to show from destinationmanager
    391.                 agent.stoppingDistance = stoppingDistanceShowcase;
    392.                 goalReached();
    393.                 if (hasWaitedForUser)
    394.                 {
    395.                     offScreenArrow.RemoveAllIndicators();
    396.                     addedAgent = false;
    397.                     hasWaitedForUser = false;
    398.                 }
    399.             }
    400.             else if (WaitForUser())
    401.             {
    402.                 canCuddle = true;
    403.                 if (!addedAgent) { offScreenArrow.AddIndicator(gameObject.transform, 0); addedAgent = true; }
    404.                 agent.SetDestination(gameObject.transform.position);
    405.                 rotDir = cam;
    406.                 if (waitText && time < Time.fixedTime) { waitText = false; }
    407.                 if (!waitText) { speeMan.Speech(speeMan.FollowMe, 4f, gameObject); waitText = true; time = Time.fixedTime + waitTime; }//follow me speech
    408.                 Rotate();
    409.                 goalReached();
    410.                 hasWaitedForUser = true;
    411.             }
    412.         }
    413.         else if (state == "atNew")
    414.         {
    415.             canCuddle = true;
    416.             setTime2 = true;
    417.             offScreenArrow.RemoveAllIndicators();
    418.             rotDir = cam.transform; // Turns towards camera when at destination
    419.             hasAskedForNewAnimals = false; // allow animal to ask for new animals again after at destination in case it's lead animal
    420.         }
    421.     }
    422.  
    423.     // CONSTANT FUNCTIONS
    424.     public void Rotate()
    425.     {
    426.         if (rotDir != null)
    427.         {
    428.             Vector3 lookAtPos = new Vector3(rotDir.position.x, transform.position.y, rotDir.position.z) - gameObject.transform.position;
    429.             Quaternion lookRot = Quaternion.LookRotation(lookAtPos);
    430.             lookRot *= Quaternion.Euler(0, -10f, 0); //angles it ever so slightly so you get a better view
    431.             transform.rotation = Quaternion.Slerp(transform.rotation, lookRot, agent.speed / 3 * Time.deltaTime);
    432.         }
    433.     }
    434.  
    435.     private void playAnim(string animState, bool animBool)
    436.     {
    437.         if (!mixAnimal) { anim.SetBool(animState, animBool); }
    438.         else if (mixAnimal) { foreach (Animator anims in animators) { anims.SetBool(animState, animBool); } }
    439.     }
    440.  
    441.     private void goalReached()
    442.     {
    443.         if (!agent.pathPending)
    444.         {
    445.             if (agent.remainingDistance <= agent.stoppingDistance)
    446.             {
    447.                 if (!agent.hasPath || agent.velocity.sqrMagnitude == 0f)
    448.                 {
    449.                     if (state != "followUser") { Rotate(); }
    450.  
    451.                     playAnim("isWalking", false);
    452.  
    453.                     if (state == "food") { StartCoroutine(Eating(eatTime)); }
    454.                                                          // food.transform.position = mouth.transform.position;// add food to mouth NEED TO CANCEL THE AGENT.DESTINATION THINGY TO NOT JITTER
    455.                 }
    456.  
    457.                 if (state == "goToNew")
    458.                 {
    459.                     playAnim("isWalking", false);
    460.  
    461.                     if (!WaitForUser())
    462.                     {
    463.                         state = "atNew";
    464.                         infoMan.TorchButtonOn();
    465.                         if (!Application.isEditor && leadAnimal) {/* torch.enableLightEstimate = true;*/ print("torch light estimate turned on in animal controller"); } //only do torch stuff if we're not in editor
    466.                         speeMan.Speech(speeMan.HereLives, waitForReply, gameObject); // Speech here lives, longer
    467.                         destination = null;
    468.                     }
    469.  
    470.                 }
    471.             }
    472.  
    473.             else { playAnim("isPlaying", false); playAnim("isCuddling", false) ;playAnim("isWalking", true); }
    474.         }
    475.     }
    476.  
    477.     // ONE-OFF FUNCTIONS
    478.     public void Food(GameObject foodInScene) {
    479.         if (CheckStringExtension.CheckFood(gameObject, foodInScene))
    480.         {
    481.             state = "food"; // set in food state
    482.             food = foodInScene; // assign food
    483.             speeMan.RightFood(gameObject, food); // starts speech manager right food
    484.             rotDir = food.transform; //rotation direction food
    485.             gameObject.transform.SetParent(null); // deparents this animal to make it stay
    486.         }
    487.         else { speeMan.WrongFood(gameObject, foodInScene); }
    488.     }
    489.  
    490.     void AfterEating()
    491.     {
    492.         playAnim("isEating", false); // stop animation
    493.         state = "hasEaten"; //set state to has eaten
    494.         canCuddle = true; //Allow animal to cuddle after this
    495.         foodCon.RemoveFood(); // remove all food
    496.         rotDir = cam; // turn towards camera
    497.         Rotate(); // rotate
    498.         speeMan.Speech(speeMan.ThanksFood, thankTime, gameObject); // Thanks for food
    499.         time = Time.fixedTime + longerWaitTime; //set wait time to next thing
    500.         infoMan.currentInfo = 2; //sets information number to be 2
    501.         if (!mixAnimal) {  animMan.AddAnimal(gameObject, thisAnimal); }//adds this animal to animMan and mixAnimMans animal list                                                                                                                                                       // else if (fromSaved) { print("this animal is from saved and should not be added to animal manager"); }
    502.     }
    503.  
    504.     public void SetCuddling(string statex, bool bol)
    505.     {
    506.         if (canCuddle)
    507.         {
    508.             if (!mixAnimal) { playAnim("isCuddling", bol); }
    509.             if (mixAnimal) { playAnim("isDancing", bol); }
    510.             rotDir = cam;
    511.         }
    512.         if (bol) {
    513.             Rotate();
    514.         }
    515.         if (!bol && allowFertility && !haseBeenFertile) { if (!fertile) { print(gameObject.name + " is now fertile"); } fertile = true; fertileTime = Time.fixedTime + 30f; } // can have children
    516.  
    517.         followP = true;
    518.  
    519.         print(gameObject.name + " is fertile = " + fertile + ", and state is: " + state);
    520.     }
    521.  
    522.     public void SetState(string newState, GameObject go = null)
    523.     {
    524.         string oldState = state; // saves old state beore reassigning
    525.         state = newState;
    526.         if (state == "goToNew")
    527.         {
    528.             // Here I need to reassign the Destination Manager because otherwise it throws a null
    529.             destination = GameObject.Find("_Manager").GetComponent<DestinationManager>().GetScene(); // get's the new destination from destman
    530.             if (destination.gameObject.name == "_Manager") { state = "followUser"; print("didn't get a correct scene animcontr"); }
    531.         }
    532.         if (state == "followUser")
    533.         {
    534.             // Here I need to reassign the OffScreenIndicator because otherwise it throws a null
    535.             GameObject.Find("OffScreenIndicator2").GetComponent<OffScreenIndicator>().RemoveAllIndicators();
    536.             if (!seenPlayed) { state = oldState; } // makes sure to not set animal in followUser state unless it has gone through start play
    537.             // Here I need to reassign the Torch Handler because otherwise it throws a null
    538.             if (!Application.isEditor) { GameObject.Find("_Manager").GetComponent<TorchHandler>().enableLightEstimate = false; }
    539.         }
    540.         if (state == "goToBirth") { partner = go; rotDir = partner.transform; }
    541.         if (state == "canGoToNew") { time = Time.fixedTime + waitAskToShowAnimals; }
    542.         print(gameObject.name + " is in set to state " + state);
    543.     }
    544.  
    545.     public void Birth()
    546.     {
    547.         rotDir = partner.transform;
    548.         state = "lookBirth";
    549.         waitToLeave = Time.fixedTime + waitToLeaveTime;
    550.         if (allowFertility) { fertile = false; haseBeenFertile = true; }
    551.     }
    552.  
    553.     public void SetDestinationNull()
    554.     {
    555.         destination = null;
    556.         SetState("followUser");
    557.         // Here I need to reassign the OffScreenIndicator because otherwise it throws a null
    558.         GameObject.Find("OffScreenIndicator2").GetComponent<OffScreenIndicator>().RemoveAllIndicators();
    559.     }
    560.  
    561.     private Vector3 SetFollowPoint()
    562.     {
    563.         if (followP) //changes follow point a little bit after cuddling
    564.         {
    565.             ranPos[ranPosX] = ranPos[ranPosX] + Random.Range(-.2f, .2f);
    566.             ranPos[ranPosZ] = ranPos[ranPosZ] + Random.Range(-.2f, .2f);
    567.             followP = false;
    568.         }
    569.         currPoint = new Vector3(cam.position.x + ranPos[ranPosX], cam.position.y, cam.position.z + ranPos[ranPosZ]); //constantly follow the point related to user
    570.         if (Vector3.Distance(currPoint, followPoint) > followDistance) { followPoint = currPoint; } // only updates this point if distance is more than 1
    571.         return (followPoint);
    572.     }
    573.  
    574.     //BOOLS
    575.     private bool WaitForUser()
    576.     {        //checks how far user is from the animal to wait for it if user doesn't come along
    577.         bool toFar = false;
    578.         if (Vector3.Distance(cam.transform.position, gameObject.transform.position) > maxDistanceToUser) { toFar = true; }
    579.         if (Vector3.Distance(cam.transform.position, gameObject.transform.position) < 1) { toFar = false; }
    580.         return (toFar);
    581.     }
    582.  
    583.     //IENumerators
    584.     private IEnumerator Eating(float eatTime)
    585.     {
    586.         playAnim("isEating", true);
    587.         if (startFoodPS) { foodCon.StartFoodParticleSystem(food, true); startFoodPS = false; } //starts particle system
    588.         yield return new WaitForSeconds(eatTime);
    589.         rotDir = cam;//Camera.main.transform;
    590.         if (state == "food") { AfterEating(); }
    591.         startFoodPS = true;
    592.     }
    593. }
    594.  
     
    Last edited: Oct 19, 2018