0
\$\begingroup\$

I have a space station with rooms and doors. Now the waypoints script will make the camera move to the waypoints with smooth rotation.

But I want that the camera will move on the baked areas like a character. Now the camera is moving through the walls to the waypoints and I want the camera to move through the right ways through halls and doors like it was a character.

All the doors in the space station are tagged as Waypoint. But the camera is moving through the walls to get to the next waypoint and I want the camera to move along a path like character moving on baked area with navmeshagent.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Waypoints : UnityEngine.MonoBehaviour
{
    // Adding selectable behaviour at the end of the path,
    // as requested from the comments.
    public enum PathCompleteBehaviour
    {
        Stop,
        Loop,
        Reverse,
        Random,
        PingPong
    }
    [Header("Path Behaviour")]
    public PathCompleteBehaviour pathBehaviour;

    [Space(5)]

    [Header("Waypoints")]
    public GameObject[] waypoints;
    public float distanceFromWP = 1;

    [Space(5)]

    [Header("Instances")]
    public GameObject[] instancesToMove;

    [Space(5)]

    [Header("Speed")]
    public float constantSpeed;
    public float minRandomSpeed, maxRandomSpeed;
    public bool randomSpeed = false;
    private bool randoms = true;
    public float rotationSpeed = 5f;

    public bool go = false;

    // Store parallel arrays for our movement parameters.
    private float[] movementSpeeds;    // Randomized speed per object.
    private int[] nextWaypointIndices; // Destination per object.

    private void Start()
    {
        // Changing terminology to be more standard.
        // - a "prefab" is a source asset you want to copy
        // - an "instance" is a copy of it that's been spawned in the scene
        instancesToMove = GameObject.FindGameObjectsWithTag("InstanceToMove");

        waypoints = GameObject.FindGameObjectsWithTag("Waypoint");

        movementSpeeds = new float[instancesToMove.Length];
        nextWaypointIndices = new int[instancesToMove.Length];

        RandomSpeed();
    }

    private void Update()
    {
        if (randomSpeed == true)
            randoms = true;
        RandomSpeed();

        if (go)
            WaypointsAI();
    }

    private void WaypointsAI()
    {
        // We want to iterate over the instances, not over the waypoints.
        for (int i = 0; i < instancesToMove.Length; i++)
        {
            // Check to see if we reached the last waypoint.
            // If so, stop / loop / turn around as needed.
            int waypointIndex = nextWaypointIndices[i];
            if (waypointIndex < 0 || waypointIndex >= waypoints.Length)
            {
                switch (pathBehaviour)
                {
                    case PathCompleteBehaviour.Stop:
                        // Leave it where it is and skip to the next instance.
                        continue;
                    case PathCompleteBehaviour.Loop:
                        // Wrap front to back / back to front.
                        waypointIndex = (waypointIndex + waypoints.Length) % waypoints.Length;
                        break;
                    case PathCompleteBehaviour.Reverse:
                        // Bounce back to the point before last.
                        waypointIndex += (movementSpeeds[i] > 0f) ? -2 : 2;
                        // Reverse direction.
                        movementSpeeds[i] *= -1f;
                        break;
                    case PathCompleteBehaviour.PingPong: 
                        // Between two last waypoints.
                        waypointIndex = (waypointIndex) % waypointIndex + 1;
                        break;
                }
                nextWaypointIndices[i] = waypointIndex;
            }


            // Look up the waypoint we want to move toward next.
            Vector3 waypoint = waypoints[waypointIndex].transform.position;

            // Read this instance's speed,
            // to compute how far it should move in this frame.
            float travel = Mathf.Abs(movementSpeeds[i]) * Time.deltaTime;

            // Apply the motion.
            Vector3 direction = (waypoints[waypointIndex].transform.position - instancesToMove[0].transform.position).normalized;
            Quaternion lookrotation = Quaternion.LookRotation(direction);
            instancesToMove[0].transform.rotation = Quaternion.Slerp(instancesToMove[0].transform.rotation, lookrotation, Time.deltaTime * rotationSpeed);
            Vector3 position = instancesToMove[i].transform.position;
            position = Vector3.MoveTowards(position, waypoint, travel);
            instancesToMove[i].transform.position = position;

            // If we're within a configurable tolerance of the
            // destination waypoint, set our destination
            // to the next waypoint after it.
            if ((position - waypoint).sqrMagnitude < distanceFromWP)
            {
                nextWaypointIndices[i] += (movementSpeeds[i] > 0f) ? 1 : -1;
            }
        }
    }

    private void RandomSpeed()
    {
        for (int i = 0; i < instancesToMove.Length; i++)
        {
            if (randomSpeed && randoms == true)
            {
                movementSpeeds[i] = Random.Range(minRandomSpeed, maxRandomSpeed);
                randoms = false;
            }
            else
            {
                movementSpeeds[i] = constantSpeed;
            }
        }
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ If you want behaviour like a NavMeshAgent, is it safe to assume you tried attaching a NavMeshAgent component and routing your movement instructions through it? How did that work out? Did you get stuck anywhere? \$\endgroup\$ – DMGregory Jul 29 '18 at 5:52
  • \$\begingroup\$ @DMGregory I did attached NavMeshAgent component to the camera and used instead this lline: instancesToMove[i].transform.position = position; with: agent.Wrap(position); and before that I got the NavMeshAgent component from the camera from instancesToMove[0] and changed the other places instead instancesToMove with the agent. When running the game the camera was rotating to the next waypoint moved a bit then stuck and was shaking a bit like it's trying to keep moving. \$\endgroup\$ – Benzi Avrumi Jul 29 '18 at 6:26
  • \$\begingroup\$ You can ask the NavMesh for a path from point A to point B, will be similar to what the NavMeshAgents does but it will not consider NavMeshObstacles (unless you are using carving in those obstacles). \$\endgroup\$ – arielsan Jul 29 '18 at 16:45

Your Answer

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

Browse other questions tagged or ask your own question.