- Home /
RTS movement not working properly
I am fairly new to unity although I have some prior experience coding in C#. I am trying to make a basic RTS game and have been working on getting units to move properly and was looking for some help.
On my unit I have the following script`using UnityEngine; using System.Collections;
public class UnitSelect : MonoBehaviour {
// Use this for initialization
void Start ()
{
}
public int isHit;
public int isSelected;
// Update is called once per frame
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if(Physics.Raycast(ray,out hit))
{
isHit = 0;
isSelected = 1;
//Destroy(GameObject.Find(hit.collider.gameObject.name));
}
}
}
} ` and then on my camera I have this script using UnityEngine; using System.Collections;
public class Movement : MonoBehaviour
{
public GameObject unit;
public GameObject unit1;
public float unitSpeed = 0.00001f;
private UnitSelect unitSelect;
void Awake()
{
unitSelect = unit.GetComponent<UnitSelect> ();
unit1 = GameObject.Find("SphereUnit");
}
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (Input.GetMouseButtonDown (1))
{
Ray ray2 = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit2 = new RaycastHit();
if (Physics.Raycast(ray2, out hit2));
{
Debug.Log("Right click works");
if (unitSelect.isSelected == 1)
{
Debug.Log("Working");
unit1.renderer.material.color = Color.red;
unit1.transform.Translate( hit2.point * unitSpeed * Time.deltaTime);
}
}
}
}
}
The problem I am having is that the unit will move only a little way to the destination of the mouse click and then if you click somewhere else it will move in a seemingly random direction. I am also unsure on how to get this to work for multiple units so any suggestions for that would be welcome. I have Googled this issue but all the answers I found where working in Jacascript.
Thanks :)
Answer by daneislazy · Feb 08, 2015 at 02:46 PM
So this is basically a case of Translate not actually doing what you think it will do.
Firstly, it just changes the transform position like doing transform.position += destination
and since your multiplying by Time.deltaTime
the magnitude of the vector is shrunk down a lot so it only moves a little bit.
Secondly, since you are not getting the vector of the difference between the current point and the target point it's not a correct vector so that's possibly what's causing the second issue.
Another cause could be if the transform is rotating when moving. If rotated, doing the translate may cause the movement to be relative to the wrong direction and thus be just wrong.
As for solving all of these problems and using it with multiple units, check out the Unity tutorial on coroutines. http://unity3d.com/learn/tutorials/modules/intermediate/scripting/coroutines
It's also worth noting the tutorial is kind of using Lerp
wrong so you will probably want to change that or use MoveTowards
instead. And add some logic for controlling the speed of the unit.
Hope that helps!
Thank you for your answer! I have been trying to work out why it wasn't working for a while before I came to ask here. So would you recommend using a coroutine for all unit movement then?
possibly, it's mostly just personal preference; if you are running it with yield return null;
it works out to be the same as running a normal method/function every Update()
. but you can run it with a waitforseconds
ins$$anonymous$$d or just run a method every FixedUpdate()
since that's when all the physics stuff is calculated anyways so it should be fine, unless a unit is really fast.
For multiple units you could probably use an Array/List/Dictionary of all the GameObjects and their destination points and just iterate through it ins$$anonymous$$d of having a ton of methods/coroutines running(`Dictionary<GameObject, Vector3>` probably best).
I haven't really had to use something like this though; so whatever works.
edit: it keeps $$anonymous$$ring out my less than & greater than symbols
Yeah that's similar to what I was planning. An array of all the units in the map and a check to see if they are selected.
So what would the correct code be to move the selected unit to the mouse click? I am using ray casting but am unsure of exactly how to implement it and tutorials aren't helping
EDIT: From what I understand, I basically want to be doing something
if (mouse click) { move unit to mouse click }
It's basically covered in that video that I linked, there are also copies of the scripts he used under the video, the $$anonymous$$ouse scripts and the second coroutine script are basically bang on.
raycasting seems fine, if the ray is hitting multiple things, you could iterate through 'till you get ground or some tag you want. But yea If(mouseclick && unitSelected){ set target position for unit; } if you put the coroutine on every unit you could have a public targetVector3 in all the unit scripts and you could just set it with a master click script. gameObjectSelected.targetVector3 = clickPosition;
again basically what they did in the tutorial. $$anonymous$$ain difference will be the public in the mouse script will be a big array of units. And use Vector3.$$anonymous$$oveTowards
ins$$anonymous$$d of Lerp.