Search Unity

2D How to make a character to follow the main character?

Discussion in '2D' started by Dumitru, May 27, 2015.

  1. Dumitru

    Dumitru

    Joined:
    May 7, 2015
    Posts:
    80
    I'm making a 2d game and I am stuck at a part where the player needs to escort 1 of the secondary characters across a level, I have been trying but I'm stuck, I'm new at Unity and scripting.

    What I'm exactly trying to accomplish

    When the player "bumps" into the secondary character, a small message above the secondary character's head pops and he starts to follow wherever the main character goes.

    Any help will be greatly appreciated, thank you for taking your time to read this post!
     
    PhilippG likes this.
  2. PhilippG

    PhilippG

    Joined:
    Jan 7, 2014
    Posts:
    257
    Yes this is really interesting. Is it top down or side 2D? I'm also working on a 2D game - a sidescroller metroidvania- and I imagine this mechanic might be useful. The only proper way to achieve this is probably to record the players moves and replay them on the following character with a fixed time offset.

    Should ideally look so:
     
    Last edited: May 27, 2015
  3. Dumitru

    Dumitru

    Joined:
    May 7, 2015
    Posts:
    80
    It is side 2d :)
     
  4. Dumitru

    Dumitru

    Joined:
    May 7, 2015
    Posts:
    80
    And yeah, but how to do so?
     
  5. PhilippG

    PhilippG

    Joined:
    Jan 7, 2014
    Posts:
    257
    This works fine:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4.  
    5. public class FollowTest : MonoBehaviour
    6. {
    7.  
    8.     public GameObject ObjectToFollow;
    9.     public float TimeOffset = 1;
    10.     public int Granularity = 10;
    11.  
    12.     public float InterpolationSpeed = 10;
    13.  
    14.     private Queue<Vector3> path = new Queue<Vector3>();
    15.     private float queueTimer;
    16.  
    17.     private Vector3 currentPathPosition;
    18.  
    19.     protected void Update ()
    20.     {
    21.         if(currentPathPosition != Vector3.zero)
    22.             transform.position += (currentPathPosition - transform.position) * Time.deltaTime * InterpolationSpeed;
    23.     }
    24.  
    25.     protected void FixedUpdate()
    26.     {
    27.         if (ObjectToFollow == null)
    28.             return;
    29.         queueTimer -= Time.fixedDeltaTime;
    30.         if (queueTimer <= 0) {
    31.             queueTimer = TimeOffset / Granularity;
    32.             if(path.Count == Granularity)
    33.                 currentPathPosition = path.Dequeue();
    34.             path.Enqueue(ObjectToFollow.transform.position);
    35.         }
    36.     }
    37. }
    You need to assign the ObjectToFollow GO in the editor or code (in your case, when you bump into the other character)
    If you raise the TimeOffset, you'll obviously also need to raise the recording Granularity

    (Edit: had a mistake in fixedupdate - is fixed now)
     
    Last edited: May 28, 2015
    LiberLogic969 likes this.
  6. PhilippG

    PhilippG

    Joined:
    Jan 7, 2014
    Posts:
    257
    Oh and you can replace the Queues vector3 type with a struct type containing all the info you need to have your follower mimic your player. (ie adding rotation, or which animation it should play) :)
     
  7. Dumitru

    Dumitru

    Joined:
    May 7, 2015
    Posts:
    80
    Thank you so much for your help, is it possible to explain this in a bit of more details? I'm really new to scripting, once again, thank you alot!
     
  8. PhilippG

    PhilippG

    Joined:
    Jan 7, 2014
    Posts:
    257
    Yes. A generic like the used queue works as a container for any datatype. You can utilize this to pack more useful data into a single element of your queue by making your own datatype.

    Say you want to mimic not only the position, but also the rotation and if the character is jumping at this point (just like in the donkey kong video). You can save all that data in the queue like this:

    Code (CSharp):
    1. private struct Playbackdata
    2. {
    3.     public Vector3 position;
    4.     public Quaternion rotation;
    5.     public bool jumping;
    6. }
    7.  
    8. private Queue<Playbackdata> playbackQueue = new Queue<Playbackdata>();
     
  9. Dumitru

    Dumitru

    Joined:
    May 7, 2015
    Posts:
    80
    alright :D although, what should I do in order to make it in sort that the secondary character cannot take damage? ( basically invincible ) ?
     
  10. PhilippG

    PhilippG

    Joined:
    Jan 7, 2014
    Posts:
    257
    o_OThat depends on how your damage system works... just.. shut it off? :-D
     
  11. Dumitru

    Dumitru

    Joined:
    May 7, 2015
    Posts:
    80
    Yeah, that's true, although I just attach this script to the secondary character, that's it? Sorry, I'm really new to this and I'd rather ask to be sure that I did not failed a step or did something wrong, thank you so much for helping me!
     
  12. PhilippG

    PhilippG

    Joined:
    Jan 7, 2014
    Posts:
    257
    Sure. Add the monobehavior to your second character and set the ObjectToFollow to be your player gameobject (drag and drop in the editor).

    This is just a starting point though.
    You will want to set the ObjectToFollow variable when the player collides with the secondary.
    You will also need to stop him to follow when your goal is reached.
    This is gamespecific behavior and therefore I didnt include it ;)
     
  13. Dumitru

    Dumitru

    Joined:
    May 7, 2015
    Posts:
    80
    alright, thank you so much for the help, could I contact you if I'm stuck at a part? once again, thank you so much!