Tag Archive : Visual Studio

/ Visual Studio

In this tutorial I’ll show you how to create a UrhoSharp project using Xamarin.Forms. This UrhoSharp project will run on Android, iOS and UWP.

A basic game I’ve created using UrhaSharp

Don’t worry if the code seems complicated, it’s not. To help you, I’ll include the source code of this project at the end of the tutorial.

The first step consists in creating a cross-platform project with Xamarin.Forms:

Creating a new cross platform Xamarin project

I suggest you to use a Blank template. Select the platform you need (Android, iOS, UWP to cover everything). Select the .NET Standard code sharing strategy.

Our new Cross Platform Solution

I suggest you to update all the Nuget packages before we start. After that, a nice clean and rebuild should guarantee us a clean start!

INSTALL URHOSHARP

The next step is to add the UrhoSharp.Forms nuget package to our solution. At the time of writing the latest version is 1.9.67. We must install this package in all our projects (.net standard, Android, iOS and UWP).

LET’S START WITH URHOSHARP

As you can imagine, UrhoSharp need a surface where it can draw our world. We can create this surface inside the MainPage.xaml file we have in our project. The MainPage will be similar to this:

As you can imagine, UrhoSharp need a surface where it can draw our world. We can create this surface inside the MainPage.xaml file we have in our project. The MainPage will be similar to this:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:UrhoSharpTutorial"
             xmlns:forms="clr-namespace:Urho.Forms;assembly=UrhoSharp.Forms"
             x:Class="UrhoSharpTutorial.MainPage">

    <StackLayout>
        <!-- Place new controls here -->
        <forms:UrhoSurface x:Name="urhoSurface" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        </forms:UrhoSurface>
    </StackLayout>

</ContentPage>

Basically we have added an UrhoSurface calling it urhoSurface. This surface will fill our entire screen. Now we need to edit the MainPage.cs to load our UrhoSharp application. The code will be this:

using Xamarin.Forms;

namespace UrhoSharpTutorial
{
    public partial class MainPage : ContentPage
    {
        XamarinExpertApp urhoApp;

        public MainPage()
        {
            InitializeComponent();
        }

        protected override async void OnAppearing()
        {
            StartUrhoApp();
        }

        async void StartUrhoApp()
        {
            urhoApp = await urhoSurface.Show<XamarinExpertApp>(new Urho.ApplicationOptions("Data") { Orientation = Urho.ApplicationOptions.OrientationType.LandscapeAndPortrait });
        }
    }
}

This code will load our XamarinExpert UrhoSharp app inside the urhoSurface when the MainPage appears. Let’s see now how to create the XamarinExpertApp class.

This XamarinExpertApp should inherit from Urho.Application. The code of this class is:

using System.Diagnostics;
using Urho;
using UrhoSharpTutorial.Scenes;

namespace UrhoSharpTutorial
{
    public class XamarinExpertApp : Application
    {
        private BaseScene _mainScene;

        [Preserve]
        public XamarinExpertApp(ApplicationOptions options = null) : base(options)
        {
        }

        static XamarinExpertApp()
        {
            UnhandledException += (s, e) =>
            {
                if (Debugger.IsAttached)
                    Debugger.Break();
                e.Handled = true;
            };
        }

        protected override void Start()
        {
            base.Start();
            Input.Enabled = true;
            Input.SetMouseVisible(true, false);
            Input.TouchEmulation = true;

            StartMainScene();
        }

        private void StartMainScene()
        {
            _mainScene?.Destroy();
            Current.UI.Root.RemoveAllChildren();
            _mainScene = new MainScene(Graphics.Width, Graphics.Height);
        }

        protected override void OnUpdate(float timeStep)
        {
            base.OnUpdate(timeStep);
            _mainScene.OnUpdate(timeStep);
        }
    }
}

This class is our UrhoSharp project. It handles the exceptions and initialises the Input of our project. Inside the Start method, we load our scene. We also override the OnUpdate method so that we can decide what will happen every time that the screen is refreshed.

At this point we should create the mainScene. In this project we have only a scene, but in a more complex project we can have multiple scenes. Maybe one for the menu, another for the game, another for the settings and so on. Because of this, I prefer to create a basic scene calling it BaseScene. The code of this class is this:

using Urho;

namespace UrhoSharpTutorial.Scenes
{
    public class BaseScene
    {
        private int width;
        private int height;
        public Scene Scene;
        public Node CameraNode { get; set; }

        public BaseScene(int width, int height)
        {
            this.width = width;
            this.height = height;
        }

        public void InitScene()
        {
            Scene = new Scene();
            Scene.CreateComponent<Octree>();
        }

        public void CreateCamera(Vector3 vector3)
        {
            CameraNode = Scene.CreateChild("Camera");
            CameraNode.Position = vector3;
            Camera camera = CameraNode.CreateComponent<Camera>();
            camera.Orthographic = true;

            camera.OrthoSize = (float)Application.Current.Graphics.Height * Application.PixelSize;
        }

        public void SetupViewport()
        {
            var renderer = Application.Current.Renderer;
            Viewport vp = new Viewport(Application.Current.Context, Scene, CameraNode.GetComponent<Camera>());
            renderer.SetViewport(0, vp);
            vp.SetClearColor(Color.White);
        }

        public virtual void OnUpdate(float timeStep)
        {
        }

        public virtual void Destroy()
        {
        }
    }
}

In this base class we store the width and the height of our surface (it’s not necessary but it could be handy). Here we have several methods to create our Scene (it’s mandatory to create a Scene, so don’t forget it), to create our Camera (again mandatory, and in this case it’s an orthographic camera) and to setup our viewport (again mandatory). We must do these things every time we need to create a scene and this is why I’ve created this base class.

Now we can finally create our mainScene. I’ll show you a basic code for a mainScene and then a more complex one where I’ll add some methods to handle the inputs and interact with the objects in our scene.

The basic scene is this:

using Urho;

namespace UrhoSharpTutorial.Scenes
{
    public class MainScene : BaseScene
    {
        public MainScene(int width, int height) : base(width, height)
        {
            CreateScene();
        }

        private void CreateScene()
        {
            InitScene();
            CreateCamera(new Vector3(0f, 0f, -15));
         
            SetupViewport();
        }
    }
}

Here we just initialise the scene, create the camera and set the Viewport. Now I can show you a more useful mainScene:

using Urho;

namespace UrhoSharpTutorial.Scenes
{
    public class MainScene : BaseScene
    {
        private MainSceneInput _mainInput;
        public float movementSize = 0.8f;
        public float movementSpeed = 0.25f;

        public MainScene(int width, int height) : base(width, height)
        {
            CreateScene();
        }

        private void CreateScene()
        {
            InitScene();
            CreateCamera(new Vector3(0f, 0f, -15));

            _mainInput = new MainSceneInput(this);
            _mainInput.OnEvaluateNode += MainInput_OnEvaluateNode;

            SetupViewport();
            CreateEvents();
        }

        private void MainInput_OnEvaluateNode(object sender, Node node)
        {
            
        }

        private void CreateEvents()
        {
            Application.Current.Input.TouchBegin += _mainInput.Input_TouchBegin;
            Application.Current.Input.TouchMove += _mainInput.Input_TouchMove;
            Application.Current.Input.TouchEnd += _mainInput.Input_TouchEnd;
            Application.Current.Input.KeyUp += _mainInput.Input_KeyUp;
        }
        
        public override void Destroy()
        {
            base.Destroy();
            Application.Current.Input.TouchBegin -= _mainInput.Input_TouchBegin;
            Application.Current.Input.TouchMove -= _mainInput.Input_TouchMove;
            Application.Current.Input.TouchEnd -= _mainInput.Input_TouchEnd;
            Application.Current.Input.KeyUp -= _mainInput.Input_KeyUp;
        }
    }
}

What I’ve added here is some logic to interact with our world. Precisely I’ve created several methods to handle the touches on the screen. I’ve implemented all the methods inside another class called MainSceneInput. The code of this class is:

using System;
using Urho;
using Urho.Actions;

namespace UrhoSharpTutorial.Scenes
{
    internal class MainSceneInput
    {
        private readonly MainScene _scene;

        public event EventHandler<Node> OnEvaluateNode;

        public MainSceneInput(MainScene scene)
        {
            _scene = scene;
        }

        private Node GetSelectedNode(float objX, float objY)
        {
            Ray cameraRay = _scene.CameraNode.GetComponent<Camera>().GetScreenRay(objX / Application.Current.Graphics.Width, objY / Application.Current.Graphics.Height);
            var result = _scene.Scene.GetComponent<Octree>().RaycastSingle(cameraRay, RayQueryLevel.Triangle, 100);
            return result?.Node;
        }

        public void Input_TouchBegin(TouchBeginEventArgs obj)
        {
            Node selectedNode = GetSelectedNode((float)obj.X, (float)obj.Y);
            OnEvaluateNode?.Invoke(this, selectedNode);
        }

        public void Input_TouchMove(TouchMoveEventArgs obj)
        {
            Node selectedNode = GetSelectedNode((float)obj.X, (float)obj.Y);
            OnEvaluateNode?.Invoke(this, selectedNode);
        }

        public async void Input_TouchEnd(TouchEndEventArgs obj)
        {

        }

        internal void Input_KeyUp(KeyUpEventArgs obj)
        {
            if (obj.Key == Key.I)
            {
                var camera = _scene.CameraNode.GetComponent<Camera>();
                camera.Zoom += 0.05f;
            }
            else if (obj.Key == Key.O)
            {
                var camera = _scene.CameraNode.GetComponent<Camera>();
                camera.Zoom -= 0.05f;
            }
            else if (obj.Key == Key.W)
            {
                _scene.CameraNode.RunActions(new MoveTo(_scene.movementSpeed, new Vector3(_scene.CameraNode.Position2D.X, _scene.CameraNode.Position2D.Y + _scene.movementSize, -1.0f)));
            }
            else if (obj.Key == Key.S)
            {
                _scene.CameraNode.RunActions(new MoveTo(_scene.movementSpeed, new Vector3(_scene.CameraNode.Position2D.X, _scene.CameraNode.Position2D.Y - _scene.movementSize, -1.0f)));
            }
            else if (obj.Key == Key.A)
            {
                _scene.CameraNode.RunActions(new MoveTo(_scene.movementSpeed, new Vector3(_scene.CameraNode.Position2D.X - _scene.movementSize, _scene.CameraNode.Position2D.Y, -1.0f)));
            }
            else if (obj.Key == Key.D)
            {
                _scene.CameraNode.RunActions(new MoveTo(_scene.movementSpeed, new Vector3(_scene.CameraNode.Position2D.X + _scene.movementSize, _scene.CameraNode.Position2D.Y, -1.0f)));
            }
        }
    }
}

In this class I have a method to evaluate which object the user has touched (in that case the OnEvaluateNode method will be called with the selected node). And another method to move the camera using the keyboard (of course you can change this as you want, this is just an example on how to intercept these events).

Conclusion

All the code added until now is a basic empty template for every UrhoSharp project you want to create. You can use this template as a starting point for your UrhoSharp projects.

I’ve added on bitbucket this source code with just a simple code to add a sprite to our scene, so from there it can be easier for you to add all the sprites you need. The link is: https://bitbucket.org/marcojak81/urhosharpbasictemplate/src/master/

I’ll create later other more advanced tutorial on UrhoSharp.

As usual, if you have questions, please ask me and I’ll try to help you.

Microsoft has released the version 15.6.3 of Visual Studio and it contains several fixes some of them for Xamarin.

Visual Studio
Visual Studio 2017

Visual Studio 2017 15.6.3 – Release note

  • Esc key doesn’t close Peek Definition Window.
  • wpp.targets file execution not working after update to version 15.6.
  • Project loaded via File->Open->CMake throws exception and CMake cache is not generated..
  • Version 15.6 update crashes Xamarin code with NullReferenceException with next scenario.
  • XCode Tools installation fails after version 15.6 update.
  • Anaconda 5.0.0 Completion DB is not up to date and hitting refresh fails.
  • Cannot run NUnit tests after version 15.6.1 update.
  • Visual Studio 2017 fails to launch from the command line when launched using 8.3 file name path.
  • Version 15.6.0 breaks when VisualStudio\\Telemetry\\TurnOffSwitch is set to 0.
  • Visual Studio Community 2017 auto closes after version 15.6 update..
  • CMake generation never stops after version 15.6.1 update.
  • Opening a solution with tests, and clicking any toolbar item in Test Explorer causes VS to crash.

I have highlighted the two bugs for Xamarin that now have been fixed.Those bugs are quite annoying so, especially if you use Xamarin, it’s very important to update Visual Studio to the  version 15.6.3 If you want to try the Visual Studio Preview Version, you can find it clicking here

Microsoft has released a preview version 15.7 of Visual Studio 2017.

Visual Studio
Visual Studio 2017

There are few improvements around Xamarin so could be quite interesting to see the release notes.As it is a Preview release, you shouldn’t use if for production code.

Release Notes

Updates

  • IntelliTrace?s step-back debugging feature is now supported for debugging .NET Core projects.
  • Debugging large solutions with /Debug:fastlink PDBs is more robust.
  • Visual Studio Tools for Xamarin can now automatically install missing Android API levels required by Xamarin.Android projects.
  • We added a limited preview of a new Python debugger based on the popular open source pydevd debugger.
  • We have improved Kestrel HTTPs support during debugging.
  • The Windows 10 Insider Preview SDK Build 17110 can now be installed as an optional component with the Universal Windows Platform.
  • We added support for NuGet package signatures.

Bug Fixed

  • .NET Core failed due to dependency on Microsoft.VisualStudio.AspNetDiagnosticPack.Msi.
  • Update to Visual Studio 2017T15.4 generates multiple package errors.
  • Add Option to Disable format on paste for razor code in razor/cshtml files.
  • Visual Studio auto formatter breaks complex razor code.
  • Update error: PackageId:Microsoft.VisualStudio.AspNetDiagnosticPack.Msi;PackageAction:Uninstall;ReturnCode:1603;.

Xamarin

This release includes Xamarin.iOS 11.10 and Xamarin.Android 8.3.

Automatic Android SDK Management

When a Xamarin.Android project is loaded, Visual Studio can now determine if the Android API level used by the project is missing from your machine and automatically install it for you in the background. To enable this feature, go to Tools > Options > Xamarin > Android Settings > Auto Install Android SDKs.

Download

You can download the Preview version of Visual Studio 2017 from here: https://www.visualstudio.com/vs/preview/

If instead of the preview version you want to use a stable one, give a look here: http://www.xamarinexpert.it/2018/03/05/vs2017-version-15-6-just-released/

Admob for Xamarin made easy

May 6, 2019 | Guide, Plugin, Tutorial | 67 Comments

In this tutorial I’ll show you how to monetize your Xamarin apps with AdMob using my MTAdmob plugin.

Important: If you receive errors compiling the code for iOS, install the package Xamarin.Google.iOS.MobileAds in your iOS project.

UPDATE 16/10/2019: MTAdmob is now Open Source on Github: https://github.com/marcojak/MTAdmobUPDATE 11/10/2019: VERY IMPORTANT!!! The new version 1.4.4 is out. There is an issue in the latest Xamarin.Google.iOS.MobileAds 7.47. Because of this, in your iOS project you have to install the plugin Xamarin.Google.iOS.SignIn 4.4.0 too. This will let you compile and use MobileAds.

UPDATE 1/May/2019: I’ve released the new version 1.3 thas sovles some issues with iOS and improves performances.

UPDATE: From version 1.2, MTAdmob supports also Google ads rewarded videos for Android and iOS

UPDATE: I’ve added on github the source code of a project to test this Admob plugin. You can find it here: https://github.com/marcojak/TestMTAdmob

To help you to speed up your Xamarin development, I’ve created a set of plugins, one of them is MTAdmob. Thanks to this plugin you can add Admob banners and Insterstitials in just few lines of code. It couldn’t be easier than that and I’ll show you.

Install the plugin

First of all, right click on your Xamarin solution and select “Manage Nuget packages for Solution”

manage nuget

Visual Studio will open a new screen where you can search and install one or more nuget packages. In this case we can search for the MTAdmob plugin. Searching for MarcTron will show you all my packages (I’m sure you can find other useful plugins that I’ve written), and we can select the MTAdmob plugin as showed in the next image.

It’s very important that you install the plugin in your PCL/.Net standard project and in your platform projects (Android, iOS, UWP).

After the Admob plugin is installed we can add banners and insterstitials to our projects.

Add Ads to our project

With version 1.0 the MTAdmob plugin supports banner and interstitials for Android and iOS. If you would like to see the plugin supporting also the UWP platform, let me now and I’ll add the support in a new version.

As I’ve said we can add Banners and Interstitials Admob ads to our project. Let’s start with the Banners

How to add an Admob Banner

An Admob banner is just a view inside our page. It means that we can add it using XAML or C#. First of all let’s see how to add an Admob banner using XAML.

Add an Admob Banner with XAML

In MTAdmob to use an Admob banner I’ve created a custom control called AdView, so to use it we can use this code:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="clr-namespace:MarcTron.Plugin.Controls;assembly=Plugin.MtAdmob"
             x:Class="Test.MTAdmob.MainPage">

<StackLayout>
    <Label Text="Let's test an Admob Banner!" 
           HorizontalOptions="Center"
           VerticalOptions="CenterAndExpand" />
    <!-- Place the Admob controls here -->
    <controls:MTAdView/>
</StackLayout>

In this example we have created a StackLayout with 2 controls: a label and an AdView (our Admob banner). Easy! Isn’t it???

The AdView control is basically a View so you can use all the properties you can think of like: HorizontalOptions, VerticalOptions, IsVisible…

In addition to these properties, I’ve added in AdView two other properties: AdsId and PersonalizedAds.

AdsId: Allows you to add the Banner Id (you can find it in your Admob account)

PersonalizedAds: This allow you to use non personalized ads. For example in case of GPDR. Of course it’s better to use personalized Ads.

To use these properties you can update the previous code to:

<controls:AdView PersonalizedAds="true" AdsId="xxxxxxxxxxxxxxxxxx"/>

Add an Admob Banner with C#

In case you don’t write your pages with XAML or you write your UI in C# or you want to add your view only in some cases, you can add your Admob Banner using this code:

using MarcTron.Plugin;
...
MTAdView ads = new MTAdView();

Of course you need to attach this View to your layout, but you know how to do it (If not, feel free to ask).

To use the custom properties you can change the previous code to:

...
MTAdView ads = new MTAdView();
ads.AdsId = "xxx";
ads.PersonalizedAds = true;

Also in this case, to add an Admob banner is INCREDIBILY EASY!!!

Global Custom Properties

As you have seen, the properties AdsId and PersonalizedAds belong to a single AdView. It means that you have to set them for every Admob Banner.

To make things even easier I’ve added the option to set these properties only once. To do so, you can use this C# code:

CrossMTAdmob.Current.UserPersonalizedAds = true;
CrossMTAdmob.Current.AdsId = "xxxxxxxxxxxxxxxx";

In this case all your Admob banner will show personalized ads and will have the same Id.

If you set local and global properties, the local ones will have higher priority.

Use of Banner Events

I’ve added 4 events to the Admob banner that you could find nice to have. These events are:

  • AdsClicked When a user clicks on the ads
  • AdsClosed When the user closes the ads
  • AdsImpression Called when an impression is recorded for an ad.
  • AdsOpened When the ads is opened

To use these events you can write this code:

AdView myAds = new AdView();
myAds.AdsClicked += MyAdsAdsClicked;
myAds.AdsClosed += MyAds_AdVClosed;
myAds.AdsImpression += MyAds_AdVImpression;
myAds.AdsOpened += MyAds_AdVOpened;

Of course you can use these events also if you have declared your AdView in your XAML code.

Admob Interstitials

Now that we know how to add Admob banners using my plugin MTAdmob, let’s see how we can add Admob Interstitials. If possible, to add an Admob interstitial is even easier. You just need a single line of code. Don’t you believe me? Look here how to show an Admob interstitial:

CrossMTAdmob.Current.ShowInterstitial("ca-app-pub-xxxxxxxxxxxxxxxx/xxxxxxxxxx");

I told you!!! That’s it!!! With that line of code you have just showed an Interstitial in you app. Of course you need to replace that string with the Insterstitial ID you can find in your Admob account.

Events for Interstitials

There 3 events that you can use with Interstitials:

OnInterstitialLoaded        When it's loaded
OnInterstitialOpened        When it's opened      
OnInterstitialClosed        When it's closed

Rewarded Video

From version 1.1 the plugin supports the amazing Rewarded Video too.

To show a rewarded video you just need a single line of code:

CrossMTAdmob.Current.ShowRewardedVideo("xx-xxx-xxx-xxxxxxxxxxxxxxxxx/xxxxxxxxxx");

Events for Rewarded videos

There are 7 events that you can use with the Rewarded video Ads:

OnRewarded                          When the user gets a reward
OnRewardedVideoAdClosed             When the ads is closed
OnRewardedVideoAdFailedToLoad       When the ads fails to load
OnRewardedVideoAdLeftApplication    When the users leaves the application
OnRewardedVideoAdLoaded             When the ads is loaded
OnRewardedVideoAdOpened             When the ads is opened
OnRewardedVideoStarted              When the ads starts

Initialization

Before you can use the Admob banners and Interstitials, you need to initialize it. You need to do it only once so it makes sense to initialize it onside the OnCreate method in Android and FinishedLaunching in iOS.

In your Android project add this line in your OnCreate method:

MobileAds.Initialize(ApplicationContext, "ca-app-pub-xxxxxxxxxxxxxxxx~xxxxxxxxxx");

In your iOS project add this line in your FinishedLaunching method:

MobileAds.SharedInstance.Start(CompletionHandler);

private void CompletionHandler(InitializationStatus status){}

In iOS you should install the package Xamarin.Google.iOS.MobileAds and Xamarin.Google.iOS.SignIn!

You need to add to your Info.plist file this:

	<key>GADApplicationIdentifier</key>
	<string>YOUR APP ID</string>
	<key>GADIsAdManagerApp</key>
	<true/>

Android Project (Important)

In your AndroidManifest you should add these lines:

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

<application android:label="Test.MTAdmob.Android">
    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
    <meta-data android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy"/>
    <activity android:name="com.google.android.gms.ads.AdActivity" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:theme="@android:style/Theme.Translucent" />
</application>

iOS Project (Important)

From version 1.4.4 you need to manually install the packages: Xamarin.Google.iOS.MobileAds and Xamarin.Google.iOS.SignIn! If you don’t install them, your app will not compile.

Some useful links

Conclusion

This Admob MTAdmob plugin is incredibly easy to use but in case you need help, or you want to suggest a new feature or for any other reason, write me.

%d bloggers like this: