【unity實戰】使用Splines+DOTween制作彎曲手牌和抽牌動畫效果

最終效果

在這里插入圖片描述

文章目錄

  • 最終效果
  • 前言
  • 實戰
    • 1、Splines的使用
    • 2、繪制樣條線
    • 3、DOTween安裝和使用
    • 4、基于樣條曲線(Spline)的手牌管理系統
      • 4.1 代碼實現
      • 4.2 解釋:
        • (1)計算第一張卡牌的位置(居中排列)
        • (1)關鍵旋轉計算:
        • (3)應用動畫
      • 4.3 配置參數
      • 4.4 效果
  • 參考
  • 專欄推薦
  • 完結

前言

本文介紹了基于Unity樣條曲線(Spline)的手牌管理系統實現方法。通過Spline插件繪制平滑路徑,結合DOTween實現卡牌動態排列效果。

系統核心功能包括:

  • 按空格鍵生成新卡牌(不超過最大數量限制),
  • 沿樣條曲線均勻分布卡牌,
  • 并利用DOTween實現平滑移動和旋轉動畫。

重點解析了卡牌居中排列的數學計算和關鍵旋轉算法,展示了如何通過LookRotation和叉積計算實現卡牌朝向的正確調整。文章提供了完整的C#代碼實現和參數配置說明,最終效果可讓卡牌按樣條路徑絲滑排列。

實戰

1、Splines的使用

Splines插件的基礎使用具體可以參考:【unity實戰】Spline 插件讓物體沿路徑 “絲滑” 走位,實現火車沿軌道移動——Spline 插件的使用

2、繪制樣條線

在這里插入圖片描述

修改中間點弧度,使其更加平滑
在這里插入圖片描述

3、DOTween安裝和使用

DOTween安裝和使用,具體可以參考:【推薦100個unity插件之2】 DoTween動畫插件的安裝和使用整合(最全)

4、基于樣條曲線(Spline)的手牌管理系統

4.1 代碼實現

主要用于在游戲中實現卡牌的動態生成、排列和動畫效果。核心功能:

  • 按空格鍵抽牌:每按一次空格,生成一張新卡牌(不超過最大數量)。

  • 沿樣條曲線排列卡牌:所有卡牌會均勻分布在一條預定義的樣條曲線上。

  • 平滑動畫過渡:使用 DOTween 實現卡牌移動和旋轉的平滑動畫。

using UnityEngine;
using DG.Tweening;
using UnityEngine.Splines;
using System.Collections.Generic;public class HandManager : MonoBehaviour
{[SerializeField] private int maxHandSize; // 手牌最大數量[SerializeField] private GameObject cardPrefab; // 卡牌預制體[SerializeField] private SplineContainer splineContainer; // 樣條曲線容器,用于卡牌排列路徑[SerializeField] private Transform spawnPoint; // 卡牌生成位置private List<GameObject> handCards = new List<GameObject>();// 當前手牌列表private void Update(){// 按空格鍵抽牌if (Input.GetKeyDown(KeyCode.Space)) DrawCard();}/// <summary>/// 抽牌方法/// </summary>private void DrawCard(){// 如果手牌已滿則返回if (handCards.Count >= maxHandSize) return;// 實例化新卡牌GameObject g = Instantiate(cardPrefab, spawnPoint.position, spawnPoint.rotation);handCards.Add(g);// 更新所有卡牌位置UpdateCardPositions();}/// <summary>/// 更新所有卡牌位置和旋轉/// </summary>private void UpdateCardPositions(){// 如果沒有手牌則返回if (handCards.Count == 0) return;// 計算卡牌間距(基于最大手牌數)float cardSpacing = 1f / maxHandSize;// 計算第一張卡牌的位置(居中排列)float firstCardPosition = 0.5f - (handCards.Count - 1) * cardSpacing / 2;// 獲取樣條曲線Spline spline = splineContainer.Spline;// 遍歷所有卡牌并設置位置和旋轉for (int i = 0; i < handCards.Count; i++){// 計算當前卡牌在曲線上的參數位置float p = firstCardPosition + i * cardSpacing;// 獲取曲線上的位置、前向向量和上向量Vector3 splinePosition = spline.EvaluatePosition(p);Vector3 forward = spline.EvaluateTangent(p);Vector3 up = spline.EvaluateUpVector(p);// 計算卡牌旋轉(使卡牌朝向正確方向)// Vector3.Cross(up, forward) 計算 up 和 forward 的 叉積,得到一個垂直于二者的方向(即“右方向”)。Quaternion rotation = Quaternion.LookRotation(up, -Vector3.Cross(up, forward).normalized);// 使用DOTween動畫平滑移動和旋轉卡牌handCards[i].transform.DOMove(splinePosition, 0.25f);handCards[i].transform.DOLocalRotateQuaternion(rotation, 0.25f);}}
}

4.2 解釋:

(1)計算第一張卡牌的位置(居中排列)
float firstCardPosition = 0.5f - (handCards.Count - 1) * cardSpacing / 2;
  • 目的是讓所有卡牌以樣條曲線的中點(0.5)對稱分布。
  • 例如 3 張卡牌時,第一張卡牌位置為 0.3,后續卡牌依次為 0.5、0.7。
(1)關鍵旋轉計算:
Quaternion rotation = Quaternion.LookRotation(up, -Vector3.Cross(up, forward).normalized);

我們可以查看目前曲線上點的旋轉,因為我們只取獲取曲線上點的前向向量和上向量,所以樣條線的x旋轉不重要,y和z分別是90和270
在這里插入圖片描述
這么查看比較抽象,我們可以新建一個空物體模擬曲線點的旋轉,y和z分別設置成90和270度,看xyz軸具體對應的方向。記得切換成3D模式和局部坐標下觀察
在這里插入圖片描述
我們可以看,曲線點的x、y、z方向分別對應世界坐標的-y、-z、x軸方向。

所以我們使用LookRotation(up, -Cross(up, forward)) 可以讓卡牌的:

  • Z 軸 對齊曲線的 up 方向。這里也就是世界坐標的-z軸方向。

  • Y 軸 對齊曲線的“左方向”(通過叉積計算,這里取了負號)。這里也就是世界坐標的y軸方向。

(3)應用動畫

使用 DOTweenDOMoveDOLocalRotateQuaternion 實現平滑移動和旋轉。

4.3 配置參數

在這里插入圖片描述
這里的Card預制體制作,可以參考我之前的文章:【unity實戰】在 Unity 中實現卡牌翻轉或者翻書的效果

spawnPoint卡牌生成位置,我定義在了屏幕的左上角位置

4.4 效果

按空格抽一張牌
在這里插入圖片描述

參考

https://www.youtube.com/@thecodeotter


專欄推薦

地址
【unity游戲開發入門到精通——C#篇】
【unity游戲開發入門到精通——unity通用篇】
【unity游戲開發入門到精通——unity3D篇】
【unity游戲開發入門到精通——unity2D篇】
【unity實戰】
【制作100個Unity游戲】
【推薦100個unity插件】
【實現100個unity特效】
【unity框架/工具集開發】
【unity游戲開發——模型篇】
【unity游戲開發——InputSystem】
【unity游戲開發——Animator動畫】
【unity游戲開發——UGUI】
【unity游戲開發——聯網篇】
【unity游戲開發——優化篇】
【unity游戲開發——shader篇】
【unity游戲開發——編輯器擴展】
【unity游戲開發——熱更新】
【unity游戲開發——網絡】

完結

好了,我是向宇,博客地址:https://xiangyu.blog.csdn.net,如果學習過程中遇到任何問題,也歡迎你評論私信找我。

贈人玫瑰,手有余香!如果文章內容對你有所幫助,請不要吝嗇你的點贊評論和關注,你的每一次支持都是我不斷創作的最大動力。當然如果你發現了文章中存在錯誤或者有更好的解決方法,也歡迎評論私信告訴我哦!
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/93191.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/93191.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/93191.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flask模板注入梳理

從模板開始介紹&#xff1a;Flask中有許多不同功能的模板&#xff0c;他們之間是相互隔離的地帶&#xff0c;可供引入和使用。Flask中的模塊&#xff1a;flask 主模塊&#xff1a;包含框架的核心類和函數&#xff0c;如 Flask&#xff08;應用實例&#xff09;、request&#x…

企業級的即時通訊平臺怎么保護敏感行業通訊安全?

聊天記錄存在第三方服務器、敏感文件被誤發至外部群組、離職員工仍能查看歷史消息.對于金融、醫療、政務等對數據安全高度敏感的行業而言&#xff0c;“溝通效率與”信息安全”的矛盾&#xff0c;從未像今天這樣尖銳。企業即時通訊怎么保護敏感行業通訊安全&#xff1f;這個問題…

Java Spring框架最新版本及發展史詳解(截至2025年8月)-優雅草卓伊凡

Java Spring框架最新版本及發展史詳解&#xff08;截至2025年8月&#xff09;-優雅草卓伊凡引言今天有個新項目 客戶問我為什么不用spring 4版本&#xff0c;卓伊凡我今天剛做完項目方案&#xff0c;我被客戶這一句問了有點愣住&#xff0c;Java Spring框架最新版本及發展史詳解…

Android實現Glide/Coil樣式圖/視頻加載框架,Kotlin

Android實現Glide/Coil樣式圖/視頻加載框架&#xff0c;Kotlin <uses-permission android:name"android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permiss…

【k8s】pvc 配置的兩種方式volumeClaimTemplates 和 PersistentVolumeClaim

pvc配置實例 實例1在Deployment中配置 template:xxxxxxvolumeClaimTemplates:- metadata:name: dataspec:accessModes:- ReadWriteOnceresources:requests:storage: 1GistorageClassName: nfsdev-storageclass (創建好的storageClassName)實例2#先創建一個pvc 然后在 Deploym…

Logistic Loss Function|邏輯回歸代價函數

----------------------------------------------------------------------------------------------- 這是我在我的網站中截取的文章&#xff0c;有更多的文章歡迎來訪問我自己的博客網站rn.berlinlian.cn&#xff0c;這里還有很多有關計算機的知識&#xff0c;歡迎進行留言或…

計算機網絡技術-知識篇(Day.1)

一、網絡概述 1、網絡的概念 兩個不在同一地理位置的主機&#xff0c;通過傳輸介質和通信協議&#xff0c;實現通信和資源共享。 2、網絡發展史 第一階段&#xff08;20世紀60年代&#xff09; 標志性事件&#xff1a;ARPANET的誕生關鍵技術&#xff1a;分組交換技術 第二…

工業元宇宙:邁向星辰大海的“玄奘之路”

一、從認知革命到工業革命&#xff1a;文明躍遷的底層邏輯1.1 認知革命&#xff1a;人類協作的基石時間線&#xff1a;約7萬年前&#xff0c;智人通過語言和想象力構建共同虛擬現實&#xff0c;形成部落協作模式。核心突破&#xff1a;虛構能力&#xff1a;創造神、國家、法律等…

9. React組件生命周期

2. React組件生命周期 2.1. 認識生命周期 2.1.1. 很多事物都有從創建到銷毀的整個過程&#xff0c;這個過程稱之為生命周期&#xff1b;2.1.2. React組件也有自己的生命周期&#xff0c;了解生命周期可以讓我們在最合適的地方完成想要的功能2.1.3. 生命周期和生命周期函數的關系…

【單板硬件開發】關于復位電路的理解

閱讀紫光同創供應商提供的FPGA單板硬件開發手冊&#xff0c;發現復位電路他們家解釋的很通俗易懂&#xff0c;所以分享一下。如下圖&#xff0c;RST_N 是低有效的異步全芯片復位信號&#xff0c;一般外部連接電路有 3 種形式如圖 3–2&#xff0c;可根據實際需要選擇合適的電路…

《Unity Shader入門精要》學習筆記一

1、本書的源代碼 https://github.com/candycat1992/Unity_Shaders_Book 2、第1章 Shader是面向GPU的工作方式 3、第2章 渲染流水線 Shader&#xff1a;著色器 渲染流水線&#xff1a;目標是渲染一張二維紋理&#xff0c;輸入是一個虛擬攝像機、一些光源、一些Shader以及紋…

從零到一:TCP 回聲服務器與客戶端的完整實現與原理詳解

目錄 一、TCP 通信的核心邏輯 二、TCP 服務器編程步驟 步驟 1&#xff1a;創建監聽 Socket 步驟 2&#xff1a;綁定地址與端口&#xff08;bind&#xff09; 步驟 3&#xff1a;設置監聽狀態&#xff08;listen&#xff09; 步驟 4&#xff1a;接收客戶端連接&#xff08…

MyBatis-Plus核心內容

MyBatis-Plus MyBatis-Plus 是一個基于 MyBatis的增強工具&#xff0c;旨在簡化開發過程&#xff0c;減少重復代碼。它在MyBatis的基礎上增加了CRUD操作封裝&#xff0c;條件構造器、代碼生成器等功能。 一、核心特性與優勢 1. 核心特性 無侵入&#xff1a;只做增強不做改變&am…

計算機網絡摘星題庫800題筆記 第4章 網絡層

第4章 網絡層4.1 網絡層概述題組闖關1.在 Windows 的網絡配置中&#xff0c;“默認網關” 一般被設置為 ( ) 的地址。 A. DNS 服務器 B. Web 服務器 C. 路由器 D. 交換機1.【參考答案】C 【解析】只有在計算機上正確安裝網卡驅動程序和網絡協議&#xff0c;并正確設置 IP 地址信…

非root用戶在linux中配置zsh(已解決ncurses-devel報錯)

Zsh&#xff08;Z Shell&#xff09;是一款功能強大的交互式 Unix shell&#xff0c;以其高度可定制性和豐富的功能著稱&#xff0c;被視為 Bash 的增強替代品。它支持智能補全、主題美化、插件擴展&#xff08;如 Oh My Zsh 框架&#xff09;、自動糾錯、全局別名等特性&#…

《Foundations and Recent Trends in Multimodal Mobile Agents: A Survey》論文精讀筆記

論文鏈接&#xff1a;https://arxiv.org/pdf/2411.02006 摘要 文章首先介紹了核心組件&#xff0c;并探討了移動基準和交互環境中的關鍵代表性作品&#xff0c;旨在全面理解研究重點及其局限性。 接著&#xff0c;將這些進展分為兩種主要方法&#xff1a; 基于提示的方法&a…

npm安裝時一直卡住的解決方法

npm install 卡住通常是由于網絡問題或緩存問題導致的。以下是幾種解決方法&#xff1a; 方法1&#xff1a;清理npm緩存 npm cache clean --force npm install方法2&#xff1a;刪除node_modules和package-lock.json重新安裝 rm -rf node_modules package-lock.json npm instal…

[密碼學實戰]使用Java生成國密SM2加密證書等(四十三)

[密碼學實戰]使用Java生成國密SM2加密證書等(四十三) 本文將詳細介紹如何通過Java代碼生成符合國密標準的SM2加密證書,包括密鑰對生成、證書擴展屬性配置、PEM格式保存等關鍵步驟。 一. 運行結果示例 二. 國密算法與加密證書 國密算法(SM系列)是中國自主研發的密碼算法體…

從零開始之stm32之CAN通信

從小白的視角了解并實現簡單的STM32F103的CAN通信&#xff0c;直接上手。一、CAN協議簡介CAN總線上傳輸的信息稱為報文&#xff0c;當總線空閑時任何連接的單元都可以開始發送新的報文&#xff0c;有5種類型的幀&#xff1a;數據幀、遙控幀、錯誤幀、過載幀、幀間隔。數據幀有兩…

Java 課程,每天解讀一個簡單Java之利用條件運算符的嵌套來完成此題:學習成績>=90分的同學用A表示,60-89分之間的用B表示, * 60分以下

package ytr250812;/*題目&#xff1a;利用條件運算符的嵌套來完成此題&#xff1a;學習成績>90分的同學用A表示&#xff0c;60-89分之間的用B表示&#xff0c;* 60分以下*/import java.util.Scanner;public class GradeEvaluator {public static void main(String[] args) …