tag:blogger.com,1999:blog-62239767441108563842024-03-19T04:13:07.780-07:00Qt ,Maemo and some other stuffSharing information related to Qt, Maemo development and some other informationAnonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.comBlogger217125tag:blogger.com,1999:blog-6223976744110856384.post-35131382157013238822015-10-10T22:25:00.001-07:002015-10-10T22:25:46.540-07:00Custom UISwitch in iOS<div dir="ltr" style="text-align: left;" trbidi="on">
I wanted to create Custom UISwitch in my iOS game. Initially I just waned to change size, font and color and for that I used UICustomSwitch from Hardy Macia found at <a href="https://github.com/suoinguon/taogiaothong-ios/blob/master/TaoGiaoThong/UICustom/UICustomSwitch.m">here</a>. It's quite easy to use and customisable, but then I wanted to switch to use custom image instead of standard one. For that I need to modify code a bit, below is the code which use custom image to create UISwitch. BTW this is how it looks<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4xLQOhYqtHkzSJpCjUXWi1wKZe_EDwPS-_LlRVoAknDHpcBqOXA4MljQlsjd-3JgYp0X8OhRDOla7hC8uY5rvEOmjH30XbCmMiTWq_AS5qCE3qew4PXFw3apMuWViS-27lS6kGIahv84k/s1600/iOS_Custom_Switch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="312" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4xLQOhYqtHkzSJpCjUXWi1wKZe_EDwPS-_LlRVoAknDHpcBqOXA4MljQlsjd-3JgYp0X8OhRDOla7hC8uY5rvEOmjH30XbCmMiTWq_AS5qCE3qew4PXFw3apMuWViS-27lS6kGIahv84k/s320/iOS_Custom_Switch.png" width="320" /></a></div>
<br />
<br />
Header is same as original implementation, but I removed unnecessary properties and added left and right images required to display on and off images for switch.
<br />
<pre class="prettyprint">@interface UICustomSwitch : UISlider {
BOOL on;
UIImageView* leftImage;
UIImageView* rightImage;
BOOL touchedSelf;
}
@property(nonatomic,getter=isOn) BOOL on;
@property (nonatomic, retain) UIImageView* leftImage;
@property (nonatomic, retain) UIImageView* rightImage;
- (void)setOn:(BOOL)on animated:(BOOL)animated;
@end
</pre>
Now lets see implementation. Below is code for initialising the UISwitch with custom rect. You can also see we are adding On and Off image as left and right subview to switch.
<br />
<pre class="prettyprint">-(id)initWithFrame:(CGRect)rect
{
if ((self=[super initWithFrame:rect])) {
[self awakeFromNib];
}
return self;
}
-(void)awakeFromNib
{
[super awakeFromNib];
self.backgroundColor = [UIColor clearColor];
[self setThumbImage:[Util imageNamed:@"switch"]
forState:UIControlStateNormal];
[self setMinimumTrackTintColor:[UIColor clearColor]];
[self setMaximumTrackTintColor:[UIColor clearColor]];
self.minimumValue = 0;
self.maximumValue = 1;
self.continuous = NO;
self.on = NO;
self.value = 0.0;
self.leftImage = [[UIImageView alloc] initWithFrame:self.frame];
self.leftImage.image = [Util imageNamed:@"on"];
[self addSubview: self.leftImage];
[self.leftImage release];
self.rightImage = [[UIImageView alloc] initWithFrame:self.frame];
self.rightImage.image = [Util imageNamed:@"off"];
[self addSubview: self.rightImage];
[self.rightImage release];
}
</pre>
<br />
Now you should be able to see UISwitch with custom images, we now need to add code required to on and off switch from code and change image accordingly.
<br />
<pre class="prettyprint">- (void)setOn:(BOOL)turnOn animated:(BOOL)animated;
{
on = turnOn;
if (animated) {
[UIView beginAnimations:@"UICustomSwitch" context:nil];
[UIView setAnimationDuration:0.2];
}
if (on) {
self.value = 1.0;
self.rightImage.hidden = YES;
self.leftImage.hidden = NO;
} else {
self.value = 0.0;
self.rightImage.hidden = NO;
self.leftImage.hidden = YES;
}
if (animated) {
[UIView commitAnimations];
}
}
</pre>
<br />
Now finally we also have to add code to enable interaction.
<br />
<pre class="prettyprint">- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event
{
[super endTrackingWithTouch:touch withEvent:event];
touchedSelf = YES;
[self setOn:on animated:YES];
}
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
[super touchesBegan:touches withEvent:event];
touchedSelf = NO;
on = !on;
}
- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
[super touchesEnded:touches withEvent:event];
if (!touchedSelf) {
[self setOn:on animated:YES];
[self sendActionsForControlEvents:UIControlEventValueChanged];
}
}
</pre>
That's it, I hope this will help.
</div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com4tag:blogger.com,1999:blog-6223976744110856384.post-20731381217998602692015-08-16T01:23:00.002-07:002015-08-22T03:40:10.143-07:00The Math Game for iOS<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
If you have read my previous posts, you might already know I was trying to learn Swift language. While doing so I tried to create a simple game.
<br />
<br />
Finally I was able to complete the app and was able to publish it as well. You can download <a href="https://itunes.apple.com/de/app/the-math-game-by-niku/id1013678552">app from here.</a>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEsoPE_dmg6PIRVu4XXsakjyA8HDoAUu7Tp0wKMdA0i6M6VeHh09AVfi9uLeKVGeJL_1KCU80VOPHzrNBEFipqn8r12vALdj2DsBfHJo0YwdkiKuOwOerF_b0td4F_yY-Jpt-_jN2Vp18/s1600/the_math_game_menu.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em; text-align: left;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGEsoPE_dmg6PIRVu4XXsakjyA8HDoAUu7Tp0wKMdA0i6M6VeHh09AVfi9uLeKVGeJL_1KCU80VOPHzrNBEFipqn8r12vALdj2DsBfHJo0YwdkiKuOwOerF_b0td4F_yY-Jpt-_jN2Vp18/s200/the_math_game_menu.png" width="111" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPSDL7yVaBi5tIer31SNSx4LdafdN-Zi_dRsKnYScXydbI14jk-muNUdFRPY8ETeR3g_lmo1jwphREmHMOp0sDANMPZrw81GV0czth8pFNWEONbc4grjBy1xfuwH6PlGYQn8E5Ho5V-RsH/s1600/the_math_game_play1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPSDL7yVaBi5tIer31SNSx4LdafdN-Zi_dRsKnYScXydbI14jk-muNUdFRPY8ETeR3g_lmo1jwphREmHMOp0sDANMPZrw81GV0czth8pFNWEONbc4grjBy1xfuwH6PlGYQn8E5Ho5V-RsH/s200/the_math_game_play1.png" width="111" /></a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgszf_9twZZHTQKeBkrwEz31_ts44IN1x3DXWn7enf1iUQD-dWeHM9qQXIxz2jkcGgRyMdZDGWhsAZ47K-kYNUk0XOXSCNJn3H_NSRcXIF84N6b6b9ycfK23rJsQ-lFc5xrJBj_DUpAcEVk/s1600/the_math_game_startgame.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgszf_9twZZHTQKeBkrwEz31_ts44IN1x3DXWn7enf1iUQD-dWeHM9qQXIxz2jkcGgRyMdZDGWhsAZ47K-kYNUk0XOXSCNJn3H_NSRcXIF84N6b6b9ycfK23rJsQ-lFc5xrJBj_DUpAcEVk/s200/the_math_game_startgame.png" width="111" /></a>
</div>
<br />
Below is demo of the game.
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/eS_V6907xts" width="420"></iframe>
<br />
You can also get more information about <a href="https://launchkit.io/websites/-AcznufSZUo/">app here.</a></div>
</div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-7971898914785817662015-07-17T20:09:00.000-07:002015-07-17T20:09:02.421-07:00Displaying Game Centre Leaders board from Swift<div dir="ltr" style="text-align: left;" trbidi="on">
In last post, I showed how we can authenticate local player and how we can post score to default leader board.
<br/><br/>
In this post, I will show how we can display leader board using swift gamekit API. Below code shows how we can display GKGameCenterViewController.
Game center viewcontroller needs delegate, which is called when view is dismissed. Also we need parent viewcontroller which will be used to display GKGameCenterViewController.
<pre class="prettyprint">
func showLeaderboard(viewController: UIViewController,
gameCenterDelegate: GKGameCenterControllerDelegate) {
let gameCenterVC: GKGameCenterViewController = GKGameCenterViewController();
gameCenterVC.leaderboardIdentifier = defaultLeaderBoard;
gameCenterVC.gameCenterDelegate = gameCenterDelegate;
viewController.presentViewController(gameCenterVC, animated: true, completion: nil);
}
</pre>
Now we have code that can display leader board, but we need to make our class conform to GKGameCenterControllerDelegate protocol and implement required method. Below is code for delegate method. Which simply dismiss presented view controller.
<pre class="prettyprint">
func gameCenterViewControllerDidFinish(gameCenterViewController: GKGameCenterViewController!) {
gameCenterViewController.dismissViewControllerAnimated(true, completion: nil)
}
</pre>
So, as you can see it's quite simple. Hope this will be helpful.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-34515128916173676912015-07-10T21:14:00.000-07:002015-07-10T21:14:49.798-07:00Creating array of IBOutlets of NSLayoutConstraint's from Swift in iOS<div dir="ltr" style="text-align: left;" trbidi="on">
While working on my iOS app, I wanted to modify UI Constraint set from Interface Builder from Swift code.
<br/><br/>
Below video shows how we can create Array of IBOutlets using Interface Builder. Here I am creating array of NSLayoutConstraint, which I want to modify from Swift Code.
<br/><br/>
<iframe width="420" height="315" src="https://www.youtube.com/embed/-I2Y5zFSqbU" frameborder="0" allowfullscreen></iframe>
<br/><br/>
Now lets see how we can manipulate constraints from swift. First we need to define array of IBOutlet. Below code shows the same.
<pre class="prettyprint">
@IBOutlet var constraints: Array<NSLayoutConstraint>?
</pre>
Now, once you connect IBoutlet from Interface Builder as shown in above video. You can use those. In below code I am modifying NSLayoutConstraint's constant value.
<pre class="prettyprint">
if( Utils.isIPad() ) {
for constraint: NSLayoutConstraint in constraints! {
if(Utils.isIPad()) {
constraint.constant = 30
}
}
}
</pre>
That's it, Thank you for reading.
<br /></div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-14756405755441412272015-06-28T22:37:00.001-07:002015-06-28T22:37:26.387-07:00Posting score to Game Kit Leader board using swift<div dir="ltr" style="text-align: left;" trbidi="on">
As you might already know, I recently started exploring Swift language and now I am trying out GameKit framework. While I have some experience in working with GameKit using Objective C. I wanted to do the same thing using swift. As such there are no API changes while using GameKit with Swift or Objective C. However there are some syntax change.
<br/></br>
In this post, I will show how to Authenticate local player using GameKit framework and post score to LeaderBoard defined in iTune Connect Application setting.
<br/></br>
Following is code snippet that shows how to Authenticate Local player. This function takes ViewController as argument. Login dialog will be displayed using this View controller. Rest will be taken care by GameKit framework.
<pre class="prettyprint">
func authenticateLocalPlayer(viewController: UIViewController) {
let localPlayer: GKLocalPlayer = GKLocalPlayer.localPlayer()
localPlayer.authenticateHandler = {(ViewController, error) -> Void in
if((ViewController) != nil) {
// 1 Show login if player is not logged in
viewController.presentViewController(ViewController, animated: true, completion: nil)
} else if (localPlayer.authenticated) {
// 2 Player is already euthenticated & logged in, load game center
self.isGameCenterEnabld = true
} else {
// 3 Game center is not enabled on the users device
self.isGameCenterEnabld = false
println("Local player could not be authenticated, disabling game center")
println(error)
}
}
}
</pre>
Now we have authenticated local player. So when we are ready to post score to Leader Board. We can use below function. Here we are posting score to "defaultLeaderBoard". Which is identifier of Leader board defined in iTune connect App setting.
<pre class="prettyprint">
func submitScore( score: Int) {
if( !isGameCenterEnabld ) {
return;
}
var sScore = GKScore(leaderboardIdentifier: defaultLeaderBoard)
sScore.value = Int64(score)
let localPlayer: GKLocalPlayer = GKLocalPlayer.localPlayer()
GKScore.reportScores([sScore], withCompletionHandler: { (error: NSError!) -> Void in
if error != nil {
println(error.localizedDescription)
} else {
println("Score submitted")
}
})
}
</pre>
That's it. Hope this will be useful.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com1tag:blogger.com,1999:blog-6223976744110856384.post-46654643684742582632015-06-27T18:42:00.001-07:002015-06-27T18:42:46.755-07:00Using NSNotificationCenter in Swift<div dir="ltr" style="text-align: left;" trbidi="on">
NSNotificationCenter is a convenient method to implement Observer pattern in iOS, something similar to what we say Signal/Slot in Qt framework.
<br/><br/>
To register one self as observer to some event, you can use addObserver method form NSNotificationCenter. In below code you are adding self as observer, selector is method which will be called when event is triggered, name is name of event or notification in which we are interested in, and object is object from which we want to receive event from, nil means we are ready to receive event from any object.
<br/>
<pre class="prettyprint">
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "gameViewClosed",
name: "gameViewClosed",
object: nil);
</pre>
Now to trigger the notification, you can use postNotificationName method from NSNotificationCenter. Following code shows the same. Here we are sending notification for "gameViewClosed" event, object nil mean deliver event to all interested objects.
<br/>
<pre class="prettyprint">
NSNotificationCenter.defaultCenter().postNotificationName(
"gameViewClosed",
object: nil);
</pre>
That's it, thanks for reading.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-91909523228124179032015-06-25T19:11:00.000-07:002015-06-25T19:11:25.154-07:00Playing sound using Swift <div dir="ltr" style="text-align: left;" trbidi="on">
Posting small code snippet to that shows how to play sound using Swift in iOS.
<br/><br/>
First we need to import AVFoundation.
<pre class="prettyprint">
import AVFoundation
</pre>
Then we need to create instance of AVAudioPlayer. I created a small utility function like below for the same.
<pre class="prettyprint">
private static func createAudioPlayer
( sound: String, type: String ) -> AVAudioPlayer {
var error:NSError?;
let soundUrl = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(sound, ofType: type)!);
println(soundUrl)
var player = AVAudioPlayer(contentsOfURL: soundUrl, error: &error);
player.prepareToPlay();
return player;
}
</pre>
And this function can be used like below.
<pre class="prettyprint">
public init() {
// Removed deprecated use of AVAudioSessionDelegate protocol
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil);
AVAudioSession.sharedInstance().setActive(true, error: nil);
correctAns = MusicHelper.createAudioPlayer("correctAns", type: "wav");
wrongAns = MusicHelper.createAudioPlayer("wrongAns",type: "wav");
}
</pre>
Now we can use AVAudioPlayer's play API to play the sound. Like below.
<pre class="prettyprint">
public func playCorrectAnsSound() {
correctAns.play();
}
public func playWrongAnsSound() {
wrongAns.play();
}
</pre>
That's it, thanks for reading.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-87957286125171110582015-06-07T02:23:00.000-07:002015-06-07T02:23:33.212-07:00Performing Segue and Passing data in iOS<div dir="ltr" style="text-align: left;" trbidi="on">
I was trying to learn how to perform view switching using Segue for UI created by StoryBoard. Using Segue is quite easy and convenient. You can create Segue from Interface Builder, which associate action to view. Like if you click some button then you can associate this click action with view switch and you can select which view to switch to. This all is quite simple and can be done using simple drag and drop.
<br/> <br/>
In case you want to perform view switch manually without any user interaction, you can call "performSegueWithIdentifier", like below. Here once my game is finished, I am calling "GameOverSegue", which will switch view to GameOver view.
<pre class="prettyprint">
self.performSegueWithIdentifier("GameOverSegue", sender: self)
</pre>
If you want to pass some data while performing Segue, your calling ViewController needs to override "prepareForSegue" function. In this function you can set data to called view. Like below, I want to pass score to my GameOver view.
<pre class="prettyprint">
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if( segue.identifier == "GameOverSegue") {
let gameOverVC: GameOverViewController =
segue.destinationViewController as! GameOverViewController;
gameOverVC.setScore(self.score)
}
}
</pre>
Thanks, hope this will be helpful.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-62321172670410188822015-06-06T19:20:00.000-07:002015-06-06T19:20:05.486-07:00Drawing round border around UIView in iOS<div dir="ltr" style="text-align: left;" trbidi="on">
I wanted to create a subview UIView with round border in iOS. I found following code works very well to draw round border around UIView. While this code is written swift you can easily write similar code in Objective C as well.
<br/><br/>
Following is the code. As you can see, I selected subview UIView and made is IBOutlet using Interface Builder. Once that is done you can see round border around view.
<pre class="prettyprint">
@IBOutlet weak var contentView: UIView?
override func viewDidLoad() {
super.viewDidLoad();
contentView?.layer.borderWidth = 3.0
contentView?.layer.borderColor = UIColor(red:102/255,green:102/225,blue:102/225, alpha:1).CGColor
contentView?.layer.cornerRadius = 14
}
</pre>
And following how it looks.
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27ZbL915rIbFI11GYxx_VxqoZyDENoMrd6hDydrRKBJtGgwHl5dDj6iykXK6KuTw-dEsICBrHtnLqnSWpjiMdtGHF9wfcjTxJk6LBrbBdmfsNtdQxF2P7v9TDg1Ed2VCT46NNsBlmYeRF/s1600/round_+border_UIVIew.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj27ZbL915rIbFI11GYxx_VxqoZyDENoMrd6hDydrRKBJtGgwHl5dDj6iykXK6KuTw-dEsICBrHtnLqnSWpjiMdtGHF9wfcjTxJk6LBrbBdmfsNtdQxF2P7v9TDg1Ed2VCT46NNsBlmYeRF/s640/round_+border_UIVIew.png" /></a></div>
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-91133914495688817112015-06-05T20:18:00.000-07:002015-06-05T20:18:52.828-07:00Hiding status bar in iOS8 using Swift<div dir="ltr" style="text-align: left;" trbidi="on">
I recently started learning swift, while learning I started to create simple game. I wanted to make my game full screen, but I was unable to hide top status bar from Interface builder. No matter what I change that status bar was always visible.
<br/><br/>
Buf I found following code snippet, if you add this code in your View Controller file, you can easily hide status bar.
<pre class="prettyprint">
override func prefersStatusBarHidden() -> Bool {
return true;
}
</pre>
Following how my ViewController file looks after adding this code.
<pre class="prettyprint">
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func prefersStatusBarHidden() -> Bool {
return true;
}
}
</pre>
That's it. Hope this will be hopeful.
</div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-87926209080453517242015-05-03T22:47:00.002-07:002015-05-03T22:47:28.150-07:00Color Animation using Animator with Unity3D<div dir="ltr" style="text-align: left;" trbidi="on">
I created a small demo application to demonstrate how Animation can be done using Animator and State Machine with Unity5. This demo creates a Blinking Animation on Mouse click.
<br />
<br />
Following is final output of this demo.<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/DANGeHrYDVg" width="420"></iframe>
<br />
Below post shows, how above animation can be created.<br />
<br />
<b>-></b> To begin, First create a simple cube and apply a material on the cube. Setup should look like below.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWrtgzD_eUE5r6KbwXu17panelDtP_LZMlUcXTMPzd067mm_H7VfI4MdD4eg_KP7QyUoX_QOZn3iUVKAzNtFFYFbJgje7KQ4JmFCGairQh1B3eLNGiBCc7qsdW38ELzw-KGnMwtDpBUg_h/s1600/Screen+Shot+2015-05-04+at+12.16.09+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="604" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWrtgzD_eUE5r6KbwXu17panelDtP_LZMlUcXTMPzd067mm_H7VfI4MdD4eg_KP7QyUoX_QOZn3iUVKAzNtFFYFbJgje7KQ4JmFCGairQh1B3eLNGiBCc7qsdW38ELzw-KGnMwtDpBUg_h/s640/Screen+Shot+2015-05-04+at+12.16.09+PM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<b>-></b> Then using "Add Component", add Animator to this cube.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKunkYIq-exL7GsLKEbm9dWyWxHRGmbJN605dr4VnAhpeCXCg1JHQJYzhDqEOBeyGrpLmzcUcEoKpfBouY4-qUWiuZscvoi5Spgb-g9a3oEYClw4uqEwoSbp3jQ0QvDQudZJTdZLwtHY2p/s1600/Screen+Shot+2015-05-04+at+12.17.08+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKunkYIq-exL7GsLKEbm9dWyWxHRGmbJN605dr4VnAhpeCXCg1JHQJYzhDqEOBeyGrpLmzcUcEoKpfBouY4-qUWiuZscvoi5Spgb-g9a3oEYClw4uqEwoSbp3jQ0QvDQudZJTdZLwtHY2p/s640/Screen+Shot+2015-05-04+at+12.17.08+PM.png" width="248" /></a></div>
<br />
<b>-> </b>Once Animator is added, open Animation window using "Window" -> "Animation", We will need to use while performing the animation. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD_JOz8vZLrR__SQghhzw71Epr0QLItQlIReG7nUDSPgbgLGk5uX53UAKa69SGfc8l-quFzTe_JJxKfGXPLdOb24Vn_k_nhdaIav-Ksc5pT_eg_N5k5ov4PVoufqnOQgDW5sWbVk6TwikZ/s1600/Screen+Shot+2015-05-04+at+12.17.52+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="322" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgD_JOz8vZLrR__SQghhzw71Epr0QLItQlIReG7nUDSPgbgLGk5uX53UAKa69SGfc8l-quFzTe_JJxKfGXPLdOb24Vn_k_nhdaIav-Ksc5pT_eg_N5k5ov4PVoufqnOQgDW5sWbVk6TwikZ/s640/Screen+Shot+2015-05-04+at+12.17.52+PM.png" width="640" /></a></div>
<br />
Animator performs animation using State Machine and this state machine should have default state. Animator will transit to this default State when object is created. In Animator, Animation clip is considered as a State, so lets add a Animation clip and name it default. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSkibHf2R53dxC6TUSGWOdXEzk_KeSaYztX5ZhYFGUGiNOcduW818bSDKxLyRpB2Xn5H8sPT_vXAo5AFMTCllm1cXC9TQUEHrVHdjysP9FVGtSqSFHGTxvdDrbPMForrJpaQ8rmqSbJ3VP/s1600/Screen+Shot+2015-05-04+at+12.19.19+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="474" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSkibHf2R53dxC6TUSGWOdXEzk_KeSaYztX5ZhYFGUGiNOcduW818bSDKxLyRpB2Xn5H8sPT_vXAo5AFMTCllm1cXC9TQUEHrVHdjysP9FVGtSqSFHGTxvdDrbPMForrJpaQ8rmqSbJ3VP/s640/Screen+Shot+2015-05-04+at+12.19.19+PM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<b>-></b> Our default state will not have any animation, it should show just initial color. Let's just add one frame with current color. Like below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTxW1bdpxuYk5_JsMn8iWK5xTwq1fJ8jlbleSgngyq0qK4iUMm7vxjPBInw9tHwKAQP-Iw0bfO2llBhw0IUffiWt4j8s0aUgILkWgLLWwPwiIwmSjxr8dZsHNOqPvxPwGKHnzhcjIafuBG/s1600/Screen+Shot+2015-05-04+at+12.20.15+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="198" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTxW1bdpxuYk5_JsMn8iWK5xTwq1fJ8jlbleSgngyq0qK4iUMm7vxjPBInw9tHwKAQP-Iw0bfO2llBhw0IUffiWt4j8s0aUgILkWgLLWwPwiIwmSjxr8dZsHNOqPvxPwGKHnzhcjIafuBG/s640/Screen+Shot+2015-05-04+at+12.20.15+PM.png" width="640" /></a></div>
<br />
<b>-></b> Now we have default state, let's add another state which will perform "Blinking" animation. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZNbMdkNXN2oUZfQKz9TJK_xulXC1-8_nc97fAWw_QtppaKvVqnZLm3A4mNZ2ftT3DPJAkO63iGAPd645Odx4xLle7ml4XkbeemVNe2s2n5q1Sl4n3Ck7sOuqrDSTbUokThj0XEcuhBw55/s1600/Screen+Shot+2015-05-04+at+12.22.09+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="502" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZNbMdkNXN2oUZfQKz9TJK_xulXC1-8_nc97fAWw_QtppaKvVqnZLm3A4mNZ2ftT3DPJAkO63iGAPd645Odx4xLle7ml4XkbeemVNe2s2n5q1Sl4n3Ck7sOuqrDSTbUokThj0XEcuhBw55/s640/Screen+Shot+2015-05-04+at+12.22.09+PM.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoOI-68fp52z5BxxAi8PR2brIe1n1DlEJHqc5gixOR1A8jasUNFXgLQLWjwB5dLTz3jALkfzJ8MoGwSnVJ1t451IRK_3h-VYjJ6Nqm6iTOK5LpFpblzJdWqVoC9RHAfyAD-QtoNKMXz5fF/s1600/Screen+Shot+2015-05-04+at+12.22.21+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjoOI-68fp52z5BxxAi8PR2brIe1n1DlEJHqc5gixOR1A8jasUNFXgLQLWjwB5dLTz3jALkfzJ8MoGwSnVJ1t451IRK_3h-VYjJ6Nqm6iTOK5LpFpblzJdWqVoC9RHAfyAD-QtoNKMXz5fF/s640/Screen+Shot+2015-05-04+at+12.22.21+PM.png" width="640" /></a></div>
<br />
<b>-></b> Now we should add frames, so let's add color property and frames to animate color. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibGiewuE2pW3cw01aM5yi4T3LGHrBc9oQeTU-4s7Vsv8OCgU9HkbatLu3h-iqiwoxYYddHF1Jtaf92zis5AyNPEJLpKdTNRZK0BmHFj8jiGikdDHtnQLBCyY-Ana8zIHblZBYdhR4E711D/s1600/Screen+Shot+2015-05-04+at+12.21.40+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="382" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibGiewuE2pW3cw01aM5yi4T3LGHrBc9oQeTU-4s7Vsv8OCgU9HkbatLu3h-iqiwoxYYddHF1Jtaf92zis5AyNPEJLpKdTNRZK0BmHFj8jiGikdDHtnQLBCyY-Ana8zIHblZBYdhR4E711D/s640/Screen+Shot+2015-05-04+at+12.21.40+PM.png" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGTG3Nz2gS0HCRbXZpl_z2cNRczHmizAqhpMBQsfVcSSWxUV-fV9LfH_xxl1-4Lrb-rMJDSCKB1ZBW8K4nuoyKHHkEreP-Ncy4vpDU0uiDweqYexEX1ik42L7EowVoAjkDhABJL5h-J2H6/s1600/Screen+Shot+2015-05-04+at+12.23.13+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="286" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGTG3Nz2gS0HCRbXZpl_z2cNRczHmizAqhpMBQsfVcSSWxUV-fV9LfH_xxl1-4Lrb-rMJDSCKB1ZBW8K4nuoyKHHkEreP-Ncy4vpDU0uiDweqYexEX1ik42L7EowVoAjkDhABJL5h-J2H6/s640/Screen+Shot+2015-05-04+at+12.23.13+PM.png" width="640" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
After adding these frames color should animate like below.
<br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/h1nTlFE6Tfo" width="420"></iframe><br />
<br />
<b>-></b> Now we have Blinking animation state, we are now ready to create a State Machine. Open Animator window by clicking on "Animator" object, it should look like below. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZxqHOLY-J9qnwwnOZxe7i8mVf5wnZHn2IiBJQUjzbR8qUuUS1vNCRoB_M6xLdZ4cnTa3FLF9fZHvD70jd6_QCPgxKv00tSbkjmHjgz4CUSQzxxAIYMFzdtBHUMjocmEtrj8Gr_4YRbDlX/s1600/Screen+Shot+2015-05-04+at+12.29.03+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZxqHOLY-J9qnwwnOZxe7i8mVf5wnZHn2IiBJQUjzbR8qUuUS1vNCRoB_M6xLdZ4cnTa3FLF9fZHvD70jd6_QCPgxKv00tSbkjmHjgz4CUSQzxxAIYMFzdtBHUMjocmEtrj8Gr_4YRbDlX/s640/Screen+Shot+2015-05-04+at+12.29.03+PM.png" /></a></div>
<br />
<b>-></b> We should now add a Parameter which will be used to Trigger animation. On "Animator" window add new boolean parameter and name it "blink". <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheENkqa3PpPhLbOaVUmx54Wm5wVUaqllMG1BZZ1aWX35-w4hP-lCW4wCTvVcaB-P6FtOyovcDt0gIpSAF5N5JmiU2Eoelnxu5S_AX9H9S-bIaB8nkLeVl_F3ahT3kjNdJerEPoWhns1Zn-/s1600/Screen+Shot+2015-05-04+at+12.32.07+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheENkqa3PpPhLbOaVUmx54Wm5wVUaqllMG1BZZ1aWX35-w4hP-lCW4wCTvVcaB-P6FtOyovcDt0gIpSAF5N5JmiU2Eoelnxu5S_AX9H9S-bIaB8nkLeVl_F3ahT3kjNdJerEPoWhns1Zn-/s640/Screen+Shot+2015-05-04+at+12.32.07+PM.png" width="510" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj66e2zThbEjzyrBFROfaf8Akm7Xlh74k3S1m1J2SKbQeoYZ3MCREAd3JMTWo49b7JAenBnQb6lwXIe1iZRvd3Ki5J5kjOvIqbdT5v2tlnJG8lZdCuN33uq_jzCQ8qPAksIxxpZqFg4A5oD/s1600/Screen+Shot+2015-05-04+at+12.32.34+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="464" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj66e2zThbEjzyrBFROfaf8Akm7Xlh74k3S1m1J2SKbQeoYZ3MCREAd3JMTWo49b7JAenBnQb6lwXIe1iZRvd3Ki5J5kjOvIqbdT5v2tlnJG8lZdCuN33uq_jzCQ8qPAksIxxpZqFg4A5oD/s640/Screen+Shot+2015-05-04+at+12.32.34+PM.png" width="640" /></a></div>
<br />
Following video shows how to create transition and how to add condition to those transition. <br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/3o9KLU-6Ks8" width="420"></iframe>
<br />
<b>-></b> Now we have state machine with transition and condition, but we want Blink Animation to terminate once its finished. Let's open "Blink Animation" and add Animation event line shown in below image. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOWdH5ssLfpM9LWxn53cyzLDJgVSWqqQ-9twUhwEXnNBlavaCdDc1EAf301XaPTYLvqFv9IWvM_HU7bf4mBZdSQGOZ04qGo1ajP4kgT_A34DTfzvsciDbXAVKnFWwJpJ6ohY-iwTsn_qk0/s1600/Screen+Shot+2015-05-04+at+12.44.37+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOWdH5ssLfpM9LWxn53cyzLDJgVSWqqQ-9twUhwEXnNBlavaCdDc1EAf301XaPTYLvqFv9IWvM_HU7bf4mBZdSQGOZ04qGo1ajP4kgT_A34DTfzvsciDbXAVKnFWwJpJ6ohY-iwTsn_qk0/s640/Screen+Shot+2015-05-04+at+12.44.37+PM.png" /></a></div>
<br />
This will prompt you to select function to be invoked when Animation frame is reached. You can select function from attached Script. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPY7q6ImuYL_sUXDmxnMxB3-hZpGzm53vcnNtExzhYm9_4qfMipuqZSclxLec7pzmSZ8wXmSU6eeJDGqQWQ-x4DvYKC24MrGGP41fwJJkRdfDiUcrM3UPgPEk62tiT7PQKzXEgx5i-rAAc/s1600/Screen+Shot+2015-05-04+at+12.44.44+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPY7q6ImuYL_sUXDmxnMxB3-hZpGzm53vcnNtExzhYm9_4qfMipuqZSclxLec7pzmSZ8wXmSU6eeJDGqQWQ-x4DvYKC24MrGGP41fwJJkRdfDiUcrM3UPgPEk62tiT7PQKzXEgx5i-rAAc/s640/Screen+Shot+2015-05-04+at+12.44.44+PM.png" /></a></div>
<br />
Following video shows the same process. <br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/9FobPk4nrYw" width="420"></iframe> <br />
<br />
<b>-></b> Finally, We also need to add a script to Cube object. Following is code for the script. In script we are setting "blink" transition parameter of Animator to true on mouse click. While StopAnimation sets "blink" parameter to false when animation event is called.<br />
<br />
<pre class="prettyprint">using UnityEngine;
using System.Collections;
public class MyAnimation : MonoBehaviour {
private Animator animator;
void Awake() {
animator = GetComponent<animator> ();
}
void OnMouseUp() {
startAnimation ();
}
public void startAnimation() {
animator.SetBool ("Blink", true);
}
public void stopAnimation() {
animator.SetBool ("Blink", false);
}
}
</animator></pre>
<br />
And now if run project and click cube, you should see blink animation as per demo video. That's it hope this post will be helpful.
</div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-89341865170852399422015-04-12T04:25:00.000-07:002015-04-12T04:25:30.448-07:00Handling Drag and Drop with Unity 3D<div dir="ltr" style="text-align: left;" trbidi="on">
Drag and Drop is quite useful and we need to implement this quite often in our project. While working on one of my Unity Project, I required to implement the same.
<br/><br/>
There are some options but I found code described in this post quite simple to use with my project. In this post I will describe how I achieved the same.
<br/><br/>
So, Let's first create a C# script, I named it Drag.cs and added following code to it. This script will enable touch interaction to added GameObject and will move object along with touch. Also add BoxCollider to GameObject, so we can detect collision.
<pre class="prettyprint">
using UnityEngine;
using System.Collections;
public class Drag : MonoBehaviour {
private Plane plane;
private Vector3 v3Offset;
void OnMouseDown() {
plane.SetNormalAndPosition
(Camera.main.transform.forward, transform.position);
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
float dist;
plane.Raycast (ray, out dist);
v3Offset = transform.position - ray.GetPoint (dist);
}
void OnMouseUp() {
}
void OnMouseDrag() {
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
float dist;
plane.Raycast (ray, out dist);
Vector3 v3Pos = ray.GetPoint (dist);
transform.position = v3Pos + v3Offset;
}
}
</pre>
Now, suppose we have another GameObject and we want to detect when GameObject we just created with above script, is dropped on it. To detect drop easily let's first add RigidBody to this GameObject and BoxCollider. After adding BoxCollider also check isTrigger is true. After doing this we need to add C# script to it which will handle drop. Let's name it to Drop.cs and add below code to it.
<br/><br/>
Below script observe the Collision. When collision happens it checks which object is collided with it.
If collided object is Drag object then do something.
<pre class="prettyprint">
using UnityEngine;
using System.Collections;
public class Drop : MonoBehaviour {
void OnCollisionEnter2D (Collision2D other) {
}
void OnCollisionExit2D(Collision2D other){
}
void OnTriggerStay2D (Collider2D other) {
if( other.gameObject.tag == "Drag" ) {
// Object dropped, handle the drop
}
}
}
</pre>
That's pretty much it, hope this helps.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-75193815048260813722015-04-04T23:10:00.000-07:002015-04-04T23:10:09.989-07:00Sprite with Text in Unity3D<div dir="ltr" style="text-align: left;" trbidi="on">
I am working on one game where I wanted to show text over sprite. With new Unity UI System, it's quite easy to create button as sprite and text over it.
<br/><br/>
But if you want to create a traditional sprite and add text to it, this post describes the same.
<br/><br/>
Basic idea is to add 3D text component to sprite, but if you have tried it then you might know after adding 3D text component we need to move it to same sorting order as sprite. Also we need to layout text properly to set alignment.
<br/><br/>
Before we begin, I assume you know how to create Sprite, how to create 3D text component and make it a Prefab object. If not you can refer <a href="http://kunalmaemo.blogspot.kr/2013/10/dynamic-object-creation-in-unity3d.html">this article</a> to know how to make Prefab object.
<br/><br/>
Finally, following is my script which I attached to Sprite. Once added to Sprite, It will create 3D text component from provided Prefab object and add the same to Sprite.
<pre class="prettyprint">
using UnityEngine;
using System.Collections;
public class TextScript : MonoBehaviour {
public string text;
public GameObject textPrefab;
void Start() {
GameObject text = Instantiate(textPrefab) as GameObject;
text.transform.parent = gameObject.transform;
text.transform.rotation = gameObject.transform.rotation;
TextMesh textInstance = text.GetComponent<TextMesh>();
textInstance.text = text;
Renderer textRenderer = text.GetComponent<Renderer> ();
Renderer thisRenderer = GetComponent<Renderer> ();
textRenderer.sortingLayerID = thisRenderer.sortingLayerID;
textRenderer.sortingOrder = thisRenderer.sortingOrder+1;
Bounds textBounds = textRenderer.bounds;
Bounds parentBounds = thisRenderer.bounds;
float x = gameObject.transform.position.x
- (textBounds.size.x/2);
float y = gameObject.transform.position.y
+ (textBounds.size.y/2);
textInstance.transform.position =
new Vector3(x, y, parentBounds.center.z + 1);
}
}
</pre>
That's it, you can add this script to any component and add text over it.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com1tag:blogger.com,1999:blog-6223976744110856384.post-7347621229313308962015-01-24T19:35:00.000-08:002015-01-24T19:39:12.867-08:00Notification on property change in iOS SDK<div dir="ltr" style="text-align: left;" trbidi="on">
I have used QML quite a lot in my projects and there is one quite nice feature in QML that makes implementation quite easy. The feature is Property change notification.
<br/><br/>
Apple iOS SDK also similar mechanism named Key-Value Observing mechanism. <a href="https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html">Here</a> is Apple's documentation for the same.
<br/><br/>
Following is simple code which demonstrate how we can use Key-Value Observer API to get notification on property changes.
First we need to register observer and in which property observer is interested in. Code shows, class "self" is interested in property change event from propertyOwner for "isPlaying" property.
<pre class="prettyprint">
[propertyOwner addObserver:self
forKeyPath:@"isPlaying"
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
context:NULL];
</pre>
Now, we have registered observer for property change, we need to implement method which will be called in case of property is changed. Following code shows the same. We need to check which object sent event and for which property, then we can take appropriate action.
<pre class="prettyprint">
- (void) observeValueForKeyPath:(NSString *)path ofObject:(id) object change:(NSDictionary *) change context:(void *)context
{
// this method is used for all observations, so you need to make sure
// you are responding to the right one.
if (object == propertyOwner && [path isEqualToString:@"isPlaying"]) {
// now we know which property is modified
}
}
</pre>
When we are done and don't need notification any more we can remove observer. Below is code for the same. It's safe to use try and catch as we might get exception if we try to remove observer when none is registered.
<pre class="prettyprint">
@try{
[propertyOwner removeObserver:self forKeyPath:@"isPlaying"];
}@catch(id anException){
//do nothing, obviously it wasn't attached because an exception was thrown
}
</pre>
Now whenever "propertyOwner" changes's "isPlaying" property then "self" will get notification and "observeValueForKeyPath" method will get called.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-68892688273324263812014-12-27T18:16:00.000-08:002014-12-27T18:16:30.969-08:00Showing Remote Image using ImageView in BB10 Cascades<div dir="ltr" style="text-align: left;" trbidi="on">
While working on my BB10 App update, I required to show Remote Image using ImageView BB10 cascades API. ImageView or Image component by default does not support loading image from URL on internet. I implemented a custom component which serve the purpose and also easily integrated with ImageView.<br/> <br/>
Following is implementation for the same, I hope it will be useful to someone.<br/><br/>
Let's start by showing how my custom component works. Following code shows how to use ImageDownloader custom component along with ImageView to display Grid of images from internet. Data Model contains two kind of URL, url for low resolution image and url for high resolution image.
<pre class="prettyprint">
import my.library 1.0
ListView {
id: listView
layout: GridListLayout {}
dataModel: model;
listItemComponents: [
ListItemComponent {
ImageView {
id: imgView
imageSource: "default_image.jpg"
attachedObjects: [
ImageDownloader {
id: imageLoader
url: ListItemData.mediumImage
onImageChanged: {
if (imageLoader.isVaid) {
imgView.image = imageLoader.image
}
}
}
]
}
}
]
}
</pre>
ImageDownloader component is available in QML because we imported "my.library". We can make any C++ code available to QML by registering it to QML System, folloiwing snippet shows how we can register C++ component to QML system.
<pre class="prettyprint">
#include "ImageDownloader.h"
int main(int argc, char **argv)
{
Application app(argc, argv);
qmlRegisterType<ImageDownloader>("my.library",1, 0, "ImageDownloader");
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(&app);
AbstractPane *root = qml->createRootObject<AbstractPane>();
app.setScene(root);
return Application::exec();
}
</pre>
Now that custom component is ready to be used with QML, let's see how its implemented. Below if header file for ImageDownloader class.
We are defining few properties like url, image and isValid. By setting "url" we can initiate download of image, when "image" download is finished downloaded image can be accessed by using "image" property. We can check if image is valid or not by checking "isValid" property. we are also defining few signal like "urlChanged" and "imageChanged", which are emited when url is changed or image is downloaded. And we are using QNetworkAccessManager to download image from internet.
<pre class="prettyprint">
#ifndef IMAGEDOWNLOADER_H_
#define IMAGEDOWNLOADER_H_
#include <QObject>
#include <bb/cascades/Image>
class QNetworkAccessManager;
class ImageDownloader: public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant image READ image NOTIFY imageChanged)
Q_PROPERTY(QString url READ url WRITE setUrl NOTIFY urlChanged)
Q_PROPERTY(bool isVaid READ isValid CONSTANT);
public:
ImageDownloader( QObject* parent = 0);
virtual ~ImageDownloader();
signals:
void urlChanged();
void imageChanged();
private slots:
QString url() const;
void setUrl( const QString& url);
QVariant image() const;
bool isValid() const;
void startDownload();
void onReplyFinished();
private:
QNetworkAccessManager mNetManager;
QString mImageUrl;
bb::cascades::Image mImage;
bool mIsValid;
};
#endif /* IMAGEDOWNLOADER_H_ */
</pre>
Implementation is also quite simple, let's see how its implemented. On URL change, we are initiating the image download using QNetworkAccessManager. When download is finished, we are reading image data in to buffer and creating Image using BB10 Image API.
<pre class="prettyprint">
#include "ImageDownloader.h"
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
ImageDownloader::ImageDownloader(QObject* parent):
QObject(parent), mIsValid(false) {}
ImageDownloader::~ImageDownloader() {}
QString ImageDownloader::url() const {
return mImageUrl;
}
void ImageDownloader::setUrl( const QString& url)
{
if(url != mImageUrl) {
mImageUrl = url;
mIsValid = false;
mImage = bb::cascades::Image();
emit urlChanged();
emit imageChanged();
startDownload();
}
}
QVariant ImageDownloader::image() const {
return QVariant::fromValue(mImage);
}
bool ImageDownloader::isValid() const {
return mIsValid;
}
void ImageDownloader::startDownload() {
QNetworkRequest request(mImageUrl);
QNetworkReply* reply = mNetManager.get(request);
connect(reply, SIGNAL(finished()), this, SLOT(onReplyFinished()));
}
void ImageDownloader::onReplyFinished() {
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
QString response;
if (reply) {
if (reply->error() == QNetworkReply::NoError) {
const int available = reply->bytesAvailable();
if (available > 0) {
const QByteArray data(reply->readAll());
mImage = bb::cascades::Image(data);
mIsValid = true;
emit imageChanged();
}
}
reply->deleteLater();
}
}
</pre>
That's all we have to do to do display remote image in BB10, hope you liked it.
<br /></div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com2tag:blogger.com,1999:blog-6223976744110856384.post-83642681815007759472014-12-20T20:17:00.000-08:002014-12-20T20:17:40.115-08:00Resolving "_clock$UNIX2003", referenced from" error<div dir="ltr" style="text-align: left;" trbidi="on">
I was trying to build Unity 3D project for simulator SDK. I wanted to get different screen size screen shot.
But when I tried to build it I got following build error.
<br />
<pre class="prettyprint">_clock$UNIX2003", referenced from
</pre>
I found one work around to resolve this issue. We need to add following patch to main.mm file.
<br />
<pre class="prettyprint">#include <time.h>
// "_clock$UNIX2003", referenced from:
//Temporary hack for building Simulator Project for Unity
extern "C"
{
clock_t
clock$UNIX2003(void)
{
return clock();
}
}
</pre>
Once I added above patch build started working fine for me and I was able to run project on Simulator.
<br /></div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com1tag:blogger.com,1999:blog-6223976744110856384.post-39379329355183772132014-11-23T03:38:00.003-08:002014-11-23T03:38:51.289-08:00Your Shot Ubuntu Touch Scope<div dir="ltr" style="text-align: left;" trbidi="on">
You might have heard about Ubuntu Touch, and one of unique feature of Ubuntu Touch is Scope. Recently they also announced Ubuntu Touch Scope competition.
This got me interested, I wanted to learn about Scope development, so I thought to take part as well in the competition.<br />
<br />
You can get more information about competition <a href="http://developer.ubuntu.com/2014/10/scope-development-competition/">here</a>.<br />
<br />
Recently I discovered <a href="http://yourshot.nationalgeographic.com/">Your Shot photo community</a>, I like pictures uploaded there and I visit site every day to checkout newly updated photos, so I thought it is good candidate for Scope development and I decided to write score for Your Shot photo community.<br />
<br />
Your Shot has nice Jason based web API and I was able to create scope quite easily using Ubuntu Touch socpe's Jason template. In fact I was able to get decent working scope in few hours using template. Documentation is also quite good and rich with <a href="http://developer.ubuntu.com/scopes/tutorials/write-a-json-scope-in-cpp/">API Reference, Guide and Tutorials.</a>
<br />
<br />
Here is demo for the same running on my desktop.<br />
<br />
<center><iframe allowfullscreen="" frameborder="0" height="315" src="//www.youtube.com/embed/KwmMtaOW8H8" width="420"></iframe></center>
<br />
And Few snapshot.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFAUxvHwYRNoo5OaM4uj6iYIgPWILBpdtrtOEY5w9BZA_prZTswy7dzN2rO5HxApOQ0IduIDX8joO4Mc6znFMwsQn2-ETQDWsB5UvACfc8SERjR5HvMnOuAdoKn4DWXEIzeG6GyO0nZAOG/s1600/main.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFAUxvHwYRNoo5OaM4uj6iYIgPWILBpdtrtOEY5w9BZA_prZTswy7dzN2rO5HxApOQ0IduIDX8joO4Mc6znFMwsQn2-ETQDWsB5UvACfc8SERjR5HvMnOuAdoKn4DWXEIzeG6GyO0nZAOG/s1600/main.png" height="400" width="365" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaKn7a6Lhri3V70RK0rv2dVcW9gNXxAdzL68u5S-w6TpR3vcZQAqp0rFn5IIDUkiO9UONLTxjfB2OZKaFSqC0JDWRk1I0epku5dfYp1CpppuJjdADBvTPT1wnhBJf-fPzuXY8ygVscVv8W/s1600/preview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiaKn7a6Lhri3V70RK0rv2dVcW9gNXxAdzL68u5S-w6TpR3vcZQAqp0rFn5IIDUkiO9UONLTxjfB2OZKaFSqC0JDWRk1I0epku5dfYp1CpppuJjdADBvTPT1wnhBJf-fPzuXY8ygVscVv8W/s1600/preview.png" height="400" width="365" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2HYHN49_fwex3Q12rVrs8JZ1c-msIuG8Yv732AVC9Pd4497O9zlqcpRInNwAhrZ4VGs04ZXpD1cHQdMHf6GgmR-EqIXLHQqkKseaFdPAzl1ueq1ACmoeBgajsPI4QOqLbV7fqWqaOPnSt/s1600/search.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2HYHN49_fwex3Q12rVrs8JZ1c-msIuG8Yv732AVC9Pd4497O9zlqcpRInNwAhrZ4VGs04ZXpD1cHQdMHf6GgmR-EqIXLHQqkKseaFdPAzl1ueq1ACmoeBgajsPI4QOqLbV7fqWqaOPnSt/s1600/search.png" height="400" width="365" /></a></div>
<br />
<br />
It looks like now I am ready to write more complex Scope but may be later.
</div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-43905395705562174712014-10-30T07:44:00.000-07:002014-10-30T07:44:43.960-07:00Creating dynamic QML object asynchronously<div dir="ltr" style="text-align: left;" trbidi="on">
We can create QML object dynamically by using createComponent and createObject API.<br/><br/>
Like follow,
<pre class="prettyprint">
var component = Qt.createComponent("Button.qml");
if (component.status == Component.Ready)
component.createObject(parent, {"x": 100, "y": 100});
</pre>
You can find more information regarding same <a href="http://kunalmaemo.blogspot.kr/2011/04/creating-qml-element-dynamically-on.html">here</a>. <br/><br/>
Latest Qt release added new API named incubateObject. This allows object to be created in asynchronously.
You can find more information about this API <a href="http://qt-project.org/doc/qt-5/qml-qtqml-component.html#incubateObject-method">here</a>.
<br/><br/>
Following code I written for Ubuntu touch calendar application, which uses the same. Here thing to remember is that incubateObject returns the incubator and not created object itself. You need to get object from incubator by incubator.object call.
<pre class="prettyprint">
var incubator = delegate.incubateObject(bubbleOverLay);
if (incubator.status !== Component.Ready) {
incubator.onStatusChanged = function(status) {
if (status === Component.Ready) {
incubator.object.objectName = children.length;
assignBubbleProperties( incubator.object, event);
}
}
} else {
incubator.object.objectName = children.length;
assignBubbleProperties(incubator.object, event);
}
</pre>
</div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-79474508643774610922014-09-13T20:13:00.001-07:002014-09-13T20:13:44.804-07:00Creating array of IBOutlet<div dir="ltr" style="text-align: left;" trbidi="on">
<span id="goog_1351415343"></span><span id="goog_1351415344"></span>Sometimes you want to enable/disable bunch of buttons together or perform other such activities on bunch of UI elements created using Interface Builder. <br />
<br />
I recently needed to perform similar operation on bunch of button for iOS game I am working on. For this kind of operation, its easier to create array of IBOutlet which can be created using IBOutletCollection.
Following is my code, which create IBOutletCollection of UIButtons and then enable/disbale them together.
<br />
<pre class="prettyprint">@interface MyViewController : UIViewController {
IBOutletCollection(UIButton) NSArray *buttons;
}
</pre>
in MyViewController.m, we can use buttons as below.
<br />
<pre class="prettyprint">-(void) enableUI:(BOOL) enable {
for( UIButton* button in buttons){
button.enabled = enable;
}
}
</pre>
Only thing missing now is, connecting UIButtons created using Interface Builder to IBoutletCollection. We need to do this from Interface Builder, process is similar to connecting UI Elements from Interface Builder to IBOutlet.<br />
<br />
Following snaps describes the required process. I created three buttons on view.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHZ8XANCn0Almm23Qm5ngo0TwpjWZX9zDHK37ZtoxPfy9QtLmcsxdNAdozX8tHRimaNfbjxj2wyNa26IkaKjXytfGwL8eMlRtZ7-ybYgDJXUI3z8t7T16WLpFLO1GQh8fCrg6AdAG0LZ48/s1600/IBOutlet_array_0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHZ8XANCn0Almm23Qm5ngo0TwpjWZX9zDHK37ZtoxPfy9QtLmcsxdNAdozX8tHRimaNfbjxj2wyNa26IkaKjXytfGwL8eMlRtZ7-ybYgDJXUI3z8t7T16WLpFLO1GQh8fCrg6AdAG0LZ48/s1600/IBOutlet_array_0.png" height="400" width="235" /></a></div>
<br />
You can connect IBoutletCollection to UIButton as shown in below snap.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGZwXROKG_ZSdisUjrcneJCMT4YF1-vaMhf9xx5c9wu700NdI3KJHycLaBhY7lcH1YNhXVn8fSoDBAsfzlnJbkov76ghyphenhypheniVI1RC-mD1oZQABSnhFVekRbNFKK9j8VP9zXLvlFQt8DxB9bG/s1600/IBOutlet_array_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGZwXROKG_ZSdisUjrcneJCMT4YF1-vaMhf9xx5c9wu700NdI3KJHycLaBhY7lcH1YNhXVn8fSoDBAsfzlnJbkov76ghyphenhypheniVI1RC-mD1oZQABSnhFVekRbNFKK9j8VP9zXLvlFQt8DxB9bG/s1600/IBOutlet_array_1.png" height="344" width="640" /></a></div>
<br />
And you can repeat above process to connect more UIButton with IBOutletCollection.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfp69erC20aplXeHknn_nyu5-2-eaanFGglxZBleskVZHaH_IIyARGT17hIglpRqpy11m4sAKNQud6y6QTcFv0vCg-EIUKAQaBiN20lKuLS_GJWhTv1RGpmW0Y_HfqTGZakN0hBHwv3Kkp/s1600/IBOutlet_array_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfp69erC20aplXeHknn_nyu5-2-eaanFGglxZBleskVZHaH_IIyARGT17hIglpRqpy11m4sAKNQud6y6QTcFv0vCg-EIUKAQaBiN20lKuLS_GJWhTv1RGpmW0Y_HfqTGZakN0hBHwv3Kkp/s1600/IBOutlet_array_2.png" height="298" width="640" /></a></div>
That's it.
</div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-45061050750572080612014-09-10T01:03:00.001-07:002014-09-10T01:03:57.844-07:00Matching custom NSObject with isEqual and hash<div dir="ltr" style="text-align: left;" trbidi="on">
While working on one multiplayer game for iOS using GameKit, I faced issue while comparing object.<br />
<div>
<br /></div>
<div>
For single player version I was not facing this issue but while running multiplayer version I was facing this issue. After debugging a little I realised condition for comparing object's value is failing and it turned out that I was comparing object's address rather then its value. As for Multiplayer game I was creating object using data from server/host, I needed to compare object's value and not its address.</div>
<div>
<br /></div>
<div>
For objectiveC, if you want to compare object's value using "==" operator, you need to overload isEqual and hash method as shown like below.<br />
<br /></div>
<div>
<pre class="prettyprint">-(BOOL)isEqual:(id) other {
if (other == self)
return YES;
if (!other || ![other isKindOfClass:[self class]])
return NO;
Card* otherCard = other;
return ( mSuit == otherCard.mSuit && mRank == otherCard.mRank);
}
- (NSUInteger)hash {
NSUInteger hash = 0;
hash += [[NSNumber numberWithInt:mSuit] hash];
hash += [[NSNumber numberWithInt:mRank] hash];
return hash;
}
</pre>
Note that you need to overload both method together, overloading only one will not work. Once I overloaded above method my multiplayer version started working as normal.
</div>
</div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-25300230784910630002014-07-04T23:14:00.002-07:002014-07-04T23:14:50.262-07:00Creating simple fade animation with Unity3D<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
I recently used fade animation or opacity animation with one of my Unity game, it was used to fade then earned points during game play. Initially I struggled a bit to achieve opacity animation due to confusion between using Animation or Animator. Look like from Unity version 4.3 we need to use Animator to animate the properties. I was trying to use Animation instead of Animator, was not able to perform opacity animation properly.
<br />
In this post I will show, how I accomplished the Fading animation. below is video of final effect and whole process to achieve animation.<br />
<iframe allowfullscreen="" frameborder="0" height="360" src="//www.youtube.com/embed/k1X_RAPs2lo" width="480"></iframe></div>
First create a initial setup of scene. Following is how my scene looks like.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIk6ylOENtyjKwgJ5FL9rswXI9bSgV6HxBg5BvEgkAgels4VHnBomq0Ztb9b9ROI2ZESn5W0CtXwLNNq3d5IdCteIuEXeXlP6Muo2IGIm0cwXLkCp6ytLaYB9G36GnVYjH7j_pn_ByRhAz/s1600/initial_Setup.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIk6ylOENtyjKwgJ5FL9rswXI9bSgV6HxBg5BvEgkAgels4VHnBomq0Ztb9b9ROI2ZESn5W0CtXwLNNq3d5IdCteIuEXeXlP6Muo2IGIm0cwXLkCp6ytLaYB9G36GnVYjH7j_pn_ByRhAz/s1600/initial_Setup.JPG" height="304" width="640" /></a></div>
<br />
I wanted to add fading effect to 3D text, which signifies the points earned during game play. Now scene looks like below.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-IImon4b-DnP6T_PmGoyASSkrczscrwVjaLfIawmWLrR66XxN7UXuNSj2GRQLYrE7OwIaHjqsublwOsprhXyjk4MdDhw09m-gY4_49t1PQFe-fmIFtD4QkkLZPQcFoBF-_jucX5UqVJLM/s1600/create_3d_text.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-IImon4b-DnP6T_PmGoyASSkrczscrwVjaLfIawmWLrR66XxN7UXuNSj2GRQLYrE7OwIaHjqsublwOsprhXyjk4MdDhw09m-gY4_49t1PQFe-fmIFtD4QkkLZPQcFoBF-_jucX5UqVJLM/s1600/create_3d_text.JPG" height="298" width="640" /></a></div>
<br />
Now we need to add animator component to text.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhruoLBT0RkRvfZUmZ0fFg613hxa-ZFn1RYsjBvAu3vC9zJpn0CQ2uZZafRb3iX4juTCZPtcuKe3aMJt2oL_qrEJYDcAcLQWKge58_l8MaZjJByOA1Y9Moq7pCpmMMmY3fCGnlXDlSoePSS/s1600/animator_adding.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhruoLBT0RkRvfZUmZ0fFg613hxa-ZFn1RYsjBvAu3vC9zJpn0CQ2uZZafRb3iX4juTCZPtcuKe3aMJt2oL_qrEJYDcAcLQWKge58_l8MaZjJByOA1Y9Moq7pCpmMMmY3fCGnlXDlSoePSS/s1600/animator_adding.png" height="282" width="640" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLinBhtIS005xVtX-snAkmWw7km3KEdcTMtDdPDAhlT1XPwqDVqoGeCS7V4aoLOEmjjZopsgte89BztjDFR4pkMKUqebzSYdOz2X8WKqUwwBPa10wjQ4AaxncG-DRHI_GJMNaQmBMCO_hh/s1600/add_animator.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjLinBhtIS005xVtX-snAkmWw7km3KEdcTMtDdPDAhlT1XPwqDVqoGeCS7V4aoLOEmjjZopsgte89BztjDFR4pkMKUqebzSYdOz2X8WKqUwwBPa10wjQ4AaxncG-DRHI_GJMNaQmBMCO_hh/s1600/add_animator.JPG" height="324" width="640" /></a></div>
<br />
Now, that we have added animator, we can go to Animation windows and setup our first key.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0AmasWm0sI1sAI3sYNgYqD5w2bCYwXnoYzVvncaKkrANEj0-K2yRvh7y_MZ8ywVN0UY78B65ZGehc2x6SH3m7cgN5kSnGSwXCbDGBDUxMe6mnLo1xi9VL8MQY_-XqC9VbPrRmLCo6Zw8M/s1600/add_first_key.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0AmasWm0sI1sAI3sYNgYqD5w2bCYwXnoYzVvncaKkrANEj0-K2yRvh7y_MZ8ywVN0UY78B65ZGehc2x6SH3m7cgN5kSnGSwXCbDGBDUxMe6mnLo1xi9VL8MQY_-XqC9VbPrRmLCo6Zw8M/s640/add_first_key.JPG" /></a></div>
<br />
First key is from where our animation will start, we need to setup second key where animation will end. Create a second key at desired location and move text at appropriate location.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihvfFJ5k9fu8s6xj1FPWGjM_6jflf5M5AmAZ5ZTw0wfJGRVmLAr60aNgBRs80ZmxyUUSY6F4X6mZmTb6E-DVrorvq0pvG67nGbWj6A9BsiX5Q0oyJ0AL8xSVbG81QOdLJOU_aKzqLQ6KbF/s1600/add_second_key.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihvfFJ5k9fu8s6xj1FPWGjM_6jflf5M5AmAZ5ZTw0wfJGRVmLAr60aNgBRs80ZmxyUUSY6F4X6mZmTb6E-DVrorvq0pvG67nGbWj6A9BsiX5Q0oyJ0AL8xSVbG81QOdLJOU_aKzqLQ6KbF/s640/add_second_key.JPG" /></a></div>
<br />
I also wanted to animate opacity with size and location. So lets add new curve for color animation.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG2KHhdZtdXPYULXbREzCvHh6TS_LNg23LGK2C6MSt6j4YT7MpuWc8y19tE2rlZ_lJ4JE_zNC4j5SRWKLrQjqOCUNZSKkQndYXPxbcbtgQGlQfE1hPRxQ7hfdW1VPm0uPh0SydIDlkoIkR/s1600/color_animation.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG2KHhdZtdXPYULXbREzCvHh6TS_LNg23LGK2C6MSt6j4YT7MpuWc8y19tE2rlZ_lJ4JE_zNC4j5SRWKLrQjqOCUNZSKkQndYXPxbcbtgQGlQfE1hPRxQ7hfdW1VPm0uPh0SydIDlkoIkR/s640/color_animation.png" /></a></div>
<br />
Setup the opacity value for color curve for both first key and second key. Following is how my keys looks like.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKZQyHDoOEX0fHoNx74rVB1fAUtiX7fYl7ej6iHSxQuRdxuJw8sH3096sQmy21v9VCZLD6VP7skeUMQLE2bViiFRDdGUFzpQQrlwafcY7SszcaoQ8955ueiNzMS5djNw1PBXc5yCOoCXjT/s1600/first_key.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKZQyHDoOEX0fHoNx74rVB1fAUtiX7fYl7ej6iHSxQuRdxuJw8sH3096sQmy21v9VCZLD6VP7skeUMQLE2bViiFRDdGUFzpQQrlwafcY7SszcaoQ8955ueiNzMS5djNw1PBXc5yCOoCXjT/s640/first_key.JPG" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuDSpy4BVrRu4USMBFb4gDu8G91WpnB9tNiM1jY0G24wRngj59xpZD6jhSua67elFxmjFjFJe8ygKX1bCr6udw9ZzX3QRvEMS7dWn95NCLTDZQT2gj3t4pi7C_r_zh4xK7DGk1BGxPH-XV/s1600/second_key.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuDSpy4BVrRu4USMBFb4gDu8G91WpnB9tNiM1jY0G24wRngj59xpZD6jhSua67elFxmjFjFJe8ygKX1bCr6udw9ZzX3QRvEMS7dWn95NCLTDZQT2gj3t4pi7C_r_zh4xK7DGk1BGxPH-XV/s640/second_key.JPG" /></a></div>
<br />
Now if you press play button or play animation you will be able to see fade animation. Thanks for reading my blog.
</div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0tag:blogger.com,1999:blog-6223976744110856384.post-35797468314562905182014-07-04T20:32:00.000-07:002014-07-04T20:32:09.088-07:00Creating global variable in Unity3D<div dir="ltr" style="text-align: left;" trbidi="on">
Sometime you want to create Global object that you can access from whole project.
Recently while working on my unity game, I also needed the same.
<br />
<br />
While method is quite simple to achieve the same, but its quite confusing if you are just started with Unity3D just like me.
Finally I now understand the process, and in this post I am describing how we can create global variable with Unity3D.
<br />
<br />
In Unity we work with Scene and when scene is unloaded all its objects are unloaded as well.
To make global variable, we need to create a game object in first scene and attach a script to it which prevent it from unloading when scene is unloaded. Now we can access this game object from newly loaded scene and other scenes as well.
<br />
<br />
Let's start with simple project and create a scene, I called this scene as first scene.
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglTS4Tyl2a243sCn3jnxuBvmGctgLfPq4zwZlyHHsh1eFFV2EeUtL61Wl9kCn0FPJY4S0sYkZ0ExNN_i95s1eSWYBwwvjjzAmSs2-H5zLpX2LJMMMXcmR8XG4LmUrXh5dyRUCB2RlBDMnv/s1600/initial_setup.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglTS4Tyl2a243sCn3jnxuBvmGctgLfPq4zwZlyHHsh1eFFV2EeUtL61Wl9kCn0FPJY4S0sYkZ0ExNN_i95s1eSWYBwwvjjzAmSs2-H5zLpX2LJMMMXcmR8XG4LmUrXh5dyRUCB2RlBDMnv/s400/initial_setup.JPG" /></a></div>
<br />
Now we need to create a empty object which we treat as a global gameobject. This object will not be destroyed when first scene is unloaded.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJu-Otr_k229S6uW05h7AslxnLqjvrTbzzB7yyfDv30mxOAsRLWJneDZySnV7xR1ffQoXo_8PCzdHKFi-h84G2qW2D3XGwbuMMWW_mTCIO2GycjxaRP2zJabI3TTRIwUtEua_rtxY4juYz/s1600/create_global_go.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJu-Otr_k229S6uW05h7AslxnLqjvrTbzzB7yyfDv30mxOAsRLWJneDZySnV7xR1ffQoXo_8PCzdHKFi-h84G2qW2D3XGwbuMMWW_mTCIO2GycjxaRP2zJabI3TTRIwUtEua_rtxY4juYz/s400/create_global_go.JPG" /></a></div>
<br />
To preserve this gameobject when First scene is unloading, we need to attach a script, I named it MakeGlobal and added following code to it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJivkcF3U0kr-7hwirrdEN7VgXwV2oT5vkSo2r3PgYft0IIfE1PuI_KtJFjtgBikVrvRsdypKK438EQCCAVl6YiYXgtHpPZs7z_rj8jtZ_svk7R1mknYkjJR3P1LCy0GeK-YZQebHcZG7h/s1600/create_makeglobal_script.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJivkcF3U0kr-7hwirrdEN7VgXwV2oT5vkSo2r3PgYft0IIfE1PuI_KtJFjtgBikVrvRsdypKK438EQCCAVl6YiYXgtHpPZs7z_rj8jtZ_svk7R1mknYkjJR3P1LCy0GeK-YZQebHcZG7h/s400/create_makeglobal_script.png" /></a></div>
<br />
<pre class="prettyprint">using UnityEngine;
using System.Collections;
public class MakeGlobal : MonoBehaviour {
void Awake () {
DontDestroyOnLoad (transform.gameObject);
}
}
</pre>
By using DontDestroyOnLoad, we ask Unity engine not to destroy this gameobject when its scene is getting unloaded, now we can assign a new script to this global gameobject, which holds global variables.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmuUwIoafHSQBpdad7XIsNDAM7UEtvCZKRm76PxUvMbB0-PiQJIFC-5QsktjFguSNb9X_3HUTi5B4ZK-BsnFI8GJiPMv6Q37Y39S2P9KXNmut6kKUaBrdeEE4lY-krCdi-VUCvYACfkcNd/s1600/create_global_variable.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmuUwIoafHSQBpdad7XIsNDAM7UEtvCZKRm76PxUvMbB0-PiQJIFC-5QsktjFguSNb9X_3HUTi5B4ZK-BsnFI8GJiPMv6Q37Y39S2P9KXNmut6kKUaBrdeEE4lY-krCdi-VUCvYACfkcNd/s400/create_global_variable.JPG" /></a></div>
<br />
This script is simple, it just holds a variable which can be accessed from any scene by any game object.
<br />
<br />
<pre class="prettyprint">using UnityEngine;
using System.Collections;
public class GlobalVariables : MonoBehaviour {
public string globalVar;
}
</pre>
<br />
Now we have a GameObject which we can treat as a Global Object and it has a script which holds global variables. But till now we have not used it. To use it we can assign a script to Background element and that assign some value to globalVar variable.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJfmZKL1PprXViVdyhvSU-LviZt1lk1Z8fEWhJyLGh4h1IVnuor7BYxQn3fvXupU1V47M3_BdTe92yEunxAjvXp1DaISTQr_xH5tWw6bpmQteFsD8K2DVoN7PvM-3fmf3Qurc1wVNlTv5r/s1600/script_to_background.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJfmZKL1PprXViVdyhvSU-LviZt1lk1Z8fEWhJyLGh4h1IVnuor7BYxQn3fvXupU1V47M3_BdTe92yEunxAjvXp1DaISTQr_xH5tWw6bpmQteFsD8K2DVoN7PvM-3fmf3Qurc1wVNlTv5r/s400/script_to_background.JPG" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<br />
<pre class="prettyprint">using UnityEngine;
using System.Collections;
public class background : MonoBehaviour {
// Use this for initialization
void Start () {
GameObject globalGO = GameObject.Find("global_gameObject");
GlobalVariables globalVars = globalGO.GetComponent<globalvariables>();
globalVars.globalVar = "String from 1st Scene";
}
}
</globalvariables></pre>
<br />
Now our global variable has value which is assigned by script attached to background object. To see its value on screen I created a 3D Text Object and assigned a simple script which update text object's text to global variable.
<br />
<br />
<pre class="prettyprint">using UnityEngine;
using System.Collections;
public class TextUpdate : MonoBehaviour {
// Update is called once per frame
void Update () {
GameObject globalGO = GameObject.Find("global_gameObject");
GlobalVariables globalVars = globalGO.GetComponent<globalvariables>();
gameObject.GetComponent<textmesh> ().text = globalVars.globalVar;
}
}
</textmesh></globalvariables></pre>
Now if you run first scene, you can see text is displaying global variables value.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOTjPm7Pmp6tpV9nG6HwqDpRGAeCAPZgjMsMkvk4QEGVKl2xP8V46kAfSDwirAF6WGQPyix9pUrqzP6hH437PdiB5ZxaeWfgWPZcAtKd34GU6ldymmGlNXbfhKz80VABTZPrslNHlCgr2T/s1600/first_Scene_running.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOTjPm7Pmp6tpV9nG6HwqDpRGAeCAPZgjMsMkvk4QEGVKl2xP8V46kAfSDwirAF6WGQPyix9pUrqzP6hH437PdiB5ZxaeWfgWPZcAtKd34GU6ldymmGlNXbfhKz80VABTZPrslNHlCgr2T/s1600/first_Scene_running.JPG" height="263" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
To test if global variable really retaining its value, we should create another scene and destroy first scene. So I created a another scene, which has 3D text object which displays global variables value, using the same TextUpdate script. You will can see it still preservs value from first scene and we can use global variable in second scene as well.
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB187k0ape19i5urEsMXOrtNZ9pNnzJuH-ZinaME-JyEo_pyXJ_kODIV1NpDfn234OqY417-jgQB36kKNwnKeHTKvNrBgJm80ZCuw1U_zlpmygJQOonZtJeYD8GYWC2FJnBBV-iXQJzUr6/s1600/second_scene_running.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB187k0ape19i5urEsMXOrtNZ9pNnzJuH-ZinaME-JyEo_pyXJ_kODIV1NpDfn234OqY417-jgQB36kKNwnKeHTKvNrBgJm80ZCuw1U_zlpmygJQOonZtJeYD8GYWC2FJnBBV-iXQJzUr6/s400/second_scene_running.JPG" /></a></div>
<br />
That's all, Thanks for reading my blog.
</div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com3tag:blogger.com,1999:blog-6223976744110856384.post-2675329962188649562014-06-28T04:34:00.002-07:002014-06-28T04:34:28.225-07:00Resolving Folder reading issue from SD Card in BB10<div dir="ltr" style="text-align: left;" trbidi="on">
There was a tricky bug in Audiobook Reader BB10 version for quite a some time which I was trying to resolve. Issue was that, for some folder in SD card, I was not able to browse it using QDir Qt API or Posix API. Though API was showing the folder, but when I try to find out folder's content, it reports folder as empty. <br /><br />
This was causing serious usability issue with Audiobook Reader application, as user were not able to add book from SD card. I debugged it long and tried to use various approach to resolve the issue but could not find any satisfactory solution.<br /><br />
I read it somewhere it causes issue if SD card was formatted with PC software and issue is resolved if you format SD card with BB10 setting. But this also looks hassle to user.<br /><br />
Finally, I decided to see how directory structure looks like and what is folders permission using SSH to device. When I used linux command like ls and cd, I was able to see folder's content fine. And I decide to use those command to resolve directory browsing issue.
<br /><br />
Following is my code, if someone else is also facing similar issue. First I am escaping special character in filepath, else linux command will not work. Then I am creating "ls" command with sorting and with output which list directory content in absolute file path. Once we have proper command I am using popen API to run command and then using IO api to read command's output.
<br />
<pre class="prettyprint">QStringList BookListModel::getFileList(const QString& dir) {
QString filePath(dir);
filePath.replace(" ","\\ ");
filePath.replace("'","\\'");
filePath.replace("`","\\`");
filePath.replace("!","\\!");
filePath.replace("$","\\$");
filePath.replace("&","\\&");
filePath.replace("*","\\*");
filePath.replace("\"","\\\"");
filePath.replace("(","\\(");
filePath.replace(")","\\)");
filePath.replace("[","\\[");
filePath.replace("]","\\]");
qDebug() << filePath;
QString cmd = QString("ls -1 %1/*").arg(filePath);
qDebug() << cmd;
QStringList files;
char path[1035];
FILE* fp = popen(cmd.toStdString().c_str(), "r");
if (fp == NULL) {
qDebug() << "Failed to run command";
return files;
}
while (fgets(path, sizeof(path)-1, fp) != NULL) {
QString file = QString(path).trimmed();
QFileInfo fileInfo(file);
if (fileInfo.isFile() && FileModel::isSupportedMedia(fileInfo.fileName()) ){
files << file;
}
}
qDebug() << files;
pclose(fp);
}
</pre>
That's all, hope it will be helpful to someone.
</div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com2tag:blogger.com,1999:blog-6223976744110856384.post-26133723413978830482014-06-26T07:17:00.000-07:002014-06-26T07:17:24.093-07:00Audiobook Reader for BB10 now got Built for Blackberry status<div dir="ltr" style="text-align: left;" trbidi="on">
Recently I upgraded my Audiobook Reader application pro version for BB10.<br />
<br />
This version contains many UI related changes and now it is more aligned to Blackberry design guideline and now it is also awarded Built for Blackberry status.
<br />
<br />
Apart form UI related changes, this version contains two major changes.
<br />
<br />
Now it Book auto pauses in case it detect phone call activity.
<br />
<br />
And there was a very critical bug in application which prevents book to be added from SD card. Though issue was related to BB10 OS, I found one work around and now adding books from SD card works as expected.
<br />
<br />
Full list of features in current version is as below.
<br />
<ul>
<li>
Allows adding single file or whole folder with book audio data</li>
<li>
Supports adding custom bookmark</li>
<li>
Supports browsing mp3 chapter files and play selected mp3 chapter file</li>
<li>
Supports chapter skip</li>
<li>
Supports 2 min, 1 min, 30 sec skip option</li>
<li>
Supports auto pause on call</li>
<li>
Supports Play/Pause using HW buttons</li>
<li>
Supports custom cover art download</li>
<li>
Advance file browser</li>
<li>
Supports sleep timer</li>
<li>
Supports shuffle</li>
<li>
and some more...</li>
</ul>
Following is demo for current version.<br />
<br />
<object height="315" width="420"><param name="movie" value="//www.youtube.com/v/9cORHuNkQ1E?hl=en_US&version=3&rel=0"></param>
<param name="allowFullScreen" value="true"></param>
<param name="allowscriptaccess" value="always"></param>
<embed src="//www.youtube.com/v/9cORHuNkQ1E?hl=en_US&version=3&rel=0" type="application/x-shockwave-flash" width="420" height="315" allowscriptaccess="always" allowfullscreen="true"></embed></object>
<br />
Hope you will like the updates.
</div>
Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com8tag:blogger.com,1999:blog-6223976744110856384.post-89807266924179189002014-06-12T18:35:00.000-07:002014-06-12T18:35:13.215-07:00Using WorkerScript from QML<div dir="ltr" style="text-align: left;" trbidi="on">
As you might know, I am contributing to Ubuntu Touch Calendar core application. Those application are pure QML application with no C++ backend or we aim to avoid it as much as possible. This is done to make sure application are portable across device.<br />
<br />
For simple use-case you can just use javascript code as backend logic and it should work fine without any problem. but if you need to some intensive calculation in application then its better to move those calculation to WorkerScript.
<br />
<br />
While working on one calendar feature, Calculating layout for overlapping events, I also needed to use WorkerScript.
But one major problem with WorkerScript is that, it does not have access to QML Engine.
So you will not be able to send your Declarative object to worker script to offload intensive task to threads.<br />
<br />
In calendar application I am getting Events declarative object from model and I needed to process events time to decide position and size of events in view.
<br />
<br />
As such I can not send those Events to WorkerScript, but to overcome that limitation, I created temporary Javascript object which has required data like start time, end time and id, which I can use to decide position, size and Id can be used to map temp object to original object from model and rest of logic then can be implemented in WorkerScript.<br />
<br />
Code wise using WorkerScript is quite easy. Following code creates WorkerScript object and sends array of events to script.
<br />
<pre class="prettyprint">
WorkerScript {
id: eventLayoutHelper
source: "EventLayoutHelper.js"
onMessage: {
//recevied process data, which we can use to layout events
layoutEvents(messageObject.schedules);
}
}
function createEvents() {
var eventMap = {};
var allSchs = [];
var startDate = new Date().midnight();
var endDate = new Date().endOfDay();
var items = model.getItems(startDate,endDate);
for(var i = 0; i < items.length; ++i) {
var event = items[i];
var schedule = {"startDateTime": event.startDateTime, "endDateTime": event.endDateTime,"id":event.itemId };
allSchs.push(schedule);
eventMap[event.itemId] = event;
}
intern.eventMap = eventMap;
//here we are asking worker script to process all the events
eventLayoutHelper.sendMessage(allSchs);
}
</pre>
<br />
Following is script code, it will process these events and will send back location and size information back.
<pre class="prettyprint">
WorkerScript.onMessage = function(events) {
//do some pre-processing like sorting and converting the data type more comfortable to algorithm
var allSchs = processEvents(events);
while( allSchs.length > 0) {
var sch = allSchs.shift();
//finds all schedules overlapping with current schedule and remove from original array
var schs = findOverlappingSchedules(sch, allSchs);
//insert original schedule first, so array remain sorted
schs.unshift(sch);
//send processed events back to GUI thread so we can render it
WorkerScript.sendMessage({ 'schedules': schs});
}
}
</pre>
</div>Anonymoushttp://www.blogger.com/profile/18433786928656006467noreply@blogger.com0