Hello
I am trying to setup a RTS type system where i can select a npc and move it around, It works fine when i have 1 npc in the scene to move, But if i duplicate that npc and select only 1 and move it, it will move all the npc’s i did not select.
Q. What am i missing here? Thanks.
private NavMeshAgent agent;
private Transform constructor;
private Animation anim;
public bool selected;
void Start ()
{
selected = false;
agent = gameObject.GetComponent<NavMeshAgent> ();
constructor = transform.FindChild("Constructor");
anim = constructor.GetComponent<Animation>();
}
void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Input.GetMouseButtonDown(0))
{
if (Physics.Raycast(ray, out hit))
{
if(hit.transform.tag == "Player")
{
selected = true;
}else{
selected = false;
}
}
}
if (Input.GetMouseButtonDown(1) && selected)
{
if (Physics.Raycast(ray, out hit))
{
agent.SetDestination(hit.point);
}
}
I am assuming that you attach this script to the NPC?
And the NPC has a tag called “Player”?
If these 2 statements are true, then YES, when one of the NPCs is clicked, both “feel” it and act as if selected.
The casting of the ray should be done in a separate script.
Here is the script for the NPCs (JS):
private var selected = false;
private var agent : NavMeshAgent;
private var anim : Animator;
private var MoveTo : Vector3;
private var NotSet = false;
function Start ()
{
anim = gameObject.transform.FindChild("Constructor").GetComponent(Animator);
agent = gameObject.GetComponent(NavMeshAgent);
}
function Update ()
{
if (selected && NotSet)
{
NotSet = false;
agent.SetDestination(MoveTo);
anim.SetTrigger("Move"); //I assume the NPC has a move animation
}
if (agent.pathStatus == NavMeshPathStatus.PathComplete)
{
anim.SetTrigger("Idle");
}
}
function Select (x : int)
{
selected = true;
}
function Deselect (x : int)
{
selected = false;
}
function Destination (d : Vector3)
{
MoveTo = d;
NotSet = true;
}
And attached to another (unrelated) GameObject, like the Camera:
private var selectedUnit : GameObject;
function Update ()
{
var hit : RaycastHit;
var ray: Ray = gameObject.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, hit))
{
if (hit.transform.tag == "Player" && Input.GetMouseButtonDown(0))
{
selectedUnit = hit.transform.gameObject;
selectedUnit.SendMessage("Select", 1);
}
if (hit.transform.tag == "Ground" && Input.GetMouseButtonDown(1))
{
selectedUnit.SendMessage("Destination", hit.point);
}
if (hit.transform.tag == "Ground" && Input.GetMouseButtonDown(0))
{
selectedUnit.SendMessage("Deselect", 1);
}
}
}
To work on multiple units keep an array of the selected gameObjects, and use a for loop (example js):
for (i in SelectedUnits)
{
i.SendMessage("Select", 1);
}