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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Function order broken.

Discussion in 'Scripting' started by Garcia-Rojas, Aug 26, 2016.

  1. Garcia-Rojas

    Garcia-Rojas

    Joined:
    Sep 1, 2015
    Posts:
    16
    HI! I have a problem with my code, is like it's skipping one of the functions. Its suppose to make a enemy look at the player and then move to a position between boss.position and player.position but is like its skipping the lookat and is just moving forward. Without StartBossMovement() there is no problem, it looks at player but if i place him in order jumps over LookToPlayer(). All this is suppose to happen in ChoosAbility()

    Thanks in advance :D.


    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class BossMovement : MonoBehaviour {
    5.  
    6.     // Use this for initialization
    7.     //<>
    8.     // Use this for initialization
    9.     public float timeLeft = 3.0f;
    10.     public bool ableToChoose = true;
    11.     public bool ableToMove = false;
    12.  
    13.     Rigidbody bossRigidBody;
    14.  
    15.     GameObject player;
    16.  
    17.     //Movement Variables
    18.     GameObject dashpoint;
    19.  
    20.     public float speed = 1f;
    21.  
    22.     private bool isLerping;
    23.  
    24.     Vector3 startPos;
    25.     Vector3 endPos;
    26.  
    27.     float timeStartedLerping;
    28.  
    29.  
    30.  
    31.  
    32.     void Start () {
    33.         dashpoint = GameObject.Find ("BossDashPoint");
    34.         player = GameObject.FindGameObjectWithTag ("Player");
    35.  
    36.         bossRigidBody = GetComponent<Rigidbody> ();
    37.  
    38.     }
    39.  
    40.     void FixedUpdate()
    41.     {
    42.         Lerping ();
    43.  
    44.     }
    45.     // Update is called once per frame
    46.     void Update () {
    47.  
    48.         if (ableToChoose == true) {
    49.             timeLeft -= Time.deltaTime;
    50.             CountDown ();
    51.         }
    52.      
    53.  
    54.     }
    55.     void CountDown()
    56.     {
    57.         if (timeLeft <= 0) {
    58.             ChooseAbility ();
    59.             timeLeft = 3.0f;
    60.         }
    61.     }
    62.      
    63.  
    64.    void ChooseAbility()
    65.     {
    66.         timeLeft = 3.0f;
    67.         int ability = Random.Range (1, 3);
    68.  
    69.         if (ability <= 3) {
    70.             LookToPlayer ();
    71.             StartBossMovement ();
    72.                          
    73.         }
    74.     }
    75.  
    76.     void LookToPlayer()
    77.     {
    78.         Vector3 bossToPlayer = player.transform.position - transform.position;
    79.         bossToPlayer.y = 0f;
    80.  
    81.         Quaternion newRotation = Quaternion.LookRotation (bossToPlayer);
    82.         bossRigidBody.MoveRotation (newRotation);
    83.         ableToMove = true;
    84.     }
    85.  
    86.  
    87.  
    88.     void StartBossMovement()
    89.     {
    90.      
    91.         startPos = transform.position;
    92.         endPos =  dashpoint.transform.position;
    93.  
    94.         isLerping = true;
    95.      
    96.         timeStartedLerping = Time.time;
    97.  
    98.  
    99.     }
    100.     void Lerping()
    101.     {
    102.  
    103.         float timeDurlingLerp = speed;
    104.  
    105.         if (isLerping) {
    106.  
    107.             float timeSinceStarted = Time.time - timeStartedLerping;
    108.             float percentageComplete = timeSinceStarted / timeDurlingLerp;
    109.  
    110.             transform.position = Vector3.Lerp (startPos, endPos, percentageComplete);
    111.  
    112.             if (percentageComplete >= 1.0f) {
    113.                 isLerping = false;
    114.             }
    115.  
    116.         }
    117.  
    118.     }
     
    Last edited: Aug 26, 2016
  2. bigmisterb

    bigmisterb

    Joined:
    Nov 6, 2010
    Posts:
    4,221
    OK, I see some weird usage of lerp here. Possibly your error, but I am not going to focus on that. I am going to focus on showing you a different system. A Finite State machine. This is where you give an AI (which is what you are trying to do) some things it can do, and then set it off to do them.

    So, consider you had 3 states, Idle, Wander and Attack. You can then summarize that in each of these states, the monster can do only certain things. Sit, move to a new position, or attack the player.

    With this, you only need a target to move to. You simply update the target based off of your action. If you are attacking, you do this every frame.

    I attached the code for this, and did some simple things. This type of AI is pretty expandable.
    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [RequireComponent(typeof(Rigidbody))]
    5. public class AIStateMachine : MonoBehaviour {
    6.     public enum AIState{
    7.         Idle,
    8.         Wander,
    9.         Attack
    10.     }
    11.     public float speed = 1; // speed of the monster
    12.     public float attackIfPlayerIsWithin = 10; // attack if the player is within X
    13.    
    14.     public AIState state = AIState.Idle; // the current state
    15.     Vector3 startPosition; // used to figure wandering
    16.     Vector3 target; // where we want to move
    17.     float timeToNextState = 0; // time to the next ai switch
    18.     Vector2 wanderRadius = new Vector2(5, 10); // how far we can wander from our start position;
    19.     GameObject player; // the player
    20.     Rigidbody rigidbody;
    21.    
    22.     // collect some info at start up
    23.     void Start(){
    24.         startPosition = transform.position;
    25.         rigidbody = GetComponent<Rigidbody> ();
    26.     }
    27.    
    28.     void Update(){
    29.         // if we haven't found a player, see if we can find him
    30.         if(player == null){
    31.             player = GameObject.FindWithTag("Player");
    32.         }
    33.  
    34.         // see if we need to, and can find a player to attack
    35.         if(player != null && state != AIState.Attack){
    36.             // see if a player is close to us.
    37.             if((transform.position - player.transform.position).sqrMagnitude < attackIfPlayerIsWithin * attackIfPlayerIsWithin){
    38.                 timeToNextState = Time.time + 1;
    39.             }
    40.         }
    41.  
    42.        
    43.  
    44.         // check to see if our wander has reached the destination.
    45.         if (state == AIState.Wander) {
    46.             float sqrDistanceToTarget = (new Vector3(transform.position.x - target.x, 0, transform.position.y - target.y)).sqrMagnitude;
    47.             if (sqrDistanceToTarget < 1) timeToNextState = 0;
    48.         }
    49.        
    50.         // if it is time, pick a new state
    51.         if(Time.time > timeToNextState){
    52.             timeToNextState += 3;
    53.             state = (AIState)Random.Range(0, 2);
    54.  
    55.             // update the target.
    56.             switch (state)
    57.             {
    58.                 case AIState.Idle: target = transform.position; break;
    59.                 case AIState.Wander:
    60.                     var rnd = Random.insideUnitCircle.normalized;
    61.                     rnd *= Random.Range(wanderRadius.x, wanderRadius.y);
    62.                    
    63.                     target = startPosition + new Vector3(rnd.x, 0, rnd.y);
    64.                     break;
    65.             }
    66.         }
    67.  
    68.         // override target position if we are attacking
    69.         if(state == AIState.Attack) target = player.transform.position;
    70.        
    71.        
    72.        
    73.         // update the look rotation
    74.         if(state != AIState.Idle){
    75.             var lookAt = new Vector3(target.x, transform.position.y, target.z);
    76.             transform.LookAt(lookAt);
    77.         }
    78.  
    79.         Debug.DrawLine(target, target + Vector3.up, Color.red);
    80.     }
    81.    
    82.     // handle movement if needed
    83.     void FixedUpdate(){
    84.         if(state != AIState.Idle){
    85.             var lookAt = new Vector3(target.x, transform.position.y, target.z);
    86.             transform.LookAt(lookAt);
    87.             rigidbody.MovePosition(transform.position + transform.forward * speed * Time.fixedDeltaTime);
    88.         }
    89.     }
    90. }
     
  3. Garcia-Rojas

    Garcia-Rojas

    Joined:
    Sep 1, 2015
    Posts:
    16
    Thanks for your quick answer! Gonna have a look to your code :D

    Edit.

    Believe it or not i solve it changing the LookAtPlayer() funciton to transform.LookAt(lookAt) frome your code. Anyway i think im gona use your option, it seems much better than my ugly code :D

    Thanks againg for your help :)
     
    Last edited: Aug 26, 2016