I want to make my player move from point A to point B, execute animation and come back

I am making a turned based battle system and I want my player character to move to the enemy character execute the attack and come back to its original transform. I want this done in a click of a button and I just can’t seem to figure it out. I tried vector2.lerp and MoveTowards but both had to be in update to work or maybe I just missed something because I am relatively new to Unity
Source code below

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using CodeMonkey.HealthSystemCM;


public class BattleHandler : MonoBehaviour
{
     public GameObject playerCharacter;
     public GameObject enemyCharacter;
     private GameObject playerPrefab;
     private GameObject enemyPrefab;
     public CharacterBase playerCharacterBase;
     public CharacterBase enemyCharacterBase;
     private HealthSystemComponent enemyHealth;
     private HealthSystemComponent playerHealth;
     private ParticleSystem addStrenghtParticle;
     private Transform playerPosition;
     private Transform enemyPosition;
     

    private void Start()
    {
        SpawnCharacter(true);
        SpawnCharacter(false);
        playerCharacterBase = playerPrefab.GetComponent<CharacterBase>();
        enemyCharacterBase = enemyPrefab.GetComponent<CharacterBase>();
        enemyHealth = enemyPrefab.GetComponent<HealthSystemComponent>();       
        playerHealth = playerPrefab.GetComponent<HealthSystemComponent>();
        addStrenghtParticle = playerPrefab.GetComponentInChildren<ParticleSystem>();
        playerPosition = playerPrefab.GetComponent<Transform>();
        enemyPosition = enemyPrefab.GetComponent<Transform>();

    }

    public void AttackMovement()
    {
        playerPosition.position = Vector2.Lerp(playerPosition.position, enemyPosition.position, Time.deltaTime);
    }

    public void AddStrenght()
    {       
        playerCharacterBase.AddStrenght();
        addStrenghtParticle.Play();
                  
    }    

    public void AttackSequence()
    {
        Invoke("PlayerAttack", 0f);
        Invoke("EnemyAttack", 1f);
        
    }

    private void PlayerAttack()
    {
            float damage1 = playerCharacterBase.CalcDamage();   
            playerCharacterBase.AttackAnim();
            enemyCharacterBase.HurtAnim();
            enemyHealth.Damage(damage1);
            enemyHealth.Die();             
    }

    private void EnemyAttack()
    {
        float damage2 = enemyCharacterBase.CalcDamage();
        enemyCharacterBase.AttackAnim();
        playerCharacterBase.HurtAnim();
        playerHealth.Damage(damage2);
        playerHealth.Die();       
    }

    public void SpawnCharacter(bool isPlayerTeam)
    {
        Vector3 position;
        if (isPlayerTeam)
        {
            position = new Vector3(-6, 15);
            playerPrefab = Instantiate(playerCharacter, position, Quaternion.identity);
        }
        else
        {
            position = new Vector3(4, 15);
            enemyPrefab = Instantiate(enemyCharacter, position, Quaternion.identity);
        }
    }
}

Hello @foxy9909 !!

Yes, you need to move the gameobject, you can do with transform.translate, change it transform.position using lerp. But you say “it needs to be in update” and thas not true. What it needs is to be executed varius frames (until reach the destination) Update is executed each fram, so it can be used for that, but its a very bad solution, as you may imagine, because you will need to have tons of “if” code inside the update function…


The solution to your problem are Corutines! If want to code/develope any game, you will need to learn corrutines yes or yes.

IEnumerator (corutines) are functions (like void functions) but they allow you to make yield comands. A yield command is just a order to code to say “wait here until… (somethign you want)” fopr example yield return null which means “wait here until next frame, then continue” , or for example yield return new WaitForseconds(3) which means “wait here and continue after 3 seconds”

This allows you to make things like this:

    void Start()
    {
        StartCoroutine(Test());
    }

    IEnumerator Test()
    {
        Debug.Log("Hello 1");
        yield return new WaitForSeconds(2);
        Debug.Log("Hello 2");
    }

Try it, you will see, the code waits 2 seconds berween Hello 1 and Hello 2.

In your case you can do something like this:

    void SomeFunctionThatWillCallYourCorutine()
    {
        StartCoroutine(MoveUnit());
    }

    IEnumerator MoveUnit()
    {
        while (Vector3.Distance(UnitPosition, Destination) > 1)
        {
        Unit.transform.Translate(Vector3.Normalize(Destinaction,UnitPosition) * Speed)
        yield return null;
        }
    }

This way, the while loop with do one Translate each frame, only one, and will do it each frame until distance between unit and destination is lower than 1.


I recommend you to go loook for tutorials or read the manuals about everything you didnt know from this scripts, to get used to them, and use it every time you need in the future.


Good Luck!

I think coroutines is what you’re looking for, coroutines are like function, but can be paused and resumed to the next frame, really useful when you don’t want to use update,
so instead using invoke method, add this to your monobehavior and call it inside the AttackSequence function.

        IEnumerator AttackSequenceProcess ()
        {
            // player attack for the 1st second
            for (float i = 0; i < 1; i+= Time.deltaTime)
            {
                PlayerAttack();
                // hang the function and resume it in the next frame
                yield return null;
            }
            //EnemyAttack for the 2nd second
            for (float i = 0; i < 1; i+= Time.deltaTime)
            {
                EnemyAttack();
                // hang the function and resume it in the next frame
                yield return null;
            }
        }

        public void AttackSequence()
        {
            StartCoroutine ( AttackSequenceProcess );
        }

There’s many tutorial about coroutines, hope that helps