Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by idbrii · Feb 18, 2021 at 08:07 PM · native pluginapplegamecenter

How do I use Apple's SFSymbols in my app?

Apple has an API to get buttons on a gamepad: GCControllerElement. Within it, you can get sfSymbolsName which is an identifier to look up a graphic in Apple's SF Symbols. That flow would provide the SF Symbol graphic for the button according to the GameCenter button mapping.

How do I get that graphic into Unity?

I've figured some details out:

  • This answer explains how to get bytes from obj-c to C#.

  • It looks like NSImage and UIImage both have init functions to load the image data.

But I'm not sure how to extract the image data and convert it to an array of bytes in a format Unity can understand.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image indie6 · May 11, 2021 at 04:09 PM 0
Share

Hey were you able to solve this issue? If so, can you provide the snippet? Thanks!

1 Reply

· Add your reply
  • Sort: 
avatar image
0

Answer by idbrii · Feb 22, 2021 at 10:22 PM

You can get an array of bytes from an NSBitmapImageRep. However, there's some hoops to jump through to get one of those from an NSImage. You'll also want to resize the image to avoid getting back a 15x15 image (the default if you try using TIFFRepresentation). I get back a 40x38 image on iOS without any resizing.

Some things I haven't figured out:

  • How to make the image white instead of black

  • Proper memory usage

Here's the code to convert to array of bytes, pass to C#, and assign that to a RawImage:

 // Obj-C
 
 // macOS-specific helper (mark this to not build for any platform)
 #import <AppKit/AppKit.h>
 NSData* GetSymbolImageAsBytes(NSString* name, int width, int height)
 {
     if (@available(macOS 11.0, *))
     {
     }
     else
     {
         // imageWithSystemSymbolName isn't available
         return nil;
     }
 
     NSImage *image = [NSImage
         imageWithSystemSymbolName: name
          accessibilityDescription: nil
     ];
 
     if (image == nil) {
         return nil;
     }
 
     // Resize to desired size.
     // https://stackoverflow.com/a/38442746/79125
 
     NSSize size = NSMakeSize(width, height);
 
     // TODO: Should reuse a single NSBitmapImageRep instance instead of
     // repeated alloc. Otherwise we leak memory here.
     NSBitmapImageRep *rep = [[NSBitmapImageRep alloc]
         initWithBitmapDataPlanes:NULL
                       pixelsWide:size.width
                       pixelsHigh:size.height
                    bitsPerSample:8
                  samplesPerPixel:4
                         hasAlpha:YES
                         isPlanar:NO
                   colorSpaceName:NSCalibratedRGBColorSpace
                      bytesPerRow:0
                     bitsPerPixel:0];
     rep.size = size;
 
     [NSGraphicsContext saveGraphicsState];
     [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:rep]];
     [image drawInRect:NSMakeRect(0, 0, size.width, size.height) fromRect:NSZeroRect operation:NSCompositingOperationCopy fraction:1.0];
     [NSGraphicsContext restoreGraphicsState];
     if (rep == nil)
     {
         return nil;
     }
     // Passing nil gives a warning but seems to work okay.
     return [rep representationUsingType:NSBitmapImageFileTypePNG properties:nil];
 }


 // iOS-specific helper (mark this to build for iOS)
 #import <UIKit/UIKit.h>
 NSData* GetSymbolImageAsBytes(NSString* name, int width, int height)
 {
         UIImage *image = [UIImage systemImageNamed: name];
         NSData *png_data = UIImagePNGRepresentation(image);
         // TODO: Rescale to input size.
         return png_data;
 }


 #import <Foundation/Foundation.h>
 #import <GameController/GameController.h>
 int GetGamepadButtonImage(int** dataPtr, int width, int height)
 {
     *dataPtr = nil;
 
     GCController *gc = [GCController current];
 
     NSString *name = gc.extendedGamepad.buttonY.sfSymbolsName;
     // Name is something like
     //~ name = @"triangle.circle";
 
     NSData* png_data = GetSymbolImageAsBytes(name, width, height);
     if (png_data == nil) {
         return -1;
     }
     
     UInt8 *png_bytes = (UInt8 *)png_data.bytes;
     *dataPtr = (int*)png_bytes;
     return (int)png_data.length;
 }
 
 
 
 // C#
 
 #ifdef UNITY_STANDALONE_OSX || UNITY_EDITOR_OSX
     // You need to compile the above objc code (minus iOS) into a
     // "Gamepad.bundle". (I used cmake.) Be sure your .bundle is only
     // included on Editor+Standalone.
     [DllImport("Gamepad", CallingConvention = CallingConvention.Cdecl)]
 #else
     // Putting above objc code (minus macOS) in Assets/Plugins/iOS/Gamepad
     // auto builds it into this dll.
     [DllImport("__Internal")]
 #endif
 private static extern int GetGamepadButtonImage(out IntPtr data, int width, int height);
 
 
 static void ReplaceTexture()
 {
     int width = 45;
     int height = 45;
     var num_bytes = GetGamepadButtonImage(out IntPtr unsafe_ptr, width, height);
     Debug.Log($"received {num_bytes} bytes of unmanaged data. {width}x{height}={width*height}.");
 
     if (num_bytes <= 0)
     {
         Debug.LogWarning($"Received no data: {num_bytes}. Aborting...");
         return;
     }
 
     var image_bytes = new byte[num_bytes];
     Marshal.Copy(unsafe_ptr, image_bytes, 0, num_bytes);
     // Trying to free like this crashes:
     //~ Marshal.FreeHGlobal(unsafe_ptr);
 
     var canvas = GameObject.Find("Canvas");
     var im = canvas.GetComponentInChildren<UnityEngine.UI.RawImage>();
     var tex = new Texture2D(width, height);
     ImageConversion.LoadImage(tex, image_bytes);
     im.texture = tex;
 }

Be sure to use the PluginInspector to set the .bundle and .m files to build only on the correct platforms!

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

114 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Does Social.LoadScores report ALL scores on GameCenter? 1 Answer

Apple iphone authentification 1 Answer

[Android] GameCenter Social.localUser id uniqueness 0 Answers

Add achievement into Game Center - Apple Store 0 Answers

How to get Sandbox mode running on Apple TV? 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges