前往
大廳
主題

Unity遊戲研究-卡牌遊戲(2)-調整手牌位置

冰峰Will | 2021-10-26 21:17:33 | 巴幣 1130 | 人氣 1587

隔了幾日才發第二篇
絕對不是因為跑去玩新的卡牌遊戲:Inscryption了
原本想從卡牌生成說起,
但生成就用Instantiate這樣,
暫時沒有其他的,
所以就從調整卡牌位置開始吧。

調整手牌位置
第一版本 先算最左邊的位置,在調整後面卡牌的位置
(大於五張牌自動縮小間距)
優點:間距、卡片旋轉角度與弧度都可細微設定
缺點:需要較多運算與驗證。
    /// <summary>
    /// 位置調整
    /// </summary>
    private void PositionAdjustment(){
        cardPosition  = new List<Vector2>();

        // 控制在一定寬度內
        float _width = cardWidth + maxSpacing;
        if(ownCards.Count > 5){
            _width = _width / (1f + (ownCards.Count - 5) / (5 - 1) );
        }

        //是否為奇數
        float odd  = 1f;
        if(ownCards.Count % 2 == 1){
            odd = 0;
        }
        
        //最左邊的位置
        float x = -((_width * (int)(ownCards.Count / 2))) + _width / 2 * odd;
        //4為最左邊牌的旋轉角度,5為當滿五張牌時,最旁邊的牌角度為4
        //也就是改成6,滿六張牌旁邊才會為4
        float z = 4f / (5f - 1f) * (ownCards.Count - 1f);
        z = z > 4f? 4f: z;

        for (int i = 0; i < ownCards.Count; i++)
        {
            
            float z1 = ((float)ownCards.Count - 1f);
            z1 = z1 == 0 ? 1 : z1;
            cardLocation[i].transform.rotation = Quaternion.Euler(0f, 0f, z - (z * 2f) / z1  * i);

            cardPosition.Add(new Vector2(x + _width * i, transform.position.y));
            
        }
        
    }
這邊我要解釋一下圖層的部分
有人會問我為啥要把位置跟圖層物件另為儲存呢?
先給大家看我的Unity畫面
我的圖層為什麼不移動的原因,
是因為我想呈現比較好看的弧度與旋轉角度,
再加上移動與變換效果方面這樣也比較方便,
(可能是我程式碼的寫法關係)
我這樣只需要將卡牌的角度變化為0,
會因為父物件的不同,
自行調整角度與位置。


第二版本 是參考此網站
利用Vector3.Slerp,去生成弧度位置。
優點:自動分配卡片弧度位置。
缺點:卡牌的旋轉角度可能要自己抓感覺
cardPosition  = new List<Vector2>();
        // 控制在一定寬度內
        float _width = cardWidth + maxSpacing;
        //最旁邊的位置
        float _x = ((_width * (int)(5 / 2)));
        //最左邊
        Vector3 a = new Vector3(-_x, 1f, 0);
        //最右邊
        Vector3 b = new Vector3(_x, 1f, 0);
        //改變弧度值
        float c = 1000f;
        //弧度中心點
        Vector3 center = (a + b) * 0.5f;
        center -= new Vector3(0, c, 0);

        a -= center;
        b -= center;
        for (int i = 1; i < ownCards.Count + 1; i++)
        {
            Vector3 v3 = Vector3.Slerp(a, b,i * (1f / (ownCards.Count + 1)));
            //減掉改變弧度時多餘的高度c
            v3 = new Vector3(v3.x, v3.y - c, v3.z);
            cardPosition.Add(v3);
        }
解答一下為啥要減掉c,
看到下圖多條紅線的地方,
當c越大弧度就越小,但Y軸就會被拉高,
而Y軸直接歸零就沒有弧度了,
所以直接減掉增加的高度就可以了。

第二版本我就沒有做旋轉角度
因為我習慣了第一個版本的了,
所以最後還是改成第一個版本。

可能之後會用第一個版本,
然後嘗試把距離位置改用Vector3.Lerp,
但現在運行的好好的,就有點懶得改了~
(大多時間都在解決Vector3.Slerp旋轉的我)



有任何程式想法都可以留言喔,
我想要更精進程式的部分,
不論是命名方式、程式寫法等,
都可以一同來交流喔~

順便宣傳DC群
這裡包含了繪畫創作、BOT娛樂、遊戲討論、影像分享、程式交流等內容。

創作回應

更多創作