ios 3D引擎 SceneKit 开发(6) --SCNAction

前面关于旋转的两篇我们利用CABasicAnimation来实现旋转动画,其实在SceneKit中,有一种更为简单的方法去实现一些基础动画,那就是SCNAction,它的执行对象是SCNNode。

一个简单的例子:

SCNAction *shipMoveAction = [SCNAction moveTo:SCNVector3Make(10,10,5) duration:4];

[shipRotationNode runAction:shipMoveAction];

上面代码很容易理解shipRotationNode 动画移动到(10,10,5)这个位置,时间间隔为4s。

我们下面简单介绍一下 SCNAction 主要的API:

+ (SCNAction *)moveByX:(CGFloat)deltaX

                                         y:(CGFloat)deltaY 

                                         z:(CGFloat)deltaZ 

                             duration:(NSTimeInterval)duration 

 //将node从x,y,z上各移动多少距离

+ (SCNAction *)moveBy:(SCNVector3)delta 

                           duration:(NSTimeInterval)duration 

 //同上,只不过传入参数为SCNVector3

+ (SCNAction *)moveTo:(SCNVector3)location 

                          duration:(NSTimeInterval)duration

//将node移动到location这个位置

+ (SCNAction *)rotateByX:(CGFloat)xAngle 

                                         y:(CGFloat)yAngle 

                                         z:(CGFloat)zAngle 

                             duration:(NSTimeInterval)duration

//将node从x,y,z上各旋转多少度

+ (SCNAction *)rotateToX:(CGFloat)xAngle 

                                         y:(CGFloat)yAngle 

                                         z:(CGFloat)zAngle 

                             duration:(NSTimeInterval)duration

/将node从x,y,z上旋转到指定角度

+ (SCNAction *)rotateToX:(CGFloat)xAngle 

                                         y:(CGFloat)yAngle 

                                         z:(CGFloat)zAngle 

                             duration:(NSTimeInterval)duration 

                 shortestUnitArc:(BOOL)shortestUnitArc

// 同上,与上面的方法区别在于多了shortestUnitArc 这个参数,BOOL值。

//举个例子:我们需要将一个node从 0度旋转到270度,

//如果将shortestUnitArc设置为NO,node会顺时针旋转到270度;

//如果将shortestUnitArc设置为YES,node会逆时针旋转90度到270度,

//即选择最小的旋转角度旋转到特定的度数。默认为NO。

+ (SCNAction *)rotateByAngle:(CGFloat)angle 

                                 aroundAxis:(SCNVector3)axis 

                                      duration:(NSTimeInterval)duration

// 沿着特定的轴旋转angle度。前面旋转都是沿x,y,z轴旋转,都是互相垂直的,

//大家有没有想过如何沿着与x轴成45度夹角的方向旋转node? 

//这个API大家这里留意一下,

//上篇提到的不在X-Z 这个平面旋转,会用这个方法在后面的demo中解决。

+ (SCNAction *)rotateToAxisAngle:(SCNVector4)axisAngle 

                                             duration:(NSTimeInterval)duration

// SCNVector4(x,y,z,angle) 沿着特定的轴旋转到angle度。

//这里解释一下angle 类似π,如果angle=2,

//我们可不能理解为旋转到2度,而是旋转到2/π*180 度。

+ (SCNAction *)scaleBy:(CGFloat)scale 

                         duration:(NSTimeInterval)sec

//缩小(放大)多少

+ (SCNAction *)scaleTo:(CGFloat)scale 

                         duration:(NSTimeInterval)sec

//缩小(放大)到多少

+ (SCNAction *)fadeInWithDuration:(NSTimeInterval)sec

//字面意思可以理解,淡入。将node 的opacity 渐渐变成1

+ (SCNAction *)fadeOutWithDuration:(NSTimeInterval)sec

// 淡出

+ (SCNAction *)fadeOpacityBy:(CGFloat)factor 

                                      duration:(NSTimeInterval)sec

//将node 的opacity 渐渐变化特定的数值

+ (SCNAction *)fadeOpacityTo:(CGFloat)opacity 

                                     duration:(NSTimeInterval)sec

//将node 的opacity 渐渐变化到特定的数值

+ (SCNAction *)hide

// 隐藏node

+ (SCNAction *)unhide

//显示node

+ (SCNAction *)removeFromParentNode

//移除node

+ (SCNAction *)playAudioSource:(SCNAudioSource *)source 

                         waitForCompletion:(BOOL)wait

//播放音频。 waitForCompletion,BOOL值,

//如果为YES Action的duration就是音频的时长;

//如果为NO,可以认为duration 为0。 

//可以去看SCNAudioPlayer 的API.

+ (SCNAction *)group:(NSArray*)actions

//group 被用来并发执行多个SCNAction

+ (SCNAction *)sequence:(NSArray*)actions

//顺序执行多个SCNAction,上个SCNAction执行结束后,才执行下个SCNAction

+ (SCNAction *)repeatAction:(SCNAction *)action

                                        count:(NSUInteger)count

//将一个SCNAction执行count 次

+ (SCNAction *)repeatActionForever:(SCNAction *)action

// 一直执行某个SCNAction

+ (SCNAction *)waitForDuration:(NSTimeInterval)sec

//延迟SCNAction,比如用sequence 顺序执行多个SCNAction时,

//可以给SCNAction a,c  中间添加一个SCNAction b,

//等a执行结束后,延迟一会,再去执行c

+ (SCNAction *)runBlock:(void (^)(SCNNode *node))block

//自定义SCNAction ,你可以在block 做一些操作

+ (SCNAction *)runBlock:(void (^)(SCNNode *node))block

                                queue:(dispatch_queue_t)queue

//在一个特定的队列中,执行block

+ (SCNAction *)customActionWithDuration:(NSTimeInterval)seconds

                                actionBlock:(void (^)(SCNNode *node, CGFloat elapsedTime))block

//上篇数学旋转用到的方法,当这个SCNAction执行时,

//SceneKit 在这个时间间隔内会重复调用actionBlock,

//并将已逝去的时间传给actionBlock

+ (SCNAction *)javaScriptActionWithScript:(NSString *)script

                                                            duration:(NSTimeInterval)seconds

//在时间间隔内,执行一段JavaScript代码

- (SCNAction *)reversedAction

//逆转一个已经创建的SCNAction,很好理解,

//相当于CABasicAnimation的autoreverses属性。哪里来的,回哪里去。

@property(nonatomic) NSTimeInterval duration

//SCNAction 的属性,时间间隔,真实时间间隔受speed影响

@property(nonatomic) CGFloat speed

//SCNAction 的属性,速度系数。假设duration 为10,但speed 为2的话,

//就是速度是以前的2倍,实际duration 就为5

@property(nonatomic) SCNActionTimingMode timingMode

//SCNAction 的属性,定时模式,有四个常量值:

Constants

SCNActionTimingModeLinear

//匀速

SCNActionTimingModeEaseIn

//一开始慢,慢慢加快

SCNActionTimingModeEaseOut

//一开始快,逐渐变慢

SCNActionTimingModeEaseInEaseOut

//开始慢慢地,通过中间的时候加速,然后再次放缓

OK,了解过SCNAction的API后,我们就可以解决上一篇的问题了:添加一艘飞船,让它绕着与x轴成45度的方向做圆周运动。

用到的API :

+ (SCNAction *)rotateByAngle:(CGFloat)angle

                                aroundAxis:(SCNVector3)axis

                                    duration:(NSTimeInterval)duration


最终实现效果:

代码全在demo里面,感兴趣的同学可以下载

https://github.com/pzhtpf/SceneKitRoationDemo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,390评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,821评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,632评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,170评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,033评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,098评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,511评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,204评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,479评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,572评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,341评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,893评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,171评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,486评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,676评论 2 335