[null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5aedb1256d2a73f6d2efaca2/1525526828342/buygum5.png", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5aedb1256d2a73f6d2efaca2/1525526828342/buygum5.png", "formatted_filename": "buygum", "alt_text": "buygum5.png"}, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78aec/1522011025051/nurbsCurve_create.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78aec/1522011025051/nurbsCurve_create.jpg", "formatted_filename": "nurbsCurve create", "alt_text": " Creating a nurbs Curve. "}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78aee/1522011838259/cirxcleAbstract.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78aee/1522011838259/cirxcleAbstract.jpg", "formatted_filename": "cirxcleAbstract", "alt_text": " Nurbs Circle options "}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78af0/1523297334919/curvePlacement.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78af0/1523297334919/curvePlacement.jpg", "formatted_filename": "curvePlacement", "alt_text": " Curve placement. The head is hidden for clarity purposes. "}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78af2/1523303735850/clusters.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78af2/1523303735850/clusters.jpg", "formatted_filename": "clusters", "alt_text": " Creating clusters "}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78af4/1523304519379/cluster_groups.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78af4/1523304519379/cluster_groups.jpg", "formatted_filename": "cluster groups", "alt_text": "cluster_groups.jpg"}, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78af8/1524083039669/collisionCapsule.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78af8/1524083039669/collisionCapsule.jpg", "formatted_filename": "collisionCapsule", "alt_text": "collisionCapsule.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78afa/1524324344492/keepOutNodes.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78afa/1524324344492/keepOutNodes.jpg", "formatted_filename": "keepOutNodes", "alt_text": "keepOutNodes.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78afc/1524325766870/keepOutNodes_outliner.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78afc/1524325766870/keepOutNodes_outliner.jpg", "formatted_filename": "keepOutNodes outliner", "alt_text": "keepOutNodes_outliner.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78afe/1524606748276/rightSideCollision.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78afe/1524606748276/rightSideCollision.jpg", "formatted_filename": "rightSideCollision", "alt_text": "rightSideCollision.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78b00/1524608510372/leftSideCollision.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78b00/1524608510372/leftSideCollision.jpg", "formatted_filename": "leftSideCollision", "alt_text": "leftSideCollision.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78b02/1524609392822/backcenterCollision.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1bd97758d46b32ee78b02/1524609392822/backcenterCollision.jpg", "formatted_filename": "backcenterCollision", "alt_text": "backcenterCollision.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae213b688251b476efe9422/1524765633813/connectMuscles.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae213b688251b476efe9422/1524765633813/connectMuscles.jpg", "formatted_filename": "connectMuscles", "alt_text": "connectMuscles.jpg"}, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1fb7ff950b7a94f3ff2d0/1524759438513/joints.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae1fb7ff950b7a94f3ff2d0/1524759438513/joints.jpg", "formatted_filename": "joints", "alt_text": "joints.jpg"}, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae20eae88251bff9db75000/1524764398355/POCInodesAll.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae20eae88251bff9db75000/1524764398355/POCInodesAll.jpg", "formatted_filename": "POCInodesAll", "alt_text": "POCInodesAll.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae21a918a922d341eabcff6/1524767389095/jointsPlacement.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae21a918a922d341eabcff6/1524767389095/jointsPlacement.jpg", "formatted_filename": "jointsPlacement", "alt_text": "jointsPlacement.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae22b39575d1f5a7ab0acff/1524771647806/bindJoints.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5ae22b39575d1f5a7ab0acff/1524771647806/bindJoints.jpg", "formatted_filename": "bindJoints", "alt_text": "bindJoints.jpg"}, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5a17f2520d92971bbc92a1c6/1511518832752/saleCubebrush.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5a17f2520d92971bbc92a1c6/1511518832752/saleCubebrush.jpg", "formatted_filename": "saleCubebrush", "alt_text": "saleCubebrush.jpg"}, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5900696ac149d3cb91ce9837/1493199211842/rfst_thumb.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/5900696ac149d3cb91ce9837/1493199211842/rfst_thumb.jpg", "formatted_filename": "rfst thumb"}, null, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/547b646ae4b0d64f97a8dbb5/1417372778688/stretchIK.png", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/547b646ae4b0d64f97a8dbb5/1417372778688/stretchIK.png", "formatted_filename": "stretchIK", "alt_text": "stretchIK.png"}, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/547b6f70e4b06290cab42534/1417375600897/stretchIkProperties.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/t/547b6f70e4b06290cab42534/1417375600897/stretchIkProperties.jpg", "formatted_filename": "stretchIkProperties", "alt_text": "stretchIkProperties.jpg"}, null, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464bebae4b02b973b9be953/5464bebce4b05e55eca132f6/1415888572316/gdc_talk_me.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464bebae4b02b973b9be953/5464bebce4b05e55eca132f6/1415888572316/gdc_talk_me.jpg", "formatted_filename": "gdc talk me", "alt_text": "gdc_talk_me.jpg"}, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464bebae4b02b973b9be953/5464bebee4b028d73fce3fa6/1415888574688/Presentation_ryse-characters.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464bebae4b02b973b9be953/5464bebee4b028d73fce3fa6/1415888574688/Presentation_ryse-characters.jpg", "formatted_filename": "Presentation ryse characters", "alt_text": "Presentation_ryse-characters.jpg"}, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464bebae4b02b973b9be953/5464bebce4b05e55eca132f6/1415888572316/gdc_talk_me.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464bebae4b02b973b9be953/5464bebce4b05e55eca132f6/1415888572316/gdc_talk_me.jpg", "formatted_filename": "gdc talk me", "alt_text": "gdc_talk_me.jpg"}, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464bebae4b02b973b9be953/5464bebee4b028d73fce3fa6/1415888574688/Presentation_ryse-characters.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464bebae4b02b973b9be953/5464bebee4b028d73fce3fa6/1415888574688/Presentation_ryse-characters.jpg", "formatted_filename": "Presentation ryse characters", "alt_text": "Presentation_ryse-characters.jpg"}, null, null, null, {"document_url": "http://www.rihamtoulan.com/blog", "unformatted_src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464ba65e4b0e9de37662935/59f29030652deaab9522eda8/1509070330886/markingMenu.jpg", "src": "https://static1.squarespace.com/static/53e3e118e4b019d919160e6d/5464ba65e4b0e9de37662935/59f29030652deaab9522eda8/1509070330886/markingMenu.jpg", "formatted_filename": "markingMenu", "alt_text": "Space Switch Tool 1.0 for Maya"}, null]
Hi guys, almost a month ago I posted this rig test for a collsion setup I made for a character I was working on. The rig is joints based, therefore would be suitable for game animations. I couldn't use the same asset but I created another one for the purposes of this tutorial.

A basic knowledge of maya and rigging in is required. This is not a rigging and rigging practices tutorial, it is made specifically to cover the technique of using cMuscleKeepOut nodes in Maya. So feel free to take it and conform it to whatever practices and naming conventions you normally use in your rigging process.

I will break this post into 3 main sections. The curve setup, the collision setup and the joints setup. But before we proceed this is how the rig should look like in the end.

You can purchase the work files for $5 on Gumroad Kiel Figgins kindly pointed out that the MayaMuscle plugin is not loaded by default in some cases so make sure you load the MayaMuscle.mll plugin in the Plug-in Manager. Loading the MayaMuscle plugin.

The Curve Setup

1 - Create a nurbs circle with 8 spans and name it "collar_crv". Creating a nurbs Curve. Nurbs Circle options

2 - Shape the curve along th einside o the collar. The curve vertices are the points of contact with our collision mesh so make sure they are placed where you would want the collision to happen. Curve placement. The head is hidden for clarity purposes.

3 - Create a cluster for every vertix of the "collar_crv". In the riggging tab go to Deform>Cluster. Creating clusters

4 - We need an offset group for each cluster. Press CTRL+G the short cut for creating an empty group. Then select the group and the cluster and go to Modify>Match Transformations>Match All Transforms. Now the group is snapped to the cluster, you can parent the cluster to the group by selecting the clusterHandle and the group and press P or go to Edit>parent. The Collision Setup

5 - Now we create our collision mesh. Most of the time I use Polygon primitives as collision shapes like a cylinder or a sphere, but in this case I will use a static duplicate of the head mesh and delete the faces I don't need to collide with the curve. Then parent the collision mesh to the neck driver. For demonstration I just parented it under the joint directly.

I chose in this case to use a duplicate of the head because his chin is quite prominant and it would be nice to have it collide against the collar. 6 - The last step for creatig our collision mesh is to selet the collision_head and go to Rigging>Deform>Muscle>Muscles/Bones>Convert Surface to Muscle/Bone. 7 - Select all the cluster handles groups and go to Rigging>Deform>Muscle>Self/Multi Collsion>Rig selection for KeepOut 8 - If you expand the cluster groups in the outliner you will see two transforms created on top of the cluster handles. The cMuscleKeepOut and the cMuscleKeepOutDriven groups. The cMuscleKeepOut node sets the local direction the cMuscleKeepOutDriven group moves when the collision happes. 9 - Before we connect the collision mesh to the keep out nodes, lets set the In Direction values to avoid having our clusters jump to the wrong direction.
Select all the keep out nodes of the cluster handles on right side and set the In Direction X to -1 and the In Direction Y to -0.5. This way when the collision happens the cluster handle would move to the right twice as much as moving down. 10 - Select all the keep out nodes of the cluster handles on left side and set the In Direction X to 1 and the In Direction Y to -0.5. 11 - Select all the keep out node of the center cluster handle on the back of the collar and set the In Direction X to 0, In Direction Y to -0.5 and In Direction Z -1. 12 - To make the cMuscleKeepOut nodes collide with our collision head, select all the cluster handle groups and the collision head lastly and go to  Rigging>Deform>Muscle>Self/Multi Collsion>Connect Muscles to Keep Out. 13 - Now if you rotate the neck you should see the clusters moving the direction we set when colliding with the collision head. The Joints Setup

Now we move to the final section of the rig which is adding the joints, attaching them to the collar curve and adding them to the jacket skin cluster. Depending on the mesh you have and your budget you can decide how many joints you can add. However, it is important to rmember this is not cloth simulation and there will be some areas in some animations that would require manual tweaking. Therefore we need to attach offset groups/ joints controllers to the curve instead of the joints themselves directly.

14 - Repeat the following steps the number of joints you would like to add to your setup. For this setup that will be 7 times:

PS: you can use any naming conventions you want, but for the sake of clarity I will refer to the locator group as the offset group.

This is the structure in the outliner: 15 -  In the NodeEditor create a pointOnCurveInfo node and check the Turn On Perecntage option in the attribute editor. Connect the collar curve shape worldSpace to the PointOnCurveInfo node inputCurve. Then connect the pointOnCurveInfo position to the locator offset group translate. 16 - Repeat the above step for every locator offset group. 17 - To place the locator offset groups and subsequently the joints we need to adjust the parameter value of every pointOnCurveInfo node we created. These are the values I used to place the offset groups like the following 0.00, 0.13, 0.3, 0.4, 0.6, 0.7, 0.87 18 - Finally, lets add the collar joints to the skin cluster by selecting all the collar joints and then the jacket mesh and go to Rigging>Skin>Edit Influences>Add Influence. Tweak the skinning so it is smooth but also test with animation to make sure the influences per joint is giving the desired result. 
If you rotate the neck joint/controller now you can see that the joints are following the curve and we still have the locator channels zeroed out for direct control over the joints. Happy Animating :) Final notes: If you can only have very few joints lets say 4 or less, you can skip the whole curve setup and just rig the joints controllers as we did for the cluster groups insted.

I used to rely a lot on the MFnTransform class solely to match the transformation of one object to another and it has worked great for me (until recently).

In my own rigging system and the ones I built for my employers I never freeze transformations. I usually create an offset/buffer group and never mess with the object's pivot. I also never have multiple rotation offsets on top of my nodes (which actually complicate the process of matching transformations of one object to another with the MfnTransform like explained below)

However, now that I am dealing with all kind of rigs from different sources I can't force my aesthetic on them and instead I have to find a way that can work around all kind of the above issues to be able to wrap them to my rigging system.

The translation methods of the MFnTransform work great in all cases, especially that you can get the rotatePivot point in worldspace directly which is beneficial if you are dealing with objects that have frozen transformations. However, it is very prone to fail with objects that have -1 scale or with frozen transformation. That is when I realised I will have to rely more on MTransformationMatrix to decompose my target node matrix to guarantee the correct rotation values that I need to apply to my object to match.

Here is the code (With Maya API 2) I use to match transformations now and tested with every case and so far worked great. I will also comment out the previous methods I used to match the rotations with the MFnTransform class and when did they fail for me in case anyone is interested in testing for themselves.

So as you can see in the code, I still use the MFnTransform to match the translation of my object to the target's rotate pivot. Then I use the MTransformationMatrix to decompose the world Matrix of the target node so I can get the correct rotation no matter what rotation order, negative scale and whatever offsets in the target's hierarchy.

PS:Using Maya API doesn't support UNDO. If you want to be able to undo the snapping consider using the API to decompose and store information and use the maya.cmds xform command to move the object instead. Made a quick tutorial to go over most of the most important features of the Dynamic Chain setup Tool and how it can be used to rig several joints chains.
The tool is currently sold for 25$ on cubebrush

Hey guys, I am moving all of my tools to Cube brush.

You can find the Dynamic Chain setup tool for all Maya versions starting from 2014.

I am releasing the tool for free. However, I would appreciate some contribution if you would like me to keep making tools for free.

Keep posted. There will be more tools added to that page :)

Time for another tutorial  not for the drag and drop (Got a bit distracted with the inspiration for this tutorial) but for adding an animated gif to a QLabel. In this example I am loading the file into a QByteArray so we don't keep that GIF in memory. However you can add the GIF file directly to the QMovie as the first argument.

If you can't display the GIF in your own code, double check the qt.conf file and make sure that it is referring to the correct plugins folder.

PS: If you don't recognise the GIF shown in the tool, you can find the Video here.("You are welcome").

I have always been using (well at least the past 7 years) QT for creating interfaces for my PySide/PyQt applications. Lately I've decided to dive a bit deeper to create and experiment with more complex behaviours.

Starting with a convenient behaviour : Drag and Drop.

In the example I am sharing here I re-implemented the drag and drop related methods of a QLabel and a QWidget so we are able to drag the label into the widget. What actually happens is that when we drop the label on  the widget we create another Label with the same information,  it is a Copying action.

TODO: In the upcoming weeks we will add the functionality of re-arranging the labels in the Drop widget and also from one Drop widget to another.

Hej Hej, its been a while since I posted here. Its been a very busy year. Moved to another country and joined a new company. Yes Dice EA and I am so excited to share with you the project that I have been working on over there, BattleField 1. 


The purpose of this post is to share with you how I tackled a problem I've always had building/adding specific components to the rig using my StretchIk class as an example.

As a rigger There is always a chance of either over or under doing a rig..

In my opinion a rigger should build a rig where they can add or remove parts from it on the go.
Production requirements change and also animators minds change :) (Don't we all love that).

It may seem an easy concept,but building a pipeline around this idea is not that easy.
There is lots of code involved and lots of properties to add. But the result is awesome and I would say it is definitely worth. Not only during the build process but afterwards when you need to query info or add extra pieces to your rig.

StretchIK is a class that I wrote with that concept in mind. I wanted to be able to add or remove my stretch setup any time during or after creating my rigs.

As you can see in the video, all what I did is instantiate the class with the ik handle.
From the ik handle I get information about the start joint, end joint and all the joints in between, and that's all I need for creating the stretch setup.

The createStretchMethod, builds the stretch setup and creates a settings group, where I save all the info I need about the stretch components, for example the joints real length and metadata for all the created stretch nodes. Having all the info I need for debugging the setup on one node made my life much much easier. if anything wrong happens, all I need to do is look at the numbers on the group and see which value doesn't make sense.

You probably noticed that I added the stretchLock with another method. stretch lock is an extended functionality for the stretch Ik. It should be added on top of the stretch setup anytime without having to rebuild the stretch setup from scratch.

The reason why at 0:57 I had to set the hingeJoint is that the class works on multiple joints. It doesn't care how many you joints in the chain all what it cares about is what is considered to be the hinge joint from a user point of view. example below And in the end of course the ability to delete the setup and reset the joints to their default.

The class it self has a bunch of getters and setter beside the working methods. Here is a screen shot of the class properties that I found very important to have. I hope you enjoyed the post and found some inspiration writing your own metadata based rigging code.

 
I thought I would share some info on the Ik Spline Advanced Twist Controls since I found a few questions about it online and also our new riggers were kind of confused about it

There are many ways to setup the twist along a spline IK joint chain.. Based on the character you are rigging you can choose what is best for you.

This tutorial assumes you are already familiar with the spline Ik setup and will be focusing only on the advanced twist settings.

First of all, if your aim axis along the joint chain...


While at GDC I attended the Blizzard party along with my colleagues at Crytek.
It was such a great party, met lots of awesome people over there. And as a huge fan of Diablo3 they handled my non stop questioning about the “Reaper of souls” release date for PS3 without  actually giving an answer :(
After giving up on getting an answer, I had a chance to challenge my boss (Chris Evans) at a game of HEARTHSTONE, miraculously I won and got out of the party with these goodies :) woahahhah It took me a while, but I managed to put together my 2013 Demoreel.
A big thank you to all the wonderful people at Crytek who helped work on this amazing project and allowed me to contribute.

I’ll be giving a presentation at GDC2014 together with the awesome Vlad Mastilovic from 3lateral. You can DOWNLOAD IT HERE
He’ll be talking about the Ryse facial rigs and I’ll be talking about the character rigging on Ryse. This is the game I’ve worked on for about 2 years.
If you have an xbox one and don’t mind spending a few bucks, check it out.

Ryse – Microsoft website
Ryse – Crytek website