Search Unity

  1. Unity 2018.3 is now released.
    Dismiss Notice
  2. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  3. Want more efficiency in your development work? Sign up to receive weekly tech and creative know-how from Unity experts.
    Dismiss Notice
  4. Build games and experiences that can load instantly and without install. Explore the Project Tiny Preview today!
    Dismiss Notice
  5. Nominations have been announced for this years Unity Awards. Celebrate the wonderful projects made by your peers this year and get voting! Vote here!
    Dismiss Notice
  6. Want to provide direct feedback to the Unity team? Join the Unity Advisory Panel.
    Dismiss Notice
  7. Improve your Unity skills with a certified instructor in a private, interactive classroom. Watch the overview now.
    Dismiss Notice

8 Directional Sprites

Discussion in 'Animation' started by Nails-of-Scream, Dec 8, 2018.

  1. Nails-of-Scream

    Nails-of-Scream

    Joined:
    Jul 27, 2016
    Posts:
    3
    Hello, new here. I would want to learn how to do 2.5D sprites like in Marathon. (Which isn't a complete Doomlike)

    This has been a huge interest for me and I want to learn to do it right. I've tried some script before, it did change the sprite to the wished direction but the character couldn't rotate nor be animated. If you can't give me a complete code then it's okay. Just say what I need to learn to make a simple 2.5D script and I would be pleased.

    EDIT: This is the current code for 8 directional sprites
    Code (CSharp):
    1. public class SpriteAnimator : MonoBehaviour {
    2.  
    3.     public GameObject cameraToSee;
    4.     public Transform player;
    5.     public float playerAngle;
    6.     Vector3 direction;
    7.  
    8.     public int locationInt, locationInt2;
    9.  
    10.     public Sprite[] sprites;
    11.     SpriteRenderer spriteRenderer;
    12.  
    13.     void Awake () {
    14.         spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
    15.         cameraToSee = Camera.main.gameObject;
    16.     }
    17.    
    18.     void Update () {
    19.         direction = player.transform.position - transform.position;
    20.         playerAngle = Mathf.Atan2(direction.x,direction.z) * Mathf.Rad2Deg;
    21.         ChangeSprite();
    22.         Vector3 targetPosition = new Vector3(cameraToSee.transform.position.x,
    23.                                              transform.position.y,
    24.                                              cameraToSee.transform.position.z);
    25.         transform.LookAt(targetPosition);
    26.         locationInt = Mathf.RoundToInt(playerAngle);
    27.         locationInt2 = Mathf.RoundToInt(playerAngle + 45);
    28.     }
    29.  
    30.     public void ChangeSprite() {
    31.         if (locationInt <= 0 && locationInt2 >= 45) spriteRenderer.sprite = sprites[0];
    32.         else if (locationInt <= 45 && locationInt2 >= 90) spriteRenderer.sprite = sprites[1];
    33.         else if (locationInt <= 90 && locationInt2 >= 135) spriteRenderer.sprite = sprites[2];
    34.         else if (locationInt <= 135 && locationInt2 >= 180) spriteRenderer.sprite = sprites[3];
    35.         else if (locationInt <= 180 && locationInt2 >= 225) spriteRenderer.sprite = sprites[4];
    36.         else if (locationInt <= -135 && locationInt2 >= -135) spriteRenderer.sprite = sprites[5];
    37.         else if (locationInt <= -90 && locationInt2 >= -90) spriteRenderer.sprite = sprites[6];
    38.         else if (locationInt <= -45 && locationInt2 >= -45) spriteRenderer.sprite = sprites[7];
    39.     }
    40. }
    It isn't masterly crafted but it worked. However the character can't rotate.
     
    Last edited: Dec 10, 2018 at 8:35 AM
  2. Nails-of-Scream

    Nails-of-Scream

    Joined:
    Jul 27, 2016
    Posts:
    3
    Here is the same script but more optimised. (Believably)
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class SpriteAnimator : MonoBehaviour {
    4.  
    5.     public GameObject cameraToSee;
    6.     public Transform player;
    7.     public float playerAngle;
    8.     public Vector3 direction;
    9.  
    10.     public GameObject spriteObject;
    11.  
    12.     public int locationInt, locationInt2;
    13.  
    14.     public string facingDir;
    15.  
    16.     void Awake () {
    17.         cameraToSee = Camera.main.gameObject;
    18.     }
    19.  
    20.     void Update () {
    21.         direction = player.transform.position - transform.position;
    22.         playerAngle = Mathf.Atan2(direction.x,direction.z) * Mathf.Rad2Deg;
    23.  
    24.  
    25.         Vector3 targetPosition = new Vector3(cameraToSee.transform.position.x,
    26.                                              transform.position.y,
    27.                                              cameraToSee.transform.position.z);
    28.         spriteObject.transform.LookAt(targetPosition);
    29.  
    30.  
    31.         locationInt = Mathf.RoundToInt(playerAngle);
    32.         locationInt2 = Mathf.RoundToInt(playerAngle + 45);
    33.  
    34.         InDirection();
    35.     }
    36.  
    37.     public void InDirection() {
    38.         if (locationInt <= 0 && locationInt2 >= 45) facingDir = "front";
    39.         else if (locationInt <= 45 && locationInt2 >= 90) facingDir = "frontright";
    40.         else if (locationInt <= 90 && locationInt2 >= 135) facingDir = "right";
    41.         else if (locationInt <= 135 && locationInt2 >= 180) facingDir = "backright";
    42.         else if (locationInt <= 180 && locationInt2 >= 225) facingDir = "back";
    43.         else if (locationInt <= -135 && locationInt2 >= -180) facingDir = "backleft";
    44.         else if (locationInt <= -90 && locationInt2 >= -135) facingDir = "left";
    45.         else if (locationInt <= -45 && locationInt2 >= -90) facingDir = "frontleft";
    46.     }
    47. }
    Here's the current state of a character's behaviour script. Jekivi.
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class JekiviTest : MonoBehaviour {
    4.  
    5.     SpriteAnimator spriteAnimator;
    6.  
    7.     public Sprite[] sprites;
    8.     public SpriteRenderer spriteRenderer;
    9.  
    10.     void Awake () {
    11.         spriteAnimator = GetComponent<SpriteAnimator>();
    12.     }
    13.  
    14.     void Update () {
    15.         ChangeSprite();
    16.     }
    17.  
    18.     public void ChangeSprite()
    19.     {
    20.         if (spriteAnimator.facingDir == "front") spriteRenderer.sprite = sprites[0];
    21.         else if (spriteAnimator.facingDir == "frontright") spriteRenderer.sprite = sprites[1];
    22.         else if (spriteAnimator.facingDir == "right") spriteRenderer.sprite = sprites[2];
    23.         else if (spriteAnimator.facingDir == "backright") spriteRenderer.sprite = sprites[3];
    24.         else if (spriteAnimator.facingDir == "back") spriteRenderer.sprite = sprites[4];
    25.         else if (spriteAnimator.facingDir == "backleft") spriteRenderer.sprite = sprites[5];
    26.         else if (spriteAnimator.facingDir == "left") spriteRenderer.sprite = sprites[6];
    27.         else if (spriteAnimator.facingDir == "frontleft") spriteRenderer.sprite = sprites[7];
    28.     }
    29. }
    30.  
    Something is wrong. Can someone help me out?
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    3,472
    The most important skill when programming is the ability to debug your own code. The usual process here is to ask yourself what you think should be happening on every line of code, and then investigate when that assumption breaks.

    In your case, you assume that the playerAngle changes based on where the player is relative to the direction the SpriteAnimator is facing, and you assume that the correct locationInt is getting set from the angle. Those are easy to check - the most straightforward way is with Debug.Log:

    Code (csharp):
    1. // after this:
    2. direction = player.transform.position - transform.position;
    3. playerAngle = Mathf.Atan2(direction.x,direction.z) * Mathf.Rad2Deg;
    4. // add:
    5. Debug.Log("The direction is " + direction + ", and the angle is " + playerAngle);
    6.  
    7. // after this:
    8. locationInt = Mathf.RoundToInt(playerAngle);
    9. locationInt2 = Mathf.RoundToInt(playerAngle + 45);
    10. // add:
    11. Debug.Log("Set location int 1 to " + locationInt + " and location int 2 to " + locationInt2);
     
  4. Nails-of-Scream

    Nails-of-Scream

    Joined:
    Jul 27, 2016
    Posts:
    3
    I did this instead.
    Code (CSharp):
    1. if (playerAngle >= 0f && playerAngle < 45f) facing = FACINGDIR.front;
    2.         else if (playerAngle >= 45f && playerAngle < 90f) facing = FACINGDIR.frontright;
    3.         else if (playerAngle >= 90f && playerAngle < 135f) facing = FACINGDIR.right;
    4.         else if (playerAngle >= 135f && playerAngle < 180f) facing = FACINGDIR.backright;
    5.         else if (playerAngle >= -180f && playerAngle < -135f) facing = FACINGDIR.back;
    6.         else if (playerAngle >= -135f && playerAngle < -90f) facing = FACINGDIR.backleft;
    7.         else if (playerAngle >= -90f && playerAngle < -45f) facing = FACINGDIR.left;
    8.         else if (playerAngle >= -45f && playerAngle < 0f) facing = FACINGDIR.frontleft;
    And it worked! But I'm not done yet. I still need to make the character's own rotation change the sprite and figure out how to make animations work. Any help is appreciated. Until then I'll try to figure it out myself.