- Home /
Character doesn't stop and sits on top of target.
Hello there, I am currently trying to make it so that when you click on an enemy the character walks towards the target and stops at a certain range. The problem is that no matter what I set the distance to in the if statement it always walks right up to the target and sits on top of it. It fine for the player to be able to walk through/past them normally so I don't want a collider on them or the player. Could anyone help please. I use the same code for normal walking and that will stop before if i set the distance to a larger variable.
Also I must double click off of the target to get it to move away normally which is annoying me also if anyone could hep with that.
This is the clickToMove script.
if(Input.GetKeyDown(KeyCode.Mouse1))
{
enemyTarget = null;
Targeting targeting = GetComponent<Targeting>();
Plane playerPlane = new Plane(Vector3.forward, transform.position);
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
float hitdist = 0.0f;
if (targeting.selectedTarget != null) {
enemyTarget = GameObject.FindGameObjectWithTag ("Target").transform;
enemyDistance = Vector2.Distance(enemyTarget.position, transform.position);
}
else if(enemyTarget == null && playerPlane.Raycast (ray, out hitdist)) {
clickPosition = ray.GetPoint(hitdist);
}
}
if(enemyTarget != null && enemyDistance > 1.3f){ // Prevents code running when it doesn't need to
transform.position += (enemyTarget.position - transform.position).normalized * moveSpeed * Time.deltaTime;
}
if(enemyTarget == null && playerDistance > 0.1f){ // Prevents code running when it doesn't need to
transform.position += (clickPosition - transform.position).normalized * moveSpeed * Time.deltaTime;
}
This is the Targeting script.
public class Targeting : MonoBehaviour {
public Transform selectedTarget = null;
public int targetfound = 0;
void Update(){
if (Input.GetMouseButtonDown(1)){ // when button clicked...
Vector3 pos = Camera.main.ScreenToWorldPoint (Input.mousePosition);
//Debug.Log (pos);
RaycastHit2D hit; // cast a ray from mouse pointer:
hit = Physics2D.Raycast (pos, Vector3.zero);
if (hit != null && hit.transform != null && hit.transform.CompareTag("Enemy")) {
DeselectTarget(); // deselect previous target (if any)...
selectedTarget = hit.transform; // set the new one...
selectedTarget.tag = "Target";
targetfound = 1;
Debug.Log ("Enemy Targeted");
}
else{
DeselectTarget();
}
}
}
private void DeselectTarget(){
if (selectedTarget != null){ // if any guy selected, deselect it
selectedTarget.tag = "Enemy";
selectedTarget = null;
}
}
}
Answer by Lockstep · Jan 29, 2014 at 01:27 AM
Your infrastructure sure is pretty messy. For instance you have your Targeting class change the tag of your enemy and then have the movement script look for the tag instead of simply taking the selectedTarget directly from Targeting. But I don't think that this will cause the problem. (But may cause other problems at other places).
The main problem is likely to be caused by the fact that both scripts are dependant of each other but manage input independantly. This way you have no controll about which script gets managed first. Out of the blue: I assume the movement script gets handled first, finds that targeting.selectedTarget is null and thus just move as if no target was selected and sets movement type to "no target found". Later that frame the Targeting script gets served, detects the enemy and sets its selectTarget field accordingly. But that was just to late for the mover script.
In such cases always add in debug statements inside of each if option to check out which branch you are running into.
To fix your current problem I'd suggest to change the update method from the targeting script to an arbitrary public method and then call it from the mover script:
Inside of targeting:
public void FindTarget(){
//The code which was inside of update but without the if Mouse
}
Inside of the mover script:
if(mouse){
//other code
targeting.FindTarget();
//more code
}
Thanks for the reply.
Yeah I did the Tag thing to see if it would help, I had what you said before. Although this will help with when I add in attack and I only want it to hit one target. I'm sure there is an easier way but I'm new :) I've also added a bit so that if its already tagged as Target it doesn't deselect. Hopefully it doesn't cause any problems as I've had enough of this script now :/
O$$anonymous$$ so I've tried that and there isn't much difference, I've added some debug statements as well.
The first thing that happens when I click on an enemy is it says "Enemy Targeted".
if(enemyTarget != null && enemyDistance > 1.3f){
transform.position += (enemyTarget.position - transform.position).normalized * moveSpeed * Time.deltaTime;
Debug.Log("$$anonymous$$oving to Target");
}
So after it says "Enemy Targeted" it then says over and and over "$$anonymous$$oving to Target" but doesn't actually move, I have to click lots of times, and then it only moves part of the way. Once it gets to a certain range it just moves directly on top of the target and shakes.
I think I see the problem now. It's this line:
enemyDistance = Vector2.Distance(enemyTarget.position, transform.position);
Or rather where this line is. You only update your enemyDistance Variable when you click, but of course you want to update this information every frame.
Try moving this line out of if(mouse){}
´and in front of if(enemyDistance){}
.
That now giving me a a null reference exception error as it doesn't start with a target so enemyTarget is null. It does when I click on a target though move to them like I was intending, but I can't move around normally now. Its hard to see as well as the null reference comes up a lot as its part of the update.
Just add if(enemyTarget)
the line before updating enemy Distance.
if(enemyTarget)
It finally works! Thank you very much :D Its all these little things I need to learn, but I'm getting there. Thanks again!