question

omerdruu avatar image
omerdruu asked

Can the photo selected from the gallery be specific to the user logged in with playfab and displayed in the photon rooms?

Hello, I am using playfab and photon plugin in my game. I can login with Playfab without any problem. In the main menu of my game, there is a user-specific panel with the user picture and username in the upper right corner. I can show the username on the panel and map it to the photon without a problem. Additionally, with a plugin, I allow users to select a profile photo from the phone gallery at login. I can show this user-selected photo on the panel in the main menu. But I want this photo to be specific to the user who is logged in with playfab, I want to show this photo next to the usernames in the rooms where the photon and usernames are listed. Is it possible? Can you guide me, what should I do? I am sharing the link of the plugin I mentioned and the code file I used.

The second code file is the code file of the prefab converted game object containing the username of the users joining the room.

https://github.com/yasirkula/UnityNativeGallery

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using PlayFab;
using PlayFab.ClientModels;
using System;
using System.IO;


public class PlayFabManager : MonoBehaviour
{
    [Header("UI")]
    public Text messageText,isim ;
    public InputField usernameInput;
    public InputField emailInput;
    public InputField passwordInput;
    public GameObject Panel
    public Image profilepicture;
    private string Email;
    private string Username;
    private string Password;
    
    private PlayFabAuthService _AuthService = PlayFabAuthService.Instance;




public void profılepıcture()
{
	GaleridenResimCek( 1024 );
}


    private void GaleridenResimCek( int maksimumBuyukluk )
{
	NativeGallery.Permission izin = NativeGallery.GetImageFromGallery( ( konum ) =>
			                                                                {
	Debug.Log( "Seçilen resmin konumu: " + konum );
	if( konum != null )
{ 	
Texture2D texture = NativeGallery.LoadImageAtPath( konum, maksimumBuyukluk );
System.IO.File.Copy(konum, Application.persistentDataPath + "/SavedImage.png", true);
if ( texture == null )
{
Debug.Log( konum + " konumundaki resimden bir texture oluşturulamadı." );
return;
}
profilepicture.sprite = Sprite.Create(texture, new Rect(0f, 0f, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100.0f);		
				  }
}, "Bir resim seçin", "image/png" );
			
Debug.Log( "İzin durumu: " + izin );
		
}




    public void RegisterButton()
    {
        if (passwordInput.text.Length < 6)
        {
            messageText.text = "Şifreniz en az 6 karakter içermelidir!";
            return;
        }
        if (usernameInput.text.Length < 6)
        {
            messageText.text = "Kullanıcı Adı 3-20 Karakter Arası Olmalıdır!";
            return;
        }


        var request = new RegisterPlayFabUserRequest
            {
               Email = emailInput.text,
               Password = passwordInput.text,
               Username = usernameInput.text,
               RequireBothUsernameAndEmail = true


            };
        PlayFabClientAPI.RegisterPlayFabUser(request, OnRegisterSuccess, OnError);
    }


    void OnRegisterSuccess(RegisterPlayFabUserResult result)
    {
        messageText.text = "Kayıt Yapıldı, Giriş Yapabilirsiniz";
        Username = PlayerPrefs.GetString("Username");
        Password = PlayerPrefs.GetString("Password");
        PlayerPrefs.Save();
    }


    void OnError(PlayFabError error)
    {
        switch (error.Error)
        {
            case PlayFabErrorCode.InvalidEmailAddress:
            case PlayFabErrorCode.InvalidPassword:
            case PlayFabErrorCode.InvalidEmailOrPassword:
                messageText.text = "Geçersiz  Şifre/Kullanıcı Adı/Email";
                break;
            case PlayFabErrorCode.UnknownError:
                messageText.text = "İnternet Bağlantınızı Kontrol Edin Ve Uygulamayı Yeniden Başlatın";
                break;
            case PlayFabErrorCode.InvalidAccount:
            case PlayFabErrorCode.InvalidUsername:
                messageText.text = "Geçersiz";
                break;


        }


        messageText.text = error.ErrorMessage;
        Debug.Log(error.GenerateErrorReport());
    }


    public void LoginButton()
    {
        PlayFabClientAPI.LoginWithPlayFab(new LoginWithPlayFabRequest
        {
            Username = "xxx",
            Password = "123456",
            InfoRequestParameters = new GetPlayerCombinedInfoRequestParams
            {
                GetUserAccountInfo = true
            }
        }, result => {   
            isim.text = result.InfoResultPayload.AccountInfo.Username;
        }, error => {
            Debug.LogError(error.GenerateErrorReport());
        });


        var request = new LoginWithPlayFabRequest
        {
            Password = passwordInput.text,
            Username = usernameInput.text


        };
        PlayFabClientAPI.LoginWithPlayFab(request, OnLoginSuccess, OnError);


        PlayerPrefs.SetString("Username", usernameInput.text);
        PlayerPrefs.SetString("Password", passwordInput.text);
        PlayerPrefs.Save();
    }


    public void ResetPasswordButton()
    {
        var request = new SendAccountRecoveryEmailRequest
        {
            Email = emailInput.text,
            TitleId = "xxxx"
        };
        PlayFabClientAPI.SendAccountRecoveryEmail(request, OnPasswordReset, OnError);
    }


    private void OnPasswordReset(SendAccountRecoveryEmailResult result)
    {
        messageText.text = "Şifre Sıfırlama Bağlantısı Mail Adresinize Gönderildi";
    }


    void OnLoginSuccess(LoginResult result)
    {


        Debug.LogFormat("Logged In as: {0}", result.PlayFabId);
        messageText.text = "Giriş Yapıldı";
        Debug.Log("Giriş Başarılı");
        isim.text = Username;
     	Panel.SetActive(false);
    }


    void Login()
    {


        if (Username ==string.Empty && Password == string.Empty)
        {


            Debug.Log("Kutucuklar Boş");
        }
        else
        {
            Debug.Log("Zaten Giriş Yapıldı");
   
            var request = new LoginWithPlayFabRequest
            {
                Password = Password,
                Username = Username
            };
            PlayFabClientAPI.LoginWithPlayFab(request, OnLoginSuccess, OnError);
 }
  }



 void Start()
    {		
	if (File.Exists(Application.persistentDataPath + "/SavedImage.png"))
	{
	Texture2D texture = NativeGallery.LoadImageAtPath(Application.persistentDataPath + "/SavedImage.png", 1024);
	profilepicture.sprite = Sprite.Create(texture, new Rect(0f, 0f, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100.0f); ;
	}
	  _AuthService.InfoRequestParams = InfoRequestParams;
	   Username = PlayerPrefs.GetString("Username");
          Password = PlayerPrefs.GetString("Password");
          Login();
	 }
}





using Photon.Pun;
using Photon.Realtime;
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using UnityEngine.UI;


public class playerlistprefab : MonoBehaviourPunCallbacks
{
 




    [SerializeField]
    private Text _text;
    [SerializeField] private string nickName;


    public Player Player { get; private set; }


    public void SetPlayerInfo(Player player)
    {
        Player = player;
        _text.text = player.NickName;
      
    }
 private void Awake()
    {
        nickName = PlayerPrefs.GetString("Username");
        
    }


}


unity3dphotonAuthentication
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Made Wang avatar image
Made Wang answered

You can upload the chosen avatar to some external avatar hosting service and then call UpdateAvatarUrl to add the returned URL to the player's profile. You can call GetPlayerProfile when needed or get it directly at login as written in your code. After getting the URL, you can use some http download methods to get the avatar.

2 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

omerdruu avatar image omerdruu commented ·

Thank you very much for your comment. I did some research and saw that external avatar hosting services are also paid. I wonder if I can fix the problem without using this service. I save the image that the user chooses during registration into application.persistentDataPath. Then, with the File.Exists method, I can display this image in the list of players joining the room in the lobby panel if there is a photo in Application.persistentDataPath. But the same image is shown for each user. How do I set this image to be specific to each user. After all i can get the location of the image and load the image from this patht. I also think that it can be displayed privately for each user. I'm just thinking, I wanted to ask if my thought would be possible. Thank you so much again

0 Likes 0 ·
Made Wang avatar image Made Wang omerdruu commented ·

As far as I know, application.persistentDataPath is the path where the local file is stored, if you want to get the player's avatar in the local path, then you need to pre-store the player's avatar and distinguish all the avatars by name.

For multiplayer online games, each user's avatar should be downloaded through the network, we still recommend using an external avatar hosting service to store the image and store the url in PlayFab.

Other than that, you can try to store the avatar in the entity file. But it should be noted that if your title is in live mode then this will incur some charges, refer to Pricing Meters - PlayFab | Microsoft Docs for billing methods.

1 Like 1 ·
omerdruu avatar image
omerdruu answered

I did some research and as you said, I decided to store the profile picture of the users in the entity file.

https://docs.microsoft.com/en-us/gaming/playfab/features/data/entities/quickstart

I followed this link, but now there are errors for me.

public class resimplayfab : MonoBehaviour
{
	public Image profilep;
	public string entityId; // Id representing the logged in player
	public string entityType; // entityType representing the logged in player
	private readonly Dictionary<string, string> _entityFileJson = new Dictionary<string, string>();
	private readonly Dictionary<string, string> _tempUpdates = new Dictionary<string, string>();
	public string ActiveUploadFileName;
	public string NewFileName;
	public int GlobalFileLock = 0; // Kind of cheap and simple way to handle this kind of lock


	public void tıkla()
	{
		GaleridenResimCek(1024);


	}
	void OnLogin(PlayFab.ClientModels.LoginResult result)
	{
		entityId = result.EntityToken.Entity.Id;
		// The expected entity type is title_player_account.
		entityType = result.EntityToken.Entity.Type;
	}
	private void GaleridenResimCek(int maksimumBuyukluk)
	{
		NativeGallery.Permission izin = NativeGallery.GetImageFromGallery((konum) =>
		{
			Debug.Log("Seçilen resmin konumu: " + konum);
			if (konum != null)
			{
				// Seçilen resmi bir Texture2D'ye çevir
				Texture2D texture = NativeGallery.LoadImageAtPath(konum, maksimumBuyukluk);
				


				if (texture == null)
				{


					Debug.Log(konum + " konumundaki resimden bir texture oluşturulamadı.");
					return;
				}


				profilep.sprite = Sprite.Create(texture, new Rect(0f, 0f, texture.width, texture.height), new Vector2(0.5f, 0.5f), 100.0f);
			}
		}, "Bir resim seçin", "image/png");


		Debug.Log("İzin durumu: " + izin);


	}


	void OnPlayFabError(PlayFabError error)
    {
		Debug.Log(error.GenerateErrorReport());
	}
	void OnSharedFailure(PlayFabError error)
	{
		Debug.LogError(error.GenerateErrorReport());
		GlobalFileLock -= 1;
	}
	void UploadFile(string fileName)
	{


		if (GlobalFileLock != 0)
			throw new Exception("This example overly restricts file operations for safety. Careful consideration must be made when doing multiple file operations in parallel to avoid conflict.");


		ActiveUploadFileName = fileName;


		GlobalFileLock += 1; // Start InitiateFileUploads
		var request = new PlayFab.DataModels.InitiateFileUploadsRequest
		{
			Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
			FileNames = new List<string> { ActiveUploadFileName },
		};
		PlayFabDataAPI.InitiateFileUploads(request, OnInitFileUpload, OnInitFailed);
	}
	void OnInitFailed(PlayFabError error)
	{
		if (error.Error == PlayFabErrorCode.EntityFileOperationPending)
		{
			// This is an error you should handle when calling InitiateFileUploads, but your resolution path may vary
			GlobalFileLock += 1; // Start AbortFileUploads
			var request = new PlayFab.DataModels.AbortFileUploadsRequest
			{
				Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
				FileNames = new List<string> { ActiveUploadFileName },
			};
			PlayFabDataAPI.AbortFileUploads(request, (result) => { GlobalFileLock -= 1; UploadFile(ActiveUploadFileName); }, OnSharedFailure); GlobalFileLock -= 1; // Finish AbortFileUploads
			GlobalFileLock -= 1; // Failed InitiateFileUploads
		}
		else
			OnSharedFailure(error);
	}
	void OnInitFileUpload(PlayFab.DataModels.InitiateFileUploadsResponse response)
	{
		Texture2D tex = (Texture2D)profilep.mainTexture;
		tex.ReadPixels(new Rect(0, 0, profilep.mainTexture.width, profilep.mainTexture.height), 0, 0);
		tex.Apply();
		byte[] bytes = tex.EncodeToPNG();


		GlobalFileLock += 1; // Start SimplePutCall
		PlayFabHttp.SimplePutCall(response.UploadDetails[0].UploadUrl,
			bytes,
			FinalizeUpload,
			error => { Debug.Log(error); }
		);
		GlobalFileLock -= 1; // Finish InitiateFileUploads
	}
	void FinalizeUpload(byte[] obj)
	{
		GlobalFileLock += 1; // Start FinalizeFileUploads
		var request = new PlayFab.DataModels.FinalizeFileUploadsRequest
		{
			Entity = new PlayFab.DataModels.EntityKey { Id = entityId, Type = entityType },
			FileNames = new List<string> { ActiveUploadFileName },
		};
		PlayFabDataAPI.FinalizeFileUploads(request, OnUploadSuccess, OnSharedFailure);
		GlobalFileLock -= 1; // Finish SimplePutCall
	}
	void OnUploadSuccess(PlayFab.DataModels.FinalizeFileUploadsResponse result)
	{
		Debug.Log("File upload success: " + ActiveUploadFileName);
		GlobalFileLock -= 1; // Finish FinalizeFileUploads
	}
}


result: i get this error: /File/InitiateFileUploads: Invalid input parameters EntityKey: Type or TypeString is required. EntityKey: Id is required. EntityKey: is not an allowed value of Type.

I shared the code I used for playfab user login in my question. I'm using LoginWithPlayFab for this. And I think the error I got is that I do not access the id and type in the entity key at the beginning. I guess I can't get this part to work properly:

void Login() { var request = new PlayFab.ClientModels.LoginWithCustomIDRequest { CustomId = SystemInfo.deviceUniqueIdentifier, CreateAccount = true, }; PlayFabClientAPI.LoginWithCustomID(request, OnLogin, OnSharedFailure); }

Are my findings so far correct? If so, can you help me how to solve this problem by using LoginWithPlayFab instead of using LoginWithCustomIDRequest? @Made Wang

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.