热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Unity笔记—常用小功能整合

常用功能整理记录(一些比较简单的功能实现集合(网上找的一些比较好的解决方案)放在这里)目录控制台打印深拷贝物体跟随鼠

   常用功能整理记录(一些比较简单的功能实现集合(网上找的一些比较好的解决方案)放在这里)

目录

控制台打印

深拷贝

物体跟随鼠标移动

UI跟随玩家移动(Canvas在屏幕坐标覆盖或者世界坐标皆可)

简易存档工具

Sprite字体使用

防止鼠标射线穿透UI的API

UniWebview无法加载Https解决办法

AB包加载小工具

Singleton

Unity物体看向鼠标

Unity小程序发布

GoogleProtobuf使用学习链接

Adrressable教程






控制台打印

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class ConsoleToSceen : MonoBehaviour
{const int maxLines = 50;const int maxLineLength = 120;private string _logStr = "";private readonly List _lines = new List();void OnEnable() { Application.logMessageReceived += Log; }void OnDisable() { Application.logMessageReceived -= Log; }void Update() { }public void Log(string logString, string stackTrace, LogType type){foreach (var line in logString.Split(&#39;\n&#39;)){if (line.Length <= maxLineLength){_lines.Add(line);continue;}var lineCount = line.Length / maxLineLength + 1;for (int i = 0; i maxLines){_lines.RemoveRange(0, _lines.Count - maxLines);}_logStr = string.Join("\n", _lines);}void OnGUI(){GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity,new Vector3(Screen.width / 1200.0f, Screen.height / 800.0f, 1.0f));GUI.Label(new Rect(10, 10, 800, 370), _logStr, new GUIStyle() { fOntSize= 30 });}
}

深拷贝

public static T DeepCopyByReflection(T obj){if (obj is string || obj.GetType().IsValueType)return obj;object retval = Activator.CreateInstance(obj.GetType());FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);foreach (var field in fields){try{field.SetValue(retval, DeepCopyByReflection(field.GetValue(obj)));}catch { }}return (T)retval;}

物体跟随鼠标移动

private Vector3 cubeScreenPos;private Vector3 mouseScreenPos;private Vector3 objOffset;// 偏移private void OnMouseDown(){Vector3 screenPos = Camera.main.WorldToScreenPoint(transform.position);mouseScreenPos = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPos.z);objOffset = transform.position - Camera.main.ScreenToWorldPoint(mouseScreenPos);}private void OnMouseDrag(){//为什么要先把cube转化为屏幕坐标?这样可以保证cube的z轴坐标不变cubeScreenPos = Camera.main.WorldToScreenPoint(transform.position);mouseScreenPos.x = Input.mousePosition.x;mouseScreenPos.y = Input.mousePosition.y;mouseScreenPos.z = cubeScreenPos.z;Vector3 endPos = Camera.main.ScreenToWorldPoint(mouseScreenPos) + objOffset;//  transform.Translate(new Vector3(endPos.x, transform.position.y, transform.position.z) * Time.deltaTime, Space.World);//transform.Translate(new Vector3(endPos.x, endPos.y, endPos.z) * Time.deltaTime, Space.World);transform.position = new Vector3(endPos.x, transform.position.y, transform.position.z);// transform.}


UI跟随玩家移动(Canvas在屏幕坐标覆盖或者世界坐标皆可)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class UIContraller : MonoBehaviour
{public GameObject player;public Camera cam;// Update is called once per framevoid Update(){CalPosition();// Vector2 pos = Camera.main.WorldToScreenPoint(player.transform.position);// GetComponent().localPosition = pos;}public Vector3 Offset = new Vector3(0, 1, 0);private void CalPosition(){Vector3 vector3 = Vector3.zero;Vector3 screenPosition = cam.WorldToScreenPoint(player.transform.position + Offset);//将目标物体的坐标转化为屏幕坐标Vector3 uiPosition = Vector3.zero;//;//将得到的屏幕坐标转化为UGUI坐标if (RectTransformUtility.ScreenPointToWorldPointInRectangle(transform as RectTransform, screenPosition, null, out uiPosition)){uiPosition = new Vector3(Mathf.FloorToInt(uiPosition.x), Mathf.FloorToInt(uiPosition.y), Mathf.FloorToInt(uiPosition.z));transform.position = uiPosition;}}}

控制UI显示顺序:UI是根据摄像机控制的,canvas下的图层顺序没用,控制摄像机的深度值即可设置Canvas显示深度

世界坐标的Canvas和世界坐标比例100:1,设置Canvas缩放0.01,直接设置坐标即可

go.GetComponent().position = Entity.transform.position;

VSCode新版代码不提示:

搜索Snippet,settingJson中修改"editor.suggest.snippetsPreventQuickSuggestions": false


简易存档工具

using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;
public static class SaveJson
{public static void WriteToJson(string fileName, object data){var json = JsonUtility.ToJson(data, true);Debug.Log(json);var path = Path.Combine(Application.persistentDataPath, fileName);try{File.WriteAllText(path, json);}catch (System.Exception e){Debug.LogError("未能写入到该json文件" + e);}}public static T ReadJsonFile(string fileName, object data){var path = Path.Combine(Application.persistentDataPath, fileName);try{string file = null;if (!File.Exists(path)){WriteToJson(fileName, data);file = File.ReadAllText(path);}else{file = File.ReadAllText(path);}var json = JsonUtility.FromJson(file);return json;}catch (System.Exception e){Debug.LogError("无法读取当前文件" + e);return default;}}public static void DeleteAllJson(string fileName){var path = Path.Combine(Application.persistentDataPath, fileName);try{File.Delete(path);}catch (System.Exception e){Debug.LogError("未能成功删除存档" + e);}}}

Sprite字体使用

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEditor;
public class SetTTf : MonoBehaviour
{//本方法是通过裁切的sprite导出字体文件,裁切使用的是unity自带的sprite editor,方便操作。//另外,裁切之后,每个sprite的名字的最后一个字符对应了ascii码的编码,比如://0: 我们只要将sprite的名字命名成xxx0,就可以了!//由于使用到的了sprite加载,所以字体图片请放在Resources目录下面,等制作完毕,再把他们放到fonts文件夹或者其他文件夹中即可。[MenuItem("SetTTf/CreateMyFontSprite")]static void CreateMyFontSprite(){if (Selection.objects == null) return;if (Selection.objects.Length == 0){Debug.LogWarning("没有选中Sprite文件,需要将Sprite Mode设置成Multiple,切分好,并且以以名字的最后一个字符当做ascii码");return;}string resoursePath = "Resources";Object o = Selection.objects[0];if (o.GetType() != typeof(Texture2D)){Debug.LogWarning("选中的并不是图片文件");return;}string selectiOnPath= AssetDatabase.GetAssetPath(o);if (selectionPath.Contains(resoursePath)){string selectiOnExt= Path.GetExtension(selectionPath);if (selectionExt.Length == 0){return;}string loadPath = selectionPath.Remove(selectionPath.Length - selectionExt.Length);string fOntPathName= loadPath + ".fontsettings";string matPathName = loadPath + ".mat";float lineSpace = 0.1f;//字体行间距,下面会根据最高的字体得到行间距,如果是固定高度,可以在这里自行调整loadPath = Path.GetFileNameWithoutExtension(selectionPath);Sprite[] sprites = Resources.LoadAll(loadPath);if (sprites.Length > 0){//以textrue方式获得该资源,可以设置到创建的材质中去Texture2D tex = o as Texture2D;//创建字体材质,并且将图片设置好Material mat = new Material(Shader.Find("GUI/Text Shader"));AssetDatabase.CreateAsset(mat, matPathName);mat.SetTexture("_MainTex", tex);//创建字体文件,设置字体文件的材质Font m_myFOnt= new Font();m_myFont.material = mat;AssetDatabase.CreateAsset(m_myFont, fontPathName);//创建字体中的字符集数组CharacterInfo[] characterInfo = new CharacterInfo[sprites.Length];//得到最高的高度,设置行高和进行偏移计算for (int i = 0; i lineSpace){lineSpace = sprites[i].rect.height;}}for (int i = 0; i 0){pivot = -lineSpace / 2 - spr.pivot.y;}else if (pivot <0){pivot = -lineSpace / 2 + rect.height - spr.pivot.y;}else{pivot = -lineSpace / 2;}Debug.Log(pivot);int offsetY = (int)(pivot + (lineSpace - rect.height) / 2);//设置字符映射到材质上的坐标info.uvBottomLeft = new Vector2((float)rect.x / tex.width, (float)(rect.y) / tex.height);info.uvBottomRight = new Vector2((float)(rect.x + rect.width) / tex.width, (float)(rect.y) / tex.height);info.uvTopLeft = new Vector2((float)rect.x / tex.width, (float)(rect.y + rect.height) / tex.height);info.uvTopRight = new Vector2((float)(rect.x + rect.width) / tex.width, (float)(rect.y + rect.height) / tex.height);//设置字符顶点的偏移位置和宽高info.minX = 0;info.minY = -(int)rect.height - offsetY;info.maxX = (int)rect.width;info.maxY = -offsetY;//设置字符的宽度info.advance = (int)rect.width;characterInfo[i] = info;}// lineSpace += 2;m_myFont.characterInfo = characterInfo;EditorUtility.SetDirty(m_myFont);//设置变更过的资源AssetDatabase.SaveAssets();//保存变更的资源AssetDatabase.Refresh();//刷新资源,貌似在Mac上不起作用//由于上面fresh之后在编辑器中依然没有刷新,所以暂时想到这个方法,//先把生成的字体导出成一个包,然后再重新导入进来,这样就可以直接刷新了//这是在Mac上遇到的,不知道Windows下面会不会出现,如果不出现可以把下面这一步注释掉AssetDatabase.ExportPackage(fontPathName, "temp.unitypackage");AssetDatabase.DeleteAsset(fontPathName);AssetDatabase.ImportPackage("temp.unitypackage", true);AssetDatabase.Refresh();//最佳高度:上下各留一个像素的间距,如果不需要可以注释掉,根据需求更改//打印是为了使使用者方便填写行高,因为font不支持设置行高。Debug.Log("创建字体成功, 最大高度:" + lineSpace + ", 最佳高度:" + (lineSpace + 2));}else{Debug.LogWarning("没有选中Sprite文件,需要将Sprite放到Resources文件夹下面,可以参考函数上方的说明操作");}}}
}

防止鼠标射线穿透UI的API

if (!EventSystem.current.IsPointerOverGameObject()){//}

UniWebview无法加载Https解决办法

网址https://blog.csdn.net/boyZhenGui/article/details/121250008UniWebView,是一个支持安卓,ios和mac系统的网页插件(Windows不可用,意味着Windows系统的Unity编辑器无法看到效果,只有打包放到手机上才可以看到效果)。原因
出现ERR_CLEARTEXT_NOT_PERMITTED这个报错的原因,在于安卓。从Android 9.0(API级别28)开始,默认情况下禁用明文支持。因此http的url均无法在webview中加载。解决方案
所以我们需要在安卓的清单中AndroidManifest.xml,添加可以加载http的标签。在Unity中完成修改AndroidManifest.xml
在Unity中无AndroidManifest.xml文件的情况下。Unity默认情况会根据插件中的所有 Android 清单,和打包设置,自动生成一份清单文件AndroidManifest.xml。如果Unity中Assets/Plugins/Android/AndroidManifest.xml,有清单文件,则会使用此清单。对于在Unity中的安卓清单详细解释可以看Unity官方手册。网上找到的清单都不符合Unity需求,我们需要得到Unity需要的清单文件。一、打包apk,得到Unity自动生成的最终清单文件AndroidManifest.xml
打包成功apk后,在关闭Unity编辑器之前,在Temp/StagingArea/AndroidManifest.xml 可以找到此apk使用的最终清单。二、将最终清单文件放到Unity中
复制步骤一中得到的清单,放到如下链接Assets/Plugins/Android/AndroidManifest.xml。三、修改AndroidManifest.xml
打开AndroidManifest.xml,找到标签, 在里面加入android:usesCleartextTraffic="true"即可,这个代码标表示可以使用http明文传输,解决方法:找到AndroidManifest.xml的方法=“找到Player下安卓的发布设置找到custom mina manifest”;或者在unity主程序找相同文件复制


AB包加载小工具


using System.Net.Mime;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;///

/// AB包管理器 全局唯一 使用单例模式/// public class ABManager : MonoSingleton{//AB包缓存---解决AB包无法重复加载的问题 也有利于提高效率。private Dictionary abCache=new Dictionary();private AssetBundle mainAB = null; //主包private AssetBundleManifest mainManifest = null; //主包中配置文件---用以获取依赖包//各个平台下的基础路径 --- 利用宏判断当前平台下的streamingAssets路径private string basePath{get{//使用StreamingAssets路径注意AB包打包时 勾选copy to streamingAssets
#if UNITY_EDITOR || UNITY_STANDALONEreturn Application.dataPath + "/StreamingAssets/";
#elif UNITY_IPHONEreturn Application.dataPath + "/Raw/";
#elif UNITY_ANDROIDreturn Application.dataPath + "!/assets/";
#endif}}//各个平台下的主包名称 --- 用以加载主包获取依赖信息private string mainABName{get{
#if UNITY_EDITOR || UNITY_STANDALONEreturn "StandaloneWindows";
#elif UNITY_IPHONEreturn "IOS";
#elif UNITY_ANDROIDreturn "Android";
#endif}}//加载AB包private AssetBundle LoadABPackage(string abName){AssetBundle ab;//加载ab包,需一并加载其依赖包。if (mainAB == null){//根据各个平台下的基础路径和主包名加载主包mainAB = AssetBundle.LoadFromFile(basePath + mainABName);//获取主包下的AssetBundleManifest资源文件(存有依赖信息)mainManifest = mainAB.LoadAsset("AssetBundleManifest");}//根据manifest获取所有依赖包的名称 固定APIstring[] dependencies = mainManifest.GetAllDependencies(abName);//循环加载所有依赖包for (int i = 0; i /// 同步加载资源---泛型加载 简单直观 无需显示转换/// ///

ab包的名称///

资源名称public T LoadResource(string abName, string resName) where T : UnityEngine. Object{//加载目标包AssetBundle ab = LoadABPackage(abName);//返回资源return ab.LoadAsset(resName);}//不指定类型 有重名情况下不建议使用 使用时需显示转换类型public Object LoadResource(string abName, string resName){//加载目标包AssetBundle ab = LoadABPackage(abName);//返回资源return ab.LoadAsset(resName);}//利用参数传递类型,适合对泛型不支持的语言调用,使用时需强转类型public Object LoadResource(string abName, string resName, System.Type type){//加载目标包AssetBundle ab = LoadABPackage(abName);//返回资源return ab.LoadAsset(resName, type);}#endregion//================三种资源异步加载方式======================///

/// 提供异步加载----注意 这里加载AB包是同步加载,只是加载资源是异步/// ///

ab包名称///

资源名称public void LoadResourceAsync(string abName, string resName, System.Action finishLoadObjectHandler){AssetBundle ab = LoadABPackage(abName);//开启协程 提供资源加载成功后的委托StartCoroutine(LoadRes(ab, resName, finishLoadObjectHandler));}private IEnumerator LoadRes(AssetBundle ab, string resName, System.Action finishLoadObjectHandler){if (ab == null) yield break;//异步加载资源APIAssetBundleRequest abr = ab.LoadAssetAsync(resName);yield return abr;//委托调用处理逻辑finishLoadObjectHandler(abr.asset);}//根据Type异步加载资源public void LoadResourceAsync(string abName, string resName, System.Type type, System.Action finishLoadObjectHandler){AssetBundle ab = LoadABPackage(abName);StartCoroutine(LoadRes(ab, resName, type, finishLoadObjectHandler));}private IEnumerator LoadRes(AssetBundle ab, string resName, System.Type type, System.Action finishLoadObjectHandler){if (ab == null) yield break;AssetBundleRequest abr = ab.LoadAssetAsync(resName, type);yield return abr;//委托调用处理逻辑finishLoadObjectHandler(abr.asset);}//泛型加载public void LoadResourceAsync(string abName, string resName, System.Action finishLoadObjectHandler) where T : Object{AssetBundle ab = LoadABPackage(abName);StartCoroutine(LoadRes(ab, resName, finishLoadObjectHandler));}private IEnumerator LoadRes(AssetBundle ab, string resName, System.Action finishLoadObjectHandler) where T : Object{if (ab == null) yield break;AssetBundleRequest abr = ab.LoadAssetAsync(resName);yield return abr;//委托调用处理逻辑finishLoadObjectHandler(abr.asset as T);}//====================AB包的两种卸载方式=================//单个包卸载public void UnLoad(string abName){if (abCache.ContainsKey(abName)){abCache[abName].Unload(false);//注意缓存需一并移除abCache.Remove(abName);}}//所有包卸载public void UnLoadAll(){AssetBundle.UnloadAllAssetBundles(false);//注意清空缓存abCache.Clear();mainAB = null;mainManifest = null;}}

Singleton

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
///


/// 无需挂载直接调用即可
///

///
public class Singleton : MonoBehaviour where T : Singleton
{private static T instance;public static T Instance{get{if (instance == null){instance = FindObjectOfType(typeof(T)) as T;if (instance == null){GameObject go = new GameObject();go.name = typeof(T).ToString();instance = go.AddComponent();}}return instance;}}/// /// 如果需要跟随场景在Awake中调用Init即可/// protected void Init(){ DontDestroyOnLoad(gameObject);if (instance == null){instance = this as T;}else{Destroy(gameObject);}}}


Unity物体看向鼠标

public LayerMask whatIsGround;// Update is called once per framevoid Update(){GetPos();}void GetPos(){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hitInfo;if (Physics.Raycast(ray, out hitInfo, 200, whatIsGround)){Vector3 target = hitInfo.point;target.y = transform.position.y;transform.LookAt(target);}}

Unity小程序发布

Unity对接抖音_暗夜血媚的博客-CSDN博客_unity 抖音小游戏


GoogleProtobuf使用学习链接

protobuf如何使用Protogen工具生成CS代码详细教学篇_Little丶Seven的博客-CSDN博客_protobuf protogen


Adrressable教程

【游戏开发探究】Unity Addressables资源管理方式用起来太爽了,资源打包、加载、热更变得如此轻松(Addressable Asset System | 简称AA)_林新发的博客-CSDN博客

Unity Addressable发布至服务器流程与自动打包代码_凌志·C的博客-CSDN博客


素材网站


阿里巴巴矢量图库,地址:iconfont-阿里巴巴矢量图标库 

如何调节你想显示的3d物理模型(比如离得近才显示完全体,离得远显示底模,加上这个组件就可以)

调节阴影距离

Npm相关

npm 安装第三方插件(moment.js)_weixin_44134551的博客-CSDN博客_npm安装moment

https://blog.csdn.net/lenfranky/article/details/90177121

如何方便快速的在指定文件夹打开cmd_LenFranky的博客-CSDN博客_在文件夹打开cmd


推荐阅读
  • 开发日志:高效图片压缩与上传技术解析 ... [详细]
  • 基于Net Core 3.0与Web API的前后端分离开发:Vue.js在前端的应用
    本文介绍了如何使用Net Core 3.0和Web API进行前后端分离开发,并重点探讨了Vue.js在前端的应用。后端采用MySQL数据库和EF Core框架进行数据操作,开发环境为Windows 10和Visual Studio 2019,MySQL服务器版本为8.0.16。文章详细描述了API项目的创建过程、启动步骤以及必要的插件安装,为开发者提供了一套完整的开发指南。 ... [详细]
  • C++ 异步编程中获取线程执行结果的方法与技巧及其在前端开发中的应用探讨
    本文探讨了C++异步编程中获取线程执行结果的方法与技巧,并深入分析了这些技术在前端开发中的应用。通过对比不同的异步编程模型,本文详细介绍了如何高效地处理多线程任务,确保程序的稳定性和性能。同时,文章还结合实际案例,展示了这些方法在前端异步编程中的具体实现和优化策略。 ... [详细]
  • WinMain 函数详解及示例
    本文详细介绍了 WinMain 函数的参数及其用途,并提供了一个具体的示例代码来解析 WinMain 函数的实现。 ... [详细]
  • DAO(Data Access Object)模式是一种用于抽象和封装所有对数据库或其他持久化机制访问的方法,它通过提供一个统一的接口来隐藏底层数据访问的复杂性。 ... [详细]
  • oracle c3p0 dword 60,web_day10 dbcp c3p0 dbutils
    createdatabasemydbcharactersetutf8;alertdatabasemydbcharactersetutf8;1.自定义连接池为了不去经常创建连接和释放 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • 2.2 组件间父子通信机制详解
    2.2 组件间父子通信机制详解 ... [详细]
  • 本文全面解析了 Python 中字符串处理的常用操作与技巧。首先介绍了如何通过 `s.strip()`, `s.lstrip()` 和 `s.rstrip()` 方法去除字符串中的空格和特殊符号。接着,详细讲解了字符串复制的方法,包括使用 `sStr1 = sStr2` 进行简单的赋值复制。此外,还探讨了字符串连接、分割、替换等高级操作,并提供了丰富的示例代码,帮助读者深入理解和掌握这些实用技巧。 ... [详细]
  • 在《ChartData类详解》一文中,我们将深入探讨 MPAndroidChart 中的 ChartData 类。本文将详细介绍如何设置图表颜色(Setting Colors)以及如何格式化数据值(Formatting Data Values),通过 ValueFormatter 的使用来提升图表的可读性和美观度。此外,我们还将介绍一些高级配置选项,帮助开发者更好地定制和优化图表展示效果。 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 利用python爬取豆瓣电影Top250的相关信息,包括电影详情链接,图片链接,影片中文名,影片外国名,评分,评价数,概况,导演,主演,年份,地区,类别这12项内容,然后将爬取的信息写入Exce ... [详细]
  • 如何在Java中使用DButils类
    这期内容当中小编将会给大家带来有关如何在Java中使用DButils类,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。D ... [详细]
  • 解决问题:1、批量读取点云las数据2、点云数据读与写出3、csf滤波分类参考:https:github.comsuyunzzzCSF论文题目ÿ ... [详细]
author-avatar
失败人一枚
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有