1.水平HorizontalLayoutGroup强制刷新,手动对其改变Scale或者长款后要重新计算
horizontalLayoutGroup.CalculateLayoutInputHorizontal();
horizontalLayoutGroup.SetLayoutHorizontal();`
2.屏幕点击射线检测,多用于点击屏幕触发游戏中的物体
if (Input.GetMouseButtonDown(0))
{
Debug.Log("ray!");
//从摄像机射出一条ray到Input.mousePosition的位置,如果是正交则直接从屏幕上射出去
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
//在Scene里绘制射线(原点,方向,颜色,持续帧数);
Debug.DrawRay(ray.origin, ray.direction * 9999, Color.red, 9999);
//用 RaycastHit 接受碰撞点信息
RaycastHit info;
//Physics.Raycast(射线, out 接受碰撞的, 检测距离(不设置就无限), 1 << LayerMask.NameToLayer("Enemy"))
//1 << LayerMask.NameToLayer("Enemy") 表示Enemy层生效
//0 << LayerMask.NameToLayer("Enemy") 表示Enemy层不生效
if (Physics.Raycast(ray, out info, Mathf.Infinity, 1 << LayerMask.NameToLayer("Enemy")))
{
Debug.Log(info.transform.name + " " + info.transform.tag);
}
}
关于为什么要左移
3.检测动画结束
添加动画状态机脚本
点击挂了脚本的动画状态,ExitTime勾选上则有柔化时间,normalizedTime在动画结束后进行柔化,所以会超过1,不勾选则到达1时就结束。
在这里不勾选Skill01的ExitTime,当normalizedTime>=1f时,则为Skill01动画结束,进行 下一步逻辑。
4.2D映射3D坐标
/// <summary>
/// UI2D映射3D坐标。传入一个UI层的2D目标,根据距离返回主摄像机3D坐标
/// </summary>
/// <param name="src2d">2D目标</param>
/// <param name="distance">距离,这个要自己目测定义</param>
public Vector3 UI2DTo3D(GameObject src2d, float distance)
{
Vector3 v = src2d.transform.position;
Vector3 des = CameraManager.Instance.uiCamera.WorldToScreenPoint(v);
Ray ray = Camera.main.ScreenPointToRay(des);
Debug.DrawRay(ray.origin, ray.direction * 9999, Color.red, 9999);
return ray.GetPoint(distance);
}
5.关于协程Coroutine
协程是根据MonoBehaviour挂起的,也就是说,在哪个MonoBehaviour里StartCoroutine只可以在该MonoBehaviour里StopCoroutine,不然就会出现“Coroutine continue failure”错误,虽然这个错误不影响程序进行,但是会报红暂停。
6.关于获取点击坐标
①Input.mousePosition
虽然名字叫作鼠标坐标,但是,在Android上也是可以用的,不过其原点与UICanvas不一样,UICanvas的原点是在屏幕中心,Input.mousePosition的原点是在左下角,所以要用Input.mousePosition获取到的坐标减去屏幕宽高的一半,但是,Input.mousePosition获取到的并不是坐标,而是像素,以中心点为例,点击分辨率为720×1280的屏幕中心点获取到(360,640),同理点击1080×2340的屏幕获取到的是(540,1170),因此,还要将实际分辨率转换为开发分辨率。
/// <summary>
/// 点击屏幕,准心移动到点击位置,看不懂就照写
/// </summary>
/// <param name="pos"></param>
public void Show(Vector2 pos)
{
float bili = (720f / Screen.width); //开发分辨率与实际分辨率比例
Vector2 half = new Vector2(Screen.width * bili / 2f, Screen.height * bili / 2f); //屏幕分辨率的一半(也要转化)
transform.localPosition = pos * bili - half; //所需坐标 = 实际分辨率×比例(转化后) - 屏幕一半分辨率
}
7.Unity中UGUI 图片实现拖拽功能
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Cell : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private Vector3 m_offset;
public RectTransform rtf;
// Start is called before the first frame update
void Start()
{
rtf = transform.GetComponent<RectTransform>();
}
public void OnBeginDrag(PointerEventData eventData)
{
// 存储点击时的鼠标坐标
Vector3 tWorldPos;
//UI屏幕坐标转换为世界坐标
RectTransformUtility.ScreenPointToWorldPointInRectangle(rtf, eventData.position, eventData.pressEventCamera, out tWorldPos);
//计算偏移量
m_offset = transform.position - tWorldPos;
SetDraggedPosition(eventData);
}
public void OnDrag(PointerEventData eventData)
{
SetDraggedPosition(eventData);
}
public void OnEndDrag(PointerEventData eventData)
{
SetDraggedPosition(eventData);
}
public void SetDraggedPosition(PointerEventData eventData)
{
//存储当前鼠标所在位置
Vector3 globalMousePos;
//UI屏幕坐标转换为世界坐标
if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rtf, eventData.position, eventData.pressEventCamera, out globalMousePos))
{
//设置位置及偏移量
rtf.position = globalMousePos + m_offset;
}
}
// Update is called once per frame
void Update()
{
}
}
8.StreamingAssets与Resourses区别:
1,StreamingAssets会原封不动拷贝到包里,并不会封装;
2,Resourses有压缩,但并没有加密。
9.如何用For循环去赋值回调
public void Test()
{
for (int i = 0; i < btns_Chapters.Count; i++)
{
btns_Chapters[i].onClick.AddListener(SetIDChapter(i))
}
}
private UnityAction SetIDChapter(int idchapter)
{
return () =>
{
//Debug.Log(idchapter);
SetIDsNE(idchapter);
};
}
10.Debug.unityLogger.logEnabled = false;可关闭Debug.Log输出;
11.单例
using System.Collections.Generic;
public class GameManager
{
public List<Enemy> enemies;
private static GameManager _instance;
public static GameManager Instance
{
get
{
if (_instance == null)
{
_instance = new GameManager();
}
return _instance;
}
}
private GameManager()
{
enemies = new List<Enemy>();
}
public int GetNumEnemy()
{
return enemies.Count;
}
}
12.Static 的 Rigibody 是不会触发 OnColliderXXX 或者 OnTriggerXXX 的,你可以改成 Kinematic 。