关于Unity记录

关于UI的一些函数和使用方法

1,获取鼠标的位置(并不是点击位置,是滑动位置)
Input.mousePosition   Vector3类型

2,判断鼠标是否在UI的范围内,需要引入事件系统,也可能需要引入引擎里的UI
using UnityEngine.UI;
using UnityEngine.EventSystems;
EventSystem.current.IsPointerOverGameObject();

3,UI的变换要放到OnGUI中。例如在Update中执行,可能是因为鼠标拖动太快,导致Image跟不
上鼠标的动作,鼠标在UI上方的判断返回值就不准确。还有就是判断鼠标和UI之间的distance
会不准确,点击鼠标,UI会瞬间移动到鼠标位置,这样做不是很好。

4,关于背包的物体拖拽到另一个地方需要的操作
//设置父物体,并且设定是否使用世界坐标
go.transform.SetParent(GameObject go,bool worldPostionStays);
//把该物体放置在父物体的列表最后,这样方便在层级上最优先显示,也有放在前面的相关函数。
go.transform.SetAsLastSibling();
//重置物体的坐标为父物体的原点。
go.transform.localPosition = Vector3.zero;

5,关于轴心
//设置轴心,就是UI中间的那个圆圈,pivot是实际轴心。
GetComponent ().pivot.Set (0, 0);
//设置缩放为原先的0.5倍。
transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
//返回正常的缩放比例,这个缩放是相对缩放,也就是只要赋值Vector.one就可以返回原先的大小。
transform.localScale = new Vector3(1f, 1f, 1f);

6,要实现UI的拖拽功能需要实现三个接口
IDragHandler, 重写public void onDrag(PointerEventData eventData){}
IPointerDownHandler, 重写public void OnPointerDown(PointerEventData eventData){}
IPointerUpHandler 重写public void OnPointerUp(PointerEventData eventData){}

7,实例化一个物体
Instantiate(Object obj,Vector3 position,Quaternion rotation);

8,UI显示,设置优先级
transform.SetSiblingIndex(int num)


9,UI的父层级添加Gird Layout Group可以让子元素自动排序。

10,屏幕适配
Canvas
    Render Mode选择  Screen Space-Overlay
Canvas Scaler
    Ui Scale Mode   Scale With Screen Size
    Screen Match Mode选择Match Width Or Height模式   根据屏幕的横屏还是竖屏来选择阈值,一般会把屏幕不能匹配的那一方向留黑就行。


11,加载资源

如果资源文件Resources下有一个Pic文件夹,需要用到Pic文件夹下的文件,那么路径可以是"Pic/xxx",因为方法是Resources.Load,所以路径名可以不用协商Resources。
参数一:资源路径,路径是工程文件中的自己创建一个Resources文件夹,从里面选取文件,里面的文件可以用数字来表示,方便读取
参数二:资源类型,如typeof(Sprite),
Resources.Load(string path,Type type) as Type;


12,获取图片的精灵
private Image image;
image.overrideSprite//只有图片才可以使用的属性,GameObject是没有的。


13,得到当前点击的对象,前提是在OnPointerUp,OnPointerDown,OnPoint方法中
eventData.pointerCurrentRaycast.gameObject;


14,得到层级面板中bag的子元素fox
GameObject ab = GameObject.Find("bag").transform.Find("fox").gameObject; 


15,动态加载物体

GameObject obj = Instantiate(Resources.Load("Prefab/"+ name )) as GameObject;//加载实例化名为"Prefab/"+ name路径下的物体,这个物体是在文件下的,目前并不在场景中。
obj.transform.parent=GameObject.Find("Camera").transform;//说明是在场景中的名为"Camera"的节点下,存在于场景中Hierarchy。
obj.transform.localPosition = Vector3.zero; //把坐标位置归零(相对于父物体,也就是当前的Camere物体)
obj.transform.localScale = Vector3.one; //把缩放因子归零。


16,如果是用按钮来控制界面的显示和隐藏,那么不能再脚本里写gameObject.setActive(bool b)这个方法,因为如果该物体是隐藏的,那么就不会调用了,所以把脚本放在父物体里最好


!!!!!

17,用Resources.Load(string path)可以加载一个预制体,当然这个预制体必须在Resources文件夹下,用路径来描述是哪个。
如果这个预制体有脚本组件,可以直接像这样
GameObject g = Resources.Load("Prefabs/animal") as GameObject
g.getComponent().jump();
加载的这个预制体调用了这个预制体自身的脚本中的方法,这样可以像是脚本间赋值。
当然加载之后需要实例化
GameObject.Instantiate(g);
如果需要的是背包的方式,可以拖动到某一个栏里
那么需要setParent,然后设置localPostion = Vector3.zero归零, localScale = Vector3.one归一化。


18,设置锚点的技巧
匹配父物体大小的快捷方式,选择子物体按住alt然后选择锚点的最后一个最大的选项。
匹配文字或者大小的范围框,可以添加一个content Size fitter脚本组件,可以让范围框以不同图片的尺寸进行改变


!!!!!

19,拖动回调方法中的参数,可以判断当前事件的一系列内容,比如说如下,当前在哪个物体上,判断标签是否是"btn"
public void OnDrag(PointerEventData eventData)
{
   if (eventData.pointerEnter.tag == "btn") { }
}


20,设置中的Ratcast Target的选项可以改变是否使用射线检测,如果有遮挡的东西,那么可以取消上层的射线检测。


21,关于unity中的事件Action

Action是unity系统内定制的一个委托泛型,和C#委托的意思一样,需要引入using System

class Grid:Monobehaviour,IPointerEnterHandler
{
    public static Action OnDoing;//委托 Action和delegate一样
    public void OnEnter(PointerEventDate p){
        if(OnDoing!=null)//不为空说明有人注册了这个委托
{
   OnDoing();   
}
    }
}


class Bag:Behaviour
{
    pubic Grid grid;//脚本 
    void Awake()
    {
    Grid.OnDoing += Doing;
    }
    //实现委托的方法
    public void Doing(){}
}

//Action的参数是这样写的
public static Action OnDoing;


22,如果需要脚本传值,最好还是不用sendMessage,效率低。在脚本内写公共或者静态方法来进行改变值比较好。


23,StringBuilder需要引入 using System.Text;


24,//UI组件的povit可以控制UI的动态生成位置,比如说鼠标移动到一个点,UI生成到这个点,povit设置在哪里,UI的povit就在哪里。


25,判断事件在哪个UI上发生
public void OnEndDrag(PointerEventData eventDate)
{
    event.pointerEnter.gameObject//在哪个UI上
}


!!!!!

26,在拖动UI的时候,如果是Canvas的直接子物体,在整个Canvas界面中拖动的话是没有问题的,如果这个UI是Canvas的子物体的子物体,并且中间的那个物体有缩放,范围和Canvas不一致。

那么在运算的时候就会有偏差(这里的运算是指RectTransformUtility.ScreenPointToLocalPointInRectangle(GameObject.Find("Canvas").GetComponent(), Input.mousePosition, null, out position);)
这种换算坐标的方式时把屏幕坐标转换为UI坐标。如果中间层有缩放,那么在拖动的时候把父物体设置为Canvas的子物体,拖动结束后,再把父物体切换回中间层那个物体。这样就可以解决了


27,格子物体拖动互换的时候,互相改变父物体就好了,需要记录好之前的位置,然后再setParent。


28,改变Image精灵的方法,第一个是路径,第二个是类型
Resources.Load("Pic/LumberjackBG", typeof(Sprite)) as Sprite;


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


关于2D贴图,纹理


1,private int resolution=256;  //分辨率
private Texture2D tex;
// 构造函数 Texture2D(int width,int height,TextureFormat format,bool mipmap);
//第一个和第二个参数是设置分辨率,第三个是图片格式,第四个是纹理映射
tex = new Texture2d(resolution , resolution ,TextureFormat.RGB24 , true); 

//设置颜色,第一个参数是横坐标点的位置,第二个是纵坐标位置,第三个是颜色,注意这里需要根据分辨率,然后用两层循环来铺满所有像素点
texture.SetPixel(x, y, Color.red);
texture.Apply();

OnEnable ()声明周期函数可以在再次被唤醒的时候再次调用,而Awake()函数里的逻辑只能关闭运行之后再次运行才可以


在一个变量上面添加如
[Range(2, 512)]
public int reslution=256;
这样在引擎里就可以有拖动条来选择变量大小


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


关于菜单


1,创建引擎上方的菜单
using UnityEngine;
using UnityEditor;

[MenuItem("Example/Create Cube")]
static void CreateCube()
{
   GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);//创建原始Cube
   Undo.RegisterCreatedObjectUndo(cube, "Create Cube");//给cube注册撤销,可以在运行时用Ctrl+z进行撤销
}

Unity的Undo采用的栈,后进先出的模式,Undo.RegisterCreatedObjectUndo(cube, "Create Cube")记录了状态,并保存在栈内。


2,Undo的类型

Undo.RecordObject(s)记录Object的状态
Undo.AddComponent 要添加Component的时候使用,可以撤销掉新加的Component
Undo.RegisterCreatedObjectUndo 新建Object的时候使用,可以撤销新建的物体
Undo.DestroyObjectImmediate 要删除Object的时候使用,可以撤销删除操作
Undo.SetTransformParent 修改Transform的Parent的时候使用,可以恢复层次结构


Undo中有Group的概念,通过Undo.IncrementCurrentGroup()来增大groupID,一个group可以包含多个记录并可以同时操作。


Undo.RevertAllInCurrentGroup() 撤回当前groupID的所有操作
Undo.IncrementCurrentGroup() 把记录的groupId加1
Undo.RevertAllDownToGroup(int groupID) 回退到groupID的状态
Undo.CollapseUndoOperations (int groupID) 把groupID组中的记录折叠,一次Ctrl+z即可回退该组所有记录


3,创建编辑器菜单

using UnityEngine ;
using System . Collections ;
 
public class Test : MonoBehaviour
{
 
[ HideInInspector ] [ SerializeField ] Rect pRectValue ;
     public Rect mRectValue
{
         get
{
return pRectValue ;
}
         set
{
             pRectValue = value ;
         }
     }
 
[ HideInInspector ] [ SerializeField ] Texture pTexture ;
     public Texture texture
{
         get
{
return pTexture ;
}
         set
{
             pTexture = value ;
         }
     }
 
}


using UnityEditor ;
using UnityEngine ;
 
//自定义Tset脚本
[ CustomEditor ( typeof ( Test ) ) ]
//在编辑模式下执行脚本,这里用处不大可以删除。
[ ExecuteInEditMode ]
//请继承Editor
public class MyEditor : Editor
{
//在这里方法中就可以绘制面板。
     public override void OnInspectorGUI ( )
{
//得到Test对象
         Test test = ( Test ) target ;
//绘制一个窗口
test . mRectValue = EditorGUILayout . RectField ( "窗口坐标" ,
test . mRectValue ) ;
//绘制一个贴图槽
test . texture =    EditorGUILayout . ObjectField ( "增加一个贴图" , test . texture , typeof ( Texture ) , true ) as Texture ;
}
}






-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


关于缩放旋转位移,向量,四元数等


1,求两个四元数的角度。
四元数.Angle(四元数A,四元数B);


2,欧拉角是按照ZXY的顺序旋转的,先旋转Z轴,然后再旋转XY轴。


3,关于旋转的描述
旋转1
transform.Rotate(new Vector3(90, 0, 0), Space.Self);  
transform.Rotate(new Vector3(0, 90, 0), Space.Self); 
旋转2
transform.Rotate(new Vector3(90, 90, 0), Space.Self); 
旋转1和旋转2的结果是不同的,
如果是分为两次旋转X,Y轴,那么旋转X轴之后会改变自身的坐标系,那么会根据自身坐标系再进行Y轴旋转。
最终结论是:每次使用Space.self进行rotate时,都是绕着调用时刻的坐标轴进行旋转的。


在Unity里,欧拉旋转的旋转顺序是Z、X、Y。
静态欧拉角和动态欧拉角是可以相互转换的
静态欧拉角是世界坐标系的旋转,按照Z-X-Y的顺序旋转。
动态欧拉角是局部坐标系的旋转。
 其结论就是:在Space.World中旋转以 Z-X-Y 归顺旋转角度(x、y、z),等价于在Space.Self中分别顺次旋转
(0,y,0)、(x,0,0)、(0,0,z)。顺序刚好相反。

Unity中的四元数支持和一个Vector3相乘,如果把这个Vector3看作一个向量,那么左乘一个四元数,就相当于对这个向量进行对应的旋转。

transform.localEulerAngles是360度的,超过360会变为0。


4,向量Lerp   四元数Slerp  最后一个参数都是float t,这里这个需要t * Time.deltaTime,不然没有平滑过渡。


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


关于动画


1,武器绑定
1.max里把模型归位到0.0.0点。
2.再把坐标放在握点那里。(如果不确定点位,最好新建个球体,转化成poly后,去Attach武器,再删去球体)
3.模型需Reset XForm!
4.输出时,不需要勾选 动画。
这样,武器到unity里,直接放在手下的 控制武器骨骼,差不多就能匹配上,但是我们 还需要在unity里,把 Rotation的X 轴归0。


2,动画事件
如果该角色有动画控制器,那么打开动画控制器可以点击左边列表选择需要添加事件的动画,在动画帧面板中找到事件帧点击按钮添加事件,
前提是在该角色身上绑定了脚本,并且脚本中有相应的回调方法,在事件帧上添加就可以了,方法需要是public的,应该是。


3,要想同时播放几个音乐,那么就要添加几个AudioSource组件,用音频资源数组
AudioSource[] aus = GameObject.GetComponents();这样来控制播放音频。


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


关于生命周期

1,在OnGUI中你不应该依赖Time.deltaTime,因为OnGUI有可能在一帧中被多次调用并且每次deltatime的值都是相同的,直到下一帧刷新


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


关于异常

1,NullReferenceException:一般是指脚本里public的变量在引擎里没有赋值。


-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


关于字符串

1,XXXYYYXXX   字符串中改变一段文字的颜色,YYY被改变,XXX没有改变。
XXXYYYXXX     字符串中改变一段文字的尺寸,YYY被改变,XXX没有改变。

你可能感兴趣的:(关于Unity记录)