Advise on how to edit text posted to facebook with FB.API of Unity Facebook SDK - unity3d

I created a Game on Unity3D and I am in the process of adding support for Facebook. What I would like to achieve is the users posting a screenshot of the game showing the score.
I succeeded technically, but Facebook rejected my game because the text message that is posted along with the picture is pre-filled, and that violates section 2.3 of their Platform Policy.
Here is a pice of code found on the Example that comes with Facebook SDK for Unity in which I based mine... I guess this sample code created by Facebook does not comply either.
private IEnumerator TakeScreenshot()
{
yield return new WaitForEndOfFrame();
var width = Screen.width;
var height = Screen.height;
var tex = new Texture2D(width, height, TextureFormat.RGB24, false);
// Read screen contents into the texture
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex.Apply();
byte[] screenshot = tex.EncodeToPNG();
var wwwForm = new WWWForm();
wwwForm.AddBinaryData("image", screenshot, "InteractiveConsole.png");
wwwForm.AddField("message", "herp derp. I did a thing! Did I do this right?");
FB.API("me/photos", Facebook.HttpMethod.POST, Callback, wwwForm);
}
So before investing a lot of time implementing a text editor in Unity3D for the sole purpose of posting to Facebook, I am looking for advise.
First, is there a way I can get my app approved without creating a text editor at all?
1) If I just post the screenshot will Facebook approve my game? Or I still will get rejected for posting a pre-filled image?
2) Is there a way to achieve this without creating an App on Facebook and requesting approval for "publish_actions" permission? maybe passing the image to the Facebook App?
If there is no option and I must create a text editor with a touch keyboard to allow the user to edit the message, what would be the best way to do it keeping compatibility for iOS, Android and Windows Phone 8.

I did manage to get approved by Facebook, but believe me, there is no shortcut. You need to offer a way for the user to preview what is being posted, and edit the text before submitting it.
In the end it was not that hard, thanks to the GUI controls. You can use GUI.DrawTexture to show a preview of the screen captured. You can use GUI.TextField to allow the user to edit the message and use GUI.Button to show "Share" and "Cancel" buttons. Put all this code on the OnGUI() method.
You can even add the profile picture next to the TextBox so the user gets the social feeling and also so the user knows which user is posting. During my tests I noticed the App cache the Facebook tokens and even if you change the Facebook user on the phone and Facebook App, my game kept using the original user when posting.
Since the question focus on how to edit the Text and not on how to interact with Facebook I will post the GUI code here, but not the facebook code which is similar to what I previously posted.
The code assumes you have all the textures mentioned and that the user already agreed to give permissions for: "public_profile,publish_actions".
The code also uses a Boolean named socialAskMessage that you need to set true in order to show the user interface. Also when you set socialAskMessage it is advisable that you ignore all other user input. In my game I reactivate all user input after 0.5 seconds in another function named DelayedCanClick(). The method to actually post to facebook resides inside social.PublishOnFacebook() that I do not present here.
void OnGUI() {
//GUI.Label(new Rect(10, 10, 100, 20), "Res" + Screen.width + " x " + Screen.height);
if (socialAskMessage)
{
//Background
GUI.DrawTexture(new Rect(0f, 0f, Screen.width, Screen.height / 3f),socialBackground,ScaleMode.StretchToFill);
//Screenshot
GUI.DrawTexture(new Rect(margin, margin, Screen.width/3f - margin*2f, Screen.height / 3f - margin*2f),screenshot,ScaleMode.ScaleToFit);
//Profile Picture
if (profilePicture != null)
GUI.DrawTexture(new Rect(Screen.width*7f/10f,Screen.height/9f,83f*Screen.width/960f,83f*Screen.width/960f), profilePicture);
//Hanlde Enter/Return event/Share Button
if (GUI.Button(new Rect(Screen.width*8f/10f,Screen.height/9f,83f*Screen.width/960f,83f*Screen.width/960f),shareButtonTexture,emptyGUIStyle)
||
( (Event.current.type == EventType.KeyDown) && (Event.current.keyCode == KeyCode.Return || Event.current.keyCode == KeyCode.KeypadEnter) )
)
{
audioTac.Play();
if (socialMessage.StartsWith("Write"))
socialMessage = "";
else if (socialMessage.Length > 0)
{
socialAskMessage = false;
social.PublishOnFacebook();
}
else //If empty
socialMessage = "Write a comment...";
}
//Hanlde ESC/Cancel Button
if (GUI.Button(new Rect(Screen.width*9f/10f,Screen.height/9f,83f*Screen.width/960f,83f*Screen.width/960f),cancelButtonTexture,emptyGUIStyle)
||
( (Event.current.type == EventType.KeyDown) && (Event.current.keyCode == KeyCode.Escape) )
)
{
audioTac.Play();
socialAskMessage = false;
}
if (socialAskMessage) //If still needed, show it
{
GUI.skin.textField.fontSize = 22;
GUI.skin.textField.fontStyle = FontStyle.Bold;
GUI.skin.textField.wordWrap = true;
GUI.skin.textField.focused.textColor = Color.white;
GUI.SetNextControlName("socialTextArea");
socialMessage = GUI.TextField(new Rect(Screen.width/3f, margin, Screen.width/2.75f - margin*2f, Screen.height / 3f - margin*2f), socialMessage, 200);
GUI.FocusControl("socialTextArea");
if ((socialMessage.Length == 17 || socialMessage.Length == 19) && socialMessage.StartsWith("Write a comment"))
socialMessage = socialMessage.Replace("Write a comment","").Replace(".","");
}
else //Dont show it anymore, reactivate click
{
StartCoroutine(DelayedCanClick());
}
}
}

Related

How to avoid TYPE_APPLICATION_OVERLAY float window that covers the whole screen conflicts with input board or system dialog in Andorid API 31?

Before API 31, this WindowManager.LayoutParams works fine. Only a little area needs to react to users' action, and the rest of the window must not cover anything behind it. Howerver, when it comes to API 31, this float window start to cover the input board and the system dialog, while it does not cover any view of my application behinds it.
What can I do to make the fullscreen float window to be compatible with input board and the system dialog again in API 31?
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
params.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
} else {
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}
params.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
params.flags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
params.format = PixelFormat.TRANSLUCENT;
params.gravity = (Gravity.START | Gravity.TOP);
params.width = WindowManager.LayoutParams.MATCH_PARENT;
params.height = WindowManager.LayoutParams.MATCH_PARENT;

Unity3d Issue NGUI UITexture/Facebook www Profile Pic

Having small issue here with Unity and NGUI. NGUI has UITexture as its main texture such as Unity has GUITexture.
I sent a request to facebook to get the users profile image which sends back a perfect url which if I put in the browser works fine.
My issue is taking that Texture2D (Facebook API does it as a Texture2D) and putting it on my UITexture. For some reason it just does not take it correctly. I keep getting a null value for it. I am also using Mobile Social as well from the asset store any help, helps.
Here is my snippet of code.
private void UserDataLoaded(FB_Result result)
{
SPFacebook.OnUserDataRequestCompleteAction -= UserDataLoaded;
if (result.IsSucceeded)
{
Debug.Log("User Data Loaded!");
IsUserInfoLoaded = true;
string FBNametxt = SPFacebook.Instance.userInfo.Name;
UILabel Name = GameObject.Find("FBName").GetComponent<UILabel>();
Name.text = FBNametxt;
Texture2D FBLoadTex = SPFacebook.Instance.userInfo.GetProfileImage(FB_ProfileImageSize.normal);
FBGetProfile.GetComponent<UITexture>().mainTexture = FBLoadTex != null ? FBLoadTex : PlaceHolderImg;
}
else {
Debug.Log("User data load failed, something was wrong");
}
}
The placeholder image is just a already selected image used if the fbprofile pic does is null. Which I keep getting.....
It's possible you're looking for RawImage which exist for this purpose
http://docs.unity3d.com/Manual/script-RawImage.html
Since the Raw Image does not require a sprite texture, you can use it to display any texture available to the Unity player. For example, you might show an image downloaded from a URL using the WWW class or a texture from an object in a game.
Use Unity.UI and use that feature.
Add "Ngui Unity2d Sprite" component instead of UiTexture to your profile picture in editor and use below code in your Fb callback
private void ProfilePicCallBack (FBResult result)
{
if (result.Error != null) {
Debug.Log ("Problem with getting Profile Picture");
return;
}
ProfileImage.GetComponent<UI2DSprite> ().sprite2D = Sprite.Create(result.Texture, new Rect(0,0,128,128), new Vector2(0,0));
}
there might be an another way to do this. but this worked for me

'publish actions' permission is not require for screenshot posting?

Sorry. I can not speak English well.
I'm developing a small game using UNITY3D and Facebook UNITY SDK
I have submitted a review to facebook team for publish_actions permission.
(My game post a screenshot to user's timeline.)
And I received this result message .
"Your app experience does not need the requested permission."
I'm using Facebook SDK example code for screenshot function.
https://developers.facebook.com/docs/unity/reference/current/FB.API
private IEnumerator TakeScreenshot()
{
yield return new WaitForEndOfFrame();
var width = Screen.width;
var height = Screen.height;
var tex = new Texture2D(width, height, TextureFormat.RGB24, false);
// Read screen contents into the texture
tex.ReadPixels(new Rect(0, 0, width, height), 0, 0);
tex.Apply();
byte[] screenshot = tex.EncodeToPNG();
var wwwForm = new WWWForm();
wwwForm.AddBinaryData("image", screenshot, "InteractiveConsole.png");
FB.API("me/photos", Facebook.HttpMethod.POST, Callback, wwwForm);
}
'Screenshot button' is pressed, dialog does not appear.
when I tried screenshot function without permission, this function did not working
What's wrong?
The docs at
https://developers.facebook.com/docs/graph-api/reference/v2.0/user/photos/#pubperms
clearly state that you need the publish_actions permission to be able to upload photos for the User.

Facebook Unity SDK FB.Feed causes NullReferenceException

I'm having a problem when using the Facebook Unity API, calling the FB.Feed() method. It winds up giving this error:
NullReferenceException: Object reference not set to an instance of an object
UnityEngine.GUILayoutUtility.DoGetRect (UnityEngine.GUIContent content,
UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options) (at
C:/BuildAgent/work/d3d49558e4d408f4/artifacts/EditorGenerated/GUILayoutUtility.cs:264)
which is immediately followed by:
ArgumentException: Getting control 1's position in a group with only 1 controls
when doing Repaint
I know the second error is usually caused in Unity by GUI elements changing between GUI event calls, etc. In my case, however, I'm not doing anything within OnGUI at all. In fact, because of tearing my hair out trying to figure out what the problem is, I created a totally new project - 1 scene with basic buttons to login, and then "brag" using the FB.Feed. I've written it the exact way that their documents show, and I get the exact same error.
I'm hoping maybe someone might be able to shed some light on what I'm missing or doing wrong.
Here is complete code in my simple barebones scene that also causes this error:
void Start()
{
FB.Init(OnInitComplete, OnHideUnity);
}
void OnInitComplete()
{
Debug.Log("FB Initialized");
}
void OnHideUnity(bool isGameShown)
{
Debug.Log("OnHideUnity");
if (!isGameShown)
Time.timeScale = 0;
else
Time.timeScale = 1;
}
void Update()
{
}
void OnGUI()
{
if (!FB.IsLoggedIn)
{
if (GUI.Button(new Rect(10, 10, 100, 30), "Login"))
FBLogin();
}
else
{
if (GUI.Button(new Rect(10, 50, 100, 30), "Brag"))
{
Brag();
}
}
}
void Brag()
{
FB.Feed(
linkCaption: "This is testing the testapp FEED",
picture: "http://myapp.com/myapplogo.jpg",
linkName: "Foo Link",
link: "http://apps.facebook.com/" + FB.AppId + "/?challenge_brag=" + (FB.IsLoggedIn ? FB.UserId : "guest")
);
}
void FBLogin()
{
FB.Login("email, publish_actions", OnLoggedIn);
}
void OnLoggedIn(FBResult result)
{
if (FB.IsLoggedIn)
Debug.Log("Logged in successfully");
}
My Facebook API is version 140220, and my Unity is 4.3.4
I'll do my best to answer any other questions for info I've missed
I've also tried using the FB API version 131022, and have the same results.
This error also happens with the FriendSmash example and as well with the InteractiveConsole example scene provided with the plugin.
I should also point out that the Window does open for the post, and loads the image, link, etc. The exception prevents anything else from working however
Additional Info: I've found that when the app is ran on an actual android device, the feed post works with no problem. It only appears to have this error within the Unity editor. I have another issue with test users logging in on the android device - they can't if the device has the Facebook app itself installed, but that issue probably warrants a separate question
I think it's just not getting all of the resources it's asking for. The docs say not to worry about it, the editor can only do so much. I get the one below. Unfortunately though, mine is not working on the device, but if yours is, I wouldn't worry about it too much.
NullReferenceException: Object reference not set to an instance of an object
UnityEngine.GUILayoutUtility.DoGetRect (UnityEngine.GUIContent content, UnityEngine.GUIStyle style, UnityEngine.GUILayoutOption[] options) (at C:/BuildAgent/work/d3d49558e4d408f4/artifacts/EditorGenerated/GUILayoutUtility.cs:264)
UnityEngine.GUILayoutUtility.GetRect (UnityEngine.GUIContent content, UnityEngine.GUIStyle style) (at C:/BuildAgent/work/d3d49558e4d408f4/artifacts/EditorGenerated/GUILayoutUtility.cs:257)
Facebook.FbSkinnedDialog.TwoButtonBar (System.String label, System.String cancelLabel)
Facebook.FeedDialog.UpdateDialog (Int32 windowID)
Facebook.FbSkinnedDialog.GeneralUpdateDialog (Int32 windowId)
UnityEngine.GUI.CallWindowDelegate (UnityEngine.WindowFunction func, Int32 id, UnityEngine.GUISkin _skin, Int32 forceRect, Single width, Single height, UnityEngine.GUIStyle style) (at C:/BuildAgent/work/d3d49558e4d408f4/artifacts/EditorGenerated/GUI.cs:1395)

Posting screenshot through Facebook SDK for Unity

I have a problem with posting screenshot to FB. Connection is not the problem because I collect, deserialize and show my fb data. Post score and message to friend work fine but I cannot manage to post a shot from my phone. I am using Eclipse for debugging but I don't get any errors. My code look like this:
`
IEnumerator TakeScreenShot()
{
//coroutine because I want to wait until end of the frame for shot
yield return new WaitForEndOfFrame();
//create new texture that will be my screenshot
Texture2D tex = new Texture2D(Screen.width,Screen.height,TextureFormat.RGB24, false);
// read pixels from screen
tex.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0);
//and apply them to texture
tex.Apply();
// now we have screenshot
// now we need to encode texture to array of bytes
byte[] buffer = tex.EncodeToPNG();
//so we can save it to storage
// System.IO.File.WriteAllBytes(Application.dataPath + "/screenshots/screen/screen" + ".png", buffer);
//or to convert it to string for posting to facebook
string s = Convert.ToBase64String(buffer);
//????? maybe my string format is not correct
var query = new Dictionary<string, string>();
query["photos"] = s;
FB.API("me?fields=photos",Facebook.HttpMethod.POST, delegate (string r) { ; }, query);
}
`
when I go to GraphExplorer and paste command "me?fields=photos" I get nothing. It means function did nothing. I forgot to say that i granted permission for user_photos. This is frustrating. I have lost three days on problem that looked trivial, and yet no solution in sight. I will appreciate any suggestions.
Right now there's no easy way to handle this through FB.API since it takes in a Dictionary<string, string>.
However FB.API() is really just a wrapper around Unity's WWW class. You can call the graph endpoints at graph.facebook.com and pass in the byte[] buffer = tex.EncodeToPNG() as a param in WWWForm().
UPDATE: FB.API() has been updated in version 4.3.3 to support WWWForm as well. You can now upload photos via that method now.