Unity C# Tutorials - Building a Graph Visualizing Math

Unity入门系列

目标: 创建图形, 可视化数学函数

Unity C# Tutorials - Building a Graph Visualizing Math_第1张图片

1 用立方体cube组成线

依赖数学函数, 计算出一系列的坐标对, 然后组成一条线

Unity C# Tutorials - Building a Graph Visualizing Math_第2张图片

1.1 Prefabs 预制件

创建一个cube

删除 collider component

拉到Assets中, 这样就形成了一个prefabs

删除场景中的cube


Unity C# Tutorials - Building a Graph Visualizing Math_第3张图片

1.2 Graph component

建一个脚本Graph

新建一个C# script, 命名为Graph

添加变量 public Transform pointPrefab;

新建一个Game Object

Create Empty, 命名为Graph

把上面的脚本Graph添加为component

再把上面的预制件cube设置到point prefab字段

Unity C# Tutorials - Building a Graph Visualizing Math_第4张图片

1.3 实例化预制件

通过Instatiate方法实例化

public class Graph : MonoBehaviour {

    public Transform pointPrefab;

    void Awake () {

        Instantiate(pointPrefab);

    }

}

Unity C# Tutorials - Building a Graph Visualizing Math_第5张图片

通过 Transform point = Instantiate(pointPrefab); 获得对象的引用

通过对象的localPosition属性设置位置

位置参数使用 3D vector.

        Transform point = Instantiate(pointPrefab);

        point.localPosition = Vector3.right;

试运行, 可以看到位置略有变化的立方体.

下面添加多一个对象

        Transform point = Instantiate(pointPrefab);

        point.localPosition = Vector3.right;

        point = Instantiate(pointPrefab);

        point.localPosition = Vector3.right * 2;

Unity C# Tutorials - Building a Graph Visualizing Math_第6张图片
两个立方体,x坐标风别是1和2

1.4 循环代码

        int i = 0;

        while (i < 10)

        {

            Transform point = Instantiate(pointPrefab);

            point.localPosition = Vector3.right * i;

            i = i + 1;

        }

Unity C# Tutorials - Building a Graph Visualizing Math_第7张图片

1.5 简化代码

        for (int i = 0; i < 10; i++)

        {

            Transform point = Instantiate(pointPrefab);

            point.localPosition = Vector3.right * i;

        }

效果是一样的.

1.6 改变范围

为函数表达方便, x的范围一般在0-1, 或者-1 ~ 1

相应的, 立方体也需要缩小

        for (int i = 0; i < 10; i++)

        {

            Transform point = Instantiate(pointPrefab);

            point.localPosition = Vector3.right * i;

            point.localScale = Vector3.one / 5f;

        }

Unity C# Tutorials - Building a Graph Visualizing Math_第8张图片

调整x的范围到 -1 ~ 1

point.localPosition = Vector3.right * ((i + 0.5f) / 5f - 1f);

重新排成一条直线.

1.7 优化一下代码

        Vector3 scale = Vector3.one / 5f;

        Vector3 position;

        position.y = 0f;

        position.z = 0f;

        for (int i = 0; i < 10; i++)

        {

            Transform point = Instantiate(pointPrefab);

            position.x = (i + 0.5f) / 5f - 1f;

            point.localPosition = position;

            point.localScale = scale;

        }

1.8 通过函数, 用x计算出y

f(x)=x

        Vector3 scale = Vector3.one / 5f;

        Vector3 position;

        //position.y = 0f;

        position.z = 0f;

        for (int i = 0; i < 10; i++)

        {

            Transform point = Instantiate(pointPrefab);

            position.x = (i + 0.5f) / 5f - 1f;

            position.y = position.x;

            point.localPosition = position;

            point.localScale = scale;

        }


Unity C# Tutorials - Building a Graph Visualizing Math_第9张图片

f(x)=x2

position.y = position.x * position.x;

Unity C# Tutorials - Building a Graph Visualizing Math_第10张图片


2 创建更多的立方体

2.1 可变数量

添加变量

public int resolution = 10;

Unity C# Tutorials - Building a Graph Visualizing Math_第11张图片

指定范围

    [Range(10, 100)]

    public int resolution = 10;

Unity C# Tutorials - Building a Graph Visualizing Math_第12张图片

2.2 使用这个变量

        float step = 2f / resolution;

        Vector3 scale = Vector3.one * step;

        Vector3 position;

        position.z = 0f;

        for (int i = 0; i < resolution; i++)

        {

            Transform point = Instantiate(pointPrefab);

            position.x = (i + 0.5f) * step - 1f;

            position.y = position.x * position.x;

            point.localPosition = position;

            point.localScale = scale;

        }

Unity C# Tutorials - Building a Graph Visualizing Math_第13张图片

2.3 设置层次, 方便管理

现在生成的立方体都是在根节点上面

Unity C# Tutorials - Building a Graph Visualizing Math_第14张图片

方便管理, 给他们设置一个父亲

point.SetParent(transform, false);

Unity C# Tutorials - Building a Graph Visualizing Math_第15张图片

3, 设置颜色

3.1 定义着色器 Shader

Assets / Create / Shader / Standard Surface Shader

命名为ColoredPoint.

Unity C# Tutorials - Building a Graph Visualizing Math_第16张图片

着色器是用脚本定义的, 但语法不同于C#, 双击可以看到脚本:

Shader "Custom/ColoredPoint" {

Properties {

_Color ("Color", Color) = (1,1,1,1)

_MainTex ("Albedo (RGB)", 2D) = "white" {}

_Glossiness ("Smoothness", Range(0,1)) = 0.5

_Metallic ("Metallic", Range(0,1)) = 0.0

}

SubShader {

Tags { "RenderType"="Opaque" }

LOD 200

CGPROGRAM

#pragma surface surf Standard fullforwardshadows

#pragma target 3.0

sampler2D _MainTex;

struct Input {

float2 uv_MainTex;

};

half _Glossiness;

half _Metallic;

fixed4 _Color;

UNITY_INSTANCING_CBUFFER_START(Props)

UNITY_INSTANCING_CBUFFER_END

void surf (Input IN, inout SurfaceOutputStandard o) {

fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

o.Albedo = c.rgb;

o.Metallic = _Metallic;

o.Smoothness = _Glossiness;

o.Alpha = c.a;

}

ENDCG

}

FallBack "Diffuse"

}

修改成我们需要的, 留意 struct Input 部分

Shader "Custom/ColoredPoint" {

Properties {

// _Color ("Color", Color) = (1,1,1,1)

// _MainTex ("Albedo (RGB)", 2D) = "white" {}

_Glossiness ("Smoothness", Range(0,1)) = 0.5

_Metallic ("Metallic", Range(0,1)) = 0.0

}

SubShader {

Tags { "RenderType"="Opaque" }

LOD 200

CGPROGRAM

#pragma surface surf Standard fullforwardshadows

#pragma target 3.0

// sampler2D _MainTex;

struct Input {

// float2 uv_MainTex;

            float3 worldPos;

};

half _Glossiness;

half _Metallic;

// fixed4 _Color;

UNITY_INSTANCING_CBUFFER_START(Props)

UNITY_INSTANCING_CBUFFER_END

void surf (Input IN, inout SurfaceOutputStandard o) {

// fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;

// o.Albedo = c.rgb;

o.Metallic = _Metallic;

o.Smoothness = _Glossiness;

// o.Alpha = c.a;

o.Alpha = 1;

}

ENDCG

}

FallBack "Diffuse"

}

现在我们已经有了一个可编程的shader

创建一个material, 命名为Colored Point, 采用上面的shader

给cube设置material为ColoredPoint

Unity C# Tutorials - Building a Graph Visualizing Math_第17张图片

3.2 用坐标定义颜色

现在进入play模式, cube都是黑色的,

修改shader的surf函数:

// o.Albedo = 0;

o.Albedo.r = IN.worldPos.x * 0.5 + 0.5;

Unity C# Tutorials - Building a Graph Visualizing Math_第18张图片

用y赋值给绿色:

o.Albedo.r = IN.worldPos.x * 0.5 + 0.5;

o.Albedo.g = IN.worldPos.y * 0.5 + 0.5;

可合并成一行:(红色 + 绿色 = 黄色)

o.Albedo.rg = IN.worldPos.xy * 0.5 + 0.5;

Unity C# Tutorials - Building a Graph Visualizing Math_第19张图片

改一个函数玩玩: position.y = position.x * position.x* position.x;


Unity C# Tutorials - Building a Graph Visualizing Math_第20张图片

4 让图像动起来,

要让图像动起来, 必须增加一个时间参数: f(x,t)取代f(x),

4.1 追踪这些点

为了让这些点动起来, 我们先建一个数组, 保存这些点, 以便可以控制他们, 改变他们的位置

points = new Transform[resolution];

for (int i = 0; i < resolution; i++) {

points[i] = point;

}

4.2 改变点的坐标

为了动态,y值的计算移到了update函数:

public class Graph : MonoBehaviour

{

    public Transform pointPrefab;

    [Range(10, 100)]

    public int resolution = 10;

    public Transform[] points;

    void Awake()

    {

        float step = 2f / resolution;

        Vector3 scale = Vector3.one * step;

        Vector3 position;

        position.z = 0f;

        position.y = 0f;

        points = new Transform[resolution];

        for (int i = 0; i < resolution; i++)

        {

            Transform point = Instantiate(pointPrefab);

            position.x = (i + 0.5f) * step - 1f;

            //不在这里计算y值了

            point.localPosition = position;

            point.localScale = scale;

            point.SetParent(transform, false);

            points[i] = point;

        }

    }

    void Update()

    {

        for (int i = 0; i < points.Length; i++)

        {

            Transform point = points[i];

            Vector3 position = point.localPosition;

            position.y = position.x * position.x * position.x;

            point.localPosition = position;

        }

    }

}

4.3 显示正弦波

现在进入play模式, 点坐标是一直值更新的, 只是一直一样, 所以我们看不出, 为了看效果, 采用正弦函数 + 时间变量

position.y =Mathf.Sin(Mathf.PI *(position.x+Time.time));

这样就可以看到动态效果了


原文: http://catlikecoding.com/unity/tutorials/basics/building-a-graph/

你可能感兴趣的:(Unity C# Tutorials - Building a Graph Visualizing Math)