热门标签 | 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


推荐阅读
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • DNN Community 和 Professional 版本的主要差异
    本文详细解析了 DotNetNuke (DNN) 的两种主要版本:Community 和 Professional。通过对比两者的功能和附加组件,帮助用户选择最适合其需求的版本。 ... [详细]
  • UNP 第9章:主机名与地址转换
    本章探讨了用于在主机名和数值地址之间进行转换的函数,如gethostbyname和gethostbyaddr。此外,还介绍了getservbyname和getservbyport函数,用于在服务器名和端口号之间进行转换。 ... [详细]
  • 本文详细介绍了 Apache Jena 库中的 Txn.executeWrite 方法,通过多个实际代码示例展示了其在不同场景下的应用,帮助开发者更好地理解和使用该方法。 ... [详细]
  • 题目Link题目学习link1题目学习link2题目学习link3%%%受益匪浅!-----&# ... [详细]
  • 本文探讨了在通过 API 端点调用时,使用猫鼬(Mongoose)的 findOne 方法总是返回 null 的问题,并提供了详细的解决方案和建议。 ... [详细]
  • 毕业设计:基于机器学习与深度学习的垃圾邮件(短信)分类算法实现
    本文详细介绍了如何使用机器学习和深度学习技术对垃圾邮件和短信进行分类。内容涵盖从数据集介绍、预处理、特征提取到模型训练与评估的完整流程,并提供了具体的代码示例和实验结果。 ... [详细]
  • 本文详细介绍如何在VSCode中配置自定义代码片段,使其具备与IDEA相似的代码生成快捷键功能。通过具体的Java和HTML代码片段示例,展示配置步骤及效果。 ... [详细]
  • dotnet 通过 Elmish.WPF 使用 F# 编写 WPF 应用
    本文来安利大家一个有趣而且强大的库,通过F#和C#混合编程编写WPF应用,可以在WPF中使用到F#强大的数据处理能力在GitHub上完全开源Elmis ... [详细]
  • 本题探讨了一种字符串变换方法,旨在判断两个给定的字符串是否可以通过特定的字母替换和位置交换操作相互转换。核心在于找到这些变换中的不变量,从而确定转换的可能性。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 本文详细介绍了如何构建一个高效的UI管理系统,集中处理UI页面的打开、关闭、层级管理和页面跳转等问题。通过UIManager统一管理外部切换逻辑,实现功能逻辑分散化和代码复用,支持多人协作开发。 ... [详细]
  • 本文探讨了 Objective-C 中的一些重要语法特性,包括 goto 语句、块(block)的使用、访问修饰符以及属性管理等。通过实例代码和详细解释,帮助开发者更好地理解和应用这些特性。 ... [详细]
  • 本文详细探讨了VxWorks操作系统中双向链表和环形缓冲区的实现原理及使用方法,通过具体示例代码加深理解。 ... [详细]
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社区 版权所有