- Home /
3D RPG - Player movement - He automatically finds the fastest way and goes around everything. How to limit his movement?
Hello guys, I'm working on a rpg game like Diablo. I wanted to make my character move when I Right click on the terrain and I did it by making two scripts - one for the movement itself and one for the controllers (left / right clicking) BUT he finds the fastest way to go to the place. For example if I have made something like barriers between two zones. My character is in Zone 1. When I click on Zone 2 he automatically finds the fastest way and goes around the barriers till he is in the place I clicked in Zone 2. I want him to move when I click somewhere but I don't want him to explore the map himself by finding the fastest way.
I will put my movement script here:
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.AI;
 
 /* This component moves our player using a NavMeshAgent. */
 
 [RequireComponent(typeof(NavMeshAgent))]
 public class PlayerMotor : MonoBehaviour
 {
     Transform target;       // Target to follow
     NavMeshAgent agent;     // Reference to our agent
 
     // Get references
     void Start()
     {
         agent = GetComponent<NavMeshAgent>();
     }
     void Update()
     {
         if(target != null)
         {
             agent.SetDestination(target.position);
             FaceTarget();
         }
     }
 
     public void MoveToPoint(Vector3 point)
     {
         agent.SetDestination(point);
     }
 
     public void FollowTarget(Interactable newTarget)
     {
         agent.stoppingDistance = newTarget.radius * .8f;
         agent.updateRotation = false;
         target = newTarget.interactionTransform;   
     }
     public void StopFollowingTarget()
     {
         agent.stoppingDistance = 0f;
         agent.updateRotation = true;
         target = null;      
     }
 
   void FaceTarget()
     {
         Vector3 direction = (target.position - transform.position).normalized;
         Quaternion lookRotation = Quaternion.LookRotation(new Vector3(direction.x, 0f, direction.z));
         transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, Time.deltaTime * 5f);
     }
 }
and here is the one with the controllers:
 using UnityEngine.EventSystems;
 using UnityEngine;
 
 /* Controls the player. Here we choose our "focus" and where to move. */
 
 [RequireComponent(typeof(PlayerMotor))]
 public class PlayerController : MonoBehaviour
 {
     public Interactable focus;
 
     public LayerMask movementMask;  // Filter out everything not walkable
 
     Camera cam;         // Reference to our camera
     PlayerMotor motor;  // Reference to our motor
 
     // Get references
     void Start()
     {
         cam = Camera.main;
         motor = GetComponent<PlayerMotor>();
     }
 
     // Update is called once per frame
     void Update()
     {
         if (EventSystem.current.IsPointerOverGameObject())
             return;
 
         // If we press left mouse
         if (Input.GetMouseButtonDown(0))
         {
             // We create a ray
             Ray ray = cam.ScreenPointToRay(Input.mousePosition);
             RaycastHit hit;
 
             // If the ray hits
             if (Physics.Raycast(ray, out hit, 100, movementMask))
             {
                 motor.MoveToPoint(hit.point);   // Move to where we hit
                 RemoveFocus();
             }
         }
 
         // If we press right mouse
         if (Input.GetMouseButtonDown(1))
         {
             // We create a ray
             Ray ray = cam.ScreenPointToRay(Input.mousePosition);
             RaycastHit hit;
 
             // If the ray hits
             if (Physics.Raycast(ray, out hit, 100))
             {
                 Interactable interactable = hit.collider.GetComponent<Interactable>();
                 if(interactable != null)
                 {
                     SetFocus(interactable);
                 }
             }
         }
     }
     void SetFocus(Interactable newFocus)
     {
         if (newFocus != focus)
         {
             if (focus != null)
                 focus.OnDefocused();
 
             focus = newFocus;
             motor.FollowTarget(newFocus);
         }
         newFocus.OnFocused(transform);
         
     }
     void RemoveFocus()
     {
         if (focus != null)
             focus.OnDefocused();
 
         focus = null;
         motor.StopFollowingTarget();
     }
 }
 
Answer by GanemVisk · Dec 26, 2019 at 11:45 PM
I believe you can use NavMesh obstacles to carve a moat around the screen and then check if there is a path to the destination before setting it.
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
               
 
			 
                