[HOWTO] How To: Make NPC Face Player in 2D

Announcements, support questions, and discussion for the Dialogue System.
Post Reply
User avatar
Tony Li
Posts: 20704
Joined: Thu Jul 18, 2013 1:27 pm

[HOWTO] How To: Make NPC Face Player in 2D

Post by Tony Li »

In 3D, you can typically use the LookAt() sequencer command to make an NPC face the player when starting a conversation.

However, the Dialogue System doesn't provide a built-in way to make a 2D character face the player because it depends on how your specific 2D game works. Some 2D games change the NPC's facing by setting its SpriteRender's "Flip X" value. Other games change the NPC's Transform > Scale X value between -1 and +1. And in other games, such as top-down games like the original Zelda, NPCs might have sprites in 4, 8, or even 16 different directions (e.g., north/south/east/west).

In general, you can either write a custom sequencer command or handle it in an OnConversationStart() method.

For example, this custom LookAt2D() command makes a character look at a subject by setting its Flip X value. Important note: It makes some assumptions that your character may not have: (1) the character can only face left or right, as in a 2D platformer; and (2) when Flip X is UNticked, the character is facing right. Also, (3) that the character has only one SpriteRenderer and that it's on the character's top-level GameObject.

Code: Select all

// Important: Read the assumptions above. This is just an example.
// Syntax: LookAt2D(subject, character)
// Description: Makes character look at subject.
// - subject: The subject to look at; defaults to listener if not specified.
// - character: The character to make look at the subject; defaults to speaker if not specified.
public class SequencerCommandLookAt2D : SequencerCommand
{
    void Awake()
    {
        var subject = GetSubject(0, listener);
        var character = GetSubject(1, speaker);
        var spriteRenderer = character.GetComponent<SpriteRenderer>();
        var faceLeft = subject.position.x < character.position.x;
        spriteRenderer.flipX = faceLeft;
    }
}
Post Reply