Project info

LifeBetBlackJack is een game die ik in mijn vrije tijd ben gaan maken. Omdat ik blackjack een leuk spel vind, heb ik mijn eigen versie ontwikkeld, geïnspireerd door Buckshot Roulette. In deze variant gebruik je power-items (powerkaartjes) om invloed uit te oefenen op het spelverloop. In plaats van tegen de dealer te spelen, speel je samen met de dealer: de dealer speelt tegelijkertijd met de speler.

Hoewel de kern van het spel staat, wil ik LifeBetBlackJack in de toekomst opnieuw aanpakken. De huidige gameplay tussen speler en dealer voelt voor mij nog niet optimaal. Met een rework wil ik de flow verbeteren, bugs oplossen, de AI-stem vervangen door visuele spreekwolken, en de game uiteindelijk releasen op Itch.io of mogelijk Steam, zodat het concept écht tot zijn recht komt.

Dit zijn een aantal leuke stukjes / featues binnen dit project

Scriptable objecten kaarten

Voor alle soorten kaarten is gebruikgemaakt van Scriptable Objects. Dit maakt het mogelijk om één kaart prefab te gebruiken dat bij het trekken uit de pot automatisch een willekeurige kaart toegewezen krijgt. In de projectbestanden zijn alle kaarten gemarkeerd met een K, bijvoorbeeld K-Boer (kaart Boer) of K-5 (kaart 5). Daarnaast is hier een voorbeeld te zien van hoe een Scriptable Object voor powerkaarten is opgebouwd. Elke powerkaart bevat een sprite om het uiterlijk van het prefab aan te passen, een type waarmee de juiste logica wordt aangeroepen, en een beschrijving die wordt gebruikt voor de UI wanneer de speler over de kaart hovert.

code snippet * Kaarten.cs / PowerKaarten.cs

public class Kaarten : ScriptableObject
{
    public string type;
    public Material Sprite;
    public int KaartValue;
    public AceSettings AceValues;
}
public struct AceSettings
{
    public Material ElevenAce;
    public Material OneAce;
}
public class PowerKaarten : ScriptableObject
{
    public Material Sprite;
    public string type;
    public string CardDesciption;
}
										

SlotManager

De SlotManager regelt de slotmachine tijdens de game. Het script stuurt de rotatie animaties aan, toont actuele game data zoals health en rondes, en beheert het trekken en plaatsen van speel en powerkaarten. Hiermee vormt de slotmachine de visuele en interactieve schakel tussen de speler en de onderliggende game logica.

code snippet * SlotManager.cs

//(dit zijn de beste stukjes uit de code niet het hele script)
public class SlotManager : MonoBehaviour
{
    public void GetPlayCard()
    {
        if (!Holding)
        {
            Vector3 Pos;
            int cardcount;
            if (P_ThisGamer == Gamers.player)
            {
                cardcount = WorkingOnHand == WorkingOn.main ? Game.PlayerPlayCards.Count : SecondHand.Count;
                if (WorkingOnHand == WorkingOn.main) Pos = Game.PlayPlacePointPlayer.transform.position + Game.PlayCardOffset * cardcount;
                else Pos = Game.PlayPlacePointPlayerSec.transform.position + Game.PlayCardOffset * cardcount;
                Game.SpawnPlayCard(Pos, CardRotation, out UsingCard gos);
                gos.ThisOwner = Gamers.player;
                gos.tagn = Game.PlayerPlayCards.Count + SecondHand.Count;
                if (WorkingOnHand == WorkingOn.main) Game.PlayerPlayCards.Add(gos);
                else SecondHand.Add(gos);
            }
            else if (P_ThisGamer == Gamers.ai)
            {
                cardcount = WorkingOnHand == WorkingOn.main ? Game.AiPlayCards.Count : SecondHand.Count;
                if (WorkingOnHand == WorkingOn.main) Pos = Game.PlayPlacePointAi.transform.position + -Game.PlayCardOffset * cardcount;
                else Pos = Game.PlayPlacePointAiSec.transform.position + -Game.PlayCardOffset * cardcount;
                Game.SpawnPlayCard(Pos, CardRotation, out UsingCard gos);
                gos.ThisOwner = Gamers.ai;
                gos.tagn = Game.AiPlayCards.Count + SecondHand.Count;
                if (WorkingOnHand == WorkingOn.main) Game.AiPlayCards.Add(gos);
                else SecondHand.Add(gos);
            }
            UI.UpdateUI();
        }
    }
    public void CheckHandForDoubble()
    {
        UsingCard[] hand = new UsingCard[2];
        hand = ThisGamer == Gamers.player ? Game.PlayerPlayCards.ToArray() : Game.AiPlayCards.ToArray();
        if (hand[0] != null && hand[1] != null)
        {
            if (hand[0].ThisCard.type == hand[1].ThisCard.type)
            {
                CanSplit = true;
                if (ThisGamer == Gamers.player) Game.GetSplitButtonOut();
            }
        }
    }
    public void GetPowerCard()
    {
        GridSlot[] Slot = P_ThisGamer == Gamers.player ? Game.PlayerPowerCards : Game.AiPowerCards; 
        if (Game.CheckActiveSlots(Slot, out int s))
        {
            Game.SpawnPowerCard(Slot[s].GridSpace, CardRotation, out PowerCard go);
            go.CardOwner = P_ThisGamer;
            go.tagn = s;
            Slot[s].InUse = true;
            Slot[s].PowerCard = go;
        }
    }
    public void StartRotate(DisplayStats WhatToDisplay)
    {
        RotateTimer = 0;
        StatsToSlot = WhatToDisplay;
        RotateState = SlotSpinning.spinning;
        SpinAudio.Play();
    }
    private void RotateSlotHealth()
    {
        int health = ThisGamer == Gamers.player ? Game.PlayerHealth : Game.AiHealth;
        health -= 1; // zet health gelijk aan aantal wheel elementen
        RotateTimer += Time.deltaTime;
        for (int i = 0; i < Wheels.Length; i++)
        {
            if (RotateTimer >= StopTimers[i])
            {
                if (!WheelsSet[i]) { WheelsSet[i] = true; StopAudio.Play(); }
                if (i <= health) Wheels[i].transform.localEulerAngles = Rotations.HeardRotation;
                else Wheels[i].transform.localEulerAngles = Rotations.SkullRoation;
            }
            else Wheels[i].transform.Rotate(0f, RotateSpeed * Time.deltaTime, 0f);
        }
        if (RotateTimer >= StopTimers[StopTimers.Length -1])
        {
            RotateState = SlotSpinning.idle;
            SpinAudio.Stop();
            for(int i = 0; i < Wheels.Length; i++)
            {
                WheelsSet[i] = false;
            }
        } 
    }
    private void RotateDisplayRounds()
    {
        RotateTimer += Time.deltaTime;
        for (int i = 0; i < Wheels.Length; i++)
        {
            if (RotateTimer >= StopTimers[i])
            {
                int roundWinner = (int)Game.RoundsWon[i] -1;
                if ((int)ThisGamer == roundWinner)
                {
                    if (Wheels[i].transform.localEulerAngles != Rotations.VinkRotation) StopAudio.Play();
                    Wheels[i].transform.localEulerAngles = Rotations.VinkRotation;
                }
                else
                {
                    if (Wheels[i].transform.localEulerAngles != Rotations.CrossRotation) StopAudio.Play();
                    if (Game.RoundsWon[i] == WhoWon.NotPlayed) NotPlayedIndicators[i].GetComponent().mesh = NotPlayedIcon;
                    Wheels[i].transform.localEulerAngles = Rotations.CrossRotation;
                }
            }
            else Wheels[i].transform.Rotate(0f, RotateSpeed * Time.deltaTime, 0f);
        }
        if (RotateTimer >= StopTimers[StopTimers.Length - 1])
        {
            Invoke("ResetIconsCollor", 3);
            RotateState = SlotSpinning.idle;
            SpinAudio.Stop();
        }
    }
    public void CompareHands()
    {
        int mainvalue = ThisGamer == Gamers.player ? Game.CheckHandValue(Game.PlayerPlayCards.ToArray()) : Game.CheckHandValue(Game.AiPlayCards.ToArray());
        int secondvalue = Game.CheckHandValue(SecondHand.ToArray());
        if (secondvalue > mainvalue && secondvalue <= 21 && mainvalue <= 21)
        {
            WorkingOnHand = WorkingOn.second;
        }
        UI.UpdateUI();
    }
    public void ResetSecondhand()
    {
        foreach (UsingCard card in SecondHand)
        {
            MoveTowards move = card.GetComponent();
            move.SetEndPoint(Game.GetCardOrigin());
            move.DoDestoyOnEnd();
        }
        SecondHand.Clear();
    }
}

										

Selecting

Voor het interacten met kaartjes of knopjes binnen het spel gebruik ik de ingebouwde OnMouseDown en OnMouseEntermethoden. In deze voorbeelden gebruik ik ze om kaartjes te selecteren en om een pop-up UI weer te geven wanneer er over powerkaartjes wordt gehoverd. Dit is simpel maar wel effectief.

code snippet * SelectCard.cs

public class SelectCard : MonoBehaviour
{
    private GameManager Game;
    public Gamers CardOwner { get; set; }
    private CardOwnerManager CardManager;
    private UsingCard CardUser;
    private void Start()
    {
        Game = FindObjectOfType();
        CardUser = GetComponent();
        CardOwner = CardUser.ThisOwner;
        CardManager = CardOwner == Gamers.player ? Game.GetPlayer() : Game.GetAi();
    }
    private void OnMouseDown()
    {
        if (CardOwner == Gamers.player) SelectThisCard();
    }
    public void SelectThisCard()
    {
        CardManager.SelectedCard = CardUser;
    }
}

public class PowerCard : MonoBehaviour
{
    private UI GameUI;
    private void OnMouseEnter()
    {
        GameUI.SetDisPlayActive(true);
        GameUI.DisplayCardDesc(P_ThisPowerCard.CardDesciption);
    }
    private void OnMouseExit()
    {
        GameUI.SetDisPlayActive(false);
    }
    private void OnMouseDown()
    {
        if (CardOwner == Gamers.player)
        {
            if (!Game.GetPlayer().Holding) UseCard();
            else GameUI.DisplayFlashText("You are blocked. you can't activate powercards");
        }
    }
}
    

PowerCards Logic

Deze code bevat de logica voor powerkaarten binnen de game. Elke functie voert een specifieke actie uit die een speler of AI kan beïnvloeden, zoals een nieuw hand creëren, een kaart splitsen, een extra aas toevoegen of de tegenstander blokkeren.

code snippet * PowerCard.cs

//(dit zijn de beste stukjes uit de code niet het hele script)

public class PowerCard : MonoBehaviour
{
    private PowerKaarten P_ThisPowerCard;
    private void Block()
    {
        CardOwnerManager GamerToBlock = CardOwner == Gamers.player ? Game.GetAi() : Game.GetPlayer();
        if (!GamerToBlock.Blocked)
        {
            GamerToBlock.Blocked = true;
            if (GamerToBlock.ThisGamer == Gamers.player) GameUI.DisplayFlashText("You Got Blocked for the next life");
            CardUsed();
        }
        else if (CardOwner == Gamers.player) GameUI.DisplayFlashText("The Dealer is already blocked");
    }
    private void Split()
    {
        CardOwnerManager GamerToSplitHand = CardOwner == Gamers.player ? Game.GetPlayer() : Game.GetAi();
        if (!GamerToSplitHand.Splitting)
        {
            if (!GamerToSplitHand.CanSplit)
            {
                Game.SplitHand(GamerToSplitHand);
                CardUsed();
            }
            else if (CardOwner == Gamers.player) GameUI.DisplayFlashText("You can already split");
        }
        else if (CardOwner == Gamers.player) GameUI.DisplayFlashText("Your are already splitting");
    }
    private void ExtraAas()
    {
        bool contin = false;
        CardOwnerManager Gamer = CardOwner == Gamers.player ? Game.GetPlayer() : Game.GetAi();
        if (Gamer.SelectedCard != null)
        {
            UsingCard[] hand = CardOwner == Gamers.player ? Game.PlayerPlayCards.ToArray() : Game.AiPlayCards.ToArray();
            MoveTowards move = GetComponent();
            move.SetEndPoint(Gamer.SelectedCard.transform.position);
            for (int i = 0; i < hand.Length; i++)
            {
                if (hand[i].tagn == Gamer.SelectedCard.tagn) contin = true;
                if (Gamer.SecondHand.Count - 1 >= i) if (Gamer.SecondHand[i].tagn == Gamer.SelectedCard.tagn) contin = true;
                if (contin)
                {
                    UsingCard thisNewUsing = gameObject.AddComponent();
                    thisNewUsing.ThisCard = Aas;
                    if (hand[i].tagn == Gamer.SelectedCard.tagn)
                    {
                        if (CardOwner == Gamers.player) Game.PlayerPlayCards[i] = thisNewUsing;
                        else Game.AiPlayCards[i] = thisNewUsing;
                    }
                    if (Gamer.SecondHand.Count - 1 >= i) if (Gamer.SecondHand[i].tagn == Gamer.SelectedCard.tagn) Gamer.SecondHand[i] = thisNewUsing;
                    MoveTowards moveSelected = Gamer.SelectedCard.GetComponent();
                    moveSelected.SetEndPoint(Game.GetCardOrigin());
                    moveSelected.DoDestoyOnEnd();
                    AceUsed();
                    //update all UI
                    Gamer.UI.UpdateUI();
                    GameUI.SetDisPlayActive(false);
                    break;
                }
            }
        }
        else if (CardOwner == Gamers.player) GameUI.DisplayFlashText("Select a card first!");
    }
    public void MakeNewHand()
    {
        CardOwnerManager gamer = CardOwner == Gamers.player ? Game.GetPlayer() : Game.GetAi();
        if (!gamer.Blackjack && !gamer.Splitting && !gamer.Blocked && !gamer.hadnewhand)
        {
            gamer.newhand = true;
            gamer.hadnewhand = true;
            // z is up
            Vector3 Pos = new Vector3();
            for (int i = 0; i <= 1; i++)
            {
                if (CardOwner == Gamers.player)
                {
                    Pos = Game.PlayPlacePointPlayer.transform.position;
                    Pos.x += Game.PlayCardOffset.x * i;
                    Pos.z += gamer.WhatIsNewDeckCardDownOffset();
                    Game.SpawnPlayCard(Pos, gamer.WhatIsCardRotation(), out UsingCard gos);
                    gos.ThisOwner = Gamers.player;
                    //er gaan nooit meer dan 100 kaarten op tagel liggen en na de ronde zijn deze weer weg. tag hardcode kan hier
                    gos.tagn = 100 + i;
                    Game.PlayerSecondChance[i] = gos;
                }
                else
                {
                    Pos = Game.PlayPlacePointAi.transform.position;
                    Pos.z += -gamer.WhatIsNewDeckCardDownOffset();
                    Game.SpawnPlayCard(Pos, gamer.WhatIsCardRotation(), out UsingCard gos);
                    gos.ThisOwner = Gamers.ai;
                    //er gaan nooit meer dan 100 kaarten op tagel liggen en na de ronde zijn deze weer weg. tag hardcode kan hier
                    gos.tagn = 100 + i;
                    Game.AiSecondChance[i] = gos;
                }
            }
            CardUsed();
        }
        else if (CardOwner == Gamers.player)GameUI.DisplayFlashText("You can't get a new hand right now");
    }
}
    

GameManager

De GameManager regelt de game states, zoals wie er heeft gewonnen, hoeveel rondes er zijn gespeeld en hoeveel levens de speler en AI hebben. Ook wordt hier de totale waarde van de handen gecontroleerd en zijn er een aantal functies die de hand van de speler kunnen beïnvloeden. Hieronder valt bijvoorbeeld de split-functie om je hand te splitsen, die zowel door de powercards als door de normale speelregels wordt gebruikt. Vanuit de GameManager worden ook alle kaarten ingespawned.

code snippet * GameManager.cs

//(dit zijn de beste stukjes uit de code niet het hele script)
[Serializable]
public struct GridSlot
{
    public Vector3 GridSpace;
    public bool InUse;
    public PowerCard PowerCard;
}
[Serializable]
public struct SplitButton
{
    public GameObject ButtonHolder;
    public Vector3 OutPoint;
    public Vector3 InPoint;
    public float MoveSpeed;
    [HideInInspector] public float MoveTimer;
    [HideInInspector] public float percentage;
}
public class GameManager : MonoBehaviour
{
    [Header("CardSpawning")]
    [SerializeField] private Kaarten[] PlayCards;
    [SerializeField] private PowerKaarten[] PowerCards;
    [SerializeField] private UsingCard GameCard;
    [SerializeField] private PowerCard PowerCard;

    [Header("Inventory")]
    public GridSlot[] PlayerPowerCards;
    public GridSlot[] AiPowerCards;
    public List PlayerPlayCards = new List();
    public List AiPlayCards = new List();
    [Tooltip("zet op 2")]
    public UsingCard[] PlayerSecondChance;
    [Tooltip("zet op 2")]
    public UsingCard[] AiSecondChance;

    [Header("Game Stats")]
    [SerializeField] private int P_PlayerHealth;
    [SerializeField] private int P_AiHealth;
    private WhoWon[] P_RoundWon;
    private int Lives = 3;
    public int PlayerHealth { get => P_PlayerHealth; }
    public int AiHealth { get => P_AiHealth; }
    public WhoWon[] RoundsWon { get => P_RoundWon; }

    private void CompareHands(int playervalue, int aivalue)
    {
        //compare scores
        //check overs
        if (GameWait == null)
        {
            if (playervalue > 21 && aivalue > 21) { GameWait = StartCoroutine(Push()); return; }
            if (playervalue > 21 && aivalue <= 21) { CurrenhandWinner(Gamers.ai); return; }
            if (aivalue > 21 && playervalue <= 21) { CurrenhandWinner(Gamers.player); return; }
            //check push
            if (playervalue == aivalue) { GameWait = StartCoroutine(Push()); return; }
            //check value win
            if (playervalue > aivalue) { CurrenhandWinner(Gamers.player); return; }
            if (playervalue < aivalue) { CurrenhandWinner(Gamers.ai); return; }
        }
    }
    private IEnumerator RoundWinner(Gamers winner)
    {
        yield return new WaitForSeconds(Player.StopTimerEnd + 0.2f);
        //set winner
        int round = RoundCheck();
        P_RoundWon[round] = winner == Gamers.player ? WhoWon.player : WhoWon.ai;
        //display won rounds
        Player.StartRotate(DisplayStats.rounds);

        yield return new WaitForSeconds(3.5f);

        //check if the game is over : + 1 om te compenseren met 0 element 
        if (round == P_RoundWon.Length - 1) Invoke("GameOver",1);

        // reset lives and display the new set of lives
        ResetLives();
        Ai.StartRotate(DisplayStats.health);
        Player.StartRotate(DisplayStats.health);
        GiveOutPowerCards(PowerCardGiveOutAmount);
    }
    private IEnumerator Push()
    {
        GameUI.DisplayFlashText("Push");
        yield return new WaitForSeconds(1);
        ResetStats();
        ResetPlayCards();
        OffHolding();
        NewHand();
        Player.SetTrap();
        Ai.SetTrap();
        GameWait = null;
    }
    private void CurrenhandWinner(Gamers gamer)
    {
        if (gamer == Gamers.player)
        {
            P_AiHealth -= 1;
            Ai.StartRotate(DisplayStats.health);
        }
        if (gamer == Gamers.ai)
        {
            P_PlayerHealth -= 1;
            Player.StartRotate(DisplayStats.health);
        }
        if (HealthCheck() && GameWait == null) GameWait = StartCoroutine(Next(7));
        else if (GameWait == null)
        {
            HealthCheck();
            GameWait = StartCoroutine(Next(2));
        }
    }
    private IEnumerator Next(float WaitTime)
    {
        GetSplitButtonIn();
        ResetStats();
        yield return new WaitForSeconds(WaitTime);
        ResetPlayCards();
        Player.WorkingOnHand = WorkingOn.main;
        Ai.WorkingOnHand = WorkingOn.main;
        OffHolding();
        NewHand();
        Player.SetTrap();
        Ai.SetTrap();
        GameWait = null;
    }
    /// 
    /// end for the very end of the game
    /// 
    private void GameOver()
    {
        GameFadeLoader Fade = FindObjectOfType();
        switch (GameWinState())
        {
            case WhoWon.player:
                Fade.StartFadeOut();
                Fade.SceneToLoad = "win";
                break;
            case WhoWon.ai:
                Fade.StartFadeOut();
                Fade.SceneToLoad = "lost";
                break;
        }
    }
    private WhoWon GameWinState()
    {
        int roundswon = 0;
        for (int i = 0; i < P_RoundWon.Length; i++)
        {
            if (P_RoundWon[i] == WhoWon.player)
            {
                roundswon++;
            }
        }
        if (roundswon >= 2) return WhoWon.player;
        else return WhoWon.ai;
    }
    public void SpawnPowerCard(Vector3 PlacePoint, Vector3 Rotation, out PowerCard go)
    {
        go = Instantiate(PowerCard,CardOriginPoint.transform.position,Quaternion.identity);
        go.GetComponent().SetEndPoint(PlacePoint);
        go.ThisPowerCards = GetRandomPowerCard();
        go.transform.eulerAngles = Rotation;
    }
    #endregion
    #region playcard
    public void GiveOutPlayCard(int amount)
    {
        for (int i = 0; i < amount; i++)
        {
            Ai.GetPlayCard();
            Player.GetPlayCard();
        }
        Player.CheckHandForDoubble();
        Ai.CheckHandForDoubble();
    }
    public void SpawnPlayCard(Vector3 PlacePoint, Vector3 Rotation, out UsingCard gos)
    {
        UsingCard go = Instantiate(GameCard, CardOriginPoint.transform.position, Quaternion.identity);
        go.GetComponent().SetEndPoint(PlacePoint); ;
        go.ThisCard = GetRandomPlayCard();
        go.transform.eulerAngles = Rotation;
        gos = go.GetComponent();
    }
    private PowerKaarten GetRandomPowerCard()
    {
        int AllCards = PowerCards.Length;
        int random = Random.Range(1, AllCards + 1);
        random -= 1; //zet int gelijk met element 0
        PowerKaarten ChosenCard = PowerCards[random];
        return ChosenCard;
    }
    #endregion
    private Kaarten GetRandomPlayCard()
    {
        int AllCards = PlayCards.Length;
        int random = Random.Range(1, AllCards + 1);
        random -= 1; //zet int gelijk met element 0
        Kaarten ChosenCard = PlayCards[random];
        return ChosenCard;
    }
    //// Checks ----
    /// 
    /// return the next available slot for a card
    /// 
    /// 
    /// 
    /// 
    public bool CheckActiveSlots(GridSlot[] slots, out int S)
    {
        // s = card slot
        for (int i = 0; i < slots.Length; i++)
        {
            if (!slots[i].InUse)
            {
                S = i;
                return true;
            }
        }
        S = 0;
        return false;
    }
    /// 
    /// checks the total value of an hand
    /// 
    /// 
    /// 
    public int CheckHandValue(UsingCard[] cards)
    {
        List acesList = new List();
        int aces = 0;
        int value = 0;
        foreach (UsingCard card in cards)
        {
            Kaarten id = card.ThisCard;
            if (id.type == "aas")
            {
                aces++;
                acesList.Add(card);
            }
            value += id.KaartValue;
        }
        int elevenace = 0;
        int oneace = 0;
        while (aces > 0)
        {
            if ((value + 11) > 21)
            {
                value +=1 ;
                oneace++;
                if (value > 21 && elevenace >= 1)
                {
                    //ace compensatie
                    value -= 10;
                    //change ace type
                    oneace += 1;
                    elevenace -= 1;
                }
            }
            else if ((value + 11) <= 21)
            {
                value += 11;
                elevenace++;
            }
            aces--;
        }
        foreach (UsingCard card in acesList)
        {
            if (elevenace > 0)
            {
                card.GetComponent().material = card.ThisCard.AceValues.ElevenAce;
                elevenace--;
            }
            else if (oneace > 0)
            {
                card.GetComponent().material = card.ThisCard.AceValues.OneAce;
                oneace--;
            } 
        }
        return value;
    }
    /// 
    /// checks in which round the game is and if there is an unplayed match
    /// 
    /// 
    /// 
    private int RoundCheck()
    {
        for (int i = 0; i < P_RoundWon.Length -1; i++)
        {
            if (P_RoundWon[i] == WhoWon.NotPlayed)
            {
                return i;
            }
        }
        return 2;
    }
    /// 
    /// checks deck of both player and ai if there is a blackjack at start
    /// 
    private void CheckStartBlackJack()
    {
        int playervalue = CheckHandValue(PlayerPlayCards.ToArray());
        int aivalue = CheckHandValue(AiPlayCards.ToArray());

        if (playervalue == 21 && aivalue == 21)
        {
            GameWait = StartCoroutine(Push());
        }
        else if (playervalue == 21)
        {
            CurrenhandWinner(Gamers.player);
        }
        else if (aivalue == 21)
        {
            CurrenhandWinner(Gamers.ai);
        }
    }
    public void GetSplitButtonOut()
    {
        Split.MoveTimer += Time.deltaTime;
        Split.percentage = Split.MoveTimer / Split.MoveSpeed; 
        Split.ButtonHolder.transform.position = Vector3.Lerp(Split.ButtonHolder.transform.position, Split.OutPoint, Split.percentage);
        if (Split.ButtonHolder.transform.position != Split.OutPoint) Invoke("GetSplitButtonOut",0);
        else
        {
            Split.MoveTimer = 0;
            Split.percentage = 0;
        }
    }
    public void SplitHand(CardOwnerManager gamer)
    {
        gamer.Splitting = true;   
        UsingCard[] hand = gamer.ThisGamer == Gamers.player ? PlayerPlayCards.ToArray() : AiPlayCards.ToArray();
        if (hand.Length == 1) return;
        int halfhand = (int)hand.Length / 2;
        for (int i = hand.Length -1; i >= halfhand; i--)
        {
            switch (gamer.ThisGamer)
            {
                case Gamers.player:
                    PlayerPlayCards.Remove(PlayerPlayCards[i]);
                    break;
                case Gamers.ai:
                    AiPlayCards.Remove(AiPlayCards[i]);
                    break;
            }
            gamer.SecondHand.Add(hand[i]);
            gamer.UI.UpdateUI();
        }
        for (int i = hand.Length -1; i >= halfhand; i--)
        {
            GameObject sechandpoint = gamer.ThisGamer == Gamers.player ? PlayPlacePointPlayerSec : PlayPlacePointAiSec;
            if (i == halfhand) hand[i].GetComponent().SetEndPoint(sechandpoint.transform.position);
            else hand[i].GetComponent().SetEndPoint(sechandpoint.transform.position + PlayCardOffset * (gamer.SecondHand.Count -1));
        }
    }
    public void HoldnewHand(Gamers Whois)
    {
        if (Whois == Gamers.player)
        {
            for (int i = 0; i <= 1; i++)
            {
                MoveTowards move = PlayerPlayCards[i].GetComponent();
                PlayerSecondChance[i].GetComponent().SetEndPoint(PlayerPlayCards[i].transform.position);
                PlayerPlayCards[i] = PlayerSecondChance[i];
                move.SetEndPoint(GetCardOrigin());
                move.DoDestoyOnEnd();
            }
            Player.newhand = false;
        }
        else
        {
            for (int i = 0; i <= 1; i++)
            {
                MoveTowards move = AiPlayCards[i].GetComponent();
                AiSecondChance[i].GetComponent().SetEndPoint(AiPlayCards[i].transform.position);
                AiPlayCards[i] = AiSecondChance[i];
                move.SetEndPoint(GetCardOrigin());
                move.DoDestoyOnEnd();
            }
            Ai.newhand = true;
        }
    }
    public void SwitchHand()
    {
        if (!Switchedhands)
        {
            Switchedhands = true;
            UsingCard[] handPlayer = PlayerPlayCards.ToArray();
            UsingCard[] handAI = AiPlayCards.ToArray();

            for (int i = 0; i < AiPlayCards.Count; i++)
            {
                AiPlayCards[i].GetComponent().SetEndPoint(PlayPlacePointPlayer.transform.position + PlayCardOffset * i);
                AiPlayCards[i].transform.eulerAngles = GetPlayer().WhatIsCardRotation();
                AiPlayCards[i].GetComponent().CardOwner = Gamers.player;
            }
            for (int i = 0; i < PlayerPlayCards.Count; i++)
            {
                PlayerPlayCards[i].GetComponent().SetEndPoint(PlayPlacePointAi.transform.position + -PlayCardOffset * i);
                PlayerPlayCards[i].transform.eulerAngles = GetAi().WhatIsCardRotation();
                AiPlayCards[i].GetComponent().CardOwner = Gamers.ai;
            }
            PlayerPlayCards.Clear();
            AiPlayCards.Clear();
            PlayerPlayCards = handAI.ToList();
            AiPlayCards = handPlayer.ToList();

            Ai.UI.UpdateUI();
            Player.UI.UpdateUI();
        }
    }
}