记录下开发中会使用的一些通用api,避免之后每次都去查看过去工程的代码。
1.记录运行日志:
/// <summary>
/// 保持的日志文件名称
/// </summary>
public const string saveLogFileName = "runLog.txt";
private void Awake()
{
Application.logMessageReceived += SaveLog;
}
private string tempBeforeLog;
/// <summary>
/// 保存日志
/// </summary>
/// <param name="condition"></param>
/// <param name="stackTrace"></param>
/// <param name="type"></param>
private void SaveLog(string condition, string stackTrace, LogType type)
{
if (condition.Equals(tempBeforeLog))//如果是相同的信息就不再写入
{
return;
}
string path = GetSaveLogPath();
using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite))
{
using (StreamWriter sw = new StreamWriter(fs))
{
fs.Seek(0, SeekOrigin.End);
sw.WriteLine(DateTime.Now.ToString("G") + " " + type.ToString() + ":" + condition + "{" + stackTrace + "}");
}
}
tempBeforeLog = condition;
}
2.监听程序退出和编辑器下的停止运行:
Application.wantsToQuit += OnQuitEvent;
#if UNITY_EDITOR
EditorApplication.wantsToQuit += OnQuitEvent;
#endif
//返回false回阻止发布后的程序关闭
private bool OnQuitEvent()
{
return true;
}
3.监听UGUI窗口变化:
public void OnRectTransformDimensionsChange()
{
Debug.Log("窗口大小发生改变");
}
4.在Awake之前执行
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void AwakeBefore()
{
Debug.Log("在Awake之前调用");
}
5.隐藏标题栏
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern long GetWindowLong(IntPtr hwd, int nIndex);
[DllImport("user32.dll")]
public static extern void SetWindowLong(IntPtr hwd, int nIndex, long dwNewLong);
[DllImport("user32")]
static extern int EnumWindows(EnumWindowsCallBack lpEnumFunc, IntPtr lParam);
[DllImport("user32")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, ref IntPtr lpdwProcessId);
[DllImport("user32.dll", EntryPoint = "FindWindow")]
public static extern System.IntPtr FindWindow(System.String className, System.String windowName);
/// <summary>
/// 窗口风格
/// </summary>
const int GWL_STYLE = -16;
/// <summary>
/// 标题栏
/// </summary>
const int WS_CAPTION = 0x00c00000;
/// <summary>
/// 外边框显示隐藏
/// </summary>
const uint WS_VISIBLE = 0x10000000;
private void Awake()
{
#if !UNITY_EDITOR && UNITY_STANDALONE_WIN
HideTitle();
Screen.SetResolution(defaultWindowWidth,defaultWindowHeight,false);
#endif
}
private static void HideTitle()
{
GetSelfWindows();
IntPtr window = myWindowHandle;//GetForegroundWindow();
//GetForegroundWindow是获取的当前焦点程序窗口,在启动的一瞬间如果选中别的窗口,则会出现将选中的窗口标题栏隐藏的问题。
var wl = GetWindowLong(window, GWL_STYLE);
wl &= ~WS_CAPTION & WS_VISIBLE;
SetWindowLong(window, GWL_STYLE, wl);
}
private static IntPtr myWindowHandle;
/// <summary>
/// 获取程序自身窗口
/// </summary>
public static void GetSelfWindows()
{
IntPtr handle = (IntPtr)System.Diagnostics.Process.GetCurrentProcess().Id; //获取进程ID
EnumWindows(new EnumWindowsCallBack(EnumWindCallback), handle); //枚举查找本窗口
//打包时的ProductName
//myWindowHandle = FindWindow(null, "WindowTitleChange");
}
隐藏后,会出现UGUI鼠标点击位置识别偏差问题,应该是差了一个标题栏的高度,在awake手动设置一下分辨率即可。
6.坐标旋转
/// <summary>
/// 围绕某点旋转指定角度
/// </summary>
/// <param name="position">自身坐标</param>
/// <param name="center">旋转中心</param>
/// <param name="axis">围绕旋转轴</param>
/// <param name="angle">旋转角度</param>
/// <returns></returns>
public static Vector3 RotateRound(Vector3 position, Vector3 center, Vector3 axis, float angle)
{
return Quaternion.AngleAxis(angle, axis) * (position - center) + center;
}
7 清理所有进程内存
[DllImport("psapi.dll")]
private static extern int EmptyWorkingSet(IntPtr hwProc);
public static void ClearMemory()
{
GC.Collect();
GC.WaitForPendingFinalizers();
Process[] processes = Process.GetProcesses();
foreach (Process process in processes)
{
try
{
EmptyWorkingSet(process.Handle);
}
catch (Exception ex)
{
Debug.Log(ex.Message);
}
}
}
8 UGUI识别当前鼠标是否位于UI控件上
public static bool GetOverUI()
{
bool isOver=false;
EventSystem uiEventSystem = EventSystem.current;
if (uiEventSystem != null)
{
PointerEventData uiPointerEventData = new PointerEventData(uiEventSystem);
uiPointerEventData.position = Input.mousePosition;
List<RaycastResult> uiRaycastResultCache = new List<RaycastResult>();
uiEventSystem.RaycastAll(uiPointerEventData, uiRaycastResultCache);
if (uiRaycastResultCache.Count > 0)
{
Transform obj = uiRaycastResultCache[0].gameObject.transform;
isOver = obj is RectTransform;
}
}
return isOver;
}
9 Inspector 面板显示按钮,调用方法
#if UNITY_EDITOR
[UnityEditor.CustomEditor(typeof(TestClass))]
public class ViveInputAdapterManagerEditor : UnityEditor.Editor
{
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
if (!Application.isPlaying)
{
var targetNode = target as TestClass;
if (targetNode == null)
{
return;
}
GUILayout.BeginHorizontal();
if (GUILayout.Button("自定义按钮"))
{
targetNode.Init();
}
GUILayout.EndHorizontal();
}
}
}
#endif
10.获取模型中心点坐标
public static Vector3 GetModelsCenter(GameObject go)
{
Vector3 center = Vector3.zero;
MeshRenderer mr = go.GetComponent<MeshRenderer>();
if (mr != null)
{
center = mr.bounds.center;
}
else
{
MeshRenderer[] mrs = go.GetComponentsInChildren<MeshRenderer>();
for (int i = 0; i < mrs.Length; i++)
{
center += mrs[i].bounds.center;
}
if (mrs.Length > 0)
{
center /= mrs.Length;
}
}
return center;
}
11.计算相对坐标
/// <summary>
/// 获取position相对origin的坐标
/// </summary>
/// <param name="origin"></param>
/// <param name="position"></param>
/// <returns></returns>
private Vector3 GetRelativePosition(Vector3 origin, Vector3 position)
{
if (origin == Vector3.zero)
{
return position;
}
Vector3 distance = position - origin;
Vector3 relativePosition = Vector3.zero;
relativePosition.x = Vector3.Dot(distance, new Vector3(origin.x, 0, 0).normalized);
relativePosition.y = Vector3.Dot(distance, new Vector3(0, origin.y, 0).normalized);
relativePosition.z = Vector3.Dot(distance, new Vector3(0, 0, origin.z).normalized);
return relativePosition;
}