From 9f0efd8aabbc124182e1f82193d6ed55cb0dc3ec Mon Sep 17 00:00:00 2001 From: Raketfart Date: Tue, 23 Aug 2016 00:26:27 +0200 Subject: [PATCH 1/6] Fixed position of sprite tiles. Now Y positions are counted from the bottom up. --- .../StreamingAssets/Images/Character/p1_animated.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 Assets/StreamingAssets/Images/Character/p1_animated.xml diff --git a/Assets/StreamingAssets/Images/Character/p1_animated.xml b/Assets/StreamingAssets/Images/Character/p1_animated.xml new file mode 100644 index 000000000..3be0c1e1f --- /dev/null +++ b/Assets/StreamingAssets/Images/Character/p1_animated.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file From c2e1773ac793d4650bc5a88f7f03a46b39f4bebf Mon Sep 17 00:00:00 2001 From: Raketfart Date: Tue, 23 Aug 2016 09:44:45 +0200 Subject: [PATCH 2/6] Added CharacterAnimation class and hooked it up to character and characterspritecontroller --- .../Controllers/CharacterSpriteController.cs | 16 ++- Assets/Scripts/Models/Character.cs | 43 ++++++- Assets/Scripts/Models/CharacterAnimation.cs | 109 ++++++++++++++++++ .../Scripts/Models/CharacterAnimation.cs.meta | 12 ++ .../Images/Character/p1_animated.xml.meta | 8 ++ .../Images/Character/p2_helmet.xml | 2 +- 6 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 Assets/Scripts/Models/CharacterAnimation.cs create mode 100644 Assets/Scripts/Models/CharacterAnimation.cs.meta create mode 100644 Assets/StreamingAssets/Images/Character/p1_animated.xml.meta diff --git a/Assets/Scripts/Controllers/CharacterSpriteController.cs b/Assets/Scripts/Controllers/CharacterSpriteController.cs index b3a356c02..07b7388d0 100644 --- a/Assets/Scripts/Controllers/CharacterSpriteController.cs +++ b/Assets/Scripts/Controllers/CharacterSpriteController.cs @@ -57,10 +57,24 @@ public void OnCharacterCreated(Character c) char_go.transform.SetParent(characterParent.transform, true); SpriteRenderer sr = char_go.AddComponent(); - sr.sprite = SpriteManager.current.GetSprite("Character", "p2_front"); + //sr.sprite = SpriteManager.current.GetSprite("Character", "p2_front"); sr.sortingLayerName = "Characters"; sr.color = c.GetCharacterColor(); + c.animation = new CharacterAnimation(c, sr); + Sprite[] sprites = { + SpriteManager.current.GetSprite("Character", "p1_idle_south"), + SpriteManager.current.GetSprite("Character", "p1_idle_east"), + SpriteManager.current.GetSprite("Character", "p1_idle_north"), + SpriteManager.current.GetSprite("Character", "p1_walk_east_01"), + SpriteManager.current.GetSprite("Character", "p1_walk_east_02"), + SpriteManager.current.GetSprite("Character", "p1_walk_north_01"), + SpriteManager.current.GetSprite("Character", "p1_walk_north_02"), + SpriteManager.current.GetSprite("Character", "p1_walk_south_01"), + SpriteManager.current.GetSprite("Character", "p1_walk_south_02") + }; + c.animation.setSprites(sprites); + // Add the inventory sprite onto the character GameObject inv_go = new GameObject("Inventory"); SpriteRenderer inv_sr = inv_go.AddComponent(); diff --git a/Assets/Scripts/Models/Character.cs b/Assets/Scripts/Models/Character.cs index 56e561aab..21d3ea2a1 100644 --- a/Assets/Scripts/Models/Character.cs +++ b/Assets/Scripts/Models/Character.cs @@ -138,6 +138,15 @@ public Tile JobTile // The item we are carrying (not gear/equipment) public Inventory inventory; + // holds all character animations + public CharacterAnimation animation; + + // is the character walking or idle + public bool IsWalking; + + // 0=north, 1=east, 2=south, 3=west + public int Facing; + /// Use only for serialization public Character() { @@ -329,7 +338,7 @@ private bool CheckForJobMaterials() // Walk towards a tile containing the required goods. Debug.Log("Walk to the stuff"); Debug.Log(myJob.canTakeFromStockpile); - + // Find the first thing in the Job that isn't satisfied. Inventory desired = myJob.GetFirstDesiredInventory(); @@ -445,9 +454,10 @@ private void Update_DoMovement(float deltaTime) if (CurrTile == DestTile) { pathAStar = null; + IsWalking = false; return; // We're already were we want to be. } - + // currTile = The tile I am currently in (and may be in the process of leaving) // nextTile = The tile I am currently entering // destTile = Our final destination -- we never walk here directly, but instead use it for the pathfinding @@ -469,15 +479,35 @@ private void Update_DoMovement(float deltaTime) NextTile = pathAStar.Dequeue(); } + IsWalking = true; + // Grab the next waypoint from the pathing system! NextTile = pathAStar.Dequeue(); if (NextTile == CurrTile) { + IsWalking = false; // Debug.LogError("Update_DoMovement - nextTile is currTile?"); } } + // Find character facing + if (NextTile.X > CurrTile.X) + { + Facing = 1; + } + else if (NextTile.Y > CurrTile.Y) + { + Facing = 0; + } + else if (NextTile.X < CurrTile.X) + { + Facing = 4; + } + else + { + Facing = 3; + } // At this point we should have a valid nextTile to move to. // What's the total distance from point A to point B? @@ -539,11 +569,16 @@ public void Update(float deltaTime) Update_DoJob(deltaTime); Update_DoMovement(deltaTime); - + + Facing = 3; + if (cbCharacterChanged != null) { - cbCharacterChanged(this); + cbCharacterChanged(this); } + + animation.Update(deltaTime); + } private void OnJobStopped(Job j) diff --git a/Assets/Scripts/Models/CharacterAnimation.cs b/Assets/Scripts/Models/CharacterAnimation.cs new file mode 100644 index 000000000..435564d9e --- /dev/null +++ b/Assets/Scripts/Models/CharacterAnimation.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +/// +/// CharacterAnimation gets reference to character, and should be able to +/// figure out which animation to play, by looking at character Facing and IsMoving +/// +public class CharacterAnimation +{ + private Character character; + private SpriteRenderer renderer; + + // currentframe is incremented each update... fix to run on time instead + private int currentFrame = 0; + + // frames before loop. halfway through the next frame is triggered + private int animationLength = 40; + + // TODO: should be more flexible .... + private Sprite[] sprites = new Sprite[9]; + + + public CharacterAnimation(Character c, SpriteRenderer r) + { + character = c; + renderer = r; + } + + public void Update(float deltaTime) + { + if (currentFrame >= animationLength) currentFrame = 0; + currentFrame++; + + callAnimation(); + } + + private void callAnimation() + { + if (character.IsWalking) + { + switch (character.Facing) + { + case 0: // walk north + toggleAnimation(5, 6); + break; + case 1: // walk east + toggleAnimation(3, 4); + break; + case 2: // walk south + toggleAnimation(7, 8); + break; + case 3: // walk west + toggleAnimation(3, 4); //TODO: FLIP east sprite + break; + default: + break; + } + } + else + { + switch (character.Facing) + { + case 0: // walk north + showSprite(2); + break; + case 1: // walk east + showSprite(1); + break; + case 2: // walk south + showSprite(0); + break; + case 3: // walk west + showSprite(1); //TODO: FLIP east sprite + break; + default: + break; + } + } + } + + private void toggleAnimation(int s1, int s2) + { + if (currentFrame == 1) + { + renderer.sprite = sprites[s1]; + } + else if (currentFrame == animationLength / 2) + { + renderer.sprite = sprites[s2]; + } + + } + + private void showSprite(int s) + { + if (currentFrame == 1) + { + renderer.sprite = sprites[s]; + } + } + + public void setSprites(Sprite[] s) + { + sprites = s; + } + +} + diff --git a/Assets/Scripts/Models/CharacterAnimation.cs.meta b/Assets/Scripts/Models/CharacterAnimation.cs.meta new file mode 100644 index 000000000..2b14b0ef8 --- /dev/null +++ b/Assets/Scripts/Models/CharacterAnimation.cs.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: ef2796d7468cd294b942c10f00613117 +timeCreated: 1471934646 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/StreamingAssets/Images/Character/p1_animated.xml.meta b/Assets/StreamingAssets/Images/Character/p1_animated.xml.meta new file mode 100644 index 000000000..6dec0e008 --- /dev/null +++ b/Assets/StreamingAssets/Images/Character/p1_animated.xml.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1a37880f7b3ba1e4d9f3049924fb3743 +timeCreated: 1471904842 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/StreamingAssets/Images/Character/p2_helmet.xml b/Assets/StreamingAssets/Images/Character/p2_helmet.xml index ee7501d66..4330cb185 100644 --- a/Assets/StreamingAssets/Images/Character/p2_helmet.xml +++ b/Assets/StreamingAssets/Images/Character/p2_helmet.xml @@ -1,4 +1,4 @@ - + \ No newline at end of file From cafbd91749c49e9a3219e89f66d91d9e1d3cf52e Mon Sep 17 00:00:00 2001 From: Raketfart Date: Tue, 23 Aug 2016 11:48:08 +0200 Subject: [PATCH 3/6] Character animation working --- .../Controllers/CharacterSpriteController.cs | 18 +++++++------- Assets/Scripts/Models/Character.cs | 9 +++---- Assets/Scripts/Models/CharacterAnimation.cs | 23 ++++++++++++------ .../Images/Character/p1_animated_nohelmet.png | Bin 22001 -> 30622 bytes .../Images/Character/p1_animated_nohelmet.xml | 12 +++++++++ .../Character/p1_animated_nohelmet.xml.meta | 8 ++++++ 6 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 Assets/StreamingAssets/Images/Character/p1_animated_nohelmet.xml create mode 100644 Assets/StreamingAssets/Images/Character/p1_animated_nohelmet.xml.meta diff --git a/Assets/Scripts/Controllers/CharacterSpriteController.cs b/Assets/Scripts/Controllers/CharacterSpriteController.cs index 07b7388d0..311e71c03 100644 --- a/Assets/Scripts/Controllers/CharacterSpriteController.cs +++ b/Assets/Scripts/Controllers/CharacterSpriteController.cs @@ -63,15 +63,15 @@ public void OnCharacterCreated(Character c) c.animation = new CharacterAnimation(c, sr); Sprite[] sprites = { - SpriteManager.current.GetSprite("Character", "p1_idle_south"), - SpriteManager.current.GetSprite("Character", "p1_idle_east"), - SpriteManager.current.GetSprite("Character", "p1_idle_north"), - SpriteManager.current.GetSprite("Character", "p1_walk_east_01"), - SpriteManager.current.GetSprite("Character", "p1_walk_east_02"), - SpriteManager.current.GetSprite("Character", "p1_walk_north_01"), - SpriteManager.current.GetSprite("Character", "p1_walk_north_02"), - SpriteManager.current.GetSprite("Character", "p1_walk_south_01"), - SpriteManager.current.GetSprite("Character", "p1_walk_south_02") + SpriteManager.current.GetSprite("Character", "p1_nh_idle_south"), + SpriteManager.current.GetSprite("Character", "p1_nh_idle_east"), + SpriteManager.current.GetSprite("Character", "p1_nh_idle_north"), + SpriteManager.current.GetSprite("Character", "p1_nh_walk_east_01"), + SpriteManager.current.GetSprite("Character", "p1_nh_walk_east_02"), + SpriteManager.current.GetSprite("Character", "p1_nh_walk_north_01"), + SpriteManager.current.GetSprite("Character", "p1_nh_walk_north_02"), + SpriteManager.current.GetSprite("Character", "p1_nh_walk_south_01"), + SpriteManager.current.GetSprite("Character", "p1_nh_walk_south_02") }; c.animation.setSprites(sprites); diff --git a/Assets/Scripts/Models/Character.cs b/Assets/Scripts/Models/Character.cs index 21d3ea2a1..fdd7ad9bb 100644 --- a/Assets/Scripts/Models/Character.cs +++ b/Assets/Scripts/Models/Character.cs @@ -502,12 +502,13 @@ private void Update_DoMovement(float deltaTime) } else if (NextTile.X < CurrTile.X) { - Facing = 4; + Facing = 3; } else { - Facing = 3; + Facing = 2; } + // At this point we should have a valid nextTile to move to. // What's the total distance from point A to point B? @@ -568,9 +569,7 @@ public void Update(float deltaTime) { Update_DoJob(deltaTime); - Update_DoMovement(deltaTime); - - Facing = 3; + Update_DoMovement(deltaTime); if (cbCharacterChanged != null) { diff --git a/Assets/Scripts/Models/CharacterAnimation.cs b/Assets/Scripts/Models/CharacterAnimation.cs index 435564d9e..25a831a65 100644 --- a/Assets/Scripts/Models/CharacterAnimation.cs +++ b/Assets/Scripts/Models/CharacterAnimation.cs @@ -39,19 +39,24 @@ private void callAnimation() { if (character.IsWalking) { + // character walking switch (character.Facing) { case 0: // walk north toggleAnimation(5, 6); + renderer.flipX = false; break; case 1: // walk east - toggleAnimation(3, 4); + toggleAnimation(3, 4); + renderer.flipX = false; break; case 2: // walk south toggleAnimation(7, 8); + renderer.flipX = false; break; case 3: // walk west - toggleAnimation(3, 4); //TODO: FLIP east sprite + toggleAnimation(3, 4); // FLIP east sprite + renderer.flipX = true; break; default: break; @@ -59,19 +64,24 @@ private void callAnimation() } else { + //character idle switch (character.Facing) { case 0: // walk north showSprite(2); + renderer.flipX = false; break; case 1: // walk east showSprite(1); + renderer.flipX = false; break; case 2: // walk south showSprite(0); + renderer.flipX = false; break; case 3: // walk west - showSprite(1); //TODO: FLIP east sprite + showSprite(1); // FLIP east sprite + renderer.flipX = true; break; default: break; @@ -93,11 +103,8 @@ private void toggleAnimation(int s1, int s2) } private void showSprite(int s) - { - if (currentFrame == 1) - { - renderer.sprite = sprites[s]; - } + { + renderer.sprite = sprites[s]; } public void setSprites(Sprite[] s) diff --git a/Assets/StreamingAssets/Images/Character/p1_animated_nohelmet.png b/Assets/StreamingAssets/Images/Character/p1_animated_nohelmet.png index 0497165192957c3d7481a8f0377ddf9fd3847359..5dfad161ad5622e1e1bc1f0b9e22440fed36abeb 100644 GIT binary patch literal 30622 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 literal 22001 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 i-@e + + + + + + + + + + + \ No newline at end of file diff --git a/Assets/StreamingAssets/Images/Character/p1_animated_nohelmet.xml.meta b/Assets/StreamingAssets/Images/Character/p1_animated_nohelmet.xml.meta new file mode 100644 index 000000000..cc16ba36a --- /dev/null +++ b/Assets/StreamingAssets/Images/Character/p1_animated_nohelmet.xml.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ddc563e08cc64254dbeea7bb037f9f49 +timeCreated: 1471945480 +licenseType: Free +DefaultImporter: + userData: + assetBundleName: + assetBundleVariant: From 95d32d89af46b2ee4dd4ded5b13f433377d6b485 Mon Sep 17 00:00:00 2001 From: Raketfart Date: Tue, 23 Aug 2016 12:38:17 +0200 Subject: [PATCH 4/6] Ran stylecop on CharacterAnimation --- .../Controllers/CharacterSpriteController.cs | 5 +- Assets/Scripts/Models/CharacterAnimation.cs | 60 +++++++++++-------- 2 files changed, 36 insertions(+), 29 deletions(-) diff --git a/Assets/Scripts/Controllers/CharacterSpriteController.cs b/Assets/Scripts/Controllers/CharacterSpriteController.cs index 311e71c03..7f6557d45 100644 --- a/Assets/Scripts/Controllers/CharacterSpriteController.cs +++ b/Assets/Scripts/Controllers/CharacterSpriteController.cs @@ -56,8 +56,7 @@ public void OnCharacterCreated(Character c) char_go.transform.position = new Vector3(c.X, c.Y, 0); char_go.transform.SetParent(characterParent.transform, true); - SpriteRenderer sr = char_go.AddComponent(); - //sr.sprite = SpriteManager.current.GetSprite("Character", "p2_front"); + SpriteRenderer sr = char_go.AddComponent(); sr.sortingLayerName = "Characters"; sr.color = c.GetCharacterColor(); @@ -73,7 +72,7 @@ public void OnCharacterCreated(Character c) SpriteManager.current.GetSprite("Character", "p1_nh_walk_south_01"), SpriteManager.current.GetSprite("Character", "p1_nh_walk_south_02") }; - c.animation.setSprites(sprites); + c.animation.SetSprites(sprites); // Add the inventory sprite onto the character GameObject inv_go = new GameObject("Inventory"); diff --git a/Assets/Scripts/Models/CharacterAnimation.cs b/Assets/Scripts/Models/CharacterAnimation.cs index 25a831a65..6b5f3debd 100644 --- a/Assets/Scripts/Models/CharacterAnimation.cs +++ b/Assets/Scripts/Models/CharacterAnimation.cs @@ -1,10 +1,18 @@ -using System; +#region License +// ==================================================== +// Project Porcupine Copyright(C) 2016 Team Porcupine +// This program comes with ABSOLUTELY NO WARRANTY; This is free software, +// and you are welcome to redistribute it under certain conditions; See +// file LICENSE, which is part of this source code package, for details. +// ==================================================== +#endregion +using System; using System.Collections.Generic; using UnityEngine; /// /// CharacterAnimation gets reference to character, and should be able to -/// figure out which animation to play, by looking at character Facing and IsMoving +/// figure out which animation to play, by looking at character Facing and IsMoving. /// public class CharacterAnimation { @@ -20,7 +28,6 @@ public class CharacterAnimation // TODO: should be more flexible .... private Sprite[] sprites = new Sprite[9]; - public CharacterAnimation(Character c, SpriteRenderer r) { character = c; @@ -29,13 +36,22 @@ public CharacterAnimation(Character c, SpriteRenderer r) public void Update(float deltaTime) { - if (currentFrame >= animationLength) currentFrame = 0; + if (currentFrame >= animationLength) + { + currentFrame = 0; + } + currentFrame++; - callAnimation(); + CallAnimation(); + } + + public void SetSprites(Sprite[] s) + { + sprites = s; } - private void callAnimation() + private void CallAnimation() { if (character.IsWalking) { @@ -43,19 +59,19 @@ private void callAnimation() switch (character.Facing) { case 0: // walk north - toggleAnimation(5, 6); + ToggleAnimation(5, 6); renderer.flipX = false; break; case 1: // walk east - toggleAnimation(3, 4); + ToggleAnimation(3, 4); renderer.flipX = false; break; case 2: // walk south - toggleAnimation(7, 8); + ToggleAnimation(7, 8); renderer.flipX = false; break; case 3: // walk west - toggleAnimation(3, 4); // FLIP east sprite + ToggleAnimation(3, 4); // FLIP east sprite renderer.flipX = true; break; default: @@ -64,23 +80,23 @@ private void callAnimation() } else { - //character idle + // character idle switch (character.Facing) { case 0: // walk north - showSprite(2); + ShowSprite(2); renderer.flipX = false; break; case 1: // walk east - showSprite(1); + ShowSprite(1); renderer.flipX = false; break; case 2: // walk south - showSprite(0); + ShowSprite(0); renderer.flipX = false; break; case 3: // walk west - showSprite(1); // FLIP east sprite + ShowSprite(1); // FLIP east sprite renderer.flipX = true; break; default: @@ -89,7 +105,7 @@ private void callAnimation() } } - private void toggleAnimation(int s1, int s2) + private void ToggleAnimation(int s1, int s2) { if (currentFrame == 1) { @@ -99,18 +115,10 @@ private void toggleAnimation(int s1, int s2) { renderer.sprite = sprites[s2]; } - } - private void showSprite(int s) + private void ShowSprite(int s) { renderer.sprite = sprites[s]; } - - public void setSprites(Sprite[] s) - { - sprites = s; - } - -} - +} \ No newline at end of file From 6fcc5b9864371b1a27b586ae86b1b7d2e09c5bb5 Mon Sep 17 00:00:00 2001 From: Raketfart Date: Tue, 23 Aug 2016 19:24:36 +0200 Subject: [PATCH 5/6] Removed whitespace --- Assets/Scripts/Models/Character.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Assets/Scripts/Models/Character.cs b/Assets/Scripts/Models/Character.cs index fdd7ad9bb..33c1aa8ce 100644 --- a/Assets/Scripts/Models/Character.cs +++ b/Assets/Scripts/Models/Character.cs @@ -338,7 +338,7 @@ private bool CheckForJobMaterials() // Walk towards a tile containing the required goods. Debug.Log("Walk to the stuff"); Debug.Log(myJob.canTakeFromStockpile); - + // Find the first thing in the Job that isn't satisfied. Inventory desired = myJob.GetFirstDesiredInventory(); @@ -457,7 +457,7 @@ private void Update_DoMovement(float deltaTime) IsWalking = false; return; // We're already were we want to be. } - + // currTile = The tile I am currently in (and may be in the process of leaving) // nextTile = The tile I am currently entering // destTile = Our final destination -- we never walk here directly, but instead use it for the pathfinding @@ -569,11 +569,11 @@ public void Update(float deltaTime) { Update_DoJob(deltaTime); - Update_DoMovement(deltaTime); - + Update_DoMovement(deltaTime); + if (cbCharacterChanged != null) { - cbCharacterChanged(this); + cbCharacterChanged(this); } animation.Update(deltaTime); From 4deec1daa22a78cabd88935255c80e365ac6da0f Mon Sep 17 00:00:00 2001 From: Raketfart Date: Tue, 23 Aug 2016 19:45:22 +0200 Subject: [PATCH 6/6] Changed facing from int to Enum --- Assets/Scripts/Models/Character.cs | 26 ++++++++++++++------- Assets/Scripts/Models/CharacterAnimation.cs | 20 ++++++++-------- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/Assets/Scripts/Models/Character.cs b/Assets/Scripts/Models/Character.cs index 33c1aa8ce..24054e2b0 100644 --- a/Assets/Scripts/Models/Character.cs +++ b/Assets/Scripts/Models/Character.cs @@ -15,6 +15,14 @@ using MoonSharp.Interpreter; using UnityEngine; +public enum Facing +{ + NORTH, + EAST, + SOUTH, + WEST +} + /// /// A Character is an entity on the map that can move between tiles and, /// for now, grabs jobs from the work queue and performs this. @@ -145,7 +153,7 @@ public Tile JobTile public bool IsWalking; // 0=north, 1=east, 2=south, 3=west - public int Facing; + public Facing CharFacing; /// Use only for serialization public Character() @@ -494,19 +502,19 @@ private void Update_DoMovement(float deltaTime) // Find character facing if (NextTile.X > CurrTile.X) { - Facing = 1; - } - else if (NextTile.Y > CurrTile.Y) - { - Facing = 0; + CharFacing = Facing.EAST; } else if (NextTile.X < CurrTile.X) { - Facing = 3; + CharFacing = Facing.WEST; } - else + else if (NextTile.Y > CurrTile.Y) + { + CharFacing = Facing.NORTH; + } + else { - Facing = 2; + CharFacing = Facing.SOUTH; } // At this point we should have a valid nextTile to move to. diff --git a/Assets/Scripts/Models/CharacterAnimation.cs b/Assets/Scripts/Models/CharacterAnimation.cs index 6b5f3debd..8ea5698c6 100644 --- a/Assets/Scripts/Models/CharacterAnimation.cs +++ b/Assets/Scripts/Models/CharacterAnimation.cs @@ -56,21 +56,21 @@ private void CallAnimation() if (character.IsWalking) { // character walking - switch (character.Facing) + switch (character.CharFacing) { - case 0: // walk north + case Facing.NORTH: // walk north ToggleAnimation(5, 6); renderer.flipX = false; break; - case 1: // walk east + case Facing.EAST: // walk east ToggleAnimation(3, 4); renderer.flipX = false; break; - case 2: // walk south + case Facing.SOUTH: // walk south ToggleAnimation(7, 8); renderer.flipX = false; break; - case 3: // walk west + case Facing.WEST: // walk west ToggleAnimation(3, 4); // FLIP east sprite renderer.flipX = true; break; @@ -81,21 +81,21 @@ private void CallAnimation() else { // character idle - switch (character.Facing) + switch (character.CharFacing) { - case 0: // walk north + case Facing.NORTH: // walk north ShowSprite(2); renderer.flipX = false; break; - case 1: // walk east + case Facing.EAST: // walk east ShowSprite(1); renderer.flipX = false; break; - case 2: // walk south + case Facing.SOUTH: // walk south ShowSprite(0); renderer.flipX = false; break; - case 3: // walk west + case Facing.WEST: // walk west ShowSprite(1); // FLIP east sprite renderer.flipX = true; break;