Catlike学习笔记(1.2)-使用Unity画函数图像
『Catlike系列教程』第二篇来了今天周六,早上~(上午11点)醒来去超市买了一周的零食回来以后就玩了一整天游戏非常有负罪感。现在晚上九点天还亮着感觉像下午7点左右的样子好像还不是很晚。。。所以就写一点东西吧。这一篇是「Building a Graph」挑战一下试试吧。
PART 1 概述
那么大概文章看下来我们预计要做以下事情。
- 使用一定数量的小方块表达函数图像
- 做一个 Shader 给图像上色使其更好看
- 给图像传入时间参数使其动起来
PART 2 画函数图像
首先我们确认一下要支持的功能细节,根据默认摄像机的位置和视野我们就暂定需要画出函数[-1. 1]之间的图像,同时可以通过一个条拖动来修改函数的解析度,假设解析度可以是[10,100],那么我们需要在x=[-1, 1]之间生成[10,100]个方块。同时动态的调整方块的大小使其完美衔接。代码如下:
public class GraphController : MonoBehaviour
{
[Range(10, 100), SerializeField] private int _resolution;
[SerializeField] private GameObject _cube;
// Use this for initialization
private void Start ()
{
_cube.SetActive(false);
var step = 2f / _resolution;
var startPosX = -1f;
var scale = Vector3.one * step;
for (int i = 0; i < _resolution; i++)
{
var pos = new Vector3(startPosX + i * step, Calc(startPosX + i * step), 0);
var point = Instantiate(_cube, transform);
point.transform.localPosition = pos;
point.transform.localScale = scale;
point.SetActive(true);
}
}
private float Calc(float x)
{
return Mathf.Pow(x, 2);
}
}
根据Calc(float)可以看出我们画出来曲线是如下函数的图像。 $y=x^2$ $f(x)=ax+b$

PART 3 给曲线上色
首先我们创建一个 Surface Shader,通过Assets / Create / Standard Surface Shader创建一个新的 Shader。修改代码如下:
Shader "Custom/ColoredPoint" {
Properties {
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM
// Physically based Standard lighting model, and enable shadows on all light types
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
// 此处将世界坐标传入IN
struct Input {
float3 worldPos;
};
half _Glossiness;
half _Metallic;
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf (Input IN, inout SurfaceOutputStandard o) {
// 在这里根据世界坐标将方块染上不同的颜色
o.Albedo.rgb = IN.worldPos.xyz * 0.5 + 0.5;
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic;
o.Smoothness = _Glossiness;
o.Alpha = 1;
}
ENDCG
}
FallBack "Diffuse"
}
运行效果如下~

PART 4 让曲线动起来
首先曲线之所以会动当然是因为我们将时间作为参数同时传进去导致的~所以我们首先稍微改一下Calc(float)这个函数让时间参数也生效~这里用到Mathf.PI是为了图像从[-1, 1]之间完整的显示一个周期,大家可以随便改改试试。
private float Calc(float x)
{
return Mathf.Sin(Mathf.PI * (x + Time.time));
}
然后直接运行肯定是不行的,我们需要把计算y和设置每个小方块的位置的代码移到Update()中去。最终代码如下:
public class GraphController : MonoBehaviour
{
[Range(10, 100), SerializeField] private int _resolution;
[SerializeField] private GameObject _cube;
private List<Transform> _points;
private float _step;
private float _startX;
// Use this for initialization
private void Start ()
{
_cube.SetActive(false);
_points = new List<Transform>();
_step = 2f / _resolution;
_startX = -1f;
var scale = Vector3.one * _step;
for (int i = 0; i < _resolution; i++)
{
var point = Instantiate(_cube, transform);
_points.Add(point.transform);
point.transform.localScale = scale;
point.SetActive(true);
}
}
private void Update()
{
for (int i = 0; i < _resolution; i++)
{
var x = _startX + i * _step;
var pos = new Vector3(x, Calc(x), 0);
var point = _points[i];
point.transform.localPosition = pos;
}
}
private float Calc(float x)
{
return Mathf.Sin(Mathf.PI * (x + Time.time));
}
}
运行效果如图:

PART 5 总结
这一篇也很简单啊一边做一边写再随便划划水很快就完成了~最后大家可以下载「Github Repo」查看运行结果和全部代码~或者到「原文地址」查看更加详细的过程和思路。
原文链接:https://snatix.com/2018/06/09/020-building-a-grap/
本文由 sNatic 发布于『大喵的新窝』 转载请保留本申明
Catlike学习笔记(1.2)-使用Unity画函数图像的更多相关文章
- Catlike学习笔记(1.3)-使用Unity画更复杂的3D函数图像
第三篇来了-今天去参加了 Unite 2018 Berlin,感觉就是....非常困...回来以后稍微睡了下清醒了觉得是时候认真学习下了,不过讲的很多东西都是还没有发布或者只有 Preview 的版本 ...
- Catlike学习笔记(1.4)-使用Unity构建分形
又两个星期没写文章了,主要是沉迷 Screeps 这个游戏,真的是太好玩了导致我这两个礼拜 Github 小绿点几乎天天刷.其实想开一个新坑大概把自己写 AI 的心路历程记录下,不过觉得因为要消耗太多 ...
- Catlike学习笔记(1.1)-使用Unity实现一个钟表
最近发现『Catlike系列教程』觉得内容真的很赞,感觉有很多地方涉及到了我的知识盲点,如果真的可以照着做下来一遍的话应该收获颇丰.因为教程很长所以逐字翻译不太可能了(主要是翻译的太差).基本上就是把 ...
- MYSQL学习笔记三:日期和时间函数
MYSQL学习笔记三:日期和时间函数 1. 获取当前日期的函数和获取当前时间的函数 /*获取当前日期的函数和获取当前时间的函数.将日期以'YYYY-MM-DD'或者'YYYYMMDD'格式返回 */ ...
- JavaScript学习笔记(十)——高阶函数之map,reduce,filter,sort
在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...
- JavaScript学习笔记(十二)——箭头函数(Arrow Function)
在学习廖雪峰前辈的JavaScript教程中,遇到了一些需要注意的点,因此作为学习笔记列出来,提醒自己注意! 如果大家有需要,欢迎访问前辈的博客https://www.liaoxuefeng.com/ ...
- C++ Primer学习笔记(三) C++中函数是一种类型!!!
C++中函数是一种类型!C++中函数是一种类型!C++中函数是一种类型! 函数名就是变量!函数名就是变量!函数名就是变量! (---20160618最新消息,函数名不是变量名...囧) (---201 ...
- 【opencv学习笔记五】一个简单程序:图像读取与显示
今天我们来学习一个最简单的程序,即从文件读取图像并且创建窗口显示该图像. 目录 [imread]图像读取 [namedWindow]创建window窗口 [imshow]图像显示 [imwrite]图 ...
- hive学习笔记之十:用户自定义聚合函数(UDAF)
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是<hive学习笔记>的第十 ...
随机推荐
- idea html热部署
IDEA SpringBoot 热部署+html修改无需make自动刷新 收藏 HeyS1 发表于 3个月前 阅读 310 收藏 2 点赞 0 评论 0 特邀IBM大咖的主题沙龙,5月20日·北京·3 ...
- Java基础知识强化之集合框架笔记80:HashMap的线程不安全性的体现
1. HashMap 的线程不安全性的体现: 主要是下面两方面: (1)多线程环境下,多个线程同时resize()时候,容易产生死锁现象.即:resize死循环 (2)如果在使用迭代器的过程中有其他线 ...
- 1552/3506. [CQOI2014]排序机械臂【平衡树-splay】
Description Input 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000. 第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. Output ...
- [Violet]天使玩偶/SJY摆棋子
题目 \(KD-tree\)做最近点对的复杂度好像是假的吧,怎么看也看不出来是\(O(\sqrt{n})\)啊 首先\(KD-tree\)长得和平衡树还是很像的,每个节点都存储了一个\(k\)维空间上 ...
- CentOS7.2安装mysql
1. 下载Mysql yum包 http://dev.mysql.com/downloads/repo/yum/ 复制链接使用wget下载 wget http://repo.mysql.com/mys ...
- 二进制包 vs. 源代码包
在ROS中, 我们可能经常会遇到缺少相关的ROS依赖的问题. 有些时候你编译或者运行一些ROS程序, 系统会提示找不到XXX功能包. 如果是缺少ROS的依赖, 通常可以用以下命令来安装: $ sudo ...
- 1553: Good subsequence (很奇妙的set模拟题,也可以直接暴力)
1553: Good subsequence Submit Page Summary Time Limit: 2 Sec Memory Limit: 256 Mb Subm ...
- Linux Shell常用技巧(二)
七. grep家族: 1. grep退出状态: 0: 表示成功: 1: 表示在所提供的文件无法找到匹配的pattern: 2: 表示参数中提供的文件不存在. 见如 ...
- iOS 多线程:『RunLoop』详尽总结
1. RunLoop 简介 1.1 什么是 RunLoop? 可以理解为字面意思:Run 表示运行,Loop 表示循环.结合在一起就是运行的循环的意思.哈哈,我更愿意翻译为『跑圈』.直观理解就像是不停 ...
- rails 中http请求发生access-control-allow-origin错误
在api项目中 本地项目无法访问服务器api 百度了下,查出原因 接着找到rails项目的解决方法,安装rack-cors这个gem包 具体方法如下: Gemfile中加入 gem 'rack-cor ...