关于找实习

 • 

昨晚突然觉得有些累,就睡觉去了。结果今天凌晨三点多就醒了,睡不着,不如找点活干。
周围的朋友在找春招,自己也在朋友圈发了一条找实习的状态,因此在博客上也写下吧。

Cocoa 或 Unity 岗都行,地点随意(若是杭州最好)。
简历:https://fincher.im/CV.pdf
英文 CV:https://fincher.im/CV(en).pdf
Portfolio:http://portfolio.justzht.com/

Cocoa 岗位,macOS 只能说会写一些小软件(参见 ArtWallWebDrop),大的项目(比如 Cetacea for Mac)至今还在跳票,貌似也没有什么能证明自己的东西了,至于 iOS 的话个人还是挺有自信的,毕竟做过一些外包,虽然写法以现在的潮流(函数式,Promise,动态化)看起来有些古典了。Unity 岗因为我一直是独立开发,不是行业内的所以也不是很清楚游戏行业的要求标准,个人水平就先参照 Lonely Planet 或者前公司 Raven H-1 的三维小人部分吧,虽然貌似我走了后同事改进了很多。

2017.2.08

 • 

昨天是妹子的生日。跑去找她,玩得很开心。今早醒来后,想起来又是异地了,有些失落。
妹子提前送了我一个 Kindle PaperWhite,挺喜欢的。


发现寒假里貌似不太可能做完任何一个项目了,因此就随便写写,给四五月份要发布的几个大新闻做些基础建设。写了会 Rails 和 ObjC,给 Lonely Planet 迁移到了 Unity 5.5。我开始变得不太那么追求项目和代码的产出了,不知道是我心态变平和了还是因为我懒,也不知道是好事是坏事。


听了 Jake Miller - RumorsObserver Drift - Warm Waves

2017.2.02

 • 

FinGameWorks 的新域名上线了。同时我和陈叔还在准备 FinGameWorks 的 AssetStore Publisher Page
最近略嗜睡。每天都是一点左右睡,十一点多醒。每天都有大人们的饭局,留给自己的时间也不多。几个进行中的项目都稍微做了些修修补补,只不过都没有较大的进展罢了。
考虑下学期找一家 base 杭州的实习,这样离妹子近一些。
看了 降临(Arrival),听了 Moving On and Getting Over by John MayerOcean 7, Pt. 2 by CrayonTreat Me Like Fire by LION BABE

2017.1.26

 • 

近日的剧情像是《挪威的森林》一样。然后渡边碰到了绿子
从大一开始我过的生活就是自己规划自己做,什么事情和亲人和朋友说声就好,但从没有和别人认真商量过。这么一种过法当然随心所欲而且效率极高,但是习惯一切都自己规划好后,想要冒险过一把有趣的生活反而会发怵。比如和妹子在一起这个事情,要考虑好多事情:我以后在哪里工作,妹子还不确定以后做什么工作,妹子以后想要去哪里工作,诸如此类。抱着这些顾虑去思考,总会觉得希望渺茫。后来问了问周边的朋友,大多都是建议我不要因为这些遥不可及的事情去断了可能的感情。想了下也的确,自己是时候鼓足勇气尝试去改变下,了解下其他人了。
感谢给我建议的各位。


China Startup Simulator 这周的开发进度有些缓慢。除去因为大部分时间在聊天以外,我对游戏本身事件的平衡性还在改来改去,导致真正需要填充的事件条目没有扩充到一个可玩的状态。以及这款游戏到底需不需要一个游戏场景?Reigns 和 Toggl 的模拟器都是纯 GUI 的游戏,也没有见多少人抱怨。而如果加上了游戏场景,必然要是一个动态的,根据事件响应的场景,这势必会需要我写很多代码。仅仅把这个游戏当作一个文字游戏来看,场景完全可以砍掉,但如果只是一个文字游戏,目前的事件条目又能保证多少玩家觉得有趣呢?

2017.1.21

 • 

昨天回到了合肥一中,参加了聚会。算是有两年没回去过了,发现女生都不同程度地变了,而男生还是一眼就能认出来。有一对高中就存在的情侣现在公开了,挺美好的一件事情。
最近母上倒是挺多次问我有没有找女朋友,或许是因为我平时表现的实在是太宅了。我倒觉得自在,虽然平时或许会心生悲寥之情,但有喜欢的事情可做,有钱可赚,倒也不觉得什么。而且我总是觉得我这样的人,大学课不上,Gap 几年再出国的计划也没定,毕业后的工作去向也没定哪个城市(虽然应该就先北京了),各种时间和空间上的不确定性,就会有各种各样的等,而我本人对等这件事情是有恐惧的。这让我对自己都有种深深的怀疑,所以还是先不要祸害别人了。


上一篇 Emoji 文章里截图的游戏还在开发,最近主要是在给 Android 设备接入 Everyplay,为了方便在移动设备上 Debug 又买了一些 Assets,深感好贵啊游戏开发人员的钱好赚啊。准备写完游戏在 Asset Store 上上架 Emojify。


Contributions 用 Element 3D 的 Promo Video 做好了。第一个版本在 Youtube 上,不过太短了(10 秒)不能用于 App Store Preview,所以做了第二个,下一个上架版本就能看到了。
此外:真的有人因为 Contributions 用 JazzHands 重写后显得只有 App Intro 而没有 App Main View 而认为软件本身有不能进入 Main View 的 bug,给了我 2 star。我思考了下,Main View 存在的意义真的不大,除非做一个游戏嵌入在里面。

Dear Pahitoz:
~~We will add a small 'flappy octocat' game as app main view soon! ~~


看了太空旅客,听了一堆存在硬盘上的老音乐。

Achieve slack-like emoji input in Unity UI Text component.

 • 

TLDR:
Copy code and use by writing

textToAddEmoji.Emojify();

最近在做一个小游戏,一开始只需要在某些文字的地方展示 Emoji 显示人物心情,所以直接用了 TextMesh Pro 的 Sprite 功能,自己拼了 8 个 Emoji:

然后选中 Texture 后新建一个 Sprite Asset,设置为默认 Sprite Asset 后在对应的 TextMesh Pro UGUI 脚本里面设置 text 属性:

<sprite=1><sprite=1><sprite=1>

就可以显示序号对应的表情了。
但是这个方案的问题在于,TMP 作为一个矢量文字显示方案,对中文的支持不是很好,在中英文都有可能出现的地方我还是尽量少用 TMP,转而使用 Unity built-in Text。而且 Unity 本身对 emoji 输入也有问题,不能像正常输入框一样输入即显示,所以还需要一个标记符替代 emoji 序列化在游戏里面。
对于前一个问题我找到了 Unity-UI-emoji,而后一个问题就准备用 Slack 的方案,在 Unity-UI-emoji 的基础上实现了。


Image refernce from slack.

Slack 对这个功能解释如下:"Slack uses the standard emoji codes found at Emoji Cheat Sheet."

Emoji Cheat Sheet 的确提供了我想要的信息,但是是用 Flash 展示的。还好找到了一个 GitHub 仓库 Emoji Alpha Codes,提供了 csv 和 json 两种格式,因此用 MiniJSON 转成 C# 的字典就可以用了。此外还需要反向转换一次,成为 alpha codes 为 key 而 emoji 为 value 的字典。

using System.Linq;
public Dictionary<string,string> InitDict ()
	{
		emojiCodeJSONTextAsset = (TextAsset)Resources.Load(emojiCodeJSONPath,typeof(TextAsset));
		deserializedEmojiCodeJSONObject = (Dictionary<string,object>)MiniJSON.Json.Deserialize(emojiCodeJSONTextAsset.text);

		_reversedCodeEmojiDict = new Dictionary<string, string>();
		List<string> arrayOfAllKeys = deserializedEmojiCodeJSONObject.Keys.ToList();
		foreach (string key in arrayOfAllKeys)
		{
			Dictionary<string,object> subDict =	(Dictionary<string,object>)deserializedEmojiCodeJSONObject[key];
			string code = (string) subDict["alpha_code"];
			string unicodeKey = GetConvertedString(key);
			//Debug.Log ("Key " + code + " ForValue " + unicodeKey);
			_reversedCodeEmojiDict[code] = unicodeKey;
		}
		return _reversedCodeEmojiDict;
	}
private static string GetConvertedString(string inputString)
	{
//有些 emoji 的图片名称带有 '-' ,这里需要拆开为两个 '\U'开头的字串拼接
		char[] chars = { '-' };
		return string.Join(string.Empty, inputString.Split(chars).Select(hex => char.ConvertFromUtf32(Convert.ToInt32(hex, 16))).ToArray());
	}

字典完成了,接下来看 GitHub 这个仓库。Unity-UI-emoji 的解决方案是读取 Text 中的 Emoji 并替换为 emSpace = '\u2001' 以保持字的长度,同时在 Text 层级下生成 RawImage 放置于 emSpace 的位置上,因为所有 emoji 都是打包成一个大贴图的,所以所有 RawImage 还是用的同一个 material,理论上可以节省 Draw Call,不过我也没测试罢了。
但是这个仓库有一个问题,在复杂的 Canvas / Text 条件下生成的Emoji 位置是错的。在我的游戏里测试下,Emoji 经常会跑到界面外。所以需要对 SetUITextThatHasEmoji 这个方法做些修改。这里需要引用到一个 SOF 回答 以及一个 BitBucket 仓库,照着 Unity 仓库源码改改就好了:

// One rawimage per emoji
for (int j = 0; j < emojiReplacements.Count; j++)
{
int emojiIndex = emojiReplacements[j].pos;

if (emojiIndex * 4 < textGen.verts.Count)
{
	GameObject newRawImage = GameObject.Instantiate(this.rawImageToClone.gameObject);
	newRawImage.transform.SetParent(textToEdit.transform);
	
	
	Vector2 locUpperLeft = new Vector2(textGen.verts[emojiIndex * 4].position.x, textGen.verts[emojiIndex * 4].position.y);
	Vector2 locBottomRight = new Vector2(textGen.verts[emojiIndex * 4 + 2].position.x, textGen.verts[emojiIndex * 4 + 2].position.y);
	
	Vector3 mid = (locUpperLeft + locBottomRight) / 2.0f;
	Vector3 size = locBottomRight - locUpperLeft;
	
	
	//Vector3 imagePos = new Vector3(textGen.verts[emojiIndex * 4].position.x, textGen.verts[emojiIndex * 4].position.y, 0);
	
	Rect inputRect = textToEdit.rectTransform.rect;
	// get the text alignment anchor point for the text in local space
	Vector2 textAnchorPivot = GetTextAnchorPivot(textToEdit.alignment);
	Vector2 refPoint = Vector2.zero;
	refPoint.x = (textAnchorPivot.x == 1 ? inputRect.xMax : inputRect.xMin);
	refPoint.y = (textAnchorPivot.y == 0 ? inputRect.yMin : inputRect.yMax);
	Vector2 roundingOffset = textToEdit.PixelAdjustPoint(refPoint) - refPoint;
	IList<UIVertex> verts = textGen.verts;
	FontData fontData = FontData.defaultFontData;
	fontData.font = textToEdit.font;
	float pixelsPerUnit = 0.0f;
	var localCanvas = GameObject.Find("GameCanvas").GetComponent<Canvas>();
	if (!localCanvas)
	{
		pixelsPerUnit = 1.0f;
	}else if (!textToEdit.font || textToEdit.font.dynamic)
	{
		pixelsPerUnit = localCanvas.scaleFactor;
	}else
	{
		pixelsPerUnit = textToEdit.font.fontSize / (float)fontData.fontSize;
	}
	float unitsPerPixel = 1 / pixelsPerUnit;
	int vertCount = verts.Count - 4;
	if (roundingOffset != Vector2.zero)
	{
		mid *= unitsPerPixel;
		mid.x += roundingOffset.x;
		mid.y += roundingOffset.y;
	}else
	{
		mid *= unitsPerPixel;
	}
	
	
	Debug.Log ("EMOJI mid X" + mid.x + " Y " + mid.y + " Z " + mid.z);
	newRawImage.transform.localPosition = mid;
	
	RawImage ri = newRawImage.GetComponent<RawImage>();
	ri.uvRect = emojiRects[emojiReplacements[j].emoji];
	ri.rectTransform.pivot = new Vector2(0.0f,0.0f);
	ri.rectTransform.localScale = Vector3.one;
	ri.rectTransform.sizeDelta = Vector2.one * textToEdit.font.lineHeight * unitsPerPixel;
	
}

代码很脏,但能用,等做完游戏后这块再重构下。
然后就是给 UnityEngine.UI.Text 加一个方法拓展,我命名为 Emojify();

static public void Emojify (this UnityEngine.UI.Text self)
{
	if (JZEmojiUITextManager.Instance.reversedCodeEmojiDict == null)
	{
		return;
	}
	string currentCodeBasedString = self.text;
	
	// 使用正则把 emoji alpha code 转换为 对应的 Unicode
	Dictionary<string,string> map = (Dictionary<string,string>)JZEmojiUITextManager.Instance.reversedCodeEmojiDict;
	var regex = new Regex(string.Join("|",map.Keys.ToArray()));
	var newStr = regex.Replace(currentCodeBasedString, m => map[m.Value]);
	// 第一次正则的 Unicode 还没有 Unscape,需要把 '\\' 改为 '\'
	Regex regex1 = new Regex (@"\\U([0-9A-F]{4})", RegexOptions.IgnoreCase);
	var newStrUnescape = regex1.Replace (newStr, match => ((char)int.Parse (match.Groups[1].Value,
		NumberStyles.HexNumber)).ToString ());
	JZEmojiUITextManager.Instance.StartCoroutine(JZEmojiUITextManager.Instance.SetUITextThatHasEmoji(self, newStrUnescape));
}

至于 JZEmojiUITextManager 就是一个简单的单例,用于生成和存放刚才的那个字典,以及把 Unity-UI-emoji 仓库的大部分方法复制了一份。现在就可以直接对某个 Text 组建直接写:

textToAddEmoji.Emojify();

另外我还替换了这个仓库的 Emoji 图片,从 Twitter Emoji 换到了 iOS Emoji,链接为 github.com/iamcal/emoji-data。现在效果如下:

Morning! Here is your new phone. 
:flag_us:
You can reply to new messages by swiping cards to left or right. Different reply will lead to different impact on company valuation and staff happiness.
Our goal is to hit $ 1 Billion valuation by the end of the year while keep our staff from leaving.

2017.1.13

 • 

A new game by FinGameWorks will be shipped within this month.


RavenLab 组除了我(Cee,豪哥,愿愿,陈叔和柯姐姐)都去日本玩去了。我之前不确定学校放假时间所以没有跟着一起办,现在只能呆在家里看着大家玩了。


Contributions 1.0.3 上架了,新增以下功能:

  • 设置界面(Settings Bundle):进系统设置找 Contributions 可见。
  • 推送通知:后台刷新后可选带一条包含图片和统计的推送
  • 分享功能:同上,只不过做到了 UIActivityController 里了而已。
  • 新的界面:之前说过用 JazzHands 重写的。

以及,考虑给 Contributions 用 Element 3D 做一个 Promo video。


看了星球大战。听了 Hold Tight - Jamie xxFascination - Julie LondonHolding On (POMO Remix) - Disclosure Gregory Porter Pomo

2017.1.7

 • 

上周考完试,然后回到了家。
和一个朋友要一起做的 Unity 工程计划有变,先停了。
Roc Zhang 以及他的学弟在长沙吃了顿饭。
JazzHands 重写了 Contributions 的 iOS 软件界面,计划 12 号上架,这之前可以联系我或加入群组参加 testflight。后台刷新仍然有不小的 bug,据 Roc Zhang 称后台刷新也看手机本身软件数目多少,软件多的话分配给每个软件的刷新几率也就小了。现在看来貌似没有一个能保证每日定时任务的解决方案,除了陈叔和我提到的服务端刷新。但我并不想把这个东西做成带服务端的东西,除了这是 Side Project 不值得大费周章以外,我总觉得一个软件最好的状态就是无依赖,这样在某种意义上作为有价值的软件的生命周期会长一些
1
,这或许能解释我为什么对 P2P 这类概念这么着迷。
选了大三下学期的课,比上学期还多,倒是出乎我意料。不过肯定还是不怎么会去上罢了。
后面或许会开始填坑 Cetacea,毕竟在我的 Portfolio 上写了 ETA 是 2017 Late Spring,至少要先把 macOS 版本完成了。我倒不担心我的效率,但我担心我在那之前会不会对 Cetacea 整个项目失去兴趣了。
看了会海边的卡夫卡英文版。一个很有趣的比喻:'Money isn't like mushrooms in a forest -- it doesn't just pop up on its own'.
考虑还给当前这个主题加一个 Archive 页面,有时候找文章还需要用 Google,实在是太麻烦了。
这几天听了 Friday Night! (Original Mix)伤心者Waters Of March - Tim Biro EditJoint Thoughts

  1. 我是个主要写客户端的人,而我已经见了很多因为服务器关停而不能运作的 app 了,这其实是一件非常令人惋惜的事情。

2016.12.31

 • 

今年最后一个周末了。写些有的没的。


聊天聊到几年前高三暑假的时候,当时的我想做一个合肥一中的社区软件。
当时我对于软件开发完全没有概念,只是为了好玩一味地想要去做罢了,因此用了那种所谓的 webapp 平台,可以打包成拙劣的“原生软件”。同大部分服务一样,当时用的 webapp 平台也提供了非免费的高级服务,而且价格不菲。我当时自然是一分钱都没有,所以只能看着高级版本的特性眼馋。
算是自那两年多后,我变成了一个靠写软件吃饭的人。我能自己独立写出当时想要的客户端和服务端了,不过我也不再关心我当时的点子了。对于我来说,“能不能靠自己写的软件活下去”和“能不能赚钱买些好玩的电子产品”变成了我要追求的新目标。
十月份我在写一个项目,每天起床后就是看 Trello 上新加的功能,看 Crashlytics 新出的 bug,然后面对着 Xcode 敲 Objective-C。除此以外,我每天挂念的最多的或许就是什么时候能拿到钱。
聊到这里我莫名地有了种“杀了龙的少年自己变成了龙”的感觉。


推特上说总结的时候,说到今年大致就两件事情,“实习”和“厌学”。
“厌学”的事情原因不再多说,需要提到的是对于对大学不是很熟悉的人们,比如我的家人,有一种误解是“厌学”必然导致“退学”,但实际上在国内这种环境下,厌学作为一种被动的抵抗,被开除总是少数,更特别如果日常能打点下和学校的关系,一般是不至于被开的。
今年各种和学校和父母拉扯后我保持这个态度:我不会去打点,也不想去打点和学校的关系。如果学校真的觉得要开我,那我反倒觉得解脱。如果学校没有这个意思,那总算是不给父母添麻烦。反正尽量减少和学校的交集就是了。
十一月份的时候收到了 cityU 一位教授以为我大四所以发给我的邮件,就此咨询也了解了一些 Master / PhD 的消息,给我的感觉是其实读个也不坏。但我想我肯定不会在国内(大陆)读研/读博了。

另外,对于本科有类似困扰的同学,倒是可以看看 Randy Lu 的离开大学这一年你根本用不着退学 两则。


对于实习,对于我的一个影响是,我见到了很多过的很潇洒的人。“潇洒”几乎囊括了所有需要费口舌描述的词汇,因为每个人对“潇洒”都有自己的幻想,但内容是否相同不重要,我就是想表达那种心生感叹的心情罢了。
我个人一直是一个欠社交的人,客观原因或许是初高中都在距离家超远的寄宿制学校,自己习惯了在家没有朋友可以一起玩的生活,自然长大后在某些场合会心生怯意。所以对于我来说,“潇洒”比常人或许要多一层含义,就是那种在社交场合自然从容的精神状态。我从内心羡慕这些人,也珍惜能和这些人一起工作的生活,因为这也是获得自我认同的一部分。


写博客的时候我经常用“或许“,“应该”这样的词,因为我也说不清我说的是否是对的,所以总要保留余地。从今年的 hackathon 我学到的是另外一种不保留任何余地说话的风格,本身 hackathon 的 pitch 最多也就五分钟,这期间要 intro,要 demo,要总结,所以任何拖泥带水的地方都是减分的。
我见过一些队伍,上台先慢悠悠地介绍完一遍团队和队员(这么做其实很蠢),然后开始扯目前的大环境(大家都知道的东西其实不需要再扯一遍),然后带到自己的产品上,这个时候已经三分钟了。如果在带入产品的推导环节再加上很多表示可能(“或许”,“有时候”)和表示是自己主观判断(”我觉得“,”我认为“)的词语,不管是自己本身说话方式使然还是出于忘词所以找词充数的原因,都只会使情况更糟,不仅时间会加速浪费完,还会让大家觉得这个队伍对自己的 demo 不自信,不然你用那么多“应该”干嘛。
不要说“我认为这个产品应该能”,说“这个产品能”,就够了。注意这点总是好的,不管是 hackathon 还是日常需要表达一种肯定表述的时候。

2016

 • 

1 月 | 参加 Swift 大会。见了很多人。Uber Hackathon。回家。
2 月 | 开始用 Unity 写 Epoch。新 PC。Fin GameWorks 主页上线。回长沙。
3 月 | 开学。研究 LibNoise。Epoch 的 VR Branch。Cetacea 的 iOS 初版。月底去北京。
4 月 | 入职渡鸦,和陈叔一起写 Leap Motion & Gear VR。闲了就联机文明和 Elite Dangerous。中间回了趟学校,但因为网络条件问题一周后又回北京工作了。看了 The Big Short。
5 月 | 回学校,做了场我至今仍然有些耿耿于怀的报告。重新看了遍《时间规划局》。给母上买了台 iPhone。学 Rails 和 C4D。Project Soda & Project Fragment & Project Crap 上线。
6 月 | 深圳 SegmentFault & AngelHack Hackathon。见到了 Yuno 和袁晨皓。看完了 TRON Uprising。入手 Pencil by 53,WebDrop 上架。夏天。
7 月 | Cetacea Mac 初版。到北京。回渡鸦 RavenLab 开始全职。写 Unity。
8 月 | 继续写 Unity,甚至写了会 Android。见了很多人。相当难忘的日子。在公司看完了豪哥推荐的《男子高中生的日常》。月底写了一堆文档。回家。
9 月 | 原本以为可以和学校申请回公司,但是一直没有消息。于是开始更新 Epoch。新的 Epoch Core 成型。Age Clock 和 Contributions For GitHub 上架。看了 Keren Ann 演唱会。
10 月 | 压抑的一个月,各种乱七八糟的课设。上海的 HACKxFDU 和云赛空间 Hackathon,以及武汉的 Hackathon。困和累。开始写外包。
11 月 | 更加压抑的一个月。和辅导员谈了次话。看了三四场电影。开始尝试给苹果实验室上 iOS 课程。写了 ArtWall,Board For GitHub,Lonely Planet。
12 月 | 例行地写了些软件更新。新的 Portfolio 上线。准备期末。长沙好像还没下过雪。

总结下来:

  1. 今年能持续地挣些钱了,可以在负担生活费的基础上随意地买些自己想买的东西。感谢那些带我入行 / 欣赏我 / 给我发工资的人。
  2. 我现在还是十分怀念七八月份在北京工作的日子,当然谈不上“理想中的生活”,但那至少是“典型的生活”,对于我来说是非常珍贵的。
  3. 不要浪费自己时间。不要浪费别人时间。
  4. 保持生产自己认为有意义的事物。无聊的事情通常也是无意义的。
  5. 少说话,多备份。