- Home /
Character keeps walking to origin with Raycast?
Hi! As of right now I'm trying to get my character to walk to where my cursor clicks by using a ray. The hit.point keeps getting reset back to (0,0,0), am I using it right? Please let me know if you need any more information. Thank you! :)
#pragma strict
private var character : GameObject;
private var move : boolean;
function Update ()
{
if (Input.GetButtonUp("Fire1"))
{
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var hit: RaycastHit;
// Move the character if it hits a collider and make it face where the point is.
if (Physics.Raycast(ray, hit))
{
move = true;
// Get the Character.
character = GameObject.Find("Main Character");
// Initiate the walking animation.
character.animation.Play("walk");
}
}
if(move)
{
Debug.Log(hit.point);
character.transform.LookAt(hit.point);
character.transform.rotation.x = 0;
character.transform.rotation.z = 0;
character.transform.Translate(Vector3.forward * Time.deltaTime * 5);
if (Vector3.Distance(character.transform.position,hit.point) < .10 )
{
move = false;
}
}
}
Answer by Peter G · Aug 05, 2013 at 01:09 AM
The problem has to do with the scope of hit
. I'm actually a little surprised the js
compiler will let you do that (because hit
is declared in one if
statement then you access it in another). You declared hit
with local scope (it's inside of the Update()
function). Every frame after Update()
is called, all the local variables go out of scope and are appropriately garbage collected. What's happening to you is that when the user lifts up the "Fire1" button, hit.point
is equal to whatever point they clicked on.
Then hit
is recreated the next frame. Only this time it doesn't store the information you want. It doesn't really store anything useful. All the values are just initialized to their default values. So hit.point
just stores the default Vector3 value which is (0,0,0)
.
Now, how to fix it. You're going to want to store the hit.point
in another variable outside of Update()
that will store it until you have reached your destination.
#pragma strict
private var character : GameObject;
private var move : boolean;
private var targetPoint : Vector3;
//we'll store the target point here.
function Update ()
{
if (Input.GetButtonUp("Fire1"))
{
var ray : Ray = Camera.main.ScreenPointToRay(Input.mousePosition);
var hit: RaycastHit;
// Move the character if it hits a collider and make it face where the point is.
if (Physics.Raycast(ray, hit))
{
move = true;
targetPoint = hit.point;
//store the position.
// Get the Character.
character = GameObject.Find("Main Character");
// Initiate the walking animation.
character.animation.Play("walk");
}
}
if(move)
{
character.transform.LookAt(targetPoint);
//targetPoint won't reset between frames.
character.transform.rotation.x = 0;
character.transform.rotation.z = 0;
character.transform.Translate(Vector3.forward * Time.deltaTime * 5);
if (Vector3.Distance(character.transform.position, targetPoint) < .10 )
{
move = false;
}
}
}
THAN$$anonymous$$ YOU SO $$anonymous$$UCH! :D
It works! However, when my character reaches the point I clicked on the animation keeps glitching. $$anonymous$$ove never gets set to false? Hmm...
Stopping the animation should be easy enough, Just have it Play/CrossFade into your "Idle" animation.
character.animation.Play("Idle");
It's also possible that your character is hopping over the stopping point. If the character moves more than .2 units in one frame then its possible the character can jump right over the point, realize they've gone to far turn around only to do the same thing again.
To test to see if that's your problem, increase the tolerance in your if
statement to something big like 1. If that solves your problem, then just s$$anonymous$$dily decrease the tolerance until the character starts glitching again. Then go back up to the radius right before that.
if (Vector3.Distance(character.transform.position, targetPoint) < 1 ) {
if that works...
if (Vector3.Distance(character.transform.position, targetPoint) < .5 ) {
and so forth.
This is so weird... $$anonymous$$y I cannot get it to work. I've tried crossfading the animations and I've set a counter as to how many times it keeps going through the if statement. $$anonymous$$y character just keeps circling around the point indefinitely. I can sometimes get it to work if I set the distance above 20 or so... I'm really not sure what's wrong here. Again, thanks a ton for your help!
// $$anonymous$$ove the character to the clicked point.
if(move)
{
character.transform.LookAt(targetPoint);
character.transform.rotation.x = 0;
character.transform.rotation.z = 0;
character.transform.Translate(Vector3.forward * Time.deltaTime * speed);
count++;
Debug.Log(count);
if (Vector3.Distance(character.transform.position,hit.point) < 15 )
{
Debug.Log("HEREEEE");
move = false;
character.animation.CrossFade("idle");
}
}
In the code you just posted, you didn't change hit.point to targetPoint in the Vector3.Distance() check
Your answer
Follow this Question
Related Questions
Raycast hit not detected on cube 1 Answer
detecting if the mouse is inside any gui element 1 Answer
How do you use a queuing mechanism in Unity? 1 Answer
RayCast Hit Point rounding itself...? 1 Answer
Pathfinding for Point & click game ? 0 Answers