Click target, move to target, and then start dialogue?

Is there a simple way to make it so that the player moves within range of the AI conversant before starting the dialogue?

I tried adding an update method to AIConversant based on how the Fighter autoattack works, but could not get it to work at all.


        [SerializeField] Dialogue dialogue = null;
        [SerializeField] string conversantName;
        [SerializeField] float dialogueRange = 5f;
        PlayerController callingController;

        private void Awake()
        {
            callingController = GetComponent<PlayerController>();
        }
        private void Update()
        {
            if (dialogue == null) return;

            if (!GetIsInDialogueRange(transform))
            {
                callingController.GetComponent<Mover>().MoveTo(transform.parent.position, 1f);
            }
            else
            {
                callingController.GetComponent<Mover>().Cancel();
                GetComponent<PlayerConversant>().StartDialogue(this, dialogue);
            }
        }

        public bool HandleRaycast(PlayerController callingController)
        {
            if (dialogue == null) return false;

            if (this.tag == "Bed")
            {
                if (Input.GetMouseButtonDown(0))
                {
                    callingController.GetComponent<Mover>().StartMoveAction(transform.position, 1);
                    //callingController.GetComponent<PlayerConversant>().StartDialogue(this, dialogue);
                }
            }

            if (GetComponent<Health>().IsDead()) return false;

            if (dialogue == null || this.tag == "Bed")
            {
                if (Input.GetMouseButtonDown(0))
                {
                    callingController.GetComponent<Mover>().StartMoveAction(transform.position, 1);
                    //callingController.GetComponent<PlayerConversant>().StartDialogue(this, dialogue);
                }
            }

            if (Input.GetMouseButtonDown(0))
            {
                callingController.GetComponent<Mover>().StartMoveAction(transform.position, 1);
                //callingController.GetComponent<PlayerConversant>().StartDialogue(this, dialogue);
            }
            
            return true;
        }

        public bool GetIsInDialogueRange(Transform target)
        {
            return Vector3.Distance(callingController.transform.position, target.transform.position) < dialogueRange;
        }

Without the update, it will walk towards the target and turn on dialogue at the same time. I need some way to make it wait until it is in range before talking (which is what update() is meant to be doing), but I can’t get it to work the same way it works for combat.

GetIsInDialogueRange() is returning null, but as im looking into this I can’t help but feel like there should be an easy way to implement this, some way to call on the controller or mover to automatically do this instead of changing the dialogue scripts.

I have a small workaround:

public bool HandleRaycast(PlayerController callingController)
        {
            if (dialogue == null) return false;
            if (!GetIsInDialogueRange(callingController, transform)) return false;
            if (this.tag == "Bed")
            {
                if (Input.GetMouseButtonDown(0))
                {
                    callingController.GetComponent<PlayerConversant>().StartDialogue(this, dialogue);
                }
            }

            if (GetComponent<Health>().IsDead()) return false;

            if (dialogue == null || this.tag == "Bed")
            {
                if (Input.GetMouseButtonDown(0) && GetIsInDialogueRange(callingController, transform))
                {
                    callingController.GetComponent<PlayerConversant>().StartDialogue(this, dialogue);
                }
            }

            if (Input.GetMouseButtonDown(0))
            {
                callingController.GetComponent<PlayerConversant>().StartDialogue(this, dialogue);
            }
            
            return true;
        }

        public bool GetIsInDialogueRange(PlayerController callingController, Transform target)
        {
            return Vector3.Distance(callingController.transform.position, target.position) < dialogueRange;
        }

if the player is not within the dialogue range of the NPC, then the raycast will not start dialogue at all. This works, but its a very clunky fix because you have to click once to walk over to the npc, then click once again to start dialogue.

It needs to be an IAction to function properly… I make the PlayerConversant inherit the IAction interface

This means that StartDialogue will need to call ActionScheduler like fighter and Mover do, and will also need a Cancel() method to clear the target.

Then rather than immediately opening the dialogue, an Update method in PlayerConversant will move to the AIConversant, interacting when the player is in range.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms