**OnGUI **
脚本驱动,可用于移动端调试
文本
富文本——可以类比于html的标签
水平/竖直方向可溢出
Raycast castTarget 射线投射目标,可以用来表示是否响应射线(暂时不太懂)
Best fit 可以使得字体变得自适应当前物体(边框)
图片
源图像处选择加载资源
图片类型可选→ 切片:四角不会变形(需要对图像先进行九宫格分割)
填充:会变形,可用于展示不完全的图片(可以拿来做技能冷却)
可选择是否保持长宽比,遮罩消失顺时针还是逆时针。
平铺:完全不变形,重复图片并铺开当前的图片
原始图像(RawImage)
texture格式,可绑定所有类型
UV矩形(Rect)
创建一个img文件后,点击这里
按住alt选择右下角,(自动填充整个画布)
Button
创建按钮动画 绑定某个事件
跳转场景的语句
SceneManager
SceneManager.LoadScene("场景名称",);
事件接口
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class test : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
void Start()
{
}
void Update()
{
}
public void OnPointerDown(PointerEventData eventData)
{
Debug.Log("鼠标按下");
// Doll_anima.SetBool("close", false);
}
public void OnPointerUp(PointerEventData eventData)
{
Debug.Log("鼠标抬起");
//Doll_anima.SetBool("close", true);
}
}
Unity动画
点击creat创建动画的同时,系统还自动创建了一个动画控制器(状态机)
打开动画,其中Sample表示采样,也就是说动画会以每秒几帧的速度播放
然后打开控制器
右键某动画的时候:Set as layer Default state (设为默认的动画,所以控制器会从空闲状态开始)
Any State 是一种向机器中所有状态添加相同向外状态转换的快捷方式
脚本间传值
网上较为普遍的是用 SendMessage 来传递参数,但是都写的不太清楚。
SendMessage 是GameObject自带的一个函数,能够将同类参数传给 GameObject下的同类组件。脚本作为一个组件,参数也能传递。
因为是GameObject的函数,所以要先定义GameObject 的Instance,或者也可用GameObject.Find(“实例名称”) 来找到对应的实例。下图中的“DeviceStatus” 即是一个实例名称。
GameObject.Find("DeviceStatus").GetComponent<IP>().SendMessage("setIP",IPAdd);
假设要在一个已触发的脚本中将参数传递给这个游戏实例对象,这里假定DeviceStatus 对象下的脚本名为 “IP.cs”,那么GetComponent后的尖括号中就应该是脚本名字 “IP”,随后再是SendMessage(“函数名”,值)
存储游戏对象数据
思路大概是建立一个空游戏对象,将该场景内所有需要传的参数存储进游戏对象内,并在切换场景时禁止销毁游戏对象。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GameSave : MonoBehaviour
{
//设定当前图片链接
private string currentUrl;
private string currentName;
private string currentDate;
private void Awake()
{
DontDestroyOnLoad(transform.gameObject);//不摧毁当前游戏对象
}
private void saveurl(string url)
{
currentUrl = url; //设置保存当前图片对象
}
private void savename(string name)
{
currentName = name; //设置保存当前名字对象
}
private void savedate(string date)
{
currentDate = date; //设置保存当前日期对象
}
}
鼠标点击时切换场景监听
public class Cilck : MonoBehaviour,IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
SceneManager.LoadScene("branch");//level1为我们要切换到的场景
Debug.Log("EventSystem.current.currentSelectedGameObject.url");
}
}
设置动画器状态转移数值语句
public void OnPointerEnter(PointerEventData eventData)
{
Doll_anima.SetBool("wake", true);
}
public void OnPointerExit(PointerEventData eventData)
{
Doll_anima.SetBool("wake", false);
}
一个网络地址图片加载代码
Unity中使用UnityWebRequest进行网络和本地图片加载
///LoadImageMgr.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.IO;
using UnityEngine.Networking;
public class LoadImageMgr
{
/// <summary>
/// download from web or hard disk
/// </summary>
/// <param name="url"></param>
/// <param name="loadEnd">callback</param>
/// <returns></returns>
public IEnumerator LoadImage(string url, Action<Texture2D> loadEnd)
{
Texture2D texture = null;
//先从内存加载
if (imageDic.TryGetValue(url,out texture))
{
loadEnd.Invoke(texture);
yield break;
}
string savePath = GetLocalPath();
string filePath = string.Format("file://{0}/{1}.png", savePath, UnityUtil.MD5Encrypt(url));
//from hard disk
bool hasLoad = false;
if (Directory.Exists(filePath))
yield return DownloadImage(filePath, (state, localTexture) =>
{
hasLoad = state;
if (state)
{
loadEnd.Invoke(localTexture);
if (!imageDic.ContainsKey(url))
imageDic.Add(url, localTexture);
}
});
if (hasLoad) yield break; //loaded
//from web
yield return DownloadImage(url, (state, downloadTexture) =>
{
hasLoad = state;
if (state)
{
loadEnd.Invoke(downloadTexture);
if (!imageDic.ContainsKey(url))
imageDic.Add(url, downloadTexture);
Save2LocalPath(url, downloadTexture);
}
});
}
public IEnumerator DownloadImage(string url, Action<bool, Texture2D> downloadEnd)
{
using (UnityWebRequest request = new UnityWebRequest(url))
{
DownloadHandlerTexture downloadHandlerTexture = new DownloadHandlerTexture(true);
request.downloadHandler = downloadHandlerTexture;
yield return request.Send();
if (string.IsNullOrEmpty(request.error))
{
Texture2D localTexture = downloadHandlerTexture.texture;
downloadEnd.Invoke(true, localTexture);
}
else
{
downloadEnd.Invoke(false, null);
Debug.Log(request.error);
}
}
}
/// <summary>
/// save the picture
/// </summary>
/// <param name="url"></param>
/// <param name="texture"></param>
private void Save2LocalPath(string url, Texture2D texture)
{
byte[] bytes = texture.EncodeToPNG();
string savePath = GetLocalPath();
try
{
File.WriteAllBytes( string.Format("{0}/{1}.png", savePath , UnityUtil.MD5Encrypt(url)), bytes);
}
catch(Exception ex)
{
Debug.LogError(ex.ToString());
}
}
/// <summary>
/// get which path will save
/// </summary>
/// <returns></returns>
private string GetLocalPath()
{
string savePath = Application.persistentDataPath + "/pics";
#if UNITY_EDITOR
savePath = Application.dataPath + "/pics";
#endif
if (!Directory.Exists(savePath))
{
Directory.CreateDirectory(savePath);
}
return savePath;
}
private Dictionary<string, Texture2D> imageDic = new Dictionary<string, Texture2D>();
public static LoadImageMgr instance {
get; private set; } = new LoadImageMgr();
}
Mesh网格
官方描述
unity通过Mesh网格绘制图形:三角形&正方体&圆柱
画一个三角形
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class Cube : MonoBehaviour
{
Mesh mesh;
Vector3[] vectices;
int[] cube;
private void Awake()
{
mesh = GetComponent<MeshFilter>().mesh;
}
private void Start()
{
CreateMeshData();
Draw();
}
void CreateMeshData()
{
vectices = new Vector3[]
{
new Vector3(0,0,0),
new Vector3(1,0,0),
new Vector3(0,1,0),
};
cube = new int[]{
0,1,2
};
}
private void Draw()
{
mesh.Clear();
mesh.vertices = vectices;
mesh.triangles = cube;
mesh.RecalculateNormals();//自动计算法线
}
}
PS.
1.看视频看到了RaycastTarget这个点,看到一个帖子是这样讲的:
看过UGUI源码的朋友一定都知道,UI事件会在EventSystem在Update的Process触发。UGUI会遍历屏幕中所有RaycastTarget是true的UI,接着就会发射线,并且排序找到玩家最先触发的那个UI,在抛出事件给逻辑层去响应。
团队多人在开发游戏界面,很多时候都是复制黏贴,比如上一个图片是需要响应RaycastTarget,然后ctrl+d以后复制出来的也就带了这个属性,很可能新复制出来的图片是不需要响应的,开发人员又没有取消勾选掉,这就出问题了。
所以RaycastTarget如果被勾选的过多的话, 效率必然会低。。
原帖:雨松MOMO UGUI之有效解决RaycastTarget勾选过多的烦恼(二十三)
2.解决UNITY官网API文档打开慢的问题
unity3d本地api打开速度慢的解决方法
3.一些需要注意的点
不要用Find、FindwithTag…等等
可以直接
4.获取路径的路径名
Name = path.Substring(path.LastIndexOf('/') + 1);
找最后最后一个/的第一个字符
2022/3/2血量和血条展示脚本、lookat()
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
/// <summary>
/// 控制怪物血量条的展示和跟随
/// </summary>
public class Healthbar_UI : MonoBehaviour
{
public GameObject HealthUIPrefab;//血条的预制体
public GameObject barpoint;//怪物的血条位置
Image healthSlider;//血量的滑动条
Transform UIbar;//血条位置
Transform cam;//摄像机位置
public bool alwaysVisible = true;//是否可见
public float visibleTime;//可见时长
private void OnEnable()
{
cam = Camera.main.transform;//挂载摄像机
UIbar = Instantiate(HealthUIPrefab,this.transform, barpoint).transform;
healthSlider = UIbar.GetChild(1).GetComponent<Image>();//获取绿条
UIbar.gameObject.SetActive(alwaysVisible);//设置是否长久可见
}
//血条跟随敌人
private void LateUpdate()
{
if (UIbar != null)
{
UIbar.position = barpoint.transform.position;
UIbar.forward = -cam.forward;
}
}
/// <summary>
/// 控制血量展示
/// </summary>
/// <param name="currentHealth">当前的生命值</param>
/// <param name="maxHealth">最大血量</param>
public void UpdateHralthBar(float currentHealth,float maxHealth)
{
//当血量归0时,摧毁血条
if (currentHealth <= 0)
Destroy(UIbar.gameObject);
UIbar.gameObject.SetActive(true);
//控制滑条显示的百分比(强制转换为int类型)
float sliderPercent = currentHealth / maxHealth;
healthSlider.fillAmount = sliderPercent;
}
}
look at()可以实现差不多相同的效果,该方法用在Update()内,表示该物体一直朝向摄像机
LateUpdate(),该函数为Unity内部的函数,该函数在Update()之后立马被调用
Invoke(String fun_name, float time)
延迟调用某一函数 fun_name为函数名,time为延迟调用的秒数。