Search Unity

RTS Problem

Discussion in 'Scripting' started by danielbutler94, Dec 6, 2012.

  1. danielbutler94

    danielbutler94

    Joined:
    May 28, 2012
    Posts:
    83
    Hello! I am making a basic RTS engine using the A* Pathfinding project and I have ran into a bit of a dead end. The unit goes where I tell it to only when selected but the problem is that it stops moving if I deselect it. In other words for the unit to move the player needs to keep it selected.

    The following is my Selectable.cs

    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4.  
    5. public class Selectable : MonoBehaviour {
    6. //Selected
    7. public bool selected = false;
    8.  
    9. //Team and Alliance
    10. public int team= 0;    //Team is the player who the unit is loyal to
    11. public int alliance= 0;//Alliance is the group of players it is loyal to
    12.  
    13.  
    14. //Set the color of the unit to the team color
    15. void  Start (){
    16.  
    17. }
    18.  
    19. //If a unit is selected then enable its Projector to show it
    20. void  Update (){
    21.     if(selected){
    22.         if(!transform.Find("Plane").GetComponent<MeshRenderer>().enabled)
    23.             transform.Find("Plane").GetComponent<MeshRenderer>().enabled = true;
    24.  
    25.     }
    26.     else{
    27.         if(transform.Find("Plane").GetComponent<MeshRenderer>().enabled)
    28.             transform.Find("Plane").GetComponent<MeshRenderer>().enabled = false;
    29.  
    30.     }
    31. }
    32. }
    and my actual AstarAI.cs

    Code (csharp):
    1. using System.Collections;
    2. //Note this line, if it is left out, the script won't know that the class 'Path' exists and it will throw compiler errors
    3. //This line should always be present at the top of scripts which use pathfinding
    4. using Pathfinding;
    5.  
    6. public class AstarAI : MonoBehaviour {
    7.     //The point to move to
    8.     public Vector3 targetPosition;
    9.     private Seeker seeker;
    10.     private CharacterController controller;
    11.     public Selectable selectable;
    12.  
    13.  
    14.     //The calculated path
    15.     public Path path;
    16.    
    17.     //The AI's speed per second
    18.     public float speed = 100;
    19.     RaycastHit hit;
    20.     Ray ray;
    21.    
    22.    
    23.     //The max distance from the AI to a waypoint for it to continue to the next waypoint
    24.     public float nextWaypointDistance = 3;
    25.  
    26.     //The waypoint we are currently moving towards
    27.     private int currentWaypoint = 0;
    28.    
    29.     float raycastlength = 1000;
    30.  
    31.     public void Start () {
    32.         seeker = GetComponent<Seeker>();
    33.         controller = GetComponent<CharacterController>();
    34.         selectable = GetComponent<Selectable>();
    35.  
    36.        
    37.         //Start a new path to the targetPosition, return the result to the MyCompleteFunction
    38.         seeker.StartPath (transform.position, targetPosition, MyCompleteFunction);
    39.     }
    40.    
    41.     public void MyCompleteFunction (Path p) {
    42.         Debug.Log ("Yey, we got a path back. Did it have an error? "+p.error);
    43.         if (!p.error) {
    44.             path = p;
    45.             //Reset the waypoint counter
    46.             currentWaypoint = 0;
    47.         }
    48.     }
    49.  
    50.  
    51.     public void Update () {
    52.         if (path == null) {
    53.             //We have no path to move after yet
    54.             return;    
    55.  
    56.         }
    57.    
    58.        
    59.          
    60.         if (selectable.selected == true)
    61.         {
    62.        
    63.         if (Input.GetButtonDown("Fire1"))
    64.         {  
    65.        
    66.             ray = Camera.main.ScreenPointToRay (Input.mousePosition);
    67.            
    68.        
    69.        
    70.         if (Physics.Raycast(ray, out hit, raycastlength))
    71.         {
    72.            
    73.             targetPosition = hit.point;
    74.             seeker.StartPath (transform.position, targetPosition, MyCompleteFunction);
    75.  
    76.                    
    77.         }
    78.        
    79.            
    80.         }
    81.        
    82.        
    83.         if (currentWaypoint >= path.vectorPath.Length) {
    84.             Debug.Log ("End Of Path Reached");
    85.             return;
    86.         }
    87.        
    88.         //Direction to the next waypoint
    89.         Vector3 dir = (path.vectorPath[currentWaypoint]-transform.position).normalized;
    90.         dir *= speed * Time.deltaTime;
    91.         controller.SimpleMove (dir);
    92.        
    93.         if (Vector3.Distance (transform.position,path.vectorPath[currentWaypoint]) < nextWaypointDistance) {
    94.             currentWaypoint++;
    95.             return;
    96.         }
    97.     }
    98.     }
    99.    
    100.     }
    Any help in how to fix this would mean alot to me! Thank you :D
     
  2. Swearsoft

    Swearsoft

    Joined:
    Mar 19, 2009
    Posts:
    1,632
    Isn't it obvious that this update only functions when if (selectable.selected == true)

    I think you should close it off sooner than if (currentWaypoint >= path.vectorPath.Length) {
    in order to get it to work as intended. Meaning add a "}" before above line and remove one"}" from
    after line 96.

    I think that should do it. Though maybe we would want to somehow indicate that the unit is Active or something
    so we don't do Length calculations each frame even when the unity is at it's intended location. Maybe use the if (path== null) with and else to achieve this. So if there is a path it will continue.
     
    Last edited: Dec 6, 2012