# Unity RTS Single Selection Problem

I am trying to build an RTS game and I have managed to form a way to select a unit using Raycast and the tag system. I made it so that if the object the ray falls onto is of tag "TankUnit" Make so and so variable true and allow it to move to another place. However, Units of the same tag even when not selected also move. How do I fix this problem? The script is bound to each unit.

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI;

public class UnitController: MonoBehaviour { bool clicked = false; //public float speed = 10f; //public float rotationSpeed = 10f;

 public LayerMask groundLayer;
public NavMeshAgent playerAgent;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButton(0))
{
Debug.Log("Clicked");
FindClickPos();
}
if (Input.GetMouseButton(1) && clicked == true)
{
Debug.Log("I clicked right mouse");
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
MoveTo(hit);
}
}
}
private void FindClickPos()
{
RaycastHit hitInfo = new RaycastHit();
bool hit = Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hitInfo);
if (hit == true)
{
Debug.Log("I hit " + hitInfo.collider.name);
if (hitInfo.collider.tag == "TankUnit")
{
Debug.Log("I hit" + hitInfo.collider.tag + "!");
clicked = true;
}
else
{
Debug.Log("I didnt hit a unit :/");
clicked = false;
}
}
else
{
Debug.Log("I didnt hit anything...");
clicked = false;
}
}
void MoveTo(RaycastHit hit)
{
Debug.Log("Position: " + hit.point);
playerAgent.SetDestination(hit.point);
}


}

The problem lies in the fact that you run the FindClickPos function for every unit. This means that if you hit 1 tank all the tanks will set their clicked variable to true. When you then right click to move all the tanks will move to that position.

To easily fix this you can check if the ray hit itself, if not you don't set clicked to true. The code below is not tested but should give you the idea.

if (hitInfo.collider.gameObject == this.gameObject)
{
Debug.Log("I hit" + hitInfo.collider.tag + "!");
clicked = true;
}


However as general advice I would recommend you don't add the player controller logic in the units themselves. Create a new script for the player controller and handle the input there. Since you have the information of the object in RaycastHit you can call the move functions from the playercontroller. This will also make your life easier when you expand the player controller logic like selecting multiple units.

• Thank you so much! I understand what you mean by not put the controller in the unit but where else should I put it? Should I create an empty and put it there? – Kiyo Oct 2 at 19:39
• You can create a separate script for your player controller that you attach to the camera for example. In this script you can put the FindClickPos function. If your raycast hits a unit you save it in a local variable. You also perform the right click logic there and call MoveTo on the saved unit from FindClickPos. – Arthur Oct 2 at 19:47