-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
742 lines (558 loc) · 100 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Lazybones Kill PLAN</title>
<subtitle>In me the tiger sniffs the rose</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://vrast.cn/"/>
<updated>2021-02-09T08:51:17.684Z</updated>
<id>http://vrast.cn/</id>
<author>
<name>keyle xiao</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>客户端常用的数学技巧1</title>
<link href="http://vrast.cn/posts/18c501b3/"/>
<id>http://vrast.cn/posts/18c501b3/</id>
<published>2020-11-02T11:38:02.000Z</published>
<updated>2021-02-09T08:51:17.684Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>先说下本篇博问的起因,在我的群里总有一些朋友在问,关于旋转,空间点判定等问题,关于这些程序实现上的问题,看完本篇后你会发现要解决也很简单。<br>本篇关键字:<code>点乘 叉乘 弧度 角度 sin cos asin atan atan2</code><br><a id="more"></a></p>
</blockquote>
<h2 id="先抛砖引玉从点乘与叉乘开始"><a href="#先抛砖引玉从点乘与叉乘开始" class="headerlink" title="先抛砖引玉从点乘与叉乘开始"></a>先抛砖引玉从点乘与叉乘开始</h2><h3 id="点乘-叉乘"><a href="#点乘-叉乘" class="headerlink" title="点乘 叉乘"></a>点乘 叉乘</h3><p>这张图可以记一下,简单明了,仔细看下图里有画垂直与Y轴与X轴的红线。<br><img src="/uploads/WX20201102-195706.png" alt="dot - cross"></p>
<h3 id="使用场景:-光照计算"><a href="#使用场景:-光照计算" class="headerlink" title="使用场景: 光照计算"></a>使用场景: 光照计算</h3><p>这边是diffuse的计算方式,这里用到的dot,判定法线是否与光源反射的方向同向。<br>如果两者同向反射光强度最高,反之则变暗。<br><img src="/uploads/241917011098992.png" alt="演示-shaderforge"></p>
<h3 id="使用场景:-判定前后或左右"><a href="#使用场景:-判定前后或左右" class="headerlink" title="使用场景: 判定前后或左右"></a>使用场景: 判定前后或左右</h3><p>这段代码直接通过dot判定是否物体在我们的前或后。<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> forward = transform.TransformDirection(Vector3.forward);</div><div class="line"><span class="keyword">var</span> toOther = other.position - transform.position;</div><div class="line"></div><div class="line">Debug.Log(<span class="string">$"在前方 ? <span class="subst">{Vector3.Dot(forward, toOther) > <span class="number">0</span>}</span>"</span>);</div><div class="line"></div><div class="line"><span class="keyword">var</span> right = transform.TransformDirection(Vector3.right);</div><div class="line"><span class="keyword">var</span> toOther = other.position - transform.position;</div><div class="line"></div><div class="line">Debug.Log(<span class="string">$"在右方 ? <span class="subst">{Vector3.Dot(right, toOther) > <span class="number">0</span>}</span>"</span>);</div></pre></td></tr></table></figure></p>
<h2 id="再稍微深入一点的概念"><a href="#再稍微深入一点的概念" class="headerlink" title="再稍微深入一点的概念"></a>再稍微深入一点的概念</h2><h3 id="弧度-与-角度"><a href="#弧度-与-角度" class="headerlink" title="弧度 与 角度"></a>弧度 与 角度</h3><p><img src="/uploads/WX20201230-163930.png" alt="rad - 弧度"><br><img src="/uploads/WX20201230-164418.png" alt="deg - 角度"></p>
<p>这个概念我常常见有人搞混,口语化描述弧度或者角度,我们都称之为度,所以经常会弄错。<br>有个简单的记忆方式:<br><figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">一般unity中对Eular Angle进行操作的api用的都是角度而非弧度。</div><div class="line">一般我们所有开放给人为配置的也都是角度(易读也好理解)</div><div class="line">一般在三角函数相关计算api使用的是弧度。</div></pre></td></tr></table></figure></p>
<h3 id="Mathf-sin-amp-cos"><a href="#Mathf-sin-amp-cos" class="headerlink" title="Mathf.sin & cos"></a>Mathf.sin & cos</h3><p><img src="/uploads/WX20201230-175742.png" alt="使用sin+cos计算一个指定的坐标"></p>
<p><img src="/uploads/WX20201230-184758.png" alt="y轴为正前方夹角30度"></p>
<h3 id="使用场景:-角度转向量"><a href="#使用场景:-角度转向量" class="headerlink" title="使用场景: 角度转向量"></a>使用场景: 角度转向量</h3><p>角度转方向向量<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> Vector3 <span class="title">OriToVec</span>(<span class="params"><span class="keyword">float</span> orientation</span>)</span></div><div class="line">{</div><div class="line"> Vector3 vector = Vector3.zero;</div><div class="line"> vector.x = Mathf.Sin(orientation * Mathf.Deg2Rad);</div><div class="line"> vector.z = Mathf.Cos(orientation * Mathf.Deg2Rad);</div><div class="line"> <span class="keyword">return</span> vector.normalized;</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h3 id="Mathf-Asin"><a href="#Mathf-Asin" class="headerlink" title="Mathf.Asin"></a>Mathf.Asin</h3><p>我这边用的是lua演示的,数学库运算结果都一样。<br><figure class="highlight lua"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">math</span>.deg(<span class="built_in">math</span>.asin(<span class="built_in">math</span>.sin(<span class="built_in">math</span>.rad(<span class="number">30</span>)))) <span class="comment">--result:30</span></div></pre></td></tr></table></figure></p>
<h3 id="Mathf-Atan-amp-Mathf-Atan2"><a href="#Mathf-Atan-amp-Mathf-Atan2" class="headerlink" title="Mathf.Atan & Mathf.Atan2"></a>Mathf.Atan & Mathf.Atan2</h3><p>Mathf.Atan()返回的值的范围是[-π/2,π/2],Mathf.Atan2()返回的值的范围是[-π,π]。</p>
<figure class="highlight lua"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">math</span>.deg(<span class="built_in">math</span>.atan2(<span class="number">3</span>,<span class="number">4</span>)) <span class="comment">--result: 36.869897645844</span></div></pre></td></tr></table></figure>
<p><img src="/uploads/WX20201230-194238.png" alt="计算的夹角如图"></p>
<h2 id="在我眼中的数学在游戏中的应用"><a href="#在我眼中的数学在游戏中的应用" class="headerlink" title="在我眼中的数学在游戏中的应用"></a>在我眼中的数学在游戏中的应用</h2><p>前人已经实现了很多数学函数库,只要把数学当作工具使用就行了。了解这个”工具“的性能,以及如何运用。那么你一定会做的很好。</p>
]]></content>
<summary type="html">
<blockquote>
<p>先说下本篇博问的起因,在我的群里总有一些朋友在问,关于旋转,空间点判定等问题,关于这些程序实现上的问题,看完本篇后你会发现要解决也很简单。<br>本篇关键字:<code>点乘 叉乘 弧度 角度 sin cos asin atan atan2</code><br>
</summary>
<category term="数学" scheme="http://vrast.cn/categories/%E6%95%B0%E5%AD%A6/"/>
<category term="数学" scheme="http://vrast.cn/tags/%E6%95%B0%E5%AD%A6/"/>
</entry>
<entry>
<title>客户端位移同步解决方案Demo</title>
<link href="http://vrast.cn/posts/def1fe6b/"/>
<id>http://vrast.cn/posts/def1fe6b/</id>
<published>2020-08-29T10:58:35.000Z</published>
<updated>2020-08-29T12:07:59.179Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>下面简单介绍下此Demo, 该demo是我的小试验田,主要是位置同步相关。感兴趣的可以follow一下。</p>
</blockquote>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">PlayerSelf.cs 模拟主角协议收发以及位移处理</div><div class="line">ServerSample.cs 模拟服务器协议收发,网络延迟波动等</div><div class="line">PlayerSolutionA.cs 模拟其他客户端的观察状态【强制位置同步】</div><div class="line">PlayerSolutionB.cs 模拟其他客户端的观察状态【差值位置同步】</div></pre></td></tr></table></figure>
<p><a href="https://github.com/KeyleXiao/GamePosSyncSolution" target="_blank" rel="external">点我转跳过去</a></p>
]]></content>
<summary type="html">
<blockquote>
<p>下面简单介绍下此Demo, 该demo是我的小试验田,主要是位置同步相关。感兴趣的可以follow一下。</p>
</blockquote>
<figure class="highlight cs"><table><tr><td class="gu
</summary>
<category term="网络" scheme="http://vrast.cn/categories/%E7%BD%91%E7%BB%9C/"/>
<category term="位置同步" scheme="http://vrast.cn/tags/%E4%BD%8D%E7%BD%AE%E5%90%8C%E6%AD%A5/"/>
</entry>
<entry>
<title>弱网多人联机表现优化</title>
<link href="http://vrast.cn/posts/840045e3/"/>
<id>http://vrast.cn/posts/840045e3/</id>
<published>2020-08-26T11:23:55.000Z</published>
<updated>2020-08-26T15:46:58.741Z</updated>
<content type="html"><![CDATA[<p>上篇讲到客户端的同步策略,也就是Client to Server的发包策略。那么这篇说一下Server to Client的网络抖动情况下优化本地表现。<br>延迟实际并不会造成客户端表现障碍,但是网络抖动会,我们优化的点在于不要让用户看到模型坐标拉扯,让表现过度自然。处理的过程中尽量追平服务器计算的实时位置。</p>
<p><img src="/uploads/QQ20200826-145550-HD.mp4" alt=""></p>
<p>这里讲一下我的思路,玩家每次收到的Pack结构如下:position是此刻当前物体处在位置,angle为运动方向,speed为0则物体进入idle。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="keyword">class</span> <span class="title">PlayerStatePack</span></div><div class="line">{</div><div class="line"> <span class="keyword">public</span> <span class="keyword">float</span> speed;</div><div class="line"> <span class="keyword">public</span> Vector3 position;</div><div class="line"> <span class="keyword">public</span> <span class="keyword">int</span> angle_deg;</div><div class="line">}</div></pre></td></tr></table></figure>
<p>下面是模拟服务端延迟的实现,fluctuation用来模拟网络抖动:</p>
<p><code> currentTime = Time.time + Ping / 1000f <em> 2 + Random.Range(-fluctuation </em> 2/1000f , fluctuation * 2/1000f ); </code> </p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">void</span> <span class="title">Update</span>(<span class="params"></span>)</span></div><div class="line">{</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < packLst.Count; i++)</div><div class="line"> {</div><div class="line"> <span class="keyword">if</span> (packLst[i].BeSend)</div><div class="line"> <span class="keyword">continue</span>;</div><div class="line"> </div><div class="line"> <span class="keyword">if</span> (packLst[i].currentTime <= Time.time)</div><div class="line"> {</div><div class="line"> packLst[i].BeSend = <span class="literal">true</span>;</div><div class="line"> ReceivePack?.Invoke(packLst[i]);</div><div class="line"> }</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<p>客户端接收消息实现如下:通过ReceivePack函数订阅模拟服务器下发的Pack, 在该函数内做一个向量的减法,获取当前客户端所处与服务器同步过来的位置之间的误差,<br>有了此向量,那后面就可以通过插值逐渐修正到一个趋近正确的位置,一定程度上抹平网络波动引起的误差。<br>在 ApplyPoint 函数我做了一个当前误差的差值与角度差值,这样效果会好一些。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">OnMove</span>(<span class="params"><span class="keyword">float</span> passTime,<span class="keyword">float</span> step,Vector3 pos,<span class="keyword">float</span> angle</span>)</span></div><div class="line">{</div><div class="line"> ...</div><div class="line">}</div><div class="line"></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">ReceivePack</span>(<span class="params">PlayerStatePack item</span>)</span></div><div class="line">{</div><div class="line"> Debug.Log(<span class="string">"其他玩家收到同步包"</span>);</div><div class="line"></div><div class="line"> modifyOffset = item.position - transform.position;</div><div class="line"> localPositon = transform.position;</div><div class="line"> localAnlge = transform.eulerAngles.y;</div><div class="line"> ...</div><div class="line">}</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="keyword">float</span> timeTakenDuringLerp = <span class="number">.2</span>f;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">Update</span>(<span class="params"></span>)</span></div><div class="line">{</div><div class="line"> ....</div><div class="line"> <span class="keyword">var</span> passTime = Time.time - currentPack.CurrentTime;</div><div class="line"></div><div class="line"> OnMove(passTime,step,pos,angle);</div><div class="line"></div><div class="line"> ApplyPoint(passTime);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">ApplyPoint</span>(<span class="params"><span class="keyword">float</span> passTime</span>)</span></div><div class="line">{</div><div class="line"> <span class="keyword">float</span> percentageComplete = passTime / timeTakenDuringLerp;</div><div class="line"> </div><div class="line"> <span class="keyword">if</span>(percentageComplete >= <span class="number">1.0</span>f)</div><div class="line"> {</div><div class="line"> transform.position = RuntimePos + modifyOffset;</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">var</span> offset = Vector3.Lerp(Vector3.zero, modifyOffset,percentageComplete); </div><div class="line"> transform.position = RuntimePos + offset;</div><div class="line"></div><div class="line"> <span class="keyword">if</span>(percentageComplete*<span class="number">2</span> >= <span class="number">1.0</span>f)</div><div class="line"> {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"> <span class="keyword">var</span> yoffset = Mathf.LerpAngle(localAnlge, currentPack.angle_deg,percentageComplete*<span class="number">2</span>);</div><div class="line"> transform.eulerAngles = <span class="keyword">new</span> Vector3(transform.transform.eulerAngles.x,yoffset,transform.transform.eulerAngles.z);</div><div class="line">}</div></pre></td></tr></table></figure>
<h1 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h1><p>还有其他方式优化表现,对我来说目前这种方式表现已经足够便没有尝试,下面贴了条链接其中有讲到 立方样条插值,这种方式常见于各种导航软件比较复杂。如果是<br>赛车游戏我倒是非常推荐用这种预测模式降低网络抖动造成的拉扯现象。</p>
<h1 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h1><p><a href="http://www.zhust.com/index.php/2014/02/网络游戏的移动同步(三)平滑算法/" target="_blank" rel="external">网络游戏的移动同步(三)平滑算法</a></p>
]]></content>
<summary type="html">
<p>上篇讲到客户端的同步策略,也就是Client to Server的发包策略。那么这篇说一下Server to Client的网络抖动情况下优化本地表现。<br>延迟实际并不会造成客户端表现障碍,但是网络抖动会,我们优化的点在于不要让用户看到模型坐标拉扯,让表现过度自然。处理
</summary>
<category term="网络" scheme="http://vrast.cn/categories/%E7%BD%91%E7%BB%9C/"/>
<category term="位置同步" scheme="http://vrast.cn/tags/%E4%BD%8D%E7%BD%AE%E5%90%8C%E6%AD%A5/"/>
</entry>
<entry>
<title>反思下开发中位置同步遇到的问题</title>
<link href="http://vrast.cn/posts/807bdaae/"/>
<id>http://vrast.cn/posts/807bdaae/</id>
<published>2020-08-13T13:48:20.000Z</published>
<updated>2020-09-12T14:39:39.463Z</updated>
<content type="html"><![CDATA[<p>先简单描述下本篇记录的是什么. 起因是服务器这段时间在查流量,需要严格控制乃至减少现在数据包的 大小/频率。<br>目前服务器的逻辑大概在30hz的频率刷新当前逻辑块,客户端并未走单独的逻辑刷新层。故现在客户端并未按照帧去判定当前是否同步,而是走固定的刷新周期。<br>250ms为一个刷新周期,触发当前同步的判定;</p>
<p>先列一下几种位置同步的【条件】:</p>
<figure class="highlight"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">角度是否变更</div><div class="line">位置是否变更</div></pre></td></tr></table></figure>
<p>在固定的周期内会检测一次两个条件是否超出一定的阀值,如果超过定量则在该周期内同步一次。服务器则根据当前同步的角度预测计算帧当前角色可能的位置。</p>
<p>如果是这种做法,当前移动速度为6m/s :</p>
<figure class="highlight lsl"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">客户端刷新周期<span class="number">250</span>ms,延迟为<span class="number">200</span>ms,服务器得到当位置的最大误差为: (<span class="number">0.25</span>s + <span class="number">0.2</span>s) * <span class="number">6</span>m = <span class="number">2.7</span>m 每秒<span class="number">4</span>个包</div><div class="line">客户端刷新周期<span class="number">100</span>ms,延迟为<span class="number">200</span>ms,服务器得到当位置的最大误差为: (<span class="number">0.1</span>s + <span class="number">0.2</span>s) * <span class="number">6</span>m = <span class="number">1.8</span>m 每秒<span class="number">10</span>个包</div><div class="line">客户端刷新周期<span class="number">50</span>ms,延迟为<span class="number">200</span>ms,服务器得到当位置的最大误差为: (<span class="number">0.05</span>s + <span class="number">0.2</span>s) * <span class="number">6</span>m = <span class="number">1.5</span>m 每秒<span class="number">20</span>个包</div><div class="line">...</div></pre></td></tr></table></figure>
<p>以此类推,稍微优化一下也用不了那么多包,如果【条件】没有变更的话是不需要持续在周期内同步。也就变成了每帧判定【条件】是否变更,如果没有变更则无需同步,<br>否则走默认的周期检测,检测周期也就可以改为1s同步一次当前位置。</p>
<h1 id="条件的改变频率"><a href="#条件的改变频率" class="headerlink" title="条件的改变频率"></a>条件的改变频率</h1><p>在此基础上可以知道延迟固定的最大误差为 0.2s * 6m = 1.2m ,那么现在基于此应该去尽量少的发送数据包,也尽量少降低误差。<br>如果【条件】改变的频繁会大幅增加发包的数量,甚至可能每帧都产生一个包。如果玩家在原地绕圈的时候.<br>此时增加【条件】的冗余可以减少当前发包的数量,如 增加 角度/距离 变更的判定范围。<br>实际上这样做的效果并不好,原因是【条件】太容易满足。</p>
<h1 id="基于误差累计替换【条件】-航位推算法DR"><a href="#基于误差累计替换【条件】-航位推算法DR" class="headerlink" title="基于误差累计替换【条件】(航位推算法DR)"></a>基于误差累计替换【条件】(航位推算法DR)</h1><p><img src="/uploads/dr.jpg" alt=""></p>
<p>前面有说到服务器预测当前物体,在计算帧的坐标是基于 运动朝向 + 物体坐标</p>
<p>那么在我们的检测代码中可以做两次计算:</p>
<p>先预测服务器得到的当前物体位置 : 上次同步的坐标 + 运动方向 * 同步结束后累计的时间<br>计算当前物体实际距离与 预测服务器得到的当前物体位置 之间的距离</p>
<p>如果当前位置与服务器预测的位置误差控制在一定的范围内则不需要同步反之立即同步一次;</p>
<p>这样的好处是误差可以控制在一定的范围内并且尽量的少发送同步包;比如误差控制在0.1m范围,如果发送的包超量再适当的增加此范围。</p>
<h1 id="基于时间戳修正"><a href="#基于时间戳修正" class="headerlink" title="基于时间戳修正"></a>基于时间戳修正</h1><p>这两天还在调试 尽量取一个比较折中的方案,如果实在达不到预期再考虑 双端同步时间种 基于此各自做运动状态的计算。</p>
<h1 id="更新:撞墙如何处理"><a href="#更新:撞墙如何处理" class="headerlink" title="更新:撞墙如何处理"></a>更新:撞墙如何处理</h1><p>撞墙后通过代码使人物转向,不要降低运动速度即可。</p>
<h1 id="参考文档"><a href="#参考文档" class="headerlink" title="参考文档"></a>参考文档</h1><p><a href="https://blog.codingnow.com/2012/03/dev_note_12.html" target="_blank" rel="external">开发笔记(12) : 位置同步策略</a><br><a href="https://blog.codingnow.com/2006/04/sync.html" target="_blank" rel="external">网络游戏的对时以及同步问题-云风的 BLOG</a><br><a href="http://www.zhust.com/index.php/2014/02/网络游戏的移动同步(二)状态更新及航位预测法/" target="_blank" rel="external">状态更新及航位预测法</a></p>
]]></content>
<summary type="html">
<p>先简单描述下本篇记录的是什么. 起因是服务器这段时间在查流量,需要严格控制乃至减少现在数据包的 大小/频率。<br>目前服务器的逻辑大概在30hz的频率刷新当前逻辑块,客户端并未走单独的逻辑刷新层。故现在客户端并未按照帧去判定当前是否同步,而是走固定的刷新周期。<br>25
</summary>
<category term="网络" scheme="http://vrast.cn/categories/%E7%BD%91%E7%BB%9C/"/>
<category term="位置同步" scheme="http://vrast.cn/tags/%E4%BD%8D%E7%BD%AE%E5%90%8C%E6%AD%A5/"/>
</entry>
<entry>
<title>迁站那些事</title>
<link href="http://vrast.cn/posts/4241dac4/"/>
<id>http://vrast.cn/posts/4241dac4/</id>
<published>2020-08-11T06:12:28.000Z</published>
<updated>2020-08-11T06:58:43.765Z</updated>
<content type="html"><![CDATA[<p>说起现在这个博客,用了已经很久了一只在折腾 各种调优 . 原因是国内访问的时候太慢了,自从去年年末开始 github 的访问变得很慢(gfw),基本上page是处于一个非常尴尬的境地。<br>我也只能在网速龟爬的基础上尽力的尝试优化访问速率,如:</p>
<figure class="highlight awk"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">切换网页内嵌的css<span class="regexp">/js/</span>font 源至国内的cdn</div><div class="line">使用国内的图床进行缓存</div><div class="line">启用七牛云(现在域名没有备案也用不了)</div><div class="line">压缩所有能压缩的资源</div></pre></td></tr></table></figure>
<p>国内的云服务器价格高带宽低,还有就是国内备案办手续时间挺久来来回回审核资料我也怕麻烦,这也是我一度觉得没必要迁入的原因之一。<br>就在最近 githubhub 的 page 服务终于迎来了社会的毒打,国内大部分品牌的宽带都没办法访问,移动网络还是偶尔可以。已经屏蔽的很彻底了。<br>我还是下决心花点时间将站点移动到国内 ,下面说说我迁站遇到的事儿。</p>
<ol>
<li>阿里云主机申请</li>
<li>域名备案</li>
<li>主机绑定</li>
</ol>
<h1 id="阿里云主机申请"><a href="#阿里云主机申请" class="headerlink" title="阿里云主机申请"></a>阿里云主机申请</h1><p>个人博客不商用就是记录一些日常的积累和一些偶尔的想法,所以呢,我想租一个尽量便宜的主机。<br>同事给介绍了一个虚拟云主机,说白了就是共享主机。如果不了解什么是共享主机的我举个栗子。租房子的 整租 和 合租的概念 你就明白了。<br>最近做活动 3 年 600+ RMB 。已经很便宜了,缺点也有只能只能ftp操作,没提供ssh,也只有php环境,基本上就是和github的page一个配置。<br>对于目前做静态博客的人来说是比较友好的,如果不是 那还是老老实实买其他类型的吧。</p>
<h1 id="备案"><a href="#备案" class="headerlink" title="备案"></a>备案</h1><p><img src="/uploads/WX20200811-143759.png" alt=""></p>
<p>备案的时候要举着身份证校验身份,非上海本地人要本市居住证。推荐上海这边管局审核,原因自然是上海这边效率高了,我大概4-5天审核好了。<br>备案之前如果你有域名的话要提前实名制域名。</p>
<h1 id="主机绑定"><a href="#主机绑定" class="headerlink" title="主机绑定"></a>主机绑定</h1><p>不知道是否只有共享主机需要这样配置,其他的我也没有在阿里云上实践过。好处也有一点 可以开一个免费的https。证书是免费的</p>
<p><img src="/uploads/WX20200811-145115.png" alt=""></p>
<p>哦对了,cdn是阿里云单独收费的服务 …</p>
<h1 id="在最后说一些"><a href="#在最后说一些" class="headerlink" title="在最后说一些"></a>在最后说一些</h1><p>在网站下面要把备案号贴出来,对 就像我现在这样。如果有时间可以再做一个公安备案。获得一个公安备案的logo,说实话还挺好看 。</p>
<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://beian.miit.gov.cn/"</span> <span class="attr">target</span>=<span class="string">"_blank"</span>></span>沪ICP备0000000号<span class="tag"></<span class="name">a</span>></span></div></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>说起现在这个博客,用了已经很久了一只在折腾 各种调优 . 原因是国内访问的时候太慢了,自从去年年末开始 github 的访问变得很慢(gfw),基本上page是处于一个非常尴尬的境地。<br>我也只能在网速龟爬的基础上尽力的尝试优化访问速率,如:</p>
<figure c
</summary>
<category term="vrast.cn" scheme="http://vrast.cn/categories/vrast-cn/"/>
<category term="网站" scheme="http://vrast.cn/tags/%E7%BD%91%E7%AB%99/"/>
</entry>
<entry>
<title>Addressable 上手就遇BUG ?</title>
<link href="http://vrast.cn/posts/ff77377d/"/>
<id>http://vrast.cn/posts/ff77377d/</id>
<published>2020-02-19T09:07:29.232Z</published>
<updated>2020-05-14T16:31:33.348Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>关注此插件已经有一段时间了,最早在2018就有preview版本了。但直到2019.7.15日 Addressable(1.1.5) 才正式发布第一个正式版。未来它会成为UNITY的内置标准组件,就像之前我介绍过的 <a href="https://vrast.cn/posts/56648355/">IMGUI:UNITY的新UI系统</a> 一样,目前该系统在UNITY2019的UNTY上已经成了标配组件。<br>从中我也发现了UNITY更新内置功能的规律。 1.放到preview给程序员们试用收集反馈 2.preview迭代后转正式 3.一段时间的正式版后转为内置组建。 那未来要预测UNITY在下版本的功能我们看preview列表中来自 <strong>Unity Technologies</strong> 的功能就行了.<br>写本章的主要目的是记录这两天遇到bug的体验。</p>
</blockquote>
<a id="more"></a>
<h2 id="测试环境"><a href="#测试环境" class="headerlink" title="测试环境"></a>测试环境</h2><p>Addressable 2019.8.28 更新到1.1.10版本,也就是本章使用的最新版本。本篇所使用的Unity版本2019.3.f1 如果你也想测试请注意本文的时效性。</p>
<p><img src="/uploads/WX20200219-171056.png" alt="Addressable的更新日志"></p>
<h2 id="起因"><a href="#起因" class="headerlink" title="起因"></a>起因</h2><p>我写了这么一段代码用来测试不用callback 而直接获取实时加载进度与结果。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">string</span> loadPath = <span class="keyword">string</span>.Empty;</div><div class="line"></div><div class="line"><span class="function">IEnumerator <span class="title">loadRes</span>(<span class="params"></span>)</span></div><div class="line">{</div><div class="line"> <span class="keyword">var</span> operationHandle = Addressables.LoadAssetAsync<GameObject>(loadPath);</div><div class="line"></div><div class="line"> Debug.Log(operationHandle.Status.ToString());</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (operationHandle.Status == AsyncOperationStatus.Failed)</div><div class="line"> {</div><div class="line"> Debug.Log(<span class="string">"load failed"</span>);</div><div class="line"> <span class="keyword">yield</span> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"></div><div class="line"> <span class="keyword">while</span> (!operationHandle.IsDone)</div><div class="line"> {</div><div class="line"> <span class="keyword">yield</span> <span class="keyword">return</span> operationHandle.PercentComplete;</div><div class="line"> <span class="comment">// yield return new WaitForSeconds(.1f);</span></div><div class="line"> Debug.LogFormat(<span class="string">"loading percent :{0}"</span>,operationHandle.PercentComplete); </div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">var</span> g = operationHandle.Result;</div><div class="line"> <span class="keyword">var</span> g_ins = Instantiate(g);</div><div class="line"> g_ins.transform.position = Vector3.zero;</div><div class="line"> </div><div class="line"> <span class="keyword">yield</span> <span class="keyword">break</span>;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">void</span> <span class="title">OnGUI</span>(<span class="params"></span>)</span></div><div class="line">{</div><div class="line"> loadPath = GUILayout.TextField(loadPath);</div><div class="line"> </div><div class="line"> <span class="keyword">if</span> (GUILayout.Button(<span class="string">"sample load test"</span>))</div><div class="line"> {</div><div class="line"> StartCoroutine(loadRes());</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<p>结果我发现我第一次点击test按钮 operationHandle.Status 并不会返回错误信息他返回的是一个None状态,导致后面的代码直接崩溃。<br>紧接着第二次点击test按钮,变得正常了打印 load failed ,并且 operationHandle.Status 为 failed 。</p>
<p>就这个问题我查了一个晚上,终于给搞明白了 。Addressables 直接加载文件,内部会校验自身是否初始化完毕如果没有初始化 那就执行一次初始化 在进行资源加载作业。<br>不负责任的猜想是开发这个插件的人觉得 Addressables 同步加载不优雅,直接给 Addressables.Initialize 函数给oabsolute,<br>改为了Addressables.InitializeSync 接口(非同步的初始化接口)。</p>
<p>现在问题来了,Addressables.InitializeSync 是非同步的,后面的加载函数肯定在 Addressables 还没初始化完毕的情况下调用,出现不可预知的错误。</p>
<p>如何解决:1. 显式初始化 2. 改代码手动添加加载KeyCache</p>
<p>第一种方案直接等待初始化完毕再进行加载处理<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="function">IEnumerator <span class="title">loadRes</span>(<span class="params"></span>)</span></div><div class="line">{</div><div class="line"> <span class="keyword">yield</span> <span class="keyword">return</span> Addressables.InitializeAsync();</div><div class="line"> </div><div class="line"> <span class="keyword">var</span> operationHandle = Addressables.LoadAssetAsync<GameObject>(loadPath);</div><div class="line"></div><div class="line"> Debug.Log(operationHandle.Status.ToString());</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (operationHandle.Status == AsyncOperationStatus.Failed)</div><div class="line"> {</div><div class="line"> Debug.Log(<span class="string">"load failed"</span>);</div><div class="line"> <span class="keyword">yield</span> <span class="keyword">break</span>;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p>第二种方案这里我说下思路</p>
<ol>
<li>找到 InitializeAsync 的 Complete 函数注册完成事件</li>
<li>在加载资源的入口判断是否初始化完成,没有完成则记录加载资源的Key 然后跳出</li>
<li>InitializeAsync 的 Complete 函数调用后完成事件,根据第二步记录的key重做一次资源加载</li>
</ol>
<h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><p><a href="https://docs.unity3d.com/Packages/com.unity.addressables@1.1/manual/AddressableAssetsGettingStarted.html" target="_blank" rel="external">Getting started with Addressable Assets</a><br><a href="https://www.jianshu.com/p/9da4a30ad989" target="_blank" rel="external">The Addressable Asset System 正式版应用(一)</a><br><a href="https://www.jianshu.com/p/e79b2eef97bf" target="_blank" rel="external">学习Unity新出资源管理系统-Addressable Asset</a><br><a href="https://github.com/Unity-Technologies/Addressables-Sample" target="_blank" rel="external">GitHub Unity-Technologies/Addressables-Sample</a></p>
]]></content>
<summary type="html">
<blockquote>
<p>关注此插件已经有一段时间了,最早在2018就有preview版本了。但直到2019.7.15日 Addressable(1.1.5) 才正式发布第一个正式版。未来它会成为UNITY的内置标准组件,就像之前我介绍过的 <a href="https://vrast.cn/posts/56648355/">IMGUI:UNITY的新UI系统</a> 一样,目前该系统在UNITY2019的UNTY上已经成了标配组件。<br>从中我也发现了UNITY更新内置功能的规律。 1.放到preview给程序员们试用收集反馈 2.preview迭代后转正式 3.一段时间的正式版后转为内置组建。 那未来要预测UNITY在下版本的功能我们看preview列表中来自 <strong>Unity Technologies</strong> 的功能就行了.<br>写本章的主要目的是记录这两天遇到bug的体验。</p>
</blockquote>
</summary>
<category term="UNITY" scheme="http://vrast.cn/categories/UNITY/"/>
<category term="Addressable" scheme="http://vrast.cn/tags/Addressable/"/>
</entry>
<entry>
<title>人生三问</title>
<link href="http://vrast.cn/posts/52273db8/"/>
<id>http://vrast.cn/posts/52273db8/</id>
<published>2020-02-18T07:58:09.000Z</published>
<updated>2020-02-18T09:28:33.276Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>2019年匆匆走完,下半年事情好像越来越多(jira任务一直处于满载)。一时竟然没有闲下来,如果说2019是让人明确自己定位(你是什么laji),那今年2020总算让我思考了人生剩下两大终极问题:你从哪儿来?你到哪儿去?</p>
</blockquote>
<a id="more"></a>
<p><img src="/uploads/WechatIMG20191238.png" alt="意料之外,今年年会拿了个辛苦奖"></p>
<p>前一段时间赶在返工前剪了个头发,在家长发飘飘玩了一个假期的手游,什么手游都尝试下。发觉目前的行业就像一座空中楼阁,楼阁的每一款游戏都是一块木板。大多数木板都是一个叫腾讯的公司的,我们就站在这个阁楼上走了半天还没走出腾讯的地界。</p>
<p>N95戴的勒耳朵,如果脸和我一样大就只能用医用口罩(在室内),人多的地方还是n95靠谱一些。不过现在N95口罩想要买也买不到。手上只有一个千万不能丢了。</p>
<p>由于疫情防控这两天公司食堂只接受订餐,没订餐就只能出去找吃的。可惜的是跑了一圈都没开门。</p>
<p><img src="/uploads/WechatIMG14.jpeg" alt="公司周围的店已经都关了,好像过了五点便利店都不营业了白跑一趟。"></p>
]]></content>
<summary type="html">
<blockquote>
<p>2019年匆匆走完,下半年事情好像越来越多(jira任务一直处于满载)。一时竟然没有闲下来,如果说2019是让人明确自己定位(你是什么laji),那今年2020总算让我思考了人生剩下两大终极问题:你从哪儿来?你到哪儿去?</p>
</blockquote>
</summary>
<category term="生活" scheme="http://vrast.cn/categories/%E7%94%9F%E6%B4%BB/"/>
<category term="小结" scheme="http://vrast.cn/tags/%E5%B0%8F%E7%BB%93/"/>
</entry>
<entry>
<title>win10 svn 校验失败无法下载 FAQ</title>
<link href="http://vrast.cn/posts/2f0ec6ff/"/>
<id>http://vrast.cn/posts/2f0ec6ff/</id>
<published>2019-08-08T07:38:23.000Z</published>
<updated>2019-08-08T07:45:28.897Z</updated>
<content type="html"><![CDATA[<p><img src="/uploads/1565239339773.jpg" alt="Checkout svn 代码出现校验失败,svn账户密码窗口未出现"></p>
<p>找了下 Stackoverflow 发现一个可用的方案:<a href="https://stackoverflow.com/questions/45299260/tortoisesvn-authentication-error" target="_blank" rel="external">原文点这里</a></p>
<a id="more"></a>
<h1 id="解决方案如下"><a href="#解决方案如下" class="headerlink" title="解决方案如下"></a>解决方案如下</h1><p>If it’s caused by using Microsoft Account instead of Local Account to log in your Windows, the solution is in the SO link below. It’s just difficult to find it because it doesn’t talk exactly about TortoiseSVN, but the Subversion library which is under the hood of TortoiseSVN:</p>
<p>In SVN how do I override automatic Windows domain authentication</p>
<p>From the answer:</p>
<p>In “%AppData%\Subversion\servers” add into [groups] this line:</p>
<p>yoursvnserver_com = *.yoursvnserver.com<br>In the same file later add this group:</p>
<p>[yoursvnserver_com]<br>http-auth-types=basic;digest</p>
<p><img src="/uploads/WX20190808-154339.png" alt="修改servers文件"></p>
]]></content>
<summary type="html">
<p><img src="/uploads/1565239339773.jpg" alt="Checkout svn 代码出现校验失败,svn账户密码窗口未出现"></p>
<p>找了下 Stackoverflow 发现一个可用的方案:<a href="https://stackoverflow.com/questions/45299260/tortoisesvn-authentication-error">原文点这里</a></p>
</summary>
<category term="FAQ" scheme="http://vrast.cn/categories/FAQ/"/>
<category term="svn" scheme="http://vrast.cn/tags/svn/"/>
</entry>
<entry>
<title>IMGUI:UNITY的新UI系统</title>
<link href="http://vrast.cn/posts/56648355/"/>
<id>http://vrast.cn/posts/56648355/</id>
<published>2019-06-05T15:30:46.000Z</published>
<updated>2019-06-05T18:03:05.296Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>我关注类似MVVM的UI框架已经很久了,从2019.1发布的功能列表中我终于看到了非常想要的功能库。那就是UI Elements.<br>我在2016年也写过类似框架介绍,感兴趣的话可以看一下<a href="http://www.manew.com/forum.php?mod=viewthread&tid=93737&extra=page%3D1%26filter%3Dtypeid%26typeid%3D324" target="_blank" rel="external">细说PreGUI框架设计思路-蛮牛网</a>。<br>与PreGUI的设计思路类似,但是官方出品质量肯定上去不止一个台阶。另外配有完善的Profile工具。让你可以清楚的看到UI的布局细节。<br>截止到今日,IMGUI还是作为辅助UI系统在Unity中使用【编辑器】,相信过不了多久他就会转正甚至取代目前的UGUI,所以我们现在早点了解也好未来可以快速上手。好了下面开始正文 :)</p>
</blockquote>
<a id="more"></a>
<h1 id="使用-UI-Elements-Debugger-查看已有Editor的结构"><a href="#使用-UI-Elements-Debugger-查看已有Editor的结构" class="headerlink" title="使用 UI Elements Debugger 查看已有Editor的结构"></a>使用 UI Elements Debugger 查看已有Editor的结构</h1><p><img src="/uploads/usedebugtoolsmodifiedname.png" alt="你甚至可以在Elements Debugger中实时的修改属性值"></p>
<h1 id="Case01"><a href="#Case01" class="headerlink" title="Case01"></a>Case01</h1><p>这里就不上图了。简单描述下 rootVisualElement,他就是我们所有UI的根节点。如果你写过HTML 那么你肯定可以轻易地的<br>可以轻易地的过渡到现在的写法上,理解上亦是如此。</p>
<p>但下面的代码里,代码我们先获取到了UI的根节点,跟然后创建各种元素,将其添加进我们的根节点上。至此我们不需要加上额外代码,即可渲染控件,就如同我们在运行时里使用UGUI做的一样。</p>
<p>这里有一个小技巧,像HTML一样我们可以通过ID来寻找我们的控件。所以在创建组件的同时,如果考虑到我们后续需要去动态寻找该组件,那么我们将其设置一个name,并且通过name来寻找。就像下面做的这样。<code>var lable =rootVisualElement.Q<label>(“lable01”);</label></code></p>
<p>⚠️注意:.Q 查询函数为所有visual elements的扩展函数,也就意味着所有的元素都能搜索自己结构下的节点。</p>
<p>在这里你可以给控件添加回调函数,在该函数中你甚至可以获取触发当前回调的来源(每个控件都有callback)。就像下面做这样<code>var slider = evt.target as SliderInt;</code></p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">void</span> <span class="title">OnEnable</span>(<span class="params"></span>)</span></div><div class="line">{</div><div class="line"> <span class="keyword">var</span> root = rootVisualElement;</div><div class="line"> </div><div class="line"> <span class="comment">//创建lable</span></div><div class="line"> <span class="keyword">var</span> label = <span class="keyword">new</span> Label();</div><div class="line"> label.name = <span class="string">"lable01"</span>;</div><div class="line"> </div><div class="line"> <span class="comment">//创建slider</span></div><div class="line"> <span class="keyword">var</span> slider = <span class="keyword">new</span> SliderInt();</div><div class="line"> slider.name = <span class="string">"slider01"</span>;</div><div class="line"> slider.RegisterValueChangedCallback(SliderValueChangeCallback);</div><div class="line"> </div><div class="line"> </div><div class="line"> </div><div class="line"> root.Add(slider);</div><div class="line"> root.Add(label);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">SliderValueChangeCallback</span>(<span class="params">ChangeEvent<<span class="keyword">int</span>> evt</span>)</span></div><div class="line">{</div><div class="line"> <span class="keyword">var</span> slider = evt.target <span class="keyword">as</span> SliderInt;</div><div class="line"></div><div class="line"> <span class="keyword">var</span> lable =rootVisualElement.Q<Label>(<span class="string">"lable01"</span>);</div><div class="line"> lable.text = evt.newValue + <span class="string">" << fontsize is change. slider name:"</span> + slider.name;</div><div class="line"> lable.style.fontSize = slider.<span class="keyword">value</span>;</div><div class="line">}</div></pre></td></tr></table></figure>
<h1 id="Case02"><a href="#Case02" class="headerlink" title="Case02"></a>Case02</h1><p>看图~</p>
<p><img src="/uploads/WX20190606-005131@2x.png" alt="在这里,你可以看到目前所有可以用的控件"></p>
<h1 id="Case03"><a href="#Case03" class="headerlink" title="Case03"></a>Case03</h1><p>当然我们想要的更多,你同样可以通过样式文件与布局文件来渲染窗口。这才是我们最终的目的,什么让我们来看一下范例吧。</p>
<p><img src="/uploads/WX20190606-011815@2x.png" alt="创建布局与样式"></p>
<h2 id="读取uxml与uss"><a href="#读取uxml与uss" class="headerlink" title="读取uxml与uss"></a>读取uxml与uss</h2><p>⚠️注意:我们读取之后的类型分别为 VisualTreeAsset 与 StyleSheet 。</p>
<p>读取之后直接<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line">VisualElement m_RootElement;</div><div class="line">VisualTreeAsset m_ModulesVisualTree;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">OnEnable</span>(<span class="params"></span>)</span></div><div class="line">{</div><div class="line"> m_TurretBuilder = <span class="keyword">new</span> TurretBuilder(<span class="keyword">this</span>);</div><div class="line"></div><div class="line"> <span class="comment">// Hierarchy</span></div><div class="line"> m_RootElement = <span class="keyword">new</span> VisualElement();</div><div class="line"> m_ModulesVisualTree =</div><div class="line"> AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(</div><div class="line"> <span class="string">"Assets/Demo/UI/TurretEditorTemplate.uxml"</span>);</div><div class="line"></div><div class="line"> <span class="comment">// Styles</span></div><div class="line"> <span class="keyword">var</span> stylesheet =</div><div class="line"> AssetDatabase.LoadAssetAtPath<StyleSheet>(</div><div class="line"> <span class="string">"Assets/Demo/UI/TurretEditorStyles.uss"</span>);</div><div class="line"> m_RootElement.styleSheets.Add(stylesheet);</div><div class="line"></div><div class="line"> <span class="comment">// WILL BE FIXED: Unset padding on parent InspectorElement.</span></div><div class="line"> m_RootElement.RegisterCallback<AttachToPanelEvent>(OnRootAttachToPanel);</div><div class="line">}</div></pre></td></tr></table></figure></p>
<h2 id="创建Elements"><a href="#创建Elements" class="headerlink" title="创建Elements"></a>创建Elements</h2><p>使用CloneTree API可以创建读取出来的结构。并且将当前节点作为root的子节点。<br><figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">m_ModulesVisualTree.CloneTree(root);</div></pre></td></tr></table></figure></p>
<h2 id="事件绑定"><a href="#事件绑定" class="headerlink" title="事件绑定"></a>事件绑定</h2><p>暂时我没有找到事件映射或者绑定的代码。也有可能是这部分的API没有开放出来。暂时来看IMGUI的完善进度也比较快,就算现在没有事件映射,也可以等等。毕竟现在还没有过preview阶段。不过现在已经看起来像那么一回事了,相信用上它的一天很快会到的。</p>
<h1 id="Case4"><a href="#Case4" class="headerlink" title="Case4"></a>Case4</h1><p>添加高亮与提示(提示有限并不能很好的支持)</p>
<p><img src="/uploads/WX20190606-011014@2x.png" alt="在编辑uxml与uss的时候你需要一个代码高亮。在rider里是这样设置的"></p>
]]></content>
<summary type="html">
<blockquote>
<p>我关注类似MVVM的UI框架已经很久了,从2019.1发布的功能列表中我终于看到了非常想要的功能库。那就是UI Elements.<br>我在2016年也写过类似框架介绍,感兴趣的话可以看一下<a href="http://www.manew.com/forum.php?mod=viewthread&amp;tid=93737&amp;extra=page%3D1%26filter%3Dtypeid%26typeid%3D324">细说PreGUI框架设计思路-蛮牛网</a>。<br>与PreGUI的设计思路类似,但是官方出品质量肯定上去不止一个台阶。另外配有完善的Profile工具。让你可以清楚的看到UI的布局细节。<br>截止到今日,IMGUI还是作为辅助UI系统在Unity中使用【编辑器】,相信过不了多久他就会转正甚至取代目前的UGUI,所以我们现在早点了解也好未来可以快速上手。好了下面开始正文 :)</p>
</blockquote>
</summary>
<category term="UI" scheme="http://vrast.cn/categories/UI/"/>
<category term="IMGUI" scheme="http://vrast.cn/tags/IMGUI/"/>
</entry>
<entry>
<title>http下载与ftp下载md5值不一致</title>
<link href="http://vrast.cn/posts/d2e8872a/"/>
<id>http://vrast.cn/posts/d2e8872a/</id>
<published>2019-05-21T08:20:34.000Z</published>
<updated>2019-05-21T08:52:48.096Z</updated>
<content type="html"><![CDATA[<p>这问题花了四个小时找答案,值得记录下。起因是这样的,我用工具上传一份文件(二进制)到ftp,通过http下载的时候md5值与我原始文件不一致。通过文件比对发现多了17字节。推测是编码问题,随后查找事情的起因。经过同事提醒是否是文件传输过程中造成的。遂检查Filezillia的传输设置。<br>修改为二进制上传,问题解决。</p>
<p><img src="/uploads/WX20190521-163850.png" alt="修改filezillia文件传设置"></p>
]]></content>
<summary type="html">
<p>这问题花了四个小时找答案,值得记录下。起因是这样的,我用工具上传一份文件(二进制)到ftp,通过http下载的时候md5值与我原始文件不一致。通过文件比对发现多了17字节。推测是编码问题,随后查找事情的起因。经过同事提醒是否是文件传输过程中造成的。遂检查Filezillia
</summary>
<category term="ftp" scheme="http://vrast.cn/categories/ftp/"/>
<category term="download" scheme="http://vrast.cn/tags/download/"/>
</entry>
<entry>
<title>使用ternimal 或 powershell 计算文件md5</title>
<link href="http://vrast.cn/posts/2a8fe98b/"/>
<id>http://vrast.cn/posts/2a8fe98b/</id>
<published>2019-05-14T07:29:39.000Z</published>
<updated>2019-05-14T07:35:07.484Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>最近经常会需要临时计算某个文件md5的需求。然后找了下相关命令在此记录下。</p>
</blockquote>
<p>MAC:</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">md5 you-file-full-path</div></pre></td></tr></table></figure>
<p>powershell</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">get</span>-filehash you-file-full-path -algorithm md5</div></pre></td></tr></table></figure>]]></content>
<summary type="html">
<blockquote>
<p>最近经常会需要临时计算某个文件md5的需求。然后找了下相关命令在此记录下。</p>
</blockquote>
<p>MAC:</p>
<figure class="highlight cs"><table><tr><td class="gutte
</summary>
<category term="teranimal" scheme="http://vrast.cn/categories/teranimal/"/>
<category term="md5" scheme="http://vrast.cn/tags/md5/"/>
</entry>
<entry>
<title>AndroidStudio AVD FAQ</title>
<link href="http://vrast.cn/posts/55eaddde/"/>
<id>http://vrast.cn/posts/55eaddde/</id>
<published>2019-05-09T13:19:20.000Z</published>
<updated>2019-05-09T13:39:38.906Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>本篇记录一些在Profile APK过程中可能遇到的一些问题。当然我也查了好一会儿。在这里做一下记录。</p>
</blockquote>
<h3 id="Device-File-Explore"><a href="#Device-File-Explore" class="headerlink" title="Device File Explore"></a>Device File Explore</h3><p><img src="/uploads/WX20190509-212231@2x.png" alt="使用 Device File Explore 可以看到当前虚拟机内文件的情况, 在View/TopWindows/Device File Explore你可以找到这个面板的入口。"></p>
<p><img src="/uploads/WX20190509-212133@2x.png" alt="这里有一个点需要注意,你如果使用了含有GooglePlay框架的包,是不可以访问系统保护目录的。所以这里需要安装Google API的包。"></p>
]]></content>
<summary type="html">
<blockquote>
<p>本篇记录一些在Profile APK过程中可能遇到的一些问题。当然我也查了好一会儿。在这里做一下记录。</p>
</blockquote>
<h3 id="Device-File-Explore"><a href="#Device-File-Exp
</summary>
<category term="AndroidStudio" scheme="http://vrast.cn/categories/AndroidStudio/"/>
<category term="AVD" scheme="http://vrast.cn/tags/AVD/"/>
</entry>
<entry>
<title>JIT && TOC</title>
<link href="http://vrast.cn/posts/cd9ab0aa/"/>
<id>http://vrast.cn/posts/cd9ab0aa/</id>
<published>2019-04-30T04:48:53.000Z</published>
<updated>2019-05-06T08:26:41.341Z</updated>
<content type="html"><![CDATA[<p>最近受一位蓝朋友影响看了一些项管相关的书,这里做一下记录。记录的内容不多科普文。摘录内容源于wiki。</p>
<a id="more"></a>
<h1 id="JIT-TOC"><a href="#JIT-TOC" class="headerlink" title="JIT TOC"></a>JIT TOC</h1><p>了解下 JIT 当然这不是C#或者Java里的JIT .</p>
<p><img src="/uploads/WX20190506-102330.png" alt="wiki词条"></p>
<h1 id="JIT-内容相关"><a href="#JIT-内容相关" class="headerlink" title="JIT 内容相关"></a>JIT 内容相关</h1><h3 id="及时制度(JIT)"><a href="#及时制度(JIT)" class="headerlink" title="及时制度(JIT)"></a>及时制度(JIT)</h3><p>JIT的想法很简单:库存是资源浪费。JIT库存系统认为,库存带来了隐含的成本,因此高效率的企业应该不存在库存。公司需要采取一系列新的管理办法,进行变革。需要采取统计学、工业工程学、生产管理和行为科学中的管理办法。及时库存逻辑阐述了库存的内涵以及与管理的关系。库存会带来成本以及浪费,而不是增加或储存价值,这与传统会计学不同。这不是说,及时系统不需要对生产好的商品进行储存。而是鼓励企业逐步消除库存,以便削减生产流程中的成本。其次,在管理中逐渐适应“零库存”的状态。库存会带来很多附加成本,例如需要建立新的仓库、需要更新设备、减少流程的可变性、缺乏工人和设备灵活性、以及影响产量等。简单来说,及时制度主要的核心是“让正确的物资,在正确的时间,流动到正确的地方,数量是刚刚好的数量。”</p>
<h3 id="环境影响"><a href="#环境影响" class="headerlink" title="环境影响"></a>环境影响</h3><p>在及时制度的诞生初期,很多产品的日常运输还是用自行车,当生产规模加大时,就需要汽车和卡车. 庫蘇馬諾在1994提出了此系統在交通阻塞和石化燃料的使用下會產生及有可能產生的弊端. 而這些弊端這違反了及時制度制訂的三條減少浪費的原則:<br>時間 - 在交通阻塞中所浪費的時間<br>庫存 - 在交通阻塞中滯留的產品<br>廢棄物 - 在交通阻塞中, 無法移動的狀態下, 燃料仍持續的被消耗<br>影响价格<br>及时系统提出,库存让价格变化性大,因为库存让企业需要提前根据产量,采购原材料,原材料的价格又会有波动,因此提高了价格变化性。如果原材料价格提高,库存成本也提高。<br>质量波动<br>及时制度提出,进口零件的质量一般稳定,如果不稳定的话,企业就会增加成本。企业一般会与固定的供应商合作,降低原材料的质量波动和价格。<br>需求波动<br>卡马克 (1989) 提出,相对稳定的需求的重要性是,帮助保证效率、资本利用率。卡马克提出,如果需求不稳定,及时系统就会带来很高的资本成本。<br>供应稳定<br>美国1992年的铁路工人罢工引起了通用电气公司裁掉了7.5万名员工,因为公司的产品供应不出去。</p>
<p>JIT实施方法<br>1) 设计产品流动流程<br>依生產流程重新設計/重新佈置場地與動線<br>减少每个批次的数量<br>合并可以合并的环节<br>平衡產线上下游的產能<br>預防保養<br>降低架設工時<br>2) 全面质量控制<br>提高工人认知度<br>进行自动化检查<br>对质量进行量化测量<br>检测瑕疵产品<br>激发工人的参与<br>3) 稳定生产时间<br>将生产时程平準化<br>建立冻结窗口(freeze windows)<br>保留部份產能<br>4) 看板拉动系统<br>根据需求进行拉动管理<br>Backflush<br>减少每批次数量<br>5) 与供應商合作<br>降低前置时间<br>頻繁但有規律的供貨<br>项目用法需求<br>统一质量<br>6) 进一步降低其他部门的库存<br>降低零售店面库存<br>降低运输过程中库存<br>改善运输工具,减少运输库存<br>利用传送带,降低运输库存<br>7) 改善产品設計<br>產品構型標準化<br>减少零件的数量<br>把产品设计进行流程化<br>统一质量</p>
<h1 id="TOC-内容相关"><a href="#TOC-内容相关" class="headerlink" title="TOC 内容相关"></a>TOC 内容相关</h1><p>限制理論(Theory of Constraints,TOC)是由以色列學者伊利雅胡·高德拉特所發展出來的一種全方面的管理哲學,主張一個複雜的系統隱含著簡單化。即使在任何時間,一個複雜的系統可能是由成千上萬人和一系列設備所組成。但是只有非常少的變數或許只有一個,稱為限制,它會限制(或阻礙)此系統達到更高的目標。<br>TOC的思考程序可協助答覆專注於改善時的主要問題:<br>什麼要改變?<br>要改變成什麼?<br>如何造成改變?<br>有時,另外兩個問題也會被列為思考程序:<br>為什麼要改變?<br>如何保持持續改善的過程(英语:Process of ongoing improvement-POOGI)?<br>TOC主張任何組織或企業成立之時必然有一目標,但同時也存在著許多限制阻礙組織或企業達成這個目標。因此為了達成其更高的績效,就必須打破這些限制,做到持續的改進。</p>
<p>中文wiki内容有限下面是英文内容:</p>
<p>The theory of constraints (TOC) is a management paradigm that views any manageable system as being limited in achieving more of its goals by a very small number of constraints. There is always at least one constraint, and TOC uses a focusing process to identify the constraint and restructure the rest of the organization around it. TOC adopts the common idiom “a chain is no stronger than its weakest link”. This means that processes, organizations, etc., are vulnerable because the weakest person or part can always damage or break them or at least adversely affect the outcome.</p>
<h3 id="The-five-focusing-steps"><a href="#The-five-focusing-steps" class="headerlink" title="The five focusing steps"></a>The five focusing steps</h3><p>Theory of constraints is based on the premise that the rate of goal achievement by a goal-oriented system (i.e., the system’s throughput) is limited by at least one constraint.</p>
<p>The argument by reductio ad absurdum is as follows: If there was nothing preventing a system from achieving higher throughput (i.e., more goal units in a unit of time), its throughput would be infinite — which is impossible in a real-life system.</p>
<p>Only by increasing flow through the constraint can overall throughput be increased.[1]</p>
<p>Assuming the goal of a system has been articulated and its measurements defined, the steps are:</p>
<p>Identify the system’s constraint(s).<br>Decide how to exploit the system’s constraint(s).<br>Subordinate everything else to the above decision(s).<br>Alleviate the system’s constraint(s).<br>Warning! If in the previous steps a constraint has been broken, go back to step 1, but do not allow inertia to cause a system’s constraint.[4]<br>The goal of a commercial organization is: “Make more money now and in the future”,[5] and its measurements are given by throughput accounting as: throughput, inventory, and operating expenses.</p>
<p>The five focusing steps aim to ensure ongoing improvement efforts are centered on the organization’s constraint(s). In the TOC literature, this is referred to as the process of ongoing improvement (POOGI).</p>
<p>These focusing steps are the key steps to developing the specific applications mentioned below.</p>
<h3 id="Constraints"><a href="#Constraints" class="headerlink" title="Constraints"></a>Constraints</h3><p>A constraint is anything that prevents the system from achieving its goal. There are many ways that constraints can show up, but a core principle within TOC is that there are not tens or hundreds of constraints. There is at least one, but at most only a few in any given system. Constraints can be internal or external to the system. An internal constraint is in evidence when the market demands more from the system than it can deliver. If this is the case, then the focus of the organization should be on discovering that constraint and following the five focusing steps to open it up (and potentially remove it). An external constraint exists when the system can produce more than the market will bear. If this is the case, then the organization should focus on mechanisms to create more demand for its products or services.</p>
<h3 id="Types-of-internal-constraints"><a href="#Types-of-internal-constraints" class="headerlink" title="Types of (internal) constraints"></a>Types of (internal) constraints</h3><p>Equipment: The way equipment is currently used limits the ability of the system to produce more salable goods/services.<br>People: Lack of skilled people limits the system. Mental models held by people can cause behaviour that becomes a constraint.<br>Policy: A written or unwritten policy prevents the system from making more.<br>The concept of the constraint in Theory of Constraints is analogous to but differs from the constraint that shows up in mathematical optimization. In TOC, the constraint is used as a focusing mechanism for management of the system. In optimization, the constraint is written into the mathematical expressions to limit the scope of the solution (X can be no greater than 5).</p>
<p>Please note: organizations have many problems with equipment, people, policies, etc. (A breakdown is just that – a breakdown – and is not a constraint in the true sense of the TOC concept). The constraint is the limiting factor that is preventing the organization from getting more throughput (typically, revenue through sales) even when nothing goes wrong.</p>
<h3 id="Breaking-a-constraint"><a href="#Breaking-a-constraint" class="headerlink" title="Breaking a constraint"></a>Breaking a constraint</h3><p>If a constraint’s throughput capacity is elevated to the point where it is no longer the system’s limiting factor, this is said to “break” the constraint. The limiting factor is now some other part of the system, or may be external to the system (an external constraint). This is not to be confused with a breakdown.</p>
<h3 id="Buffers"><a href="#Buffers" class="headerlink" title="Buffers"></a>Buffers</h3><p>Buffers are used throughout the theory of constraints. They often result as part of the exploit and subordinate steps of the five focusing steps. Buffers are placed before the governing constraint, thus ensuring that the constraint is never starved. Buffers are also placed behind the constraint to prevent downstream failure from blocking the constraint’s output. Buffers used in this way protect the constraint from variations in the rest of the system and should allow for normal variation of processing time and the occasional upset (Murphy) before and behind the constraint.</p>
<p>Buffers can be a bank of physical objects before a work center, waiting to be processed by that work center. Buffers ultimately buy you time, as in the time before work reaches the constraint and are often verbalized as time buffers. There should always be enough (but not excessive) work in the time queue before the constraint and adequate offloading space behind the constraint.</p>
<p>Buffers are not the small queue of work that sits before every work center in a Kanban system although it is similar if you regard the assembly line as the governing constraint. A prerequisite in the theory is that with one constraint in the system, all other parts of the system must have sufficient capacity to keep up with the work at the constraint and to catch up if time was lost. In a balanced line, as espoused by Kanban, when one work center goes down for a period longer than the buffer allows, then the entire system must wait until that work center is restored. In a TOC system, the only situation where work is in danger is if the constraint is unable to process (either due to malfunction, sickness or a “hole” in the buffer – if something goes wrong that the time buffer can not protect).</p>
<p>Buffer management, therefore, represents a crucial attribute of the theory of constraints. There are many ways to apply buffers, but the most often used is a visual system of designating the buffer in three colors: green (okay), yellow (caution) and red (action required). Creating this kind of visibility enables the system as a whole to align and thus subordinate to the need of the constraint in a holistic manner. This can also be done daily in a central operations room that is accessible to everybody.</p>
<h3 id="Plant-types"><a href="#Plant-types" class="headerlink" title="Plant types"></a>Plant types</h3><p>There are four primary types of plants in the TOC lexicon. Draw the flow of material from the bottom of a page to the top, and you get the four types. They specify the general flow of materials through a system, and also provide some hints about where to look for typical problems. This type of analysis is known as VATI analysis[6] as it uses the bottom-up shapes of the letters V, A, T, and I to describe the types of plants. The four types can be combined in many ways in larger facilities, e.g. “an A plant feeding a V plant”.</p>
<p>V-plant: The general flow of material is one-to-many, such as a plant that takes one raw material and can make many final products. Classic examples are meat rendering plants or a steel manufacturer. The primary problem in V-plants is “robbing,” where one operation (A) immediately after a diverging point “steals” materials meant for the other operation (B). Once the material has been processed by A, it cannot come back and be run through B without significant rework.<br>A-plant: The general flow of material is many-to-one, such as in a plant where many sub-assemblies converge for a final assembly. The primary problem in A-plants is in synchronizing the converging lines so that each supplies the final assembly point at the right time.<br>T-plant: The general flow is that of an I-plant (or has multiple lines), which then splits into many assemblies (many-to-many). Most manufactured parts are used in multiple assemblies and nearly all assemblies use multiple parts. Customized devices, such as computers, are good examples. T-plants suffer from both synchronization problems of A-plants (parts aren’t all available for an assembly) and the robbing problems of V-plants (one assembly steals parts that could have been used in another).<br>I-plant: Material flows in a sequence, such as in an assembly line. The primary work is done in a straight sequence of events (one-to-one). The constraint is the slowest operation.<br>From the above list, one can deduce that for non-material systems one could draw the flow of work or the flow of processes, instead of physical flows, and arrive at similar basic V, A, T, or I structures. A project, for example, is an A-shaped sequence of work, culminating in a delivered product (i.e., the intended outcome of the project).</p>
<h1 id="甘特图"><a href="#甘特图" class="headerlink" title="甘特图"></a>甘特图</h1><p>甘特图我推荐用下面这个,平时我做计划几乎都离不开Omniplan,它支持导出Project格式,同时支持任务排期跳过节假日等。</p>
<p><img src="/uploads/WX20190506-104321.png" alt="Omniplan"></p>
<p><a href="https://en.wikipedia.org/wiki/Theory_of_constraints" target="_blank" rel="external">TOC</a><br><a href="https://en.wikipedia.org/wiki/Just-in-time_manufacturing" target="_blank" rel="external">Just-in-time manufacturing</a><br><a href="https://baike.baidu.com/item/全面质量管理/82450?fromtitle=TQM&fromid=1446922&fr=aladdin" target="_blank" rel="external">TQM</a></p>
]]></content>
<summary type="html">
<p>最近受一位蓝朋友影响看了一些项管相关的书,这里做一下记录。记录的内容不多科普文。摘录内容源于wiki。</p>
</summary>
<category term="gantt chart" scheme="http://vrast.cn/categories/gantt-chart/"/>
<category term="project" scheme="http://vrast.cn/tags/project/"/>
</entry>
<entry>
<title>使用VisualStudio Code 预览.md文件</title>
<link href="http://vrast.cn/posts/47642b6e/"/>
<id>http://vrast.cn/posts/47642b6e/</id>
<published>2019-04-19T14:44:21.000Z</published>
<updated>2019-04-26T14:38:40.730Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>本篇是给一个小朋友看的,原话是这样的:“用VisualStudio Code 看不了Markdown文件 。” 那么按照本篇操作,你将可以方便的在VsCode中预览Markdown文件。</p>
</blockquote>
<a id="more"></a>
<h1 id="给VisualStudio-Code安装Markdown预览插件"><a href="#给VisualStudio-Code安装Markdown预览插件" class="headerlink" title="给VisualStudio Code安装Markdown预览插件"></a>给VisualStudio Code安装Markdown预览插件</h1><p><img src="/uploads/WX20190419-225136@2x.png" alt="安装插件的步骤"></p>
<h1 id="快捷键"><a href="#快捷键" class="headerlink" title="快捷键"></a>快捷键</h1><p>安装完毕之后打开<code> .md </code>文件。就可以使用preview功能了。</p>
<p><img src="/uploads/WX20190419-225136@2x.png" alt="按一次Ctrl + Shift + v 就可以开启preview窗口了。"></p>
<p><img src="/uploads/WX20190419-225734@2x.png" alt="如果想要左右分屏 可以点一下这个小图标"></p>
<p><img src="/uploads/WX20190419-225904@2x.png" alt="分屏效果图"></p>
<p><img src="/uploads/WX20190419-225344@2x.png" alt="快捷键在插件内部也有介绍,非常的简单"></p>
]]></content>
<summary type="html">
<blockquote>
<p>本篇是给一个小朋友看的,原话是这样的:“用VisualStudio Code 看不了Markdown文件 。” 那么按照本篇操作,你将可以方便的在VsCode中预览Markdown文件。</p>
</blockquote>
</summary>
<category term="Markdown" scheme="http://vrast.cn/categories/Markdown/"/>
<category term="tools" scheme="http://vrast.cn/tags/tools/"/>
</entry>
<entry>
<title>Mac平台Debug lua提示缺少socket.http组件</title>
<link href="http://vrast.cn/posts/d708212d/"/>
<id>http://vrast.cn/posts/d708212d/</id>
<published>2019-04-18T02:35:02.000Z</published>
<updated>2019-04-18T03:19:56.561Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>起因是这样的我想在Mac上配一下Lua Debug环境,在debug的时候会用到socket链接到调试器。在intelliJ中Debug的时候它提示我“module ‘socket.http’ not found” 然后我就去了解了一下Lua环境的配置,这里着重要提到Lua的包管理工具 <a href="https://luarocks.org" target="_blank" rel="external">luarocks</a>,还真是很方便缺什么直接就装什么。</p>
</blockquote>
<a id="more"></a>
<h1 id="安装luarocks"><a href="#安装luarocks" class="headerlink" title="安装luarocks"></a>安装luarocks</h1><p>直接用Homebrew就能安装,当然可以下载源码编译。<br><figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">brew </span>update</div><div class="line"><span class="keyword">brew </span><span class="keyword">install </span>luarocks</div></pre></td></tr></table></figure></p>
<p>或者</p>
<ol>
<li>下载 <a href="https://luarocks.org/releases/luarocks-3.0.4.tar.gz" target="_blank" rel="external">https://luarocks.org/releases/luarocks-3.0.4.tar.gz</a></li>
<li>解压进入luarocks-3.0.4</li>
<li>编译 ./configure; sudo make bootstrap</li>
<li>安装luasocket sudo luarocks install luasocket</li>
</ol>
<p>这里需要注意如果你和我是使用Mac那么在第4步的时候需要切换到<code>/usr/local/share/lua/5.3</code>这个路径下。这是默认的lua文件存放位置。</p>
<h1 id="更多命令"><a href="#更多命令" class="headerlink" title="更多命令"></a>更多命令</h1><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">luarocks <span class="built_in">help</span></div></pre></td></tr></table></figure>
<h1 id="关于插件"><a href="#关于插件" class="headerlink" title="关于插件"></a>关于插件</h1><p>我看了下好用的lua扩展还真不少<br><img src="/uploads/WX20190418-104738.png" alt="比如关于Protobuf的库"></p>
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a href="https://stackoverflow.com/questions/16491242/module-socket-http-not-found-lua-on-imac" target="_blank" rel="external">“module ‘socket.http’ not found:” –Lua on iMac [closed]
</a></p>
]]></content>
<summary type="html">
<blockquote>
<p>起因是这样的我想在Mac上配一下Lua Debug环境,在debug的时候会用到socket链接到调试器。在intelliJ中Debug的时候它提示我“module ‘socket.http’ not found” 然后我就去了解了一下Lua环境的配置,这里着重要提到Lua的包管理工具 <a href="https://luarocks.org">luarocks</a>,还真是很方便缺什么直接就装什么。</p>
</blockquote>
</summary>
<category term="FAQ" scheme="http://vrast.cn/categories/FAQ/"/>
<category term="Lua" scheme="http://vrast.cn/tags/Lua/"/>
</entry>
<entry>
<title>UNITY Unable to instantiate UnityPlayerActivity</title>
<link href="http://vrast.cn/posts/80d969f4/"/>
<id>http://vrast.cn/posts/80d969f4/</id>
<published>2019-04-11T08:11:24.000Z</published>
<updated>2019-04-11T10:56:40.650Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>这段时间自从用了UNITY 2018.3.8F1 出现的bug很多,关于构建包的。不知道是不是 Unity 频繁更新导致的。截止到目前为止 我已经在UNITY HUB上看到了 UNITY2018.3.12.F1 这个版本了。我这边的遇到的问题主要体现在使用Gradle构建或者使用内置方式构建都会出现无法找到MainActivity。也就是Unity默认运行的那个Activity.即使我直接创建一个新的工程打包,亦是如此。<br><img src="/uploads/WX20190411-161531.png" alt="无法找到这个 unityplayer.UnityActivity 或者 xxx.xxx.xxx.UnityPlayerActivity"></p>
</blockquote>
<a id="more"></a>
<p><img src="/uploads/WX20190411-183559.png" alt="打开AndroidManifest.xml之后发现这边直接找不到。"></p>
<p><img src="/uploads/WX20190411-183859.png" alt="既然这样我直接用UNITY3D默认的"></p>
<p>好吧 解决了。</p>
<p>当然这并不是引发当前问题的根源,然而为什么会引发这个问题呢 ? 于是我重新审视了一下代码</p>
<p><img src="/uploads/WX20190411-184808.png" alt="这段代码的继承类是 Activity"></p>
<h1 id="但是"><a href="#但是" class="headerlink" title="但是"></a>但是</h1><p><img src="/uploads/WX20190411-185258.png" alt="在老版本里是这样的,改成继承自UnityPlayerAcitivity问题解决。"></p>
<h1 id="所以-这又是Unity的BUG吗?"><a href="#所以-这又是Unity的BUG吗?" class="headerlink" title="所以 这又是Unity的BUG吗?"></a>所以 这又是Unity的BUG吗?</h1>]]></content>
<summary type="html">
<blockquote>
<p>这段时间自从用了UNITY 2018.3.8F1 出现的bug很多,关于构建包的。不知道是不是 Unity 频繁更新导致的。截止到目前为止 我已经在UNITY HUB上看到了 UNITY2018.3.12.F1 这个版本了。我这边的遇到的问题主要体现在使用Gradle构建或者使用内置方式构建都会出现无法找到MainActivity。也就是Unity默认运行的那个Activity.即使我直接创建一个新的工程打包,亦是如此。<br><img src="/uploads/WX20190411-161531.png" alt="无法找到这个 unityplayer.UnityActivity 或者 xxx.xxx.xxx.UnityPlayerActivity"></p>
</blockquote>
</summary>
<category term="UNITY" scheme="http://vrast.cn/categories/UNITY/"/>
<category term="Android" scheme="http://vrast.cn/tags/Android/"/>
</entry>
<entry>
<title>优化IL2CPP打包速度</title>
<link href="http://vrast.cn/posts/b5ee8b26/"/>
<id>http://vrast.cn/posts/b5ee8b26/</id>
<published>2019-04-10T06:54:16.000Z</published>
<updated>2019-04-10T07:31:36.780Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>今天有同事找我聊了一下关于打包的问题,他说在UNITY IL2CPP下编译速度过慢,切换成 mono 会快三分之一。这个速度有没有办法优化。我倒是没有什么实际优化打包速度的操作经验,让我来做一般就是资源层优化,当然这是最难也最容易做到的。但是他倒是给我提了几个不错的建议。我看了下UNITY的官网确实如此。本篇记录之。</p>
</blockquote>
<ul>
<li>降低硬盘读写(各种方案:关闭杀毒软件/用两块ssd项目与unity分开/等)</li>
<li>增量包构建会加速进程</li>
</ul>
<p>下面是UNITY官方的实践经验:</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">Optimizing IL2CPP build times</div><div class="line">Project build times can be much longer when building a project with IL2CPP</div><div class="line">. However, there are several ways to reduce the build time significantly:</div><div class="line"></div><div class="line"><span class="keyword">Use</span> incremental building</div><div class="line"></div><div class="line"><span class="keyword">When</span> <span class="keyword">using</span> incremental building, the C++ compiler <span class="keyword">only</span> recompiles files that have <span class="keyword">changed</span> since the <span class="keyword">last</span> build. <span class="keyword">To</span> <span class="keyword">use</span> incremental building, <span class="keyword">build</span> your <span class="keyword">project</span> <span class="keyword">to</span> a previous <span class="keyword">build</span> location (<span class="keyword">without</span> deleting the target <span class="keyword">directory</span>).</div><div class="line"></div><div class="line"><span class="keyword">Exclude</span> <span class="keyword">project</span> <span class="keyword">and</span> target <span class="keyword">build</span> folders <span class="keyword">from</span> anti-malware software scans</div><div class="line"></div><div class="line">You can improve <span class="keyword">build</span> times <span class="keyword">by</span> disabling anti-malware software <span class="keyword">before</span> building your project. (Testing <span class="keyword">by</span> Unity Technologies <span class="keyword">found</span> that <span class="keyword">build</span> times decreased <span class="keyword">by</span> <span class="number">50</span> – <span class="number">66</span>% <span class="keyword">after</span> disabling Windows Defender <span class="keyword">on</span> a <span class="keyword">fresh</span> Windows <span class="number">10</span> installation.)</div><div class="line"></div><div class="line"><span class="keyword">Store</span> your <span class="keyword">project</span> <span class="keyword">and</span> target <span class="keyword">build</span> folder <span class="keyword">on</span> a Solid State Drive (SSD)</div><div class="line"></div><div class="line">Solid State Drives (SSDs) have faster <span class="keyword">read</span>/write speed, <span class="keyword">when</span> compared <span class="keyword">to</span> traditional Hard Disk Drives (HDD). Converting IL code <span class="keyword">to</span> C++ <span class="keyword">and</span> compiling it involves a <span class="keyword">large</span> <span class="built_in">number</span> <span class="keyword">of</span> <span class="keyword">read</span>/write operations. A faster <span class="keyword">storage</span> device speeds up this process.</div></pre></td></tr></table></figure>
]]></content>
<summary type="html">
<blockquote>
<p>今天有同事找我聊了一下关于打包的问题,他说在UNITY IL2CPP下编译速度过慢,切换成 mono 会快三分之一。这个速度有没有办法优化。我倒是没有什么实际优化打包速度的操作经验,让我来做一般就是资源层优化,当然这是最难也最容易做到的。但是他倒是
</summary>
<category term="UNITY" scheme="http://vrast.cn/categories/UNITY/"/>
<category term="BuildTimes" scheme="http://vrast.cn/tags/BuildTimes/"/>
</entry>
<entry>
<title>安装Unity导出APK显示失败</title>
<link href="http://vrast.cn/posts/434d7425/"/>
<id>http://vrast.cn/posts/434d7425/</id>
<published>2019-04-05T09:45:02.000Z</published>
<updated>2019-05-14T07:34:50.978Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>遇到一个非常皮的问题,我更新了Android Studio的SDK Build Tools,直接将 Build Tools 29 rc1 与 rc2 都下载了。<br><img src="/uploads/WX20190405-174643.png" alt="我当时是直接更新到了 29 rc2"><br>直接导出项目在Android Studio中会直接显示 …</p>
</blockquote>
<a id="more"></a>
<p><strong>android studio ERROR: Failed to find Build Tools revision 29.0.0</strong><br>另外如果直接出APK然后安装会显示一个<br><strong>Installation error:INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION</strong><br>这个报错信息是十分误导人的,网上的解决方案一般都是更改keystone或直接更改unity的项目导出模版。这样越改越偏。如果你也和我一样不妨试一下下面的方案。</p>
<p>我在Stackoverflow上找到了一解决方案:</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">For building a project, Unity3d uses a stable version of the Build Tools and not an rc (<span class="keyword">release</span> candidate).</div><div class="line"></div><div class="line">The Android SDK <span class="keyword">path</span> <span class="keyword">is</span> usually C:\<span class="keyword">Users</span>\<username>\AppData\<span class="keyword">Local</span>\Android\sdk\<span class="keyword">build</span>-tools\ <span class="keyword">delete</span> the <span class="number">29.0</span><span class="number">.0</span>-rc1 folder <span class="keyword">or</span> <span class="keyword">move</span> it <span class="keyword">out</span> <span class="keyword">to</span> anywhere. You could also remove the rc <span class="keyword">version</span> <span class="keyword">of</span> the SDK <span class="keyword">Build</span> Tools via Android Studio<span class="string">'s SDK manager.</span></div><div class="line"></div><div class="line">Doing that the project should build successfully.</div></pre></td></tr></table></figure>
<p>大意就是让我直接将下载的 Build Tools 29 rc1 与 rc2 先删除然后再打包。试了一下成功安装了。</p>
<p><img src="/uploads/WX20190405-175318.png" alt="安装成功了"></p>
<h1 id="UNITY的Build-Tools使用策略猜测"><a href="#UNITY的Build-Tools使用策略猜测" class="headerlink" title="UNITY的Build Tools使用策略猜测"></a>UNITY的Build Tools使用策略猜测</h1><p>经过上面的实力躺坑,可以推断如果你安装了更新的Build Tools,unity导出的时候就会使用最近更新的最新的那个,或许是路径拼接的问题,unity所引用的build tools只会引用前面的版本号 ,就像我遇到的一样 明明下载了 29 rc1 / 29 rc2 ,Unity偏偏不用执着的去找一个叫 29 的 Build Tools。</p>
<p>或许这是一个隐藏bug吧,希望Unity团队早日解决。</p>
]]></content>
<summary type="html">
<blockquote>
<p>遇到一个非常皮的问题,我更新了Android Studio的SDK Build Tools,直接将 Build Tools 29 rc1 与 rc2 都下载了。<br><img src="/uploads/WX20190405-174643.png" alt="我当时是直接更新到了 29 rc2"><br>直接导出项目在Android Studio中会直接显示 …</p>
</blockquote>
</summary>
<category term="UNITY" scheme="http://vrast.cn/categories/UNITY/"/>
<category term="ANDROID" scheme="http://vrast.cn/tags/ANDROID/"/>
</entry>
<entry>
<title>使用Android Studio进行APK Profile</title>
<link href="http://vrast.cn/posts/98741dc2/"/>
<id>http://vrast.cn/posts/98741dc2/</id>
<published>2019-04-04T08:02:23.000Z</published>
<updated>2019-04-05T02:37:51.169Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>很多时候我们需要从Android端获取崩溃日志,但是手动adb比较麻烦。这时候就应该使用AndroidStudio了。</p>
</blockquote>
<a id="more"></a>
<h2 id="使用AndroidStudio进行Profile"><a href="#使用AndroidStudio进行Profile" class="headerlink" title="使用AndroidStudio进行Profile"></a>使用AndroidStudio进行Profile</h2><p><img src="/uploads/WX20190404-160013.png" alt="导入APK到IDE中"></p>
<p><img src="/uploads/WX20190405-100856.png" alt="选择需要启用调试的设备,也可以是真机(需要开启USB调试)"></p>
<p><img src="/uploads/WX20190405-101425.png" alt="使用logcat轻松获取当前Log,如果信息过多 你可以直接用Unity关键字过滤"></p>
<p>还有性能/内存等详细的分析这里有一份参考:<a href="https://blog.csdn.net/niubitianping/article/details/72617864" target="_blank" rel="external">Android studio中android profile(性能分析器)的使用</a></p>
]]></content>
<summary type="html">
<blockquote>
<p>很多时候我们需要从Android端获取崩溃日志,但是手动adb比较麻烦。这时候就应该使用AndroidStudio了。</p>
</blockquote>
</summary>
<category term="Android Profile" scheme="http://vrast.cn/categories/Android-Profile/"/>
<category term="APK" scheme="http://vrast.cn/tags/APK/"/>
</entry>
<entry>
<title>UNITY移动端路径的注意事项</title>
<link href="http://vrast.cn/posts/d425b5d3/"/>
<id>http://vrast.cn/posts/d425b5d3/</id>
<published>2019-04-04T06:41:42.000Z</published>
<updated>2019-04-05T07:12:28.363Z</updated>
<content type="html"><![CDATA[<blockquote>
<p>在移动端加载路径与Windwos或Mac上加载有一些区分,有时候资源文件找不到是在是查起来头疼。这里写一些推荐规范,从非开发角度就能避免这些问题。</p>
</blockquote>
<a id="more"></a>
<h2 id="路径大小写"><a href="#路径大小写" class="headerlink" title="路径大小写"></a>路径大小写</h2><p>在UNITY EDITOR下你不必关注路径大小写问题,⚠️ 注意:但是在移动端大小写是敏感的。</p>
<ul>
<li>建议所有AB包都保持小写的命名方式 </li>
<li>建议在加载文件的地方的留一个可以开关的宏定义用来查路径问题</li>
</ul>
<h2 id="StreamAssets目录的资源加载"><a href="#StreamAssets目录的资源加载" class="headerlink" title="StreamAssets目录的资源加载"></a>StreamAssets目录的资源加载</h2><p>StreamAsset目录中。在移动端File.IO不可用,⚠️ 注意:你需要使用www来加载当前目录下资源</p>
<p>你可以使用下面的代码块进行资源的同步加载,而不必非要放到携程里进行加载。</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">using</span> (WWW www = <span class="keyword">new</span> WWW(path))</div><div class="line">{</div><div class="line"> <span class="keyword">while</span> (!www.isDone)</div><div class="line"> {</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">using</span> (<span class="keyword">var</span> ms = <span class="keyword">new</span> MemoryStream(www.bytes))</div><div class="line"> {</div><div class="line"> </div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure>
<h2 id="路径的隐含条件"><a href="#路径的隐含条件" class="headerlink" title="路径的隐含条件"></a>路径的隐含条件</h2><ul>
<li>建议统一使用www加载,避免大量的逻辑判断(比如是否需要拼接”file://“)</li>
<li>在StreamAsset目录下就不要使用 File.exsits 之类位于 System.IO命名空间下函数</li>
</ul>
<p>//在android下<br>Application.streamingAssetsPath = “jar:file://“ + Application.dataPath + “!/assets/“</p>
<p>//在pc & mac端<br>Application.streamingAssetsPath = Application.dataPath + “/StreamingAssets”</p>
<p>//在iOS端<br>Application.streamingAssetsPath = Application.dataPath + “/Raw”</p>
<p><img src="/uploads/WX20190404-160429.png" alt="APK内StreamAsset目录结构"></p>
<p>当然你可以使用下面的代码块直接进行www加载路径的拼接</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">string</span> <span class="title">GetWWWLoadingPathAtStreamingAssetsFolder</span>(<span class="params"></span>)</span></div><div class="line">{</div><div class="line"> <span class="keyword">string</span> path;</div><div class="line"> <span class="meta">#<span class="meta-keyword">if</span> UNITY_EDITOR</span></div><div class="line"> path = <span class="string">"file:"</span> + Application.dataPath + <span class="string">"/StreamingAssets"</span>;</div><div class="line"> <span class="meta">#<span class="meta-keyword">elif</span> UNITY_ANDROID</span></div><div class="line"> path = <span class="string">"jar:file://"</span>+ Application.dataPath + <span class="string">"!/assets/"</span>;</div><div class="line"> <span class="meta">#<span class="meta-keyword">elif</span> UNITY_IOS</span></div><div class="line"> path = <span class="string">"file:"</span> + Application.dataPath + <span class="string">"/Raw"</span>;</div><div class="line"> <span class="meta">#<span class="meta-keyword">else</span></span></div><div class="line"> <span class="comment">//Desktop (Mac OS or Windows)</span></div><div class="line"> path = <span class="string">"file:"</span>+ Application.dataPath + <span class="string">"/StreamingAssets"</span>;</div><div class="line"> <span class="meta">#<span class="meta-keyword">endif</span></span></div><div class="line"> </div><div class="line"> <span class="keyword">return</span> path;</div><div class="line">}</div></pre></td></tr></table></figure>
]]></content>
<summary type="html">
<blockquote>
<p>在移动端加载路径与Windwos或Mac上加载有一些区分,有时候资源文件找不到是在是查起来头疼。这里写一些推荐规范,从非开发角度就能避免这些问题。</p>
</blockquote>
</summary>
<category term="MOBILE" scheme="http://vrast.cn/tags/MOBILE/"/>
</entry>
</feed>