睿朗 发布的文章 - 汪汪源码
首页
AI写作王
统计
友链
关于
推荐
智能AI工具
开始搜索
1
【UNITY 3D】Enviro - Sky and Weather 动态天气制作插件
1,637 阅读
2
3个免费的下载百度文库文档的方法
1,560 阅读
3
Unity3D完美的异步解决UniTask
1,431 阅读
4
Unity风格化海洋水面着色器 Stylized Water2 1.2.0 URP
1,139 阅读
5
Unity常见插件汇总
972 阅读
毕业设计
益智类
塔防
角色扮演
动作
小程序
小程序搭建
网站搭建
笔记
源码
unity
模型
套件
动画
界面
特效
插件
完整项目
2D素材
音效
开发
开发笔记
样式
视频教程
unity教程
通用资产
精灵和角色
图形用户界面
背景
图标
瓦片集
集合
系统
幻灯片
素材下载
3D模型
UI界面
2D精灵
搜 索
标签搜索
瓦
网站搭建
资源
特点
平台游戏
场景编辑
shader
建筑
场景
车辆
等距的
瓦片
3d
2d
必备工具
游戏工具
地形
镇城市
自顶向下
坦克
睿朗
累计撰写
2,454
篇文章
累计收到
25
条评论
首页
栏目
毕业设计
益智类
塔防
角色扮演
动作
小程序
小程序搭建
网站搭建
笔记
源码
unity
模型
套件
动画
界面
特效
插件
完整项目
2D素材
音效
开发
开发笔记
样式
视频教程
unity教程
通用资产
精灵和角色
图形用户界面
背景
图标
瓦片集
集合
系统
幻灯片
素材下载
3D模型
UI界面
2D精灵
页面
AI写作王
统计
友链
关于
推荐
智能AI工具
找到
390
篇与
相关的结果
2022-12-11
Unity 制作图集
一、制作图集的好处:众所周知CPU是用来处理游戏的逻辑运算的,而GPU是用来处理游戏中图像的。在GPU中,我们要绘制一个图像需要提交图片(纹理)到显存,然后再进行绘制(在这个过程中会产生一次DrawCall),也就是说我们要绘制100张图片就要产生100次DrawCall.显然这是非常消耗性能的。这是制作图集的好处就显而易见了:①、减少性能消耗,提高处理效率②、可以归类不同模块的图片③、一次加载或者卸载完成多图片的处理,提高了运行效率二、打包图集需要的工具我们经常听说是在NGUI中打包图集,在用UGUI时,我们也需要将一个个小图打包成图集,以减小Drawcall(类似coco2d-x一样,打包成图集一次性加载以内存换取图片读取效率),UGUI打包并使用图集有两种方法:一种是使用系统自带的打包工具SpritePacker;一种是使用外部插件TexturePacker打包图片并使用;关于第一种方法有另一个文章为大家讲解,另一种熟悉的方法用TexturePacker工具打包,也是本文下面要讲解的本文所使用的是Unity 2018.2.5f1 (64-bit)版本,TexturePacker 5.2.0版本最新版本1、先用TexturePacker打小图打包成我们所需要的图集,打包的格式要注意是"Unity - Texture2D sprite sheet"2、打包之后会有一个.png和一个.tpsheet,不用作其他修改,将这两个文件放在工程资源中,这时从工程看这只是一张大图,并不能算是一个图集,使用里面的小图(这时虽然可以用unity3d自带功能,手动对图片进行裁剪,但裁剪的小图大小基本是不对的)3、接下来需要下载并导入一个Unity3d的插件,TexturePacker自己出的的一个插件(TexturePacker Importer),插件链接https://www.assetstore.unity3d.com/en/#!/content/16641,下载并成功导入之后,不用写任何代码,作任何操作,插件会自己根据.tpsheet,将刚才打包好放进入工程的大图自动裁剪成小图,如下图,打图集点开我们只需像使用单独小图一样,将图集里的小图拖进Source Image里即可。这时我们还只能在编辑器里设置使用图集。4、我们还需要在程序中动态加载图集并使用图集里的小图,才算是完整的。unity3d 并没有明确api说明我们如何用这种图集,而常用Resources.Load()加载只能返回单独的一个图片纹理,所以我们用另一个方法 Resources.LoadAll();加载整一张图集,此方法会返回一个Object[],里面包含了图集的纹理 Texture2D和图集下的全部Sprite,所以我们就可以根据object 的类型和名字找到我们需要的某张小图片。5、下面写了一个图集纹理的管理类,去统一管理加载,是一个单例类,找个不被销毁的GameObject绑定就行, 代码比较简单,用一个Dictionary按图集的路径过key将加载过的图集缓存起来,需要时再由外部删除掉,下面是代码:using System.Collections;using System.Collections.Generic;using UnityEngine;using System.Collections;using System.Collections.Generic;using UnityEngine.UI;public class PPTextureManager : MonoBehaviour{private static GameObject m_pMainObject; private static PPTextureManager m_pContainer = null; public static PPTextureManager getInstance() { if(m_pContainer == null) { m_pContainer = m_pMainObject.GetComponent<PPTextureManager>(); } return m_pContainer; } //图集的集合 private Dictionary<string, Object[]> m_pAtlasDic; private void Awake() { initData(); } private void initData() { PPTextureManager.m_pMainObject = gameObject; m_pAtlasDic = new Dictionary<string, Object[]>(); } //加载图集上的精灵 public Sprite LoadAtlasSprite(string _spriteAtlasPath,string _spriteName) { //从缓存中查找图集 Sprite _sprite = FindSpriteFormBuffer(_spriteAtlasPath, _spriteName); if(_sprite == null) { Debug.LogError("查找的图集为空"); Object[] _atlas = Resources.LoadAll(_spriteAtlasPath);//加载图集 m_pAtlasDic.Add(_spriteAtlasPath, _atlas);//将加载的图集存到字典中(路径对应图片) _sprite = SpriteFormAtlas(_atlas, _spriteName);//从图集中找到图片 } return _sprite; } //从图集中找出sprite private Sprite SpriteFormAtlas(Object[] _atlas,string _spriteName) { for(int i = 0;i<_atlas.Length;i++) { if(_atlas[i].GetType()==typeof(UnityEngine.Sprite)) { if(_atlas[i].name == _spriteName) { return (Sprite)_atlas[i]; } } } return null; } //从缓存中查找图集并找出sprite private Sprite FindSpriteFormBuffer(string _spriteAtlasPath,string _spriteName) { if(m_pAtlasDic.ContainsKey(_spriteAtlasPath)) { Object[] _atlas = m_pAtlasDic[_spriteAtlasPath]; Sprite _sprite = SpriteFormAtlas(_atlas, _spriteName); return _sprite; } return null; } //删除图集缓存 public void DeleteAtlas(string _spriteAtlasPath) { if(m_pAtlasDic.ContainsKey(_spriteAtlasPath)) { m_pAtlasDic.Remove(_spriteAtlasPath); } }}
2022年12月11日
486 阅读
0 评论
22 点赞
2022-12-11
测试
二维
2022年12月11日
86 阅读
2 评论
13 点赞
2022-12-11
Unity VideoPlayer播放视频 Slider控制播放进度
using UnityEngine;using UnityEngine.UI;using UnityEngine.Video;public class ToPlayVideo : MonoBehaviour{public VideoClip[] videoClips; // 视频的文件 参数 public Text videoTimeText; // 视频的当前时间 Text public Text videoNameText; // 视频的总时长 Text public Slider videoTimeSlider; // 视频的时间 Slider // 定义参数获取VideoPlayer组件和RawImage组件 internal VideoPlayer videoPlayer; private RawImage rawImage; public Texture pingBao; // 屏保图片 // 当前视频的总时间值和当前播放时间值的参数 private int currentHour; private int currentMinute; private int currentSecond; private int clipHour; private int clipMinute; private int clipSecond; public Sprite play; public Sprite pause; private bool isPlay = true; //是否正在播放视频 public Button playPauseButton; //播放暂停按钮 public Button stopButton; //停止播放按钮 public Button button1; public Button button2; public Button button3; public Button button4; // Use this for initialization void Start() { //清空文本 videoNameText.text = ""; videoTimeText.text = ""; //获取场景中对应的组件 videoPlayer = this.GetComponent<VideoPlayer>(); rawImage = this.GetComponent<RawImage>(); videoPlayer.audioOutputMode = VideoAudioOutputMode.AudioSource; videoPlayer.SetTargetAudioSource(0, this.GetComponent<AudioSource>()); videoPlayer.playOnAwake = false; videoPlayer.IsAudioTrackEnabled(0); playPauseButton.onClick.AddListener(PlayOrPause); stopButton.onClick.AddListener(StopVideo); button1.onClick.AddListener(delegate ); button2.onClick.AddListener(delegate ); button3.onClick.AddListener(delegate ); button4.onClick.AddListener(delegate ); } // Update is called once per frame void Update() { //如果videoPlayer没有对应的视频texture,则返回屏保 if (videoPlayer.texture == null) { rawImage.texture = pingBao; return; } //把VideoPlayerd的视频渲染到UGUI的RawImage rawImage.texture = videoPlayer.texture; ShowVideoTime(); } /// <summary> /// 显示当前视频的时间 /// </summary> private void ShowVideoTime() { // 当前的视频播放时间 currentHour = (int)videoPlayer.time / 3600; currentMinute = (int)(videoPlayer.time - currentHour * 3600) / 60; currentSecond = (int)(videoPlayer.time - currentHour * 3600 - currentMinute * 60); // 把当前视频播放的时间显示在 Text 上 videoTimeText.text = string.Format("::", currentHour, currentMinute, currentSecond); // 把当前视频播放的时间比例赋值到 Slider 上 videoTimeSlider.value = (float)(videoPlayer.time / videoPlayer.clip.length); } /// <summary> /// 显示视频的总时长 /// </summary> /// <param name="videos">当前视频</param> void ShowVideoLength(VideoClip videos) { videoPlayer.clip = videos; videoPlayer.Play(); videoTimeSlider.gameObject.SetActive(true); clipHour = (int)videoPlayer.clip.length / 3600; clipMinute = (int)(videoPlayer.clip.length - clipHour * 3600) / 60; clipSecond = (int)(videoPlayer.clip.length - clipHour * 3600 - clipMinute * 60); videoNameText.text = string.Format(":: ", clipHour, clipMinute, clipSecond); } private void OnClick(int num) { switch (num) { case 0: ShowVideoLength(videoClips[0]); break; case 1: ShowVideoLength(videoClips[1]); break; case 2: ShowVideoLength(videoClips[2]); break; case 3: ShowVideoLength(videoClips[3]); break; case 4: ShowVideoLength(videoClips[4]); break; default: break; } } /// <summary> /// 视频播放暂停 /// </summary> void PlayOrPause() { //如果视频片段不为空,并且视频画面没有播放完毕 if (videoPlayer.clip != null && (ulong)videoPlayer.frame < videoPlayer.frameCount) { //如果视频正在播放 if (isPlay) { playPauseButton.image.sprite = pause; videoPlayer.Pause(); isPlay = false; } else { playPauseButton.image.sprite = play; videoPlayer.Play(); isPlay = true; } } } void StopVideo() { videoPlayer.Stop(); playPauseButton.image.sprite = play; videoTimeSlider.gameObject.SetActive(false); videoNameText.text = ""; videoTimeText.text = ""; isPlay = true; }}using UnityEngine;using UnityEngine.EventSystems;/// <summary>/// 继承 拖拽接口/// </summary>public class SliderEvent : MonoBehaviour, IDragHandler, IEndDragHandler{[SerializeField] public ToPlayVideo toPlayVideo; // 视频播放的脚本 // Use this for initialization void Start() { } // Update is called once per frame void Update() { } /// <summary> /// 给 Slider 添加开始拖拽事件 /// </summary> /// <param name="eventData"></param> public void OnDrag(PointerEventData eventData) { toPlayVideo.videoPlayer.Pause(); SetVideoTimeValueChange(); } /// <summary> /// 当前的 Slider 比例值转换为当前的视频播放时间 /// </summary> private void SetVideoTimeValueChange() { toPlayVideo.videoPlayer.time = toPlayVideo.videoTimeSlider.value * toPlayVideo.videoPlayer.clip.length; } /// <summary> /// 给 Slider 添加结束拖拽事件 /// </summary> /// <param name="eventData"></param> public void OnEndDrag(PointerEventData eventData) { toPlayVideo.videoPlayer.Play(); }}
2022年12月11日
88 阅读
33 评论
0 点赞
2022-12-11
uniapp基础知识—大总结
uni-app介绍uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、H5、以及各种小程序(微信/支付宝/百度/头条/QQ/钉钉)等多个平台。即使不跨端,uni-app同时也是更好的小程序开发框架。具有vue和微信小程序的开发经验,可快速上手uni-app为什么要去学习uni-app?相对开发者来说,减少了学习成本,因为只学会uni-app之后,即可开发出iOS、Android、H5、以及各种小程序的应用,不需要再去学习开发其他应用的框架,相对公司而言,也大大减少了开发成本。环境搭建安装编辑器HbuilderX 下载地址HBuilderX是通用的前端开发工具,但为uni-app做了特别强化。下载App开发版,可开箱即用安装微信开发者工具 下载地址利用HbuilderX初始化项目点击HbuilderX菜单栏文件>项目>新建选择uni-app,填写项目名称,项目创建的目录运行项目在菜单栏中点击运行,运行到浏览器,选择浏览器即可运行在微信开发者工具里运行:进入hello-uniapp项目,点击工具栏的运行 -> 运行到小程序模拟器 -> 微信开发者工具,即可在微信开发者工具里面体验uni-app在微信开发者工具里运行:进入hello-uniapp项目,点击工具栏的运行 -> 运行到手机或模拟器 -> 选择调式的手机注意:如果是第一次使用,需要先配置小程序ide的相关路径,才能运行成功微信开发者工具在设置中安全设置,服务端口开启介绍项目目录和文件作用pages.json 文件用来对 uni-app 进行全局配置,决定页面文件的路径、窗口样式、原生的导航栏、底部的原生tabbar 等manifest.json 文件是应用的配置文件,用于指定应用的名称、图标、权限等。App.vue是我们的跟组件,所有页面都是在App.vue下进行切换的,是页面入口文件,可以调用应用的生命周期函数。main.js是我们的项目入口文件,主要作用是初始化vue实例并使用需要的插件。uni.scss文件的用途是为了方便整体控制应用的风格。比如按钮颜色、边框风格,uni.scss文件里预置了一批scss变量预置。unpackage就是打包目录,在这里有各个平台的打包文件pages所有的页面存放目录static静态资源目录,例如图片等components组件存放目录为了实现多端兼容,综合考虑编译速度、运行性能等因素,uni-app 约定了如下开发规范:页面文件遵循 Vue 单文件组件 (SFC) 规范组件标签靠近小程序规范,详见uni-app 组件规范接口能力(JS API)靠近微信小程序规范,但需将前缀 wx 替换为 uni,详见uni-app接口规范数据绑定及事件处理同 Vue.js 规范,同时补充了App及页面的生命周期为兼容多端运行,建议使用flex布局进行开发全局配置和页面配置
2022年12月11日
141 阅读
22 评论
0 点赞
2022-11-28
使用攻略
【高端精品】美团最新实战暴利玩法, 【首发最详细话术】
2022年11月28日
91 阅读
0 评论
0 点赞
1
...
77
78