[Unity 学习] - 基础篇 - 构建视图
重新学习Unity,做些笔记
链接: https://zhuanlan.zhihu.com/p/346943226
1 创建一排立方体
学习编程时需要对数学有很好的了解。从根本上讲,数学是对代表数字的符号的操作。解方程归结为重写一组符号,让它变成了另一组(通常较短的)符号。数学规则决定了如何进行这种重写。
1.1预制体
我们将使用一个自定义组件来创建此立方体的许多实例并正确放置它们。为此,我们将立方体变成游戏对象模板。将立方体从层次结构窗口拖到项目窗口中。这将创建一种新资产,称为预制件。
预制体和预制实体不同,预制体可以理解为一个模板,这个模板会将预制实体的所有数据都进行初始化,当我们需要改变预制实体时,我们可以自定义的改变这些参数,后文我们会讲到。这里需要注意的是预制体不等于预制实体,我们对预制实体的所有改变都不会影响到预制体。当我们希望改变预制体时,可以直接修改预制体或者改变预制实体后点击playerPrefabs按钮
1.2 Graph组件
我们需要一个C#脚本让这些Point预制体生成视图。创建一个并将其命名为Graph。
在C#脚本中,我们可以实例化预制体,并对这些预制实体进行自定义的修改
下面展示一些 内联代码片
。
//实例化预制体,并设置其父节点
Transform point = Instantiate(pointPrefab);
point.SetParent(transform);
float step = 2f / resclution;
Vector3 size = Vector3.one * step;
Vector3 position = Vector3.zero;
......
//设置位置,将
for(int i = 0;i < points.Length; ++i)
{
Transform point = Instantiate(pointPrefab);
position.x = (float)(i + 0.5) * step - 1f;
position.y = position.x * position.x * position.x;
point.localPosition = position;
point.localScale = size;
point.SetParent(transform);
points[i] = point;
}
如果你希望他动起来可以用
void Update()
{
//加入时间参数,让物体动起来
float time = Time.time;
for(int i=0;i<points.Length;++i)
{
Transform point = points[i];
Vector3 position = point.localPosition;
position.y = Mathf.Sin(Mathf.PI * (position.x + Time.time));
point.localPosition = position;
}
}
2 给视图上色
2.1 创建表面着色器
GPU运行着色器程序以渲染3D对象。Unity的材质资产确定使用哪个着色器,并允许配置其属性。我们需要创建一个自定义着色器以获得所需的功能。通过Assets/ Create / Shader / Standard Surface创建一个,并将其命名为“ Point Surface”。
shader代码:
Shader "Graph/Point Surface"
{
Properties
{
//设置一个可以在Unity中修改的平滑度
_Smoothness("Smoothness", Range(0,1)) = 0.5
}
SubShader
{
CGPROGRAM
//着色器编译器生成具有标准照明并完全支持阴影的表面着色器
#pragma surface ConfigureSurface Standard fullforwardshadows
#pragma target 3.0
// 定义传入的数据,这里传入一个世界坐标的位置
// Input是固定语法,可以传入一些参数
// float3 viewDir - 视图方向 (view direction)。为了计算视差效果(Parallaxeffects),边缘光照等
// float4 with COLOR semantic -每个顶点插值后的颜色
// float4 screenPos - 屏幕空间中的位置。 为了反射效果,需要包含屏幕空间中的位置信息。
// float3 worldPos - 世界空间中的位置。
// float3 worldRefl - 世界空间中的反射向量。 如果surfaceshader没有赋值o.Normal,将会包含世界反射向量。参见例子:Reflect-Diffuse shader。
// float3 worldNormal - 世界空间中的法线向量。如果surfaceshader没有赋值o.Normal,将会包含世界法向量
// float3 worldRefl; INTERNAL_DATA - 世界空间中的反射向量。如果surfaceshader没有赋值o.Normal,将会包含这个参数。为了获得逐像素法线贴图的反射向量,
// 请使用WorldReflectionVector(IN, o.Normal)。参见例子: Reflect-Bumped shader。
// float3 worldNormal; INTERNAL_DATA -世界空间中的法线向量。如果surfaceshader没有赋值o.Normal,将会包含世界法向量。为了获得逐像素法线贴图的法向量,
// 请使用WorldNormalVector(IN, o.Normal)。
struct Input
{
float3 worldPos;
float aaa;// PS:也可以写一些自己的定义的参数,但是目前不知道在哪里可以将这些数据写入 ヽ(´~`;)
};
//平滑度配置,属性块定义的数据需要在SubShader中用同名参数接收
float _Smoothness;
//定义ConfigureSurface方法
//第一个参数是Input类型的输入参数
//第二个参数是表面配置数据,inout表明它用于函数的结果,用法和out一样
//Surface:表面 output:输出 Standard:标准
void ConfigureSurface(Input input, inout SurfaceOutputStandard surface)
{
// 定义的位置为[-1,1],负数是没有意义的,所以我们需要将这部分算入
// surface.Albedo = input.worldPos * 0.5 + 0.5;
// 也可以通过将xy赋值给rg将z值的蓝色过滤掉
surface.Albedo.rg = saturate(input.worldPos.xy * 0.5 + 0.5);
surface.Smoothness = _Smoothness;
}
ENDCG
}
//如果渲染失败就是用默认渲染管线
FallBack "Diffuse"
}
现在,我们有了一个功能良好的着色器,为其创建了一个材质,称为Point Surface。通过在其检查器标题中的Shader下拉列表中选择Graph / Point Surface,将其设置为使用我们的着色器。
PS:这里的Shader代码已经是做好的
===================
学习放牛的星星大佬的Unity教程系列,在这里做个笔记记录一下自己的成长,如果有不对的地方,欢迎各位大佬指出