#serialization with Strict Open XML
Explore tagged Tumblr posts
Text
Strict Open XML Format Support & Get Effects by Text-box Paragraphs inside .NET Apps
What's New in this Release?
Aspose team is happy to share the announcement of Aspose.Slides for .NET 18.10. This is primarily a maintenance release whereby Aspose team has resolved certain issues incurring in API. It has introduced Support for rendering shape Soft Edges (EffectFormat) effect and enhanced Turning off updates automatically option for Date time in PPT while converting to PDF. There are some important enhancements and bug fixes part of this release, such as Connector fails to draw in straight line, Shadows effects are lost in generated PDF and thumbnail, Ink pen drawing is missing in the PDF output, Exception on cloning Fonts, Soft Edges effect on image are missing in exported PDF, Y axis interval in the chart has been changed, When PPTX is converted to PDF, item is missing in pie chart, Export to SVG corrupts if made repeatedly, PPT not properly converted to PDF, Exception on converting PPTX to PDF, Background image color changes in exported PDF and many more. This list of new, improved and bug fixes in this release are given below
Support for rendering shape Soft Edges (EffectFormat) effect.
Turning off updates automatically option for Date time in PPT while converting to PDF.
Connector fails to draw in straight line.
Shadows effects are lost in generated PDF and thumbnail.
Ink pen drawing is missing in the PDF output.
Exception on cloning Fonts.
Soft Edges effect on image are missing in exported PDF.
The blue underline is missing after conversion to the image (PNG).
Y axis interval in the chart has been changed.
When converting PPTX to PDF, chart lines are different and overlapping the text..
When PPTX is converted to PDF, item is missing in pie chart..
Aspose.Slides fails to re-open ODP presentation, saved with Aspose.Slides.
Argument exception on generating PDF Notes.
Export to SVG corrupts if made repeatedly.
Grayscale image rendered colored in generated thumbnail.
ArgumentOutOfRangeException on loading PPTX.
The footer’s font has changed after loading and saving.
Some characters in vertical text are rotated to wrong layout in a PDF format.
PPTX/PPT not properly converted to PDF.
Uknown Field type returned for Field.
Exception on loading presentation.
PPTX not properly saved to PPTX.
Connector draws wrong.
PPT not properly converted to PDF.
Overlapping text portions in PDF with custom fonts.
Exception on loading the presentation.
Charts are missing in exported PDF.
Cloud shape is improperly rendered in generated thumbnail.
Exception on loading the presentation.
Background image color changes in exported PDF
Exception on converting PPTX to PDF.
Other most recent bug fixes are also included in this release
Newly added documentation pages and articles
Some new tips and articles have now been added into Aspose.Slides for Java documentation that may guide users briefly how to use Aspose.Slides for performing different tasks like the followings.
Converting Presentation to HTML
Converting ODP PPT to PPTX
Overview: Aspose.Slides for .NET
Aspose.Slides is a .NET component to read, write and modify a PowerPoint document without using MS PowerPoint. PowerPoint versions from 97-2007 and all three PowerPoint formats: PPT, POT, PPS are also supported. Now users can create, access, copy, clone, edit and delete slides in their presentations. Other features include saving PowerPoint slides into PDF, adding & modifying audio & video frames, using shapes like rectangles or ellipses and saving presentations in SVG format, streams or images.
More about Aspose.Slides for .NET
Homepage of Aspose.Slides for .NET
Downlaod of Aspose.Slides for .NET
Online documentation of Aspose.Slides for .NET
#Strict Open XML format support#serialization with Strict Open XML#get effects by text-box paragraphs#set Callout for Doughnut chart#PPTX to PDF Export#.NET PowerPoint API
0 notes
Text
The New iTunes Podcast RSS Tags
Last Friday, Apple announced some additional XML tags that it will support in podcast RSS feeds. Here’s the video of the session where the tags were announced and here’s a PDF explaining each tag.
First, lets give Apple some credit — these features could have been built into their Podcast Connect backend, which would have brought podcasting further under its control. Apple instead chose to extend open RSS feeds. This is an encouraging signal for third party podcast app makers and for anyone else who cares about the openness of the podcasting ecosystem.
News Podcasts and Story Podcasts
The majority of podcasts can be categorized as news-type shows. Some clear examples of this are Pod Save America’s political analysis, The Talk Show’s Apple discussions and Football Weekly’s soccer coverage. Listeners of these shows are not expected to know the context provided by previous episodes, and the most recent episode is the most relevant. Apple refers to these as "episodic" which is ambiguous, but I'm going to stick to their terminology for the rest of this post.
There is another type that is less common but still important: story-type shows. Some of the most successful podcasts in the last few years have been story-type shows, which are much more like a TV series than a news show. Serial and S-Town are the obvious examples. Listeners of these shows are expected to listen in order, starting from the first episode. Apple calls these "serial" podcasts.
Every podcast app I’ve tried treats every podcast like an episodic one. When you first subscribe, episodes that are older than the most recent one are marked as played. They’re not actually played, but this shortcut taken by app makers has persisted for years and is now a part of how podcast apps are expected to work. Castro is strict about the meaning of “played”, so older episodes go in the archive instead of being marked as played but the effect here is the same; older episodes are de-emphasized. The one token gesture towards serial shows in Castro is on the subscribe screen, Castro shows the oldest and newest episodes for easy queuing if you do intend to listen from the start. This helps, but it doesn’t add up to solid serial podcast support.
One of the challenges for podcast apps in accommodating serial shows is that there’s no way for podcasters to signal that their show is meant to be listened sequentially. App makers could build a serial workflow but it would require every user to understand what that is and then each user would have to toggle a setting for each relevant subscription. Users rarely change default settings so its unlikely that this feature would be used even where appropriate.
What do the new tags do?
These new tags provide a means for podcasters to indicate directly in the feed that a podcast is an episodic podcast or a serial podcast. This gives podcast app makers all the information they need to handle these shows correctly without user intervention.
Additionally these tags allow podcasters to explicitly assign season numbers and episode numbers, and to distinguish bonus or trailer episodes from full episodes.
With this information, apps will be able to:
pick the correct starting point when a user subscribes to a serial podcast.
provide appropriate auto-queue behaviour for serial podcasts.
highlight and play trailer episodes for users who are browsing to help them decide if they want to subscribe.
The new tags in practice
What about other podcast types?
There’s a third type of podcast that is not well served by either the episodic or the serial approach. A good example is In Our Time which is made up of hundreds of interviews with experts on various historical people and events. The relevant factor for deciding whether to listen is the episode’s topic. An episode from 5 years ago may be more relevant to your interests than one published today. It’s a shame that podcast apps bury these older episodes. Perhaps there is an opportunity to add a third type that identifies these shows separately?
Should bonus episodes get season/episode numbers?
While integrating the parsing of these tags to our server, I picked one serial podcast feed (Serial) and manually added the tags myself. A number of questions arose about how to use the tags:
The Serial podcast feed includes three episodes during season two that don’t progress the season story, but instead provide updates on the events of season one. Of the three possible episode types (full, bonus, trailer). It makes sense to me to consider these to be bonus episodes.
The three bonus episodes have a preferred order for playback, so it also makes sense that they should have episode numbers.
Which season should they belong to? They relate to season one content, but were published during season two. Should they be their own season?
If they’re in season one or two, what are their episode numbers?
Update: I filed rdar://33007101 about this
How should trailers be handled?
The feed also contains a preview and a trailer for a different podcast called S-Town. These should reasonably be classified as trailers, but they’re not trailers for the current show. If a podcast app assumes that a trailer episode provides a preview of the show in question, it’ll be playing the S-Town trailer on the Serial podcast.
Should trailers have season numbers?
How should a podcast app handle multiple trailers in a feed?
There are a range of acceptable answers to these questions but the point is that podcasters will need to think through these decisions carefully because their choices will affect the display of their episodes. If there’s too much ambiguity, it’ll be hard for podcast apps to do the right thing in all cases. Over the next few years I expect that some best-practises will evolve.
Update: I filed rdar://33006962 about this
Conclusion
It became clear to me even when considering Serial, which is perhaps, the canonical example of a serial podcast feed, that there were a number of questions about how best to choose values for these new tags.
Podcasters should start thinking about answering these questions and adding these tags to their feeds right away. Even episodic podcasts will benefit from the episodeTypes and explicit episode numbers. This will allow app makers to start building features that take advantage of them and understanding any unexpected usage.
I finished integrating the new tags into our aggregator yesterday, and it has already found a podcast that uses them: The Incomparable’s “This Week in Time Travel” uses the new episode number, title and episodeType tags. Well done Incomparable people. 1 down, 399,999 more podcasts to go!
2 notes
·
View notes
Text
How to Save and Load a Game in Unity
Games are getting longer and longer, with some having over 100 hours of content. It would be impossible to expect players be able to complete all of what a game has to offer in just one sitting. That’s why letting the player save their game is one of the most essential features your game should have — even if it’s just to keep track of their high scores.
But how does one create a save file and what should be in it? Do you need to use a save file to keep track of player settings too? What about submitting saves to the web so they can be downloaded later on a different device?
In this tutorial you will learn:
What serialization and deserialization are.
What PlayerPrefs is and how to use it to save player settings.
How to create a save game file and save it to disk.
How to load a save game file.
What JSON is and how you would use it.
It is assumed that you have some basic working knowledge of how Unity works (such as being able to create and open scripts), but other than that everything has been prepared so this tutorial will be very easy to follow. Even if you are new to C#, you should have no trouble keeping up except for a few concepts that might require further reading.
Note: If you are new to Unity or looking to pick up more Unity skills, you should checkout out our other Unity tutorials where you can learn about lots of Unity topics from C# to how the UI works.
Getting Started
Download the starter project here. You will be implementing the code for saving and loading the game, as well as the logic for saving the players settings.
Important Save Concepts
There are four key concepts to saving in Unity:
PlayePrefs: This is a special caching system to keep track of simple settings for the player between game sessions. Many new programmers make the mistake of thinking they can use this as a save game system as well, but it is bad practice to do so. This should only be used for keeping track of simple things like graphics, sound settings, login info, or other basic user-related data.
Serialization: This is the magic that makes Unity work. Serialization is the conversion of an object into a stream of bytes. That might seem vague but take a quick look at this graphic:
What is an “object”? In this case an “object” is any script or file in Unity. In fact, whenever you create a MonoBehaviour script, Unity uses serialization & deserialization to convert that file down to C++ code and then back to the C# code that you see in the inspector window. If you’ve ever added [SerializeField] to get something to appear in the inspector, you now have an idea of what’s going on.
Note: If you’re a Java or web developer, you might be familiar with a concept known as marshalling. Serialization and marshalling are loosely synonymous, but in case you’re wondering what a strict difference would be, serialization is about converting an object from one form to another (e.g. an object into bytes), whereas marshalling is about getting parameters from one place to another.
Deserialization: This is exactly what it sounds like. It’s the opposite of serialization, namely the conversion of a stream of bytes into an object.
JSON: This stands for JavaScript Object Notation, which is a convenient format for sending and receiving data that is language agnostic. For example, you might have a web server running in Java or PHP. You couldn’t just send a C# object over, but you could send a JSON representation of that object and let the server recreate a localized version of it there. You’ll learn more about this format in the last section but for now just know that this simply a way of formatting data to make it multi-platform readable (like XML). When dealing with converting to and from JSON, the terms are JSON serialization and JSON deserialization respectively.
Player Prefs
This project has been set up so that all you will focus on is the logic for saving and loading games. However, if you are curious how it all works, don’t be afraid to open all the scripts and see whats going on, and feel free to ask a question here or in the forums if you need help.
Open the project, then open the Scene named Game and then click play.
To start a game, click the New Game button. To play the game, you simply move your mouse, and the gun will follow your movement. Click the left mouse button to fire a bullet and hit the targets (which flip up and down at various time intervals) to get points. Try it out and see how high a score you can get in 30 seconds. To bring up the menu at any time, press the escape key.
As fun as that game was, it might have been a little dry without music. You may have noticed that there is a music toggle, but it was switched off. Click play to start a new game, but this time click the Music toggle so it’s set to “On”, and you will hear music when you start your game. Make sure your speakers are on!
Changing the music setting was simple, but click the play button again and you’ll notice a problem: the music is no longer checked. While you did change the music setting earlier, there was nothing keeping track of that change. This is the kind of thing that PlayerPrefs excels at.
Create a new script named PlayerSettings in the Scripts folder. Since you’ll be using some UI elements, add the following line at the top of the file with the other namespaces:
using UnityEngine.UI;
Next, add the following variables:
[SerializeField] private Toggle toggle; [SerializeField] private AudioSource myAudio;
These will keep track of the Toggle and AudioSource objects.
Next add the following function:
public void Awake () { // 1 if (!PlayerPrefs.HasKey("music")) { PlayerPrefs.SetInt("music", 1); toggle.isOn = true; myAudio.enabled = true; PlayerPrefs.Save (); } // 2 else { if (PlayerPrefs.GetInt ("music") == 0) { myAudio.enabled = false; toggle.isOn = false; } else { myAudio.enabled = true; toggle.isOn = true; } } }
When set up, this will:
Check if the PlayerPrefs has a cached setting for the ���music” key. If there is no value there, it creates a key-value pair for the music key with a value of 1. It also sets the toggle to on and enables the AudioSource. This will be run the first time the player runs the game. The value of 1 is used because you cannot store a Boolean (but you can use 0 as false and 1 as true).
This checks the “music” key saved in the PlayerPrefs. If the value is set to 1, the player had music on, so it enables the music and sets the toggle to on. Otherwise, it sets the music to off and disables the toggle.
Now Save the changes to your script and return to Unity.
Add the PlayerSettings script to the Game GameObject. Then expand the UI GameObject, followed by the Menu GameObject to reveal its children. Then drag the Music GameObject on to the Toggle field of the PlayerSettings script. Next, select the Game GameObject and drag the AudioSource over to the MyAudio field.
<
The music is set up to work when the game runs (since there is code in the Awake function), but you still need to add the code if the player changes the setting during gameplay. Open the PlayerSettings script and add the following function:
public void ToggleMusic() { if (toggle.isOn) { PlayerPrefs.SetInt ("music", 1); myAudio.enabled = true; } else { PlayerPrefs.SetInt ("music", 0); myAudio.enabled = false; } PlayerPrefs.Save (); }
This does almost the same as the code you wrote earlier, except it has one important difference. It checks the state of the music toggle and then updates the saved setting accordingly. In order for this method to be called, and thus for it to be able to do its work, you need to set the callback method on the Toggle GameObject. Select the Music GameObject and drag the Game GameObject over the object field in the OnValueChanged section:
Select the dropdown which currently says No Function, and select PlayerSettings -> ToggleMusic(). When the toggle button in the menu is pressed, it will call the ToggleMusic function.
Now you’ve got things set up to keep track of the music setting. Click Play and try it out by setting the music toggle to on or off, then ending the play session and starting a new play session.
The music setting is now properly saved! Great job — but you’re only getting started with the power of serialization.
Saving The Game
Using PlayerPrefs was pretty simple wasn’t it? With it, you will be able to easily store other settings in there such as the player’s graphic settings, or login info (perhaps Facebook or Twitter tokens), and whatever other configuration settings make sense to keep track of for the player. However, PlayerPrefs is not designed to keep track of game saves. For that, you will want to use serialization.
The first step to creating a save game file is creating the save file class. Create a script named Save and remove the MonoBehaviour inheritance. Remove the default Start() and Update() methods as well.
Next, add the following variables:
public List<int> livingTargetPositions = new List<int>(); public List<int> livingTargetsTypes = new List<int>(); public int hits = 0; public int shots = 0;
In order to save the game you will need to keep track of where existing robots are and what types they are. The two lists accomplish this. For the number of hits and shots you are just going to store those as ints.
There is one more very important bit of code you need to add. Above the class declaration, add the following line:
[System.Serializable]
This is known as an attribute and it is metadata for your code. This tells Unity that this class can be serialized, which means you can turn it into a stream of bytes and save it to a file on disk.
Note: Attributes have a wide range of uses and let you attach data to a class, method, or variable (this data is known as metadata). You can even define your own attributes to use in your code. Serialization makes use of the [SerializeField] and [System.Serializable] attributes so that it knows what to write when serializing the object. Other uses for attributes include settings for unit tests and dependency injection, which are way beyond the scope of this tutorial but well worth investigating.
The entire Save script should look like this:
using System.Collections; using System.Collections.Generic; using UnityEngine; [System.Serializable] public class Save { public List<int> livingTargetPositions = new List<int>(); public List<int> livingTargetsTypes = new List<int>(); public int hits = 0; public int shots = 0; }
Next, open the Game script and add the following method:
private Save CreateSaveGameObject() { Save save = new Save(); int i = 0; foreach (GameObject targetGameObject in targets) { Target target = targetGameObject.GetComponent<Target>(); if (target.activeRobot != null) { save.livingTargetPositions.Add(target.position); save.livingTargetsTypes.Add((int)target.activeRobot.GetComponent<Robot>().type); i++; } } save.hits = hits; save.shots = shots; return save; }
This code creates an instance of the Save class you made earlier and then sets the values from the existing robots. It also saves the players shots and hits.
The Save button has been hooked up to the SaveGame method in the Game script, but there is no code in SaveGame yet. Replace the SaveGame function with the following code:
public void SaveGame() { // 1 Save save = CreateSaveGameObject(); // 2 BinaryFormatter bf = new BinaryFormatter(); FileStream file = File.Create(Application.persistentDataPath + "/gamesave.save"); bf.Serialize(file, save); file.Close(); // 3 hits = 0; shots = 0; shotsText.text = "Shots: " + shots; hitsText.text = "Hits: " + hits; ClearRobots(); ClearBullets(); Debug.Log("Game Saved"); }
Taking it comment-by-comment:
Create a Save instance with all the data for the current session saved into it.
Create a BinaryFormatter and a FileStream by passing a path for the Save instance to be saved to. It serializes the data (into bytes) and writes it to disk and closes the FileStream. There will now be a file named gamesave.save on your computer. The .save was just used as an example, and you could use any extension for the file save name.
This just resets the game so that after the player saves, everything is in a default state.
To save the game, press Escape at any time during play and click the Save button. You should notice everything resets and the console output displays a note that the game has been saved.
LoadGame in the Game script is connected to the Load button. Open the Game script and locate the LoadGame function. Replace it with the following:
public void LoadGame() { // 1 if (File.Exists(Application.persistentDataPath + "/gamesave.save")) { ClearBullets(); ClearRobots(); RefreshRobots(); // 2 BinaryFormatter bf = new BinaryFormatter(); FileStream file = File.Open(Application.persistentDataPath + "/gamesave.save", FileMode.Open); Save save = (Save)bf.Deserialize(file); file.Close(); // 3 for (int i = 0; i < save.livingTargetPositions.Count; i++) { int position = save.livingTargetPositions[i]; Target target = targets[position].GetComponent<Target>(); target.ActivateRobot((RobotTypes)save.livingTargetsTypes[i]); target.GetComponent<Target>().ResetDeathTimer(); } // 4 shotsText.text = "Shots: " + save.shots; hitsText.text = "Hits: " + save.hits; shots = save.shots; hits = save.hits; Debug.Log("Game Loaded"); Unpause(); } else { Debug.Log("No game saved!"); } }
Looking at this in detail:
Checks to see that the save file exists. If it does, it clears the robots and the score. Otherwise it logs to the console that there is no saved game.
Similar to what you did when saving the game, you again create a BinaryFormatter, only this time you are providing it with a stream of bytes to read instead of write. So you simply pass it the path to the save file. It creates the Save object and closes the FileStream.
Even though you have the save information, you still need to convert that into the game state. This code loops through the saved robot positions (for living robots) and adds a robot at that position. It also sets it to the right type. For simplicity, the timers are reset, but you can remove this if you prefer. This prevents the robots from disappearing right away and gives the player a few seconds to get oriented in the world. Also, for simplicity, the animation of the robot moving up is set to finished, which is why robots partly moving up when you saved will be shown as fully up when a game is loaded.
This updates the UI to have the right hits and shots set, and it sets the local variables so that when the player fires or hits a target it continues to count up on the value that was previously. If you didn’t do this step, the next time the player fires or hits a target the displayed values would get set to 1.
Click Play, play the game for a bit then save. Click the Load button and you will see it load the enemies as they were set up before when you saved the game. It also properly sets your score and the shots you’ve fired.
Saving Data With JSON
There’s one more trick you can use when you want to save data — and that is JSON. You could create a local JSON representation of your game save, send it to a server, then get that JSON (as a String) to another device and convert it from a string back to JSON. This tutorial won’t cover sending/receiving from the web, but it is very helpful to know how to use JSON — and it’s incredibly simple.
The format of JSON can be a little different than what you might be used from C# code, but it’s pretty straightforward. Here is a simple JSON example:
{ "message":"hi", "age":22 "items": [ "Broadsword", "Bow" ] }
The outer brackets represent the parent entity that is the JSON. If you are familiar with a Dictionary data structure, then JSON is similar. A JSON file is a mapping of key and value pairs. So the above example has 3 key-value pairs. With JSON, the keys are always strings, but the values can be objects (i.e. children JSON objects), arrays, numbers, or strings. The value set to the “message” key is “hi”, the value of the “age” key is the number 22, and the value of the “items” key is an array with two strings in it.
The JSON object itself is represented by a String type. By passing this data as a String, any language can easily re-create JSON object from the string as a constructor argument. Very convenient and very simple.
Each language has its own way of creating an object from this format. Since Unity 5.3, there exists a native method to create a JSON object from a JSON string. You will create a JSON representation of the high score of the player and then print it to the console. But you extend this logic by sending the JSON to a server.
The Game script has a method named SaveAsJSON that is hooked up to the Save As JSON button. Replace SaveAsJSON with the following code:
public void SaveAsJSON() { Save save = CreateSaveGameObject(); string json = JsonUtility.ToJson(save); Debug.Log("Saving as JSON: " + json); }
This creates the Save instance like you did earlier. Then it creates a JSON string using the ToJSON method on the JsonUtility class. It then prints the output to console.
Start a game, hit a few targets, then press Escape to bring up the menu. Click the Save As JSON button, and you will see the JSON string you created:
If you want convert that JSON into a Save instance you would simply use:
Save save = JsonUtility.FromJson<Save>(json);
That is what you would do if you wanted to download a save file from the web and then load it into your game. But setting up a web server is a whole other process! For now, pat yourself on the back because you just learned a few techniques that will… save you some trouble in your next game (groan)!
Where to Go From Here?
You can download the final project files here.
You’ve now gained a powerful tool for creating great games by enabling your players to save and load their game through the magic of serialization. You’ve also learned what JSON is and how you could use it to implement cloud saving. You’ve also learned what PlayerPrefs is used for (settings!), and what it’s not used for (saving the game).
If you’re looking to get more rounded in Unity, we have a whole section of Unity tutorials over here, and you’re welcome to join us on the Unity forums. You can always leave a comment here if you have anything you’d like to say.
If you are a die-hard Unity fan and want to become a full fledged developer, then check out our book Unity Games by Tutorials where you will make 4 complete games from scratch. One of the chapters even goes over how to use JSON as a level loader!
If you have any questions or comments on this tutorial, please join the discussion below!
The post How to Save and Load a Game in Unity appeared first on Ray Wenderlich.
How to Save and Load a Game in Unity published first on http://ift.tt/2fA8nUr
0 notes