SceneKit_中級(jí)04_約束的使用

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

讓學(xué)習(xí)成為一種習(xí)慣

先告訴你

我們?cè)谧鰬?yīng)用開發(fā)的時(shí)候,也會(huì)用到約束,應(yīng)用中的約束,就是當(dāng)一個(gè)視圖變化的時(shí)候倔矾,讓和他之間有約束關(guān)系的其他視圖,按照一定的約束規(guī)則變化,那在游戲中,我們的約束是用來干什么的?
官方的解釋:

約束能夠根據(jù)你定義的規(guī)則,自動(dòng)調(diào)整這些變化(位置 旋轉(zhuǎn) 和 比例)

認(rèn)識(shí)新朋友

  • SCNConstraint

這個(gè)是游戲中的約束類,是一個(gè)抽象的類,我們不能直接使用,但是它有3個(gè)子類可以供我們使用。

我們看這個(gè)類有哪些屬性

 /* 
  * 作用: 影響因子,決定約束的強(qiáng)度
  * 工作原理: 如果設(shè)置為1 那么在游戲每一幀渲染的時(shí)候,系統(tǒng)都會(huì)調(diào)整這個(gè)約束,如果你設(shè)置為0.5 在游戲的某些幀,系統(tǒng)不會(huì)進(jìn)行約束調(diào)整 0 完全忽略約束
  * 注意 SCNTransformConstraint  對(duì)這類約束不起作用
  */
 var influenceFactor: CGFloat,默認(rèn)值為 1,這是為0 時(shí),則

接下來我們分析三個(gè)子類

  • SCNLookAtConstraint

1.作用:

讓一個(gè)節(jié)點(diǎn)的方向,總是指向另外一個(gè)一個(gè)節(jié)點(diǎn)

2.怎么用? 我舉個(gè)簡(jiǎn)單的例子谅海,幫助大家理解它的用法

如果你想要玩第一視角的游戲,這是我們需要讓攝像機(jī)捕捉到人物移動(dòng)時(shí)的位置,這是需要給照相機(jī)節(jié)點(diǎn)添加一個(gè)SCNLookAtConstraint 類型的約束,就能實(shí)現(xiàn)這個(gè)效果。

3.原理:

其實(shí)這個(gè)約束的原理是更改節(jié)點(diǎn)的transform的屬性

4.怎么創(chuàng)建

 // target 就是指向的那個(gè)目標(biāo)節(jié)點(diǎn) 
+ (instancetype)lookAtConstraintWithTarget:(SCNNode *)target;

5.我們?nèi)绻胍障鄼C(jī)的視野保持在水平面上,也就是說只沿在Y軸轉(zhuǎn)動(dòng)跟隨目標(biāo)節(jié)點(diǎn),我們應(yīng)該怎么做呢?

// 設(shè)置下面的屬性為YES蹦浦,就能實(shí)現(xiàn)上面的效果扭吁,默認(rèn)為NO
var gimbalLockEnabled: Bool
  • SCNTransformConstraint

1.作用:

創(chuàng)建一個(gè)轉(zhuǎn)換約束(提供給節(jié)點(diǎn)一個(gè)新的轉(zhuǎn)換的計(jì)算),當(dāng)系統(tǒng)進(jìn)行下一次渲染的時(shí)候,會(huì)重新計(jì)算這個(gè)塊中的約束,然后調(diào)整節(jié)點(diǎn)的狀態(tài)

2.創(chuàng)建方法

 /*
  * world 設(shè)置為YES 使用世界坐標(biāo)系盲镶,設(shè)置為NO 使用自身坐標(biāo)系 
+ (instancetype)transformConstraintInWorldSpace:(BOOL)world  withBlock:(SCNMatrix4 (^)(SCNNode *node,  SCNMatrix4 transform))block
  • SCNIKConstraint(反向運(yùn)動(dòng)約束)

1.作用:

將一個(gè)節(jié)點(diǎn)鏈移動(dòng)到一個(gè)目標(biāo)位置

給張圖理解一下:

讓學(xué)習(xí)成為一種習(xí)慣

2.使用步驟:

1.創(chuàng)建一個(gè)節(jié)點(diǎn)鏈
2.給根節(jié)點(diǎn)添加 SCNIKConstraint 約束對(duì)象(胳膊)
3.添加約束給執(zhí)行器(手)
3.限定鏈?zhǔn)焦?jié)點(diǎn)移動(dòng)的范圍
4.設(shè)置目標(biāo)位置,這個(gè)值可以動(dòng)態(tài)的改變

3.舉個(gè)例子理解一下

比如機(jī)器人的組成身體 上臂 胳膊 和 手,身體是上臂的根節(jié)點(diǎn),上臂是胳膊的根節(jié)點(diǎn),胳膊是手的根節(jié)點(diǎn)侥袜,手是身體的根節(jié)點(diǎn),如果我們要實(shí)現(xiàn)上面的約束的話,需要將約束的根節(jié)點(diǎn)設(shè)置為上臂,那我們把這個(gè)約束應(yīng)該添加到手(執(zhí)行)這個(gè)節(jié)點(diǎn)上去

4.創(chuàng)建反向運(yùn)動(dòng)約束

- (instancetype)initWithChainRootNode:(SCNNode *)chainRoot  
+ inverseKinematicsConstraintWithChainRootNode:

5.設(shè)置約束的最大旋轉(zhuǎn)角度

- (void)setMaxAllowedRotationAngle:(CGFloat)angle
                      forJoint:(SCNNode *)node

6.設(shè)置目標(biāo)位置

var targetPosition: SCNVector3

走進(jìn)代碼的世界

友情提示:

第一種約束和第二種約束都很簡(jiǎn)單,在這里就不寫代碼了,我們重點(diǎn)研究一下,第三種約束的實(shí)現(xiàn)溉贿。

制作一個(gè)機(jī)器手模型

1.創(chuàng)建工程(略)
2.添加模型文件(略)
3.添加框架<SceneKit/SceneKit.h>
4.創(chuàng)建游戲場(chǎng)景

scnView = [[SCNView alloc]initWithFrame:self.view.bounds];
scnView.backgroundColor = [UIColor blackColor];
scnView.allowsCameraControl = true;
scnView.scene = [SCNScene scene];
scnView.scene.physicsWorld.gravity = SCNVector3Make(0, 90, 0);// 添加一個(gè)重力枫吧,我們讓其方向朝上
[self.view addSubview:scnView];

5.添加照相機(jī)

 SCNNode *cameraNode = [SCNNode node];
cameraNode.camera = [SCNCamera camera];
cameraNode.camera.automaticallyAdjustsZRange = true;
cameraNode.position = SCNVector3Make(0, 0,1000);
[scnView.scene.rootNode addChildNode:cameraNode];

6.添加機(jī)器手臂并設(shè)置約束

-(void)addArmToScene{

// 創(chuàng)建手掌
SCNNode *handNode = [SCNNode node];
handNode.geometry = [SCNBox boxWithWidth:20 height:20 length:20 chamferRadius:0];
handNode.geometry.firstMaterial.diffuse.contents = [UIColor purpleColor];
handNode.position = SCNVector3Make(0, -50, 0);

// 創(chuàng)建小手臂
SCNNode *lowerArm = [SCNNode node];
lowerArm.geometry = [SCNCylinder cylinderWithRadius:1 height:100];
lowerArm.geometry.firstMaterial.diffuse.contents = [UIColor redColor];
lowerArm.position = SCNVector3Make(0, -50, 0);
lowerArm.pivot = SCNMatrix4MakeTranslation(0, 50, 0); // 連接點(diǎn)
[lowerArm addChildNode:handNode];

// 創(chuàng)建上臂
SCNNode *upperArm = [SCNNode node];
upperArm.geometry = [SCNCylinder cylinderWithRadius:1 height:100];
upperArm.geometry.firstMaterial.diffuse.contents = [UIColor greenColor];
upperArm.pivot = SCNMatrix4MakeTranslation(0, 50, 0);
[upperArm addChildNode:lowerArm];

// 創(chuàng)建控制點(diǎn)
SCNNode *controlNode = [SCNNode node];
controlNode.geometry = [SCNSphere sphereWithRadius:10];
controlNode.geometry.firstMaterial.diffuse.contents = [UIColor blueColor];
[controlNode addChildNode:upperArm];
controlNode.position= SCNVector3Make(0, 100, 0);

// 添加到場(chǎng)景中去
[scnView.scene.rootNode addChildNode:controlNode];
scnView.delegate = self;

// 創(chuàng)建約束
 ikContrait =[SCNIKConstraint inverseKinematicsConstraintWithChainRootNode:controlNode];

// 給執(zhí)行器添加約束
handNode.constraints = @[ikContrait];
}

7.添加一個(gè)手,每次點(diǎn)擊屏幕宇色,隨機(jī)增加一個(gè)球

// 添加手勢(shì)
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapHandle)];
[scnView addGestureRecognizer:tap];
-(void)tapHandle{
[self createNodeToScene:scnView.scene andConstraint:ikContrait];
}

-(void)createNodeToScene:(SCNScene*)scene andConstraint:(SCNIKConstraint*)ikConstrait{
SCNNode *node = [SCNNode node];
node.position = SCNVector3Make(arc4random_uniform(100), arc4random_uniform(100), arc4random_uniform(100));
[scene.rootNode addChildNode:node];
node.geometry = [SCNSphere sphereWithRadius:10];
node.geometry.firstMaterial.diffuse.contents = [UIColor colorWithRed:arc4random_uniform(255.0)/255.0 green:arc4random_uniform(255.0)/255.0 blue:arc4random_uniform(255.0)/255.0 alpha:1];
// 創(chuàng)建動(dòng)畫九杂,當(dāng)手掌接觸到小球時(shí),給小球添加一個(gè)動(dòng)態(tài)身體
[SCNTransaction begin];
[SCNTransaction setAnimationDuration:0.5];
ikConstrait.targetPosition = node.position;
[SCNTransaction commit];
node.physicsBody = [SCNPhysicsBody dynamicBody];  
}

運(yùn)行一下試試看:

讓學(xué)習(xí)成為一種習(xí)慣

總結(jié)

今天我們使用了反向運(yùn)動(dòng)約束,不知道你學(xué)會(huì)了沒有,其他兩種約束都比較簡(jiǎn)單宣蠕,請(qǐng)自行進(jìn)行學(xué)習(xí)例隆,如有疑問,請(qǐng)聯(lián)系我!


代碼庫,聽說經(jīng)常給人點(diǎn)贊都當(dāng)老板了!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市抢蚀,隨后出現(xiàn)的幾起案子镀层,更是在濱河造成了極大的恐慌,老刑警劉巖皿曲,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件唱逢,死亡現(xiàn)場(chǎng)離奇詭異吴侦,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)坞古,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門备韧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人绸贡,你說我怎么就攤上這事盯蝴∫慊” “怎么了听怕?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)虑绵。 經(jīng)常有香客問我尿瞭,道長(zhǎng),這世上最難降的妖魔是什么翅睛? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任声搁,我火速辦了婚禮,結(jié)果婚禮上捕发,老公的妹妹穿的比我還像新娘疏旨。我一直安慰自己,他們只是感情好扎酷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布檐涝。 她就那樣靜靜地躺著,像睡著了一般法挨。 火紅的嫁衣襯著肌膚如雪谁榜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天凡纳,我揣著相機(jī)與錄音窃植,去河邊找鬼。 笑死荐糜,一個(gè)胖子當(dāng)著我的面吹牛巷怜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播暴氏,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丛版,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了偏序?” 一聲冷哼從身側(cè)響起页畦,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎研儒,沒想到半個(gè)月后豫缨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體独令,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年好芭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了燃箭。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡舍败,死狀恐怖招狸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情邻薯,我是刑警寧澤裙戏,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站厕诡,受9級(jí)特大地震影響累榜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜灵嫌,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一壹罚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧寿羞,春花似錦猖凛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至霞幅,卻和暖如春漠吻,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背司恳。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工途乃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扔傅。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓耍共,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親猎塞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子试读,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

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