Search Unity

List of things that don't work for Flash Export.

Discussion in 'Flash' started by cannon, Dec 30, 2011.

  1. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    How about a stickied master list of things that don't work during Flash export that aren't in the FAQ?

    For 3.5b6:

    - [C#] Comma-delimited multidimensional arrays, e.g. [,] notation causes export failures. [][] notation works.
    - [C#] Some functions in System.Collections.Generic.List<T> cause export failure. Commonly used functions probably work, but check each function first until we have a comprehensive list of what does and doesn't work.
     
    Last edited: Jan 1, 2012
  2. Lucas Meijer_old

    Lucas Meijer_old

    Joined:
    Apr 5, 2008
    Posts:
    436
    most of List<T> works fine. only some methods on it are missing.
     
  3. tomworcom

    tomworcom

    Joined:
    Dec 27, 2011
    Posts:
    50
    Not sure if there are any other specific requirements for those bugs, but I had those happen in my project:

    - [All] Solid color camera backgrounds are black when real-time shadows are enabled
    - [All] Occasional white noise with AudioClips playing with "Logarithmic Rolloff"
     
  4. increpare

    increpare

    Joined:
    Nov 17, 2010
    Posts:
    151
    things that don't work:
    structs aren't compared by value in Equals

    things to be wary of:
    enums (couple of bugs that bit me with them, so I ditched them entirely)
    custom generic functions (mostly don't seem to work, ditched them)
     
  5. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    ToSting("<Format>") formatting does not work, ToString(); does work.
    System.Convert.To<Type> does not work normal conversion works.
    DateTime and Duration types do not work in Flash.
     
  6. NoBloodyHero

    NoBloodyHero

    Joined:
    Apr 29, 2009
    Posts:
    54
    Some things I've come across:

    • List<T>.Sort() seems to attempt a numeric sort instead of using IComparable (I got cast exceptions when it tried to cast to a float). Using Sort(Comparer) worked fine.
    • Static classes don't seem to work.
    • Nullables do not work (ie: int?)
    • This is a convoluted one: overriding methods/properties that are defined in multiple base classes / interfaces. For example if you are overriding a hidden property in your base class but also implementing a hidden property for some other interface, that wont work. The name generated for action script seems to be based on the base class version of methods.
    • Events don't work, but delegates do.
    • Local variables used in anonymous methods / lamdas don't work. Had to make them fields on the class. Not sure what kind of closure support action script has but this could cause some hard to track down problems when updating code.
    • Convert.To methods all seem to be missing. .Parse methods are hit or miss.
    • Don't do this: char c = 'y'; string s = "unit"; s += c; Action script will treat c as a number. This works: s+= c.ToString()
    • String.Equals(str1, str2) does not work. Use str1.Equals(str2) (with a null check first if needed).
    • Don't increment inside of an indexer: someArray[i++];
    • OnMouseOver/Down/Up/Exit don't work. I got around it using Camera.main.ScreenPointToRay(Input.mousePosition
    It would be nice to keep a running list of what everyone finds. That way when we run into problems we can come here and search it instead of spending an hour tracking the problem down.
     
    Last edited: Dec 31, 2011
  7. Alex Mat

    Alex Mat

    Joined:
    May 14, 2010
    Posts:
    177
    o Cubemap based reflection is really low unless you specify a white reflection color
    o Failed to destroy a FixedJoint component (JS) (I have not tried with other components)
    o Updating a mesh takes much more resources than it should, so updating a mesh every LateUpdate or any Update should no be done
    o Sometimes, calculating normals in mesh importer does not work
    o Halo component becomes a lightsaber component (draws a ray of halo color to the closest point on screen's frame)
    o If more than 2 or 3 (don't remember) AudioSources with 2D AudioClips are connected, only the 2 (?) first will work (Edit: I mean, are on the same GameObject)
     
    Last edited: Dec 31, 2011
  8. Vikram

    Vikram

    Joined:
    May 15, 2011
    Posts:
    16
    1. AudioSource PlayOneShot plays as a loop depending on its loop value. Workaround -
    audio.loop = false;
    audio.PlayOneShot(mySound);
    audio.loop = true ;

    2. Agree with Alex on 2D sounds. For me 2D sound is never played when I have a continuous 3D loop.

    3. Transparent Materials do not show up in Flash(not sure if this is supported yet), Workaround - use Particle materials if possible
     
  9. Arowx

    Arowx

    Joined:
    Nov 12, 2009
    Posts:
    8,194
    More than one large none integer switch statements can generate a "Type '<PrivateImplementationDetails>' is defined in multiple scripts." error.

    Workaround Tip:
    Code (csharp):
    1. #if !UNITY_FLASH
    2. <switch case with complex comparison type>
    3. #endif
     
  10. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    Ahhh, it's probably ToArray in my implementation then.
     
  11. FredericRP

    FredericRP

    Joined:
    Jan 11, 2010
    Posts:
    79
    Hi there, a little detail on above list :

    Int16.Parse is not supported but Int32.Parse is
     
  12. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    Another one, hoping to save people some time

    - In some cases, GameObject.Instantiate can fail on a GameObject that has a public List<string> property. Use Arrays as a workaround.
     
    Last edited: Jan 3, 2012
  13. medi

    medi

    Joined:
    Dec 1, 2011
    Posts:
    3
    how can i use [][] notation? can you explain more?
     
  14. jeromemd

    jeromemd

    Joined:
    Oct 7, 2010
    Posts:
    16
    Trail Renderer fails to show once exported to Flash :(
     
  15. jeromemd

    jeromemd

    Joined:
    Oct 7, 2010
    Posts:
    16
    Sorry, it works. The issue was the transparent material. Using a particle material fixes the issue!
     
  16. Yanko

    Yanko

    Joined:
    Jan 2, 2012
    Posts:
    7
    - bool[] arrays won't work (and might be the cause of a (!) bug)

    "In the current public build, serialized arrays of bools are broken. You can work around this by either not serializing them (make them private or add [NonSerialized]), or by changing it to a int[] instead, and just use 1's or 0's."

    (source: http://forum.unity3d.com/threads/116570-Serialization-problem-Flash )
     
  17. Lucas Meijer_old

    Lucas Meijer_old

    Joined:
    Apr 5, 2008
    Posts:
    436
    Hi cannon, could you be so kind to file a bug with a reproducable project for this? I can't get this to happen over here. thanks!
     
  18. lilymontoute

    lilymontoute

    Joined:
    Feb 8, 2011
    Posts:
    1,181
    Setting a boolean value to ^= true (flipping it) causes an export error.
     
  19. RalphH

    RalphH

    Administrator

    Joined:
    Dec 22, 2011
    Posts:
    592
    @Thinksquirrel; you can flip it like this; myBool = !myBool
     
  20. lilymontoute

    lilymontoute

    Joined:
    Feb 8, 2011
    Posts:
    1,181
    Right. Just wanted to add it to the list, really - it's a very minor bug in reality.
     
  21. Alex Mat

    Alex Mat

    Joined:
    May 14, 2010
    Posts:
    177
    Some others:
    AudioSource.time or .timeSamples does not work;
    AudioSource.Pause() stops the thing

    Has already been said but no quality settings or other graphic related stuffs
     
  22. fanjules

    fanjules

    Joined:
    Nov 9, 2011
    Posts:
    167
    Was expecting this topic to be mainly about rendering issues, so a little alarmed initially that a lot of it is basic scripting stuff that is failing to convert to Actionscript or in some cases failing to compile. Hopefully though by the time we reach the Release version of 3.5 most of this will be old news, it's easy to take for granted what the Unity guys have achieved but it's a huge undertaking when you consider how much is packed into Unity.

    Nobody seems to have answered you, and I too was looking for an answer, so I made a whole new post on the topic:

    http://forum.unity3d.com/threads/117936-C-Multi-dimensional-Arrays-in-Flash
     
  23. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Id like to use ParticleSystem.Play(); in flash build; But wont compile with that, have to enable/disable/emmit particle's gameObject.
     
  24. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    Hi Lucas, the case # is 436182. You're right though, it doesn't normally fail.
     
  25. rand1815

    rand1815

    Joined:
    Apr 7, 2009
    Posts:
    27
    Does anyone know if there any way to get a 2d array working in JS? I see people say to use [][] in c# but that doesn't work for JS. I am using a bunch of int[,] and if there isn't a workaround I guess its a deal breaker for the moment :(
     
  26. Alex Mat

    Alex Mat

    Joined:
    May 14, 2010
    Posts:
    177
  27. fanjules

    fanjules

    Joined:
    Nov 9, 2011
    Posts:
    167
    Hmmm, the same deal in Javascript huh? Hopefully they will convert our rectangular arrays to jagged arrays automatically in the next release else it makes a mockery of cross-compiling if we have to change all our code to something that will then be less efficient in the other build targets.
     
  28. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    Use #if UNITY_FLASH to segregate out platform specific quirks.
     
  29. fanjules

    fanjules

    Joined:
    Nov 9, 2011
    Posts:
    167
    Compiler directives are always an option but still hardly ideal - one of my loops consists of lot's of multidimensional arrays and needs to be optimised for speed... but it's also hugely complex and readability is vital - padding it out and representing each line of code twice over isn't really what we want.

    In any case I entrust the Unity team will handle the rectangular arrays in the next release: it's no big deal to convert from one type to the other but definitely a task for the compiler not a human, after all that's what we have computers for, right? :)
     
  30. login4donald

    login4donald

    Joined:
    Jan 3, 2012
    Posts:
    462
    OnCollision and OnTrigger don't work unless you use C#, this makes me that when converting or building flash Javascript coding has some limitations unlike C#, being the 'high-level' language that it is. Hope this helps.
     
  31. RecursiveFrog

    RecursiveFrog

    Joined:
    Mar 7, 2011
    Posts:
    350
    Oddly I found that OnCollision/OnTrigger just weren't triggering "at all"* even though I already do use C#.


    (* "at all" meaning the player and enemy collision callback doesn't work, and neither does the "fell off a cliff" trigger or the "reached the goal" trigger. Oddly, the enemy stepping on a pressure plate triggers! But not the player stepping on the plate! On the other hand, the player and enemy both collide with the ground...)
     
    Last edited: Jan 4, 2012
  32. RecursiveFrog

    RecursiveFrog

    Joined:
    Mar 7, 2011
    Posts:
    350
    I don't know if this was just me but I found that my camera follow script wasn't working at all. Perhaps this is because the camera's following script was tucked away inside a LateUpdate function?
     
  33. nanaki

    nanaki

    Joined:
    Jan 4, 2012
    Posts:
    2
    • Stack<T> and Queue<T> classes doesn't exist
      Definition System.Collections.Generic:Queue$1/Stack$1 could not be found.​
    • Dictionary<Key,Value>.Values isn't iterable
      Call to a possibly undefined method ValueCollection_GetEnumerator through a reference with static type System.Collections.Generic:Dictionary$2_ValueCollection​
    • List<T>.TrimExcess method doesn't exist
      Call to a possibly undefined method List$1_TrimExcess through a reference with static type System.Collections.Generic:List$1.​
    • Subsequent assigns on a single line can create type conversion errors.
      e.g.
      MyType instance = someMyTypeList = new MyType();
      Implicit coercion of a value with static type Object to a possibly unrelated type global:MyType.​

      [*] No binary search functions (I've tried only Array.BinarySearch<T> or List<T>.BinarySearch)
     
  34. J_P_

    J_P_

    Joined:
    Jan 9, 2010
    Posts:
    1,027
    I've heard you have to pass arguments for collisions to work
     
  35. Mister Gilmore

    Mister Gilmore

    Joined:
    Jul 13, 2011
    Posts:
    6
    I tried playing a build of mine, paused the game, returned to the main menu, and tried to reload the same level and it wouldn't load. I was using a coroutine to do it, and it would not load the second time around, so I think there may be something screwy with the StartCoroutine/WaitForSeconds methods.
     
  36. Mister Gilmore

    Mister Gilmore

    Joined:
    Jul 13, 2011
    Posts:
    6
    Additionally, Convex mesh colliders didn't work for me, I got that Fatal Error 1506 that has been mentioned in a few topics, and it seems to be because (at least in my case) by convex mesh colliders.
     
  37. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    is Input.mousePosition working? It works in Unity but when I build I get no response from the mouse using this :

     
  38. BrUnO-XaVIeR

    BrUnO-XaVIeR

    Joined:
    Dec 6, 2010
    Posts:
    1,687
    Try ScreenToWorldPoint instead.
     
  39. crafTDev

    crafTDev

    Joined:
    Nov 5, 2008
    Posts:
    1,820
    It wasnt that. I debugged to find that this line:

    wasnt working...whats the formula to calculate degree from radian?

    EDIT: Actually its not Rad2Deg, it all boils down to this last line in my code:
    EulerAngles isnt working?

    EDIT2: figured it out, its so stupid that I declared calculateDegree as an int instead of a float...and thats what was causing all this mess and wasting hours...
     
    Last edited: Jan 4, 2012
  40. rand1815

    rand1815

    Joined:
    Apr 7, 2009
    Posts:
    27
    I am also getting errors for each instance of GameObject[] that I use. My code is soooo broken :(

    -EDIT

    I found out that I can just use List<GameObject> as a work around. Its slower but at least it works. Now if only there was a good way to have a multidimensional array of gameObjects I would really be in business!
     
    Last edited: Jan 5, 2012
  41. henry96

    henry96

    Joined:
    Sep 28, 2011
    Posts:
    582
    I also have problem when exporting to flash. When I export to Unity Web Player, everything works fine. The performance is great. Texture is there. However, if the game is exported to Flash, the performance starts to slow down. There are also bugs. (For example, player can go through wall easily). DOes anyone face the same problem? And do you know why it's happening?
     
  42. mazzino

    mazzino

    Joined:
    Jan 30, 2012
    Posts:
    15
    I'd like to contribute to this list of things that don't work for the Flash export. Some fixes have been made recently in latest release, but there might be some that would still cause trouble, so maybe this feedback could help.

    We're working on our main title Miner Wars 2081 (http:///www.minerwars.com) and apart of it, we are working on one smaller project in Unity 3D - Miner Wars 2.5D – which is something like a remake of the old DOS game Tunneler.

    You can see a preview here: http://www.minerwars.com/ContestFlashUnity/MW2.5D.html. MW 2.5D is developed in JavaScript and Unity3D 3.5.0b6.

    Problems which appeared:
    • multidimensional array type ([,]) doesn't work properly, there was need to make all these array types through objects to simulate multidimensional behavior (c# generics for this purpose also seemed not to work properly)
    • when adding variables with int and float types in one operation resulted in some cases always in 0 (mainly maybe in situation when processing Delta.fixedTime in our case), solution was to Math.floor float value manually
    • QualitySettings for export doesn't work, even main setting of texture resolution in editor has no effect in exported application
    • every audio clip (both 3D and 2D type) has to have rolloff set to linear and pan level to 0 - sounds can't be heard in different settings (or are extremely silent)
    • there's need to stop audio clip manually when test for isPlaying needs to be done, because even when it's not playing any more, it behaves like it is running
    • unexpected behavior when using and mapping Control, Shift or Alt keys for input (some actions happened to one of these keys, even when the behavior is not mapped, or no action happened even if it was mapped)
    • enum test for -1 doesn't work when this variable is not set up (the value seems to be < 0, but different (maybe it was just type collision))
    • basic lose of application focus doesn't work (game thread was paused in default unity webplayer after that)
    • it's not possible to hide mouse cursor (even it's possible in current version of flash)
     
  43. fanjules

    fanjules

    Joined:
    Nov 9, 2011
    Posts:
    167
    The multi-dimensional arrays are now working in the last release, though I'm only storing floats in them so maybe there's an issue with other data types?

    Regarding the unexpected behaviour of ctrl/shift/alt... I've got Ctrl working okay in an Update() loop, using Input.GetKeyDown(KeyCode.LeftControl) and Input.GetKey(KeyCode.LeftControl) without any problems - can you be more specific?
     
  44. fgielow

    fgielow

    Joined:
    Jan 3, 2012
    Posts:
    122
    I could not get multi-dimensional arrays to work with int type. I just created a topic about that here: http://forum.unity3d.com/threads/12...on-quot-in-flash-building?p=827677#post827677
     
  45. Lord_Pall

    Lord_Pall

    Joined:
    Sep 25, 2009
    Posts:
    52
    [system.serializable] is a huge problem for us right now.

    I was using

    [System.Serializable]
    public class foo
    {
    public int theNumber;
    public string theString;
    }

    public List<foo> theList;


    So I could edit the class in the editor.

    At Runtime I was getting a reference error. The only way we could fix it was to remove any of [System.Serializable] tags and hardcode the data.

    Runtime Error below (One of a few different ones, all linked to System.serializable in difference places)

    ReferenceError: Error #1069: Property length not found on System.CLIArray and there is no default value.
    at UnityEngine.Serialization::SerializedStateWriter/WriteArray()
    at UnityEngine.Serialization::SerializedStateWriter/WriteIDeserializableArray()
    at UnityEngine.Serialization::SerializedStateWriter/WriteIDeserializableList()
    at global::StatisticManager/Serialize()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Temp/StagingArea/Data/ConvertedDotNetCode/global/StatisticManager.as:109]
    at global::StatisticManagerClient/Serialize()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Temp/StagingArea/Data/ConvertedDotNetCode/global/StatisticManagerClient.as:78]
    at UnityEngine.Serialization::ActionScriptDeserializer$/Serialize()
    at com.unity::UnityNative$/Ext_SerializeMonoBehaviour()
    at com.unity::UnityNative$/_ZN13MonoBehaviour23VirtualRedirectTransferER19StreamedBinaryWriteILb0EE()
    at com.unity::UnityNative$/_ZL15CloneObjectImplP6ObjectR10vector_mapIllSt4lessIlE13stl_allocatorISt4pairIllEL18MemLabelIdentifier93ELi4EEE()
    at com.unity::UnityNative$/Object_CUSTOM_Internal_CloneSingle()
    at UnityEngine::_Object$/Object_Internal_CloneSingle_Object()
    at UnityEngine::_Object$/Object_Instantiate_Object()
    at global::NetworkManager/NetworkManager_Create_String_Int32()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Temp/StagingArea/Data/ConvertedDotNetCode/global/NetworkManager.as:443]
    at global::GameManagerClient/GameManagerClient_CreateHero_String()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Temp/StagingArea/Data/ConvertedDotNetCode/global/GameManagerClient.as:83]
    at com.unity::UnityNative$/Ext_Flash_InvokeMethodOnObject()
    at com.unity::UnityNative$/_ZN13MonoBehaviour30InvokeMethodOrCoroutineCheckedEP15ScriptingMethodPFP15ScriptingObjectPvPP18ScriptingExceptionES3_()
    at com.unity::UnityNative$/_Z15SendMonoMessageRN5Unity10GameObjectEPKcP15ScriptingObject()
    at com.unity::UnityNative$/_Z20BroadcastMonoMessageRN5Unity10GameObjectEPKcP15ScriptingObject()
    at com.unity::UnityNative$/_Z20BroadcastMonoMessageRN5Unity10GameObjectEP15ScriptingStringP15ScriptingObjecti()
    at com.unity::UnityNative$/Component_CUSTOM_BroadcastMessage()
    at UnityEngine::Component/Component_BroadcastMessage_String_Object_SendMessageOptions()
    at global::NetworkManager/NetworkManager_ProcessPacketReceived_String()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Temp/StagingArea/Data/ConvertedDotNetCode/global/NetworkManager.as:307]
    at global::NetworkManager/NetworkManager_ProcessSocketReceived_StringRef()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Temp/StagingArea/Data/ConvertedDotNetCode/global/NetworkManager.as:149]
    at global::FlashNetCom/FlashNetCom_Receive_String()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Temp/StagingArea/Data/ConvertedDotNetCode/global/FlashNetCom.as:65]
    at Function/http://adobe.com/AS3/2006/builtin::apply()
    at UnityBridge/unityfunc()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Assets/Scripts/ActionScript/UnityBridge.as:34]
    at UnityBridge/receive()[/Volumes/Disk Image/DivineIntervention2/branches/demo beta/DIMultiProto/Assets/Scripts/ActionScript/UnityBridge.as:106]
     
  46. tripknotix

    tripknotix

    Joined:
    Apr 21, 2011
    Posts:
    744
  47. DDowell

    DDowell

    Joined:
    Feb 8, 2012
    Posts:
    52
    1. (Global) Fog doesn´t work.
    2. Reflection (which is wierd since AS3 has a very potent reflection API, so a port should have been easy).
    3. Events in DLLs (events in MonoBehaviours seem to work).

    PS. Anyone know if one can specify your own swc files to include in the Flash build process? If so, we might be able to write the missing libraries ourselves...
     
  48. ChrisYummi

    ChrisYummi

    Joined:
    Jul 5, 2012
    Posts:
    8
    My compile errors found for flash:

    System.Enum.Parse
    System.TimeSpan.Subtract
     
  49. bigpants

    bigpants

    Joined:
    Dec 9, 2009
    Posts:
    49
    Problems found in Unity 4.0.0f7 C# Flash Export

    1. Simple Vertex Lit shader coming out black
      http://forum.unity3d.com/threads/163554-Simple-Vertex-Lit-Shader-appearing-black
      (works great without Lighting On)

    2. Geometry of some procedurally generated cubes messed up.
      Z is scaled infinitely big, but only on some cubes.
      Did not appear to happen in earlier Unity Flash export (unsure)

    Problems found in Unity 3.5.5f3 C# Flash Export
    (may or may not have been fixed in newer versions of Unity)

    1. In a >FEW< cases, I needed to switch from GetComponent("string") to GetComponent<Type>()
      Fail:
      ((MeshRenderer) mPlayer.GetComponent("MeshRenderer")).material =
      ((MeshRenderer) GameObject.Find("HoldMaterials").GetComponent("MeshRenderer")).materials[(int) Level.MaterialE.VertexTextureLit];
      Fix:
      mPlayer.GetComponent<MeshRenderer>().material =
      GameObject.Find("HoldMaterials").GetComponent<MeshRenderer>().materials[(int) Level.MaterialE.VertexTextureLit];

    2. 2D Array / Multidimensional Arrays (that everyone here has already mentioned)
      Fail:
      public static byte[,] cubeCounters = new byte[100,100];
      if (cubeCounters[x, y] == ...
      Fix:
      public static byte[] cubeCounters = new byte[10000];
      if (cubeCounters[x + y * 100] == ...

    3. Clone method
      Fail:
      sourceVertices = (Vector3[]) sourceMesh.mesh.vertices.Clone();
      Fix:
      sourceVertices = new Vector3[sourceMesh.mesh.vertices.Length];
      for (int index = 0; index < sourceMesh.mesh.vertices.Length; index++) { sourceVertices[index] = sourceMesh.mesh.vertices[index]; }

      Note: I realized afterwards that Cloning a value type (vertices) is unnecessary (and promptly removed .Clone())
      I'm still posting this "bug" in case .Clone() has issues for objects


    Things that appear to have exported properly, somewhat unexpectedly
    (some forum postings mention issues, but I haven't had any)
    Enumerations - I use a TON of them
    Static classes - even exposing enumerated types and byte arrays
    Procedurally generated meshes - aside from aforementioned issue, they seem to work​
     
  50. actuallystarky

    actuallystarky

    Joined:
    Jul 12, 2010
    Posts:
    188
    One that everyone is probably aware of but thought it worth mentioning - no MovieTexture support. It's supposedly replaceable by interfacing with Actionscript but I have yet to find a working example and my own attempts have failed.