Unity3D___微信小游戏常用API总结
获取用户信息
游戏初始化,想要获取玩家的信息还需要在mp中进行隐私设置。
WX.InitSDK((code) =>
{
// 打印屏幕信息
var systemInfo = WX.GetSystemInfoSync();
Debug.Log($"{systemInfo.screenWidth}:{systemInfo.screenHeight}, {systemInfo.windowWidth}:{systemInfo.windowHeight}, {systemInfo.pixelRatio}");
// 创建用户信息获取按钮,在底部区域创建一个300高度的透明区域
// 首次获取会弹出用户授权窗口, 可通过右上角-设置-权限管理用户的授权记录
var canvasWith = (int)(systemInfo.screenWidth * systemInfo.pixelRatio);
var canvasHeight = (int)(systemInfo.screenHeight * systemInfo.pixelRatio);
var buttonHeight = (int)(canvasWith / 1080f * 300f);
infoButton = WX.CreateUserInfoButton(0, canvasHeight - buttonHeight, canvasWith, buttonHeight, "zh_CN", false);
infoButton.OnTap((userInfoButonRet) =>
{
Debug.Log(JsonUtility.ToJson(userInfoButonRet.userInfo));
txtUserInfo.text = $"nickName:{userInfoButonRet.userInfo.nickName}, avartar:{userInfoButonRet.userInfo.avatarUrl}";
//userInfoButonRet.userInfo.nickName 获取用户昵称
//userInfoButonRet.userInfo.avatarUrl 获取用户图片
});
Debug.Log("infoButton Created");
});
游戏分享
public void OnShareClick()
{
WX.ShareAppMessage(new ShareAppMessageOption()
{
title = "分享标题xxx",
imageUrl = "https://inews.gtimg.com/newsapp_bt/0/12171811596_909/0",
});
}
利用PlayerPref数据持久化
和在Unity中使用方法差不多
// 注意!!! PlayerPrefs为同步接口,iOS高性能模式下为"跨进程"同步调用,会阻塞游戏线程,请避免频繁调用
PlayerPrefs.SetString("mystringkey", "myestringvalue");
PlayerPrefs.SetInt("myintkey", 123);
PlayerPrefs.SetFloat("myfloatkey", 1.23f);
Debug.Log($"PlayerPrefs mystringkey:{PlayerPrefs.GetString("mystringkey")}");
Debug.Log($"PlayerPrefs myintkey:{PlayerPrefs.GetInt("myintkey")}");
Debug.Log($"PlayerPrefs myfloatkey:{PlayerPrefs.GetFloat("myfloatkey")}");
文本输入框调用手机键盘输入
将脚本挂载在InputField上即可。
public class Inputs : MonoBehaviour, IPointerClickHandler, IPointerExitHandler
{
public InputField input;
public Text text;
private bool isShowKeyboad = false;
public void OnPointerClick(PointerEventData eventData)
{
ShowKeyboad();
}
public void OnPointerExit(PointerEventData eventData)
{
// 隐藏输入法
if (!input.isFocused)
{
HideKeyboad();
}
}
public void OnInput(OnKeyboardInputListenerResult v)
{
Debug.Log("onInput");
Debug.Log(v.value);
text.text = v.value;
if (input.isFocused)
{
input.text = v.value;
}
}
public void OnConfirm(OnKeyboardInputListenerResult v)
{
// 输入法confirm回调
Debug.Log("onConfirm");
Debug.Log(v.value);
HideKeyboad();
}
public void OnComplete(OnKeyboardInputListenerResult v)
{
// 输入法complete回调
Debug.Log("OnComplete");
Debug.Log(v.value);
HideKeyboad();
}
private void ShowKeyboad()
{
if (!isShowKeyboad)
{
WX.ShowKeyboard(new ShowKeyboardOption()
{
defaultValue = "",
maxLength = 20,
confirmType = "go"
});
//绑定回调
WX.OnKeyboardConfirm(OnConfirm);
WX.OnKeyboardComplete(OnComplete);
WX.OnKeyboardInput(OnInput);
isShowKeyboad = true;
}
}
private void HideKeyboad()
{
if (isShowKeyboad)
{
WX.HideKeyboard(new HideKeyboardOption());
//删除掉相关事件监听
WX.OffKeyboardInput(OnInput);
WX.OffKeyboardConfirm(OnConfirm);
WX.OffKeyboardComplete(OnComplete);
isShowKeyboad = false;
}
}
}
音效控制
和在Unity中使用方法差不多
public class AudioManager : MonoBehaviour
{
public AudioSource AudioSource;
public AudioClip AudioClipLong;
public AudioClip AudioClipShort;
public Slider VolumeSlider;
private void Start()
{
VolumeSlider.value = AudioSource.volume;
VolumeSlider.onValueChanged.AddListener((_) =>
{
OnVolumeChanged(_);
});
}
void OnVolumeChanged(float volume)
{
AudioSource.volume = volume;
}
/// <summary>
/// 循环播放
/// </summary>
public void PlayLong()
{
AudioSource.clip = AudioClipLong;
AudioSource.loop = true;
AudioSource.Play();
}
/// <summary>
/// 播放一次
/// </summary>
public void PlayShort()
{
AudioSource.clip = AudioClipShort;
AudioSource.loop = false;
AudioSource.Play();
}
/// <summary>
/// 暂停播放
/// </summary>
public void Pause()
{
AudioSource.Pause();
}
/// <summary>
/// 恢复播放
/// </summary>
public void Resume()
{
AudioSource.UnPause();
}
/// <summary>
/// 关闭声音
/// </summary>
public void Stop()
{
AudioSource.Stop();
}
}
获取微信字体
// fallbackFont作为旧版本微信或者无法获得系统字体文件时的备选CDN URL
var fallbackFont = Application.streamingAssetsPath + "/Fz.ttf";
WX.GetWXFont(fallbackFont, (font) =>
{
if (font != null)
{
txtTestWXFont.font = font;
}
});
微信文件系统存储
public void OnFileSystemManagerClick()
{
// 扫描文件系统目录
fs.Stat(new WXStatOption
{
path = env.USER_DATA_PATH + "/__GAME_FILE_CACHE",
recursive = true,
success = (succ) =>
{
Debug.Log($"stat success");
foreach (var file in succ.stats)
{
Debug.Log($"stat info. {file.path}, " +
$"{file.stats.size}," +
$"{file.stats.mode}," +
$"{file.stats.lastAccessedTime}," +
$"{file.stats.lastModifiedTime}");
}
},
fail = (fail) =>
{
Debug.Log($"stat fail {fail.errMsg}");
}
});
// 同步接口创建目录(请勿在游戏过程中频繁调用同步接口)
var errMsg = fs.MkdirSync(env.USER_DATA_PATH + "/mydir", true);
// 异步写入文件
fs.WriteFile(new WriteFileParam
{
filePath = env.USER_DATA_PATH + "/mydir/myfile.txt",
encoding = "utf8",
data = System.Text.Encoding.UTF8.GetBytes("Test FileSystemManager"),
success = (succ) =>
{
Debug.Log($"WriteFile succ {succ.errMsg}");
// 异步读取文件
fs.ReadFile(new ReadFileParam
{
filePath = env.USER_DATA_PATH + "/mydir/myfile.txt",
encoding = "utf8",
success = (succ) =>
{
Debug.Log($"ReadFile succ. stringData(utf8):{succ.stringData}");
},
fail = (fail) =>
{
Debug.Log($"ReadFile fail {fail.errMsg}");
}
});
// 异步以无编码(二进制)方式读取
fs.ReadFile(new ReadFileParam
{
filePath = env.USER_DATA_PATH + "/mydir/myfile.txt",
encoding = "",
success = (succ) =>
{
Debug.Log($"ReadFile succ. data(binary):{succ.binData.Length}, stringData(utf8):{System.Text.Encoding.UTF8.GetString(succ.binData)}");
},
fail = (fail) =>
{
Debug.Log($"ReadFile fail {fail.errMsg}");
}
});
},
fail = (fail) =>
{
Debug.Log($"WriteFile fail {fail.errMsg}");
},
complete = null
});
}
获取微信用户唯一标识OpenId
两种方式,均用协程
/// <summary>
/// 调用云函数获取用户OpenID
/// </summary>
/// <returns></returns>
IEnumerator CallFunc()
{
WX.cloud.Init(new CallFunctionInitParam{
env="cloud1-2gdeopavbdf6d731",
});
WX.cloud.CallFunction(new CallFunctionParam
{
name = "login",
data = "{}",
success = (res) =>
{
Debug.Log("[云函数] [login] user openid: " + res.result);
if (!string.IsNullOrEmpty(res.result))
{
Dictionary<string, object> jsonDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(res.result);
Debug.Log("真正获取openid:" + jsonDict["openid"].ToString());
}
},
fail = (err) =>
{
Debug.Log("Fail" + err.result);
}
});
yield return null;
}
/// <summary>
/// 利用UnityWebRequest获取
/// </summary>
/// <returns></returns>
IEnumerator GetAccessToken()
{
bool flag = true;
string jsCode = "";
WX.Login(new LoginOption
{
success = (res) => {
jsCode = res.code;
}
,
complete = (res) =>
{
flag = false;
}
});
while (flag)
{
yield return null;
}
string url = "https://api.weixin.qq.com/sns/jscode2session?appid=wx87659b52c2900cfb&secret=7593e6c0fe683d4ac03828e59cadd566&js_code=" + jsCode+"&grant_type=authorization_code";
Debug.Log(url);
UnityWebRequest request = UnityWebRequest.Get(url);
yield return request.SendWebRequest();
if(string.IsNullOrEmpty(request.error))
{
// access token获取成功,将结果发送给Unity游戏
Debug.Log(request.downloadHandler.text);
OnAccessTokenReceived(request.downloadHandler.text);
}
else
{
// 获取access token失败
Debug.Log(request.error);
}
}
public void OnAccessTokenReceived(string json)
{
// 将json字符串反序列化为AccessTokenResponse对象
AccessTokenResponse accessTokenResponse = JsonUtility.FromJson<AccessTokenResponse>(json);
if (accessTokenResponse.access_token != null)
{
// access token获取成功,可以在这里实现验证和其他操作。
Debug.Log("Access token received: " + accessTokenResponse.access_token
+"OpenID:"+ accessTokenResponse.openid
);
}
else
{
// access token获取失败
Debug.Log("Error: " + accessTokenResponse.errmsg);
}
}
[System.Serializable]
public class AccessTokenResponse
{
public string access_token;
public int expires_in;
public string refresh_token;
public string openid;
public string scope;
public string errcode;
public string errmsg;
}
各种广告的api
using UnityEngine;
using WeChatWASM;
public class ADManager : MonoBehaviour
{
public WXBannerAd BannerAd;
public WXRewardedVideoAd RewardedVideoAd;
public WXCustomAd CustomAd;
private void Start()
{
WX.InitSDK((code) =>
{
CreateBannerAd();
CreateRewardedVideoAd();
CreateCustomAd();
});
}
/// <summary>
/// 创建一个固定在底部的广告
/// </summary>
private void CreateBannerAd()
{
BannerAd = WX.CreateFixedBottomMiddleBannerAd("adunit-c0b06553f23c5081", 30, 200);
}
public void ShowBannerAd()
{
BannerAd.Show((suc) => {
Debug.Log("显示成功");
}, (fail) => {
Debug.Log("显示失败");
});
}
public void HideBannerAd()
{
BannerAd.Hide();
}
public void DestroyBannerAd()
{
BannerAd.Destroy();
}
/// <summary>
/// 创建一个激励视频广告
/// </summary>
private void CreateRewardedVideoAd()
{
RewardedVideoAd = WX.CreateRewardedVideoAd(new WXCreateRewardedVideoAdParam()
{
adUnitId = "adunit-f8bd4231b2720db6",
});
RewardedVideoAd.OnLoad((res) =>
{
Debug.Log("RewardedVideoAd.OnLoad:" + JsonUtility.ToJson(res));
var reportShareBehaviorRes = RewardedVideoAd.ReportShareBehavior(new RequestAdReportShareBehaviorParam()
{
operation = 1,
currentShow = 1,
strategy = 0,
shareValue = res.shareValue,
rewardValue = res.rewardValue,
depositAmount = 100,
});
Debug.Log("ReportShareBehavior.Res:" + JsonUtility.ToJson(reportShareBehaviorRes));
});
RewardedVideoAd.OnError((err) =>
{
Debug.Log("RewardedVideoAd.OnError:" + JsonUtility.ToJson(err));
});
RewardedVideoAd.OnClose((res) =>
{
Debug.Log("RewardedVideoAd.OnClose:" + JsonUtility.ToJson(res));
});
RewardedVideoAd.Load();
}
public void ShowRewardedVideoAd()
{
RewardedVideoAd.Show();
}
public void DestroyRewardedVideoAd()
{
RewardedVideoAd.Destroy();
}
/// <summary>
/// 自定义广告类型
/// </summary>
private void CreateCustomAd()
{
CustomAd = WX.CreateCustomAd(new WXCreateCustomAdParam()
{
adUnitId = "adunit-2f150d9a6500399d",
adIntervals = 30,
style = {
left = 0,
top = 100,
},
});
CustomAd.OnLoad((res) =>
{
Debug.Log("CustomAd.OnLoad:" + JsonUtility.ToJson(res));
});
CustomAd.OnError((res) =>
{
Debug.Log("CustomAd.onError:" + JsonUtility.ToJson(res));
});
CustomAd.OnHide(() =>
{
Debug.Log("CustomAd.onHide:");
});
CustomAd.OnClose(() =>
{
Debug.Log("CustomAd.onClose");
});
}
public void ShowCustomAd()
{
CustomAd.Show();
}
public void HideCustomAd()
{
CustomAd.Hide();
}
public void DestroyCustomAd()
{
CustomAd.Destroy();
}
private void OnDestroy()
{
DestroyBannerAd();
DestroyRewardedVideoAd();
DestroyCustomAd();
}
}
微信排行榜
using System.IO;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using WeChatWASM;
[System.Serializable]
public class OpenDataMessage
{
// type 用于表明时间类型
public string type;
public string shareTicket;
public int score;
}
public class Ranking : MonoBehaviour
{
public Button ShowButton;
public Button ShareButton;
public Button ReportButton;
public RawImage RankBody;
public GameObject RankMask;
public GameObject RankingBox;
void Start()
{
WX.InitSDK((code) =>
{
Init();
});
/**
* 使用群排行功能需要特殊设置分享功能,详情可见链接
* https://developers.weixin.qq.com/minigame/dev/guide/open-ability/share/share.html
*/
WX.UpdateShareMenu(new UpdateShareMenuOption()
{
withShareTicket = true,
isPrivateMessage = true,
});
/**
* 群排行榜功能需要配合 WX.OnShow 来使用,整体流程为:
* 1. WX.UpdateShareMenu 分享功能;
* 2. 监听 WX.OnShow 回调,如果存在 shareTicket 且 query 里面带有启动特定 query 参数则为需要展示群排行的场景
* 3. 调用 WX.ShowOpenData 和 WX.GetOpenDataContext().PostMessage 告知开放数据域侧需要展示群排行信息
* 4. 开放数据域调用 wx.getGroupCloudStorage 接口拉取获取群同玩成员的游戏数据
* 5. 将群同玩成员数据绘制到 sharedCanvas
*/
WX.OnShow((OnShowCallbackResult res) =>
{
string shareTicket = res.shareTicket;
Dictionary<string, string> query = res.query;
if (!string.IsNullOrEmpty(shareTicket) && query != null && query["minigame_action"] == "show_group_list")
{
OpenDataMessage msgData = new OpenDataMessage();
msgData.type = "showGroupFriendsRank";
msgData.shareTicket = shareTicket;
string msg = JsonUtility.ToJson(msgData);
ShowOpenData();
WX.GetOpenDataContext().PostMessage(msg);
}
});
}
void ShowOpenData()
{
RankMask.SetActive(true);
RankingBox.SetActive(true);
//
// 注意这里传x,y,width,height是为了点击区域能正确点击,x,y 是距离屏幕左上角的距离,宽度传 (int)RankBody.rectTransform.rect.width是在canvas的UI Scale Mode为 Constant Pixel Size的情况下设置的。
/**
* 如果父元素占满整个窗口的话,pivot 设置为(0,0),rotation设置为180,则左上角就是离屏幕的距离
* 注意这里传x,y,width,height是为了点击区域能正确点击,因为开放数据域并不是使用 Unity 进行渲染而是可以选择任意第三方渲染引擎
* 所以开放数据域名要正确处理好事件处理,就需要明确告诉开放数据域,排行榜所在的纹理绘制在屏幕中的物理坐标系
* 比如 iPhone Xs Max 的物理尺寸是 414 * 896,如果排行榜被绘制在屏幕中央且物理尺寸为 200 * 200,那么这里的 x,y,width,height应当是 107,348,200,200
* x,y 是距离屏幕左上角的距离,宽度传 (int)RankBody.rectTransform.rect.width是在canvas的UI Scale Mode为 Constant Pixel Size的情况下设置的
* 如果是Scale With Screen Size,且设置为以宽度作为缩放,则要这要做一下换算,比如canavs宽度为960,rawImage设置为200 则需要根据 referenceResolution 做一些换算
* 不过不管是什么屏幕适配模式,这里的目的就是为了算出 RawImage 在屏幕中绝对的位置和尺寸
*/
CanvasScaler scaler = gameObject.GetComponent<CanvasScaler>();
var referenceResolution = scaler.referenceResolution;
var p = RankBody.transform.position;
WX.ShowOpenData(RankBody.texture, (int)p.x, Screen.height - (int)p.y, (int)((Screen.width / referenceResolution.x) * RankBody.rectTransform.rect.width), (int)((Screen.width / referenceResolution.x) * RankBody.rectTransform.rect.height));
}
void Init()
{
ShowButton.onClick.AddListener(() =>
{
ShowOpenData();
OpenDataMessage msgData = new OpenDataMessage();
msgData.type = "showFriendsRank";
string msg = JsonUtility.ToJson(msgData);
WX.GetOpenDataContext().PostMessage(msg);
});
RankMask.GetComponent<Button>().onClick.AddListener(() =>
{
RankMask.SetActive(false);
RankingBox.SetActive(false);
WX.HideOpenData();
});
ShareButton.onClick.AddListener(() =>
{
WX.ShareAppMessage(new ShareAppMessageOption()
{
title = "最强战力排行榜!谁是第一?",
query = "minigame_action=show_group_list",
imageUrl = "https://mmgame.qpic.cn/image/5f9144af9f0e32d50fb878e5256d669fa1ae6fdec77550849bfee137be995d18/0",
});
});
ReportButton.onClick.AddListener(() =>
{
OpenDataMessage msgData = new OpenDataMessage();
msgData.type = "setUserRecord";
msgData.score = Random.Range(1, 1000);
string msg = JsonUtility.ToJson(msgData);
Debug.Log(msg);
WX.GetOpenDataContext().PostMessage(msg);
});
}
}