inline float SoftUnityGet2DClipping (in float2 position, in float4 clipRect)
{
float2 xy = (position.xy-clipRect.xy)/float2(_ClipSoftX,_ClipSoftY)*step(clipRect.xy, position.xy);
float2 zw = (clipRect.zw-position.xy)/float2(_ClipSoftX,_ClipSoftY)*step(position.xy,clipRect.zw);
float2 factor = clamp(0, zw, xy);
return saturate(min(factor.x,factor.y));
}
c.a *= SoftUnityGet2DClipping(i.wpos.xy, float4(_MinX, _MinY, _MaxX, _MaxY));需要将RectMask2D的区域传给3d物品显示的Shader,然后控制3d物体的透明度,不在范围内的设置为0
首先修改使用到的Shader,添加(使用到的参数声明忽略):
//Properties
_MinX ("Min X", Float) = -10
_MaxX ("Max X", Float) = 10
_MinY ("Min Y", Float) = -10
_MaxY ("Max Y", Float) = 10
//顶点函数
o.wpos = mul(unity_ObjectToWorld, v.vertex).xyz;
//片元函数
c.a *= (i.wpos.x >= _MinX );
c.a *= (i.wpos.x <= _MaxX);
c.a *= (i.wpos.y >= _MinY);
c.a *= (i.wpos.y <= _MaxY);
c.rgb *= c.a;获取RectMask2D的区域,传递需要裁剪的3D物体
Vector3[] corners = new Vector3[4];
RectTransform rectTransform = GetComponent<RectTransform>("UIGirdlView/Viewport");
rectTransform.GetWorldCorners(corners);
m_GridCorners[0] = corners[0].x;
m_GridCorners[1] = corners[0].y;
m_GridCorners[2] = corners[2].x;
m_GridCorners[3] = corners[2].y;
var items = transform.GetComponentsInChildren<Renderer>();
foreach (var item in items)
{
var m = item.material;
m.SetFloat("_MinX", m_GridCorners[0]);
m.SetFloat("_MinY", m_GridCorners[1]);
m.SetFloat("_MaxX", m_GridCorners[2]);
m.SetFloat("_MaxY", m_GridCorners[3]);
}对于在Shader使用Toggle标志的参数
[Toggle(_KEYWORD0_ON)] _Keyword0("Keyword 0", Float) = 0
#ifdef _KEYWORD0_ON
#else
#endif可以通过以下C#控制开关
m_Image.material.EnableKeyword("_KEYWORD0_ON");
m_Image.material.DisableKeyword("_KEYWORD0_ON");可以直接用对ui的输入操作来对3d物体进行交互,例如添加父物体是ui的一个空image,勾选Raycast target,对他做IpointClickHandler等,后影响3D物体即可
public static void RestartOrKillApp()
{
if (Application.isEditor) return;
if (Application.platform == RuntimePlatform.Android)
{
using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
const int kIntent_FLAG_ACTIVITY_CLEAR_TASK = 0x00008000;
const int kIntent_FLAG_ACTIVITY_NEW_TASK = 0x10000000;
var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
var pm = currentActivity.Call<AndroidJavaObject>("getPackageManager");
var intent = pm.Call<AndroidJavaObject>("getLaunchIntentForPackage", Application.identifier);
intent.Call<AndroidJavaObject>("setFlags", kIntent_FLAG_ACTIVITY_NEW_TASK | kIntent_FLAG_ACTIVITY_CLEAR_TASK);
currentActivity.Call("startActivity", intent);
currentActivity.Call("finish");
var process = new AndroidJavaClass("android.os.Process");
int pid = process.CallStatic<int>("myPid");
process.CallStatic("killProcess", pid);
}
}
else if (Application.platform == RuntimePlatform.IPhonePlayer)
{
//测试只有下面俩种类型好用,FatalError几率卡界面
UnityEngine.Diagnostics.Utils.ForceCrash(UnityEngine.Diagnostics.ForcedCrashCategory.FatalError);
//UnityEngine.Diagnostics.Utils.ForceCrash(UnityEngine.Diagnostics.ForcedCrashCategory.PureVirtualFunction);
}
else
{
Application.Quit();
}
}需要扩展一下UnityWebRequestAsyncOperation
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using UnityEngine.Networking;
public static class ExtensionMethods
{
public static TaskAwaiter<object> GetAwaiter(this UnityWebRequestAsyncOperation op)
{
var tcs = new TaskCompletionSource<object>();
op.completed += (obj) =>
{
tcs.SetResult(null);
};
return tcs.Task.GetAwaiter();
}
}可以用uniwebview插件。
可能都有试过,给文本组件的物体添加了ContentSizeFiter组件然后去获取PreferredHeight的情况,发现PreferredHeight并不是设置文本后的,此时可以留意设置文本和获取长度时物体是不是被隐藏了,ContentSizeFiter在被激活的时候才会生效。
ios facebook内置浏览器打开链接把参数都转为小写,此时如果使用了一些大些内容,被转化后解密或读取就会出现问题。
解决:寻找一种全是小写参数的内容,例如将参数Base64处理后在将大写字母转化为(_%l)的形式,缺点变长了很多
function string.lowerBase64Encode(data)
local data = string.base64Encoding(data)
return data:gsub("%u",function(sub)
return '_' .. string.lower(sub)
end)
end
function string.lowerBase64Decode(data)
local data = data:gsub("_%l",function(sub)
return string.upper(sub[2])
end)
return string.base64Decoding(data)
end只需要修改Project Settings下的Player的Active Input Handling为Input Manager(Old)
