Unity-Technologies / 2d-extras

Fun 2D Stuff that we'd like to share!
Other
1.54k stars 342 forks source link

Animated Tile Expansion #376

Open Kuro-Lai opened 1 year ago

Kuro-Lai commented 1 year ago

Hello, i made for my project a customized Tile.

For a single tile it works well. I can add a separate sprite (In this case a MirrorSprite) to and SpriteRenderer in the attached Object.

Is there a way to add and refresh the "MirrorSprite" in an Animated Tile too? I found only a way to set the base spriteArrays, but no function to refresh the Object by a custom function each time the sprite is changed.

This is the base code

    public class GroundTile : TileBase
    {
        /// <summary>
        /// The Sprites used for randomizing output.
        /// </summary>
        [SerializeField] public GroundSprite[] m_DefaultSprite = new GroundSprite[1];
        /// <summary>
        /// The Default GameObject.
        /// </summary>
        public GameObject m_DefaultGameObject;
        /// <summary>
        /// The Default Collider Type set when creating a new Rule.
        /// </summary>
        public Tile.ColliderType m_DefaultColliderType = Tile.ColliderType.None;

        public SingleUnityLayer m_HindernisMask;
        public SingleUnityLayer m_StepMask;
        public SingleUnityLayer m_WalkMask;
        public SingleUnityLayer m_SurfMask;

        public Colider m_CTopLeft = Colider.Nothing;
        public Colider m_CTopRight = Colider.Nothing;
        public Colider m_CBotLeft = Colider.Nothing;
        public Colider m_CBotRight = Colider.Nothing;

        public Direction m_DTopLeft = Direction.Nothing;
        public Direction m_DTopRight = Direction.Nothing;
        public Direction m_DBotLeft = Direction.Nothing;
        public Direction m_DBotRight = Direction.Nothing;

        public float m_SpeedMultiplier = 1f;

        [Serializable]
        public struct GroundSprite
        {
            /// <summary>
            /// Sprite.
            /// </summary>
            public Sprite Sprite;
            /// <summary>
            /// Sprite for Mirrormask
            /// </summary>
            public Sprite MirrorSprite;
            /// <summary>
            /// Weight of the Sprite.
            /// </summary>
            public int Weight;
        }
        [System.Flags]
        public enum Direction
        {
            Nothing = 0,
            Up = 1,
            Down = 2,
            Left = 4,
            Right = 8,
            Everything = 0b1111
        }
        public enum Colider
        {
            Nothing,
            Hindernis,
            Walkable,
            Surfable,
            Step
        }
        public void SetDefaultData(TileData tileData)
        {
            if (tileData.gameObject != null)
            {
                Transform var = tileData.gameObject.transform.Find("Collider");
                if (var != null)
                {
                    // Object in Tile enthalten
                    GameObject LayerObject;
                    LayerObject = var.transform.Find("HTL")?.gameObject;
                    int newMask = 0;
                    switch (m_CTopLeft)
                    {
                        case Colider.Hindernis:
                            newMask = m_HindernisMask.LayerIndex;
                            break;
                        case Colider.Walkable:
                            newMask = m_WalkMask.LayerIndex;
                            break;
                        case Colider.Surfable:
                            newMask = m_SurfMask.LayerIndex;
                            break;
                        case Colider.Step:
                            newMask = m_StepMask.LayerIndex;
                            break;
                    }
                    SetGridData(LayerObject, m_CTopLeft, m_DTopLeft, m_SpeedMultiplier, newMask);

                    LayerObject = var.transform.Find("HTR")?.gameObject;
                    newMask = 0;
                    switch (m_CTopRight)
                    {
                        case Colider.Hindernis:
                            newMask = m_HindernisMask.LayerIndex;
                            break;
                        case Colider.Walkable:
                            newMask = m_WalkMask.LayerIndex;
                            break;
                        case Colider.Surfable:
                            newMask = m_SurfMask.LayerIndex;
                            break;
                        case Colider.Step:
                            newMask = m_StepMask.LayerIndex;
                            break;
                    }
                    SetGridData(LayerObject, m_CBotRight, m_DTopRight, m_SpeedMultiplier, newMask);

                    LayerObject = var.transform.Find("HBL")?.gameObject;
                    newMask = 0;
                    switch (m_CBotLeft)
                    {
                        case Colider.Hindernis:
                            newMask = m_HindernisMask.LayerIndex;
                            break;
                        case Colider.Walkable:
                            newMask = m_WalkMask.LayerIndex;
                            break;
                        case Colider.Surfable:
                            newMask = m_SurfMask.LayerIndex;
                            break;
                        case Colider.Step:
                            newMask = m_StepMask.LayerIndex;
                            break;
                    }
                    SetGridData(LayerObject, m_CBotLeft, m_DBotLeft, m_SpeedMultiplier, newMask);

                    LayerObject = var.transform.Find("HBR")?.gameObject;
                    newMask = 0;
                    switch (m_CBotRight)
                    {
                        case Colider.Hindernis:
                            newMask = m_HindernisMask.LayerIndex;
                            break;
                        case Colider.Walkable:
                            newMask = m_WalkMask.LayerIndex;
                            break;
                        case Colider.Surfable:
                            newMask = m_SurfMask.LayerIndex;
                            break;
                        case Colider.Step:
                            newMask = m_StepMask.LayerIndex;
                            break;
                    }
                    SetGridData(LayerObject, m_CBotRight, m_DBotRight, m_SpeedMultiplier, newMask);
                }
            }

        }
        public void SetGridData(GameObject obj, Colider colidertype, Direction direction, float speed, int layerMask)
        {
            GroundData Data = obj.GetComponent<GroundData>();
            if (Data == null)
            {
                Data = obj.AddComponent<GroundData>();
            }
            obj.layer = layerMask;
            Data.direction = direction;
            Data.colidertype = colidertype;
            Data.SpeedMultiplier = speed;
        }

        public override void GetTileData(Vector3Int position, ITilemap tilemap, ref TileData tileData)
        {
            tileData.sprite = m_DefaultSprite[0].Sprite;
            tileData.gameObject = m_DefaultGameObject;
            tileData.colliderType = m_DefaultColliderType;
            tileData.flags = TileFlags.LockTransform;
            tileData.color = Color.white;
            tileData.transform = Matrix4x4.identity;

            SpriteRenderer mSprite = tileData.gameObject?.transform.Find("Mirror")?.GetComponent<SpriteRenderer>();
            if (mSprite != null) mSprite.sprite = m_DefaultSprite[0].MirrorSprite;

            SetDefaultData(tileData);
        }
    }

and this is the code for the animated tile in a subclass

        public override bool GetTileAnimationData(Vector3Int position, ITilemap tilemap, ref TileAnimationData tileAnimationData)
        {
            if (m_DefaultSprite.Length > 0)
            {
                tileAnimationData.animatedSprites = m_DefaultSprite.Select(p => p.Sprite).ToArray();
                tileAnimationData.animationSpeed = Random.Range(m_MinSpeed, m_MaxSpeed);
                return true;
            }
            return false;
        }

Is there a way to call this function every time the Frame of the Tile is updated to set the correct Sprite in the Object?

            SpriteRenderer mSprite = tileData.gameObject?.transform.Find("Mirror")?.GetComponent<SpriteRenderer>();
            if (mSprite != null) mSprite.sprite = m_DefaultSprite[FrameIndex].MirrorSprite;