Basic vector 3 comparison script help needed(solved)

Hi guys
Bit embarrased can’t work this out and that I don’t know how to spell embarresed(bah) so I’m trying to figure out how to move a AI char from waypoint to waypoint. But I’m stuck so hope you are willing to help.

using UnityEngine;
using System.Collections;

public class movingman : MonoBehaviour {
    float x=280f;
    float y=1f;
    float z=280f;

     Vector3 across = new Vector3(5.0f,0.0f,0.0F);
        Vector3 away = new Vector3(0f,0f,25f);
    // Use this for initialization
    void Start () {
        Vector3 spot = new Vector3 (x,y,z);//place to move to   
    }
   
    // Update is called once per frame
    void Update ()
    {


    if (transform.position)!=(x variable)//check if positions across x axis match
        transform.Translate (across * Time.deltaTime);//if not move x
        if (transform.position)!=(z variable)//check if positions across z axis match
            transform.Translate (away * Time.deltaTime);//if not move z
                }
}

.

So how do i compare the x and z positions ?
Thx

Why do you have to compare it? Just move it from one Vector3 to the other. If any of the values are the same, there won’t be a change anyway. So instead of “across” and “away” variables, just have a single “destination” variable or something that’s (5, 0, 25).

Also, maybe try and get in the habit early on of giving variables meaningful names. Like “spot” doesn’t really say what it’s for. Maybe like “targetSpot” or “originSpot”, depending what it’s for.

Lastly, juuuuust in case this is your code and not just pseudo… writing this:

if (transform.position)!=(x variable)

Isn’t right. You want this:

if (transform.position.x != x)

What you need to keep in mind is that the components are stored as floating point numbers.

You don’t compare floating point numbers using “==”. The problem is that only certain small numbers can be stored (IEEE 754).

So when comparing floating point numbers, you don’t check whether they’re equal, because that won’t happen most of the time. Instead you check whether they’re almost equal.
You’ll need to write a function for that.

if (FloatsAlmostEqual(transform.position.x, x_variable))
    // Do something

^ Agreed, looking at your code it’s hard to tell what exactly you’re trying to do because there’s all sorts of variables that don’t seem to be serving any purpose. Your “spot” variable, for instance, is being declared in the Start function, so the scope of the variable is in the Start function- you won’t be able to see it from anywhere else. If you want, you can declare it in the class scope (like you did with x, y, and z), and then assign it a value in the start function and that’ll work fine.

Now, as for the information you’re actually looking for:

To actually achieve manual movement this way, there’s three popular methods: The first method to simply translate it from one spot to another, but that’s instant movement from point A to point B. You’ll have to do your vector and distance calculations beforehand if you want to increment it by time (free movement with WASD or a controller can work this way). The second method is to point the object at a point in space (make it look at it), and then just move the current object “forward” (toward the other object) by a rate of speed*time. This can be really useful if you set up a timer beforehand (walk toward X for 3 seconds, then stop). The third method involves the Vector3.MoveTowards function, which I especially like in cases like these because it won’t overshoot the target and start “flickering”- like a car that runs something over and then keeps reversing/accelerating to run it over again and again. If it’s going to overshoot it, it’ll just stick right to it instead.

EDIT: I hope I said something that may help you with the logic of this kind of thing, but upon looking back at the question it seems I misunderstood the problem. To answer what I now see as the actual problem, the others seem to have gotten there first. Transform.Position is actually a vector3, and as such it has 3 members called x, y, and z which are floats indicating their various positions along that axis in space. So, you just have to call transform.position.x to get the float value for x and compare it to some other value.

As TheSniperFan has stated, comparing float values is seriously annoying, and the solution he offered is only effective if you have absolute confidence that Object A is going to be getting incrementally closer to Object B. In this case, that may never happen, because overshooting your target by enough means it’ll reverse over it and overshoot it again by an equal amount- it won’t work unless the distance is being divided in some way. I think using the third approach I mentioned, the Vector3.MoveTowards() function, would be far better in this case as it avoids that kind of problem.

All of your code can be condensed to this:

using UnityEngine;
using System.Collections;
   
public class movingman : MonoBehaviour {
    public Vector3 TargetPosition = new Vector3(200f, 1f, 200f);
    float speed = 10f;

    void Start(){
    }
   
    void Update(){
        if(transform.position != TargetPosition)
            Vector3.MoveTowards(transform.position, TargetPosition, speed * Time.deltaTime);
    }
}

Thx guys this gives me a lot to work with I will play with them all see what fits best the reason i put the spot (x,y,z) in the start was because it threw a hissy fit when i tried to put it the class scope. I was wanting to use spot as a placeholder in that once a destination is reached new x,y,z coords are fed into it creating a waypoint or random wander type situation.

Ok so it compares the x now and moves accordingly but it does not compare the z? Ps not ignoring your advice above just want to be able to do it this way first then will do it the other ways.

using UnityEngine;
using System.Collections;

public class movingman : MonoBehaviour {
    float ax=280f;
    float by=1f;
    float cz=280f;
    Vector3 spot = new Vector3(0f,0f,0f) ;
     Vector3 across = new Vector3(25.0f,0.0f,0.0F);
        Vector3 away = new Vector3(0f,25f,25f);
    // Use this for initialization

      void Start() {
        ax = 500f;
        by = 1f;
        cz = 500f;
                  }

     
    // Update is called once per frame
    void Update ()
    {
        Vector3 spot = new Vector3 (ax,by,cz);//place to move to 

     if (transform.position.x>spot.x)//check if positions across x axis match
        transform.Translate (-across * Time.deltaTime);//if not move x
    if (transform.position.x<spot.x)//check if positions across x axis match
        transform.Translate (across * Time.deltaTime);//if not move x
        if (transform.position.z<spot.z);//check if positions across z axis match
        transform.Translate (away * Time.deltaTime);//if not move z
        //if (transform.position.z>spot.z);//check if positions across z axis match
        transform.Translate (-away * Time.deltaTime);//if not move z





    }
}

Also why if i put Vector3 spot = new Vector3 (ax,by,cz) in the void start does it equal (9,0,0) instead of the ax,by,cz values but if i put it in update it runs correct?

I think you’re really overworking yourself. It’s unnecessary to compare each axis value, and then move it along each axis individually, when you can just move it entirely based on a Vector3 position.

Also, with your current code you posted, you can get rid of lines 8, 14, 15, 16, and 23… and just have this in your declarations at the top.

Vector3 spot = new Vector3(500, 1, 500);

By declaring “spot” in the Update function… you’re creating a new variable called spot every single frame, instead of referencing a single version of it.

As for you actual post questions:

  1. It may actually be comparing the Z’s, but if you have line 31 commented out, as it appears to be, both 30 and 32 will execute, seemingly cancelling each other out.
  2. I can’t imagine any reason spot would equal (9, 0, 0) in this script unless you had those values set in the inspector… but your variables aren’t public, so don’t see that as the case either.

Ultimately though, once you get this figured out, you should definitely look to do something more towards Lysander’s example. The simplest method is often the best.

Well, line 31 is commented out. :face_with_spiral_eyes:
I don’t understand what you’re trying to say at the bottom. Punctuation please.

Also, this makes no sense:

float ax=280f;
float by=1f;
float cz=280f;
// ...
void Start() {
     ax = 500f;
     by = 1f;
     cz = 500f;
}

Why do you initialize them twice?

Hey
Yea i know its not super efficient but I need to understand why it doesn’'t work before I move on.
For instance if i put Vector3 spot = new Vector3(ax,by,cz) ; in the void start () it completely ignores it and uses the first initializations values (0,0,0)(9 was a typo sorry) this doesn’t make any sense to me. but if i put different values for ax,by,cz in start and put Vector3 spot = new Vector3(ax,by,cz) in update then it passes those values on. So i,m missing something here.

I did not have the line commented out in initial testing i was commenting lines out to try debug it and missed that reverting them back.

using UnityEngine;
using System.Collections;

public class movingman : MonoBehaviour {
    float ax=280f;
    float by=1f;
    float cz=280f;
    Vector3 spot = new Vector3(21f,21f,21f) ;
     Vector3 across = new Vector3(25.0f,0.0f,0.0F);
        Vector3 away = new Vector3(0.0f,25.0f,25.0f);
    // Use this for initialization

      void Start() {
        Vector3 spot = new Vector3(ax,by,cz) ;
                  }

       
    // Update is called once per frame
    void Update ()
    {
   
     if (transform.position.x>spot.x)//check if positions across x axis match
        transform.Translate (-across * Time.deltaTime);//if not move x
    if (transform.position.x<spot.x)//check if positions across x axis match
        transform.Translate (across * Time.deltaTime);//if not move x
    if (transform.position.z<spot.z);//check if positions across z axis match
        transform.Translate (away * Time.deltaTime);//if not move z
    if (transform.position.z>spot.z);//check if positions across z axis match
        transform.Translate (-away * Time.deltaTime);//if not move z
   
                   



    }
}

This is the code as i would like it to run and feel logically it should but it does not the value of spot is not changed in the start call! and no attempt is made to change the z value despite me using the same method as for the x axis.

  • Vector3 spot = new Vector3(500, 1, 500);
    Yes this would work but i am trying to figure this out with the intention of doing a waypoint route and random wander pattern which would require variables that can be changed on the fly.

The value of spot is not changed in the start call because by specifying a type, in this case Vector3, you’re declaring a NEW variable called spot, and not using the one you already made. You just need to remove the “Vector3” from line 14. This is similar to what I mentioned you were previously doing in Update. In fact if you’re going to set the values in Start, you don’t even need to set them in the declarations. In line 14 just have “Vector3 spot;” for line 8.

About it not doing anything with Z again… you have semi-colons at the end of your IF statements, lines 26 and 28. Honestly I’m surprised it even lets you compile with those there. So it’s moving it by both away AND -away, which is why it seems to not be doing anything.

HI Sniper did it to test what the hell was going on.
I initially had
Vector3 spot =new Vector3(ax,by,cz) ;in the void start()
the debug log i had right after this line showed that it had passed in the ax,by,cz values as set out in the original initialization but the Debug.log at the start of update showed these values were reset to (0,0,0)(the initial amounts ) .So i assigned diff values to the variables ax,by,cz in the start and debug.logged it the variable kept the altered values from the void start() and into the update. My question is why is the value of the vector 3 reverted back but the variables retain there altered values it doesn’t make any sense i can’t understand it

So just to be clear a altered vector 3 value is changed once update starts but a altered variable retains its value.

using UnityEngine;
using System.Collections;

public class movingman : MonoBehaviour {
    float ax=280f;
    float by=1f;
    float cz=280f;
    [COLOR=#ff4d4d]Vector3 spot = new Vector3(21f,21f,21f)[/COLOR] ;
     Vector3 across = new Vector3(25.0f,0.0f,0.0F);
        Vector3 away = new Vector3(0.0f,25.0f,25.0f);
    // Use this for initialization

      void Start() {
        Debug.Log (spot); //value should be  21,21,21 but instead throws up an error [COLOR=#ff8000] [/COLOR][COLOR=#ff4d4d]a local variable spot can not be used before it is declared? i thought i declared it here already[/COLOR]
        Debug.Log (ax); // value is 280
        Vector3 spot = new Vector3(ax,by,cz) ;
        [COLOR=#0000ff]Debug.Log (spot);// return values are 280,1,280[/COLOR]
        ax=400f;
       [COLOR=#000066] [/COLOR][COLOR=#b300b3]Debug.Log (ax); // returned values is 400[/COLOR]
    }
    
       
    // Update is called once per frame
    void Update ()
    {
       [COLOR=#0080ff] Debug.Log (spot);//return value is (21,21,21);[/COLOR]
        [COLOR=#b300b3]Debug.Log (ax);// return value is 400[/COLOR]
     if (transform.position.x>spot.x)//check if positions across x axis match
        transform.Translate (-across * Time.deltaTime);//if not move x
    if (transform.position.x<spot.x)//check if positions across x axis match
        transform.Translate (across * Time.deltaTime);//if not move x
    if (transform.position.z<spot.z);//check if positions across z axis match
        transform.Translate (away * Time.deltaTime);//if not move z
    if (transform.position.z>spot.z);//check if positions across z axis match
        transform.Translate (-away * Time.deltaTime);//if not move z
   
    }
}

Allso the // in my code was left in by accident with or without it still no movement on the z axis.

I just edited my last post a bit but… just so it’s here again. Two important things you need to understand.

  1. By saying “Vector3 spot = whatever” in Start instead of “spot = whatever”… you’re declaring a NEW variable called spot and not changing the one you already made. This would apply if it was a int, float, bool, anything, not just Vector3’s.

  2. You have semi-colons at the end of your IF statements on lines 32 and 34. So lines 33 and 35 are executing regardless of the outcome of those if statements. It IS moving along the Z, but it’s doing both “away” and “-away”… so it looks like it isnt.

You sir earn a chocolate chip cookie !! 2 cookies even:smile: Yea i am very much lost when it comes to punctuation so like salt I just put ;;;;; on everything:).
Next step is to try place a navmesh agent on this guy and then once that works get to doing movement better and mechanim root motion instead of assigned speed values hope it goes a lot smoother.
Here’s the successful albeit bloated code. Thx everyone for the help appreciate it!

using UnityEngine;
using System.Collections;

public class movingman : MonoBehaviour {
    float ax=280f;
    float by=1f;
    float cz=280f;
    Vector3 spot = new Vector3(21f,21f,21f) ;
     Vector3 across = new Vector3(20.0f,0.0f,0.0F);
        Vector3 away = new Vector3(0.0f,0.0f,20.0f);
    // Use this for initialization

      void Start() {
         spot = new Vector3(ax,by,cz) ;

    }
    
       
    // Update is called once per frame
    void Update ()
    {

     if (transform.position.x > spot.x)
    transform.Translate (-across * Time.deltaTime);
    if (transform.position.x < spot.x)
    transform.Translate (across * Time.deltaTime);
    if (transform.position.z < spot.z)
    transform.Translate (away * Time.deltaTime);
    if (transform.position.z > spot.z)
    transform.Translate (-away * Time.deltaTime);
   
    }
}

Yep thx was correcting while you typed this all out:smile:

Another way to handle all this moving around is to use NavMeshes.

Enclosed see a simple project with a bunch of waypoints and a little agent patrolling between them all randomly. The script and scene are both tiny, and it works pretty slick.

1927241–124491–nma3.zip (15.2 KB)

Yea that’s A+ pathfinding isn’t it?. I looked into that then went with rain instead then decided I should know how to do my own and so this rather torturous process began. but I now have a better understanding of movement so there’s that.