SceneKit_入門13_骨骼動畫

SceneKit_入門01_旋轉(zhuǎn)人物
SceneKit_入門02_如何創(chuàng)建工程
SceneKit_入門03_節(jié)點
SceneKit_入門04_燈光
SceneKit_入門05_照相機
SceneKit_入門06_行為動畫
SceneKit_入門07_幾何體
SceneKit_入門08_材質(zhì)
SceneKit_入門09_物理身體
SceneKit_入門10_物理世界
SceneKit_入門11_粒子系統(tǒng)
SceneKit_入門12_物理行為
SceneKit_入門13_骨骼動畫
SceneKit_中級01_模型之間的過渡動畫
SceneKit_中級02_SCNView 詳細講解
SceneKit_中級03_切換照相機視角
SceneKit_中級04_約束的使用
SceneKit_中級05_力的使用
SceneKit_中級06_場景的切換
SceneKit_中級07_動態(tài)修改屬性
SceneKit_中級08_陰影詳解
SceneKit_中級09_碰撞檢測
SceneKit_中級10_濾鏡效果制作
SceneKit_中級11_動畫事件
SceneKit_高級01_GLSL
SceneKit_高級02_粒子系統(tǒng)深入研究
SceneKit_高級03_自定義力
SceneKit_高級04_自定義場景過渡效果
SceneKit_高級05 檢測手勢點擊到節(jié)點
SceneKit_高級06_加載頂點狡赐、紋理、法線坐標
SceneKit_高級07_SCNProgram用法探究
SceneKit_高級08_天空盒子制作
SceneKit_高級09_霧效果
SceneKit_大神01_掉落的文字
SceneKit_大神02_彈幕來襲
SceneKit_大神03_navigationbar上的3D文字

讓學習成為一種習慣

學習目標

1.理解骨骼動畫的含義
2.學習骨骼動畫相關的類(SCNKinner)

開始吧

百度百科

當前有兩種模型動畫的方式:頂點動畫和骨骼動畫筐高。頂點動畫中换薄,每幀動畫其實就是模型特定姿態(tài)的一個“快照”苛白。通過在幀之間插值的方法,引擎可以得到平滑的動畫效果,在骨骼動畫中,模型具有互相連接的“骨骼”組成的骨架結(jié)構(gòu)论衍,通過改變骨骼的朝向和位置來為模型生成動畫。
骨骼動畫比頂點動畫要求更高的處理器性能聚磺,但同時它也具有更多的優(yōu)點坯台,骨骼動畫可以更容易、更快捷地創(chuàng)建瘫寝。不同的骨骼動畫可以被結(jié)合到一起——比如蜒蕾,模型可以轉(zhuǎn)動頭部稠炬、射擊并且同時也在走路。一些引擎可以實時操縱單個骨骼咪啡,這樣就可以和環(huán)境更加準確地進行交互——模型可以俯身并向某個方向觀察或射擊首启,或者從地上的某個地方撿起一個東西。多數(shù)引擎支持頂點動畫撤摸,但不是所有的引擎都支持骨骼動畫毅桃。

蘋果官方

骨骼動畫是一種簡化復雜幾何形狀的動畫的技術,比如游戲中人的特征,動畫骨架是一個簡單的控制節(jié)點的層次結(jié)構(gòu),本身沒有可見的幾何對象,將骨頭和幾何對象進行結(jié)合,當你移動這個骨頭控制的節(jié)點時允許SceneKit 去自動使幾何對象變形。

給張圖理解一下

讓學習成為一種習慣

相信你已經(jīng)基本了解骨骼動畫的含義了准夷。

接下來學習一個類的使用

  • SCNKinner 能干什么?

提供一些方法可以將節(jié)點的骨骼動畫進行分離,你可以使用這個對象管理從Scene文件導入的骨骼動畫與節(jié)點和幾何對象之間動態(tài)關系钥飞。

  • 怎么使用骨骼動畫?

1.一般情況下,游戲設計師使用3D 工具創(chuàng)建一個皮膚模型,包含了骨骼的動畫,保存在一個場景文件中,你從場景文件中導入這個骨骼模型,然后讓他們運動起來,
2.另外你也可以直接從場景文件中導入動畫對象直接操作骨頭節(jié)點
3.您還可以單獨創(chuàng)建一個自定義的幾何和骨架數(shù)據(jù)的皮膚模型

  • 我們先找一個帶骨骼的模型文件,分析一下它的結(jié)構(gòu)
讓學習成為一種習慣
讓學習成為一種習慣
讓學習成為一種習慣

我們先看一下完整的動畫效果

讓學習成為一種習慣

接下來我們做一個練習

如何將一段完整的動畫衫嵌,分階段執(zhí)行,我們剛才看見了這段動畫的時間為0~24秒左右读宙。

首先先介紹一個類(SCNSceneSource)

主要用于管理場景文件的讀取任務,也可以讀取NSData對象哦!你懂了吧,如果這個模型,我們從網(wǎng)絡傳輸?shù)脑?可能就需要使用這個類了。

這個類不詳細講解,今天主要用到它的兩個方法
N0.1

- (NSArray<NSString *> *)identifiersOfEntriesWithClass:(Class)entryClass;

作用:

獲取場景中包含的某一類對象的標識(數(shù)組),可以獲取的類型有 SCNMaterial, SCNScene, SCNGeometry, SCNNode, CAAnimation, SCNLight, SCNCamera, SCNSkinner, SCNMorpher, NSImage

NO.2

- (nullable id)entryWithIdentifier:(NSString *)uid withClass:(Class)entryClass;

作用:

根據(jù)對象的ID 和對象的類型楔绞,獲取對象本身

NO.3

+ (nullable instancetype)sceneSourceWithURL:(NSURL *)url options:(nullable NSDictionary<NSString *, id> *)options;

作用:

初始化方法

NO.4

- (nullable SCNScene *)sceneWithOptions:(nullable NSDictionary<NSString *, id> *)options error:(NSError **)error;

作用:

創(chuàng)建場景

走進代碼的世界

1.創(chuàng)建工程(略)
2.加載場景文件(略)
3.添加框架SceneKit/Scenekit.h
4.創(chuàng)建場景資源對象

 SCNSceneSource *sceneSource = [SCNSceneSource sceneSourceWithURL:[[NSBundle mainBundle] URLForResource:@"skinning" withExtension:@"dae"] options:nil];

5.創(chuàng)建場景

scnView.scene  = [sceneSource sceneWithOptions:nil error:nil];

6.獲取場景中的某種對象的標識數(shù)組

// 我們獲取動畫類的數(shù)組
NSArray *animationIDs =  [sceneSource identifiersOfEntriesWithClass:[CAAnimation class]];

7.把每個動畫幀放到一個大數(shù)組中

NSUInteger animationCount = [animationIDs count];
NSMutableArray *longAnimations = [[NSMutableArray alloc] initWithCapacity:animationCount];
CFTimeInterval maxDuration = 0;
for (NSInteger index = 0; index < animationCount; index++) {
    CAAnimation *animation = [sceneSource entryWithIdentifier:animationIDs[index] withClass:[CAAnimation class]];
    if (animation) {
        maxDuration = MAX(maxDuration, animation.duration);
        [longAnimations addObject:animation];
    }
}

8.創(chuàng)建一個動畫組

 CAAnimationGroup *longAnimationsGroup = [[CAAnimationGroup alloc] init];
 longAnimationsGroup.animations = longAnimations;
 longAnimationsGroup.duration = maxDuration;

9.截取我們要的動畫階段比如(20~24秒)

// 截取20秒之后的動畫組
CAAnimationGroup *idleAnimationGroup = [longAnimationsGroup copy];
idleAnimationGroup.timeOffset = 20 ;
// 創(chuàng)建一個重復執(zhí)行這個動畫的動畫組
CAAnimationGroup *lastAnimationGroup;
lastAnimationGroup = [CAAnimationGroup animation];
lastAnimationGroup.animations = @[idleAnimationGroup];
lastAnimationGroup.duration = 24.71 -20;
lastAnimationGroup.repeatCount = 10000;
lastAnimationGroup.autoreverses = YES;

10.然后將這個動畫組添加到模型節(jié)點去就可以了

SCNNode *cNode = [scnView.scene.rootNode childNodeWithName:@"avatar_attach" recursively:YES];
[cNode addAnimation:lastAnimationGroup forKey:@"animation"];

運行一下:

帥爆了,有沒有

提示:

模型中的骨頭只是一個位置,沒有大小和形狀的,如果你想要查看骨頭在什么位置怎么辦呢?

  // 查找骨頭節(jié)點
    _skeletonNode = [_characterNode childNodeWithName:@"skeleton" recursively:YES];
//  調(diào)用下面的方法給骨頭添加一個小四方塊
 - (void)visualizeBones:(BOOL)show ofNode:(SCNNode *)node inheritedScale:(CGFloat)scale
{
 scale *= node.scale.x;
if (show) {
    if (node.geometry == nil)
        node.geometry = [SCNBox boxWithWidth:6.0 / scale height:6.0 / scale length:6.0 / scale chamferRadius:0.5];
}
else {
    if ([node.geometry isKindOfClass:[SCNBox class]])
        node.geometry = nil;
}

for (SCNNode *child in node.childNodes)
    [self visualizeBones:show ofNode:child inheritedScale:scale];
}

效果如下:

讓學習成為一種習慣

SWIFT 版本

  • 第一步 獲取資源
 let source = SCNSceneSource(url: file!, options: nil)
  • 第二步 獲取動畫標志數(shù)組
  let animationIDs = source?.identifiersOfEntries(withClass: CAAnimation.self)
    var animationArray:[CAAnimation] = []
    for id in animationIDs!{
        let animation = source?.entryWithIdentifier(id, withClass: CAAnimation.self)
        animationArray.append(animation!)
    }
  • 第三步 創(chuàng)建動畫數(shù)組
let animationGroup = CAAnimationGroup()
animationGroup.animations = animationArray
 animationGroup.duration = 21.33
 animationGroup.repeatCount = 1000
 animationGroup.beginTime = 0
  • 第四步 添加
   rightHetun.addAnimation(animationGroup, forKey: "an")
  • 什么玩意,難道我們做個游戲结闸,光添加動畫就這么復雜?

其實不是的,實際開發(fā)過程中,我們不需要這么做的墓律,處分你要對文件中的骨骼動畫,進行時間上的調(diào)整膀估,我們才會使用這種方法

下面叫大家一種更為簡單的方式,添加骨骼動畫耻讽,找一個帶骨骼動畫的文件

    let file = Bundle.main.url(forResource: "hetun", withExtension: "dae")
    let source = SCNSceneSource(url: file!, options: nil)
    let  hetun = try! source?.scene(options: nil).rootNode
    // 調(diào)整位置
    hetun?.scale = SCNVector3Make(0.01, 0.01, 0.01)
    hetun?.rotation = SCNVector4Make(0, 1, 0, -Float.pi/2)
    hetun?.position = SCNVector3Make(0, 0, 0)

解釋一下

我們只要獲取到文件的根節(jié)點,根節(jié)點中包含文件所有的元素,然后將rootnode添加到指定的位置即可,這樣我們就完成了,是不是很簡單呢察纯?

總結(jié)

本節(jié)內(nèi)容簡單的介紹了骨骼動畫的概念,骨骼動畫更高級的用法,我們后面再繼續(xù)講解。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末针肥,一起剝皮案震驚了整個濱河市饼记,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌慰枕,老刑警劉巖具则,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異具帮,居然都是意外死亡博肋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門蜂厅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來匪凡,“玉大人,你說我怎么就攤上這事掘猿〔∮危” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵稠通,是天一觀的道長衬衬。 經(jīng)常有香客問我买猖,道長,這世上最難降的妖魔是什么滋尉? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任玉控,我火速辦了婚禮,結(jié)果婚禮上兼砖,老公的妹妹穿的比我還像新娘奸远。我一直安慰自己,他們只是感情好讽挟,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著丸冕,像睡著了一般耽梅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上胖烛,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天眼姐,我揣著相機與錄音,去河邊找鬼佩番。 笑死众旗,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的趟畏。 我是一名探鬼主播贡歧,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼赋秀!你這毒婦竟也來了利朵?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤猎莲,失蹤者是張志新(化名)和其女友劉穎绍弟,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體著洼,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡樟遣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了身笤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片豹悬。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖展鸡,靈堂內(nèi)的尸體忽然破棺而出屿衅,到底是詐尸還是另有隱情,我是刑警寧澤莹弊,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布涤久,位于F島的核電站涡尘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏响迂。R本人自食惡果不足惜考抄,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蔗彤。 院中可真熱鬧川梅,春花似錦、人聲如沸然遏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽待侵。三九已至丢早,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間秧倾,已是汗流浹背怨酝。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留那先,地道東北人农猬。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像售淡,于是被迫代替她去往敵國和親斤葱。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容