013-Unity编辑器

前排提要:

Unity中的几种坐标系:理解Unity3D中的四种坐标体系_u012371712的博客-CSDN博客

上面只说了4种,这篇结合Shader补充和扩展了一些:unity 七种坐标系统详解与互相转换的方法 模型坐标、世界坐标、观察坐标(视口坐标)、裁剪坐标、屏幕坐标、ui坐标、uv坐标_我们做点事情吧-CSDN博客_模型坐标和世界坐标

另外,裁剪坐标系和视口坐标系可以认为是相同的,这个在第二篇中没有明说

灯光面板:Unity实时GI与烘焙GI_TQT的博客-CSDN博客

重要文件夹:Unity资产,特殊文件夹以及重要路径_u012138730的专栏-CSDN博客

2D物理关节:Unity - 2D物理关节 - SouthBegonia - 博客园


美术相关:

Unity线性空间和Gamma空间下的渲染流程:

 

Unity中的渲染管线:

Pipeline Asset和Render的关系可以先类比接口和每一个实现的接口方法

可以参考:URP——通用渲染管线中的渲染_liquanyi007的博客-CSDN博客

内置(默认的)渲染管线

SRP(可编程渲染管线)

URP(通用渲染管线,Unity提供的特殊的SRP)

HDPR(高清渲染管线,Unity提供的特殊的SRP)

天空盒生成的问题:注意不用反射探针仅用灯光面板生成的天空盒不可调节(如反射的区域,参照点的位置等等),所以局限特别大


Unity中的组件:

ScroolRect组件:拖动需要滑动的物体到Contont下(一般是该组件挂载物体的子物体),注意需要滑动的物体大小最好不要等于该组件挂载物体的大小,否则滑动效果不明显,其它参数可以看文档

Horizontal Layout Group:规范水平布局的组件,挂载在父物体上,然后子物体的水平布局将受该组件调控

Vertical Layout Group:Padding:布局组边缘内的填充,例如如果top为5,那么当前挂载该组件的游戏物体会先在该物体的顶部边缘内侧填充5像素,再布局元素。Child Force Expand,是否强制所有子元素(将所有子元素同时选中)的区域扩展以填充当前组件挂载游戏物体多余的空间,不会改变每个子元素的大小,只是位置的移动。Control Child Size,是否可以控制子元素的大小,将Child Force Expand选中后再选中该项会发现游戏物体为了填满整个区域其大小和位置都会改变。Use Child Scale,在布局和调整时是否考虑所有子元素(将所有子元素同时选中)的缩放,可以在改变子元素的缩放后查看勾选和不勾选的区别(其它相似组件的参数也可参考该组件)

Grid Layout Group:Start Corner和Child Alignment的区别:前者是每个子物体从什么地方开始摆,如果是Upper Left,则说明每增加一个子物体,该物体都是在指定区域(这里指该组件挂载物体的范围再减去去已经摆好子物体所占的范围)的左上角开始摆;后者是所有子物体的整体布局,如果是Upper Left,则说明若将所有子物体看作一个整体时该整体是偏向左上的

Content Size Fitter:可以调整当前组件挂载的游戏物体的大小,调整模式有三种,分别是Unconstrained(无限制),Preferred Size(最合适大小,如果当前组件上还挂有文本组件的话那么随着文本中文字的增多,该组件将自动调整挂载游戏物体的大小也就是文本框的大小),Min Size(最小尺寸)即将大小设置为0,可以配合Vertical Layout Group使用(挂载该组件的游戏物体会将所有子元素的大小算作自己的大小,所以Content Size Fitter可以根据子元素的数目对父物体的大小做合适的调整)。注意该组件不推荐嵌套,但嵌套也可以使用

Polygon Collider 2D:多边形碰撞器,碰撞器的一种

刚体休眠的坑:如果通过键盘或者其它设备导致某个游戏物体的刚体状态放生改变,那么当前场景中的任意一个Sleeping Mode设置为Start Awake的刚体,都会被唤醒


基本和细节:

按住V建移动物体可以进行定点吸附

地形设计时按住Shift可以抹平地形

Unity中的小方格为长度为1米,Unity的距离默认单位为米

Unity中的Pivot:用于计算坐标、作为旋转中心等,默认与几何中心重合,但不是几何中心,后者是程序计算出来的中心点,不能更改,Anchor位置的确定就是以父亲的几何中心为参考点的

Unity中的局部坐标即以父亲的pivot为原点的坐标,世界坐标是以某一点为原点的坐标,屏幕坐标是以左下角为原点,以像素为单位的坐标。注意,前两者的基本单位都是unity中规定好的基本单位。Unity中的几种坐标系:理解Unity3D中的四种坐标体系_u012371712的博客-CSDN博客

Unity面板中显示的是相对父物体的局部坐标

物体旋转是绕着Pivot的

Unity中Project面板下的图片文件均为Texture2D类型(无论TextureType选哪种),而我们常用的Sprite类型是指当图片的TextureType选择Sprite(2D and UI)时该图片展开下的图片文件(注意不是该图片本身,本身还是Texture2D类型)


相机

对于Sorting Layer是指在特定相机下的渲染层级,相机按照从上到下的顺序渲染,Order in Layer是指在渲染层级相同时按照该值大的覆盖小的的顺序显示

摄像机移动导致的物体突然消失,往往是渲染问题,需要改大一下Order in Layer

Layer是用来让不同相机拍摄的,即如果将某些相机设置为只能拍某个层级,那么如果想要某个物体被这个相机拍到就需要将该物体的Layer设置为相机能拍的层级


动画:

上图动画切换区间的长短主要影响动画切换的时间,位置主要影响动画的切换时机(注意从左边界开始播目标动画),而HasExitTime:若不勾选则表示是否当设定的条件一旦不满足,则立刻终止切换(这也表明动画不会自动切换),勾选的话,会播放到切换区间左边界再切换

关于Exit Time的详细解释:Exit Time表示播放多少百分比的动画后进入转换。注意当其值为0时表示的是当动画播完后进入转换(游戏运行时可以看到,编辑器下只能看到开始就转换)
没有Exit Time表示不退出,除非指定条件

动画状态机的空状态:

当2D图片处于该状态时会保持和上一个状态(动画)的最后一张图片一样,如果没有上一个状态,即默认就是空状态,那么图片与图片组件中设置的一样。也就是空状态不改变图片

当3D模型处于该状态时会进入到模型在建模软件中的设定姿势

ApplyRootMotion:

Unity中的动画变换分为两种,一种是BodyTransform,另一种是RootTransform,二者区别如下:

如果是设置成BodyTransform的话,就相当这些变换是属于动画本身的一部分,也就是说,不管设不设置ApplyRootMotion,在场景中,我们都会看到模型位置或角度的变化(因为Body Transform不影响模型实际的位置和角度,所以这里只是纯粹的动画效果,模型的位置和角度参数值不变)

如果设置成RootTransform,RootTransform将影响模型的实际位置和角度(前提是要设置“ApplyRootMotion”,如果不设置ApplyRootMotion的话,也就是说变换将不应用,场景中的模型位置或角度是不会有变化的(参数值自然也不变),就像一个行走动画,可能一直在原地行走)

2D动画可以通过逐帧图片实现(BodyTransform),也可以改变Transform等组件实现(RootTransform)

由于ApplyRootMotion在前一种方式中无效,所以我们着重看后一种方式

当不勾选时物体会严格按照动画变化,且无法从外界干涉,这是最基本和自然的情况。而勾选时如果有刚体,则动画不会播放,如果无刚体,动画正常播放且可以从外界干涉,最终的看到的效果是两者叠加的结果

3D同理

骨骼动画:
模型的网格(Mesh)则分为 Skeletal Mesh(已绑定骨骼)和 Static Mesh(未绑定骨骼)两种。
Skeletal Mesh 由两部分组成:固有的多边形数据 + 额外存有一份骨骼信息,导入 Unity 时会生成一个 Skinned Mesh Renderer 组件;
而 Static Mesh 只有多边形数据,没有骨骼信息,对于这种模型网格,只能translated, rotated and scaled,而无法通过骨骼 animate the vertices,所以只会生成一个 Mesh Filter + Mesh Renderer。出自:https://gameinstitute.qq.com/community/detail/117790

TimeLine ActivationTrack 中的Post-playback state选项卡:首先这个属性虽然每一个这样的轨道都有,但它表示的是当前TimeLine的整个动画全部播放完之后各个轨道所对应游戏物体的状态。Active表示播放完之后该轨道游戏物体处于Active状态,Inactive同理,Revert表示动画播放完之后将该游戏物体恢复到动画播放之前的活跃状态,Leave As Is表示该动画播放完之后保持原样,在具体实践中的情况比较复杂

2D Blend Type:

2D Simple Directional:普通的混合,在一个方向上只能有一个动作,比如跑和走 就不能融合到一起

2D Freeform Directional:可以在同一方向设置两个,但是必须在原点有一个Idle状态,并且对旋转有一定限制

2D Freeform Cartesian:没什么限制


编辑器API相关:

绘制编辑器常用api:

//需要准备这样的一个类
using UnityEditor;

public class AudioWindowEditor : EditorWindow
{
    [MenuItem("Manager/AudioManager")]//在菜单栏中创建选项
    static void CreateWindow()//当选项被点击后需要执行的方法
    {
        //下面的方法窗口固定大小
        //Rect rect = new Rect(0, 0, 300, 400);
        //AudioWindowEditor window =   EditorWindow.GetWindowWithRect(typeof(AudioWindowEditor), rect) as AudioWindowEditor;
        //下面的方法窗口大小可改变
        AudioWindowEditor window = EditorWindow.GetWindow<AudioWindowEditor>("音效管理");
    
        //必须要显示窗口
        window.Show();
    }
    
    //Awake方法和Update方法的执行时机变为当窗口实例化时和窗口显示时,MonoBehaviour类中的其它方法也可以类比

    void OnGUI()//Unity内置方法,绘制UI界面时使用
    {
        EditorGUILayout.TextField("输入文字1", text);//第一个参数为文本框的名称,第二个参数为要在文本框显示的文字,返回值为文本框显示的字符串
        GUILayout.TextField("输入文字2");//参数为要在文本框显示的文字,返回值为文本框显示的文字,注意它不可以在编辑器面板编辑
        EditorGUI.TextField(new Rect(0, 40, 100, 20), "输入文字3");//同第二种,但可以指定位置
    
        GUILayout.BeginHorizontal();//排版开始变为水平
        GUILayout.Label("音效名称");//绘制不可更改的文字
        GUILayout.Label("音效路径");
        GUILayout.Label("操作");
        GUILayout.EndHorizontal();//排版不再水平

        if (GUILayout.Button("删除"))//绘制按钮,参数为按钮的内容,并且判断按钮是否按下
    }

    void OnInspectorUpdate()//内置方法,每秒执行10次,用来更新面板
    {
    }
}

Ps:
//创建一个field,并指定该field的类型,第三个参数为该object是否可以是场景中的物体
tex = (Texture2D)EditorGUILayout.ObjectField(tex, typeof(Texture2D), true);

//打开windows文件面板并返回选中文件夹的路径,第一个参数为面板名称,第二个参数为默认所在路径,第三个参数为默认选择的文件名
fontPath = EditorUtility.OpenFolderPanel("字体路径", Application.dataPath, "");

string selectionPath = AssetDatabase.GetAssetPath(tex); //得到tex的相对路径(以Assets开头)

string selectionExt = Path.GetExtension(selectionPath); //得到指定路径对应文件的后缀名
//编辑器相关的另一个类ScriptableWizard,它继承自EditorWindow类,做了一些封装,使我们使用更方便
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class RenderCubemap : ScriptableWizard
{
    public Transform renderPos;
    public Cubemap cubemap;

    [MenuItem("Tools/CreateCubemap")]
    static void CreateCubemap()
    {
        ScriptableWizard.DisplayWizard<RenderCubemap>("Render Cube", "Create"); //窗口标题和按钮上的文字,<>中需要放一个ScriptableWizard类或其子类,这里放该类即可
    }

    private void OnWizardUpdate() //该类所对应的窗口
    {
        helpString = "选择渲染位置并确定需要设置的Cubemap"; //提示文本
        isValid = renderPos != null && cubemap !=null; //本例中,指Create按钮是否有效
    }

    private void OnWizardCreate() //本例中点击Create按钮后发生的事情
    {
        GameObject go = new GameObject("CubemapCam"); //创建一个名叫CubemapCam的GameObject
        Camera camera = go.AddComponent<Camera>();
        go.transform.position = renderPos.position;
        camera.RenderToCubemap(cubemap); //利用相机生成Cubemap
        DestroyImmediate(go); //可以用Destroy代替
    }
}
//绘制gizmos用的方法
private void OnDrawGizmos()
{
    //画线框
    Gizmos.color = Color.green;
    if (this.mesh!=null)
    {
        //不要用DrawMesh,它是填充的
        Gizmos.DrawWireMesh(this.mesh, this.transform.position, this.transform.rotation, this.transform.localScale);
    }
    //用控制柄类画箭头
    UnityEditor.Handles.color = Color.red;
    UnityEditor.Handles.ArrowHandleCap(0, transform.position, this.transform.rotation, 1f, EventType.Repaint);
}

其它API:

//如果修改一个Unity的序列化资源(如Prefab,美术资源,ScriptableObject等类型),必须告诉Unity该值已经改变
//每当一个属性发生变化,Unity内置组件在内部调用setDirty
//而上述资源不自动做这个,因此为了一致性最好手动加上
EditorUtility.SetDirty(m_myFont);
//标记为已更改资源后,再调用SaveAssets即可将改变后的资源保存在磁盘(注意该方法对于编辑器界面的修改无法保存,只能保存代码中的修改)
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();//刷新资源
//详见:https://blog.csdn.net/ltycloud/article/details/79318054

//创建一个ScriptableObject对象,通过泛型可以创建其子类的对象,泛型中的类型必须继承自它
settings = ScriptableObject.CreateInstance<JPhysicsSetting>();
//将创建的ScriptableObject对象保存在硬盘的指定路径
AssetDatabase.CreateAsset(settings, _settingsPath);

//直接在编辑器下操作是可以撤销的,而如果我们使用脚本在编辑器环境下做出的操作则不可以撤销,这与Unity内部的实现有关
//要想撤销,可以使用下面的方法,记录当前_target的信息,方便还原
//第一个参数即为要做记录的对象引用,第二个参数为要在撤消历史记录中显示(即在撤销菜单中可见)的操作的名称,可以重复但不推荐
Undo.RecordObject(_target, "Change Layer Masks");

//将Project面板置于页面最顶端同时获得焦点
EditorUtility.FocusProjectWindow();

//设置选中物体
Selection.activeObject = settings;

当我们想给自己写的某个脚本定制面板时可以使用[CustomEditor(typeof(脚本名))]该特性,用法如下:

[CustomEditor(typeof(JBoxCollider2D))]
public class JBoxCollider2DInspector : Editor
{
    private JBoxCollider2D _target;

    void OnEnable()
    {
        //获得要定制面板脚本的对象
        _target = this.target as JBoxCollider2D;
        //根据名称获得当前项目(编辑器)中的指定序列化字段
        _gravity = serializedObject.FindProperty("_gravity");
    }

    void OnDisable()
    {
            
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        //利用编辑器方法重写

        //如果输入数据值有改变则返回ture
	    if (GUI.changed)
		{
			
		}

		//保存当前项目(编辑器)中序列化值的更改
		serializedObject.ApplyModifiedProperties();
    }

    //OnSceneGUI等其它适用方法

}

三个常用编辑器开发绘图类辨析:

1.EditorGUILayout、GUILayout两个可以用来画编辑器的GUI(所以在下面三个画场景视图的方法中使用无效),前者位于UnityEditor命名空间下,后者位于UnityEngine命名空间下

注意:GUILayout和GUI(命名空间与GUILayout同)也可以用来画运行时游戏中的GUI(此时常把它们写在继承了MonoBehaviour类并已挂载游戏物体的脚本中,它们绘制的物体只有运行时才会显示),GUILayout类与GUI类不同的是它自动帮我们处理了布局问题
2.Handle主要用来画场景视图中的东西(在下面三个画场景视图的方法调用时),但也能在编辑器面板画出东西(在OnInspectorGUI中调用时),它位于Editor命名空间下
3.Gizmos位于UnityEngine命名空间下,只能画场景视图中的东西且只有当它在OnDrawGizmos和OnDrawGizmosSelected中使用时才有效

常用编辑器开发绘图方法:

画场景视图的方法:
OnDrawGizmos:每帧调用

OnDrawGizmosSelected:物体被选中的时候每帧调用
OnSceneGUI:同OnDrawGizmosSelected

注意:要实现OnSceneGUI必须继承Editor类,实现OnDrawGizmos和OnDrawGizmosSelected要继承MonoBehaviour类
画编辑器的方法:
OnInspectorGUI:在这里自定义编辑器面板,只要我们做出了关于该面板的操作该方法就会执行,例如将鼠标移入移出该面板等

注意:要重写该方法必须继承Editor类

画游戏运行时GUI界面的方法:

OnGUI:每帧调用一次,用来绘制GUI界面

实现该方法必须继承MonoBehaviour类

Editor文件夹和#if UNITY_EDITOR:
Editor文件夹下的文件不会打包,可以存一些编辑器工具,减小游戏包的大小;而后者的宏定义表示如果是在Unity编辑器平台上则运行其中的代码


其它:

关于编辑器与序列化的一些知识(解释了为什么Unity中只有序列化的变量才可以被显示在面板上):

当用户直接在面板输入且JBounds(自定义的一个类,举例用)可以被序列化,那么该输入的值会被序列化,用于游戏运行时的注入以及运行结束时的恢复(注入都发生在游戏运行和运行结束之后)。如果不能序列化,则不会被序列化,只是在面板上保存,游戏运行和结束时没有序列化的变量自然也不会被注入值

Unity在编辑器界面会先创建一个JBoxCollider2D对象,为用户提供编辑器下的操作,运行时会重新创建并将编辑器模式下输入并序列化好的值注入,退出运行时同样重新一个JBoxCollider2D对象,把编辑器下输入并序列化好的值注入以实现还原

FullScreen Mode:

ExclusiveFullScreen:

独占模式

在此模式下,Unity 将更改显示器分辨率,并且声明目标显示器在支持它的平台上的独占使用。 注意,在使用独占模式时,从启动对话框中不可获得监视器选择。此外,在最小化 Player 时不支持后台运行

FullScreenWindow:

全屏窗口

在此模式下,Unity 将创建一个覆盖整个屏幕的窗口。它将始终以桌面分辨率运行,其他请求的分辨率将进行缩放以适合此窗口。操作系统 UI 将正确显示在全屏窗口的顶部(例如 IME 输入窗口)

MaximizedWindow:

最大化窗口

在此模式下,Unity 将在支持此模式的平台上创建窗口且最大化窗口。等同于 macOS 上的 FullscreenWindowWithDockAndMenuBar

Windowed

窗口化

在此模式下,Unity 将在支持此模式的平台上创建一个标准非全屏窗口

 Unity中的AssetBundle用于打包游戏资源,在运行时获取这些资源,不能打包C#脚本。参考:unity3d里面prefab、assetbundle、unitypackage等包的使用【图文】_球球闪电_51CTO博客

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity Addressables是Unity引擎用于管理资源加载和打包的工具。它可以帮助我们更方便地管理大量的资源,并且能够降低内存使用和加载时间。 如果想要更改Unity Addressables的编辑器打包路径,可以按照以下步骤进行操作: 1. 打开Unity编辑器,在菜单栏选择Window -> Asset Management -> Addressable Assets。 2. 在Addressable Assets窗口,点击右上角的按钮“Groups”。这将打开Addressable Groups窗口。 3. 在Addressable Groups窗口,选择需要更改打包路径的Group。 4. 在Inspector面板,找到“Path”属性。这是资源的默认保存路径。 5. 点击“Path”属性旁边的“...”按钮。这将打开一个文件夹浏览器,允许你选择新的打包路径。 6. 在文件夹浏览器,选择你想要设置为新的打包路径的文件夹。 7. 点击“选择文件夹”按钮,确认你选择的新打包路径。 8. 点击Addressable Groups窗口右下角的“Apply”按钮,将新的打包路径应用到Addressable Groups。 现在,当你使用Unity Addressables打包资源时,所选Group的资源将会保存到新的打包路径。 需要注意的是,更改打包路径可能会导致一些资源的引用失效或者无法正确加载。所以,在更改路径之前,我们应该确保调整资源的引用路径,以确保资源可以正确地被加载和使用。 希望以上内容能够帮助你更改Unity Addressables的编辑器打包路径。如有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值