Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Voting for the Unity Awards are OPEN! We’re looking to celebrate creators across games, industry, film, and many more categories. Cast your vote now for all categories
    Dismiss Notice
  3. Dismiss Notice

Can I ignore "You are trying to create a MonoBehaviour using the 'new' keyword"?

Discussion in 'Scripting' started by Xhitman, Sep 3, 2018.

  1. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    I get many warning on
    Code (CSharp):
    1.  public List<Transform> AllProjectilesInScene = new List<Transform>();
    2.     public List<Weapon> weapon = new List<Weapon>();
    but I don't find any error when run the game. ?
     
  2. Fido789

    Fido789

    Joined:
    Feb 26, 2013
    Posts:
    343
    That error probably belongs to something else, you are not creating any MonoBehaviours in the code above.
     
  3. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    I get the warning when I start Unity. No need to run the game.
    More details:

    You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all
    UnityEngine.MonoBehaviour:.ctor()
    RobotAI:.ctor() (at Assets/BattleMap/RobotAI.cs:200)
    BattleManager:.ctor() (at Assets/BattleMap/BattleManager.cs:87)

    Code (CSharp):
    1. using UnityEngine;
    2. using System;
    3. using System.Collections.Generic;
    4. using System.Collections;
    5. using UnityEngine.AI;
    6. using System.Linq;
    7. using Random = UnityEngine.Random;
    8.  
    9.  
    10.  
    11. public class RobotAI : MonoBehaviour {      
    12.  
    13.     AssetBundle assetBundle;
    14.        
    15.     // what is the list index in the Data
    16.     public int robotIndex;
    17.     public float moveDistanceMax;
    18.    
    19.     public Transform target ;
    20.     public Transform targetCATRoot;
    21.     Vector3 targetOriginalPosition;
    22.     Vector3 robotOriginalPosition;
    23.     Quaternion robotOriginalRotation;
    24.  
    25.     [SerializeField] Animator animator;
    26.     [SerializeField] GameObject robotExplosion;
    27.     string robotAnimationIdleClipName;
    28.     Rigidbody robotRigidBody;
    29.     NavMeshAgent navAgent;  
    30.     Vector3 destination;
    31.    
    32.     public Transform placeHolder;
    33.     public Transform catRoot;  
    34.     Vector3 catLocalPositionOriginal;
    35.    
    36.     // Need to know what animiation this robot is playing now
    37.     // reason is: how to find out jab vs jab ? when melee weaponeffect dummy hit target, we dont know what target robot is doing.
    38.     // And what target robot doing affect the reaction animation choice
    39.  
    40.     public RobotAnimation currentAnimation;
    41.    
    42.     // Death
    43.     enum DeathMode {Prepare, Animation, Explosion}
    44.     DeathMode deathMode = DeathMode.Prepare;
    45.  
    46.     // For rocket punch hand and digit transfer
    47.     // public Transform handLCAT, handRCAT;
    48.  
    49.     //------------------- Fast refer to the body parts
    50.     public Transform head;
    51.     public Transform eye;
    52.     public Transform earL;
    53.     public Transform earR;
    54.     public Transform mouth;
    55.     public Transform helm;
    56.     public Transform helmTop;
    57.  
    58.     public Transform neck;
    59.         public Transform chest;
    60.         public Transform back;
    61.         public Transform abdomen;
    62.         public Transform pelvis;
    63.  
    64.         public Transform shoulderL;
    65.         public Transform shoulderR;
    66.  
    67.         public Transform upperArmL;
    68.         public Transform upperArmR;
    69.  
    70.         public Transform foreArmL;
    71.         public Transform foreArmR;
    72.  
    73.         public Transform handL;
    74.         public Transform handR;
    75.  
    76.         // for robotEditor, BattleManager dont use them
    77.         public Transform digitL;
    78.         public Transform digitR;
    79.  
    80.         public List<Transform> digitLList = new List<Transform>();
    81.         public List<Transform> digitRList = new List<Transform>();
    82.    
    83.     public Transform thighL;
    84.         public Transform thighR;
    85.         public Transform calfL;
    86.         public Transform calfR;
    87.         public Transform footL;
    88.         public Transform footR;
    89.  
    90.     // Inverse Kinematic target  for ForeArm
    91.     public InverseKinematics IKForeArmL;
    92.     public InverseKinematics IKForeArmR;
    93.  
    94.     //----------------------Skill--------------------------
    95.    
    96.     public List<Transform> assistAttackMember = new List<Transform>();
    97.  
    98.     // total repeat attack time
    99.     public int repeatAttack = 0;
    100.  
    101.  
    102.     //-------------Extra Weapon
    103.     // 1. Use this extra weapon if they are not null
    104.     // 2. if target is out of this extra weapon range, use any weapon that robot animation is standby
    105.  
    106.     // how many attack used before remove weapon from hand?
    107.     public int ExtraWpRUseMax;
    108.     public int ExtraWpRUseCounter;
    109.     public int ExtraWpLUseMax;
    110.     public int ExtraWpLUseCounter;
    111.  
    112.     public Transform ExtraWpR;
    113.     public Transform ExtraWpL;
    114.     //===============================================================
    115.  
    116.     [SerializeField]
    117.     GameObject meleeHandDetectDummy;
    118.     [SerializeField]
    119.     GameObject meleeKickDetectDummy;
    120.     // refer to the dummy generated in scene
    121.     GameObject meleeDetectDummy;
    122.  
    123.     enum MeleeDetectDummyLocation {HandL,HandR,FootL,FootR }
    124.  
    125.     // decide need to move the robot or not while playing melee animation
    126.     bool meleeMove = false; // check if this is melee type animation
    127.     public bool meleeMoveStart = false; // check if now is the melee animation that can start moving transform. make it public to let battleManager know this robot is moving
    128.     bool meleeMoveStartAtIdle = false; // transform start moving when robot animation start, or when robot animation Idle start
    129.     public bool meleeHit = false;    // access by weapon manager, check hit target or not, to stop moving transform
    130.     public Vector3 meleeDestination;  // to finialize the robot position, need to record it before target and robot move (the location where the robot hit target may not be the middle of Hex)
    131.     float meleeMoveDelta=1f; //1 for 1 hex distance, 2 for 2 hex distance
    132.  
    133.     // the point the robot move to when punch by Jab
    134.     //public Vector3 attackedByJabDestinationSelf;
    135.     public Vector3 attackedByJabDestinationWorld;
    136.     const float attackedByJabMoveSpeed = 50;
    137.  
    138.     //===============================Super Electrical Drill Path
    139.  
    140.     [SerializeField] GameObject SEDMovePath1Prefab;  
    141.  
    142.     GameObject SEDMovePathAnimation;
    143.     // path 1: Start point to path 1 point, attach robot on path dummy1
    144.     // path 2: move to target freely by script, remove path dummy
    145.     // path 3: when hit target, attach robot on path dummy2
    146.     // path 4: Return robot to destination point on ground
    147.     // path 7: rotate to origional rotation
    148.     // path 8: fall to ground animation
    149.     // path 9: for non robot unit, keep rotating for 2 sec at target, then go to 7
    150.     public enum SEDMoveModeStage {Path1Setup, Path1, Path2, Path3Setup, Path3, Path4, Path5, Path6, Path7, Path8, Path9}
    151.     public SEDMoveModeStage SEDMoveMode;
    152.     public float SEDPath9Timer;
    153.     int SEDCATRotateSpeed = 5000;
    154.  
    155.     [SerializeField]
    156.     GameObject emptyDummyPrefab; // an alternative solution for robot to follow another object position/rotation when set parent is impossible
    157.     GameObject emptyDummy;
    158.  
    159.     //==============Sword  
    160.     // Three speical issue:
    161.     // 1. Sword attack: prepare sword, move forward, sword hit, where sword hit cannot start from standby, so the RA0, RA1 system wont work
    162.     // 2. Total two weapon dummy: PA0 is the enemy detection dummy, PA1 is the sword hit dummy
    163.     // 3. Robot animation and part animation parelle, RAPAParalle true.
    164.     // (robot take sword and move forward same time is not an option now)
    165.    
    166.     enum MeleeSubMode {Prepare, MoveForward, Attack, Return}
    167.     MeleeSubMode meleeSubMode = MeleeSubMode.Prepare;
    168.    
    169.     // ========Shield
    170.     // check target projectile and standby state
    171.     // Need to start checking after target attack, otherwise robot will end shield animation immediately
    172.    
    173.     enum ShieldSubMode {WaitTargetAttack, Defending}
    174.     ShieldSubMode shieldSubMode = ShieldSubMode.WaitTargetAttack;
    175.  
    176.     // -------------------------------------------
    177.     // this collider list is for projectile physic ignore in weapon management, because projectile can hit robot itself if not ignore
    178.     public List<Collider> robotBodyPartColliderList = new List<Collider>();
    179.    
    180.     public RobotActionMode actionMode = RobotActionMode.Idle;
    181.  
    182.     // assign from enemy weapon effect manager, it decide what melee animation this robot should take when being attacked
    183.     public RobotReactionToAttack robotReactionToAttack =  RobotReactionToAttack.Null;
    184.     enum MeleeReturnSubMode { Setup, Waiting }
    185.     MeleeReturnSubMode meleeReturnSubMode = MeleeReturnSubMode.Setup;
    186.  
    187.     public enum ReactionToAttackSubMode {ReactionAnimation1, ReactionAnimationWaiting1, ReactionAnimation2, ReactionAnimationWaiting2}
    188.     public ReactionToAttackSubMode reactionToAttackSubMode = RobotAI.ReactionToAttackSubMode.ReactionAnimation1;
    189.  
    190.     public int weaponID =0 ; //trace which weapon is attacking now
    191.     public int weaponIDExtraWpR = 99; // if hand have weapon, which weapon it is in the weapon list?
    192.     public int weaponIDExtraWpL = 99; // 99 = not equip
    193.  
    194.     // the projectiles list in the weapon class is not enough for checking
    195.     // for shield defend case. We need to know all projectiles are destoryed before cancel shield defend.
    196.     // the original NoprojectileInscene() cannot check sub-projectile, such as machine gun.
    197.     // The current weapon system work fine, robot cancel animation when projectiles are destoryed.
    198.     // So we dont modifiy it. We add another list that include sub projectiles for defend checking
    199.     public List<Transform> AllProjectilesInScene = new List<Transform>();
    200.     public List<Weapon> weapon = new List<Weapon>();
    201.  
    202.  
    203.     Quaternion deltaRot;
    204.     Vector3 test;
    205.     Vector3 startRot;
    206.     //---------
    207.     void Awake()
    208.     {  
    209.         // assetBundle = GameObject.Find("Canvas").GetComponent<BattleManager>().assetBundle;
    210.  
    211.         catLocalPositionOriginal = catRoot.localPosition;
    212.  
    213.         robotRigidBody = GetComponent<Rigidbody>();    
    214.  
    215.         navAgent = GetComponent<NavMeshAgent>();
    216.                
    217.         IKForeArmL = catRoot.GetComponent<RobotCATStructure>().upperArmL.parent.GetComponent<InverseKinematics>();
    218.         IKForeArmR = catRoot.GetComponent<RobotCATStructure>().upperArmR.parent.GetComponent<InverseKinematics>();
    219.         //  health = Data.robotMaxHealth;
    220.  
    221.     }  
    222.    
    223.     // Import weapon from all robot parts, should only be called by Battle Manager
    224.     public void ImportWeaponData()
    225.     {
    226.         Transform[] bodyParts;
    227.  
    228.         bodyParts = GetComponentsInChildren<Transform>();
    229.  
    230.         // First, generate weapon list
    231.         for (int i = 0; i < bodyParts.Length; i++)
    232.         {
    233.             if (bodyParts[i].GetComponent<RobotBodyPartSpec>() != null && bodyParts[i].GetComponent<RobotBodyPartSpec>().weapon.type!= WeaponType.Null)
    234.             {
    235.                 weapon.Add(bodyParts[i].GetComponent<RobotBodyPartSpec>().weapon);
    236.             }
    237.         }    
    238.  
    239.         // Remove combo weapon part that is not a pair
    240.         for(int i = weapon.Count-1;i>=0 ;i--)
    241.         {
    242.             if (weapon[i].comboRBP != ComboRobotBodyPart.Null && !ComboRBPExist(i))
    243.                 weapon.RemoveAt(i);
    244.  
    245.         }
    246.  
    247.         // sort the list by range
    248.         weapon = weapon.OrderBy(wp => wp.range).ToList();
    249.     }
    250.    
    251.     // Check if the required combo part exist
    252.     // if no, return false; if yes, check if pair exist
    253.     bool ComboRBPExist(int wpID)
    254.     {
    255.         string fal = foreArmL.name.Replace("L", ""); ;
    256.         string far = foreArmR.name.Replace("R", ""); ;
    257.  
    258.         if (weapon[wpID].parentID == ParentID.RobotForeArmL && weapon[wpID].comboRBP.ToString() == far)
    259.             return true;
    260.         else if (weapon[wpID].parentID == ParentID.RobotForeArmR && weapon[wpID].comboRBP.ToString() == fal)
    261.             return true;
    262.         else
    263.             return false;
    264.     }
    265.    
    266.  
    267.  
    268.     // Set physic ignore for each colliders on Robot, for example, upperarm collider wont trigger forearm collider
    269.     public void IgnoreRobotAllColliders()
    270.     {
    271.         for (int k = 0; k < robotBodyPartColliderList.Count; k++)
    272.             for (int i=0; i<robotBodyPartColliderList.Count;i++)
    273.                 Physics.IgnoreCollision(robotBodyPartColliderList[k], robotBodyPartColliderList[i]);
    274.     }
    275.  
    276.     void FixedUpdate()
    277.     {
    278.         Vector3 direction;
    279.         // Standard flow: robot animation -> part animation -> Wait weapon Dummy hit ->  robot animation -> part animation -> Wait weapon Dummy hit -> end
    280.         // RA0 ->PA0 ->RA1 -> PA1 -> End
    281.         // Special Flow: For the case that there are too many little animation clip need to match between part and robot animation, we match the animation in 3DS max, and start both animation same time.
    282.         // So, no matching need to be handled in Unity
    283.  
    284.         switch (actionMode)
    285.         {
    286.             case RobotActionMode.Idle:
    287.  
    288.                 // nav agent should be enable when idle , it may be turn off by melee attack
    289.                 //     if (!navAgent.enabled && Data.playerRobot[robotIndex].map != Map.RBLauncher)
    290.                 //     navAgent.enabled = true;
    291.  
    292.                 // possible bug that running in RA003 loop
    293.                 if (animator.GetCurrentAnimatorStateInfo(0).IsName("RA003") && !animator.GetBool("Idle End"))
    294.                 {
    295.  
    296.                     //   animator.SetTrigger("Idle End");
    297.                 }
    298.  
    299.                 break;
    300.  
    301.             case RobotActionMode.RA0:
    302.  
    303.                 // transform start to move when animation start
    304.                 // or transform start to move when animation Idle start
    305.                 // decide at robotanimationstart()
    306.                 if (meleeMove && !meleeMoveStart)
    307.                 {
    308.                     if (!meleeMoveStartAtIdle && animator.GetCurrentAnimatorStateInfo(0).IsName(weapon[weaponID].RA0.ToString()))
    309.                         meleeMoveStart = true;
    310.                     else if (meleeMoveStartAtIdle && animator.GetCurrentAnimatorStateInfo(0).IsName(robotAnimationIdleClipName))
    311.                         meleeMoveStart = true;
    312.                 }
    313.                 // Fixedupate run faster than animation, so need to make sure animation is idle
    314.  
    315.                 if (meleeMoveStart && !meleeHit)
    316.                 {
    317.                     if (targetCATRoot.position.y > 10)
    318.                         direction = new Vector3(targetCATRoot.position.x, 0, targetCATRoot.position.z) - catRoot.position;
    319.                     else
    320.                         direction = targetCATRoot.position - catRoot.position;
    321.  
    322.                     transform.Translate(direction.normalized * meleeMoveDelta, Space.World);
    323.  
    324.                     // Stop moving
    325.                     if (direction.magnitude < 1)
    326.                     {
    327.                         Destroy(meleeDetectDummy);
    328.                         meleeMoveStart = false;
    329.                         meleeMove = false;
    330.                     }
    331.  
    332.                 }
    333.                 // robot animation finish, now start PartAnimation
    334.                 else if (animator.GetCurrentAnimatorStateInfo(0).IsName(robotAnimationIdleClipName))
    335.                 {
    336.                     meleeMove = false;
    337.                     meleeHit = false;
    338.  
    339.                     // Check for arm IK target
    340.                     SetArmIKTarge(true);
    341.  
    342.                     // 1. PA after RA
    343.                     // 2. No PA after RA
    344.                     // 2a. Melee
    345.                     // 2b. NonMelee
    346.                     if (weapon[weaponID].PA0)
    347.                         RobotBodyPartAnimationTurnOn(weaponID, false);
    348.                     else if (weapon[weaponID].type != WeaponType.SideKick01 && weapon[weaponID].type != WeaponType.Jab)
    349.                     {
    350.                         // 2b.
    351.                         // for rocket punch that do not have PA, need to pass fingers to forearm before firing
    352.                         if (weapon[weaponID].digitsRoot != null)
    353.                             FingersToBodyPartCAT(weaponID);
    354.  
    355.                         RobotBodyPartWeaponEffect(weapon[weaponID].projectile0);
    356.                         actionMode = RobotActionMode.WE0;
    357.                     }
    358.                     else
    359.                     {
    360.                         // 2a.              
    361.                         // Do meleeReturn need for this animation?
    362.                         if (weapon[weaponID].type == WeaponType.Jab || weapon[weaponID].type == WeaponType.SideKick01)
    363.                             actionMode = RobotActionMode.MeleeReturn;
    364.                         else
    365.                         {
    366.                             // RA, and No PA, meleemove stop or hit by melee,
    367.                             // so this part is for melee only
    368.                             weapon[weaponID].projectile0.projectileInScene.Clear();
    369.                             transform.position = meleeDestination;
    370.  
    371.                             // forbid the case that other robot set action mode to reaction, but this robot set itself to idle at the same frame
    372.                             if (actionMode != RobotActionMode.ReactionToAttack)
    373.                             {
    374.                                 ReturnIdle();
    375.                             }
    376.                         }
    377.                     }
    378.                 }
    379.  
    380.  
    381.                 break;
    382.  
    383.             case RobotActionMode.PAS0:
    384.  
    385.                 if (weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAI0"))
    386.                 {
    387.                     RobotBodyPartWeaponEffect(weapon[weaponID].projectile0);
    388.                     actionMode = RobotActionMode.WE0;
    389.                 }
    390.  
    391.                 break;
    392.  
    393.             case RobotActionMode.WE0:
    394.                 // Waiting Weapon Effect Finish
    395.                 // 3 cases:
    396.                 // 1. No RA, No PA, (no need to put in WE1)
    397.                 // 2. No RA, PA
    398.                 // 3. RA, PA
    399.  
    400.                 if (NoWeaponProjectileInScene())
    401.                 {
    402.                     SetArmIKTarge(false);
    403.  
    404.                     // end part animation
    405.                     if (weapon[weaponID].PA0)
    406.                         weapon[weaponID].animator.SetTrigger("PAE0");
    407.  
    408.                     // forbid the case that other robot set action mode to reaction, but this robot set itself to idle at the same frame
    409.                     if (actionMode != RobotActionMode.ReactionToAttack)
    410.                     {
    411.                         if (weapon[weaponID].RA0 != RobotAnimation.Null)
    412.                         {
    413.                             animator.SetTrigger("Idle End"); // end robot animation
    414.                         }
    415.  
    416.                         if (weapon[weaponID].RA1 == RobotAnimation.Null)
    417.                         {
    418.                             ReturnIdle();                          
    419.                         }
    420.                         else
    421.                         {
    422.                             StartRobotAnimation(weapon[weaponID].RA1);
    423.                             actionMode = RobotActionMode.RA1;
    424.                         }
    425.  
    426.                         // Extra Weapon
    427.                         if (weapon[weaponID].extraWeaponSpec != null)
    428.                         {
    429.                             if (weapon[weaponID].parentID == ParentID.RobotHandL || weapon[weaponID].parentID == ParentID.RobotForeArmL)
    430.                             {
    431.                                 ExtraWpLUseCounter++;
    432.                                 if (ExtraWpLUseCounter >= ExtraWpLUseMax)
    433.                                 {
    434.                                     weapon[weaponID].extraWeaponSpec.returnWeapon = true;
    435.                                     // set weapon timer, count start when weapon return                                  
    436.                                     weapon[weaponID].coolDownTimer = Data.currentTurn[(int)Data.currentMap];
    437.                                 }
    438.                             }
    439.                             else if (weapon[weaponID].parentID == ParentID.RobotHandR || weapon[weaponID].parentID == ParentID.RobotForeArmR)
    440.                             {
    441.                                 ExtraWpRUseCounter++;
    442.                                 if (ExtraWpRUseCounter >= ExtraWpRUseMax)
    443.                                 {
    444.                                     weapon[weaponID].extraWeaponSpec.returnWeapon = true;
    445.                                     // set weapon timer, count start when weapon return                                  
    446.                                     weapon[weaponID].coolDownTimer = Data.currentTurn[(int)Data.currentMap];
    447.                                 }
    448.                             }
    449.                         }
    450.  
    451.                     }
    452.                 }
    453.                 break;
    454.  
    455.             case RobotActionMode.RA1:
    456.  
    457.                 // transform start to move when animation start
    458.                 // or transform start to move when animation Idle start
    459.                 if (meleeMove && !meleeMoveStart)
    460.                 {
    461.                     if (!meleeMoveStartAtIdle && animator.GetCurrentAnimatorStateInfo(0).IsName(weapon[weaponID].RA1.ToString()))
    462.                         meleeMoveStart = true;
    463.                     else if (meleeMoveStartAtIdle && animator.GetCurrentAnimatorStateInfo(0).IsName(robotAnimationIdleClipName))
    464.                         meleeMoveStart = true;
    465.                 }
    466.  
    467.                 if (meleeMoveStart && !meleeHit)
    468.                 {
    469.                     if (targetCATRoot.position.y > 10)
    470.                         direction = new Vector3(targetCATRoot.position.x, 0, targetCATRoot.position.z) - catRoot.position;
    471.                     else
    472.                         direction = targetCATRoot.position - catRoot.position;
    473.  
    474.                     transform.Translate(direction.normalized * meleeMoveDelta, Space.World);
    475.  
    476.                     // Stop moving
    477.                     if (direction.magnitude < 1)
    478.                     {
    479.                         Destroy(meleeDetectDummy);
    480.                         meleeMoveStart = false;
    481.                         meleeMove = false;
    482.                     }
    483.  
    484.                 }
    485.                 // robot animation finish, now start PartAnimation
    486.                 else if (animator.GetCurrentAnimatorStateInfo(0).IsName(robotAnimationIdleClipName))
    487.                 {
    488.                     meleeHit = false;
    489.                     meleeMove = false;
    490.  
    491.                     SetArmIKTarge(true);
    492.  
    493.                     // start part animation after hit target
    494.                     // if no part animation, keep moving to target destination
    495.                     if (weapon[weaponID].PA1)
    496.                         RobotBodyPartAnimationTurnOn(weaponID, false);
    497.                     else if (weapon[weaponID].type != WeaponType.SideKick01 && weapon[weaponID].type != WeaponType.Jab)
    498.                     {
    499.                         RobotBodyPartWeaponEffect(weapon[weaponID].projectile1);
    500.                         actionMode = RobotActionMode.WE1;
    501.                     }
    502.                     else
    503.                     {
    504.                         // Do meleeReturn need for this animation?
    505.                         if (weapon[weaponID].type == WeaponType.Jab || weapon[weaponID].type == WeaponType.SideKick01)
    506.                             actionMode = RobotActionMode.MeleeReturn;
    507.                         else
    508.                         {
    509.                             weapon[weaponID].projectile1.projectileInScene.Clear();
    510.                             transform.position = meleeDestination;
    511.  
    512.                             // forbid the case that other robot set action mode to reaction, but this robot set itself to idle at the same frame
    513.                             if (actionMode != RobotActionMode.ReactionToAttack)
    514.                             {
    515.                                 ReturnIdle();                              
    516.                             }
    517.                         }
    518.                     }
    519.                 }
    520.  
    521.                 break;
    522.  
    523.             case RobotActionMode.PAS1:
    524.  
    525.                 if (weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAI1"))
    526.                 {
    527.                     RobotBodyPartWeaponEffect(weapon[weaponID].projectile1);
    528.                     actionMode = RobotActionMode.WE1;
    529.                 }
    530.                 break;
    531.  
    532.             case RobotActionMode.WE1:       // Waiting Weapon Effect Finish
    533.  
    534.                 if (NoWeaponProjectileInScene())
    535.                 {
    536.                     SetArmIKTarge(false);
    537.  
    538.                     if (weapon[weaponID].PA1)
    539.                         weapon[weaponID].animator.SetTrigger("PAE1"); // end part animation
    540.  
    541.                     // forbid the case that other robot set action mode to reaction, but this robot set itself to idle at the same frame
    542.                     if (actionMode != RobotActionMode.ReactionToAttack)
    543.                     {
    544.                         if (weapon[weaponID].RA1 != RobotAnimation.Null)
    545.                             animator.SetTrigger("Idle End"); // end robot animation
    546.  
    547.                         ReturnIdle();                      
    548.                     }
    549.  
    550.                     // Extra Weapon
    551.                     if (weapon[weaponID].extraWeaponSpec != null)
    552.                     {
    553.                         if (weapon[weaponID].parentID == ParentID.RobotHandL || weapon[weaponID].parentID == ParentID.RobotForeArmL)
    554.                         {
    555.                             ExtraWpLUseCounter++;
    556.                             if (ExtraWpLUseCounter >= ExtraWpLUseMax)
    557.                             {
    558.                                 weapon[weaponID].extraWeaponSpec.returnWeapon = true;
    559.                                 // set weapon timer, count start when weapon return                                  
    560.                                 weapon[weaponID].coolDownTimer = Data.currentTurn[(int)Data.currentMap];
    561.                             }
    562.                         }
    563.                         else if (weapon[weaponID].parentID == ParentID.RobotHandR || weapon[weaponID].parentID == ParentID.RobotForeArmR)
    564.                         {
    565.                             ExtraWpRUseCounter++;
    566.                             if (ExtraWpRUseCounter >= ExtraWpRUseMax)
    567.                             {
    568.                                 weapon[weaponID].extraWeaponSpec.returnWeapon = true;
    569.                                 // set weapon timer, count start when weapon return                                  
    570.                                 weapon[weaponID].coolDownTimer = Data.currentTurn[(int)Data.currentMap];
    571.                             }
    572.                         }
    573.                     }
    574.                 }
    575.                 break;
    576.  
    577.             case RobotActionMode.Melee:
    578.  
    579.                 // Enter by WeaponFire()
    580.  
    581.                 // Three speical issue:
    582.                 // 1. Sword attack: prepare sword, move forward, sword hit, where sword hit cannot start from standby, so the RA0, RA1 system wont work
    583.                 // 2. Total two weapon dummy: PA0 is the enemy detection dummy, PA1 is the sword hit dummy
    584.                 // 3. Robot animation and part animation parelle, RAPAParalle true.
    585.                 // (robot take sword and move forward same time is not an option now)
    586.  
    587.                 // Melee mode
    588.                 // 1. PA0/RA0 - > Transform forward -> Hit Enemy, Idle End -> RA0-Return (animation can hit enemy by muzzle1 hit dummy)
    589.                 // 2. PA0 -> PA Idle -> RA0 - RA0 Idle -> Transform forward -> Hit Enemy, Idle End -> RA0-Return (animation can hit enemy by muzzle1 hit dummy)
    590.  
    591.                 // flying knee strike use the sword system
    592.                 switch (meleeSubMode)
    593.                 {
    594.                     case MeleeSubMode.Prepare:
    595.  
    596.                         // RA and PA start by WeaponFire, and now is waiting for RA idle
    597.                         if (animator.GetCurrentAnimatorStateInfo(0).IsName(robotAnimationIdleClipName))
    598.                         {
    599.                             // let robot move inside target agent
    600.                             //     navAgent.enabled = false;
    601.  
    602.                             // create detect dummy
    603.                             RobotBodyPartWeaponEffect(weapon[weaponID].projectile0);
    604.                             meleeSubMode = MeleeSubMode.MoveForward;
    605.  
    606.  
    607.                             //if(weapon[weaponID].animator!=null)
    608.                             //  weapon[weaponID].animator.SetTrigger("PAE0");
    609.                         }
    610.                         break;
    611.  
    612.                     case MeleeSubMode.MoveForward:
    613.  
    614.                         // cancel immediately if target die
    615.                         if (target == null)
    616.                         {
    617.                             if (weapon[weaponID].animator != null)
    618.                                 weapon[weaponID].animator.SetTrigger("PAE0");
    619.  
    620.                             animator.Play(RobotAnimation.StandBy.ToString());
    621.                             meleeSubMode = MeleeSubMode.Prepare;
    622.                             meleeReturnSubMode = MeleeReturnSubMode.Waiting;
    623.                             actionMode = RobotActionMode.MeleeReturn;
    624.                         }
    625.                         // Not hit yet? keep moving to target
    626.                         // detect dummy should be destory by weapon effect manager when hit
    627.                         if (NoWeaponProjectileInScene())
    628.                         {
    629.                             // sword case: sword hit animation do not start from Standby, so it cant use RA1                      
    630.                             // So it will be a problem for sword attack.
    631.                             // sword hit animation is in the same sword attack flow, so we use Idle end to trigger hit animation
    632.                             // also need to create sword hit dummy
    633.  
    634.                             meleeHit = false;
    635.                             animator.applyRootMotion = true;
    636.                             animator.SetTrigger("Idle End"); // start sword hit animation
    637.                             RobotBodyPartWeaponEffect(weapon[weaponID].projectile1);
    638.                             meleeSubMode = MeleeSubMode.Attack;
    639.                         }
    640.                         else
    641.                         {
    642.                             //if (targetCATRoot.position.y > 10)
    643.                             //    direction = new Vector3(targetCATRoot.position.x, 0, targetCATRoot.position.z) - catRoot.position;
    644.                             // else
    645.                             direction = targetCATRoot.position - catRoot.position;
    646.  
    647.                             // Stop moving
    648.                             if (direction.magnitude < 1)
    649.                             {
    650.                                 Debug.Log("error");
    651.                                 actionMode = RobotActionMode.Idle;
    652.                             }
    653.                             else
    654.                                 transform.Translate(direction.normalized * meleeMoveDelta, Space.World);
    655.                         }
    656.                         break;
    657.  
    658.                     case MeleeSubMode.Attack:
    659.  
    660.                         // Waiting Sword hit target
    661.                         // detect dummy should be destory by weapon effect manager when hit
    662.                         if (NoWeaponProjectileInScene() || animator.GetCurrentAnimatorStateInfo(0).IsName(RobotAnimation.StandBy.ToString()))
    663.                         {
    664.                             // Safe point check
    665.                             // for the case that melee attack animation finish, but dummy still not trigger
    666.                             // bug: robot become idle, but weapon dummy in scene not empty
    667.                             if (weapon[weaponID].projectile1.projectileInScene.Count != 0)
    668.                                 CancelProjectileInScene(true);
    669.  
    670.                             if (weapon[weaponID].animator != null)
    671.                                 weapon[weaponID].animator.SetTrigger("PAE0");
    672.  
    673.                             // it is too early to set extra weapon return true here, need to wait the animation return finish
    674.                             // so do it at meleeReturn
    675.                             meleeSubMode = MeleeSubMode.Prepare;
    676.                             meleeReturnSubMode = MeleeReturnSubMode.Waiting;
    677.                             actionMode = RobotActionMode.MeleeReturn;
    678.  
    679.                         }
    680.                         break;
    681.                 }
    682.                 break;
    683.  
    684.             case RobotActionMode.Shield:
    685.  
    686.                 // no projectile, no part animation, Only robot defend animation
    687.                 // wait until all target projectile in scene destoryed
    688.                 // also need to wait target become idle, in case target is still in melee action, but this robot cancel defend animation too early
    689.  
    690.                 switch (shieldSubMode)
    691.                 {
    692.                     case ShieldSubMode.WaitTargetAttack:
    693.                         // wait until target create projectile in scene
    694.                         if (!target.GetComponent<RobotAI>().NoWeaponProjectileInScene())
    695.                             shieldSubMode = ShieldSubMode.Defending;
    696.                         break;
    697.  
    698.                     case ShieldSubMode.Defending:
    699.                         // wait until all projectiles destoryed
    700.                         if (target.GetComponent<RobotAI>().NoAnyProjectileInScene() && target.GetComponent<RobotAI>().animator.GetCurrentAnimatorStateInfo(0).IsName("StandBy"))
    701.                         {
    702.                             // shield on L, so only check L;
    703.                             if (weapon[weaponID].extraWeaponSpec != null)
    704.                             {
    705.                                 ExtraWpLUseCounter++;
    706.                                 if (ExtraWpLUseCounter >= ExtraWpLUseMax)
    707.                                 {
    708.                                     weapon[weaponID].extraWeaponSpec.returnWeapon = true;
    709.  
    710.                                     // set weapon timer, count start when weapon return                                  
    711.                                     weapon[weaponID].coolDownTimer = Data.currentTurn[(int)Data.currentMap];
    712.                                 }
    713.                             }
    714.                             shieldSubMode = ShieldSubMode.WaitTargetAttack;
    715.  
    716.                             currentAnimation = RobotAnimation.Null;
    717.                             animator.SetTrigger("Idle End");
    718.                             actionMode = RobotActionMode.Idle;
    719.  
    720.                             // clear up transform list
    721.                             NoAnyProjectileInScene();
    722.                         }
    723.                         break;
    724.                 }
    725.                 break;
    726.  
    727.             case RobotActionMode.MeleeReturn:
    728.                 // use default "-E" animation in animator controller
    729.                 // but need to control the catRoot, such that it stay on terrain
    730.  
    731.                 switch (meleeReturnSubMode)
    732.                 {
    733.                     case MeleeReturnSubMode.Setup:
    734.  
    735.                         animator.SetTrigger("Idle End");
    736.                         meleeReturnSubMode = MeleeReturnSubMode.Waiting;
    737.  
    738.                         break;
    739.                     case MeleeReturnSubMode.Waiting:
    740.  
    741.  
    742.                         // Now it should be RA008
    743.                         // robot return to ground destination point                      
    744.  
    745.                         // fall on ground
    746.                         if (catRoot.position.y >= 2)
    747.                         {
    748.                             // return animation include attack, if falling start too early, attack will miss.
    749.                             // so wait until standby mode to start falling.
    750.                             if (animator.GetCurrentAnimatorStateInfo(0).IsName("StandBy"))
    751.                                 transform.Translate(Vector3.down * 50 * Time.deltaTime, Space.World);
    752.                         }
    753.                         else
    754.                         {
    755.                             if (catRoot.position.y <= 0)
    756.                                 catRoot.position = new Vector3(catRoot.position.x, 0, catRoot.position.z);
    757.  
    758.                             if (animator.GetCurrentAnimatorStateInfo(0).IsName("StandBy"))
    759.                             {
    760.                                 // for sword (shield do not need meleereturn)
    761.                                 // do not want shield disappear during attack.
    762.                                 if (weapon[weaponID].extraWeaponSpec != null)
    763.                                 {
    764.                                     if (weapon[weaponID].parentID == ParentID.RobotHandL || weapon[weaponID].parentID == ParentID.RobotForeArmL)
    765.                                     {
    766.                                         ExtraWpLUseCounter++;
    767.                                         if (ExtraWpLUseCounter >= ExtraWpLUseMax)
    768.                                         {
    769.                                             weapon[weaponID].extraWeaponSpec.returnWeapon = true;
    770.                                             // set weapon timer, count start when weapon return                                  
    771.                                             weapon[weaponID].coolDownTimer = Data.currentTurn[(int)Data.currentMap];
    772.                                         }
    773.                                     }
    774.                                     else if (weapon[weaponID].parentID == ParentID.RobotHandR || weapon[weaponID].parentID == ParentID.RobotForeArmR)
    775.                                     {
    776.                                         ExtraWpRUseCounter++;
    777.                                         if (ExtraWpRUseCounter >= ExtraWpRUseMax)
    778.                                         {
    779.                                             weapon[weaponID].extraWeaponSpec.returnWeapon = true;
    780.                                             // set weapon timer, count start when weapon return                                  
    781.                                             weapon[weaponID].coolDownTimer = Data.currentTurn[(int)Data.currentMap];
    782.                                         }
    783.                                     }
    784.                                 }
    785.  
    786.                                 ReturnIdle();
    787.                             }
    788.                         }
    789.                         break;
    790.                 }
    791.                 break;
    792.  
    793.             case RobotActionMode.ComboRA:
    794.  
    795.                 robotAnimationIdleClipName = weapon[weaponID].comboRA.ToString() + "-I";
    796.  
    797.                 // start move only if now is the melee animation, the reason is animation clip run slower than fixedupdate
    798.                 if (meleeMove && animator.GetCurrentAnimatorStateInfo(0).IsName(weapon[weaponID].comboRA.ToString()))
    799.                     meleeMoveStart = true;
    800.  
    801.                 // Fixedupate run faster than animation, so need to make sure animation is at the "melee" stage
    802.                 // case 1. punch hit target, punch target back and move to target current hex
    803.                 // case 2. punch hit target, start part animation before punch target back
    804.                 if (meleeMoveStart && !meleeHit)
    805.                 {
    806.                     transform.Translate(transform.forward * meleeMoveDelta, Space.World);
    807.                 }
    808.                 // robot animation finish, now start PartAnimation
    809.                 else if (animator.GetCurrentAnimatorStateInfo(0).IsName(robotAnimationIdleClipName))
    810.                 {
    811.                     meleeMove = false;
    812.                     meleeMoveStart = false;
    813.                     meleeHit = false;
    814.  
    815.                     // start this part and combo part animation after hit target
    816.                     // if no part animation, keep moving to target destination hex location
    817.                     if (weapon[weaponID].PA0)
    818.                     {
    819.                         RobotBodyPartAnimationTurnOn(weaponID, false);
    820.  
    821.                         RobotBodyPartAnimationTurnOn(GetComboWeaponID(), false);
    822.  
    823.                         // override the actionmode declared in RobotBodyPartAnimationTurnOn;
    824.                         actionMode = RobotActionMode.ComboPAS;
    825.                     }
    826.                     else
    827.                     {
    828.                         direction = meleeDestination - transform.position;
    829.  
    830.                         if (direction.magnitude > 1)
    831.                             transform.Translate(transform.forward * meleeMoveDelta, Space.World);
    832.                         else
    833.                         {
    834.                             weapon[weaponID].projectile0.projectileInScene.Clear();
    835.                             weapon[GetComboWeaponID()].projectile0.projectileInScene.Clear();
    836.  
    837.                             transform.position = meleeDestination; // make sure the robot is exactly on the hex center
    838.  
    839.                             // forbid the case that other robot set action mode to reaction, but this robot set itself to idle at the same frame
    840.                             if (actionMode != RobotActionMode.ReactionToAttack)
    841.                             {
    842.                                 ReturnIdle();                              
    843.                             }
    844.                         }
    845.                     }
    846.                 }
    847.                 break;
    848.  
    849.             case RobotActionMode.ComboPAS:
    850.  
    851.                 if (weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAI0") && weapon[GetComboWeaponID()].animator.GetCurrentAnimatorStateInfo(0).IsName("PAI0"))
    852.                 {
    853.                     weapon[weaponID].projectile0.projectileInScene.Clear();
    854.                     weapon[GetComboWeaponID()].projectile0.projectileInScene.Clear();
    855.  
    856.                     RobotBodyPartWeaponEffect(weapon[weaponID].projectile0);
    857.                     RobotBodyPartWeaponEffect(weapon[GetComboWeaponID()].projectile0);
    858.  
    859.                     actionMode = RobotActionMode.ComboWE;
    860.  
    861.                     // Set up Path Node for SED
    862.                     if (weapon[weaponID].type == WeaponType.SuperElectricalDrill)
    863.                     {
    864.                         SEDMoveMode = SEDMoveModeStage.Path1Setup;
    865.                         // Let cut in camera know
    866.                         meleeMoveStart = true;
    867.                         SEDMove();
    868.                     }
    869.                 }
    870.  
    871.                 break;
    872.  
    873.             case RobotActionMode.ComboWE:
    874.  
    875.                 if (weapon[weaponID].type == WeaponType.SuperElectricalDrill)
    876.                 {
    877.                     SEDMove();
    878.                 }
    879.                 else if (NoWeaponProjectileInScene())
    880.                 {
    881.                     weapon[weaponID].animator.SetTrigger("PAE0"); // end part animation
    882.                     weapon[GetComboWeaponID()].animator.SetTrigger("PAE0");
    883.  
    884.                     // forbid the case that other robot set action mode to reaction, but this robot set itself to idle at the same frame
    885.                     if (actionMode != RobotActionMode.ReactionToAttack)
    886.                     {
    887.                         ReturnIdle();                      
    888.                     }
    889.  
    890.                 }
    891.                 break;
    892.  
    893.             case RobotActionMode.Move:
    894.  
    895.                 // Normal Move, Walking or Fly                                              
    896.                 if (Vector3.Distance(destination, transform.position) <= navAgent.stoppingDistance)
    897.                 {
    898.                     animator.SetTrigger("Idle End"); // end walking animation
    899.                     navAgent.velocity = Vector3.zero;
    900.                     navAgent.Stop();
    901.                     currentAnimation = RobotAnimation.Null;
    902.                     actionMode = RobotActionMode.Idle;
    903.  
    904.  
    905.                     break;
    906.                 }
    907.                 // Limit the max distance move
    908.                 if (Vector3.Distance(robotOriginalPosition, transform.position) >= moveDistanceMax)
    909.                 {
    910.                     animator.SetTrigger("Idle End");
    911.                     navAgent.velocity = Vector3.zero;
    912.                     navAgent.Stop();
    913.                     currentAnimation = RobotAnimation.Null;
    914.                     actionMode = RobotActionMode.Idle;
    915.  
    916.                 }
    917.  
    918.                 break;
    919.  
    920.  
    921.             case RobotActionMode.ReactionToAttack:
    922.  
    923.                 // Weapon dummy may still in go home stage and weapon animator in idle stage, need to trigger the idle when dummy at home
    924.                 /*           if (weapon[weaponID].animator!=null)
    925.                            {
    926.                                if (weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAI0") && NoWeaponProjectileInScene())
    927.                                    weapon[weaponID].animator.SetTrigger("PAE0");
    928.                                if (weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAI1") && NoWeaponProjectileInScene())
    929.                                    weapon[weaponID].animator.SetTrigger("PAE1");
    930.                            }
    931.                            */
    932.  
    933.                 // Force aniamtion state to become StandBy and set IK target to null before start the expected reaction animation
    934.                 switch (robotReactionToAttack)
    935.                 {
    936.                     case RobotReactionToAttack.RE_SelfRotating:
    937.  
    938.                         // animation is "Standby"                      
    939.                         SelfRotator(720);
    940.  
    941.                         // Need a way to break loop
    942.                         // if target is idle, it means no anymore attack from target, so break loop
    943.                         if (target.GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    944.                         {
    945.                             ReturnIdle();                    
    946.                         }
    947.                         break;
    948.  
    949.                     case RobotReactionToAttack.RE_JumpBack:
    950.  
    951.                         switch (reactionToAttackSubMode)
    952.                         {
    953.                             case ReactionToAttackSubMode.ReactionAnimation1:
    954.  
    955.                                 // Play reaction animation directly                              
    956.                                 // also clear IK target if any
    957.                                 SetArmIKTarge(false);
    958.                                 animator.Play(robotReactionToAttack.ToString());
    959.                                 reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimationWaiting1;
    960.                                 break;
    961.  
    962.                             case ReactionToAttackSubMode.ReactionAnimationWaiting1:
    963.  
    964.                                 if (animator.GetCurrentAnimatorStateInfo(0).IsName("StandBy"))
    965.                                 {
    966.                                     reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimation1;
    967.  
    968.                                     ReturnIdle();
    969.                                  
    970.                                 }
    971.                                 break;
    972.  
    973.                         }
    974.                         break;
    975.  
    976.                     case RobotReactionToAttack.RE_FallOnGroundFront:
    977.  
    978.                         switch (reactionToAttackSubMode)
    979.                         {
    980.                             case ReactionToAttackSubMode.ReactionAnimation1:
    981.  
    982.                                 SetArmIKTarge(false);
    983.                                 animator.Play(robotReactionToAttack.ToString());
    984.  
    985.                                 reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimationWaiting1;
    986.                                 break;
    987.  
    988.                             case ReactionToAttackSubMode.ReactionAnimationWaiting1:
    989.  
    990.                                 if (animator.GetCurrentAnimatorStateInfo(0).IsName("StandBy"))
    991.                                 {
    992.                                     reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimation1;
    993.                                     ReturnIdle();
    994.                                     /*
    995.                                     currentAnimation = RobotAnimation.Null;
    996.                                     navAgent.enabled = true;                                  
    997.                                     actionMode = RobotActionMode.Idle;
    998.                                     meleeMoveStart = false;
    999.                                     */
    1000.  
    1001.                                 }
    1002.                                 break;
    1003.  
    1004.                         }
    1005.                         break;
    1006.  
    1007.  
    1008.                     case RobotReactionToAttack.RE_PushBack:
    1009.  
    1010.                         switch (reactionToAttackSubMode)
    1011.                         {
    1012.                             case ReactionToAttackSubMode.ReactionAnimation1:
    1013.  
    1014.                                 SetArmIKTarge(false);
    1015.                                 animator.Play(robotReactionToAttack.ToString());
    1016.  
    1017.                                 // Start knock back animation once
    1018.                                 animator.applyRootMotion = true;
    1019.                                 reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimationWaiting1;
    1020.                                 break;
    1021.  
    1022.                             case ReactionToAttackSubMode.ReactionAnimationWaiting1:
    1023.  
    1024.                                 if (animator.GetCurrentAnimatorStateInfo(0).IsName(robotReactionToAttack.ToString() + "-I"))
    1025.                                 {
    1026.                                     // Move robot root transform to destination hex position, shift CAT by delta so it can stay at same point in scene when root transform move
    1027.                                     ReturnIdle();
    1028.                                     /*
    1029.                                     Vector3 delta = catRoot.position - transform.position;
    1030.                                     transform.position = catRoot.position;
    1031.                                     catRoot.position -= delta;
    1032.                                    
    1033.                                     catRoot.localPosition = Vector3.zero;
    1034.                                     catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    1035.                                     transform.LookAt(target);
    1036.  
    1037.                                     animator.SetTrigger("Idle End");                                  
    1038.                                     animator.applyRootMotion = false;
    1039.                                                                        
    1040.                                     reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimation1;
    1041.                                     currentAnimation = RobotAnimation.Null;
    1042.                                     navAgent.enabled = true;
    1043.                                    
    1044.                                     actionMode = RobotActionMode.Idle;
    1045.                                     meleeMoveStart = false;
    1046.                                     */
    1047.                                 }
    1048.                                 break;
    1049.  
    1050.                         }
    1051.                         break;
    1052.  
    1053.                     case RobotReactionToAttack.RE_SEDFull:
    1054.  
    1055.                         switch (reactionToAttackSubMode)
    1056.                         {
    1057.                             case ReactionToAttackSubMode.ReactionAnimation1:
    1058.  
    1059.                                 SetArmIKTarge(false);
    1060.                                 animator.Play(robotReactionToAttack.ToString());
    1061.  
    1062.                                 animator.applyRootMotion = true;
    1063.                                 reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimationWaiting1;
    1064.                                 break;
    1065.  
    1066.                             case ReactionToAttackSubMode.ReactionAnimationWaiting1:
    1067.  
    1068.                                 if (animator.GetCurrentAnimatorStateInfo(0).IsName(robotReactionToAttack.ToString() + "-I"))
    1069.                                 {
    1070.                                     // shift CAT by delta so it can stay at same point in scene when root transform move
    1071.  
    1072.                                     ReturnIdle();
    1073.                                     /*
    1074.                                     Vector3 delta = catRoot.position - transform.position;
    1075.                                     transform.position = catRoot.position;
    1076.                                     catRoot.position -= delta;
    1077.  
    1078.                                     animator.SetTrigger("Idle End");                                
    1079.                                     animator.applyRootMotion = false;                                  
    1080.  
    1081.                                     catRoot.localPosition = Vector3.zero;
    1082.                                     catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    1083.                                     transform.LookAt(target);                                  
    1084.                                     reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimation1;
    1085.                                     currentAnimation = RobotAnimation.Null;
    1086.                                     navAgent.enabled = true;
    1087.                                    
    1088.                                     actionMode = RobotActionMode.Idle;
    1089.                                     meleeMoveStart = false;
    1090.                                     */
    1091.                                 }
    1092.  
    1093.                                 break;
    1094.  
    1095.                         }
    1096.  
    1097.                         break;
    1098.                     case RobotReactionToAttack.RE_SEDHalf:
    1099.  
    1100.                         switch (reactionToAttackSubMode)
    1101.                         {
    1102.                             case ReactionToAttackSubMode.ReactionAnimation1:
    1103.  
    1104.                                 SetArmIKTarge(false);
    1105.                                 animator.Play(robotReactionToAttack.ToString());
    1106.  
    1107.                                 animator.applyRootMotion = true;
    1108.                                 reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimationWaiting1;
    1109.                                 break;
    1110.  
    1111.                             case ReactionToAttackSubMode.ReactionAnimationWaiting1:
    1112.  
    1113.                                 if (animator.GetCurrentAnimatorStateInfo(0).IsName(robotReactionToAttack.ToString() + "-I"))
    1114.                                 {
    1115.                                     ReturnIdle();
    1116.  
    1117.                                     // shift CAT by delta so it can stay at same point in scene when root transform move
    1118.  
    1119.                                     /*
    1120.                                     Vector3 delta = catRoot.position - transform.position;
    1121.                                     transform.position = catRoot.position;
    1122.                                     catRoot.position -= delta;
    1123.  
    1124.                                     animator.SetTrigger("Idle End");
    1125.                                     animator.applyRootMotion = false;
    1126.  
    1127.                                     catRoot.localPosition = Vector3.zero;
    1128.                                     catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    1129.                                     transform.LookAt(target);
    1130.                                     reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimation1;
    1131.                                     currentAnimation = RobotAnimation.Null;
    1132.                                     navAgent.enabled = true;
    1133.                                    
    1134.                                     actionMode = RobotActionMode.Idle;
    1135.                                     meleeMoveStart = false;
    1136.                                     */
    1137.                                 }
    1138.  
    1139.                                 break;
    1140.  
    1141.                         }
    1142.  
    1143.                         break;
    1144.                 }
    1145.                 break;
    1146.  
    1147.             case RobotActionMode.Death:
    1148.  
    1149.                 // 1. trigger by weapon effect maanger when health <0              
    1150.                 // 2. trigger death animation              
    1151.                 // 4. instantiate explosion when death animation idle
    1152.                 // 5. "explosion killer" destory robot when particle effect end
    1153.  
    1154.                 // because animator death is a dead end flow, no problem to trgger idle end many times
    1155.  
    1156.                 switch (deathMode)
    1157.                 {
    1158.                     case DeathMode.Prepare:
    1159.  
    1160.                         animator.Play(RobotAnimation.Death.ToString());
    1161.  
    1162.                         Data.canvas.GetComponent<BattleManager>().RobotDeath(transform);
    1163.  
    1164.                         Data.canvas.GetComponent<BattleManager>().focusCameraTarget = transform;
    1165.  
    1166.                         deathMode = DeathMode.Animation;
    1167.  
    1168.                         break;
    1169.  
    1170.                     case DeathMode.Animation:
    1171.  
    1172.                         if (animator.GetCurrentAnimatorStateInfo(0).IsName(RobotAnimation.Death.ToString() + "-I"))
    1173.                         {
    1174.                             GameObject obj = Instantiate(robotExplosion, chest.position, transform.rotation);
    1175.                             obj.transform.SetParent(transform);
    1176.  
    1177.                             // put explosion in the projectiles, so ui need to wait for this robot die before taking next action
    1178.                             // to solve the null reference death robot problem
    1179.                             // for the case that this robot is killed by non robot turret, target may be null                  
    1180.                             if (target != null)
    1181.                                 target.GetComponent<RobotAI>().AllProjectilesInScene.Add(obj.transform);
    1182.  
    1183.                             deathMode = DeathMode.Explosion;
    1184.                         }
    1185.                         break;
    1186.  
    1187.                     case DeathMode.Explosion:
    1188.                         break;
    1189.                 }
    1190.                 break;
    1191.         }
    1192.     }
    1193.     // Reset all Idle paramter
    1194.     void ReturnIdle()
    1195.     {
    1196.         Vector3 delta = catRoot.position - transform.position;
    1197.         transform.position = catRoot.position;
    1198.         catRoot.position -= delta;
    1199.  
    1200.         catRoot.localPosition = new Vector3(0, 0.3f, 0);
    1201.         catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    1202.         transform.LookAt(target);
    1203.  
    1204.         animator.applyRootMotion = false;
    1205.  
    1206.         actionMode = RobotActionMode.Idle;
    1207.         reactionToAttackSubMode = ReactionToAttackSubMode.ReactionAnimation1;
    1208.         meleeReturnSubMode = MeleeReturnSubMode.Setup;
    1209.         currentAnimation = RobotAnimation.Null;      
    1210.                
    1211.         meleeMoveStart = false;
    1212.         meleeHit = false;
    1213.         meleeMove = false;
    1214.  
    1215.         // both agent turn off when weapon fire
    1216.         // so need to turn them on when attack finish
    1217.         // some attack finish very early and will cause problem if they turn on target agent
    1218.         // and same problem on 1 vs 1, because attack member is 0
    1219.         navAgent.enabled = true;
    1220.        // if (target != null && target.GetComponent<RobotAI>())
    1221.          //   if(target.GetComponent<RobotAI>().actionMode ==  RobotActionMode.Idle)
    1222.            //     target.GetComponent<NavMeshAgent>().enabled = true;
    1223.                
    1224.         // clear up transform list
    1225.         NoAnyProjectileInScene();
    1226.  
    1227.         if (animator.GetCurrentAnimatorStateInfo(0).IsName(robotReactionToAttack.ToString() + "-I"))
    1228.             animator.SetTrigger("Idle End");
    1229.  
    1230.  
    1231.         // clear assist attack bool or end robot attack this turn
    1232.         if (transform.CompareTag(Tag.PlayerRobot.ToString()))
    1233.         {
    1234.             if (Data.playerRobot[robotIndex].thisIsAssistAttack)
    1235.                 Data.playerRobot[robotIndex].thisIsAssistAttack = false;
    1236.             else
    1237.                 Data.playerRobot[robotIndex].attackedThisTurn = true;
    1238.         }
    1239.         else
    1240.         {
    1241.             if (Data.enemyRobot[robotIndex].thisIsAssistAttack)
    1242.                 Data.enemyRobot[robotIndex].thisIsAssistAttack = false;
    1243.             else
    1244.                 Data.enemyRobot[robotIndex].attackedThisTurn = true;
    1245.         }
    1246.  
    1247.     }
    1248.  
    1249.     // 1. Import Default Data from Body Part Prefab
    1250.     // 2. Import Player customerised Data, such as laser color, from Data Center
    1251.     // 3. Also set attackDistance Max/Min value
    1252.  
    1253.  
    1254.     //-----------------------------Attack---------------
    1255.  
    1256.     // 1. Find out all enemy in attack range
    1257.     // 2. Return closet enemy if no enemy in range
    1258.     // 3. Sort enemy list by distance, return closest enemy that LOS ok and weapon available
    1259.     // 4. Move to target in next attack range if no weapon avaiable
    1260.  
    1261.     // Update enemy List, and return the closest as target
    1262.  
    1263.     bool TargetInAttackRange(float d)
    1264.     {
    1265.         if (Vector3.Distance(target.position, transform.position) < d)      
    1266.             return true;
    1267.        
    1268.         else
    1269.             return false;
    1270.  
    1271.  
    1272.     }
    1273.  
    1274.     // Set Move animation, copy path point
    1275.     public void Move(Vector3 point, float stoppingDistance )
    1276.     {
    1277.         actionMode = RobotActionMode.Move;
    1278.         animator.SetBool("RA003", true);      
    1279.         navAgent.Resume();
    1280.         navAgent.destination = point;
    1281.         navAgent.stoppingDistance = stoppingDistance;
    1282.         destination = point;
    1283.         robotOriginalPosition = transform.position;
    1284.     }
    1285.  
    1286.  
    1287.  
    1288.     // Idle mode in RBLauncher
    1289.     public void Idle(bool onOff)
    1290.     {
    1291.         if(onOff)
    1292.             animator.SetTrigger("Idle");
    1293.         else
    1294.             animator.SetTrigger("Idle End");
    1295.     }
    1296.            
    1297.  
    1298.     //-------------- Fire Weapon Section--------------------------------------------------------------
    1299.     // 1. Start CAT animation
    1300.     // 2. When CAT animation enter idle, start body part animation
    1301.     // 3. When body part animation enter idle, generate weapon effect
    1302.     // 4. When weapon effect finish, restart the body part animation
    1303.     // 5. When body part animation finish, restart the CAT animation
    1304.     // 6 PA0 -> RA0 -> WE0 -> PA1 -> RA1  -> WE1
    1305.     // Another Flow for sword:
    1306.     // 1. Sword Prepare Animation, Create enemy detect dummy when Idle
    1307.     // 2. Transform move forward until detect dummy trigger, and create hit dummy
    1308.     // 3. Sword attack Animation, hit dummy trigger when hit target
    1309.     // 4. RA -> transform move -> RA
    1310.    
    1311.     public void WeaponFire(int wID)
    1312.     {
    1313.         targetOriginalPosition = target.position;
    1314.         robotOriginalPosition = transform.position;
    1315.         robotOriginalRotation = transform.rotation;
    1316.  
    1317.         // nav agent, so they wont affect each other
    1318.         if(target.GetComponent<RobotAI>())
    1319.             target.GetComponent<NavMeshAgent>().enabled = false;
    1320.         navAgent.enabled = false;
    1321.  
    1322.         // pid is for identify which body part weapon
    1323.         // Start Robot Animation
    1324.  
    1325.         weaponID = wID;
    1326.         // set weapon timer
    1327.         weapon[weaponID].coolDownTimer = Data.currentTurn[(int)Data.currentMap];
    1328.  
    1329.         // 4 cases:
    1330.         // 1. No RA, No PA, fire weapon
    1331.         // 2. No RA, PA, start part animation
    1332.         // 3. RA, PA, start robot animation
    1333.         // 4. RA, no PA
    1334.         if (weapon[weaponID].type != WeaponType.Null && weapon[weaponID].RA0 == RobotAnimation.Null && !weapon[weaponID].PA0)
    1335.         {
    1336.             //1. No RA, No PA
    1337.             RobotBodyPartWeaponEffect(weapon[weaponID].projectile0);
    1338.             actionMode = RobotActionMode.WE0;
    1339.  
    1340.         }
    1341.         else if (weapon[weaponID].RA0 == RobotAnimation.Null)
    1342.         {
    1343.             // 2. No RA
    1344.             RobotBodyPartAnimationTurnOn(weaponID, false);
    1345.         }
    1346.         else
    1347.         {
    1348.             // 3. RA And ( PA or no PA)
    1349.  
    1350.             // check if this weapon need to change robot animation
    1351.             if (weapon[weaponID].comboRA == RobotAnimation.Null)
    1352.             {              
    1353.                 // RA and PA
    1354.                
    1355.                 StartRobotAnimation(weapon[weaponID].RA0);
    1356.                 actionMode = RobotActionMode.RA0;
    1357.  
    1358.                 // also start part animation if parallel
    1359.                 // So, parellel action mode skip RA0, and go to PA0 directly
    1360.  
    1361.                 // Go to WE0 by default                                      
    1362.                 if (weapon[weaponID].RAPAParalle)
    1363.                     RobotBodyPartAnimationTurnOn(weaponID, false);
    1364.  
    1365.                 //ExtraWpHandRPart is still null, so cannot access useweapon by them                    
    1366.                 // only call extraweapon function when no weapon on hand
    1367.                 // because the extraweapon function is responsible for color change and pass weapon.
    1368.                 // No need to change color and pass weapon when weapon already on hand.
    1369.                 if (weapon[weaponID].extraWeaponSpec != null)
    1370.                     if (!weapon[weaponID].extraWeaponSpec.weaponOnHand)
    1371.                     {
    1372.                         weapon[weaponID].extraWeaponSpec.useWeapon = true;
    1373.                     }
    1374.  
    1375.                     // Change to sword mode, or shield mode
    1376.                     if (weapon[weaponID].type == WeaponType.Sword || weapon[weaponID].type == WeaponType.KneeStrike)
    1377.                     {
    1378.                         actionMode = RobotActionMode.Melee;
    1379.                     }
    1380.                     else if (weapon[weaponID].type == WeaponType.Shield)
    1381.                     {
    1382.                         actionMode = RobotActionMode.Shield;
    1383.                     }
    1384.             }
    1385.             else if (ComboRBPExist())
    1386.             {
    1387.                 // change to combo robot animation and combo mode
    1388.                 StartRobotAnimation(weapon[weaponID].comboRA);
    1389.                 actionMode = RobotActionMode.ComboRA;
    1390.  
    1391.             }
    1392.             else
    1393.             {
    1394.                
    1395.                 // Use default robot animation if not pair
    1396.                 StartRobotAnimation(weapon[weaponID].RA0);
    1397.                 actionMode = RobotActionMode.RA0;
    1398.             }
    1399.  
    1400.         }
    1401.  
    1402.      
    1403.     }
    1404.  
    1405.     // Set Nav agent off here before melee start
    1406.     // Resume on reaction mode
    1407.     void StartRobotAnimation(RobotAnimation rba)
    1408.     {
    1409.         currentAnimation = rba;
    1410.  
    1411.         // animation that require something more
    1412.         // flying knee strike use the sword system
    1413.         switch (rba)
    1414.         {
    1415.             // For some attack that do not start part animation,  we need to create weapon effect dummy for detection before starting the animation
    1416.             // also need to move the robot forward
    1417.             // RA005 is flying punch that do not have part animation
    1418.             case RobotAnimation.RA005:
    1419.                
    1420.                 MeleeDummyGenerator(MeleeDetectDummyLocation.HandR);
    1421.                 meleeDestination = target.position;
    1422.                 meleeMove = true;
    1423.                 meleeMoveStartAtIdle = false;
    1424.                 meleeMoveStart = false;
    1425.                 meleeHit = false;
    1426.  
    1427.                 if (Vector3.Distance(target.position, transform.position) >= 50)
    1428.                     meleeMoveDelta = 1.5f;
    1429.                 else
    1430.                     meleeMoveDelta = 1;        
    1431.  
    1432.                 // disable nav agent, so this robot can enter other nav agent                
    1433.                 //navAgent.enabled = false;
    1434.  
    1435.                 break;
    1436.  
    1437.             // RA007 is super electronic Drill, start at part animation, then follow by robot animation. standard process
    1438.             // so the melee detection dummy will be generated at  RobotBodyPartWeaponEffec
    1439.             case RobotAnimation.RA007:
    1440.                 // disable nav agent, so this robot can fly
    1441.                 //navAgent.enabled = false;
    1442.                 break;
    1443.  
    1444.                 // Kick from sky
    1445.             case RobotAnimation.RA011:
    1446.  
    1447.                 MeleeDummyGenerator(MeleeDetectDummyLocation.FootR);
    1448.                 meleeDestination = target.position;
    1449.                 meleeMove = true;
    1450.                 meleeMoveStartAtIdle = true;              
    1451.                 meleeMoveStart = false;
    1452.                 meleeHit = false;
    1453.  
    1454.                 animator.applyRootMotion = true;
    1455.  
    1456.                 //if (Vector3.Distance(target.position, transform.position) >= 50)
    1457.                    // meleeMoveDelta = f;
    1458.                 //else
    1459.                     meleeMoveDelta = 3;
    1460.  
    1461.                 // disable nav agent, so this robot can jump to sky
    1462.              //   navAgent.enabled = false;
    1463.  
    1464.                 break;
    1465.         }
    1466.  
    1467.         // check fingers
    1468.         // Move fingers to CAT before start animation
    1469.         // because they may not link to CAT due to the interrupt from attack
    1470.         // i.e, robot go to idle mode after reaction mode, but fingers still on foreArm part cat
    1471.         // The problem can be solved by adding a checking point before going to idle, but we put it here because it seems to be easier
    1472.  
    1473.         if (handL.parent != catRoot.GetComponent<RobotCATStructure>().handL || handR.parent != catRoot.GetComponent<RobotCATStructure>().handR)
    1474.                 FingersToRobot(weaponID);
    1475.                
    1476.         if (ExtraWpR == null && ExtraWpL == null)
    1477.         {
    1478.             animator.SetTrigger(rba.ToString());          
    1479.         }
    1480.         else
    1481.         {
    1482.             // Use ex animation instead
    1483.             // there is no RA0EX-I, so keep using original RA0-I for idle checking
    1484.             if (weapon[weaponID].RA0Ex !=  RobotAnimation.Null)
    1485.                 animator.SetTrigger(weapon[weaponID].RA0Ex.ToString());
    1486.             else
    1487.                 animator.SetTrigger(rba.ToString());
    1488.         }
    1489.  
    1490.         robotAnimationIdleClipName = rba.ToString() + "-I";
    1491.     }
    1492.  
    1493.     // Create dummy on Hand or Foot for collision detect
    1494.     void MeleeDummyGenerator(MeleeDetectDummyLocation where)
    1495.     {
    1496.         GameObject obj=null;
    1497.  
    1498.         switch(where)
    1499.         {          
    1500.             case  MeleeDetectDummyLocation.HandR:
    1501.  
    1502.                 obj = Instantiate(meleeHandDetectDummy, transform.position, transform.rotation);
    1503.  
    1504.                 // projectile detail seem not importamt for melee dummy, so just put projectile0 here
    1505.                 obj.GetComponent<WeaponEffectManager>().Init("Robot", transform, target, weapon[weaponID].projectile0);
    1506.  
    1507.                 SetParent(obj.transform, catRoot.GetComponent<RobotCATStructure>().handR);
    1508.  
    1509.                 break;
    1510.  
    1511.             case MeleeDetectDummyLocation.FootR:
    1512.  
    1513.                 obj = Instantiate(meleeKickDetectDummy, transform.position, transform.rotation);
    1514.                 // projectile detail seem not importamt for melee dummy, so just put projectile0 here
    1515.                 obj.GetComponent<WeaponEffectManager>().Init("Robot", transform, target, weapon[weaponID].projectile0);
    1516.  
    1517.                 SetParent(obj.transform, catRoot.GetComponent<RobotCATStructure>().footR);
    1518.  
    1519.                 break;              
    1520.         }
    1521.  
    1522.         // so we can refer it and destroy in RA0,RA1 later
    1523.         meleeDetectDummy = obj;
    1524.     }
    1525.  
    1526.     // Check if the required combo part exist
    1527.     // if no, return false; if yes, check if pair exist
    1528.     bool ComboRBPExist()
    1529.     {
    1530.         string fal = foreArmL.name.Replace("L", ""); ;
    1531.         string far = foreArmR.name.Replace("R", ""); ;
    1532.  
    1533.         if (weapon[weaponID].parentID == ParentID.RobotForeArmL && weapon[weaponID].comboRBP.ToString() == far)
    1534.             return true;
    1535.         else if(weapon[weaponID].parentID == ParentID.RobotForeArmR && weapon[weaponID].comboRBP.ToString() == fal)
    1536.             return true;
    1537.         else
    1538.             return false;
    1539.     }
    1540.  
    1541.     // find out the combo part weapon ID
    1542.     int GetComboWeaponID()
    1543.     {
    1544.         if (weapon[weaponID].parentID == ParentID.RobotForeArmL)
    1545.             for (int i = 0; i < weapon.Count; i++)
    1546.                 if (weapon[i].parentID == ParentID.RobotForeArmR)
    1547.                     return i;
    1548.         if (weapon[weaponID].parentID == ParentID.RobotForeArmR)
    1549.             for (int i = 0; i < weapon.Count; i++)
    1550.                 if (weapon[i].parentID == ParentID.RobotForeArmL)
    1551.                     return i;
    1552.  
    1553.         return 999;
    1554.  
    1555.     }
    1556.    
    1557.     // number = false, robot animation 0; true = robot animation 1
    1558.     public void RobotBodyPartAnimationTurnOn(int wID, bool number)
    1559.     {
    1560.         if (number)
    1561.         {
    1562.             // if (weapon[wID].digitsRoot != null)
    1563.             //   FingersToBodyPartCAT();
    1564.  
    1565.             weapon[wID].animator.SetTrigger("PAS1");
    1566.             actionMode = RobotActionMode.PAS1;
    1567.         }
    1568.         else
    1569.         {          
    1570.             // for the case that pass digits to body part cat before start body part animation          
    1571.             if (weapon[wID].digitsRoot != null)
    1572.                 FingersToBodyPartCAT(wID);
    1573.  
    1574.             weapon[wID].animator.SetTrigger("PAS0");
    1575.             actionMode = RobotActionMode.PAS0;
    1576.          
    1577.         }
    1578.     }
    1579.  
    1580.     // Reponsible for create projectile, laser dummy etc
    1581.     public void RobotBodyPartWeaponEffect(Weapon.Projectile projectile)
    1582.     {
    1583.         GameObject obj = null;
    1584.  
    1585.         // specially for funnel, pick a value for each funnel.
    1586.         // Cannot assign from weaponeffectmanager(on the funnel projectile), because we need to make sure each funnel assigned value is different
    1587.         Vector3[] funnelTargetPositionDeltaList = new Vector3[] { new Vector3(20, 20, 0), new Vector3(20, 20, -20), new Vector3(-20, 20, 0), new Vector3(-20, 20, 20), new Vector3(0, 20, 20) };
    1588.         int funnelCounter = 0;
    1589.         for (int i = 0; i < projectile.projectileMuzzleLocation.Count; i++)
    1590.         {
    1591.             obj = Instantiate(projectile.projecitlePrefab, projectile.projectileMuzzleLocation[i].position, projectile.projectileMuzzleLocation[i].rotation) as GameObject;
    1592.  
    1593.             // Pass Data to WeaponEffectManager
    1594.             obj.GetComponent<WeaponEffectManager>().Init("Robot", transform, target, projectile);
    1595.  
    1596.             switch (weapon[weaponID].type)
    1597.             {
    1598.                 case WeaponType.MachineGun:
    1599.  
    1600.                     obj.transform.parent = projectile.projectileMuzzleLocation[i];
    1601.  
    1602.                     break;
    1603.  
    1604.                 case WeaponType.MeleeTargetDetect:
    1605.  
    1606.                     obj.transform.parent = projectile.projectileMuzzleLocation[i];
    1607.  
    1608.                     break;
    1609.  
    1610.                 case WeaponType.Sword:
    1611.  
    1612.                     obj.transform.parent = projectile.projectileMuzzleLocation[i];
    1613.  
    1614.                     break;
    1615.  
    1616.                 case WeaponType.KneeStrike:
    1617.  
    1618.                     obj.transform.parent = projectile.projectileMuzzleLocation[i];
    1619.  
    1620.                     break;
    1621.  
    1622.                 case WeaponType.Funnel:
    1623.  
    1624.                     obj.GetComponent<WeaponEffectManager>().homePosition = projectile.projectileMuzzleLocation[i];
    1625.  
    1626.                     obj.GetComponent<WeaponEffectManager>().funnelID = i;
    1627.                     obj.GetComponent<WeaponEffectManager>().funnelTargetPositionDelta = funnelTargetPositionDeltaList[funnelCounter];
    1628.                     funnelCounter++;
    1629.                     break;
    1630.  
    1631.                 case WeaponType.RocketPunch:
    1632.  
    1633.                     // Move forearm to rocket dummy
    1634.                     switch (weapon[weaponID].parentID)
    1635.                     {
    1636.                         case ParentID.RobotForeArmR:
    1637.  
    1638.                             obj.GetComponent<WeaponEffectManager>().homePosition = foreArmR.parent;                                                      
    1639.                             foreArmR.parent = obj.transform;
    1640.  
    1641.                             // if rocket punch is provided by attack skill, attach the attack skill transform to rocket punch dummy too
    1642.                             // such that the digits on the dummy palm can also follow the rocket
    1643.                             if (weapon[weaponID].attackSkill)
    1644.                                 weapon[weaponID].thisTransform.parent = obj.transform;
    1645.  
    1646.  
    1647.                             break;
    1648.                         case ParentID.RobotForeArmL:
    1649.  
    1650.                             obj.GetComponent<WeaponEffectManager>().homePosition = foreArmL.parent;
    1651.                             foreArmL.parent = obj.transform;
    1652.  
    1653.                             if (weapon[weaponID].attackSkill)
    1654.                                 weapon[weaponID].thisTransform.parent = obj.transform;
    1655.  
    1656.                             break;
    1657.                     }
    1658.                     break;
    1659.                 case WeaponType.SuperElectricalDrill:
    1660.  
    1661.                     obj.transform.parent = projectile.projectileMuzzleLocation[i];
    1662.  
    1663.                     break;
    1664.  
    1665.                 case WeaponType.Turret:
    1666.  
    1667.                     // turn on turret to fire
    1668.                     // use empty dummy for standard turret, otherwise the projectile count check will stop the robot attack
    1669.                     // and also need a method for NoProjectileInScene checking in WE0 or WE1, we set a destory timer to ensure WE0/1 can end.
    1670.                     // mount the dummy on robot too, otherwise the projectile from turret can trigger collision on the dummy
    1671.  
    1672.                     weapon[weaponID].thisTransform.GetComponent<TurretAI>().fire = true;
    1673.  
    1674.                     // Place the dummy on the body part, not on the muzzle
    1675.                     obj.transform.parent = weapon[weaponID].thisTransform;
    1676.                     obj.transform.localPosition = Vector3.zero;
    1677.  
    1678.                     Destroy(obj, weapon[weaponID].projectile0.projectileKillTime);
    1679.                     break;
    1680.             }
    1681.             projectile.projectileInScene.Add(obj);
    1682.         }
    1683.  
    1684.         // Ingore each other collision
    1685.         for (int i = 0; i < projectile.projectileInScene.Count; i++)
    1686.             for (int k = 0; k < projectile.projectileInScene.Count; k++)              
    1687.                     Physics.IgnoreCollision(projectile.projectileInScene[i].GetComponent<Collider>(), projectile.projectileInScene[k].GetComponent<Collider>());
    1688.        
    1689.     }
    1690.  
    1691.     // Check if all weapon projectile in scene destoryed
    1692.     bool NoWeaponProjectileInScene()
    1693.     {
    1694.         // Remove all "missing" in projectile scene list
    1695.         for(int i=0;i<weapon.Count;i++)
    1696.         {
    1697.             // projectile 0
    1698.             try
    1699.             {
    1700.                 for (int k = weapon[i].projectile0.projectileInScene.Count - 1; k >= 0; k--)
    1701.                     if (weapon[i].projectile0.projectileInScene[k] == null)
    1702.                         weapon[i].projectile0.projectileInScene.RemoveAt(k);
    1703.             }
    1704.             catch (NullReferenceException) { }
    1705.             try
    1706.             {
    1707.                 // projectile 1          
    1708.                 for (int k = weapon[i].projectile1.projectileInScene.Count - 1; k >= 0; k--)
    1709.                     if (weapon[i].projectile1.projectileInScene[k] == null)
    1710.                         weapon[i].projectile1.projectileInScene.RemoveAt(k);
    1711.             }
    1712.             catch (NullReferenceException) { }
    1713.         }
    1714.  
    1715.         // if all list count is 0, return true
    1716.         for (int i = 0; i < weapon.Count; i++)
    1717.         {
    1718.             try {
    1719.                 if (weapon[i].projectile0.projectileInScene.Count != 0)
    1720.                     return false;
    1721.             }
    1722.             catch (NullReferenceException) { }
    1723.             try {
    1724.                 if (weapon[i].projectile1.projectileInScene.Count != 0)
    1725.                     return false;
    1726.             }
    1727.             catch (NullReferenceException) { }
    1728.         }
    1729.  
    1730.         if(NoAnyProjectileInScene())
    1731.             return true;
    1732.  
    1733.         return false;
    1734.     }
    1735.  
    1736.     // include sub projectile check, specially for shield defend
    1737.     bool NoAnyProjectileInScene()
    1738.     {      
    1739.             try
    1740.             {
    1741.                 for (int k = AllProjectilesInScene.Count-1; k >= 0; k--)
    1742.                     if (AllProjectilesInScene[k] == null)
    1743.                         AllProjectilesInScene.RemoveAt(k);
    1744.             }
    1745.             catch (NullReferenceException) { }
    1746.  
    1747.         // if all list count is 0, return true      
    1748.             try
    1749.             {
    1750.                 if (AllProjectilesInScene.Count != 0)
    1751.                     return false;
    1752.             }
    1753.             catch (NullReferenceException) { }      
    1754.  
    1755.         return true;
    1756.  
    1757.     }
    1758.     public void CancelProjectileInScene(bool destroy)
    1759.     {
    1760.         for (int i = 0; i < weapon.Count; i++)
    1761.         {
    1762.             // projectile 0
    1763.             for (int k = weapon[i].projectile0.projectileInScene.Count - 1; k >= 0; k--)
    1764.                 if (weapon[i].projectile0.projectileInScene[k] != null)
    1765.                     if (destroy)
    1766.                         Destroy(weapon[i].projectile0.projectileInScene[k]);
    1767.                     else
    1768.                         weapon[i].projectile0.projectileInScene[k].GetComponent<WeaponEffectManager>().Cancel();
    1769.  
    1770.             weapon[i].projectile0.projectileInScene.Clear();
    1771.  
    1772.             // projectile 1
    1773.             for (int k = weapon[i].projectile1.projectileInScene.Count - 1; k >= 0; k--)
    1774.                 if (weapon[i].projectile1.projectileInScene[k] != null)
    1775.                     if(destroy)
    1776.                         Destroy(weapon[i].projectile1.projectileInScene[k]);
    1777.                     else
    1778.                         weapon[i].projectile1.projectileInScene[k].GetComponent<WeaponEffectManager>().Cancel();
    1779.  
    1780.             weapon[i].projectile1.projectileInScene.Clear();
    1781.         }      
    1782.         // end part animation, but rocket punch should only do part animation when forearm at home, so it will be trigger by rocket punch dummy
    1783.         if (weapon[weaponID].animator != null && weapon[weaponID].type != WeaponType.RocketPunch)
    1784.         {
    1785.             if (weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAS0") || weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAI0"))
    1786.                 weapon[weaponID].animator.SetTrigger("PAE0");          
    1787.             if (weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAS1") || weapon[weaponID].animator.GetCurrentAnimatorStateInfo(0).IsName("PAI1"))
    1788.                 weapon[weaponID].animator.SetTrigger("PAE1");
    1789.         }
    1790.  
    1791.     }
    1792.  
    1793.     // Rotate robot continuously, caused by tornado etc
    1794.     void SelfRotator(int rotateSpeed)
    1795.     {
    1796.         transform.Rotate(transform.up, rotateSpeed * Time.deltaTime);
    1797.     }
    1798.  
    1799.     // move  digits to body part digit root, so digits can follow animation
    1800.     // should call before part animation start
    1801.     public void FingersToBodyPartCAT(int wID)
    1802.     {      
    1803.         switch (weapon[wID].parentID)
    1804.         {
    1805.             case ParentID.RobotForeArmR:
    1806.  
    1807.                 handR.parent = weapon[wID].digitsRoot;
    1808.  
    1809.                 for (int i = 0; i < digitRList.Count; i++)
    1810.                 {                
    1811.                     digitRList[i].parent = weapon[wID].digitsRoot;
    1812.                 }
    1813.  
    1814.                 break;
    1815.             case ParentID.RobotForeArmL:              
    1816.                
    1817.                 handL.parent = weapon[wID].digitsRoot;
    1818.  
    1819.                 for (int i = 0; i < digitLList.Count; i++)
    1820.                 {
    1821.                     digitLList[i].parent = weapon[wID].digitsRoot;
    1822.                 }
    1823.                 break;
    1824.         }
    1825.  
    1826.        
    1827.     }
    1828.      
    1829.     // Return fingers from rocket punch projectile to robot
    1830.     public void FingersToRobot(int wID)
    1831.     {
    1832.         switch (weapon[wID].parentID)
    1833.         {
    1834.             case ParentID.RobotForeArmR:
    1835.  
    1836.                 SetParent(foreArmR, catRoot.GetComponent<RobotCATStructure>().foreArmR);
    1837.                 SetParent(handR, catRoot.GetComponent<RobotCATStructure>().handR);
    1838.  
    1839.                 for (int k = 0; k < digitRList.Count; k++)
    1840.                 {
    1841.                     switch (digitRList[k].name)
    1842.                     {
    1843.                         case "RD00":
    1844.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD00);
    1845.                             break;
    1846.                         case "RD01":
    1847.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD01);
    1848.                             break;
    1849.                         case "RD02":
    1850.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD02);
    1851.                             break;
    1852.  
    1853.                         case "RD10":
    1854.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD10);
    1855.                             break;
    1856.                         case "RD11":
    1857.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD11);
    1858.                             break;
    1859.                         case "RD12":
    1860.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD12);
    1861.                             break;
    1862.  
    1863.                         case "RD20":
    1864.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD20);
    1865.                             break;
    1866.                         case "RD21":
    1867.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD21);
    1868.                             break;
    1869.                         case "RD22":
    1870.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD22);
    1871.                             break;
    1872.  
    1873.                         case "RD30":
    1874.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD30);
    1875.                             break;
    1876.                         case "RD31":
    1877.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD31);
    1878.                             break;
    1879.                         case "RD32":
    1880.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD32);
    1881.                             break;
    1882.  
    1883.                         case "RD40":
    1884.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD40);
    1885.                             break;
    1886.                         case "RD41":
    1887.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD41);
    1888.                             break;
    1889.                         case "RD42":
    1890.                             SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD42);
    1891.                             break;
    1892.                     }
    1893.                 }
    1894.                 return;
    1895.  
    1896.             case ParentID.RobotForeArmL:
    1897.                              
    1898.                 SetParent(foreArmL,catRoot.GetComponent<RobotCATStructure>().foreArmL);
    1899.                 SetParent(handL, catRoot.GetComponent<RobotCATStructure>().handL);
    1900.  
    1901.                 for (int k = 0; k < digitLList.Count; k++)
    1902.                 {                  
    1903.                     switch (digitLList[k].name)
    1904.                     {
    1905.                         case "LD00":
    1906.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD00);
    1907.                             break;
    1908.                         case "LD01":
    1909.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD01);
    1910.                             break;
    1911.                         case "LD02":
    1912.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD02);
    1913.                             break;
    1914.  
    1915.                         case "LD10":
    1916.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD10);
    1917.                             break;
    1918.                         case "LD11":
    1919.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD11);
    1920.                             break;
    1921.                         case "LD12":
    1922.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD12);
    1923.                             break;
    1924.  
    1925.                         case "LD20":
    1926.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD20);
    1927.                             break;
    1928.                         case "LD21":
    1929.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD21);
    1930.                             break;
    1931.                         case "LD22":
    1932.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD22);
    1933.                             break;
    1934.  
    1935.                         case "LD30":
    1936.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD30);
    1937.                             break;
    1938.                         case "LD31":
    1939.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD31);
    1940.                             break;
    1941.                         case "LD32":
    1942.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD32);
    1943.                             break;
    1944.  
    1945.                         case "LD40":
    1946.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD40);
    1947.                             break;
    1948.                         case "LD41":
    1949.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD41);
    1950.                             break;
    1951.                         case "LD42":
    1952.                             SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD42);
    1953.                             break;
    1954.                     }
    1955.                 }
    1956.                 return;          
    1957.         }
    1958.        
    1959.         // If the current weapon is not foreArm, we fix both hand
    1960.  
    1961.         // HandR
    1962.         SetParent(handR, catRoot.GetComponent<RobotCATStructure>().handR);
    1963.  
    1964.         for (int k = 0; k < digitRList.Count; k++)
    1965.         {
    1966.             switch (digitRList[k].name)
    1967.             {
    1968.                 case "RD00":
    1969.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD00);
    1970.                     break;
    1971.                 case "RD01":
    1972.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD01);
    1973.                     break;
    1974.                 case "RD02":
    1975.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD02);
    1976.                     break;
    1977.  
    1978.                 case "RD10":
    1979.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD10);
    1980.                     break;
    1981.                 case "RD11":
    1982.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD11);
    1983.                     break;
    1984.                 case "RD12":
    1985.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD12);
    1986.                     break;
    1987.  
    1988.                 case "RD20":
    1989.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD20);
    1990.                     break;
    1991.                 case "RD21":
    1992.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD21);
    1993.                     break;
    1994.                 case "RD22":
    1995.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD22);
    1996.                     break;
    1997.  
    1998.                 case "RD30":
    1999.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD30);
    2000.                     break;
    2001.                 case "RD31":
    2002.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD31);
    2003.                     break;
    2004.                 case "RD32":
    2005.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD32);
    2006.                     break;
    2007.  
    2008.                 case "RD40":
    2009.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD40);
    2010.                     break;
    2011.                 case "RD41":
    2012.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD41);
    2013.                     break;
    2014.                 case "RD42":
    2015.                     SetParent(digitRList[k], catRoot.GetComponent<RobotCATStructure>().RD42);
    2016.                     break;
    2017.             }
    2018.         }
    2019.  
    2020.         // HandL      
    2021.         SetParent(handL, catRoot.GetComponent<RobotCATStructure>().handL);
    2022.  
    2023.         for (int k = 0; k < digitLList.Count; k++)
    2024.         {
    2025.             switch (digitLList[k].name)
    2026.             {
    2027.                 case "LD00":
    2028.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD00);
    2029.                     break;
    2030.                 case "LD01":
    2031.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD01);
    2032.                     break;
    2033.                 case "LD02":
    2034.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD02);
    2035.                     break;
    2036.  
    2037.                 case "LD10":
    2038.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD10);
    2039.                     break;
    2040.                 case "LD11":
    2041.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD11);
    2042.                     break;
    2043.                 case "LD12":
    2044.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD12);
    2045.                     break;
    2046.  
    2047.                 case "LD20":
    2048.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD20);
    2049.                     break;
    2050.                 case "LD21":
    2051.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD21);
    2052.                     break;
    2053.                 case "LD22":
    2054.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD22);
    2055.                     break;
    2056.  
    2057.                 case "LD30":
    2058.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD30);
    2059.                     break;
    2060.                 case "LD31":
    2061.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD31);
    2062.                     break;
    2063.                 case "LD32":
    2064.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD32);
    2065.                     break;
    2066.  
    2067.                 case "LD40":
    2068.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD40);
    2069.                     break;
    2070.                 case "LD41":
    2071.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD41);
    2072.                     break;
    2073.                 case "LD42":
    2074.                     SetParent(digitLList[k], catRoot.GetComponent<RobotCATStructure>().LD42);
    2075.                     break;
    2076.             }
    2077.         }
    2078.     }
    2079.  
    2080.     // Super Electrical Drill Setup
    2081.     // 1. create SED Move Path Prefab
    2082.     // 2. Set robot parent to SED prefab, so robot can follow
    2083.     // 3. Start SED Move Path Animation  
    2084.  
    2085.     // hit stationary robot: Full process, path1 to path4
    2086.     // hit stationary robot: Half process: path1, path2, path7, path8
    2087.     // hit moving robot, move to target original position: Path1, path2, then Path5(trigger by weapon effect dummy) , Path6
    2088.     // hit statinoary non robot unit: path 1, path 2, 9, 7, 8
    2089.     void SEDMove()
    2090.     {
    2091.         Vector3 direction = Vector3.zero;
    2092.         Quaternion r;
    2093.      
    2094.         switch (SEDMoveMode)
    2095.         {
    2096.             case SEDMoveModeStage.Path1Setup:
    2097.                            
    2098.                 SEDMovePathAnimation = Instantiate(SEDMovePath1Prefab, transform.position, transform.rotation);
    2099.                 transform.parent = SEDMovePathAnimation.transform;
    2100.                 SEDMovePathAnimation.GetComponent<Animator>().SetTrigger("SEDMoveStart");
    2101.                 SEDMoveMode = SEDMoveModeStage.Path1;
    2102.  
    2103.                 break;
    2104.  
    2105.             case SEDMoveModeStage.Path1:
    2106.                
    2107.                 // follow path dummy until idle animation
    2108.                     if (SEDMovePathAnimation.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).IsName("SED-Idle"))
    2109.                     {
    2110.                         transform.parent = null;
    2111.                         Destroy(SEDMovePathAnimation);
    2112.                     SEDMovePathAnimation = null; //missing -> null
    2113.                         SEDMoveMode = SEDMoveModeStage.Path2;
    2114.                     }
    2115.                 catRoot.Rotate(Vector3.up, SEDCATRotateSpeed * Time.deltaTime, Space.Self);
    2116.                 break;
    2117.             case SEDMoveModeStage.Path2:
    2118.  
    2119.                 // weapon dummy hit target, enter stage3
    2120.                 if (NoWeaponProjectileInScene())
    2121.                 {
    2122.                     switch (target.GetComponent<RobotAI>().robotReactionToAttack)
    2123.                     {
    2124.                         case RobotReactionToAttack.RE_SEDFull:
    2125.                             SEDMoveMode = SEDMoveModeStage.Path3Setup;
    2126.                             break;
    2127.                         case RobotReactionToAttack.RE_SEDHalf:
    2128.                             SEDMoveMode = SEDMoveModeStage.Path3Setup;
    2129.                             break;
    2130.                     }
    2131.                 }
    2132.                 else
    2133.                 {
    2134.                     // robot fly to target, no path animation                  
    2135.  
    2136.                     if (target.GetComponent<RobotAI>())
    2137.                         direction = target.GetComponent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().pelvis.position - transform.position;
    2138.                     else if(target.GetComponent<RobotTargetDummy>())
    2139.                         direction = target.GetComponent<RobotTargetDummy>().hitPoint - transform.position;
    2140.  
    2141.                     r = Quaternion.FromToRotation(Vector3.up, direction);
    2142.  
    2143.                     transform.Translate(direction.normalized * 100 * Time.deltaTime, Space.World); //150
    2144.                     transform.rotation = Quaternion.RotateTowards(transform.rotation, r, Time.deltaTime * 200);
    2145.  
    2146.                     catRoot.Rotate(Vector3.up, SEDCATRotateSpeed * Time.deltaTime, Space.Self);
    2147.                 }
    2148.                 break;
    2149.  
    2150.             case SEDMoveModeStage.Path3Setup:
    2151.                
    2152.                 // 1. Adjust robot transform, so the drill can hit the target pelvis
    2153.                 // 2. Create a dummy on target pelvis that robot can follow later
    2154.  
    2155.                 transform.position = target.TransformPoint(new Vector3(0, 13.7f, 28f));
    2156.                 transform.rotation = robotOriginalRotation;
    2157.                 transform.Rotate(Vector3.right, 90, Space.Self);
    2158.  
    2159.                 emptyDummy = Instantiate(emptyDummyPrefab, transform.position, transform.rotation);            
    2160.                 emptyDummy.transform.parent = target.GetComponentInParent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().pelvis;
    2161.                 SEDMoveMode = SEDMoveModeStage.Path3;
    2162.                              
    2163.                 break;
    2164.  
    2165.             case SEDMoveModeStage.Path3:
    2166.  
    2167.                 // follow target animation until height is 30, the peak of the sed reaction animation
    2168.                      
    2169.                 if (emptyDummy.transform.position.y >30 && target.GetComponent<RobotAI>().robotReactionToAttack == RobotReactionToAttack.RE_SEDFull)
    2170.                 {
    2171.                     Destroy(emptyDummy);
    2172.                     emptyDummy = null;
    2173.  
    2174.                     // Let RBA idle end
    2175.                     weapon[weaponID].animator.SetTrigger("PAE0");
    2176.                     weapon[GetComboWeaponID()].animator.SetTrigger("PAE0");
    2177.  
    2178.                     transform.rotation = robotOriginalRotation;
    2179.                     catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    2180.  
    2181.                     // go to RA008 rather than standby
    2182.                     currentAnimation = RobotAnimation.Null;
    2183.                     animator.SetTrigger("Idle End");                  
    2184.                     SEDMoveMode = SEDMoveModeStage.Path4;            
    2185.                     break;
    2186.                 }
    2187.                 // cannot use y position to check, because the robot only mainly rotating at the original position
    2188.                 // angle start at 180 to 100
    2189.                 // another main difference is the meleeDestination which is not the target original position.
    2190.                 else if (Vector3.Angle(transform.forward, Vector3.up) <120 && target.GetComponent<RobotAI>().robotReactionToAttack == RobotReactionToAttack.RE_SEDHalf)
    2191.                 {                  
    2192.                     Destroy(emptyDummy);
    2193.                     emptyDummy = null;
    2194.  
    2195.                     // Let RBA idle end
    2196.                     weapon[weaponID].animator.SetTrigger("PAE0");
    2197.                     weapon[GetComboWeaponID()].animator.SetTrigger("PAE0");
    2198.  
    2199.                     transform.rotation = robotOriginalRotation;
    2200.                     catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    2201.  
    2202.                     // go to RA008 rather than standby
    2203.                     currentAnimation = RobotAnimation.Null;
    2204.                     animator.SetTrigger("Idle End");
    2205.                     SEDMoveMode = SEDMoveModeStage.Path4;
    2206.                     break;
    2207.                 }
    2208.  
    2209.                 // Locked emptyDummy X axis related to Target
    2210.                 // because target pelvis may rotate by animation after Path3 is setup, it will cause emptyDummy shift out of target transform.forward.
    2211.                 // a bit math to make sure emptyDummy is always on target.forward direction
    2212.                 emptyDummy.transform.parent = target;          
    2213.                  emptyDummy.transform.localPosition = new Vector3(0,emptyDummy.transform.localPosition.y, emptyDummy.transform.localPosition.z);          
    2214.                  emptyDummy.transform.parent = target.GetComponentInParent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().pelvis;
    2215.                
    2216.                 transform.position = emptyDummy.transform.position;
    2217.                 transform.LookAt(target.GetComponentInParent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().pelvis);
    2218.                 transform.Rotate(Vector3.right, 90, Space.Self);
    2219.                                
    2220.                 catRoot.Rotate(Vector3.up, SEDCATRotateSpeed * Time.deltaTime, Space.Self);
    2221.                
    2222.                 break;
    2223.  
    2224.             case SEDMoveModeStage.Path4:
    2225.  
    2226.                 // Now it should be RA008
    2227.                 // robot return to ground destination point
    2228.                 direction = meleeDestination - transform.position;
    2229.  
    2230.                 if (direction.magnitude > 1)
    2231.                 {
    2232.                     transform.Translate(direction.normalized * 30 * Time.deltaTime, Space.World);
    2233.  
    2234.                     direction = targetOriginalPosition - robotOriginalPosition;
    2235.                     r = Quaternion.LookRotation(direction, Vector3.up);
    2236.                     transform.rotation = Quaternion.RotateTowards(transform.rotation, robotOriginalRotation, 50*Time.deltaTime);
    2237.                 }
    2238.                 else
    2239.                 {
    2240.                     // applyrootmotion should be false when enter this part
    2241.                     if (animator.applyRootMotion == false)
    2242.                     {                    
    2243.                         // start animation that touch ground
    2244.                         transform.position = meleeDestination;
    2245.                         transform.rotation = robotOriginalRotation;
    2246.                         animator.applyRootMotion = true;
    2247.                         currentAnimation = RobotAnimation.Null;
    2248.                         animator.SetTrigger("Idle End");                      
    2249.                     }
    2250.                     else if (animator.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).IsName("RA008-I"))
    2251.                     {
    2252.                         animator.applyRootMotion = false;
    2253.                         catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    2254.                         catRoot.localPosition = Vector3.zero;
    2255.                         currentAnimation = RobotAnimation.Null;
    2256.                         animator.SetTrigger("Idle End");
    2257.                         navAgent.enabled = true;
    2258.                        
    2259.                         actionMode = RobotActionMode.Idle;
    2260.                         meleeMoveStart = false;
    2261.                     }
    2262.                 }
    2263.                 break;
    2264.  
    2265.             case SEDMoveModeStage.Path5:
    2266.                 // When 2 SED robot hit, continue to move to target original destination top
    2267.  
    2268.                 direction = new Vector3(targetOriginalPosition.x, transform.position.y, targetOriginalPosition.z) - transform.position;
    2269.  
    2270.                 transform.Translate(direction.normalized * 100 * Time.deltaTime, Space.World); //150
    2271.                 catRoot.Rotate(Vector3.up, SEDCATRotateSpeed * Time.deltaTime, Space.Self);
    2272.  
    2273.                 if (direction.magnitude < 5)
    2274.                 {
    2275.                     // weapon dummy cannot be destoryed in OntriggerEnter, because it will trigger robot animation idle end
    2276.                     // so weapon dummy will destory here when robot arrive top of target original destination
    2277.                     CancelProjectileInScene(false);  
    2278.  
    2279.                     // Let RBA idle end
    2280.                     weapon[weaponID].animator.SetTrigger("PAE0");
    2281.                     weapon[GetComboWeaponID()].animator.SetTrigger("PAE0");
    2282.  
    2283.                     transform.rotation = robotOriginalRotation;
    2284.                     catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    2285.  
    2286.                     // go to RA008 rather than standby
    2287.                     currentAnimation = RobotAnimation.Null;
    2288.                     animator.SetTrigger("Idle End");
    2289.                     SEDMoveMode = SEDMoveModeStage.Path6;                  
    2290.                 }
    2291.                 break;
    2292.  
    2293.             case SEDMoveModeStage.Path6:
    2294.  
    2295.                 // Fall to ground same as standard process in Path4
    2296.                 // Now it should be RA008
    2297.                 // robot return to ground destination point
    2298.                 direction = targetOriginalPosition - transform.position;
    2299.  
    2300.                 if (direction.magnitude > 1)
    2301.                 {
    2302.                     transform.Translate(direction.normalized * 30 * Time.deltaTime, Space.World);
    2303.  
    2304.                     direction = targetOriginalPosition - robotOriginalPosition;
    2305.                     r = Quaternion.LookRotation(direction, Vector3.up);
    2306.                     transform.rotation = Quaternion.RotateTowards(transform.rotation, robotOriginalRotation, 50 * Time.deltaTime);
    2307.                 }
    2308.                 else
    2309.                 {
    2310.                     // It should trigger once only and wait until the animation finish, so we use animator root to check                  
    2311.                     if (animator.applyRootMotion == false)
    2312.                     {
    2313.                         // start animation that touch ground
    2314.                         transform.position = meleeDestination;
    2315.                         transform.rotation = robotOriginalRotation;
    2316.                         animator.applyRootMotion = true;
    2317.                         currentAnimation = RobotAnimation.Null;
    2318.                         animator.SetTrigger("Idle End");
    2319.                     }
    2320.                     else if (animator.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).IsName("RA008-I"))
    2321.                     {
    2322.                         animator.applyRootMotion = false;
    2323.                         catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    2324.                         catRoot.localPosition = Vector3.zero;
    2325.                         currentAnimation = RobotAnimation.Null;
    2326.                         animator.SetTrigger("Idle End");
    2327.                         navAgent.enabled = true;
    2328.                        
    2329.                         actionMode = RobotActionMode.Idle;
    2330.                         meleeMoveStart = false;
    2331.                     }
    2332.                 }
    2333.                 break;
    2334.  
    2335.             case SEDMoveModeStage.Path7:
    2336.  
    2337.                 // Rotate robot to original rotation
    2338.  
    2339.                 transform.rotation = Quaternion.RotateTowards(transform.rotation, robotOriginalRotation, Time.deltaTime*100);
    2340.                 catRoot.Rotate(Vector3.up, SEDCATRotateSpeed * Time.deltaTime, Space.Self);
    2341.  
    2342.                 if (Quaternion.Angle(transform.rotation, robotOriginalRotation) < 10)
    2343.                 {
    2344.                     transform.rotation = robotOriginalRotation;
    2345.                     catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    2346.  
    2347.                     // Let RBA idle end
    2348.                     weapon[weaponID].animator.SetTrigger("PAE0");
    2349.                     weapon[GetComboWeaponID()].animator.SetTrigger("PAE0");
    2350.  
    2351.                     //  transform.rotation = robotOriginalRotation;
    2352.                     //   catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    2353.  
    2354.                     // go to RA008 rather than standby
    2355.                     currentAnimation = RobotAnimation.Null;
    2356.                     animator.SetTrigger("Idle End");
    2357.  
    2358.                     SEDMoveMode = SEDMoveModeStage.Path8;
    2359.                 }
    2360.  
    2361.  
    2362.                 break;
    2363.  
    2364.             case SEDMoveModeStage.Path8:
    2365.  
    2366.                 // Now it should be RA008
    2367.                 // Fall to ground same as standard process in Path4, or Path6
    2368.                 // The main difference is the location which is not get from target
    2369.                 // Use vector.down directly, the location do not matter.
    2370.                
    2371.                 if (transform.position.y > 1)
    2372.                 {
    2373.                     transform.Translate(Vector3.down * 30 * Time.deltaTime, Space.World);
    2374.  
    2375.                     direction = targetOriginalPosition - robotOriginalPosition;
    2376.                     r = Quaternion.LookRotation(direction, Vector3.up);
    2377.                     transform.rotation = Quaternion.RotateTowards(transform.rotation, robotOriginalRotation, 20 * Time.deltaTime);
    2378.                 }
    2379.                 else
    2380.                 {
    2381.                     // It should trigger once only and wait until the animation finish, so we use animator root to check                  
    2382.                     if (animator.applyRootMotion == false)
    2383.                     {
    2384.                         // start animation that touch ground
    2385.                      //   transform.position = meleeDestination;
    2386.                         transform.rotation = robotOriginalRotation;
    2387.                         animator.applyRootMotion = true;
    2388.                         currentAnimation = RobotAnimation.Null;
    2389.                         animator.SetTrigger("Idle End");
    2390.                     }
    2391.                     else if (animator.GetComponent<Animator>().GetCurrentAnimatorStateInfo(0).IsName("RA008-I"))
    2392.                     {
    2393.                         animator.applyRootMotion = false;
    2394.                         catRoot.localRotation = Quaternion.Euler(0, 0, 0);
    2395.                         catRoot.localPosition = Vector3.zero;
    2396.                         currentAnimation = RobotAnimation.Null;
    2397.                         animator.SetTrigger("Idle End");
    2398.                         navAgent.enabled = true;
    2399.                        
    2400.                         actionMode = RobotActionMode.Idle;
    2401.                         meleeMoveStart = false;
    2402.                     }
    2403.                 }
    2404.  
    2405.                 break;
    2406.  
    2407.             case SEDMoveModeStage.Path9:
    2408.  
    2409.                 catRoot.Rotate(Vector3.up, SEDCATRotateSpeed * Time.deltaTime, Space.Self);
    2410.  
    2411.                 if (SEDPath9Timer + 0.3  < Time.time)              
    2412.                     SEDMoveMode = SEDMoveModeStage.Path7;                  
    2413.  
    2414.  
    2415.                 break;
    2416.  
    2417.         }
    2418.        
    2419.  
    2420.     }
    2421.  
    2422.     // set forearm Ik target
    2423.     void SetArmIKTarge(bool set)
    2424.     {
    2425.         // To know what weapon should set ik target, the simple method is to have a bool in the weapon class,
    2426.         // another method is to check the robot animation, only animation that point hand to target need to set
    2427.         if (set)
    2428.         {
    2429.             if (currentAnimation == RobotAnimation.RA002L || currentAnimation == RobotAnimation.RA002R
    2430.                 || currentAnimation == RobotAnimation.RA014L || currentAnimation == RobotAnimation.RA014R || currentAnimation == RobotAnimation.RA002RL)
    2431.             {
    2432.                 // if target is robot, need to switch to chest, otherwise arm will point to terrain
    2433.                 if (target.GetComponent<RobotAI>())
    2434.                 {
    2435.                     if (weapon[weaponID].parentID == ParentID.RobotForeArmL || weapon[weaponID].parentID == ParentID.RobotHandL)
    2436.                         IKForeArmL.target = target.GetComponent<RobotAI>().chest;
    2437.                     else if (weapon[weaponID].parentID == ParentID.RobotForeArmR || weapon[weaponID].parentID == ParentID.RobotHandR)
    2438.                         IKForeArmR.target = target.GetComponent<RobotAI>().chest;
    2439.                 }
    2440.                 else
    2441.                 {                  
    2442.                     if (weapon[weaponID].parentID == ParentID.RobotForeArmL || weapon[weaponID].parentID == ParentID.RobotHandL)
    2443.                         IKForeArmL.target = target;
    2444.                     else if (weapon[weaponID].parentID == ParentID.RobotForeArmR || weapon[weaponID].parentID == ParentID.RobotHandR)
    2445.                         IKForeArmR.target = target;
    2446.                 }
    2447.  
    2448.                 // Adjust angle for special case, dont know why hand upside down on some animation    
    2449.                 if (currentAnimation == RobotAnimation.RA014L)
    2450.                     IKForeArmL.forearm_OffsetRotation.x = 0;
    2451.                 else if (currentAnimation == RobotAnimation.RA014R)
    2452.                     IKForeArmR.forearm_OffsetRotation.x = 180;
    2453.             }
    2454.  
    2455.             IKForeArmL.UpdateIK();
    2456.             IKForeArmR.UpdateIK();
    2457.  
    2458.  
    2459.         }
    2460.         else
    2461.         {
    2462.             IKForeArmL.target = null;
    2463.             IKForeArmR.target = null;
    2464.         }
    2465.     }
    2466.  
    2467.     void SetParent(Transform child, Transform parent)
    2468.     {
    2469.    child.position = parent.position;
    2470.    child.rotation = parent.rotation;
    2471.    child.SetParent(parent);
    2472. }
    2473.  
    2474. }
    2475.  
     
  4. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,186
    This is strange. As you said, line 200 of RobotAI isn't creating any MonoBehaviours. What's BattleManager.87, though? Is that perhaps declaring a new RobotAI?
     
  5. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    it is
    Code (CSharp):
    1.  RobotAI currentSelectedRobotAI = new RobotAI();
    Full code:

    Code (CSharp):
    1. using UnityEngine;
    2. using Random = UnityEngine.Random;
    3. using System;
    4. using System.Collections;
    5. using System.Collections.Generic;
    6. using UnityEngine.EventSystems;
    7. using System.IO;
    8. using UnityEngine.UI;
    9. using UnityEngine.AI;
    10. using UnityEngine.SceneManagement;
    11. using System.Linq;
    12. using TMPro;
    13.  
    14. public class BattleManager : MonoBehaviour
    15. {
    16.  
    17.     //------New-------
    18.     bool enemyTurnStart = false;
    19.  
    20.     //----- Assist
    21.     //--------Line sign
    22.     [SerializeField]
    23.     LineRenderer walkLine;
    24.     Vector3 currentRobotDestination;
    25.  
    26.     //-------UI---------
    27.     public Slider HealthBarPrefab;
    28.     public Transform HealthBarGroup;
    29.     [SerializeField]
    30.     GameObject battleMapUI;
    31.  
    32.     public SkillManager skillManager;
    33.  
    34.     [SerializeField]
    35.     Text currentTurnText;
    36.  
    37.     [SerializeField]
    38.     RectTransform optionMenu;
    39.     //---------Enemy Generator--------
    40.     [SerializeField]
    41.     GameObject enemyRobotSpherePrefab;
    42.  
    43.     //------Map---------
    44.     [SerializeField]
    45.     Map map;
    46.     [SerializeField]
    47.     Transform BSLauncher;
    48.     [SerializeField]
    49.     GameObject terrain;
    50.     [SerializeField]
    51.     Transform currentRobotDestinationIcon;
    52.     [SerializeField]
    53.     Transform currentSelectedRoboIcon;
    54.     List<TextMeshPro> iconRangeText = new List<TextMeshPro>();  
    55.  
    56.     [SerializeField]
    57.     Transform robotTargetDummy; // when robot attack battleship etc, battleship.transform.position do not work anymore
    58.  
    59.     [SerializeField]
    60.     GameObject robotCAT;
    61.  
    62.     //-------RobotInfoWindow-----
    63.     [SerializeField]
    64.     RectTransform robotInfoWindow;
    65.     [SerializeField]
    66.     RectTransform mousePointTo;
    67.  
    68.     //--------Facility---------
    69.     [SerializeField]
    70.     List<Transform> RBLauncherPlatform = new List<Transform>();
    71.     [SerializeField]
    72.     RectTransform robotButtonGroup;
    73.  
    74.     // refer to the robots transform
    75.     public List<Transform> playerRobotTransformList = new List<Transform>();
    76.     public List<Transform> enemyRobotTransformList = new List<Transform>();
    77.     // refer to non-robot unit
    78.     public List<Transform> playerNonRobotUnitTransformList = new List<Transform>();
    79.     public List<Transform> enemyNonRobotUnitTransformList = new List<Transform>();
    80.     // healt bar list
    81.     public List<RectTransform> playerRobotHealthBarList = new List<RectTransform>();
    82.     public List<RectTransform> enemyRobotHealthBarList = new List<RectTransform>();
    83.     // Enemy Robot Sphere
    84.     public List<Transform> enemyRobotSphereList = new List<Transform>();
    85.  
    86.     public Transform currentSelectedRobot = null;
    87.     RobotAI currentSelectedRobotAI = new RobotAI();
    88.     Transform assistRobot = null;
    89.     public int currentEnemyRobotIndex;
    90.  
    91.     public int currentSelectedRobotWeaponID;
    92.     public Transform currentSelectedRobotTarget = null;
    93.     public Transform currentSelectedRBLauncher = null;
    94.  
    95.     public enum UIMode { Idle, PlayerTurret, AddEnemy, PlayerRobotMove, WaitingRobotMove, WaitingRobotAttack, PlayerRobotRotate, PlayerRobotAttack, AssistAttack, CameraMoving, RBLauncher, EnemyTurn, RobotInfoWindow };
    96.     public UIMode uiMode;
    97.     enum SubUIMode { Null, RobotFromRBLauncher, WaitingRobotMoveFromLauncher, RobotToRBLauncher, WaitingRobotMoveToLauncher, EnemyMove, WaitingEnemyMove, WaitingEnemyAttack }
    98.     SubUIMode subuiMode;  
    99.     bool addEnemy = true;
    100.  
    101.  
    102.     //Transform cameraTargetPoint = null;
    103.     // public List<Transform> PlayerRobotMovePath = new List<Transform>();
    104.     //  public List<Vector3> PlayerRobotMovePath = new List<Vector3>();
    105.     //  public List<GameObject> PlayerRobotMovePathHighlight = new List<GameObject>();
    106.     // Transform lastHitHex;
    107.     //   Vector3 lastTilePoint;
    108.  
    109.  
    110.     //-------------------
    111.     // Constant section
    112.     const int LOSSphereCastRadius = 5;
    113.     const int LOSSphereCastRadiusOnTurret = 2;
    114.  
    115.     //
    116.     public bool LoadFromResource = true;  
    117.  
    118.     GameObject cat;
    119.     RaycastHit hit;
    120.     //int currentBattleMapID;
    121.  
    122.  
    123.     // Mouse
    124.  
    125.    
    126.     public float firstClickTime, doubleClickTimer;
    127.  
    128.     //--------------Camera------------
    129.     enum CameraMode { Idle, RobotAttackZoomIn, RobotAttackZoomOut, TraceProjectile, LookOn, AddEnemy, PlayerTurret, RobotDeath }
    130.     CameraMode cameraMode;
    131.  
    132.     // Camera Control, adjustable by player in option setting
    133.     const float cameraMoveSpeed = 5, cameraRotateSpeed = 1;
    134.  
    135.     float screenW = Screen.width;
    136.     float screenH = Screen.height;
    137.     float screenAutoScrollLenght;
    138.  
    139.     [SerializeField]
    140.     Transform cameraHolder;
    141.     public Transform mainCamera; // acces by damage text on weapon  effect manager
    142.     public Transform cutInCamera;
    143.     [SerializeField]
    144.     Transform focusCamera;
    145.  
    146.     Transform cutInCameraTarget;
    147.     public Transform focusCameraTarget; // assign by robotai
    148.     // time to delay before disable after target kill, because want to focus until death explosion end, target null check cannot do so
    149.     float focusCameraDelayTimer;
    150.  
    151.  
    152.  
    153.  
    154.     [SerializeField]
    155.     Transform cutInCamerasRoot;
    156.     //float playerTurretCameraTimer;
    157.  
    158.     // First, switch to camera for part animation
    159.     // Second, switch to camera for robot animation
    160.     // Front, Back, Left, Right
    161.     const int FrontUpNear = 0; // chest
    162.     const int FrontMiddleNear = 1; // pelvis
    163.     const int FrontDownNear = 2; // leg
    164.     const int BackNear = 3;
    165.     const int LeftMiddleNear = 4;
    166.     const int RightMiddleNear = 5;
    167.     const int LeftDownNear = 6;
    168.     const int RightDownNear = 7;
    169.     const int BackFar = 8;
    170.     const int LeftBackFar = 9;
    171.     const int RighBackFar = 10;
    172.     const int TopFrontNear = 11;
    173.     const int TopLeftNear = 12;
    174.     const int TopRightNear = 13;
    175.  
    176.     int[] allowCutInCameraChest = { FrontUpNear, LeftMiddleNear, RightMiddleNear };
    177.     int[] allowCutInCameraBack = { BackNear, BackFar };
    178.     int[] allowCutInCameraAbdomen = { FrontMiddleNear, LeftMiddleNear, RightMiddleNear };
    179.     int[] allowCutInCameraPelvis = { FrontMiddleNear, LeftMiddleNear, RightMiddleNear };
    180.  
    181.     int[] allowCutInCameraShoulderL = { TopFrontNear, TopLeftNear, TopRightNear };
    182.     int[] allowCutInCameraShoulderR = { TopFrontNear, TopLeftNear, TopRightNear };
    183.     int[] allowCutInCameraForeArmL = { FrontUpNear, LeftMiddleNear };
    184.     int[] allowCutInCameraForeArmR = { FrontUpNear, RightMiddleNear };
    185.  
    186.     int[] allowCutInCameraCalfL = { LeftDownNear };
    187.     int[] allowCutInCameraCalfR = { RightDownNear };
    188.  
    189.     int[] allowCutInCameraZoomOut = { BackFar, LeftBackFar, RighBackFar };
    190.  
    191.     //----------------------UI----------------------
    192.     //---Mini Map-----
    193.     [SerializeField]
    194.     Transform miniMap;
    195.     [SerializeField]
    196.     GameObject dotEnemyPrefab;
    197.     [SerializeField]
    198.     GameObject dotPlayerPrefab;
    199.     [SerializeField]
    200.     Transform miniMapCamera;
    201.  
    202.     List<GameObject> dotList = new List<GameObject>();
    203.     /*
    204.     //-------Unit Battle Info --------
    205.     [SerializeField] UnitBattleInfo unitBattleInfo = new BattleManager.UnitBattleInfo();
    206.  
    207.     [Serializable]  
    208.     class UnitBattleInfo
    209.     {      
    210.         public TextMeshProUGUI name;
    211.         public TextMeshProUGUI armor;
    212.         public TextMeshProUGUI damage;
    213.         public TextMeshProUGUI range;
    214.  
    215.     }
    216.     */
    217.     public TextMeshProUGUI damageTMPPrefab;
    218.  
    219.     //--------------------testing
    220.     public int starTurn;
    221.     public int currentTurn;
    222.  
    223.     public AssetBundle assetBundle;
    224.  
    225.     void Awake()
    226.     {
    227.         doubleClickTimer = 0.5f;
    228.         screenAutoScrollLenght = 50;
    229.  
    230.         Data.canvas = transform;
    231.         Data.skillManager = skillManager;
    232.  
    233.         // init icon text
    234.         for (int i = 0; i < currentSelectedRoboIcon.childCount; i++)      
    235.             iconRangeText.Add(currentSelectedRoboIcon.GetChild(i).GetComponent<TextMeshPro>());
    236.  
    237.         // Load asset bundle
    238.         string assetBundleFileName = "robotparts";
    239.         string assetBundleFileLocation = System.IO.Path.Combine(Application.streamingAssetsPath, assetBundleFileName);
    240.         //   assetBundle = AssetBundle.LoadFromFile(assetBundleFileLocation);
    241.  
    242.         //  currentBattleMapID = Data.currenBattleMapID;
    243.     }
    244.  
    245.     void Start()
    246.     {
    247.         NewGame();
    248.  
    249.         GameObject obj;
    250.         int transformListID;
    251.  
    252.         Data.currentMap = map;
    253.  
    254.         // Set camera      
    255.         if (Data.cameraPosition != Vector3.zero)
    256.         {
    257.             cameraHolder.position = Data.cameraPosition;
    258.             cameraHolder.rotation = Data.cameraRotation;
    259.             mainCamera.GetComponent<Camera>().orthographicSize = Data.cameraOrthographicSize;
    260.         }
    261.  
    262.  
    263.         //-------------------Load Robot    
    264.  
    265.         for (int i = 0; i < Data.playerRobot.Count; i++)
    266.         {
    267.             // load robot to scene if robot belong to this map
    268.             if (Data.playerRobot[i].map == map)
    269.             {
    270.                 LoadRobot(Data.playerRobot[i], playerRobotTransformList);
    271.  
    272.                 transformListID = playerRobotTransformList.Count - 1;
    273.                 Data.playerRobot[i].transformListID = transformListID;
    274.  
    275.                 playerRobotTransformList[transformListID].GetComponent<RobotAI>().robotIndex = i;
    276.                 LoadColliderToRobotAI(playerRobotTransformList[transformListID]);
    277.                 playerRobotTransformList[transformListID].GetComponent<RobotAI>().IgnoreRobotAllColliders();
    278.                 playerRobotTransformList[transformListID].GetComponent<RobotAI>().ImportWeaponData();
    279.                 playerRobotTransformList[transformListID].GetComponent<RobotAI>().moveDistanceMax = Data.playerRobot[i].moveMaxDistance;
    280.                 playerRobotTransformList[transformListID].tag = Tag.PlayerRobot.ToString();
    281.  
    282.                 playerRobotTransformList[transformListID].position = Data.playerRobot[i].position;
    283.                 playerRobotTransformList[transformListID].rotation = Data.playerRobot[i].rotation;
    284.  
    285.                 playerRobotTransformList[transformListID].name = i.ToString();
    286.  
    287.                 // Idle posture rather than standby if robot is at launcher
    288.                 // also need to turn off nav agent
    289.                 if (Data.playerRobot[i].onRBLauncher)
    290.                 {
    291.                     playerRobotTransformList[transformListID].GetComponent<RobotAI>().Idle(true);
    292.                     playerRobotTransformList[transformListID].GetComponent<NavMeshAgent>().enabled = false;
    293.                 }
    294.  
    295.                 // create health bar
    296.                 obj = Instantiate(HealthBarPrefab, Vector3.zero, transform.rotation).gameObject;
    297.                 obj.SetActive(true);
    298.                 obj.transform.SetParent(HealthBarGroup);
    299.                 playerRobotHealthBarList.Add(obj.GetComponent<RectTransform>());
    300.  
    301.                 // Get extra armor, damage from skill
    302.                 skillManager.Init(Data.playerRobot[i]);
    303.             }
    304.         }
    305.  
    306.  
    307.         for (int i = 0; i < Data.enemyRobot.Count; i++)
    308.         {
    309.             if (Data.enemyRobot[i].map == map)
    310.             {
    311.                 LoadRobot(Data.enemyRobot[i], enemyRobotTransformList);
    312.  
    313.                 transformListID = enemyRobotTransformList.Count - 1;
    314.                 Data.enemyRobot[i].transformListID = transformListID;
    315.  
    316.                 enemyRobotTransformList[transformListID].GetComponent<RobotAI>().robotIndex = i;
    317.                 LoadColliderToRobotAI(enemyRobotTransformList[transformListID]);
    318.                 enemyRobotTransformList[transformListID].GetComponent<RobotAI>().IgnoreRobotAllColliders();
    319.                 enemyRobotTransformList[transformListID].GetComponent<RobotAI>().ImportWeaponData();
    320.                 enemyRobotTransformList[transformListID].GetComponent<RobotAI>().moveDistanceMax = Data.enemyRobot[i].moveMaxDistance;
    321.                 enemyRobotTransformList[transformListID].tag = Tag.EnemyRobot.ToString();
    322.  
    323.                 enemyRobotTransformList[transformListID].position = Data.enemyRobot[i].position;
    324.                 enemyRobotTransformList[transformListID].rotation = Data.enemyRobot[i].rotation;
    325.  
    326.                 // create health bar
    327.                 obj = Instantiate(HealthBarPrefab, Vector3.zero, transform.rotation).gameObject;
    328.                 obj.SetActive(true);
    329.                 obj.transform.SetParent(HealthBarGroup);
    330.                 enemyRobotHealthBarList.Add(obj.GetComponent<RectTransform>());
    331.  
    332.                 // Get extra armor, damage from skill
    333.                 skillManager.Init(Data.enemyRobot[i]);
    334.             }
    335.         }
    336.         // Load Non Robot Unit
    337.  
    338.         for (int i = 0; i < Data.playerNonRobotUnit.Count; i++)
    339.         {
    340.             // load only if unit in the current map
    341.             if (Data.playerNonRobotUnit[i].map == map)
    342.             {
    343.                 obj = Instantiate(Resources.Load(GetResourcesPath(Data.playerNonRobotUnit[i].uniqueID))) as GameObject;
    344.  
    345.                 // if it is stronghold map, battleship should be on the bs launcher
    346.                 if (Data.playerNonRobotUnit[i].type == NonRobotUnitType.BattleShip && map == Map.MainMap)
    347.                 {
    348.                     Data.playerNonRobotUnit[i].position = BSLauncher.GetComponent<FacilityManager>().lift.position;
    349.                     Data.playerNonRobotUnit[i].rotation = BSLauncher.GetComponent<FacilityManager>().lift.rotation;
    350.  
    351.                     // make the battleship mount on lift, and set renderqueue, so it can be visible below terrain
    352.                     obj.transform.parent = BSLauncher.GetComponent<FacilityManager>().lift;
    353.                     BSLauncher.GetComponent<FacilityManager>().SetRenderQueue();
    354.                 }
    355.  
    356.                 obj.transform.position = Data.playerNonRobotUnit[i].position;
    357.                 obj.transform.rotation = Data.playerNonRobotUnit[i].rotation;
    358.  
    359.                 playerNonRobotUnitTransformList.Add(obj.transform);
    360.             }
    361.         }
    362.     }
    363.  
    364.     // Setup Data for new game
    365.     // should be moved to New game button in title later
    366.     void NewGame()
    367.     {
    368.         // only setup data for strongHold battleship
    369.         if (Data.playerNonRobotUnit.Count == 0)
    370.         {
    371.             NonRobotUnit u = new NonRobotUnit();
    372.             u.uniqueID = "BattleShip001";
    373.             u.map = Map.MainMap;
    374.  
    375.             Data.playerNonRobotUnit.Add(u);
    376.         }
    377.  
    378.         // setup Data turn
    379.         for (int i = 0; i < Enum.GetNames(typeof(Map)).Length; i++)
    380.         {
    381.             Data.startTurn.Add(0);
    382.             Data.currentTurn.Add(0);
    383.         }
    384.     }
    385.  
    386.     // Update is called once per frame
    387.     void FixedUpdate()
    388.     {
    389.  
    390.  
    391.         // test
    392.  
    393.         starTurn = Data.startTurn[(int)map];
    394.         currentTurn = Data.currentTurn[(int)map];
    395.  
    396.         //------
    397.         CameraControl();
    398.         FocusCamera();
    399.         ShowHealth();
    400.         MousePointTo();
    401.         MouseClick();
    402.         MiniMap();
    403.         //ShowUnitBattleInfo();
    404.  
    405.         // Task that need to do even mouse not click
    406.         // Player Turn -> enemy Turn -> add enemy - > Player Turret -> repeat
    407.         switch (uiMode)
    408.         {
    409.             case UIMode.PlayerTurret:
    410.  
    411.                 //const float playerTurretCameraTime = 2;
    412.                 // if (Time.time > playerTurretCameraTime + playerTurretCameraTimer)
    413.                 {
    414.                     uiMode = UIMode.Idle;
    415.                     CutInCameraSelector(CameraMode.Idle);
    416.                     Data.currentTurn[(int)Data.currentMap]++;
    417.                 }
    418.                 currentTurnText.text = Data.currentTurn[(int)Data.currentMap].ToString();
    419.  
    420.                 break;
    421.  
    422.             case UIMode.AddEnemy:
    423.                 // This is follow by enemy turn
    424.                 // add enemy every 5 turn
    425.                 // switch to idle mode when the enemy sphere detsory
    426.  
    427.                 if (Data.currentTurn[(int)Data.currentMap] % 1 == 0 && addEnemy)
    428.                 {
    429.                     addEnemy = false;
    430.                     AddEnemyRobot();
    431.                     CutInCameraSelector(CameraMode.AddEnemy);
    432.  
    433.                 }
    434.  
    435.                 // when sphere toucn ground, it will kill and remove itself from sphere list,
    436.                 // so check sphere list count here to make sure no sphere on scene
    437.                 if (enemyRobotSphereList.Count == 0)
    438.                 {
    439.                     addEnemy = true;
    440.  
    441.                     //bool idleMode = true;
    442.  
    443.                     // Let battleship turrets fire
    444.                     for (int i = 0; i < playerNonRobotUnitTransformList.Count; i++)
    445.                         playerNonRobotUnitTransformList[i].GetComponent<NonRobotUnitAI>().fire = true;
    446.  
    447.                     /*
    448.                         for (int k = 0; k < playerNonRobotUnitTransformList[i].GetComponent<NonRobotUnitAI>(). turretList.Count; k++)
    449.                             if (playerNonRobotUnitTransformList[i].GetComponent<NonRobotUnitAI>().turretList[k].GetComponent<TurretAI>().target != null)
    450.                             {
    451.                                 playerNonRobotUnitTransformList[i].GetComponent<NonRobotUnitAI>().fire = true;
    452.                                 idleMode = false;
    453.                             }
    454.                        
    455.                     if (idleMode)
    456.                     {
    457.                         uiMode = UIMode.Idle;
    458.                         CutInCameraSelector(CameraMode.Idle);
    459.                         Data.currentTurn[(int)Data.currentMap]++;                      
    460.                     }
    461.                     else
    462.                     {
    463.                     */
    464.                     uiMode = UIMode.PlayerTurret;
    465.                     //  playerTurretCameraTimer = Time.time;
    466.                     CutInCameraSelector(CameraMode.PlayerTurret);
    467.  
    468.                 }
    469.  
    470.                 break;
    471.  
    472.             case UIMode.Idle:
    473.  
    474.                 // end turn when all player robot finish
    475.                 // also need to check if any enemy robot still in counter attack
    476.                 if (playerRobotTransformList.Count != 0)
    477.                 {
    478.                     enemyTurnStart = true;
    479.                     for (int i = 0; i < playerRobotTransformList.Count; i++)
    480.                     {
    481.                         if (!Data.playerRobot[playerRobotTransformList[i].GetComponent<RobotAI>().robotIndex].attackedThisTurn && playerRobotTransformList[i].GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    482.                         {
    483.                             enemyTurnStart = false;
    484.                             break;
    485.                         }
    486.                     }
    487.                     for (int i = 0; i < enemyRobotTransformList.Count; i++)
    488.                     {
    489.                         if (enemyRobotTransformList[i].GetComponent<RobotAI>().actionMode != RobotActionMode.Idle)
    490.                         {
    491.                             enemyTurnStart = false;
    492.                             break;
    493.                         }
    494.  
    495.                     }
    496.  
    497.                     // start enemy turn if all player robot acted
    498.                     if (enemyTurnStart)
    499.                         EndTurn();
    500.                 }
    501.  
    502.                 break;
    503.  
    504.             case UIMode.EnemyTurn:
    505.  
    506.                 // Two way to exit enemy turn:
    507.                 // 1. enemy index ++ until index >= count              
    508.                 // 2. no enemy in scene or enemy index > = count suddenly due to robot death
    509.                 if (enemyRobotTransformList.Count == 0 || currentEnemyRobotIndex >= enemyRobotTransformList.Count)
    510.                 {
    511.                     int rbIndex;
    512.                     // Reset player robot action bool
    513.                     foreach(Transform rb in playerRobotTransformList)
    514.                     {
    515.                         rbIndex = rb.GetComponent<RobotAI>().robotIndex;
    516.                         Data.playerRobot[rbIndex].movedThisTurn = false;
    517.                         Data.playerRobot[rbIndex].attackedThisTurn = false;
    518.                         skillManager.ArmorRegen(rb);
    519.                     }
    520.                     currentEnemyRobotIndex = 0;
    521.                     uiMode = UIMode.AddEnemy;
    522.                     subuiMode = SubUIMode.Null;
    523.                 }
    524.                 else
    525.                 {
    526.                     switch (subuiMode)
    527.                     {
    528.                         case SubUIMode.EnemyMove:
    529.  
    530.                             AI.StartAI(enemyRobotTransformList[currentEnemyRobotIndex], playerRobotTransformList);
    531.  
    532.                             if (AI.targetSelected != null)
    533.                             {
    534.                                 enemyRobotTransformList[currentEnemyRobotIndex].GetComponent<RobotAI>().Move(AI.destination, 1);
    535.                                 subuiMode = SubUIMode.WaitingEnemyMove;
    536.                             }
    537.                             else
    538.                             {
    539.                                 // if current robot cannot move to target, skip to next robot
    540.                                 currentEnemyRobotIndex++;
    541.                                 if (currentEnemyRobotIndex >= enemyRobotTransformList.Count)
    542.                                 {
    543.                                     int rbIndex;
    544.                                     // Reset player robot action bool
    545.                                     foreach (Transform rb in playerRobotTransformList)
    546.                                     {
    547.                                         rbIndex = rb.GetComponent<RobotAI>().robotIndex;
    548.                                         Data.playerRobot[rbIndex].movedThisTurn = false;
    549.                                         Data.playerRobot[rbIndex].attackedThisTurn = false;
    550.                                         skillManager.ArmorRegen(rb);
    551.                                     }
    552.                                     currentEnemyRobotIndex = 0;
    553.                                     uiMode = UIMode.AddEnemy;
    554.                                     subuiMode = SubUIMode.Null;
    555.                                 }
    556.                             }
    557.                             break;
    558.                         case SubUIMode.WaitingEnemyMove:
    559.  
    560.                             // when this enemy robot is moving while other enemy die, the currentEnemyRobotIndex will be invalid
    561.                             // need to reasgin, now is done at explosion killer when destory robot
    562.                             if (enemyRobotTransformList[currentEnemyRobotIndex].GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    563.                             {
    564.                                 int weaponID = WeaponSelector(enemyRobotTransformList[currentEnemyRobotIndex], AI.targetSelected);
    565.                                 if (weaponID != 99 && enemyRobotTransformList[currentEnemyRobotIndex].GetComponent<RobotAI>().weapon[weaponID].type != WeaponType.Shield)
    566.                                 {
    567.                                     skillManager.Attack(enemyRobotTransformList[currentEnemyRobotIndex], AI.targetSelected);
    568.                                     RobotAttack(enemyRobotTransformList[currentEnemyRobotIndex], AI.targetSelected, weaponID, true);
    569.  
    570.                                     currentSelectedRobot = enemyRobotTransformList[currentEnemyRobotIndex];
    571.                                     CutInCameraSelector(CameraMode.RobotAttackZoomIn);
    572.                                 }
    573.                                 subuiMode = SubUIMode.WaitingEnemyAttack;
    574.                             }
    575.                             break;
    576.  
    577.                         case SubUIMode.WaitingEnemyAttack:
    578.  
    579.                             // process if robot and its target both idle  
    580.                             if (enemyRobotTransformList[currentEnemyRobotIndex].GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    581.                             {
    582.                                 CutInCameraSelector(CameraMode.Idle);
    583.  
    584.                                 if (enemyRobotTransformList[currentEnemyRobotIndex].GetComponent<RobotAI>().target == null || enemyRobotTransformList[currentEnemyRobotIndex].GetComponent<RobotAI>().target.GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    585.                                 {
    586.                                     skillManager.KillEffect(RobotSkill.Taunt, 0);
    587.                                     currentEnemyRobotIndex++;
    588.                                     subuiMode = SubUIMode.EnemyMove;
    589.  
    590.                                     /*
    591.                                     if (currentEnemyRobotIndex >= enemyRobotTransformList.Count)
    592.                                     {
    593.                                         // Reset player robot action bool
    594.                                         for (int i = 0; i < playerRobotTransformList.Count; i++)
    595.                                         {
    596.                                             Data.playerRobot[playerRobotTransformList[i].GetComponent<RobotAI>().robotIndex].movedThisTurn = false;
    597.                                             Data.playerRobot[playerRobotTransformList[i].GetComponent<RobotAI>().robotIndex].attackedThisTurn = false;
    598.                                         }
    599.  
    600.                                         currentEnemyRobotIndex = 0;
    601.                                         uiMode = UIMode.AddEnemy;
    602.                                         subuiMode = SubUIMode.Null;
    603.                                     }
    604.                                     */
    605.                                 }
    606.                             }
    607.                             break;
    608.                     }
    609.                 }
    610.                 break;
    611.  
    612.             case UIMode.PlayerRobotMove:
    613.                 DrawRobotMoveLine();
    614.                 break;
    615.  
    616.             case UIMode.PlayerRobotRotate:
    617.  
    618.                 RotatePlayerRobot();
    619.  
    620.                 break;
    621.  
    622.             case UIMode.WaitingRobotMove:
    623.  
    624.                 switch (subuiMode)
    625.                 {
    626.                     case SubUIMode.Null:
    627.                         // Normal robot move
    628.                         if (currentSelectedRobotAI.actionMode == RobotActionMode.Idle)
    629.                         {
    630.                             Data.playerRobot[currentSelectedRobotAI.robotIndex].movedThisTurn = true;
    631.                             uiMode = UIMode.WaitingRobotAttack;
    632.                         }
    633.                         break;
    634.  
    635.                     case SubUIMode.WaitingRobotMoveFromLauncher:
    636.  
    637.                         // Robot from RBLauncher to Map
    638.                         if (currentSelectedRobotAI.actionMode == RobotActionMode.Idle)
    639.                         {
    640.                             Data.playerRobot[currentSelectedRobotAI.robotIndex].map = Map.MainMap;
    641.  
    642.                             Data.playerRobot[currentSelectedRobotAI.robotIndex].movedThisTurn = true;
    643.  
    644.                             uiMode = UIMode.WaitingRobotAttack;
    645.  
    646.                             currentSelectedRobot.GetComponent<NavMeshAgent>().enabled = true;
    647.  
    648.  
    649.                             currentSelectedRBLauncher.GetComponent<FacilityManager>().resume = true;
    650.                             currentSelectedRBLauncher = null;
    651.  
    652.  
    653.                             subuiMode = SubUIMode.Null;
    654.                         }
    655.                         break;
    656.                     case SubUIMode.RobotToRBLauncher:
    657.  
    658.                         if (currentSelectedRBLauncher.GetComponent<FacilityManager>().idle)
    659.                         {
    660.                             currentSelectedRobotAI.Move(currentRobotDestination, 1);
    661.                             subuiMode = SubUIMode.WaitingRobotMoveToLauncher;
    662.                         }
    663.                         break;
    664.  
    665.                     case SubUIMode.WaitingRobotMoveToLauncher:
    666.  
    667.                         if (currentSelectedRobotAI.actionMode == RobotActionMode.Idle)
    668.                         {
    669.                             // if launch is false, the whole RBLauncher animation finish
    670.                             if (!currentSelectedRBLauncher.GetComponent<FacilityManager>().launch)
    671.                             {
    672.                                 currentSelectedRobot.position = RBLauncherPlatform[Data.playerRobot[currentSelectedRobotAI.robotIndex].RBLauncherPlatformID].position;
    673.                                 currentSelectedRobot.rotation = RBLauncherPlatform[Data.playerRobot[currentSelectedRobotAI.robotIndex].RBLauncherPlatformID].rotation;
    674.                                 currentSelectedRobot.parent = null;
    675.  
    676.  
    677.                                 Data.playerRobot[currentSelectedRobotAI.robotIndex].movedThisTurn = true;
    678.                                 Data.playerRobot[currentSelectedRobotAI.robotIndex].attackedThisTurn = true;
    679.                                 currentSelectedRobotAI.Idle(true);
    680.  
    681.  
    682.                                 currentSelectedRBLauncher = null;
    683.                                 currentSelectedRobot = null;
    684.                                 currentSelectedRobotAI = null;
    685.                                 subuiMode = SubUIMode.Null;
    686.                                 uiMode = UIMode.Idle;
    687.                             }
    688.                             else if (!currentSelectedRBLauncher.GetComponent<FacilityManager>().resume)
    689.                             {
    690.                                 // To Launcher, launch is still true at this stage
    691.                                 // When resume complete, launch will be set to false in FacilityManager, so the above part will be executed
    692.                                 currentSelectedRobot.parent = currentSelectedRBLauncher.GetComponent<FacilityManager>().lift;
    693.                                 currentSelectedRBLauncher.GetComponent<FacilityManager>().resume = true;
    694.  
    695.                                 // Turn off agent, so robot can move to undergroup
    696.                                 Data.playerRobot[currentSelectedRobotAI.robotIndex].onRBLauncher = true;
    697.                                 currentSelectedRobot.GetComponent<NavMeshAgent>().enabled = false;
    698.  
    699.                                 currentSelectedRoboIcon.gameObject.SetActive(false);
    700.                             }
    701.                         }
    702.  
    703.                         break;
    704.                 }
    705.                 break;
    706.  
    707.             case UIMode.PlayerRobotAttack:
    708.  
    709.                 if (currentSelectedRobot == null || currentSelectedRobotAI.actionMode == RobotActionMode.Idle)
    710.                 {
    711.                     // next stage: repeat attack or assist attack
    712.  
    713.                     // Return to Top view main camera
    714.                     CutInCameraSelector(CameraMode.Idle);
    715.  
    716.                     if (currentSelectedRobotAI.repeatAttack > 0)
    717.                     {
    718.                         if (currentSelectedRobotTarget == null)
    719.                             uiMode = UIMode.AssistAttack;
    720.  
    721.                         // wait until target
    722.                         if (currentSelectedRobotTarget.GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    723.                         {
    724.                             currentSelectedRobotAI.repeatAttack--;
    725.                             skillManager.KillEffect(RobotSkill.Repeat_Attack, 0);
    726.  
    727.                             // do not attack if target destroyed
    728.                             if (currentSelectedRobotTarget == null)
    729.                             {
    730.                                 uiMode = UIMode.AssistAttack;
    731.                                 break;
    732.                             }
    733.  
    734.                             if (currentSelectedRobotTarget.CompareTag(Tag.EnemyRobot.ToString()))
    735.                             {
    736.                                 int weaponID = WeaponSelector(currentSelectedRobot, currentSelectedRobotTarget);
    737.                                 // do not use shield attack
    738.                                 if (weaponID != 99 && currentSelectedRobotAI.weapon[weaponID].type != WeaponType.Shield)
    739.                                 {
    740.                                     RobotAttack(currentSelectedRobot, currentSelectedRobotTarget, weaponID, true);
    741.                                     uiMode = UIMode.PlayerRobotAttack;
    742.                                     CutInCameraSelector(CameraMode.RobotAttackZoomIn);
    743.  
    744.                                     //currentSelectedRoboIcon.gameObject.SetActive(false);
    745.                                 }
    746.                             }
    747.                             else if (currentSelectedRobotTarget.CompareTag(Tag.EnemyNonRobotUnit.ToString()))
    748.                             {
    749.                                 /*
    750.                                 // dummy position should be on terrain, so all melee attack will be correct
    751.                                 // hit should be the part that player trying to attack
    752.                                 // rootbody is the unit on scene, not a part
    753.                                 robotTargetDummy.GetComponent<RobotTargetDummy>().hitTransform = hit.transform;
    754.                                 robotTargetDummy.GetComponent<RobotTargetDummy>().hitPoint = hit.point;
    755.                                 robotTargetDummy.GetComponent<RobotTargetDummy>().hitRootTransfrom = hit.transform.root;
    756.                                 robotTargetDummy.position = hit.transform.GetComponent<Collider>().ClosestPointOnBounds(currentSelectedRobot.position);
    757.                                 //   robotTargetDummy.position = new Vector3(hit.point.x, 0, hit.point.z);
    758.                                 */
    759.  
    760.                                 int weaponID = WeaponSelector(currentSelectedRobot, robotTargetDummy);
    761.  
    762.                                 if (weaponID != 99)
    763.                                 {
    764.                                     RobotAttack(currentSelectedRobot, currentSelectedRobotTarget, weaponID, true);
    765.                                     uiMode = UIMode.PlayerRobotAttack;
    766.                                     CutInCameraSelector(CameraMode.RobotAttackZoomIn);
    767.  
    768.                                     //   currentSelectedRoboIcon.gameObject.SetActive(false);
    769.                                 }
    770.                             }
    771.                         }
    772.                     }
    773.                     else
    774.                         uiMode = UIMode.AssistAttack;
    775.                 }
    776.  
    777.                 break;
    778.  
    779.             case UIMode.AssistAttack:
    780.  
    781.                 // Let assist attack member to attack one by one
    782.                 // also check for the case target die
    783.                 if (currentSelectedRobotTarget == null)
    784.                 {
    785.                     currentSelectedRobotAI.assistAttackMember.Clear();
    786.                     uiMode = UIMode.Idle;
    787.                     break;
    788.                 }
    789.  
    790.                 // 1. wait for selected robot idle to start assist process
    791.                 // 2. In the assist process, need to wait for assist robot idle to start next assist robot
    792.                 if (currentSelectedRobotAI.actionMode == RobotActionMode.Idle && currentSelectedRobotTarget.GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    793.                 {
    794.                     if (currentSelectedRobotAI.assistAttackMember.Count == 0)
    795.                     {
    796.                         // wait until assist rb finish attack
    797.                         if (assistRobot == null || assistRobot.GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    798.                             uiMode = UIMode.Idle;
    799.                     }
    800.                     else
    801.                     {
    802.                         //currentSelectedRobot = currentSelectedRobotAI.assistAttackMember[currentSelectedRobotAI.assistAttackMember.Count - 1];
    803.                         int assistRbId = currentSelectedRobotAI.assistAttackMember.Count - 1;
    804.                         assistRobot = currentSelectedRobotAI.assistAttackMember[assistRbId];
    805.  
    806.                         // wait for idle to make sure robot attack one by one
    807.                         if (assistRobot.GetComponent<RobotAI>().actionMode == RobotActionMode.Idle)
    808.                         {
    809.                             int weaponID = WeaponSelector(assistRobot, currentSelectedRobotTarget);
    810.                             if (weaponID != 99)
    811.                             {
    812.                                 RobotAttack(assistRobot, currentSelectedRobotTarget, weaponID, false);
    813.                             }
    814.  
    815.                             skillManager.KillEffect(RobotSkill.Assist_Attack_I, assistRbId);
    816.  
    817.                             currentSelectedRobotAI.assistAttackMember.RemoveAt(assistRbId);
    818.                         }
    819.                     }
    820.                 }
    821.                 break;
    822.  
    823.             case UIMode.RBLauncher:
    824.  
    825.                 switch (subuiMode)
    826.                 {
    827.                     case SubUIMode.RobotFromRBLauncher:
    828.  
    829.                         if (currentSelectedRBLauncher.GetComponent<FacilityManager>().idle)
    830.                         {
    831.                             currentSelectedRobot.parent = null;
    832.                             currentSelectedRobot.position = new Vector3(currentSelectedRobot.position.x, 0, currentSelectedRobot.position.z);
    833.  
    834.                             uiMode = UIMode.PlayerRobotMove;
    835.                             subuiMode = SubUIMode.WaitingRobotMoveFromLauncher; // it will be used for checking when mouse cancel click
    836.  
    837.                             currentSelectedRobot.GetComponent<NavMeshAgent>().enabled = true;
    838.                         }
    839.                         break;
    840.                 }
    841.                 break;
    842.         }
    843.  
    844.     }
    845.  
    846.     // Load robot from Data to scene, and assign the robot transform to player/enemy transform list
    847.     public void LoadRobot(Robot r, List<Transform> robotList)
    848.     {
    849.         string partName;
    850.         GameObject rb, part;
    851.         Material[] materials;
    852.  
    853.         // Create robot CAT
    854.         rb = Instantiate(robotCAT, r.position, r.rotation);
    855.  
    856.         robotList.Add(rb.transform);
    857.  
    858.         for (int i = 0; i < r.partsList.Count; i++)
    859.         {
    860.             partName = r.partsList[i].prefabID;
    861.  
    862.             part = Instantiate(Resources.Load(GetResourcesPath(partName)), r.position, r.rotation) as GameObject;
    863.             part.name = part.name.Replace("(Clone)", "");
    864.  
    865.             if (!partName.Contains("Digit"))
    866.             {
    867.                 part.transform.parent = GetParent(rb.GetComponent<RobotAI>().catRoot, r.partsList[i].parentID);
    868.                 part.transform.localPosition = r.partsList[i].localTransfrom.position;
    869.                 part.transform.localRotation = r.partsList[i].localTransfrom.rotation;
    870.                 part.transform.localScale = r.partsList[i].localTransfrom.scale;
    871.  
    872.                 part.GetComponent<RobotBodyPartSpec>().weapon.thisTransform = part.transform;
    873.  
    874.                 // Remove editor collider from part
    875.                 if (part.GetComponent<ExtraWeaponSpec>() && part.GetComponent<ExtraWeaponSpec>().colliderForEditor != null)
    876.                 {
    877.                     part.GetComponent<ExtraWeaponSpec>().colliderForEditor.SetParent(null);
    878.                     Destroy(part.GetComponent<ExtraWeaponSpec>().colliderForEditor.gameObject);
    879.                     part.GetComponent<ExtraWeaponSpec>().colliderForEditor = null;
    880.                 }
    881.  
    882.                 // set color according to Data
    883.                 for (int k = 0; k < part.GetComponent<RobotBodyPartSpec>().subParts.Count; k++)
    884.                 {
    885.                     materials = part.GetComponent<RobotBodyPartSpec>().subParts[k].GetComponent<Renderer>().materials;
    886.                     for (int j = 0; j < materials.Length; j++)
    887.                     {
    888.                         materials[j].color = r.partsList[i].subPartsColor[k].colorList[j];
    889.                     }
    890.                     Array.Clear(materials, 0, materials.Length);
    891.                 }
    892.  
    893.                 // For Pelvis, set all small parts to their CAT
    894.                 if (part.GetComponent<PelvisDetail>())
    895.                 {
    896.                     SetParent(part.GetComponent<PelvisDetail>().Buttock, rb.GetComponent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().Buttock);
    897.                     SetParent(part.GetComponent<PelvisDetail>().HipR, rb.GetComponent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().HipR);
    898.                     SetParent(part.GetComponent<PelvisDetail>().HipL, rb.GetComponent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().HipL);
    899.                     SetParent(part.GetComponent<PelvisDetail>().InguinaR, rb.GetComponent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().InguinaR);
    900.                     SetParent(part.GetComponent<PelvisDetail>().InguinaL, rb.GetComponent<RobotAI>().catRoot.GetComponent<RobotCATStructure>().InguinaL);
    901.                 }
    902.  
    903.  
    904.                 // assign part to robotAI script
    905.                 // ignore extra weapon part, they are not body part
    906.                 //if (!part.GetComponent<ExtraWeaponSpec>() ||(part.GetComponent<ExtraWeaponSpec>() && part.GetComponent<ExtraWeaponSpec>().bodypart)  && !part.name.Contains("AttackSkill"))
    907.                 if (part.name.Contains("AttackSkill"))
    908.                 { }
    909.                 else if (part.GetComponent<ExtraWeaponSpec>() && !part.GetComponent<ExtraWeaponSpec>().bodypart)
    910.                 { }
    911.                 else
    912.                     switch (r.partsList[i].parentID)
    913.                     {
    914.                         case ParentID.RobotChest:
    915.                             rb.GetComponent<RobotAI>().chest = part.transform;
    916.                             break;
    917.                         case ParentID.RobotBack:
    918.                             rb.GetComponent<RobotAI>().back = part.transform;
    919.                             break;
    920.                         case ParentID.RobotAbdomen:
    921.                             rb.GetComponent<RobotAI>().abdomen = part.transform;
    922.                             break;
    923.                         case ParentID.RobotPelvis:
    924.                             rb.GetComponent<RobotAI>().pelvis = part.transform;
    925.                             break;
    926.  
    927.                         case ParentID.RobotShoulderL:
    928.                             rb.GetComponent<RobotAI>().shoulderL = part.transform;
    929.                             break;
    930.                         case ParentID.RobotShoulderR:
    931.                             rb.GetComponent<RobotAI>().shoulderR = part.transform;
    932.                             break;
    933.                         case ParentID.RobotUpperArmL:
    934.                             rb.GetComponent<RobotAI>().upperArmL = part.transform;
    935.                             break;
    936.                         case ParentID.RobotUpperArmR:
    937.                             rb.GetComponent<RobotAI>().upperArmR = part.transform;
    938.                             break;
    939.                         case ParentID.RobotForeArmL:
    940.                             rb.GetComponent<RobotAI>().foreArmL = part.transform;
    941.                             break;
    942.  
    943.                         case ParentID.RobotForeArmR:
    944.                             rb.GetComponent<RobotAI>().foreArmR = part.transform;
    945.                             break;
    946.  
    947.                         case ParentID.RobotHandL:
    948.                             rb.GetComponent<RobotAI>().handL = part.transform;
    949.                             break;
    950.                         case ParentID.RobotHandR:
    951.                             rb.GetComponent<RobotAI>().handR = part.transform;
    952.                             break;
    953.  
    954.                         case ParentID.RobotCalfL:
    955.                             rb.GetComponent<RobotAI>().calfL = part.transform;
    956.                             break;
    957.                         case ParentID.RobotCalfR:
    958.                             rb.GetComponent<RobotAI>().calfR = part.transform;
    959.                             break;
    960.                         case ParentID.RobotThighL:
    961.                             rb.GetComponent<RobotAI>().thighL = part.transform;
    962.                             break;
    963.                         case ParentID.RobotThighR:
    964.                             rb.GetComponent<RobotAI>().thighR = part.transform;
    965.                             break;
    966.                         case ParentID.RobotFootL:
    967.                             rb.GetComponent<RobotAI>().footL = part.transform;
    968.                             break;
    969.                         case ParentID.RobotFootR:
    970.                             rb.GetComponent<RobotAI>().footR = part.transform;
    971.                             break;
    972.  
    973.                     }
    974.             }
    975.             else
    976.             {
    977.                 // assign digit to CAT one by one
    978.                 for (int k = part.transform.childCount - 1; k >= 0; k--)
    979.                 {
    980.                     // List for rockect punch
    981.                     if (part.transform.GetChild(k).name.Contains("LD"))
    982.                         rb.GetComponent<RobotAI>().digitLList.Add(part.transform.GetChild(k));
    983.                     else
    984.                         rb.GetComponent<RobotAI>().digitRList.Add(part.transform.GetChild(k));
    985.  
    986.                     // Set each digit color to digit root color
    987.                     part.transform.GetChild(k).GetComponent<Renderer>().material.color = r.partsList[i].subPartsColor[0].colorList[0];
    988.  
    989.                     switch (part.transform.GetChild(k).name)
    990.                     {
    991.                         case "LD00":
    992.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD00));
    993.                             break;
    994.                         case "LD01":
    995.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD01));
    996.                             break;
    997.                         case "LD02":
    998.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD02));
    999.                             break;
    1000.  
    1001.                         case "LD10":
    1002.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD10));
    1003.                             break;
    1004.                         case "LD11":
    1005.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD11));
    1006.                             break;
    1007.                         case "LD12":
    1008.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD12));
    1009.                             break;
    1010.  
    1011.                         case "LD20":
    1012.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD20));
    1013.                             break;
    1014.                         case "LD21":
    1015.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD21));
    1016.                             break;
    1017.                         case "LD22":
    1018.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD22));
    1019.                             break;
    1020.  
    1021.                         case "LD30":
    1022.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD30));
    1023.                             break;
    1024.                         case "LD31":
    1025.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD31));
    1026.                             break;
    1027.                         case "LD32":
    1028.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD32));
    1029.                             break;
    1030.  
    1031.                         case "LD40":
    1032.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD40));
    1033.                             break;
    1034.                         case "LD41":
    1035.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD41));
    1036.                             break;
    1037.                         case "LD42":
    1038.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotLD42));
    1039.                             break;
    1040.  
    1041.                         // Right
    1042.  
    1043.                         case "RD00":
    1044.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD00));
    1045.                             break;
    1046.                         case "RD01":
    1047.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD01));
    1048.                             break;
    1049.                         case "RD02":
    1050.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD02));
    1051.                             break;
    1052.  
    1053.                         case "RD10":
    1054.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD10));
    1055.                             break;
    1056.                         case "RD11":
    1057.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD11));
    1058.                             break;
    1059.                         case "RD12":
    1060.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD12));
    1061.                             break;
    1062.  
    1063.                         case "RD20":
    1064.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD20));
    1065.                             break;
    1066.                         case "RD21":
    1067.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD21));
    1068.                             break;
    1069.                         case "RD22":
    1070.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD22));
    1071.                             break;
    1072.  
    1073.                         case "RD30":
    1074.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD30));
    1075.                             break;
    1076.                         case "RD31":
    1077.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD31));
    1078.                             break;
    1079.                         case "RD32":
    1080.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD32));
    1081.                             break;
    1082.  
    1083.                         case "RD40":
    1084.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD40));
    1085.                             break;
    1086.                         case "RD41":
    1087.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD41));
    1088.                             break;
    1089.                         case "RD42":
    1090.                             SetParent(part.transform.GetChild(k), GetParent(rb.GetComponent<RobotAI>().catRoot, ParentID.RobotRD42));
    1091.                             break;
    1092.                     }
    1093.                 }
    1094.  
    1095.                 // destory the transparent palm
    1096.                 Destroy(part);
    1097.  
    1098.             }
    1099.         }
    1100.  
    1101.     }
    1102.  
    1103.     string GetResourcesPath(string partName)
    1104.     {
    1105.         string result = null;
    1106.  
    1107.         if (partName.Contains("Head"))
    1108.             result = "RobotBodyParts/Head/" + partName;
    1109.         else if (partName.Contains("Ear"))
    1110.             result = "RobotBodyParts/Head/" + partName;
    1111.         else if (partName.Contains("Eye"))
    1112.             result = "RobotBodyParts/Head/" + partName;
    1113.         else if (partName.Contains("Helm"))
    1114.             result = "RobotBodyParts/Head/" + partName;
    1115.         else if (partName.Contains("Mouth"))
    1116.             result = "RobotBodyParts/Head/" + partName;
    1117.         else if (partName.Contains("Neck"))
    1118.             result = "RobotBodyParts/Neck/" + partName;
    1119.  
    1120.         else if (partName.Contains("Chest"))
    1121.             result = "RobotBodyParts/Chest/" + partName;
    1122.         else if (partName.Contains("Back"))
    1123.             result = "RobotBodyParts/Back/" + partName;
    1124.         else if (partName.Contains("Abdomen"))
    1125.             result = "RobotBodyParts/Abdomen/" + partName;
    1126.         else if (partName.Contains("Pelvis"))
    1127.             result = "RobotBodyParts/Pelvis/" + partName;
    1128.  
    1129.         else if (partName.Contains("ShoulderL"))
    1130.             result = "RobotBodyParts/ShoulderL/" + partName;
    1131.         else if (partName.Contains("ShoulderR"))
    1132.             result = "RobotBodyParts/ShoulderR/" + partName;
    1133.         else if (partName.Contains("UpperArmL"))
    1134.             result = "RobotBodyParts/UpperArmL/" + partName;
    1135.         else if (partName.Contains("UpperArmR"))
    1136.             result = "RobotBodyParts/UpperArmR/" + partName;
    1137.         else if (partName.Contains("ForeArmL"))
    1138.             result = "RobotBodyParts/ForeArmL/" + partName;
    1139.         else if (partName.Contains("ForeArmR"))
    1140.             result = "RobotBodyParts/ForeArmR/" + partName;
    1141.         else if (partName.Contains("HandL"))
    1142.             result = "RobotBodyParts/HandL/" + partName;
    1143.         else if (partName.Contains("HandR"))
    1144.             result = "RobotBodyParts/HandR/" + partName;
    1145.  
    1146.         else if (partName.Contains("DigitR"))
    1147.             result = "RobotBodyParts/HandR/" + partName;
    1148.         else if (partName.Contains("DigitL"))
    1149.             result = "RobotBodyParts/HandL/" + partName;
    1150.  
    1151.         else if (partName.Contains("CalfR"))
    1152.             result = "RobotBodyParts/CalfR/" + partName;
    1153.         else if (partName.Contains("CalfL"))
    1154.             result = "RobotBodyParts/CalfL/" + partName;
    1155.         else if (partName.Contains("ThighL"))
    1156.             result = "RobotBodyParts/ThighL/" + partName;
    1157.         else if (partName.Contains("ThighR"))
    1158.             result = "RobotBodyParts/ThighR/" + partName;
    1159.         else if (partName.Contains("FootL"))
    1160.             result = "RobotBodyParts/FootL/" + partName;
    1161.         else if (partName.Contains("FootR"))
    1162.             result = "RobotBodyParts/FootR/" + partName;
    1163.         else if (partName.Contains("BattleShip"))
    1164.             result = "NonRobotUnit/" + partName;
    1165.         else if (partName.Contains("ExtraWeapon"))
    1166.             result = "ExtraWeapon/" + partName;
    1167.         else if (partName.Contains("AttackSkill"))
    1168.             result = "AttackSkill/" + partName;
    1169.  
    1170.         return result;
    1171.         /*
    1172.         string[] path;
    1173.         path = Directory.GetFiles(Application.dataPath, partName + ".prefab", SearchOption.AllDirectories);
    1174.  
    1175.         path[0] = path[0].Replace(Application.dataPath, "");
    1176.         path[0] = path[0].Replace(".prefab", "");
    1177.         path[0] = path[0].Replace(@"\", "/");
    1178.         path[0] = path[0].Replace("/Resources/", "");
    1179.         return path[0];
    1180.         */
    1181.     }
    1182.  
    1183.     // Get the robot CAT transform structure by ParentID
    1184.     Transform GetParent(Transform rbCAT, ParentID parentID)
    1185.     {
    1186.         // Find parent, ie. bone, of this part
    1187.         switch (parentID)
    1188.         {
    1189.             case ParentID.RobotHead:
    1190.                 return rbCAT.GetComponent<RobotCATStructure>().head;
    1191.  
    1192.             case ParentID.RobotNeck:
    1193.                 return rbCAT.GetComponent<RobotCATStructure>().neck;
    1194.  
    1195.             case ParentID.RobotChest:
    1196.                 return rbCAT.GetComponent<RobotCATStructure>().chest;
    1197.  
    1198.             case ParentID.RobotBack:
    1199.                 return rbCAT.GetComponent<RobotCATStructure>().back;
    1200.  
    1201.             case ParentID.RobotAbdomen:
    1202.                 return rbCAT.GetComponent<RobotCATStructure>().abdomen;
    1203.  
    1204.             case ParentID.RobotPelvis:
    1205.                 return rbCAT.GetComponent<RobotCATStructure>().pelvis;
    1206.  
    1207.             case ParentID.RobotShoulderL:
    1208.                 return rbCAT.GetComponent<RobotCATStructure>().shoulderL;
    1209.  
    1210.             case ParentID.RobotShoulderR:
    1211.                 return rbCAT.GetComponent<RobotCATStructure>().shoulderR;
    1212.  
    1213.             case ParentID.RobotUpperArmL:
    1214.                 return rbCAT.GetComponent<RobotCATStructure>().upperArmL;
    1215.  
    1216.             case ParentID.RobotUpperArmR:
    1217.                 return rbCAT.GetComponent<RobotCATStructure>().upperArmR;
    1218.  
    1219.             case ParentID.RobotForeArmL:
    1220.                 return rbCAT.GetComponent<RobotCATStructure>().foreArmL;
    1221.  
    1222.             case ParentID.RobotForeArmR:
    1223.                 return rbCAT.GetComponent<RobotCATStructure>().foreArmR;
    1224.  
    1225.             case ParentID.RobotHandL:
    1226.                 return rbCAT.GetComponent<RobotCATStructure>().handL;
    1227.  
    1228.             case ParentID.RobotHandR:
    1229.                 return rbCAT.GetComponent<RobotCATStructure>().handR;
    1230.  
    1231.             case ParentID.RobotThighL:
    1232.                 return rbCAT.GetComponent<RobotCATStructure>().thighL;
    1233.  
    1234.             case ParentID.RobotThighR:
    1235.                 return rbCAT.GetComponent<RobotCATStructure>().thighR;
    1236.  
    1237.             case ParentID.RobotCalfL:
    1238.                 return rbCAT.GetComponent<RobotCATStructure>().calfL;
    1239.  
    1240.             case ParentID.RobotCalfR:
    1241.                 return rbCAT.GetComponent<RobotCATStructure>().calfR;
    1242.  
    1243.             case ParentID.RobotFootL:
    1244.                 return rbCAT.GetComponent<RobotCATStructure>().footL;
    1245.  
    1246.             case ParentID.RobotFootR:
    1247.                 return rbCAT.GetComponent<RobotCATStructure>().footR;
    1248.  
    1249.             //--------Digit
    1250.  
    1251.             case ParentID.RobotLD00:
    1252.                 return rbCAT.GetComponent<RobotCATStructure>().LD00;
    1253.             case ParentID.RobotLD01:
    1254.                 return rbCAT.GetComponent<RobotCATStructure>().LD01;
    1255.             case ParentID.RobotLD02:
    1256.                 return rbCAT.GetComponent<RobotCATStructure>().LD02;
    1257.  
    1258.             case ParentID.RobotLD10:
    1259.                 return rbCAT.GetComponent<RobotCATStructure>().LD10;
    1260.             case ParentID.RobotLD11:
    1261.                 return rbCAT.GetComponent<RobotCATStructure>().LD11;
    1262.             case ParentID.RobotLD12:
    1263.                 return rbCAT.GetComponent<RobotCATStructure>().LD12;
    1264.  
    1265.             case ParentID.RobotLD20:
    1266.                 return rbCAT.GetComponent<RobotCATStructure>().LD20;
    1267.             case ParentID.RobotLD21:
    1268.                 return rbCAT.GetComponent<RobotCATStructure>().LD21;
    1269.             case ParentID.RobotLD22:
    1270.                 return rbCAT.GetComponent<RobotCATStructure>().LD22;
    1271.  
    1272.             case ParentID.RobotLD30:
    1273.                 return rbCAT.GetComponent<RobotCATStructure>().LD30;
    1274.             case ParentID.RobotLD31:
    1275.                 return rbCAT.GetComponent<RobotCATStructure>().LD31;
    1276.             case ParentID.RobotLD32:
    1277.                 return rbCAT.GetComponent<RobotCATStructure>().LD32;
    1278.  
    1279.             case ParentID.RobotLD40:
    1280.                 return rbCAT.GetComponent<RobotCATStructure>().LD40;
    1281.             case ParentID.RobotLD41:
    1282.                 return rbCAT.GetComponent<RobotCATStructure>().LD41;
    1283.             case ParentID.RobotLD42:
    1284.                 return rbCAT.GetComponent<RobotCATStructure>().LD42;
    1285.  
    1286.             // R Digit
    1287.             case ParentID.RobotRD00:
    1288.                 return rbCAT.GetComponent<RobotCATStructure>().RD00;
    1289.             case ParentID.RobotRD01:
    1290.                 return rbCAT.GetComponent<RobotCATStructure>().RD01;
    1291.             case ParentID.RobotRD02:
    1292.                 return rbCAT.GetComponent<RobotCATStructure>().RD02;
    1293.  
    1294.             case ParentID.RobotRD10:
    1295.                 return rbCAT.GetComponent<RobotCATStructure>().RD10;
    1296.             case ParentID.RobotRD11:
    1297.                 return rbCAT.GetComponent<RobotCATStructure>().RD11;
    1298.             case ParentID.RobotRD12:
    1299.                 return rbCAT.GetComponent<RobotCATStructure>().RD12;
    1300.  
    1301.             case ParentID.RobotRD20:
    1302.                 return rbCAT.GetComponent<RobotCATStructure>().RD20;
    1303.             case ParentID.RobotRD21:
    1304.                 return rbCAT.GetComponent<RobotCATStructure>().RD21;
    1305.             case ParentID.RobotRD22:
    1306.                 return rbCAT.GetComponent<RobotCATStructure>().RD22;
    1307.  
    1308.             case ParentID.RobotRD30:
    1309.                 return rbCAT.GetComponent<RobotCATStructure>().RD30;
    1310.             case ParentID.RobotRD31:
    1311.                 return rbCAT.GetComponent<RobotCATStructure>().RD31;
    1312.             case ParentID.RobotRD32:
    1313.                 return rbCAT.GetComponent<RobotCATStructure>().RD32;
    1314.  
    1315.             case ParentID.RobotRD40:
    1316.                 return rbCAT.GetComponent<RobotCATStructure>().RD40;
    1317.             case ParentID.RobotRD41:
    1318.                 return rbCAT.GetComponent<RobotCATStructure>().RD41;
    1319.             case ParentID.RobotRD42:
    1320.                 return rbCAT.GetComponent<RobotCATStructure>().RD42;
    1321.         }
    1322.         return null;
    1323.     }
    1324.  
    1325.     //--------------------------------------------------------------------
    1326.  
    1327.     void SetParent(Transform child, Transform parent)
    1328.     {
    1329.         child.position = parent.position;
    1330.         child.rotation = parent.rotation;
    1331.         child.SetParent(parent);
    1332.     }
    1333.  
    1334.     public void LoadColliderToRobotAI(Transform r)
    1335.     {
    1336.         Transform[] parts;
    1337.  
    1338.         parts = r.GetComponentsInChildren<Transform>();
    1339.  
    1340.         // ignore extra weapon collider
    1341.         for (int i = 0; i < parts.Length; i++)
    1342.         {
    1343.             if (parts[i].GetComponent<BoxCollider>())
    1344.                 r.GetComponent<RobotAI>().robotBodyPartColliderList.Add(parts[i].GetComponent<BoxCollider>());
    1345.  
    1346.         }
    1347.  
    1348.     }
    1349.  
    1350.  
    1351.     //---------------------Camera------------------
    1352.  
    1353.     void CameraControl()
    1354.     {
    1355.  
    1356.         // 1. Idle Mode, allow to control camera
    1357.         // 2. Player , Enemy Robot attack, cut in camera, cant control
    1358.         // 3. Add enemy , cut in camera
    1359.         // 4. turret attack, cut in camera
    1360.  
    1361.         switch (cameraMode)
    1362.         {
    1363.             case CameraMode.Idle:
    1364.  
    1365.                 if (mainCamera.gameObject.activeSelf)
    1366.                 {
    1367.                     // Zoom
    1368.                     if (Input.mouseScrollDelta == Vector2.down)
    1369.                         Camera.main.orthographicSize += 10;
    1370.                     else if (Input.mouseScrollDelta == Vector2.up)
    1371.                         Camera.main.orthographicSize -= 10;
    1372.  
    1373.                     if (Camera.main.orthographicSize <= 0)
    1374.                         Camera.main.orthographicSize = 10;
    1375.                     else if (Camera.main.orthographicSize >= 300)
    1376.                         Camera.main.orthographicSize = 300;
    1377.  
    1378.                     // Rotate
    1379.                     if (Input.GetKey(KeyCode.E))
    1380.                         Camera.main.transform.Rotate(Vector3.up * cameraRotateSpeed, Space.World);
    1381.                     else if (Input.GetKey(KeyCode.Q))
    1382.                         Camera.main.transform.Rotate(Vector3.down * cameraRotateSpeed, Space.World);
    1383.  
    1384.                     // Move,  Z use camera forward project vector, X use camera right            
    1385.                     if (Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
    1386.                     {
    1387.                         Vector3 projectVector = Vector3.ProjectOnPlane(Camera.main.transform.forward, Vector3.up);
    1388.                         cameraHolder.Translate(projectVector * Input.GetAxisRaw("Vertical") * cameraMoveSpeed, Space.World);
    1389.                         cameraHolder.Translate(Camera.main.transform.right * Input.GetAxisRaw("Horizontal") * cameraMoveSpeed, Space.World);
    1390.                     }
    1391.  
    1392.                     // Camera Up Down
    1393.                     if (Input.GetKey(KeyCode.Z))
    1394.                         Camera.main.transform.Rotate(Vector3.right * cameraRotateSpeed, Space.Self);
    1395.                     else if (Input.GetKey(KeyCode.X))
    1396.                         Camera.main.transform.Rotate(Vector3.left * cameraRotateSpeed, Space.Self);
    1397.  
    1398.                 }
    1399.                 break;
    1400.             case CameraMode.RobotAttackZoomIn:
    1401.  
    1402.                 Weapon wp = currentSelectedRobotAI.weapon[currentSelectedRobotWeaponID];
    1403.  
    1404.                 // Zoom Out Camera when robot melee start
    1405.                 if (currentSelectedRobotAI.meleeMoveStart)
    1406.                 {
    1407.                     CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1408.                 }
    1409.  
    1410.                 // For arms that may move out of camera, such as SED
    1411.                 // if (cutInCameraTarget != null)
    1412.                 //   cutInCamera.LookAt(cutInCameraTarget);
    1413.  
    1414.                 // For Turret, camera target is assigned by the turretAI, because it is turret to fire projectile
    1415.                 // robody part turret dummy -> turretAI fire true -> fire projectiles
    1416.                 // only check when cutincamera target is not assign
    1417.                 if (cutInCameraTarget == null)
    1418.                 {
    1419.                     // For turret, do not check the wp.projectile, check the turret AI projectiles direclty
    1420.                     if (wp.thisTransform.GetComponent<TurretAI>())
    1421.                     {
    1422.                         // wait until turret fire
    1423.                         if (wp.thisTransform.GetComponent<TurretAI>().projectilesInScene.Count != 0)
    1424.                         {
    1425.                             cutInCameraTarget = wp.thisTransform.GetComponent<TurretAI>().projectilesInScene[0];
    1426.                         }
    1427.                     }
    1428.                     else
    1429.                     {
    1430.                         // area emission is different from other, need to trace its camera dummy
    1431.                         if (wp.projectile0.projectileInScene.Count != 0 && wp.projectile0.projectileInScene[0] != null)
    1432.                         {
    1433.                             if (wp.type == WeaponType.AreaEmission)
    1434.                                 cutInCameraTarget = wp.projectile0.projectileInScene[0].GetComponent<WeaponEffectManager>().cutInCameraTraceDummy;
    1435.                             else
    1436.                                 cutInCameraTarget = wp.projectile0.projectileInScene[0].transform;
    1437.                         }
    1438.                         else if (wp.projectile1.projectileInScene.Count != 0 && wp.projectile1.projectileInScene[0] != null)
    1439.                         {
    1440.                             if (wp.type == WeaponType.AreaEmission)
    1441.                                 cutInCameraTarget = wp.projectile1.projectileInScene[0].GetComponent<WeaponEffectManager>().cutInCameraTraceDummy;
    1442.                             else
    1443.                                 cutInCameraTarget = wp.projectile1.projectileInScene[0].transform;
    1444.                         }
    1445.                     }
    1446.                 }
    1447.  
    1448.                 // How camera react after zoom in dependen on weapon type                      
    1449.                 // only check when cutincamera target is assign
    1450.  
    1451.                 if (cutInCameraTarget != null)
    1452.                     switch (wp.type)
    1453.                     {
    1454.                         case WeaponType.RocketPunch:
    1455.  
    1456.                             // camera trace rocket punch or not
    1457.                             if (Random.Range(0, 2) >= 1)
    1458.                                 CutInCameraSelector(CameraMode.TraceProjectile);
    1459.                             else
    1460.                                 CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1461.  
    1462.                             break;
    1463.  
    1464.                         case WeaponType.Beam:
    1465.  
    1466.                             if (Random.Range(0, 2) >= 1)
    1467.                                 CutInCameraSelector(CameraMode.TraceProjectile);
    1468.                             else
    1469.                                 CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1470.  
    1471.                             break;
    1472.  
    1473.                         case WeaponType.Projectile:
    1474.  
    1475.                             if (Random.Range(0, 2) >= 1)
    1476.                                 CutInCameraSelector(CameraMode.TraceProjectile);
    1477.                             else
    1478.                                 CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1479.  
    1480.                             break;
    1481.                            
    1482.                         case WeaponType.Funnel:
    1483.  
    1484.                             // camera trace rocket punch or not
    1485.                             if (Random.Range(0, 2) >= 1)
    1486.                                 CutInCameraSelector(CameraMode.TraceProjectile);
    1487.                             else
    1488.                                 CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1489.  
    1490.                             break;
    1491.  
    1492.                         case WeaponType.SelfAOE:
    1493.  
    1494.                             // switch camera when the sphere is large enough to touch camera
    1495.                             if (Vector3.Distance(cutInCameraTarget.GetComponent<Renderer>().bounds.ClosestPoint(cutInCamera.position), cutInCamera.position) < 5)
    1496.                                 CutInCameraSelector(CameraMode.Idle);
    1497.  
    1498.                             break;
    1499.  
    1500.                         case WeaponType.Missile:
    1501.  
    1502.                             if (Random.Range(0, 2) >= 1)
    1503.                                 CutInCameraSelector(CameraMode.TraceProjectile);
    1504.                             else
    1505.                                 CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1506.  
    1507.                             break;
    1508.  
    1509.                         case WeaponType.MachineGun:
    1510.  
    1511.                             // wait a bit before switch camera
    1512.                             // but i dont want to add a timer, so just count on the projectile in scene
    1513.                             if (wp.projectile0.projectileInScene.Count >= wp.projectile0.projectileMuzzleLocation.Count)
    1514.                             {
    1515.                                 if (Random.Range(0, 2) >= 1)
    1516.                                     CutInCameraSelector(CameraMode.TraceProjectile);
    1517.                                 else
    1518.                                     CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1519.  
    1520.                             }
    1521.  
    1522.                             break;
    1523.  
    1524.                         case WeaponType.AreaEmission:
    1525.  
    1526.                             CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1527.  
    1528.                             break;
    1529.  
    1530.                         case WeaponType.Sword:
    1531.  
    1532.                             CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1533.  
    1534.                             break;
    1535.  
    1536.                         case WeaponType.FlameThrower:
    1537.  
    1538.                             CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1539.  
    1540.                             break;
    1541.  
    1542.                         case WeaponType.Turret:
    1543.  
    1544.                             CutInCameraSelector(CameraMode.TraceProjectile);
    1545.  
    1546.                             break;
    1547.  
    1548.                         case WeaponType.DefendTurret:
    1549.  
    1550.                             CutInCameraSelector(CameraMode.TraceProjectile);
    1551.  
    1552.                             break;
    1553.  
    1554.                         case WeaponType.KneeStrike:
    1555.  
    1556.                             // lock on knee is better for view
    1557.  
    1558.                             //CutInCameraSelector(CameraMode.TraceProjectile);
    1559.                             cutInCamera.GetComponent<Camera>().fieldOfView = 70;
    1560.                             cameraMode = CameraMode.LookOn;
    1561.  
    1562.                             break;
    1563.  
    1564.                         case WeaponType.SuperElectricalDrill:
    1565.  
    1566.                             CutInCameraSelector(CameraMode.LookOn);
    1567.  
    1568.                             break;
    1569.  
    1570.                     }
    1571.  
    1572.                 break;
    1573.  
    1574.             case CameraMode.LookOn:
    1575.  
    1576.                 // camera follow robot
    1577.                 cutInCamerasRoot.position = currentSelectedRobot.position;
    1578.                 cutInCamerasRoot.rotation = currentSelectedRobot.rotation;
    1579.  
    1580.                 break;
    1581.  
    1582.             case CameraMode.TraceProjectile:
    1583.  
    1584.                 if (cutInCameraTarget != null)
    1585.                 {
    1586.                     cutInCamera.LookAt(cutInCameraTarget);
    1587.                 }
    1588.  
    1589.                 break;
    1590.  
    1591.             case CameraMode.RobotAttackZoomOut:
    1592.  
    1593.                 if(currentSelectedRobot!=null)
    1594.                     cutInCamerasRoot.position = currentSelectedRobot.position;
    1595.  
    1596.                 if (cutInCameraTarget != null)
    1597.                 {
    1598.                     cutInCamera.LookAt(cutInCameraTarget);
    1599.                 }
    1600.  
    1601.                 break;
    1602.  
    1603.             case CameraMode.AddEnemy:
    1604.  
    1605.                 if (cutInCamera.parent == null)
    1606.                     CutInCameraSelector(CameraMode.Idle);
    1607.  
    1608.                 break;
    1609.  
    1610.             case CameraMode.RobotDeath:
    1611.  
    1612.                 if (cutInCameraTarget == null)
    1613.                 {
    1614.                     cameraMode = CameraMode.Idle;
    1615.                     CutInCameraSelector(CameraMode.Idle);
    1616.                 }
    1617.  
    1618.                 break;
    1619.         }
    1620.     }
    1621.  
    1622.     void CutInCameraSelector(CameraMode cm)
    1623.     {
    1624.         // 1. Pick a default camera from list based on body part when robot attack
    1625.         // 2. Set field of view based on body part
    1626.         int cameraID = 0;
    1627.  
    1628.         // do not change camera if now is death mode
    1629.         // death mode only allow to change when robot disappear
    1630.         if (cameraMode == CameraMode.RobotDeath)
    1631.             return;
    1632.  
    1633.         switch (cm)
    1634.         {
    1635.             case CameraMode.RobotAttackZoomIn:
    1636.  
    1637.                 // Save camera
    1638.                 Data.cameraPosition = cameraHolder.position;
    1639.                 Data.cameraRotation = cameraHolder.rotation;
    1640.                 Data.cameraOrthographicSize = mainCamera.GetComponent<Camera>().orthographicSize;
    1641.  
    1642.                 // do not zoom in if setting is 0 or 50% test
    1643.                 // 2 cases: player and enemy
    1644.                 if (uiMode == UIMode.EnemyTurn)
    1645.                 {
    1646.                     // enemy
    1647.                     if (Data.optionMenuEnemyCameraSetting == 0)
    1648.                         return;
    1649.                     if (Data.optionMenuEnemyCameraSetting == 1)
    1650.                         if (Random.Range(0, 2) == 0)
    1651.                             return;
    1652.                 }
    1653.                 else
    1654.                 {
    1655.                     // player
    1656.                     if (Data.optionMenuPlayerCameraSetting == 0)
    1657.                         return;
    1658.                     if (Data.optionMenuPlayerCameraSetting == 1)
    1659.                         if (Random.Range(0, 2) == 0)
    1660.                             return;
    1661.                 }
    1662.  
    1663.                 Weapon wp = currentSelectedRobotAI.weapon[currentSelectedRobotWeaponID];
    1664.  
    1665.                 cutInCameraTarget = null;
    1666.                 switch (wp.parentID)
    1667.                 {
    1668.                     case ParentID.RobotChest:
    1669.  
    1670.                         cameraID = allowCutInCameraChest[Random.Range(0, allowCutInCameraChest.Length)];
    1671.                         cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1672.                         break;
    1673.  
    1674.                     case ParentID.RobotBack:
    1675.  
    1676.                         cameraID = allowCutInCameraBack[Random.Range(0, allowCutInCameraBack.Length)];
    1677.                         cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1678.  
    1679.                         break;
    1680.  
    1681.                     case ParentID.RobotAbdomen:
    1682.  
    1683.                         cameraID = allowCutInCameraAbdomen[Random.Range(0, allowCutInCameraAbdomen.Length)];
    1684.                         cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1685.                         break;
    1686.  
    1687.                     case ParentID.RobotPelvis:
    1688.  
    1689.                         cameraID = allowCutInCameraPelvis[Random.Range(0, allowCutInCameraPelvis.Length)];
    1690.                         cutInCamera.GetComponent<Camera>().fieldOfView = 20;
    1691.                         break;
    1692.  
    1693.                     case ParentID.RobotShoulderL:
    1694.                         cameraID = allowCutInCameraShoulderL[Random.Range(0, allowCutInCameraShoulderL.Length)];
    1695.                         cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1696.  
    1697.                         break;
    1698.  
    1699.                     case ParentID.RobotShoulderR:
    1700.                         cameraID = allowCutInCameraShoulderR[Random.Range(0, allowCutInCameraShoulderR.Length)];
    1701.                         cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1702.  
    1703.                         break;
    1704.  
    1705.                     case ParentID.RobotForeArmL:
    1706.  
    1707.                         if (wp.type == WeaponType.SuperElectricalDrill)
    1708.                             cameraID = TopFrontNear;
    1709.                         else
    1710.                             cameraID = allowCutInCameraForeArmL[Random.Range(0, allowCutInCameraForeArmL.Length)];
    1711.  
    1712.  
    1713.                         cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1714.                         cutInCameraTarget = currentSelectedRobotAI.foreArmL;
    1715.                         break;
    1716.  
    1717.                     case ParentID.RobotForeArmR:
    1718.  
    1719.                         if (wp.type == WeaponType.SuperElectricalDrill)
    1720.                             cameraID = FrontUpNear;
    1721.                         else
    1722.                             cameraID = allowCutInCameraForeArmR[Random.Range(0, allowCutInCameraForeArmR.Length)];
    1723.  
    1724.                         cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1725.                         cutInCameraTarget = currentSelectedRobotAI.foreArmR;
    1726.  
    1727.                         break;
    1728.  
    1729.                     case ParentID.RobotCalfL:
    1730.  
    1731.                         // Do not zoom in if kick
    1732.                         if (wp.type == WeaponType.SideKick01)
    1733.                         {
    1734.                             CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1735.                             return;
    1736.                         }
    1737.                         else
    1738.                         {
    1739.                             cameraID = allowCutInCameraCalfL[Random.Range(0, allowCutInCameraCalfL.Length)];
    1740.                             cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1741.                         }
    1742.                         break;
    1743.  
    1744.                     case ParentID.RobotCalfR:
    1745.  
    1746.                         // Do not zoom in if kick
    1747.                         if (wp.type == WeaponType.SideKick01)
    1748.                         {
    1749.                             CutInCameraSelector(CameraMode.RobotAttackZoomOut);
    1750.                             return;
    1751.                         }
    1752.                         else
    1753.                         {
    1754.                             cameraID = allowCutInCameraCalfR[Random.Range(0, allowCutInCameraCalfR.Length)];
    1755.                             cutInCamera.GetComponent<Camera>().fieldOfView = 30;
    1756.                         }
    1757.                         break;
    1758.                 }
    1759.  
    1760.                 // Move cameraRoot to robot
    1761.                 cutInCamerasRoot.position = currentSelectedRobot.position;
    1762.                 cutInCamerasRoot.rotation = currentSelectedRobot.rotation;
    1763.  
    1764.                 // Move camera to cameraRoot child and enable it
    1765.                 cutInCamera.parent = cutInCamerasRoot.GetChild(cameraID);
    1766.                 cutInCamera.localPosition = Vector3.zero;
    1767.                 cutInCamera.localRotation = Quaternion.Euler(0, 0, 0);
    1768.  
    1769.                 cameraMode = CameraMode.RobotAttackZoomIn;
    1770.                 mainCamera.gameObject.SetActive(false);
    1771.                 cutInCamera.gameObject.SetActive(true);
    1772.  
    1773.                 break;
    1774.  
    1775.             case CameraMode.RobotAttackZoomOut:
    1776.  
    1777.                 cameraID = allowCutInCameraZoomOut[Random.Range(0, allowCutInCameraZoomOut.Length)];
    1778.                 cutInCamera.GetComponent<Camera>().fieldOfView = 40;
    1779.  
    1780.                 // Move cameraRoot to robot
    1781.                 cutInCamerasRoot.position = currentSelectedRobot.position;
    1782.                 cutInCamerasRoot.rotation = currentSelectedRobot.rotation;
    1783.  
    1784.                 // Move camera to cameraRoot child and enable it
    1785.                 cutInCamera.parent = cutInCamerasRoot.GetChild(cameraID);
    1786.                 cutInCamera.localPosition = Vector3.zero;
    1787.                 cutInCamera.localRotation = Quaternion.Euler(0, 0, 0);
    1788.  
    1789.                 cameraMode = CameraMode.RobotAttackZoomOut;
    1790.                 mainCamera.gameObject.SetActive(false);
    1791.                 cutInCamera.gameObject.SetActive(true);
    1792.  
    1793.  
    1794.                 break;
    1795.  
    1796.             case CameraMode.TraceProjectile:
    1797.  
    1798.                 cutInCamera.parent = null;
    1799.  
    1800.                 cameraMode = CameraMode.TraceProjectile;
    1801.                 mainCamera.gameObject.SetActive(false);
    1802.                 cutInCamera.gameObject.SetActive(true);
    1803.  
    1804.  
    1805.                 break;
    1806.  
    1807.             case CameraMode.Idle:
    1808.  
    1809.                 cameraHolder.position = Data.cameraPosition;
    1810.                 cameraHolder.rotation = Data.cameraRotation;
    1811.                 mainCamera.GetComponent<Camera>().orthographicSize = Data.cameraOrthographicSize;
    1812.  
    1813.                 cameraMode = CameraMode.Idle;
    1814.                 cutInCamera.parent = null;
    1815.                 cutInCamera.gameObject.SetActive(false);
    1816.                 mainCamera.gameObject.SetActive(true);
    1817.  
    1818.                 break;
    1819.  
    1820.             case CameraMode.AddEnemy:
    1821.  
    1822.                 cameraMode = CameraMode.AddEnemy;
    1823.  
    1824.                 // Save camera
    1825.                 Data.cameraPosition = cameraHolder.position;
    1826.                 Data.cameraRotation = cameraHolder.rotation;
    1827.                 Data.cameraOrthographicSize = mainCamera.GetComponent<Camera>().orthographicSize;
    1828.  
    1829.                 cutInCamera.parent = enemyRobotSphereList[0];
    1830.                 cutInCamera.position = enemyRobotSphereList[0].GetComponent<EnemyRobotSphere>().cameraLocation.position;
    1831.                 cutInCamera.rotation = enemyRobotSphereList[0].GetComponent<EnemyRobotSphere>().cameraLocation.rotation;
    1832.  
    1833.  
    1834.                 mainCamera.gameObject.SetActive(false);
    1835.                 cutInCamera.gameObject.SetActive(true);
    1836.  
    1837.                 break;
    1838.  
    1839.             case CameraMode.PlayerTurret:
    1840.  
    1841.  
    1842.                 //cameraHolder.position = playerNonRobotUnitTransformList[0].GetComponent<NonRobotUnitAI>().cameraLocation.position;
    1843.                 //cameraHolder.rotation = playerNonRobotUnitTransformList[0].GetComponent<NonRobotUnitAI>().cameraLocation.rotation;
    1844.  
    1845.                 /*
    1846.                 cameraMode = CameraMode.PlayerTurret;
    1847.  
    1848.                 cutInCamera.parent = null;
    1849.                 cutInCamera.position = enemyRobotSphereList[0].GetComponent<EnemyRobotSphere>().cameraLocation.position;
    1850.                 cutInCamera.rotation = enemyRobotSphereList[0].GetComponent<EnemyRobotSphere>().cameraLocation.rotation;
    1851.  
    1852.  
    1853.                 mainCamera.gameObject.SetActive(false);
    1854.                 cutInCamera.gameObject.SetActive(true);
    1855.                 */
    1856.                 break;
    1857.  
    1858.             case CameraMode.RobotDeath:
    1859.  
    1860.                 Debug.Log("a");
    1861.                 cameraMode = CameraMode.RobotDeath;
    1862.  
    1863.                 // Save camera
    1864.                 Data.cameraPosition = cameraHolder.position;
    1865.                 Data.cameraRotation = cameraHolder.rotation;
    1866.                 Data.cameraOrthographicSize = mainCamera.GetComponent<Camera>().orthographicSize;
    1867.  
    1868.                 // Move cameraRoot to robot
    1869.                 cutInCamerasRoot.position = cutInCameraTarget.position;
    1870.                 cutInCamerasRoot.rotation = cutInCameraTarget.rotation;
    1871.  
    1872.                 // Move camera to cameraRoot child and enable it
    1873.                 cutInCamera.parent = cutInCamerasRoot.GetChild(allowCutInCameraChest[Random.Range(0, allowCutInCameraChest.Length)]);
    1874.                 cutInCamera.localPosition = Vector3.zero;
    1875.                 cutInCamera.localRotation = Quaternion.Euler(0, 0, 0);
    1876.  
    1877.                 mainCamera.gameObject.SetActive(false);
    1878.                 cutInCamera.gameObject.SetActive(true);
    1879.                 break;
    1880.         }
    1881.  
    1882.     }
    1883.     void FocusCamera()
    1884.     {
    1885.         // only work on robot death now
    1886.         if (focusCameraTarget != null && !focusCamera.gameObject.activeSelf)
    1887.         {
    1888.             List<Vector3> positionOption = new List<Vector3>();
    1889.             positionOption.Add(new Vector3(0, 16, 25));
    1890.             positionOption.Add(new Vector3(0, 27, 25));
    1891.             positionOption.Add(new Vector3(0, 30, -25));
    1892.  
    1893.             focusCamera.gameObject.SetActive(true);
    1894.             focusCamera.position = focusCameraTarget.position + positionOption[Random.Range(0, positionOption.Count - 1)];
    1895.             focusCamera.LookAt(focusCameraTarget.GetComponent<RobotAI>().chest);
    1896.  
    1897.             focusCameraDelayTimer = Time.time;
    1898.         }
    1899.         if (focusCameraTarget == null && focusCamera.gameObject.activeSelf)
    1900.         {
    1901.             const float focusCameraDelay = 3;
    1902.  
    1903.             if (Time.time > focusCameraDelayTimer + focusCameraDelay)
    1904.                 focusCamera.gameObject.SetActive(false);
    1905.  
    1906.         }
    1907.     }
    1908.  
    1909.     void MouseClick()
    1910.     {
    1911.         // not allow to click object behind ui
    1912.         if (!EventSystem.current.IsPointerOverGameObject())
    1913.         {
    1914.             if (Input.GetMouseButtonDown(0))
    1915.             {
    1916.                 Ray ray = mainCamera.GetComponent<Camera>().ScreenPointToRay(Input.mousePosition);
    1917.  
    1918.                 if (Physics.Raycast(ray, out hit))
    1919.                 {
    1920.                     switch (uiMode)
    1921.                     {
    1922.                         case UIMode.Idle:
    1923.  
    1924.                             if (hit.transform.root.GetComponent<RobotAI>())
    1925.                             {
    1926.                                 currentSelectedRobot = hit.transform.root;
    1927.                                 currentSelectedRobotAI = hit.transform.root.GetComponent<RobotAI>();
    1928.                             }
    1929.  
    1930.                             if (hit.transform.root.CompareTag(Tag.PlayerRobot.ToString()))
    1931.                             {
    1932.                                 if (!Data.playerRobot[hit.transform.root.GetComponent<RobotAI>().robotIndex].movedThisTurn)
    1933.                                 {
    1934.                                     currentSelectedRobot = hit.transform.root;
    1935.                                     currentSelectedRobotAI = hit.transform.root.GetComponent<RobotAI>();
    1936.                                     currentSelectedRobot.GetComponent<NavMeshAgent>().enabled = true;
    1937.                                     uiMode = UIMode.PlayerRobotMove;
    1938.                                 }
    1939.                                 else if (!Data.playerRobot[hit.transform.root.GetComponent<RobotAI>().robotIndex].attackedThisTurn)
    1940.                                 {
    1941.                                     currentSelectedRobot = hit.transform.root;
    1942.                                     currentSelectedRobotAI = hit.transform.root.GetComponent<RobotAI>();
    1943.                                     uiMode = UIMode.WaitingRobotAttack;
    1944.                                 }
    1945.                             }
    1946.                             else if (hit.transform.root.CompareTag(Tag.Facility.ToString()))
    1947.                             {
    1948.                                 // hide map, disable mesh, collider                                                              
    1949.                                 terrain.SetActive(false);
    1950.                                 hit.transform.root.GetComponent<FacilityManager>().Focus(true);
    1951.  
    1952.                                 //cameraTargetPoint = hit.transform.root.GetComponent<FacilityManager>().cameraPoint;
    1953.  
    1954.                                 currentSelectedRBLauncher = hit.transform.root;
    1955.                                 uiMode = UIMode.RBLauncher;
    1956.                             }
    1957.                             break;
    1958.  
    1959.                         case UIMode.RBLauncher:
    1960.  
    1961.                             switch (subuiMode)
    1962.                             {
    1963.                                 case SubUIMode.Null:
    1964.                                     // When player click robot directly
    1965.                                     if (hit.transform.root.CompareTag(Tag.PlayerRobot.ToString()))
    1966.                                     {
    1967.                                         // Show status, edit, color button near mouse
    1968.                                         //currentSelectedRobot = hit.transform.root;
    1969.  
    1970.                                     }
    1971.                                     // When player click on the plate of the robot fixture
    1972.                                     else
    1973.                                     {
    1974.                                         Transform whatToCheck = null;
    1975.                                         int platformID = 99;
    1976.  
    1977.                                         // Use name to decide what is clicked, better than put a script in each object
    1978.                                         if (hit.transform.name.Contains("Platform"))
    1979.                                             whatToCheck = hit.transform;
    1980.                                         else if (hit.transform.name.Contains("Launch"))
    1981.                                             whatToCheck = hit.transform.parent; // = platform
    1982.                                         else if (hit.transform.name.Contains("StatusPanel"))
    1983.                                             whatToCheck = hit.transform.parent.parent; // = platform
    1984.  
    1985.                                         // 1. find out if the click platform is in the RBLauncherPlatform
    1986.                                         for (int i = 0; i < RBLauncherPlatform.Count; i++)
    1987.                                             if (GameObject.ReferenceEquals(RBLauncherPlatform[i], whatToCheck))
    1988.                                             {
    1989.                                                 platformID = i;
    1990.                                                 // also reset currentSelectedRBLauncher, the reason is player may click a RBlaucnher, and then click platform in other RBLauncher
    1991.                                                 currentSelectedRBLauncher.GetComponent<FacilityManager>().Focus(false);
    1992.                                                 currentSelectedRBLauncher = RBLauncherPlatform[i].root;
    1993.                                             }
    1994.                                         // 2. If not, break
    1995.                                         if (platformID == 99)
    1996.                                             break;
    1997.  
    1998.                                         if (hit.transform.name.Contains("Platform"))
    1999.                                             LoadRobotEditor(platformID);
    2000.                                         else if (hit.transform.name.Contains("Launch"))
    2001.                                             LaunchRobot(platformID);
    2002.                                         else if (hit.transform.name.Contains("StatusPanel"))// 3. Load robot editor
    2003.                                         {
    2004.                                             // need to assign currentRobot
    2005.                                             for (int i = 0; i < Data.playerRobot.Count; i++)
    2006.                                                 if (Data.playerRobot[i].onRBLauncher && Data.playerRobot[i].RBLauncherPlatformID == platformID)
    2007.                                                 {
    2008.                                                     currentSelectedRobot = playerRobotTransformList[i];
    2009.                                                     currentSelectedRobotAI = playerRobotTransformList[i].GetComponent<RobotAI>();
    2010.                                                     RobotInfoWindow();
    2011.                                                 }
    2012.                                         }
    2013.  
    2014.                                     }
    2015.                                     break;
    2016.                             }
    2017.                             break;
    2018.  
    2019.                         case UIMode.PlayerRobotMove:
    2020.  
    2021.                             float navAgentSphereCastRadius = currentSelectedRobot.GetComponent<NavMeshAgent>().radius;
    2022.  
    2023.                             // check the choice base on what really hit on destination
    2024.                             Physics.SphereCast(currentRobotDestination + new Vector3(0, 300, 0), navAgentSphereCastRadius, Vector3.down, out hit);
    2025.  
    2026.                             if (hit.transform.root.CompareTag(Tag.Facility.ToString()) && hit.transform.root.GetComponent<FacilityManager>().type == FacilityManager.Type.RBLauncher)
    2027.                             {
    2028.                                 // Move from map to RBLauncher                                                  
    2029.                                 {
    2030.                                     if (RBLauncherPlatform[Data.playerRobot[currentSelectedRobotAI.robotIndex].RBLauncherPlatformID].IsChildOf(hit.transform.root))
    2031.                                     {
    2032.                                         walkLine.enabled = false;
    2033.                                         //currentSelectedRoboIcon.transform.position = new Vector3(currentRobotDestination.x, currentSelectedRoboIcon.transform.position.y, currentRobotDestination.z);
    2034.                                         currentRobotDestinationIcon.gameObject.SetActive(false);
    2035.  
    2036.                                         uiMode = UIMode.WaitingRobotMove;
    2037.                                         subuiMode = SubUIMode.RobotToRBLauncher;
    2038.  
    2039.                                         currentSelectedRBLauncher = hit.transform.root;
    2040.                                         hit.transform.root.GetComponent<FacilityManager>().launch = true;
    2041.                                     }
    2042.                                 }
    2043.                             }
    2044.                             else if (hit.transform.root.tag == Tag.Map.ToString())
    2045.                             {
    2046.                                 walkLine.enabled = false;
    2047.                                 SelectedRoboIcon(currentSelectedRobot, currentRobotDestination);
    2048.                                 //currentSelectedRoboIcon.position = new Vector3(currentRobotDestination.x, currentSelectedRoboIcon.transform.position.y, currentRobotDestination.z);
    2049.                                 currentRobotDestinationIcon.gameObject.SetActive(false);
    2050.  
    2051.                                 uiMode = UIMode.WaitingRobotMove;
    2052.  
    2053.                                 currentSelectedRobotAI.Move(currentRobotDestination, 1);
    2054.                             }
    2055.  
    2056.                             break;
    2057.  
    2058.                         case UIMode.WaitingRobotAttack:
    2059.  
    2060.                             // 3 case: Robot, robotTargetDummy(for nonRobotUnit), Turret(height is not too low for robot normal attack)
    2061.  
    2062.                             if (!Data.playerRobot[currentSelectedRobotAI.robotIndex].attackedThisTurn)
    2063.                             {
    2064.                                 // click enemy robot (transform.root)
    2065.                                 if (hit.transform.root.CompareTag(Tag.EnemyRobot.ToString()))
    2066.                                 {
    2067.                                     int weaponID = WeaponSelector(currentSelectedRobot, hit.transform.root);
    2068.                                     // do not use shield attack
    2069.                                     if (weaponID != 99 && currentSelectedRobotAI.weapon[weaponID].type != WeaponType.Shield)
    2070.                                     {
    2071.                                         currentSelectedRobotTarget = hit.transform.root;
    2072.  
    2073.                                         skillManager.Attack(currentSelectedRobot, currentSelectedRobotTarget);
    2074.                                         RobotAttack(currentSelectedRobot, currentSelectedRobotTarget, weaponID, true);
    2075.                                         uiMode = UIMode.PlayerRobotAttack;
    2076.                                         CutInCameraSelector(CameraMode.RobotAttackZoomIn);
    2077.  
    2078.                                         currentSelectedRoboIcon.gameObject.SetActive(false);
    2079.                                     }
    2080.                                     else
    2081.                                     {
    2082.                                         Debug.Log("cannotattack");
    2083.                                     }
    2084.                                 }
    2085.                                 // For nonrobot unit , when the unit is too big, we cannot use transform.position
    2086.                                 // For turret, its pivot may not be at the terrain too                              
    2087.                                 // need a special method:
    2088.                                 // 1. place a dummy on the click position.
    2089.                                 // 2. then robot attack this dummy in the same process as robot attack robot
    2090.                                 else if (hit.transform.CompareTag(Tag.EnemyNonRobotUnit.ToString()))
    2091.                                 {
    2092.                                     // dummy position should be on terrain, so all melee attack will be correct
    2093.                                     // hit should be the part that player trying to attack
    2094.                                     // rootbody is the unit on scene, not a part
    2095.                                     robotTargetDummy.GetComponent<RobotTargetDummy>().hitTransform = hit.transform;
    2096.                                     robotTargetDummy.GetComponent<RobotTargetDummy>().hitPoint = hit.point;
    2097.                                     robotTargetDummy.GetComponent<RobotTargetDummy>().hitRootTransfrom = hit.transform.root;
    2098.                                     robotTargetDummy.position = hit.transform.GetComponent<Collider>().ClosestPointOnBounds(currentSelectedRobot.position);
    2099.                                     //   robotTargetDummy.position = new Vector3(hit.point.x, 0, hit.point.z);
    2100.  
    2101.  
    2102.                                     int weaponID = WeaponSelector(currentSelectedRobot, robotTargetDummy);
    2103.  
    2104.                                     if (weaponID != 99)
    2105.                                     {
    2106.                                         currentSelectedRobotTarget = robotTargetDummy;
    2107.                                         RobotAttack(currentSelectedRobot, currentSelectedRobotTarget, weaponID, true);
    2108.                                         uiMode = UIMode.PlayerRobotAttack;
    2109.                                         CutInCameraSelector(CameraMode.RobotAttackZoomIn);
    2110.  
    2111.                                         currentSelectedRoboIcon.gameObject.SetActive(false);
    2112.                                     }
    2113.                                     else
    2114.                                     {
    2115.                                         Debug.Log("cannotattack");
    2116.                                     }
    2117.                                 }
    2118.  
    2119.                             }
    2120.  
    2121.                             break;
    2122.  
    2123.                         case UIMode.PlayerRobotRotate:
    2124.  
    2125.                             // when robot move from launcher, but stay at the launcher tile, i.e. rotate mode at launcher tile
    2126.                             if (subuiMode == SubUIMode.WaitingRobotMoveFromLauncher)
    2127.                             {
    2128.                                 //currentSelectedRobot.position = RBLauncherPlatform[Data.playerRobot[currentSelectedRobotAI.robotIndex].RBLauncherPlatformID].position;
    2129.                                 //currentSelectedRobot.rotation = RBLauncherPlatform[Data.playerRobot[currentSelectedRobotAI.robotIndex].RBLauncherPlatformID].rotation;
    2130.                                 Data.playerRobot[currentSelectedRobotAI.robotIndex].map = Map.MainMap;
    2131.                             }
    2132.  
    2133.                             uiMode = UIMode.Idle;
    2134.                             subuiMode = SubUIMode.Null;
    2135.  
    2136.                             if (currentSelectedRBLauncher != null)
    2137.                                 currentSelectedRBLauncher.GetComponent<FacilityManager>().resume = true;
    2138.  
    2139.                             currentSelectedRBLauncher = null;
    2140.                             currentSelectedRobot = null;
    2141.                             currentSelectedRobotAI = null;
    2142.  
    2143.                             break;
    2144.                     }
    2145.                 }
    2146.             }
    2147.             else if (Input.GetMouseButtonDown(1))
    2148.             {
    2149.                 // if cancel during launching, it will cause problem
    2150.                 if (subuiMode != SubUIMode.RobotFromRBLauncher)
    2151.                 {
    2152.                     if (uiMode == UIMode.WaitingRobotAttack)
    2153.                     {
    2154.                         currentSelectedRoboIcon.gameObject.SetActive(false);
    2155.                         Data.playerRobot[currentSelectedRobotAI.robotIndex].attackedThisTurn = true;
    2156.                     }
    2157.  
    2158.                     if (currentSelectedRBLauncher != null)
    2159.                         currentSelectedRBLauncher.GetComponent<FacilityManager>().Focus(false);
    2160.  
    2161.                     if (subuiMode == SubUIMode.WaitingRobotMoveFromLauncher)
    2162.                     {
    2163.                         currentSelectedRobot.position = RBLauncherPlatform[Data.playerRobot[currentSelectedRobotAI.robotIndex].RBLauncherPlatformID].position;
    2164.                         currentSelectedRobot.rotation = RBLauncherPlatform[Data.playerRobot[currentSelectedRobotAI.robotIndex].RBLauncherPlatformID].rotation;
    2165.  
    2166.                         currentSelectedRBLauncher.GetComponent<FacilityManager>().resume = true;
    2167.                         Data.playerRobot[currentSelectedRobotAI.robotIndex].onRBLauncher = false;
    2168.                         currentSelectedRBLauncher = null;
    2169.                         subuiMode = SubUIMode.Null;
    2170.                     }
    2171.  
    2172.                     currentSelectedRobot = null;
    2173.                     currentSelectedRobotAI = null;
    2174.                     terrain.SetActive(true);
    2175.                     uiMode = UIMode.Idle;
    2176.  
    2177.                 }
    2178.             }
    2179.         }
    2180.  
    2181.         // ==============HotKey Section
    2182.         if (Input.GetKeyDown(KeyCode.Escape))
    2183.         {
    2184.             if (optionMenu.gameObject.activeInHierarchy)
    2185.                 optionMenu.gameObject.SetActive(false);
    2186.             else
    2187.                 optionMenu.gameObject.SetActive(true);
    2188.         }
    2189.  
    2190.     }
    2191.  
    2192.     //----------------Facility Section----------------------------------------------------
    2193.  
    2194.     // load robot to scene, 99 means edit old robot
    2195.     // Data.robotIndexForRobotEditor need to be defined before calling this function
    2196.     void LoadRobotEditor(int platformID)
    2197.     {
    2198.         // Find out this platform have robot or not by comparing Data.playerRobot.RBLaucnher Platform  
    2199.         for (int i = 0; i < Data.playerRobot.Count; i++)
    2200.             if (Data.playerRobot[i].RBLauncherPlatformID == platformID)
    2201.             {
    2202.                 // Only edit robot if it is on RBLauncher
    2203.                 if (Data.playerRobot[i].onRBLauncher)
    2204.                 {
    2205.                     // edit old robot
    2206.                     Data.robotIndexForRobotEditor = i;
    2207.  
    2208.                     SavePlayerRobotData();
    2209.                     SaveEnemyRobotData();
    2210.  
    2211.                     // Save camera
    2212.                     Data.cameraPosition = cameraHolder.position;
    2213.                     Data.cameraRotation = cameraHolder.rotation;
    2214.                     Data.cameraOrthographicSize = mainCamera.GetComponent<Camera>().orthographicSize;
    2215.  
    2216.                     SceneManager.LoadScene(SceneList.RobotEditor.ToString());
    2217.                     return;
    2218.                 }
    2219.                 else
    2220.                     return;
    2221.             }
    2222.  
    2223.         // If fail to loadscene above, it means it is a new robot      
    2224.         // Check if create new robot or not by the max allow player robot
    2225.         if (playerRobotTransformList.Count < Data.playerRobotMax)
    2226.         {
    2227.             // Save transformList to Data
    2228.             SavePlayerRobotData();
    2229.             SaveEnemyRobotData();
    2230.  
    2231.             Robot r = new Robot();
    2232.  
    2233.             r.RBLauncherPlatformID = platformID;
    2234.             r.map = map;
    2235.             r.onRBLauncher = true;
    2236.             r.position = RBLauncherPlatform[platformID].position;
    2237.             r.rotation = RBLauncherPlatform[platformID].rotation;
    2238.             r.armor = r.armorMax;
    2239.             r.armorLastTurn = r.armor;
    2240.             r.moveMaxDistance = Data.robotMoveMaxDistance;
    2241.  
    2242.             // Create attackMatrix instance, Cannot init because no body parts yet
    2243.             /*  for (int i = 0; i < 5; i++)
    2244.               {
    2245.                   Robot.AttackMatrix am = new Robot.AttackMatrix();
    2246.                   r.attackMatrix.Add(am);
    2247.               }
    2248.               */
    2249.             Data.playerRobot.Add(r);
    2250.             Data.robotIndexForRobotEditor = Data.playerRobot.Count - 1;
    2251.  
    2252.             // Save camera
    2253.             Data.cameraPosition = cameraHolder.position;
    2254.             Data.cameraRotation = cameraHolder.rotation;
    2255.             Data.cameraOrthographicSize = mainCamera.GetComponent<Camera>().orthographicSize;
    2256.  
    2257.             SceneManager.LoadScene(SceneList.RobotEditor.ToString());
    2258.         }
    2259.     }
    2260.  
    2261.     // Launch robot from RBLauncher
    2262.     void LaunchRobot(int platformID)
    2263.     {
    2264.         // Find out the robot is on Platform or not
    2265.         for (int i = 0; i < Data.playerRobot.Count; i++)
    2266.             if (Data.playerRobot[i].RBLauncherPlatformID == platformID)
    2267.             {
    2268.                 // If robot is on Platform, launch
    2269.                 if (Data.playerRobot[i].onRBLauncher)
    2270.                 {
    2271.                     Data.playerRobot[i].onRBLauncher = false;
    2272.  
    2273.                     int transformListID = Data.playerRobot[i].transformListID;
    2274.                     playerRobotTransformList[transformListID].parent = currentSelectedRBLauncher.GetComponent<FacilityManager>().lift;
    2275.                     playerRobotTransformList[transformListID].localPosition = Vector3.zero;
    2276.                     playerRobotTransformList[transformListID].rotation = currentSelectedRBLauncher.GetComponent<FacilityManager>().lift.rotation;
    2277.                     currentSelectedRBLauncher.GetComponent<FacilityManager>().launch = true;
    2278.  
    2279.                     terrain.SetActive(true);
    2280.                     currentSelectedRBLauncher.GetComponent<FacilityManager>().Focus(false);
    2281.                     LaunchRobotRendererQueue(playerRobotTransformList[transformListID]);
    2282.  
    2283.                     // uiMode is still RBLaucnher
    2284.                     subuiMode = SubUIMode.RobotFromRBLauncher;
    2285.                     currentSelectedRobot = playerRobotTransformList[transformListID];
    2286.                     currentSelectedRobotAI = playerRobotTransformList[transformListID].GetComponent<RobotAI>();
    2287.  
    2288.                     currentSelectedRobotAI.Idle(false);
    2289.                     return;
    2290.                 }
    2291.                 // if robot not on Platform, do nothing
    2292.                 return;
    2293.             }
    2294.  
    2295.     }
    2296.  
    2297.     // Set renderer queue, so robot can be visible under map
    2298.     void LaunchRobotRendererQueue(Transform robot)
    2299.     {
    2300.         const int queue = 1500;
    2301.  
    2302.         // Set render quene for all parts
    2303.         Transform[] partList = robot.GetComponentsInChildren<Transform>();
    2304.  
    2305.         for (int i = 0; i < partList.Length; i++)
    2306.             if (partList[i].GetComponent<Renderer>())
    2307.                 partList[i].GetComponent<Renderer>().material.renderQueue = queue;
    2308.     }
    2309.     //----------------Facility Section End----------------------------------------------------
    2310.  
    2311.     //------------Player Robot Section------------------------------------------------------
    2312.     // Show player selected robot move Hex on map, only call after clicked robot
    2313.     void DrawRobotMoveLine()
    2314.     {
    2315.         Vector3 checkPoint = Vector3.zero;
    2316.         Vector3 hitPoint; // we dont use hit.point from raycast, because it may be any object in scene
    2317.         RaycastHit hit2;
    2318.         const float radiusBuffer = 1;
    2319.  
    2320.         walkLine.enabled = true;
    2321.         currentRobotDestinationIcon.gameObject.SetActive(true);
    2322.         currentSelectedRoboIcon.gameObject.SetActive(true);
    2323.         SelectedRoboIcon(currentSelectedRobot, currentSelectedRobot.position);
    2324. //        currentSelectedRoboIcon.position = currentSelectedRobot.position + new Vector3(0, currentSelectedRoboIcon.transform.position.y, 0);
    2325.  
    2326.         // 1. get mouse hit point
    2327.         // 2. any collider block ?
    2328.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    2329.         if (Physics.Raycast(ray, out hit))
    2330.         {
    2331.             hitPoint = new Vector3(hit.point.x, 0, hit.point.z); // translate to a point on Terrain
    2332.             NavMeshPath path = new NavMeshPath();
    2333.  
    2334.             float navAgentSphereCastRadius = currentSelectedRobot.GetComponent<NavMeshAgent>().radius + radiusBuffer;
    2335.             checkPoint = new Vector3(hitPoint.x, 300, hitPoint.z);
    2336.  
    2337.             if (Vector3.Distance(currentSelectedRobot.position, hitPoint) <= currentSelectedRobotAI.moveDistanceMax)
    2338.             {
    2339.                 currentSelectedRobot.GetComponent<NavMeshAgent>().CalculatePath(hitPoint, path);
    2340.                 // accept this hitpoint only if raycast hit the map, y=0, and the path complete
    2341.                 if (Physics.SphereCast(checkPoint, navAgentSphereCastRadius, Vector3.down, out hit2) && hit2.transform.tag == Tag.Map.ToString() && hit2.point.y == 0 && path.status == NavMeshPathStatus.PathComplete)
    2342.                     currentRobotDestination = hitPoint;
    2343.                 // click RBlauncher is allowed
    2344.                 else if (hit2.transform.root.name.Contains("RBLauncher"))
    2345.                     currentRobotDestination = new Vector3(hit2.transform.root.position.x, 0, hit2.transform.root.position.z);
    2346.  
    2347.                 //  Debug.Log(hit2.transform + " " + currentSelectedRobot.GetComponent<NavMeshAgent>().CalculatePath(hitPoint, path));
    2348.  
    2349.             }
    2350.             else
    2351.             {
    2352.                 // if distance between mouse point and robot bigger than move distance limit, decide the destination point by direction and length
    2353.                 Vector3 direction = hitPoint - currentSelectedRobot.position;
    2354.                 direction = direction.normalized * currentSelectedRobotAI.moveDistanceMax;
    2355.  
    2356.                 // in case mouse point on where is not walkable, need to find the closest walkable point along the direction
    2357.                 do
    2358.                 {
    2359.  
    2360.                     checkPoint = currentSelectedRobot.position + direction;
    2361.  
    2362.                     currentSelectedRobot.GetComponent<NavMeshAgent>().CalculatePath(checkPoint, path);
    2363.                     // y == 0 to make sure the point is not on mountain
    2364.                     if (Physics.SphereCast(checkPoint + new Vector3(0, 300, 0), navAgentSphereCastRadius, Vector3.down, out hit2) && hit2.transform.tag == Tag.Map.ToString() && hit2.point.y == 0 && path.status == NavMeshPathStatus.PathComplete)
    2365.                         break;
    2366.                     direction -= direction.normalized;
    2367.                 } while (direction.magnitude > 10);
    2368.  
    2369.                 currentRobotDestination = checkPoint;
    2370.             }
    2371.  
    2372.             // shift up, so not overlap with map
    2373.             walkLine.SetPosition(0, currentSelectedRobot.position + Vector3.up);
    2374.             walkLine.SetPosition(1, currentRobotDestination + Vector3.up);
    2375.             currentRobotDestinationIcon.transform.position = new Vector3(currentRobotDestination.x, currentRobotDestinationIcon.transform.position.y, currentRobotDestination.z);
    2376.         }
    2377.     }
    2378.  
    2379.     void RotatePlayerRobot()
    2380.     {
    2381.         Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    2382.         int distance = 0;
    2383.  
    2384.         if (Physics.Raycast(ray, out hit) && hit.transform.name == "Map")
    2385.         {
    2386.             distance = (int)Vector3.Distance(new Vector3(hit.point.x, 0, hit.point.z), new Vector3(currentSelectedRobot.transform.position.x, 0, currentSelectedRobot.transform.position.z));
    2387.  
    2388.             if (distance != 0)
    2389.                 currentSelectedRobot.LookAt(new Vector3(hit.point.x, 0, hit.point.z));
    2390.         }
    2391.     }
    2392.  
    2393.     void RobotAttack(Transform rb, Transform target, int weaponID, bool counter)
    2394.     {
    2395.         // the case that robot try to attack a dieing target, when the target is destoryed, it cause null error
    2396.         if (target == null)
    2397.             return;
    2398.  
    2399.         int defendWpID = 99;
    2400.         rb.GetComponent<RobotAI>().target = target;
    2401.  
    2402.         if (target.GetComponent<RobotAI>())
    2403.             rb.GetComponent<RobotAI>().targetCATRoot = target.GetComponent<RobotAI>().catRoot;
    2404.         else if (target.GetComponent<RobotTargetDummy>())
    2405.             rb.GetComponent<RobotAI>().targetCATRoot = target;
    2406.  
    2407.         rb.LookAt(target);
    2408.         rb.GetComponent<RobotAI>().WeaponFire(weaponID);
    2409.         currentSelectedRobotWeaponID = weaponID;
    2410.  
    2411.         // target defend
    2412.         // robot can defend, but non robot unit cannot defend
    2413.         if (counter)
    2414.         {
    2415.             if (target.CompareTag(Tag.PlayerRobot.ToString()) || target.CompareTag(Tag.EnemyRobot.ToString()))
    2416.             {
    2417.                 // no matter whether target can defend or not, look at robot
    2418.                 target.LookAt(rb);
    2419.                 target.GetComponent<RobotAI>().target = rb;
    2420.                 target.GetComponent<RobotAI>().targetCATRoot = rb.GetComponent<RobotAI>().catRoot;
    2421.  
    2422.                 if (rb.tag == Tag.PlayerRobot.ToString())
    2423.                     defendWpID = WeaponSelector(target, rb);
    2424.                 else
    2425.                     defendWpID = WeaponSelector(target, rb);
    2426.  
    2427.                 if (defendWpID != 99)
    2428.                 {
    2429.                     target.GetComponent<RobotAI>().WeaponFire(defendWpID);
    2430.                 }
    2431.                 else
    2432.                 {
    2433.                     // weaponfire turn off both robots nav agent
    2434.                     // turn on NAV agent if target cannot attack
    2435.                     target.GetComponent<NavMeshAgent>().enabled = true;
    2436.                 }
    2437.             }
    2438.         }
    2439.         else
    2440.         {
    2441.             if (rb.CompareTag(Tag.PlayerRobot.ToString()))
    2442.                 Data.playerRobot[rb.GetComponent<RobotAI>().robotIndex].thisIsAssistAttack = true;
    2443.             else if(rb.CompareTag(Tag.EnemyRobot.ToString()))
    2444.                 Data.enemyRobot[rb.GetComponent<RobotAI>().robotIndex].thisIsAssistAttack = true;
    2445.  
    2446.             // weaponfire turn off both robots nav agent
    2447.             // turn on NAV agent if target cannot attack
    2448.             target.GetComponent<NavMeshAgent>().enabled = true;
    2449.         }
    2450.  
    2451.     }
    2452.     // Select weapon
    2453.     // 1. Find weapon to attack
    2454.     // 2. If weapon available, find shield to defend.
    2455.     int WeaponSelector(Transform rb, Transform target)
    2456.     {
    2457.         Layer oldLayer = (Layer)rb.gameObject.layer;
    2458.  
    2459.         // the case that robot try to attack a dieing target, when the target is destoryed, it cause null error
    2460.         if (target == null)
    2461.             return 99;
    2462.  
    2463.         Vector3 direction = target.position - rb.position;
    2464.        
    2465.         float distance = direction.magnitude;
    2466.         int wpIDR;
    2467.         int wpIDL;
    2468.  
    2469.         // two cases: hand have weapon or not
    2470.         // weapon list is already sort by range
    2471.         // robot should use shortest range weapon, because it is unlikely to get interrupt
    2472.         // by default, larger range, higher damage, but more animation to be interrupt
    2473.  
    2474.         // Check hand weapon first
    2475.         // Then normal weapon check loop, it will repeat checking on the hand weapon, but it should fail because of the range      
    2476.         // and it create a problem, that some weapon should not be allowed to use when weapon on hand
    2477.         // need to add a check point in the weapon check loop if hand weapon exit
    2478.                
    2479.         // ignore raycast on whole robot collider
    2480.         SetLayer(rb.gameObject, Layer.IgnoreRayCast);
    2481.         if (rb.GetComponent<RobotAI>().ExtraWpR != null || rb.GetComponent<RobotAI>().ExtraWpL != null)
    2482.         {
    2483.             // 1. check if robot can use hand weapon attack
    2484.             // 2. if no, pick weapon from weapon list that is "Stand by" animation
    2485.             wpIDR = rb.GetComponent<RobotAI>().weaponIDExtraWpR;
    2486.  
    2487.             if (wpIDR != 99)
    2488.             {
    2489.                 // Check Right Hand
    2490.                 if (target.GetComponent<RobotAI>())
    2491.                 {
    2492.                     if (Physics.SphereCast(rb.GetComponent<RobotAI>().chest.position, LOSSphereCastRadius, direction, out hit, rb.GetComponent<RobotAI>().weapon[wpIDR].range) && hit.transform.root == target)
    2493.                     {
    2494.                         SetLayer(rb.gameObject, oldLayer);
    2495.                         return wpIDR;
    2496.                     }                
    2497.                 }
    2498.                 else if (target.GetComponent<RobotTargetDummy>())
    2499.                 {
    2500.                     if (Physics.SphereCast(rb.GetComponent<RobotAI>().chest.position, LOSSphereCastRadius, direction, out hit, rb.GetComponent<RobotAI>().weapon[wpIDR].range) && hit.transform.root == target.GetComponent<RobotTargetDummy>().hitRootTransfrom)
    2501.                     {
    2502.                         SetLayer(rb.gameObject, oldLayer);
    2503.                         return wpIDR;
    2504.                     }                  
    2505.                 }
    2506.             }
    2507.             // Check Left Hand, if right hand weapon out of range          
    2508.             wpIDL = rb.GetComponent<RobotAI>().weaponIDExtraWpL;
    2509.  
    2510.             if (wpIDL != 99)
    2511.             {
    2512.                 if (target.GetComponent<RobotAI>())
    2513.                 {                  
    2514.                     if (Physics.SphereCast(rb.GetComponent<RobotAI>().chest.position, LOSSphereCastRadius, direction, out hit, rb.GetComponent<RobotAI>().weapon[wpIDL].range) && hit.transform.root == target)
    2515.                     {
    2516.                         SetLayer(rb.gameObject, oldLayer);
    2517.                         return wpIDL;
    2518.                     }                
    2519.                 }
    2520.                 else if (target.GetComponent<RobotTargetDummy>())
    2521.                 {                  
    2522.                     if (Physics.SphereCast(rb.GetComponent<RobotAI>().chest.position, LOSSphereCastRadius, direction, out hit, rb.GetComponent<RobotAI>().weapon[wpIDL].range) && hit.transform.root == target.GetComponent<RobotTargetDummy>().hitRootTransfrom)
    2523.                     {
    2524.                         SetLayer(rb.gameObject, oldLayer);
    2525.                         return wpIDL;
    2526.                     }                
    2527.                 }
    2528.             }
    2529.         }
    2530.  
    2531.         // standard weapon checking loop
    2532.         // Special check condition for weapon on Hand:
    2533.         // 1. if hand weapon exit, forearmhand and hand weapon should not be consider
    2534.         // 2. some robot animation should be ban.
    2535.  
    2536.         for (int i = 0; i < rb.GetComponent<RobotAI>().weapon.Count; i++)
    2537.         {
    2538.             if (rb.GetComponent<RobotAI>().ExtraWpR != null && rb.GetComponent<RobotAI>().weapon[i].parentID == ParentID.RobotForeArmR)
    2539.             {
    2540.                 // Remove foreArmR weapon from choice
    2541.             }
    2542.             else if (rb.GetComponent<RobotAI>().ExtraWpL != null && rb.GetComponent<RobotAI>().weapon[i].parentID == ParentID.RobotForeArmL)
    2543.             {
    2544.                 // Remove foreArmL weapon from choice
    2545.             }
    2546.             else if ((rb.GetComponent<RobotAI>().ExtraWpR != null || rb.GetComponent<RobotAI>().ExtraWpL != null) && !Data.ExtraWeaponAllowAnimationList.Contains(rb.GetComponent<RobotAI>().weapon[i].RA0))
    2547.             {
    2548.                 // ban robot animation when either hand have weapon
    2549.             }
    2550.             else if (rb.GetComponent<RobotAI>().weapon[i].type == WeaponType.DefendTurret)
    2551.             {
    2552.                 // remove defend turret from choice
    2553.             }
    2554.             else
    2555.             {
    2556.                 // check CD, LOS(include range check)
    2557.                 // 3 case: Robot, robotTargetDummy(for nonRobotUnit), Turret(height is not too low for robot normal attack)
    2558.                 if (rb.GetComponent<RobotAI>().weapon[i].coolDownTimer + rb.GetComponent<RobotAI>().weapon[i].coolDown <= Data.currentTurn[(int)Data.currentMap])
    2559.                 {
    2560.                     if (target.GetComponent<RobotAI>())
    2561.                     {
    2562.                         /*
    2563.                         Physics.SphereCast(rb.GetComponent<RobotAI>().chest.position, LOSSphereCastRadius, direction, out hit, rb.GetComponent<RobotAI>().weapon[i].range);
    2564.                        
    2565.                         if (hit.transform != null)
    2566.                             Debug.Log(hit.transform.root + "  " + rb.GetComponent<RobotAI>().weapon[i].range + " " + hit.transform);
    2567.                         else
    2568.                             Debug.Log("nul" + "  " + rb.GetComponent<RobotAI>().weapon[i].range);
    2569.                             */
    2570.  
    2571.                         if (Physics.SphereCast(rb.GetComponent<RobotAI>().chest.position, LOSSphereCastRadius, direction, out hit, rb.GetComponent<RobotAI>().weapon[i].range) && hit.transform.root == target)
    2572.                         {
    2573.                             SetLayer(rb.gameObject, oldLayer);
    2574.                             return i;
    2575.                         }                    
    2576.                     }
    2577.                     else if (target.GetComponent<RobotTargetDummy>())
    2578.                     {                      
    2579.                         /*
    2580.                         Physics.SphereCast(rb.GetComponent<RobotAI>().chest.position, LOSSphereCastRadius, direction, out hit, rb.GetComponent<RobotAI>().weapon[i].range);
    2581.                         if (hit.transform != null)
    2582.                             Debug.Log(hit.transform.root + "  " + rb.GetComponent<RobotAI>().weapon[i].range + " " + target.GetComponent<RobotTargetDummy>().hitRootTransfrom);
    2583.                         else
    2584.                             Debug.Log("nul" + "  " + rb.GetComponent<RobotAI>().weapon[i].range);
    2585.                             */
    2586.                         if (Physics.SphereCast(rb.GetComponent<RobotAI>().chest.position, LOSSphereCastRadius, direction, out hit, rb.GetComponent<RobotAI>().weapon[i].range) && hit.transform.root == target.GetComponent<RobotTargetDummy>().hitRootTransfrom)
    2587.                         {
    2588.                             SetLayer(rb.gameObject, oldLayer);
    2589.                             return i;
    2590.                         }                    
    2591.                     }
    2592.  
    2593.                 }
    2594.             }
    2595.         }
    2596.  
    2597.         SetLayer(rb.gameObject, oldLayer);
    2598.         // Step 2. Find Shield
    2599.         // Shield range is 0, so the above loop will not select shield because of physic raycast failure
    2600.  
    2601.         // shield already equip, use it
    2602.         if (rb.GetComponent<RobotAI>().ExtraWpL != null && rb.GetComponent<RobotAI>().ExtraWpL.GetComponent<RobotBodyPartSpec>().weapon.type == WeaponType.Shield)
    2603.         {
    2604.             return rb.GetComponent<RobotAI>().weaponIDExtraWpL;
    2605.         }
    2606.  
    2607.         // shield not equip yet, check CD
    2608.         for (int i = 0; i < rb.GetComponent<RobotAI>().weapon.Count; i++)
    2609.         {
    2610.             if (rb.GetComponent<RobotAI>().weapon[i].type == WeaponType.Shield && rb.GetComponent<RobotAI>().weapon[i].coolDownTimer + rb.GetComponent<RobotAI>().weapon[i].coolDown <= Data.currentTurn[(int)Data.currentMap])
    2611.             {
    2612.                 return i;
    2613.             }
    2614.  
    2615.         }
    2616.  
    2617.         return 99;
    2618.     }
    2619.      
    2620.     void AutoScrollWindow()
    2621.     {
    2622.         float deltaX, deltaZ;
    2623.  
    2624.         deltaX = 0;
    2625.         deltaZ = 0;
    2626.  
    2627.         // Set scroll area      
    2628.         if (Input.mousePosition.x < screenAutoScrollLenght)
    2629.         {
    2630.             if (cameraHolder.position.x > 0)
    2631.                 deltaX = -cameraMoveSpeed;
    2632.         }
    2633.         else if (Input.mousePosition.x > screenW - screenAutoScrollLenght)
    2634.         {
    2635.             if (cameraHolder.position.x < 500)
    2636.                 deltaX = cameraMoveSpeed;
    2637.         }
    2638.  
    2639.         if (Input.mousePosition.y < screenAutoScrollLenght)
    2640.         {
    2641.             if (cameraHolder.position.z > 0)
    2642.                 deltaZ = -cameraMoveSpeed;
    2643.         }
    2644.         else if (Input.mousePosition.y > screenH - screenAutoScrollLenght)
    2645.         {
    2646.             if (cameraHolder.position.z < 500)
    2647.                 deltaZ = cameraMoveSpeed;
    2648.         }
    2649.  
    2650.         cameraHolder.Translate(new Vector3(deltaX, 0, deltaZ) * cameraMoveSpeed, Space.Self);
    2651.  
    2652.     }
    2653.  
    2654.     // Set object layer
    2655.     void SetLayer(GameObject obj, Layer layerNumber)
    2656.     {
    2657.         Transform[] list = obj.GetComponentsInChildren<Transform>();
    2658.         foreach (Transform child in list)
    2659.             child.gameObject.layer = (int)layerNumber;
    2660.  
    2661.     }
    2662.  
    2663.     //----------------------Save Data------------------------
    2664.  
    2665.     void SavePlayerRobotData()
    2666.     {
    2667.         int DataID;
    2668.  
    2669.         for (int i = 0; i < playerRobotTransformList.Count; i++)
    2670.         {
    2671.             DataID = playerRobotTransformList[i].GetComponent<RobotAI>().robotIndex;
    2672.             Data.playerRobot[DataID].position = playerRobotTransformList[i].position;
    2673.             Data.playerRobot[DataID].rotation = playerRobotTransformList[i].rotation;
    2674.         }
    2675.     }
    2676.  
    2677.     void SaveEnemyRobotData()
    2678.     {
    2679.         int DataID;
    2680.  
    2681.         for (int i = 0; i < enemyRobotTransformList.Count; i++)
    2682.         {
    2683.             DataID = enemyRobotTransformList[i].GetComponent<RobotAI>().robotIndex;
    2684.  
    2685.             Data.enemyRobot[DataID].position = enemyRobotTransformList[i].position;
    2686.             Data.enemyRobot[DataID].rotation = enemyRobotTransformList[i].rotation;
    2687.         }
    2688.  
    2689.     }
    2690.  
    2691.  
    2692.     //-------------------------Android Section-----------------
    2693.  
    2694.     /*
    2695.         void AndriodCameraControl()
    2696.         {
    2697.             //X & Z axis movement      
    2698.  
    2699.             if (Input.touchCount > 0 && Input.GetTouch(0).phase == TouchPhase.Moved)
    2700.                 if (Input.GetTouch(0).position.x > screenW / 2)
    2701.                 {
    2702.                     float x = cameraHolder.position.x + Input.GetTouch(0).deltaPosition.x;
    2703.                     float z = cameraHolder.position.z + Input.GetTouch(0).deltaPosition.y;
    2704.                     if (0 < x && x < 500 && -50 < z && z < 550)
    2705.                         cameraHolder.Translate(Input.GetTouch(0).deltaPosition.x, 0, Input.GetTouch(0).deltaPosition.y, Space.Self);
    2706.                 }
    2707.                 // Rotate camera
    2708.                 else
    2709.                 {
    2710.                     // rotate left/right
    2711.                     cameraHolder.Rotate(Vector3.up * Input.GetTouch(0).deltaPosition.x, Space.Self);
    2712.                     // rotate up/down
    2713.                     Camera.main.transform.Rotate(Vector3.right * -Input.GetTouch(0).deltaPosition.y, Space.Self);
    2714.                 }
    2715.         }
    2716.  
    2717.         */
    2718.  
    2719.     //-------------------Enemy Generator--------------
    2720.  
    2721.     // Add new enemy geenerator to scene
    2722.     void AddEnemyRobot()
    2723.     {
    2724.         Vector3 position = Vector3.zero;
    2725.         /*       do
    2726.                {
    2727.                    position = new Vector3(Random.Range(50, 2000), 400, Random.Range(50, 2000));
    2728.                } while (Physics.SphereCast(position, 30, Vector3.down, out h, 600) && h.transform.tag != Tag.Map.ToString() && h.point.y != 0);
    2729.                */
    2730.         position = new Vector3(1000, 400, 1100);
    2731.         GameObject obj = Instantiate(enemyRobotSpherePrefab);
    2732.         obj.transform.position = position;
    2733.  
    2734.         enemyRobotSphereList.Add(obj.transform);
    2735.  
    2736.     }
    2737.  
    2738.     //===============================UI==============================
    2739.  
    2740.     //-----------------RobotInfo Section----------------------------
    2741.     // Set currentRobot by battleManager before call
    2742.     void RobotInfoWindow()
    2743.     {
    2744.         uiMode = UIMode.RobotInfoWindow;
    2745.  
    2746.         robotInfoWindow.gameObject.SetActive(true);
    2747.         robotInfoWindow.GetComponent<RobotInfoManager>().currentRobot = currentSelectedRobot;
    2748.         robotInfoWindow.GetComponent<RobotInfoManager>().RobotInfoWindow();
    2749.     }
    2750.  
    2751.     // End Turn
    2752.     public void EndTurn()
    2753.     {
    2754.         if (uiMode == UIMode.Idle)
    2755.         {
    2756.             uiMode = UIMode.EnemyTurn;
    2757.             subuiMode = SubUIMode.EnemyMove;
    2758.         }
    2759.     }
    2760.  
    2761.     // Show robot health bar
    2762.     // or hide them when using cut in camera
    2763.     void ShowHealth()
    2764.     {
    2765.         const float delta = 20;
    2766.         if (Data.canvas.GetComponent<BattleManager>().mainCamera.gameObject.activeInHierarchy)
    2767.         {
    2768.             for (int i = 0; i < playerRobotTransformList.Count; i++)
    2769.             {
    2770.                 Vector3 screenPoint = mainCamera.GetComponent<Camera>().WorldToScreenPoint(playerRobotTransformList[i].position) - Vector3.up * delta;
    2771.  
    2772.                 playerRobotHealthBarList[i].gameObject.SetActive(true);
    2773.                 playerRobotHealthBarList[i].position = screenPoint;
    2774.                 playerRobotHealthBarList[i].GetComponent<Slider>().value = (float)(Data.playerRobot[i].armorMax - Data.playerRobot[i].armor) / Data.playerRobot[i].armorMax;
    2775.  
    2776.             }
    2777.  
    2778.             for (int i = 0; i < enemyRobotTransformList.Count; i++)
    2779.             {
    2780.                 Vector3 screenPoint = mainCamera.GetComponent<Camera>().WorldToScreenPoint(enemyRobotTransformList[i].position) - Vector3.up * delta;
    2781.  
    2782.                 enemyRobotHealthBarList[i].gameObject.SetActive(true);
    2783.                 enemyRobotHealthBarList[i].position = screenPoint;
    2784.                 enemyRobotHealthBarList[i].GetComponent<Slider>().value = (float)(Data.enemyRobot[i].armorMax - Data.enemyRobot[i].armor) / Data.enemyRobot[i].armorMax;
    2785.             }
    2786.         }
    2787.         else
    2788.         {
    2789.             for (int i = 0; i < playerRobotTransformList.Count; i++)
    2790.                 playerRobotHealthBarList[i].gameObject.SetActive(false);
    2791.  
    2792.             for (int i = 0; i < enemyRobotTransformList.Count; i++)
    2793.                 enemyRobotHealthBarList[i].gameObject.SetActive(false);
    2794.         }
    2795.     }
    2796.  
    2797.     // Update mini Map
    2798.     void MiniMap()
    2799.     {
    2800.         Vector3 position = Vector3.zero;
    2801.         GameObject obj;
    2802.  
    2803.         // destory old dot
    2804.         for (int i = 0; i < dotList.Count; i++)
    2805.             Destroy(dotList[i].gameObject);
    2806.         dotList.Clear();
    2807.  
    2808.         // create new dot
    2809.         // player robot, enemy robot
    2810.         for (int i = 0; i < playerRobotTransformList.Count; i++)
    2811.         {
    2812.             // miniMap size / terrain size = 100/2500 = 0.04
    2813.             position.x = playerRobotTransformList[i].position.x * 0.04f;
    2814.             position.y = playerRobotTransformList[i].position.z * 0.04f; // y->z
    2815.             obj = Instantiate(dotPlayerPrefab, position, transform.rotation);
    2816.             obj.transform.SetParent(miniMap);
    2817.             obj.transform.localPosition = position;
    2818.             dotList.Add(obj);
    2819.         }
    2820.  
    2821.  
    2822.         for (int i = 0; i < enemyRobotTransformList.Count; i++)
    2823.         {
    2824.             position.x = enemyRobotTransformList[i].position.x * 0.04f;
    2825.             position.y = enemyRobotTransformList[i].position.z * 0.04f; // y->z
    2826.             obj = Instantiate(dotEnemyPrefab, position, transform.rotation);
    2827.             obj.transform.SetParent(miniMap);
    2828.             obj.transform.localPosition = position;
    2829.             dotList.Add(obj);
    2830.         }
    2831.  
    2832.         // update camera icon
    2833.         position.x = cameraHolder.position.x * 0.04f;
    2834.         position.y = cameraHolder.position.z * 0.04f;
    2835.         miniMapCamera.localPosition = position;
    2836.         miniMapCamera.localRotation = Quaternion.Euler(0, 0, -cameraHolder.eulerAngles.y);
    2837.     }
    2838.  
    2839.  
    2840.     void SelectedRoboIcon(Transform rb, Vector3 position)
    2841.     {
    2842.         // Put icon at the robot position
    2843.         // find out ready weapon range.      
    2844.         List<int> rangeCount = new List<int>{ 0, 0, 0, 0, 0 };
    2845.         currentSelectedRoboIcon.position = new Vector3(position.x, currentSelectedRoboIcon.position.y, position.z);
    2846.  
    2847.         foreach (Weapon w in rb.GetComponent<RobotAI>().weapon)
    2848.         {
    2849.             if(w.type != WeaponType.DefendTurret)
    2850.                 switch (w.range)
    2851.             {
    2852.                 case 50:
    2853.                     if (w.coolDown+w.coolDownTimer <= Data.currentTurn[(int)Data.currentMap])
    2854.                         rangeCount[0]++;
    2855.                     break;
    2856.                 case 100:
    2857.                     if (w.coolDown + w.coolDownTimer <= Data.currentTurn[(int)Data.currentMap])                      
    2858.                     rangeCount[1]++;
    2859.                     break;
    2860.                 case 150: if (w.coolDown + w.coolDownTimer <= Data.currentTurn[(int)Data.currentMap])
    2861.                         rangeCount[2]++; break;
    2862.                 case 200: if (w.coolDown + w.coolDownTimer <= Data.currentTurn[(int)Data.currentMap])
    2863.                         rangeCount[3]++; break;
    2864.                 case 250: if (w.coolDown + w.coolDownTimer <= Data.currentTurn[(int)Data.currentMap])
    2865.                         rangeCount[4]++; break;
    2866.             }
    2867.         }
    2868.  
    2869.         for (int i = 0; i < rangeCount.Count; i++)
    2870.             iconRangeText[i].text = rangeCount[i].ToString();
    2871.     }
    2872.  
    2873.     void MousePointTo()
    2874.     {
    2875.         if (Camera.current != null)
    2876.         {
    2877.             RaycastHit h;
    2878.             Ray ray = Camera.current.ScreenPointToRay(Input.mousePosition);
    2879.             if (Physics.Raycast(ray, out h))
    2880.                 mousePointTo.GetComponent<Text>().text = h.transform.name;
    2881.         }
    2882.     }
    2883.     /*
    2884.     void ShowUnitBattleInfo()
    2885.     {
    2886.         if (Camera.current != null)
    2887.         {
    2888.             RaycastHit h;
    2889.             Ray ray = Camera.current.ScreenPointToRay(Input.mousePosition);
    2890.             if (Physics.Raycast(ray, out h) && h.transform.root.GetComponent<RobotAI>())
    2891.             {
    2892.                 Robot rbData = new Robot();
    2893.                 int id = 0;
    2894.                 if (h.transform.root.gameObject.CompareTag(Tag.PlayerRobot.ToString()))
    2895.                 {
    2896.                     id = h.transform.root.GetComponent<RobotAI>().robotIndex;
    2897.                     rbData = Data.playerRobot[id];
    2898.                 }
    2899.                 else if (h.transform.root.gameObject.CompareTag(Tag.EnemyRobot.ToString()))
    2900.                 {
    2901.                     id = h.transform.root.GetComponent<RobotAI>().robotIndex;
    2902.                     rbData = Data.enemyRobot[id];
    2903.                 }
    2904.  
    2905.                 unitBattleInfo.name.text = rbData.name.ToString();
    2906.                 unitBattleInfo.armor.text = rbData.armor.ToString("N0") + "/" + rbData.armorMax.ToString("N0");
    2907.                 unitBattleInfo.damage.text = rbData.damageFactor.ToString("N2");
    2908.  
    2909.                 // Get vaild Attack Range
    2910.                 int max = 0, min = 500;
    2911.                 foreach (Weapon w in h.transform.root.GetComponent<RobotAI>().weapon)
    2912.                 {
    2913.                     if (w.coolDown + w.coolDownTimer < Data.currentTurn[(int)Data.currentMap] && w.type != WeaponType.DefendTurret)
    2914.                     {
    2915.                         if (w.range > max)
    2916.                             max = w.range;
    2917.                         if (w.range < min)
    2918.                             min = w.range;
    2919.                     }
    2920.                 }
    2921.                 if (min == 500)
    2922.                     min = 0;
    2923.  
    2924.                 unitBattleInfo.range.text = min.ToString() + "-" + max.ToString();
    2925.             }
    2926.         }
    2927.     }
    2928.     */
    2929.     //---------------Event System---------------
    2930.     // 1. Create Event Randomly
    2931.     // 2. Setup event Button on UI
    2932.     // 3. Wait player to enter event
    2933.  
    2934.     void EventGenerator()
    2935.     {
    2936.  
    2937.  
    2938.     }
    2939.  
    2940.  
    2941.     //-------------Transform List Reset when robot die---------
    2942.     // 1. robot die
    2943.     // 2. robot ai lock on death mode
    2944.     // 3. clear up battle manager UI mode if the dying robot is the controlled robot or target
    2945.     // 4. Reset transform list
    2946.     // 5. destroy weapon effect dummy (dummy that do not use robot or target transform is not affected, e.g. machine gun subprojectile)
    2947.  
    2948.     public void RobotDeath(Transform dyingRB)
    2949.     {
    2950.         ResetProjectile(dyingRB);
    2951.         ResetUIMode(dyingRB);
    2952.         ResetTransformList(dyingRB);
    2953.         skillManager.KillAllEffect();
    2954.     }
    2955.  
    2956.     void ResetProjectile(Transform dyingRB)
    2957.     {
    2958.         if (uiMode == UIMode.PlayerRobotAttack || uiMode == UIMode.PlayerRobotMove || uiMode == UIMode.PlayerRobotRotate)
    2959.         {
    2960.             // destory dying robot projectile, and cancel the other side projectile
    2961.             if (dyingRB == currentSelectedRobot)
    2962.             {
    2963.                 currentSelectedRobotAI.CancelProjectileInScene(true);
    2964.                 currentSelectedRobotTarget.GetComponent<RobotAI>().CancelProjectileInScene(false);
    2965.             }          
    2966.             else if (dyingRB == currentSelectedRobotTarget)
    2967.             {
    2968.                 currentSelectedRobotAI.CancelProjectileInScene(false);
    2969.                 currentSelectedRobotTarget.GetComponent<RobotAI>().CancelProjectileInScene(true);
    2970.             }
    2971.         }
    2972.         else if (uiMode == UIMode.EnemyTurn)
    2973.         {          
    2974.             if (dyingRB == enemyRobotTransformList[currentEnemyRobotIndex])
    2975.             {
    2976.                 enemyRobotTransformList[currentEnemyRobotIndex].GetComponent<RobotAI>().CancelProjectileInScene(true);
    2977.                 AI.targetSelected.GetComponent<RobotAI>().CancelProjectileInScene(false);
    2978.             }
    2979.             else if (dyingRB == AI.targetSelected)
    2980.             {
    2981.                 enemyRobotTransformList[currentEnemyRobotIndex].GetComponent<RobotAI>().CancelProjectileInScene(false);
    2982.                 AI.targetSelected.GetComponent<RobotAI>().CancelProjectileInScene(true);
    2983.             }
    2984.         }
    2985.     }
    2986.  
    2987.     void ResetUIMode(Transform dyingRobot)
    2988.     {
    2989.         if (uiMode == UIMode.PlayerRobotAttack || uiMode == UIMode.PlayerRobotMove || uiMode == UIMode.PlayerRobotRotate)
    2990.         {
    2991.             if (dyingRobot == currentSelectedRobot || dyingRobot == currentSelectedRobotTarget)
    2992.             {
    2993.                 currentSelectedRobot = null;
    2994.                 currentSelectedRobotAI = null;
    2995.                 currentSelectedRobotTarget = null;
    2996.                 uiMode = UIMode.Idle;
    2997.                 CutInCameraSelector(CameraMode.Idle);
    2998.             }
    2999.         }
    3000.         else if (uiMode == UIMode.EnemyTurn)
    3001.         {
    3002.             // 0 1 2 3 4 5
    3003.             // 2 die, current id = 2
    3004.             // 0 1   3 4 5
    3005.             // reset transform list          
    3006.             // 0 1   2 3 4
    3007.             // next id(current id) = 2
    3008.             if (dyingRobot == enemyRobotTransformList[currentEnemyRobotIndex])
    3009.             {              
    3010.                 subuiMode = SubUIMode.EnemyMove;
    3011.             }
    3012.             else if (dyingRobot == AI.targetSelected)
    3013.             {
    3014.                 // if target die, enemy transform list will not be reset, so enemy robot index need to ++ to avoid the same robot take action again.
    3015.                 currentEnemyRobotIndex++;
    3016.                 subuiMode = SubUIMode.EnemyMove;
    3017.             }
    3018.         }
    3019.     }
    3020.  
    3021.  
    3022.     void ResetTransformList(Transform member)
    3023.     {
    3024.         Transform healthbar = null;
    3025.         int memberTFIndex, memberDataIndex;
    3026.  
    3027.         // remove robot from all list, destory robot
    3028.         // remove healthbar from this, and destory health bar
    3029.         // transform list in battle manager, health list in battle manager,  unit list in Data
    3030.         if (member.tag == Tag.PlayerRobot.ToString())
    3031.         {
    3032.             // transform list index = health bar list index
    3033.             // transform list index != data list index
    3034.             // need to reassign robotIndex, because it shift
    3035.  
    3036.             // get index and health bar
    3037.             memberTFIndex = Data.canvas.GetComponent<BattleManager>().playerRobotTransformList.IndexOf(member);
    3038.             memberDataIndex = member.GetComponent<RobotAI>().robotIndex;
    3039.             healthbar = Data.canvas.GetComponent<BattleManager>().playerRobotHealthBarList[memberTFIndex];
    3040.  
    3041.             // remove them from transfrom list
    3042.             Data.canvas.GetComponent<BattleManager>().playerRobotHealthBarList.RemoveAt(memberTFIndex);
    3043.             Data.canvas.GetComponent<BattleManager>().playerRobotTransformList.RemoveAt(memberTFIndex);
    3044.  
    3045.             // remove from Data list
    3046.             Data.playerRobot.RemoveAt(memberDataIndex);
    3047.             ShiftRobotID(memberDataIndex, Data.canvas.GetComponent<BattleManager>().playerRobotTransformList);
    3048.  
    3049.             // if the destory member is currentselected robot, it become null after destroy
    3050.         }
    3051.         else if (member.tag == Tag.EnemyRobot.ToString())
    3052.         {
    3053.             //Transform previousRB = Data.canvas.GetComponent<BattleManager>().enemyRobotTransformList[Data.canvas.GetComponent<BattleManager>().currentEnemyRobotIndex];
    3054.  
    3055.             memberTFIndex = Data.canvas.GetComponent<BattleManager>().enemyRobotTransformList.IndexOf(member);
    3056.             memberDataIndex = member.GetComponent<RobotAI>().robotIndex;
    3057.             healthbar = Data.canvas.GetComponent<BattleManager>().enemyRobotHealthBarList[memberTFIndex];
    3058.  
    3059.             Data.canvas.GetComponent<BattleManager>().enemyRobotHealthBarList.RemoveAt(memberTFIndex);
    3060.             Data.canvas.GetComponent<BattleManager>().enemyRobotTransformList.RemoveAt(memberTFIndex);
    3061.  
    3062.             Data.enemyRobot.RemoveAt(memberDataIndex);
    3063.             ShiftRobotID(memberDataIndex, Data.canvas.GetComponent<BattleManager>().enemyRobotTransformList);                      
    3064.         }
    3065.         // member destoy in explosion killer, health bar destory here
    3066.         Destroy(healthbar.gameObject, 1);
    3067.     }
    3068.  
    3069.     //transform list  0 1 2 3 4 5
    3070.     // data list 0 1 2 3 4 5
    3071.     // kill 2, then
    3072.     // TF 0 1 2 3 4
    3073.     // Data 0 1 2 3 4
    3074.     // but robot ID in RobotAI is  0 1 3 4 5
    3075.     // should be 0 1 2 3 4
    3076.  
    3077.     void ShiftRobotID(int removeID, List<Transform> rbList)
    3078.     {
    3079.         for (int i = 0; i < rbList.Count; i++)
    3080.             if (rbList[i].GetComponent<RobotAI>().robotIndex >= removeID)
    3081.                 rbList[i].GetComponent<RobotAI>().robotIndex--;
    3082.     }  
    3083.  
    3084.     //--------------Testing----------
    3085.  
    3086.     public void AddSkillTest()
    3087.     {
    3088.         for (int i = 0; i < Data.playerRobot.Count; i++)
    3089.         {
    3090.            
    3091.             Data.playerRobot[i].skill.Add( RobotSkill.Assist_Attack_I);
    3092.             Data.playerRobot[i].skill.Add(RobotSkill.Assist_Attack_II);
    3093.             Data.playerRobot[i].skill.Add(RobotSkill.Repeat_Attack);
    3094.             Data.playerRobot[i].skill.Add(RobotSkill.Taunt);
    3095.  
    3096.         }
    3097.  
    3098.        
    3099.     }
    3100.  
    3101.     public void SendRobotToOtherMap()
    3102.     {
    3103.         int transformListID = 0;
    3104.  
    3105.         // Set robot location in Data List
    3106.         int DataListID = playerRobotTransformList[transformListID].GetComponent<RobotAI>().robotIndex;
    3107.         Data.playerRobot[DataListID].map = Map.BossSpaceMap;
    3108.         Data.playerRobot[DataListID].onRBLauncher = false;
    3109.  
    3110.         // kick this robot from the fixedUpdate loop
    3111.         Data.playerRobot[DataListID].attackedThisTurn = true;
    3112.         Data.playerRobot[DataListID].movedThisTurn = true;
    3113.  
    3114.         // remove robot from transform list in battle manager,
    3115.         // remove relative healthBar
    3116.         Destroy(playerRobotTransformList[transformListID].gameObject);
    3117.         playerRobotTransformList.RemoveAt(transformListID);
    3118.  
    3119.         Destroy(playerRobotHealthBarList[transformListID].gameObject);
    3120.         playerRobotHealthBarList.RemoveAt(transformListID);
    3121.  
    3122.         // Now, robotIndex of RobotAi is correct, but transfromListID of Data is wrong      
    3123.         for (int i = 0; i < playerRobotTransformList.Count; i++)
    3124.         {
    3125.             DataListID = playerRobotTransformList[i].GetComponent<RobotAI>().robotIndex;
    3126.             Data.playerRobot[DataListID].transformListID = i;
    3127.         }
    3128.  
    3129.  
    3130.     }
    3131.  
    3132.  
    3133.     public void LoadOtherMap()
    3134.     {
    3135.         // when sub map is generated, start turn should be record
    3136.         // change map should not affect start turn of the map
    3137.  
    3138.         // test only
    3139.         Data.startTurn[(int)Map.BossSpaceMap] = Data.currentTurn[(int)Map.MainMap];
    3140.         Data.currentTurn[(int)Map.BossSpaceMap] = Data.currentTurn[(int)Map.MainMap];
    3141.  
    3142.         SceneManager.LoadScene(SceneList.BossSpaceMap.ToString());
    3143.  
    3144.     }
    3145. }
     
  6. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,186
    Yup, that's wrong. You're instantiating a new RobotAI, which is a MonoBehaviour. That'll not be a valid RobotAI.

    Not quite sure why the stack trace points you down to the array creation.
     
    Vryken likes this.
  7. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    I think I understand a bit after looking at https://answers.unity.com/questions/653904/you-are-trying-to-create-a-monobehaviour-using-the-2.html

    But how can I have a global reference for currentSelectedRobot.GetComponent<RobotAI>() which use often in script?

    When player click the robot:
    currentSelectedRobot = hit.transform.root;
    currentSelectedRobotAI = hit.transform.root.GetComponent<RobotAI>();
     
  8. ezjm427

    ezjm427

    Joined:
    May 17, 2014
    Posts:
    100
    Instead of doing RobotAI currentSelectedRobotAI = new RobotAI();, you have to do

    Code (CSharp):
    1. RobotAI currentSelectedRobotAI = gameObject.AddComponent<RobotAI>().
    The only downside is it'll be added to the GameObject's components in the inspector, but AddComponent will return the newly created RobotAI so it'll work. That's how you're supposed to make new objects that are Monobehaviors, something with how Monobehaviors work is restricting them so they have to be added to GameObjects.
     
  9. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    It don't work for global variable.

    The problem is I cannot put
    Code (CSharp):
    1. RobotAI currentSelectedRobotAI = gameObject.AddComponent<RobotAI>().
    in global. What I need is a global reference directly to RobotAI such that I dont need to access currentselectrobot and then access GetComponent<RobotAI>() everywhere. I think it reduce 50% workLoad?
     
  10. ezjm427

    ezjm427

    Joined:
    May 17, 2014
    Posts:
    100
    Attach it to a static GameObject that all robot AI's are contained in. If you just try to create a new one it won't work properly
     
  11. Xhitman

    Xhitman

    Joined:
    Oct 30, 2015
    Posts:
    452
    No any warning when I use

    Code (CSharp):
    1.  RobotAI currentSelectedRobotAI;
    although I don't know why.
     
  12. bobisgod234

    bobisgod234

    Joined:
    Nov 15, 2016
    Posts:
    1,042
    Just declaring currentSelectedRobotAI doesn't actually create an instance of RobotAI. Assuming that you can have no selected robot AI, you should be able to initialize currentSelectedRobotAI to null and set/unset it as needed.
     
  13. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,186

    When you declare a variable without setting it to something, as you're doing there, it gets set to the default value for that type. For classes, that's null, so it's equivalent to
     RobotAI currentSelectedRobotAI = null;