0
\$\begingroup\$

[EDIT: Working code added]

[Original question]

I'm putting together a "raid cam" or "overview cam" for a given map in my shooter for an observing player to use to fly down a given preset path (to prevent griefing and cheating, this may change in my final build)

Unfortunately though I can get the program to invoke the given method, iterate through each of my points, and display this to the debug console, my player camera does not move from the very first start point. I'm attempting to use the Vector3.MoveTowards function at the moment but if there is a better way to move the camera between the points I am open to that.

[/Original question]

The code is as follows, and heavily commented for clarity on my thought process:

// Invoked from external function, takes precoded path and translates player between the given points
public void FlyThroughPath(List<Vector3> path){

    // If the flightpath is not empty
    if(path.Count > 0){
        // If we haven't already enabled fly through mode
        if (!enabled){
            Debug.Log ("enabling fly through mode");
            // Enable fly mode
            enabled = true;
            // Assign our starting point
            CurrentIndex = 0;
            StartPoint = path[0];
            // Move us to the start point
            transform.position = StartPoint;
        }else if (enabled && CurrentIndex < path.Count){
            Debug.Log ("Already enabled, moving to next point");
            // If the distance between the points is too far we keep moving towards that point
            if(Vector3.Distance(transform.position, path[CurrentIndex]) > 5.5f){
                Debug.Log("Too far keep moving");
                FlyToNextPoint(transform.position, path[CurrentIndex]);
            }else if (Vector3.Distance(transform.position, path[CurrentIndex]) <= 5.5f){
                Debug.Log ("Point reached move to next one");
                CurrentIndex++;
            }else{
                Debug.Log ("Ifs were too specific, whoops");
            }
        }else if(enabled && CurrentIndex >= path.Count){ // If enabled and we don't have another point in our path
            Debug.Log ("no more points let's disable the flythrough");
            // We have arrived at our last point so let's disable the flythrough;
            enabled = false;
        }
    }
}

// Takes two points and transforms the player camera between them at a preset speed
public void FlyToNextPoint(Vector3 start, Vector3 end){
    // Grab the time for movement speed and duration
    // Snag the player's last chosen speed for consistency
    m_speed = flyMotor.m_actualSpeed; 
    // put together the time we want to use between the two points
    float t = m_speed * Time.deltaTime; 
    // Move the player between the given points at the given speed
    Debug.Log ("Flying to " + end.ToString() + " from position " + start.ToString());
    // Move the player camera towards the next point from the given start point
    transform.position = Vector3.MoveTowards(start,end, t); 
}

EDIT: For clarity the function is evoked here:

// Update is called once per frame
void Update () {
   [...]
   else if(cInput.GetKeyUp("Fly Mode Start")){
        Debug.Log ("Flythrough initiated in FlyMotor");
        // Instantiate and start the flight path functions
        AutoFlyThrough = GetComponent<FlyThrough>();
        AutoFlyThrough.FlyThroughPath(FlightPath);
    }

    if(AutoFlyThrough != null){
        if (AutoFlyThrough.enabled){
            // Check the position and continue to move the player
            AutoFlyThrough.FlyThroughPath(FlightPath);
        }
    }
}
\$\endgroup\$
0
\$\begingroup\$

You can't assign transform.position = StartPoint at the beginning of each invocation of your FlyThroughPath. I'm assuming you're calling FlyThroughPath on every frame so I'll walk through quickly what's going on in each frame.

  1. Position gets reset to the first starting point
  2. Add a little bit of the distance to each point in the path to the position

After this occurs, it appears to be at the first point but is really a little bit of the way to every point (which is still not what you want).

Instead your algorithm should behave more like this

  1. Determine which point you're currently flying towards (keep track of this)
  2. Call transform.position = Vector3.MoveTowards(transform.position, NextPoint, t)
  3. If you reach the point, update the next point to the next in the list

Note that this probably requires keeping some state! You need to recall which index into the list you're currently flying towards. The index should be initialized to 0, and when it reaches the end of the array you know the fly through is over. You increment the index when you get very very close to the current destination point, you probably should not do floating point comparisons to see if they're equal. Instead check to see if the distance between the current position and the current destination is less than the speed at which you move.

\$\endgroup\$
  • \$\begingroup\$ At first glance I thought you were right about repeating the assignment in each frame, but looking at my debug output I only hit the first and second debug outputs once each, so I don't think that's what's happening. However I think you're right about checking the distance to the next point so I'll give that a whirl and report back. \$\endgroup\$ – Miguet Schwab Sep 9 '15 at 18:51
  • \$\begingroup\$ If you do not hit those debug statements multiple times then your function is only being called once, it must be called on each frame. You should make sure you call this on each frame, and if you need more help please include the rest of the code where you call this. \$\endgroup\$ – Alex Sherman Sep 9 '15 at 18:53
  • \$\begingroup\$ Just updated, let me know if I can provide more info. My goal was to call the function from the FlyController once and let it run through it's process in the flythrough controller. \$\endgroup\$ – Miguet Schwab Sep 9 '15 at 18:55
  • \$\begingroup\$ Yeah so like I said, you only call FlyThroughPath in a single frame, when the key is released. You need to continue calling it while the fly through is in progress, and for that you can check the status of the index state I described in my answer. \$\endgroup\$ – Alex Sherman Sep 9 '15 at 19:00
  • \$\begingroup\$ Added my code (that works!), thanks for your help @Vector57, if you have any suggestions on optimization I'll take them but I've got a working solution now thanks to you. \$\endgroup\$ – Miguet Schwab Sep 9 '15 at 21:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.