Search Unity

  1. Engage, network and learn at Unite Austin 2017, Oct 3 - 5. Get your ticket today!
    Dismiss Notice
  2. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  3. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice
  4. Unity 2017.1 is now released.
    Dismiss Notice
  5. Unity 2017.2 beta is now available for download.
    Dismiss Notice

Google Universal Analytics for Unity - Support Thread

Discussion in 'Assets and Asset Store' started by tonic, Sep 25, 2013.

  1. jason_yak

    jason_yak

    Joined:
    Aug 25, 2016
    Posts:
    118
    Now that our game is released on Android (Agent A), it's seems to be doing well so far in regard to the write access without needing permissions. Will update if I find out otherwise.
     
  2. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    @jason_yak great to hear that, thanks for reporting back!
     
  3. michaelheiml

    michaelheiml

    Joined:
    Sep 21, 2015
    Posts:
    3
    @tonic

    Please help me with this: In our app, I use userID. I want to use user-based custom metrics (e.g. if the user is a premium user to distinguish all events from premium and free users). In the documentation is the method "addCustomMetric (int index, long value)" listed which creates a custom metric, but I can't figure out how to send an event with a custom metric. I already added the custom metric with index 1 to Google Universal Analytics via the web interface.

    According to this website, I would have to add the custom metric to the event that is sent, the code example is:
    googleAnalytics.LogEvent(newEventHitBuilder()
    .SetEventCategory("Achievement")
    .SetEventAction("Unlocked")
    .SetEventLabel("Slay 10 dragons")
    .SetEventValue(5)
    .SetCustomMetric(3,"200"));

    How do I achieve this using your plugin?
     
  4. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    Hi @michaelheiml, please have a look e.g. in the "void sendSystemInfoEvent(.......)" method in Analytics.cs for some reference. That shows how to make your own customized event hits.

    Between the calls beginHit ... sendHit, you should add the call for addCustomMetric.The logic in GUA API is that you build an analytics hit by first calling beginHit, then "add" some hit specific things there (like the custom metric), and then finally call sendHit.

    Please read the doxygen docs and/or source code to find out what pieces are required to be "added" by hit type. For example, for event hits, you must at least call addEventCategory and addEventAction.
     
  5. michaelheiml

    michaelheiml

    Joined:
    Sep 21, 2015
    Posts:
    3

    @tonic
    Thanks for your quick reply! I already wrote a new method following the ones that are already implemented, but I am stuck somewhere else:

    Code (CSharp):
    1.  
    2. public void sendEventHitWithMetric(string eventCategory, string eventAction, string eventLabel = null, int eventValue = -1, string eventCustomMetric = null)
    3.     {
    4.         if (analyticsDisabled)
    5.             return;
    6.  
    7.         beginHit(HitType.Event);
    8.         addEventCategory(eventCategory);
    9.         addEventAction(eventAction);
    10.         if (eventLabel != null)
    11.             addEventLabel(eventLabel);
    12.         if (eventValue >= 0)
    13.             addEventValue(eventValue);
    14.         if (eventCustomMetric != null)
    15.             addEventCustomMetric(eventCustomMetric);
    16.         sendHit();
    17.     }
    Code (CSharp):
    1.  
    2. publicvoidaddEventCustomMetric(stringmetric)
    3. {
    4. if(hitType !=HitType.EventWithMetric)
    5. return;
    6. stringdata=escapeString(metric);
    7. sb.Append("&ecm=");
    8. sb.Append(data);
    9. }
    10.  
    As parameter "eventCustomMetric", I pass:
    "{'metric2':true}"
    as string, but that might be the problem.

    The GUA doc gives this parameter as an example, but I can't figure out how to convert that to work with the plugin?
    .SetCustomMetric(3,"200"));
    Where the first parameter is the metric index (int) and the second one is the value (long).
     
  6. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    @michaelheiml, I'm afraid you're a bit on the wrong tracks (there is no hit type of "event with metric", and there's no "ecm" in the measurement protocol).

    Perhaps try something like this:
    Code (CSharp):
    1. public void sendCustomMetricEvent(int cmIndex, long cmValue, string eventCategory, string eventAction, string eventLabel = null, int eventValue = -1)
    2. {
    3.     GoogleUniversalAnalytics gua = GoogleUniversalAnalytics.Instance;
    4.     gua.beginHit(GoogleUniversalAnalytics.HitType.Event);
    5.     gua.addEventCategory(eventCategory);
    6.     gua.addEventAction(eventAction);
    7.     if (eventLabel != null)
    8.         gua.addEventLabel(eventLabel);
    9.     if (eventValue >= 0)
    10.         gua.addEventValue(eventValue);
    11.     gua.addCustomMetric(cmIndex, cmValue);
    12.     gua.sendHit();
    13. }
    14.  
    And call it for example like this:
    // custom metric 3 and custom metric value "200", assuming no event label or value is needed:
    sendCustomMetricEvent(3, "200", "CustomEvent", "EventAction");

    Edit: also there's nothing taking in JSON in the API, so there's no point trying to pass strings like "{'metric2':true}".
     
  7. michaelheiml

    michaelheiml

    Joined:
    Sep 21, 2015
    Posts:
    3
    @tonic Thanks for your help, it works!
     
  8. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    The way to set up a new tracking property has changed, since currently the GA site will by default forward to using Firebase instead.

    The lower half of the following web page has instructions how to now set up tracking properties differently.
    https://support.google.com/analytics/answer/2587086
    That list applies to this asset as well. Here is copy of those instructions:
    1. Sign in to your Google Analytics account.
    2. Click Admin.
    3. In the PROPERTY column, select Create new property from the dropdown menu.
    4. Select Website.
    5. Provide a Website Name. You may use the name of your app.
    6. Provide a Website URL. You may use your company URL or the URL for your app’s marketing site.
    7. Click Get Tracking ID.
    8. In the VIEW column, select Create new view from the dropdown menu.
    9. Select Mobile app.
    10. Provide a Reporting View Name.
    11. Click Create View.
    Additionally, be sure to leave your newly created mobile app view "active" by selecting it in the views column. It seems that only when the view is selected, the real-time reports screen will show the Overview and Screens pages for app tracking, just as it used to be.
     
  9. ITSTH

    ITSTH

    Joined:
    Jun 11, 2015
    Posts:
    4
    @tonic: Can I use your asset to visualize funnels? Basically I need a nice graph showing which level(s) the user solved. Some levels may be optional. (UA can't do that, I think.)
     
  10. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    @ITSTH, this asset is a wrapper for sending analytics hits to GA, so there is no any kind of own visualization features. All you get is what GA offers.

    GA website has support for funnels but it's up to you to figure how to best map analytics data from your app to there (beyond what I can help you with).
     
  11. radimoto

    radimoto

    Joined:
    Aug 23, 2012
    Posts:
    255
    Hi @tonic

    Just to let you know Google Universal Analytics fails on Unity 2017.1.0.f2 when building to IOS.
    Xcode logs an exception due to invalid characters.

    InvalidOperationException: Header value contains invalid characters
    at UnityEngine.WWW..ctor (System.String url, System.Byte[] postData, System.Collections.Generic.Dictionary`2[TKey,TValue] headers) [0x00000] in <00000000000000000000000000000000>:0
    at Strobotnik.GUA.GoogleUniversalAnalytics.beginWWWRequest (System.String postDataString) [0x00000] in <00000000000000000000000000000000>:0
    at Strobotnik.GUA.GoogleUniversalAnalytics+<netActivity>c__Iterator0.MoveNext () [0x00000] in <00000000000000000000000000000000>:0
    at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00000] in <00000000000000000000000000000000>:0
    at Strobotnik.GUA.GoogleUniversalAnalytics.initialize (UnityEngine.MonoBehaviour analyticsHelperBehaviour, System.String trackingID, System.String anonymousClientID, System.String appName, System.String appVersion, System.Boolean useHTTPS, System.String offlineCacheFilePath) [0x00000] in <00000000000000000000000000000000>:0
    at Strobotnik.GUA.Analytics.Awake () [0x00000] in <00000000000000000000000000000000>:0
    Strobotnik.GUA.GoogleUniversalAnalytics:initialize(MonoBehaviour, String, String, String, String, Boolean, String)
    Strobotnik.GUA.Analytics:Awake()

    (Filename: currently not available on il2cpp Line: -1)

    This is due to the parentheses in the user-agent:

    customHeaders.Add("User-Agent", "Mozilla/5.0 (iPhone; CPU iOS 11_0 like Mac OS X)");

    if (customHeaders != null)
    return new WWW(useHTTPS ? httpsCollectUrl : httpCollectUrl, postData, customHeaders);

    If the parentheses are removed, there is no exception:

    customHeaders.Add("User-Agent", "Mozilla/5.0 iPhone; CPU iOS 11_0 like Mac OS X");

    I am in the process of uploading a bug report.
     
    Last edited: Jul 8, 2017
  12. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    Hi @radimoto, thank you for notifying about this! That certainly seems like an error in Unity, let's hope that'll be resolved quickly. :rolleyes:
     
  13. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    @radimoto, additional note: if you want a quick workaround, it's a possibility to tweak the source a bit by commenting out the addition of custom-built user agent to customHeaders. And instead use the setUserAgentOverride(...) which supplies an user-agent override through the analytics API. In that case the hits will be submitted as whatever user-agent supplied by Unity, and GA should pick that overridden useragent for the analytics data.
     
  14. marbotic

    marbotic

    Joined:
    Apr 29, 2014
    Posts:
    2
    Hi everyone :)
    Hi @tonic

    I would like to understand how to use the custom dimension with your plugin.
    1) I clearly understand set up on Google Analytics.
    2) I tried to set all my event to my custom dimension "TypeProfile" by using "the code 1" screenshot. -> it didn't worked.
    3) i modified your code (see screenshot code 2) -> it worked.

    So either i didn't understand how you want us to use custom dimension or either there is a bug ?

    Thanks in advance for your advice.
     

    Attached Files:

  15. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    Hi @marbotic, you're definitely on the right tracks!

    For "exotic" use cases one is expected to make own helper method which builds an event with custom stuff and sends it. And the custom dimension stuff is such an "exotic" case.

    The first screenshot is definitely wrong, since the "addCustomDimension" is definitely meant to be used between calls to beginHit and sendHit. And that's what you have done in the second screenshot, so it works!

    The only thing I recommend is that you don't modify the included normal "sendEventHit" method, but instead move that customized version to somewhere in your own code and rename it. Just add using Strobotnik.GUA; and the Analytics.gua. prefixing to methods where needed. That way you can still use the regular sendEventHit in some other places, and a potential asset update later won't overwrite customizations.
     
  16. marbotic

    marbotic

    Joined:
    Apr 29, 2014
    Posts:
    2
    Thank you for your quick answer @tonic :)
     
  17. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
  18. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
  19. P4blo

    P4blo

    Joined:
    Dec 12, 2012
    Posts:
    12
  20. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    Hi @P4blo,

    Sure it is. After initialization, you can do a single call to: void setAnonymizeIP(true). After that it's applied to all subsequent sent hits.
     
    P4blo likes this.
  21. P4blo

    P4blo

    Joined:
    Dec 12, 2012
    Posts:
    12
    Thanks for the quick answer @tonic , I have another question. About the license, do I need a license per seat or per project?
     
  22. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    No per seat license needed, as it's not an editor extension.
     
  23. naligator

    naligator

    Joined:
    Jul 24, 2014
    Posts:
    6
    Hi @tonic Jetro-

    It seems - Google allowing only firebase Google-Analytics Property for Apps.

    What do you suggest I should do ?
    Should I select APp and let google analytics set it to firebase ? OR should I select Website ?

    OR is it game over for Strobotnik Google Univesal Analytics ?

    Do let me know- am about to ship an app hence will appreciate a fast reply.
    [​IMG]

    https://drive.google.com/open?id=0B3b_uo7JziDdTXJybG5zSUMyOVk

    Regards,
    -N
    ps: have also emailed you about this!
     
  24. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    Hi @naligator, an earlier thread posting has the answer for this - repeated below.

    --

    The way to set up a new tracking property has changed, since currently the GA site will by default forward to using Firebase instead.

    The lower half of the following web page has instructions how to now set up tracking properties differently.
    https://support.google.com/analytics/answer/2587086
    That list applies to this asset as well. Here is copy of those instructions:
    1. Sign in to your Google Analytics account.
    2. Click Admin.
    3. In the PROPERTY column, select Create new property from the dropdown menu.
    4. Select Website.
    5. Provide a Website Name. You may use the name of your app.
    6. Provide a Website URL. You may use your company URL or the URL for your app’s marketing site.
    7. Click Get Tracking ID.
    8. In the VIEW column, select Create new view from the dropdown menu.
    9. Select Mobile app.
    10. Provide a Reporting View Name.
    11. Click Create View.
    Additionally, be sure to leave your newly created mobile app view "active" by selecting it in the views column. It seems that only when the view is selected, the real-time reports screen will show the Overview and Screens pages for app tracking, just as it used to be.
     
  25. inZania

    inZania

    Joined:
    Mar 3, 2016
    Posts:
    26
    @tonic First, thanks for the effective plugin; it's been producing good data. However I've also had the same problem re: headers. I don't think asking developers to comment out the custom header is the right solution. Though this may be considered a bug in Unity, you can work around it with proper character encoding in the GoogleUniversalAnalytics class: https://issuetracker.unity3d.com/is...n-when-user-agent-header-contains-parenthesis

    Additionally, I would appreciate it if you would mark your methods as "virtual" on the Analytics class. There are a couple cases where I wanted to better customize the functionality for my use-case.
     
    Last edited: Sep 20, 2017 at 3:43 PM
  26. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    Hi @inZania, thanks for the kind words and feedback.

    I somehow first expected that the bug would have been resolved more quickly. I think there's certain amount of risk in encoding the parentheses, since normally that's not needed. If the encoded form is passed to server as is, then it's up to server to correctly decode them. So, it would at the very least take some back-and-forth testing to verify if the GA backend accepts that or not. Have you perhaps been using a modified version with the encoding, and verified it works?

    Another way should be to just use the API-provided setUserAgentOverride -method like I suggested earlier, without the above mentioned "risk". You're right this shouldn't be a hassle for users of GUA. I noted this down and will do something about in the next update.
     
  27. inZania

    inZania

    Joined:
    Mar 3, 2016
    Posts:
    26
    Thanks @tonic ! I did verify that my fix works by observing my "Macintosh Intel 10.2" platform in Google Analytics. I also have another fix: I added the Screen to the EventHit method, because the events were not logging the screens in which they appeared. Here's a paste of my working version.

    Ideally, the class itself would track the current screen and report it automatically.
     
    Last edited: Sep 20, 2017 at 4:59 PM
  28. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    Okay thanks @inZania. I recommend you make an own custom hit sending instead of modifying the built-in sendEventHit (but the idea is fine, i.e. making a cusomized hit sending based on what you want or need).

    Please remove that gist link though; while it's not the whole asset, it still exposes a large part of it to the public. :eek:
     
  29. inZania

    inZania

    Joined:
    Mar 3, 2016
    Posts:
    26
    Whoops, sorry about the gist. For some reason I was thinking this asset was publicly viewable anyways.

    While I agree with you that a custom function is a good idea in principle, it's not really possible because the class is sealed. I wish the class were partial and/or use virtual methods so I could tailor it better without my changes being overwritten whenever you push an update.
     
  30. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    @inZania, I will give changing to virtual some consideration. However, what I've been recommending is to just make customized hit sending methods in your own class, like MyCustomGUAHits.cs or whatever. That is, make a method similar to the example in this post (#206), and put in a new MonoBehaviour class for example, just remember to add "using Strobotnik.GUA;" at the top.
     
  31. inZania

    inZania

    Joined:
    Mar 3, 2016
    Posts:
    26
    Yep, I get that -- but because the entire "default functionality" must be copy/pasted into such a function, it means if you ever upgrade the base functionality it would be easy for us to not get that upgrade. This is why I generally prefer that SDKs provide high levels of customization -- so that I might augment their functionality while still relying upon core helper methods that ensure any framework upgrades "come for free."
     
  32. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    @inZania, inheritance & overriding virtual methods wouldn't help in this case, since the whole default functionality would still need to be copied over to the classes deriving from the GUA (that is, beginHit...addstuff...send stuff).

    The structure for building hits and sending them has been part of the public API of GUA and I think it has actually remained intact for the whole lifetime of the asset, likewise what's inside some of the base helpers like sendEventHit. So it should not be a problem to build own customized hit methods like I recommended. If you put the custom code to a separate class which just uses the GUA instance, then version updates should be safe for the main class (and in the past, features such as offline caching, have been added with the benefits coming just like you mentioned).
     
  33. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    @inZania, I sent you privately a patch with a fix for the header issue for testing out right away.

    I'll try to release the updated version soonish, containing also updated instructions for setting up a new tracking profile.
     
  34. tonic

    tonic

    Joined:
    Oct 31, 2012
    Posts:
    317
    Version 1.7.1 update is now available.

    It contains these changes:
    • Updated instructions for setting up new profiles in Google Analytics.
    • Added workaround for custom header bug in Unity 2017.