<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>引擎相关 - 初晴神社</title>
	<atom:link href="https://vki.cc/engine/feed/" rel="self" type="application/rss+xml" />
	<link>https://vki.cc/category/greattruth/engine/</link>
	<description>白露的博客</description>
	<lastBuildDate>Fri, 02 Apr 2021 06:36:21 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1</generator>

<image>
	<url>https://cdn.vki.cc/wp-content/uploads/2018/03/cropped-icemaplen-1-32x32.png</url>
	<title>引擎相关 - 初晴神社</title>
	<link>https://vki.cc/category/greattruth/engine/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Unity 内存管理</title>
		<link>https://vki.cc/greattruth/engine/731/</link>
					<comments>https://vki.cc/greattruth/engine/731/#respond</comments>
		
		<dc:creator><![CDATA[白露]]></dc:creator>
		<pubDate>Wed, 22 Jul 2020 12:10:38 +0000</pubDate>
				<category><![CDATA[引擎相关]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<category><![CDATA[优化]]></category>
		<category><![CDATA[内存]]></category>
		<category><![CDATA[原创]]></category>
		<guid isPermaLink="false">https://bye6.cc/?p=731</guid>

					<description><![CDATA[<p>我胡汉三又回来啦！~ 内存交换 标准交换在内存与备份存储之间移动进程，备份存储通常是快速磁盘，它应足够大，以容纳所有用户的所有内存映像的副本，并且它应提供对这些存储器映像的直接访问。 移动设备不支&#8230;</p>
<p><a href="https://vki.cc/greattruth/engine/731/">Unity 内存管理</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<pre class="wp-block-preformatted">我胡汉三又回来啦！~</pre>



<h4 class="wp-block-heading" id="o8CfU"><span id="%e5%86%85%e5%ad%98%e4%ba%a4%e6%8d%a2">内存交换</span></h4>



<p class="has-text-align-left has-black-color has-text-color wp-block-paragraph">标准交换在内存与备份存储之间移动进程，备份存储通常是快速磁盘，它应足够大，以容纳所有用户的所有内存映像的副本，并且它应提供对这些存储器映像的直接访问。</p>



<p class="has-black-color has-text-color wp-block-paragraph"><strong>移动设备不支持任何形式的内存交换。</strong></p>



<ul class="wp-block-list"><li>移动设备通常采用闪存，而不是空间更大的硬盘作为它的永久存储。导致的空间约束是移动操作系统设计者避免交换的原因之一；</li><li>闪存写入次数的限制；</li><li>内存与闪存之间的吞吐量差；</li></ul>



<p class="has-black-color has-text-color wp-block-paragraph">当空闲内存降低到一定阈值以下时：</p>



<ul class="wp-block-list"><li>iOS：不釆用交换，而是要求应用程序自愿放弃分配的内存。只读数据（如代码）可从系统中删除，以后如有必要再从闪存重新加载。已修改的数据（如堆栈）不会被删除。然而，操作系统可以终止任何未能释放足够内存的应用程序。</li><li>Android：不支持交换，釆用类似 iOS 使用的策略。如果没有足够可用的空闲内存，则它可以终止进程。然而，在终止进程之前，Android 将其应用程序状态写到闪存，以便它能快速重新启动。</li></ul>



<p class="has-black-color has-text-color wp-block-paragraph">iOS支持内存压缩，Android不可以。</p>



<p class="has-black-color has-text-color wp-block-paragraph">Android 内存单位为Page，大小一般为4k，以分配单位回收，分为用户态和内核态，不可越界访问。</p>



<p class="has-black-color has-text-color wp-block-paragraph">Low Memory Killier：内存杀手。</p>



<p class="has-black-color has-text-color wp-block-paragraph"><strong>Android服务优先级（从高到低），当内存不够时从优先级低的开始销毁</strong>：</p>



<ul class="wp-block-list"><li>Native</li><li>System 当杀到这一层级的时候手机重启</li><li>Persistent</li><li>Foreground 前台应用，具体表现为APP闪退</li><li>Perceptible</li><li>Service</li><li>Home 桌面</li><li>Previous 上一个使用的APP</li><li>Cached 后台APP</li></ul>



<h4 class="wp-block-heading" id="36R9c"><span id="unity%e5%86%85%e5%ad%98">Unity内存</span></h4>



<p class="has-black-color has-text-color wp-block-paragraph">按类型分为 <strong>Native Memory </strong>和<strong> Managed Memory</strong></p>



<p class="has-black-color has-text-color wp-block-paragraph">Editor与Runtime不同</p>



<ul class="has-cyan-bluish-gray-color has-text-color wp-block-list"><li data-lake-id="11ad0f3d261d1bdfaad1f6170d68b6da">Editor模式会尽可能的加载资源（启动较慢）</li><li data-lake-id="920753378d0cef5c0e9628ab6efaa826">Runtime按需加载</li></ul>



<p class="has-black-color has-text-color wp-block-paragraph">Unity封装了C++中与申请内存相关的函数，并添加了Label用于统计。</p>



<h4 class="wp-block-heading" id="FzmP4"><span id="audio">Audio</span></h4>



<p class="wp-block-paragraph"><strong>DSP Buffer</strong></p>



<ul class="wp-block-list"><li data-lake-id="b320a7254b16d587a6f73bceb02ab68b">过大会导致声音有延迟</li><li data-lake-id="988feb3af3915b96c8fd2c5133f0b1ab">过小会使CPU负担上升</li></ul>



<p class="wp-block-paragraph"><strong>Force to mono</strong></p>



<p class="wp-block-paragraph">双声道改单声道（尽量，绝大多数声音不需要双声道）</p>



<p class="wp-block-paragraph"><strong>Compress Format</strong></p>



<h4 class="wp-block-heading" id="e3S92"><span id="code-size">Code Size</span></h4>



<p class="wp-block-paragraph">慎用模板泛型，</p>



<h4 class="wp-block-heading" id="UfI9X"><span id="assetbundle">AssetBundle</span></h4>



<p class="wp-block-paragraph">Type Tree</p>



<p class="wp-block-paragraph">当Unity版本与APP版本一致时可以关掉</p>



<ul class="wp-block-list"><li style="list-style-type: none;">
<ul data-lake-id="3e53979f08d5f031e7fefefd919b79c4">
<li data-lake-id="6feee38208c0af4aca7e153e5c19465c">减小内存</li>
<li data-lake-id="2f7a8c2489975976f9ad934aa76d1b4b">减小包大小</li>
<li data-lake-id="47ac6b264aafb950d9d0f23e668ee5e0">Build和Runtime变快</li>
</ul>
</li></ul>



<p class="wp-block-paragraph"><strong>压缩方式</strong></p>



<p class="wp-block-paragraph">LZ4 推荐</p>



<p class="wp-block-paragraph">LZMA 弃用</p>



<p class="wp-block-paragraph"><strong>extra</strong></p>



<p class="wp-block-paragraph">不建议每个文件打一个AssetBundle包</p>



<p class="wp-block-paragraph">因为它们有相同的“头”，仅数据部分不同，容易浪费空间。</p>



<h4 class="wp-block-heading" id="dNP1Y"><span id="resources">Resources</span></h4>



<p class="wp-block-paragraph">通过红黑树进行索引，每次启动游戏都要分析加载红黑树，拖慢启动时间。其次整个游戏生命周期都会存在与内存中。</p>



<h4 class="wp-block-heading" id="KpCjw"><span id="texture">Texture</span></h4>



<p class="wp-block-paragraph"><strong>Upload Buffer</strong></p>



<p class="wp-block-paragraph"><strong>Read&amp;Write</strong></p>



<p class="wp-block-paragraph">没有特殊需求就关掉write</p>



<p class="wp-block-paragraph"><strong>Mipmap</strong></p>



<p class="wp-block-paragraph">同样没有特殊需求就关掉</p>



<h4 class="wp-block-heading" id="x73lJ"><span id="mesh">Mesh</span></h4>



<p class="wp-block-paragraph"><strong>Read&amp;Write</strong></p>



<p class="wp-block-paragraph"><strong>Compresssion</strong></p>



<h3 class="wp-block-heading" id="rbJ5r"><span id="managed%e5%86%85%e5%ad%98">Managed内存</span></h3>



<p class="has-black-color has-text-color wp-block-paragraph">VM内存池</p>



<p class="has-black-color has-text-color wp-block-paragraph">VM会返还内存给OS</p>



<p class="has-black-color has-text-color wp-block-paragraph">条件：一个block连续6次GC没被访问到</p>



<h4 class="wp-block-heading" id="epv2S"><span id="unity-gc-%e7%ae%97%e6%b3%95">Unity GC 算法</span></h4>



<pre class="wp-block-preformatted">貌似不采用CLR的GC机制_(:з」∠)_（参见另一篇文章，传送门）</pre>



<p class="has-black-color has-text-color wp-block-paragraph"><strong>Boehm GC</strong></p>



<p class="has-black-color has-text-color wp-block-paragraph">旧版垃圾回收方式，新版Unity已弃用。</p>



<p class="has-black-color has-text-color wp-block-paragraph"><strong>不分代</strong>（速度更快）</p>



<p class="has-black-color has-text-color wp-block-paragraph"><strong>不压缩</strong>（因为一些历史原因。。跟mono有关）</p>



<p class="has-black-color has-text-color wp-block-paragraph"><strong>Incremental GC（渐进式GC）</strong></p>



<p class="has-black-color has-text-color wp-block-paragraph">Unity2019.3之后使用，新一代垃圾回收算法。</p>



<p class="has-black-color has-text-color wp-block-paragraph">主要目的为了解决旧版GC导致主线程卡顿（旧版GC时会暂停主线程）的问题，<strong>分帧解决，且分代</strong></p>



<h4 class="wp-block-heading" id="4mYDq"><span id="gc%e6%9c%ba%e5%88%b6%e8%80%83%e9%87%8f">GC机制考量</span></h4>



<ul class="wp-block-list"><li data-lake-id="660957963fddbea01fd4ec0bcda75a61">回收能力</li><li data-lake-id="13580033e8e418799d5f260ba564a88d">暂停时长</li><li data-lake-id="522b2a4651dc451b9655e3c8fdf7d6cf">碎片化</li><li data-lake-id="2547a49c18f9244054ccb157d5bc822c">额外消耗</li><li data-lake-id="fdb31eab183fabe0398e946148dd5263">可扩展性</li><li data-lake-id="f3c2da301939823205f12211aedc759a">可移植性</li></ul>



<h4 class="wp-block-heading" id="J5Onq"><span id="%e5%86%85%e5%ad%98%e7%a2%8e%e7%89%87%e5%8c%96">内存碎片化</span></h4>



<p class="has-black-color has-text-color wp-block-paragraph">内存碎片通常分为内部碎片和外部碎片：</p>



<ol class="wp-block-list"><li>内部碎片是由于采用固定大小的内存分区，当一个进程不能完全使用分给它的固定内存区域时就产生了内部碎片，通常内部碎片难以完全避免；</li><li>外部碎片是由于某些未分配的连续内存区域太小，以至于不能满足任意进程的内存分配请求，从而不能被进程利用的内存区域。</li></ol>



<p class="has-black-color has-text-color wp-block-paragraph"><strong>先加载消耗大内存的资源，再加载小内存</strong></p>



<h4 class="wp-block-heading" id="FPdj0"><span id="%e5%83%b5%e5%b0%b8%e5%86%85%e5%ad%98">僵尸内存</span></h4>



<ul class="wp-block-list"><li data-lake-id="bc5462d9e5d49a7e6c32d79622a65214">无用内存</li><li data-lake-id="14915a15a5f640a5f8e01cbe11540cca">没有释放</li><li data-lake-id="796e8d72732ba18a118b944039f28f34">可通过代码管理和性能工具分析</li></ul>



<h4 class="wp-block-heading" id="7Bfhj"><span id="setactive">SetActive</span></h4>



<p class="wp-block-paragraph">TODO。。。</p>



<p class="wp-block-paragraph">都说要少用，但是不清楚机制，有机会看一下Unity源码 Orz</p>



<h3 class="wp-block-heading" id="QSWFN"><span id="%e4%bc%98%e5%8c%96%e5%bb%ba%e8%ae%ae">优化建议</span></h3>



<ul class="wp-block-list"><li data-lake-id="d69d8eee51298fd6887027e6e0e00d34"><strong>使用Destroy，别用null<br></strong></li><li data-lake-id="f2c16401a975b5ae82b4a625bbf6f445"><strong>Class/Struct</strong></li></ul>



<ul class="wp-block-list"><li data-lake-id="d566bb88ddc562cd4fa58dc8340331bf">少于8个字节的数据可用Struct代替Class（存疑）</li></ul>



<ul class="wp-block-list"><li data-lake-id="fdc6d72d868ae679fe6380d181f3b88d"><strong>池中池</strong></li><li data-lake-id="4334e0ca514037df778864799063153d"><strong>闭包和匿名函数</strong></li></ul>



<ul class="wp-block-list"><li data-lake-id="1250b809d7a3beea6d2bac105f387a0d">少用，在IL2CPP里这些都会new class</li><li data-lake-id="413a0dbfac105ff19edbffae41a3061e"><strong>协程</strong></li></ul>



<ul class="wp-block-list"><li data-lake-id="53c02b79234a6494d0ac6d3c4caf0935">用的时候再产生，不用的时候及时终止</li><li data-lake-id="c1e7ec9e3126fc936fc53cac7fa4b6bc">不要当线程使用</li><li data-lake-id="6d7ccc3bc281cf367da7a0f4e14430ad"><strong>配置表</strong></li></ul>



<ul class="wp-block-list"><li data-lake-id="f80c86b757dd40ebb7835f06cfb868b8">excel、json等，按需加载，不然会很占用内存空间</li><li data-lake-id="200224045513b88bcbc82c20699f1adb"><strong>单例模式 Singleton</strong></li></ul>



<ul class="wp-block-list"><li data-lake-id="82ebf0cbb49cdc3719ae3174695d3c4c">慎用，生命周期较长，占用内存</li></ul>
<p><a href="https://vki.cc/greattruth/engine/731/">Unity 内存管理</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vki.cc/greattruth/engine/731/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>在Unity中制作小地图</title>
		<link>https://vki.cc/greattruth/engine/342/</link>
					<comments>https://vki.cc/greattruth/engine/342/#comments</comments>
		
		<dc:creator><![CDATA[白露]]></dc:creator>
		<pubDate>Sat, 03 Feb 2018 14:36:54 +0000</pubDate>
				<category><![CDATA[咸鱼心得]]></category>
		<category><![CDATA[引擎相关]]></category>
		<category><![CDATA[UGUI]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[心得]]></category>
		<category><![CDATA[教程]]></category>
		<guid isPermaLink="false">http://www.icemaplen.com/?p=342</guid>

					<description><![CDATA[<p>在很多游戏里，小地图都是不可或缺的存在，今天我们就来学习下如何在Unity中制作小地图 _(:з」∠)_ 据我目前所知（知识有限），小地图有两种制作方式： 一是新建一个小摄像机，放在场景上空朝下进行拍摄； 二&#8230;</p>
<p><a href="https://vki.cc/greattruth/engine/342/">在Unity中制作小地图</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></description>
										<content:encoded><![CDATA[<p>在很多游戏里，小地图都是不可或缺的存在，今天我们就来学习下如何在Unity中制作小地图</p>
<p>_(:з」∠)_</p>
<p>据我目前所知（知识有限），小地图有两种制作方式：</p>
<p>一是新建一个小摄像机，放在场景上空朝下进行拍摄；</p>
<p>二是计算场景中物体的相对位置，通过UI显示出来；</p>
<p>在本例中，我使用的是第一张方式，这种方式实现相对简单一点，所以很方便。</p>
<h2 id="%e9%a6%96%e5%85%88%e5%9c%a8project%e4%b8%ad%e6%96%b0%e5%bb%ba%e4%b8%80%e4%b8%aarender-texture%ef%bc%8c%e5%91%bd%e5%90%8d%e4%b8%baminimap">首先在Project中新建一个Render Texture，命名为“Minimap”</h2>
<p><img  fetchpriority="high"  decoding="async"  class="alignnone size-full wp-image-351"  src="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203224324.jpg"  alt=""  width="505"  height="446"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203224324.jpg 505w, https://cdn.vki.cc/wp-content/uploads/2018/02/20180203224324-300x265.jpg 300w"  sizes="(max-width: 505px) 100vw, 505px" ></p>
<p>然后在场景中新建一个Camera，将其设为Player（将会在小地图中处于中心位置的玩家）的子物体，并调整其位置和方向，令其处于Player上方且朝向正下方，再将其Target Texture指定为刚才创建的Render Texture，如图：</p>
<p><img  decoding="async"  class="alignnone size-full wp-image-352"  src="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203224607.jpg"  alt=""  width="389"  height="406"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203224607.jpg 389w, https://cdn.vki.cc/wp-content/uploads/2018/02/20180203224607-287x300.jpg 287w"  sizes="(max-width: 389px) 100vw, 389px" ></p>
<p>然后在场景中创建UI-Raw Image，并设置Texture为刚才创建的Render Texture，你会发现image显示的是小地图Camera拍的内容 _(:з」∠)_</p>
<p>这样大体上就做出来了，不过还要调节下。</p>
<h2 id="%e8%ae%be%e7%bd%ae%e9%9c%80%e8%a6%81%e6%98%be%e7%a4%ba%e5%9c%a8%e5%b0%8f%e5%9c%b0%e5%9b%be%e4%b8%8a%e7%9a%84%e5%ad%90%e7%89%a9%e4%bd%93">设置需要显示在小地图上的子物体</h2>
<p>在需要显示在小地图上的的物体上添加一个Sphere子物体，改成绿色，同样改变高度使其位于上方（注意不要超过小地图Camera的高度）</p>
<p>新建一个Layer层，命名为Minimap，将Sphere置为Minimap层，</p>
<p>将地面模型也置为Minimap层，</p>
<p>更改小地图Camera的Culling Mask，只勾选刚才创建的Minimap层，注意勾选Occlusion Culling，这样小地图就只显示Minimap层的东西了。</p>
<p><img  decoding="async"  class="alignnone size-full wp-image-354"  src="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203230422.jpg"  alt=""  width="285"  height="350"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203230422.jpg 285w, https://cdn.vki.cc/wp-content/uploads/2018/02/20180203230422-244x300.jpg 244w"  sizes="(max-width: 285px) 100vw, 285px" ></p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-355"  src="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203230741.jpg"  alt=""  width="244"  height="234" ></p>
<h2 id="%e7%be%8e%e5%8c%96%e5%b0%8f%e5%9c%b0%e5%9b%be">美化小地图</h2>
<p>现在的小地图还是方形的，如何改成圆形呢？</p>
<p>打开ps，制作一个白色的圆，背景为透明，保存为png格式，导入到unity中，再设置属性为Sprite(2D and UI)，</p>
<p>[infobox title=&#8221;白色圆&#8221;]<a href="https://cdn.vki.cc/wp-content/uploads/2018/02/mask-1.png" target="_blank" rel="noopener noreferrer"><img  loading="lazy"  decoding="async"  class="alignnone wp-image-356 size-medium"  src="https://cdn.vki.cc/wp-content/uploads/2018/02/mask-1-300x300.png"  alt=""  width="300"  height="300"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/02/mask-1-300x300.png 300w, https://cdn.vki.cc/wp-content/uploads/2018/02/mask-1-150x150.png 150w, https://cdn.vki.cc/wp-content/uploads/2018/02/mask-1.png 512w"  sizes="auto, (max-width: 300px) 100vw, 300px" ></a> [/infobox]</p>
<p>在场景中新建UI-Image，image指定为白色的圆，添加上Mask组件，设置为Raw Image的父物体。这样小地图就变成圆形了：</p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-358"  src="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203231256.jpg"  alt=""  width="216"  height="214"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203231256.jpg 216w, https://cdn.vki.cc/wp-content/uploads/2018/02/20180203231256-150x150.jpg 150w"  sizes="auto, (max-width: 216px) 100vw, 216px" ></p>
<p>或者可以再加上一个圈：</p>
<p><a href="https://cdn.vki.cc/wp-content/uploads/2018/02/mask3.png" target="_blank" rel="noopener noreferrer">[infobox title=&#8221;圆圈&#8221;]<img  loading="lazy"  decoding="async"  class="alignnone wp-image-357 size-medium"  src="https://cdn.vki.cc/wp-content/uploads/2018/02/mask3-300x300.png"  alt=""  width="300"  height="300"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/02/mask3-300x300.png 300w, https://cdn.vki.cc/wp-content/uploads/2018/02/mask3-150x150.png 150w, https://cdn.vki.cc/wp-content/uploads/2018/02/mask3.png 512w"  sizes="auto, (max-width: 300px) 100vw, 300px" >[/infobox]</a></p>
<p>最终效果：</p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-359"  src="https://cdn.vki.cc/wp-content/uploads/2018/02/20180203231458.jpg"  alt=""  width="208"  height="213" ></p>
<hr />
<p>写完了，睡觉 _(:з」∠)_</p>
<p><a href="https://vki.cc/greattruth/engine/342/">在Unity中制作小地图</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vki.cc/greattruth/engine/342/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>UGUI 字体背景尺寸自适应</title>
		<link>https://vki.cc/greattruth/engine/321/</link>
					<comments>https://vki.cc/greattruth/engine/321/#respond</comments>
		
		<dc:creator><![CDATA[白露]]></dc:creator>
		<pubDate>Wed, 31 Jan 2018 09:06:22 +0000</pubDate>
				<category><![CDATA[咸鱼心得]]></category>
		<category><![CDATA[引擎相关]]></category>
		<category><![CDATA[UGUI]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<guid isPermaLink="false">http://www.icemaplen.com/?p=321</guid>

					<description><![CDATA[<p>最近再做一个模仿QQ聊天界面的聊天功能，在开发过程中遇到了一个问题，就是需要将字体的背景气泡自动随着字体长度变化。 经过一番尝试，最终功能如下： 怎么实现的呢？一起来看看吧。 &#160; 首先将背景图片&#8230;</p>
<p><a href="https://vki.cc/greattruth/engine/321/">UGUI 字体背景尺寸自适应</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></description>
										<content:encoded><![CDATA[<p>最近再做一个模仿QQ聊天界面的聊天功能，在开发过程中遇到了一个问题，就是需要将字体的背景气泡自动随着字体长度变化。</p>
<p>经过一番尝试，最终功能如下：</p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-324"  src="https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165407.jpg"  alt=""  width="610"  height="246"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165407.jpg 610w, https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165407-300x121.jpg 300w"  sizes="auto, (max-width: 610px) 100vw, 610px" ></p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-325"  src="https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165408.jpg"  alt=""  width="591"  height="257"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165408.jpg 591w, https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165408-300x130.jpg 300w"  sizes="auto, (max-width: 591px) 100vw, 591px" ></p>
<p>怎么实现的呢？一起来看看吧。</p>
<p>&nbsp;</p>
<p>首先将背景图片设为父物体，字体text为子物体；</p>
<p>给父物体添加[kbd]Horizontal Layout Group[/kbd]和[kbd]Content Size Fitter[/kbd]组件，</p>
<p>在[kbd]Horizontal Layout Group[/kbd]中设置Child Alignment为Middle Center，</p>
<p>勾选Child Controls Size里的Width和Height，该选项是令子物体控制其尺寸。</p>
<p>&nbsp;</p>
<p>在[kbd]Content Size Fitter[/kbd]中将两个选项都选为 PreferredSize；<br />
<span style="color: #808080;">Unconstrained：不执行任何调整 </span><br />
<span style="color: #808080;">MinSize：调整内容的最小大小 </span><br />
<span style="color: #808080;">PreferredSize：调整内容的首选大小，也就是会自动根据内容来调整大小</span></p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-326"  src="https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165826.jpg"  alt=""  width="766"  height="353"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165826.jpg 766w, https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165826-300x138.jpg 300w, https://cdn.vki.cc/wp-content/uploads/2018/01/20180131165826-750x346.jpg 750w"  sizes="auto, (max-width: 766px) 100vw, 766px" ></p>
<p>这样就可以了！做个测试吧</p>
<p>&nbsp;</p>
<p>为了美观，可以设置下背景的padding，这样文字和背景边框之间就会用一定的间隔啦</p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-328"  src="https://cdn.vki.cc/wp-content/uploads/2018/01/20180131170736.jpg"  alt=""  width="402"  height="190"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/01/20180131170736.jpg 402w, https://cdn.vki.cc/wp-content/uploads/2018/01/20180131170736-300x142.jpg 300w"  sizes="auto, (max-width: 402px) 100vw, 402px" ></p>
<p>&nbsp;</p>
<p><a href="https://vki.cc/greattruth/engine/321/">UGUI 字体背景尺寸自适应</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vki.cc/greattruth/engine/321/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>分享一个摄像机跟随的代码模板</title>
		<link>https://vki.cc/greattruth/engine/315/</link>
					<comments>https://vki.cc/greattruth/engine/315/#comments</comments>
		
		<dc:creator><![CDATA[白露]]></dc:creator>
		<pubDate>Tue, 23 Jan 2018 23:53:11 +0000</pubDate>
				<category><![CDATA[咸鱼心得]]></category>
		<category><![CDATA[引擎相关]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<category><![CDATA[心得]]></category>
		<guid isPermaLink="false">http://www.icemaplen.com/?p=315</guid>

					<description><![CDATA[<p>先上代码： using System.Collections; using System.Collections.Generic; using UnityEngine; public class CameraFollow : MonoBehaviour { public float Distance = 20; //摄像机与目标距离 public floa&#8230;</p>
<p><a href="https://vki.cc/greattruth/engine/315/">分享一个摄像机跟随的代码模板</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></description>
										<content:encoded><![CDATA[<p>先上代码：</p>
<pre class="pure-highlightjs"><code class="cs">using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraFollow : MonoBehaviour
{

    public float Distance = 20;                     //摄像机与目标距离
    public float RotSpeedInHorizontal = 0.05f;      //横向旋转速度
    public float RotSpeedInVertical = 0.05f;        //纵向旋转速度
    public float ZoomSpeed = 0.2f;                  //距离变化速度

    public float rot = 0;                           //横向角度
    private float roll = 30f * 2 * Mathf.PI / 360;  //纵向角度

    private float minRoll = -10f * 2 * Mathf.PI / 360;  //纵向角度范围
    private float maxRoll= 70f * 2 * Mathf.PI / 360;    //纵向角度范围

    private float minDistance = 10f;    //距离范围
    private float maxDisrance = 50f;

    private GameObject targetGO;        //目标物体  
    

    void Start()
    {
        SetTarget(GameObject.Find("Tank"));
    }
    
    void LateUpdate()
    {
        if (targetGO != null &amp;&amp; Camera.main != null)
        {
            RotateInHorizontal();
            RotateInVertical();
            Zoom();
            FollowTarget(targetGO.transform);
        }
    }

    private void SetTarget(GameObject target)
    {
        Transform cameraPoint = target.transform.Find("CameraPoint");
        targetGO = cameraPoint != null ? cameraPoint.gameObject : target;

        //if (cameraPoint != null)
        //{
        //    targetGO = cameraPoint.gameObject;
        //}
        //else
        //{
        //    targetGO = target;
        //}
    }

    private void FollowTarget(Transform targetTrans)
    {
        Vector3 targetPos = targetTrans.position;
        Vector3 cameraPos;
        float d = Distance * Mathf.Cos(roll);
        float height = Distance * Mathf.Sin(roll);
        cameraPos.x = targetPos.x + d * Mathf.Cos(rot);
        cameraPos.z = targetPos.z + d * Mathf.Sin(rot);
        cameraPos.y = targetPos.y + height;

        Camera.main.transform.position = cameraPos;
        Camera.main.transform.LookAt(targetTrans);
    }

    /// &lt;summary&gt;
    /// 水平旋转。
    /// &lt;/summary&gt;
    private void RotateInHorizontal()
    {
        float tmp = Input.GetAxis("Mouse X") * RotSpeedInHorizontal;
        rot -= tmp;
    }

    /// &lt;summary&gt;
    /// 竖直旋转。
    /// &lt;/summary&gt;
    private void RotateInVertical()
    {
        float tmp = Input.GetAxis("Mouse Y") * RotSpeedInVertical * 0.5f;
        roll -= tmp;

        roll = Mathf.Clamp(roll, minRoll, maxRoll);
    }

    /// &lt;summary&gt;
    /// 调节摄像机与目标之间的距离。
    /// &lt;/summary&gt;
    private void Zoom()
    {
        if (Input.GetAxis("Mouse ScrollWheel") &gt; 0)
        {
            if (Distance &gt; minDistance)
            {
                Distance -= ZoomSpeed;
            }
        }
        else if (Input.GetAxis("Mouse ScrollWheel") &lt; 0)
        {
            if (Distance &lt; maxDisrance)
            {
                Distance += ZoomSpeed;
            }
        }
    }
}
</code></pre>
<h2 id="%e8%ae%be%e7%bd%ae%e8%b7%9f%e9%9a%8f%e7%9b%ae%e6%a0%87-settargetgameobject-target">设置跟随目标 SetTarget(GameObject target)</h2>
<pre class="pure-highlightjs"><code class="cs">private void SetTarget(GameObject target)
    {
        Transform cameraPoint = target.transform.Find("CameraPoint");
        targetGO = cameraPoint != null ? cameraPoint.gameObject : target;

        //if (cameraPoint != null)
        //{
        //    targetGO = cameraPoint.gameObject;
        //}
        //else
        //{
        //    targetGO = target;
        //}
    }
</code></pre>
<p>因为目标物体的大小形状可能不同，有时候我们想让相机对准目标身上某个自定义的点，便可以在目标上添加一个子物体，命名为&#8221;CameraPoint&#8221;。</p>
<p>这个方法的作用就是查找目标是否存在&#8221;CameraPoint&#8221;，如果有就将&#8221;CameraPoint&#8221;设为目标点。如果没有，仍然使用默认目标点。</p>
<h2 id="%e7%9b%b8%e6%9c%ba%e8%b7%9f%e9%9a%8f%e7%9b%ae%e6%a0%87-followtargettransform-targettrans">相机跟随目标 FollowTarget(Transform targetTrans)</h2>
<pre class="pure-highlightjs"><code class="cs">    private void FollowTarget(Transform targetTrans)
    {
        Vector3 targetPos = targetTrans.position;
        Vector3 cameraPos;
        float d = Distance * Mathf.Cos(roll);
        float height = Distance * Mathf.Sin(roll);
        cameraPos.x = targetPos.x + d * Mathf.Cos(rot);
        cameraPos.z = targetPos.z + d * Mathf.Sin(rot);
        cameraPos.y = targetPos.y + height;

        Camera.main.transform.position = cameraPos;
        Camera.main.transform.LookAt(targetTrans);
    }</code></pre>
<p>这一部分较为复杂，使用了三角函数的知识。</p>
<p>要想让相机跟随目标移动，就要明白在一定角度下相机与目标的位置关系，如图所示</p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-318"  src="https://cdn.vki.cc/wp-content/uploads/2018/01/CameraFollow1.jpg"  alt=""  width="571"  height="429"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/01/CameraFollow1.jpg 571w, https://cdn.vki.cc/wp-content/uploads/2018/01/CameraFollow1-300x225.jpg 300w"  sizes="auto, (max-width: 571px) 100vw, 571px" ></p>
<p>（灵魂画手。。）</p>
<p>设相机与目标距离为distance，相机与xz平面角度为roll。根据三角函数即可求得distance映射在xz平面上的距离为distance*cos(roll)，高度为distance*sin(roll)。</p>
<p>&nbsp;</p>
<p>再如下图，设相机与目标在水平面上的距离为d（即distance映射在水平面的长度），相机旋转角度为rot，由图可知相机与目标的连线与x轴角度为rot-180。</p>
<p>根据三角函数，求得x轴位移为d*sin(rot)，z轴位移为d*cos(rot)。所以，只要用目标坐标减去相对位移，便能求出相机坐标。</p>
<p><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-319"  src="https://cdn.vki.cc/wp-content/uploads/2018/01/CameraFollow2.jpg"  alt=""  width="464"  height="439"  srcset="https://cdn.vki.cc/wp-content/uploads/2018/01/CameraFollow2.jpg 464w, https://cdn.vki.cc/wp-content/uploads/2018/01/CameraFollow2-300x284.jpg 300w"  sizes="auto, (max-width: 464px) 100vw, 464px" ></p>
<h2 id="%e5%85%b6%e4%bb%96">其他</h2>
<p>1.相机跟随代码最好放入LateUpdate()中；</p>
<p>2.Mathf.Sin()和Mathf.Cos()使用弧度做单位，使用时将度数乘以[kbd]2*Mathf.Pi/360[/kbd]转化为弧度；</p>
<p><a href="https://vki.cc/greattruth/engine/315/">分享一个摄像机跟随的代码模板</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vki.cc/greattruth/engine/315/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>【转】Unity中的序列化</title>
		<link>https://vki.cc/greattruth/engine/276/</link>
					<comments>https://vki.cc/greattruth/engine/276/#comments</comments>
		
		<dc:creator><![CDATA[白露]]></dc:creator>
		<pubDate>Sat, 09 Sep 2017 12:34:53 +0000</pubDate>
				<category><![CDATA[引擎相关]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<category><![CDATA[心得]]></category>
		<category><![CDATA[教程]]></category>
		<category><![CDATA[解析]]></category>
		<category><![CDATA[转载]]></category>
		<guid isPermaLink="false">http://www.icemaplen.com/?p=276</guid>

					<description><![CDATA[<p>What is it?  序列化的概念 长篇大论起来，序列化就是一个将对象的状态信息转换为可以存储或传输到内存，数据库或者文件的过程。简而言之，就是如何存储对象以便后续调用的过程。   假设我们需要定义和存储&#8230;</p>
<p><a href="https://vki.cc/greattruth/engine/276/">【转】Unity中的序列化</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></description>
										<content:encoded><![CDATA[<h2 id="what-is-it-%e5%ba%8f%e5%88%97%e5%8c%96%e7%9a%84%e6%a6%82%e5%bf%b5"><strong><span style="font-size: medium;"><span style="color: black;"><span style="font-family: 微软雅黑, sans-serif;">What is it?  </span></span><span style="color: black;"><span style="font-family: 微软雅黑, sans-serif;">序列化的概念</span></span></span></strong><span style="font-size: medium;"><strong><span style="color: black;"><span style="font-family: 微软雅黑, sans-serif;"><br />
</span></span></strong></span></h2>
<div align="left"><span style="font-size: medium;">长篇大论起来，序列化就是一个将对象的状态信息转换为可以存储或传输到内存，数据库或者文件的过程。简而言之，就是如何存储对象以便后续调用的过程。</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">假设我们需要定义和存储一个向量，那这个向量的哪些字段状态我们需要保存起来？很明显是向量的三个分量X.Y,Z啦。您可以考虑将重要的数据进行序列化操作，以便在后续进行反序列化的操作。在这里我们再次简明概括一下序列化以及反序列化。</span></div>
<div align="left"><span style="font-size: medium;">序列化： 将数据结构或对象转换成二进制串的过程</span></div>
<div align="left"><span style="font-size: medium;">反序列化：将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程</span></div>
<div align="left"></div>
<div align="left"><span style="font-size: medium;">正如我们所分析那样，序列化经常用于存储或者转化数据。假设我们在我们的服务器上部署了一个商城，并且正常运行了数据库管理应用。那么，将内存数据（（内存数据断电即丢失））写入硬盘的操作过程就是将对象序列化成数据表的实例。其他平台的数据存储操作，也属于序列化的范畴。</span></div>
<h2 id="how-unity-does-unity%e7%9a%84%e5%ba%8f%e5%88%97%e5%8c%96%e5%b7%a5%e4%bd%9c%e5%8e%9f%e7%90%86"><strong><span style="font-size: medium;"><span style="color: black;"><span style="font-family: 微软雅黑, sans-serif;">How Unity Does  </span></span><span style="font-family: 微软雅黑, sans-serif;">Unity</span><span style="font-family: 微软雅黑, sans-serif;">的序列化工作原理</span></span></strong></h2>
<p><span style="font-size: medium;">Unity作为一个<a class="relatedlink" href="http://www.manew.com/forum-news-1.html" target="_blank" rel="noopener noreferrer">游戏引擎</a>，除了需要从外部（磁盘）加载一大堆资源，如脚本，预设以及场景等到内存，还需要将数据从原生C++端转移到C#端进行托管。序列化操作不仅限于底层数据的加载和存储，它在前端界面也有所应用，如属性窗口，编辑器重定义以及场景对象实例化等。鉴于个人能力有限，您可以在本帖子的延伸阅读（最下方）找寻其他作者关于Unity序列化的博文。我相信处女座的同学会立马谷歌一下。</span></p>
<div align="left"><span style="font-size: medium;">已被序列化的UnityEngine.Object类会提供相应的序列化资源 ：如MonoBehaviour，ScriptableObject（稍后会提到），Shader,Sprite以及Unity的基础内置资源。一般上述资源在游戏开发过程中的调用不可见，除了在脚本编写的环节才有所体现。毕竟在脚本编码过程中，您需要关注哪些字段需要被序列化。如果要对字段进行序列化，您必须遵循以下规则：</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">将该字段定义为public,或者为其添加【SerializeField】的属性</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">该字段不能使用static关键字</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">该字段不能使用const关键字</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">该字段不能使用readonly关键字</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">字段的数据类型必须能序列化</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">通过查询unity文档可知，以下类型可被序列化：</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">带有[Serializable]属性的自定义非抽象类</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">带有[Serializable]属性的自定义结构体</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">继承自UntiyEngine.Object的对象引用</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">基本数据类型（int,float,double,bool,string等）</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">能序列化的字段数组</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">能序列化的线性表</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">需要重点关注的是，自定义的字典类型数据是不能序列化的，就算定义其为公有或附带[SerializeField]属性。鉴于上述原因，在游戏开发过程中，应避免使用字典进行序列化。</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">说了那么多，让我们来实战一下。</span></div>
<h2 id="examples-%e6%a1%88%e4%be%8b"><strong><span style="font-size: medium;"><span style="color: black;"><span style="font-family: 微软雅黑, sans-serif;">Examples </span></span><span style="font-family: 微软雅黑, sans-serif;">案例</span></span></strong><span style="font-size: medium;"><span style="font-family: 微软雅黑, sans-serif;"><br />
</span></span></h2>
<div align="left"><span style="font-size: medium;">可复制以下代码到C#文件进行调试：</span></div>
<div align="left">
<pre class="pure-highlightjs"><code class="cs">using UnityEngine;public class MyBehaviour : MonoBehaviour
{
    [SerializeField] private int x = 3;
    [SerializeField] private float y = 5.6f;
    public float pi = 3.1415f;
    private int mySecret = 42;
    public static int myStatic = 10;
    public const int myConst = 22;
    public readonly int myReadOnly = 99;
    public int MyProperty { get { return 100; } }
}</code></pre>
</div>
<div align="left"></div>
<div align="left"><span style="font-size: medium;">根据序列化原则可知，当字段含有static, const, readonly关键字或该字段定义为非公有时，不能被序列化，综上所述仅”x,y和pi”能被序列化。这些能被序列化的字段都可在脚本的属性面板进行查看。</span></div>
<div align="left"><span style="font-size: medium;"> <img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-278"  src="https://cdn.vki.cc/wp-content/uploads/2017/09/044950iagkaazzmd4ieaio.png.thumb_.png"  alt=""  width="274"  height="91" ></span></div>
<div align="left"><span style="font-size: medium;">通过对象克隆的方式，可输出并调试非序列化的字段。以下案例将阐述序列化过程中调用Instantiate方法的过程。</span></div>
<div align="left"></div>
<div align="left">
<pre class="pure-highlightjs"><code class="cs">private void Start()
{
   Debug.Log(“Pi: “ + pi + “. MySecret: “ + x+ “. MyStatic: “ + myStatic);// 译者注：MySecret的值引用的x,不知道是否错误，但我改为mySecrte时，2次输出同为42
}private void Update()
{
   if (Input.GetMouseButtonDown(0))
   {
       pi = –4;
       mySecret = –11;
       myStatic = 13;
       GameObject.Instantiate(gameObject);
   }
}</code></pre>
</div>
<div align="left"><span style="font-size: medium;">运行上述程序并点击鼠标左键时，会在场景中引用当前对象并创建第二个对象。由于第二个对象是第一个对象的拷贝，我们是否可以认为第二个对象的值与第一个对象相同？参照输出列表发现，MySecret的值保持不变（没被序列化），而Pi的值改变了（序列化了）。</span></div>
<div align="left"><span style="font-size: medium;"> <img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-279"  src="https://cdn.vki.cc/wp-content/uploads/2017/09/044950v4by6zynpxg95nss.png.thumb_.png"  alt=""  width="226"  height="69" ></span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">鉴于mySecret字段为private且没附带【SerializeField】属性，所以它不能被序列化。（某些场合私有字段可被序列化）。</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">某些场合私有字段可被序列化，这种特殊情况会在【Problems】章节中进行描述。</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;">细心的读者肯定会发现，字段myStatic的值也发生了改变，那是否意味着它也被序列化了。答案是否定的。虽然控制台所输出的值会让我们认为该字段被序列化，但事实上仅仅因为它是静态字段，而静态字段仅属于类，而不属于类实例。如果我们新建一个空的物体【GameObject &gt; Create Empty】并赋予它该脚本时，运行上述程序时，myStatic的值一样为13(没被序列化)。需要注意的是，Pi的值变为原来的值。</span></div>
<div align="left"><span style="font-size: medium;"> </span></div>
<div align="left"><span style="font-size: medium;"><span style="color: #ff0000;"><img  loading="lazy"  decoding="async"  class="alignnone size-full wp-image-280"  src="https://cdn.vki.cc/wp-content/uploads/2017/09/044950d2flygiyl29lgyzl.png.thumb_.png"  alt=""  width="233"  height="105" ></span></span></div>
<blockquote>
<div align="left">序列化的意思是说再次读取Unity时序列化的变量是有值的，不需要你再次去赋值，因为它已经被保存下来。</div>
</blockquote>
<div align="left"></div>
<div align="left">
<h2 id="unity%e5%ba%8f%e5%88%97%e5%8c%96">Unity序列化</h2>
<p>在Unity中，在检视面板中可以看到的，就是被成功序列化了的参数。与序列化相关的常用的关键字有SerializeField，HideInInspector，NonSerialized，Serializable并可以组合使用。</p>
<ul>
<li>SerializeField : 表示变量可被序列化。众所周知，公有变量可以在检视面板中看到并编辑，而私有和保护变量不行。SerializeField与private，protected结合使用可以达到让脚本的变量在检视面板里可视化编辑，同时保持它的私有性的目的。</li>
<li>HideInInspector : 将原本显示在检视面板上的序列化值隐藏起来。</li>
<li>NonSerialized :通过此方法可以将一个公有变量不序列化并且不显示在检视面板中。</li>
<li>Serializable：用在类的前面，表示该类可被序列化。</li>
</ul>
<pre class="pure-highlightjs"><code class="cs">public class Test :Monobehavior
{
    public int  a;                               //序列化，显示
    private int b;                               //不序列化，不显示
    [SerializeField ] int c;                     //序列化，显示
    [HideInInspector] public int d;              //序列化，不显示
    [NonSerialized ] public int e;               //不序列化，不显示
    public Test2 test2;                          //序列化，显示（可序列化的部分）
}

[Serializable ]
public class Test2
{
     public int aa;
     private int bb;
}</code></pre>
</div>
<p><a href="https://vki.cc/greattruth/engine/276/">【转】Unity中的序列化</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vki.cc/greattruth/engine/276/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>Unity学习笔记（不定时更新）</title>
		<link>https://vki.cc/greattruth/engine/258/</link>
					<comments>https://vki.cc/greattruth/engine/258/#comments</comments>
		
		<dc:creator><![CDATA[白露]]></dc:creator>
		<pubDate>Fri, 18 Aug 2017 00:51:57 +0000</pubDate>
				<category><![CDATA[咸鱼心得]]></category>
		<category><![CDATA[引擎相关]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<category><![CDATA[原创]]></category>
		<category><![CDATA[心得]]></category>
		<category><![CDATA[教程]]></category>
		<guid isPermaLink="false">http://www.icemaplen.com/?p=258</guid>

					<description><![CDATA[<p>想到什么写什么，可能有那么一点乱，等我有空了整理下_(:з」∠)_ Mathf.Clamp( A , Min, Max ); 将A的值限定在Min和Max之间。 Input.GetMouseButton(序号); 左 中 右 0   2   1 Input.GetAxis(“&#8230;”); &#&#8230;</p>
<p><a href="https://vki.cc/greattruth/engine/258/">Unity学习笔记（不定时更新）</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></description>
										<content:encoded><![CDATA[<p><span style="color: #999999;">想到什么写什么，可能有那么一点乱，等我有空了整理下_(:з」∠)_</span></p>
<h2 id="mathf-clamp-a-min-max">Mathf.Clamp( A , Min, Max );</h2>
<div>将A的值限定在Min和Max之间。</div>
<div></div>
<h2 id="input-getmousebutton%e5%ba%8f%e5%8f%b7">Input.GetMouseButton(序号);</h2>
<div>左 中 右</div>
<div>0   2   1</div>
<div></div>
<h2 id="input-getaxis">Input.GetAxis(“&#8230;”);</h2>
<div>&#8220;Mouse ScrollWheel&#8221; 鼠标滑轮</div>
<div>&#8220;Mouse X&#8221; 水平轴滑动</div>
<div>&#8220;Mouse Y&#8221; 竖直轴滑动</div>
<div></div>
<h2 id="%e7%bb%95%e7%9d%80%e6%9f%90%e4%b8%80%e7%82%b9%e6%97%8b%e8%bd%ac">绕着某一点旋转</h2>
<div>Transform.RotateAround(Vector3 point, Vector3 axis, float angle);【无返回值】</div>
<div>绕着某一点旋转，第二个参数为旋转的轴，第三个为角度。</div>
<div></div>
<h2 id="%e5%85%b3%e4%ba%8e%e5%90%91%e9%87%8f%e7%9a%84%e5%87%a0%e4%b8%aa%e7%94%a8%e6%b3%95"> 关于向量的几个用法</h2>
<div>vector3.normalized</div>
<div>单位化向量（不改变原向量的值）</div>
<div>vector3.magnitude</div>
<div>求向量的模长</div>
<div></div>
<h2 id="%e6%ac%a7%e6%8b%89%e8%a7%92%e5%92%8c%e5%9b%9b%e5%85%83%e6%95%b0"> 欧拉角和四元数</h2>
<div>transform.eulerAngles 物体的角度,Vector3类型</div>
<div>tranform.rotation Quaternion类型</div>
<div></div>
<div></div>
<div><a href="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard1.png" target="_blank" rel="noopener noreferrer"><img  loading="lazy"  decoding="async"  class="alignnone wp-image-262 size-full"  src="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard1.png"  alt=""  width="655"  height="234"  srcset="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard1.png 655w, https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard1-300x107.png 300w"  sizes="auto, (max-width: 655px) 100vw, 655px" ></a></div>
<p>&nbsp;</p>
<div><a href="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard2.png" target="_blank" rel="noopener noreferrer"><img  loading="lazy"  decoding="async"  class="alignnone wp-image-263 size-full"  src="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard2.png"  alt=""  width="995"  height="560"  srcset="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard2.png 995w, https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard2-300x169.png 300w, https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard2-768x432.png 768w, https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard2-750x422.png 750w"  sizes="auto, (max-width: 995px) 100vw, 995px" ></a></div>
<h2 id="%e5%a6%82%e4%bd%95%e4%bf%ae%e6%94%b9%e9%bc%a0%e6%a0%87%e6%8c%87%e9%92%88">如何修改鼠标指针</h2>
<div>public Texture2D Cursor_Normal;</div>
<div>鼠标图片为Texture2D</div>
<div>【void】Cursor.SetCursor(Texture2D texture, Vector2 hotspot, CursorMode cursorMode);</div>
<h2 id="%e4%b8%96%e7%95%8c%e5%9d%90%e6%a0%87%e8%bd%ac%e5%8c%96%e4%b8%ba%e5%b1%8f%e5%b9%95%e5%9d%90%e6%a0%87">世界坐标转化为屏幕坐标</h2>
<div>
<pre class="pure-highlightjs"><code class="cs">Camera.main.WorldToScreenPoint(transform.position) - new Vector3(Screen.width / 2, Screen.height / 2, 0);</code></pre>
</div>
<div>世界坐标系中间为0；屏幕坐标系左下为0；</div>
<div>所以需要减去一半的屏幕分辨率大小；反之相加。</div>
<div></div>
<h2 id="unity%e9%bb%98%e8%ae%a4%e6%a0%b9%e8%b7%af%e5%be%84%e6%98%af%e5%b7%a5%e7%a8%8b%e6%96%87%e4%bb%b6%e7%9a%84%e7%9b%ae%e5%bd%95%ef%bc%9a">Unity默认根路径是工程文件的目录：</h2>
<div>如读取</div>
<div>xmlDoc.Load(@&#8221;Assets/ObjectsInfo/Objects.xml&#8221;);</div>
<div>不必考虑脚本所在的位置。</div>
<div></div>
<div></div>
<div>遍历并保存Xml文件</div>
<div>XmlDocument xmlDoc = new XmlDocument();</div>
<div>xmlDoc.Load(@&#8221;路径&#8221;);</div>
<div><img  decoding="async"  src="E:/%E6%9C%89%E9%81%93%E4%BA%91%E7%AC%94%E8%AE%B0%E6%9C%AC%E5%9C%B0/qq93CB0B0F7CB83F27C78F17474711D63A/536ba5bd1d3441d5a067e7bc6df85a6b/clipboard.png"  alt=""  data-media-type="image"  data-attr-org-src-id="12872443253545AEBD34FAF46EF51AEF" ><a href="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard3.png" target="_blank" rel="noopener noreferrer"><img  loading="lazy"  decoding="async"  class="alignnone wp-image-264 size-full"  src="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard3.png"  alt=""  width="649"  height="332"  srcset="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard3.png 649w, https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard3-300x153.png 300w"  sizes="auto, (max-width: 649px) 100vw, 649px" ></a></div>
<div></div>
<div>节点的内容：node.InnerText</div>
<div>节点的属性：node.Attributes[0].Value</div>
<div>node.Attributes[1].Value</div>
<div>以此类推</div>
<div></div>
<h2 id="ngui%e7%9a%84tween">NGUI的Tween</h2>
<div>tween.PlayForward(); 顺序播放</div>
<div>tween.PlayReverse(); 倒序播放</div>
<div></div>
<div></div>
<h2 id="%e5%ae%9e%e4%be%8b%e6%a8%a1%e5%bc%8f%e4%b8%bainstance%e8%b5%8b%e5%80%bc%e6%97%b6%e6%9c%80%e5%a5%bd%e5%9c%a8awake%e9%87%8c%e8%bf%9b%e8%a1%8c">实例模式为Instance赋值时最好在Awake()里进行.</h2>
<div>不然调用时可能会发生”object reference not set to an insance“错误。、</div>
<div>不仅为Instance赋值，别的情况也可以这样试试。比如从Xml中读取数据并存储到类里面，有可能会在未存储之前调用这个类，这时便会报错。</div>
<div></div>
<div></div>
<h2 id="ngui%e4%b8%ad%e5%a6%82%e6%9e%9c%e5%ae%9e%e7%8e%b0%e6%9f%90%e4%b8%80sprite%e8%b7%9f%e7%9d%80%e9%bc%a0%e6%a0%87%e6%8b%96%e6%8b%bd">NGUI中如果实现某一Sprite跟着鼠标拖拽</h2>
<p>可以添加一个继承自UIDragDropItem的脚本，不过注意调用基类的Start()和Update()方法.</p>
<div>当释放鼠标时会调用：</div>
<div><img  loading="lazy"  decoding="async"  class="alignnone wp-image-265 size-full"  src="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard4.png"  alt=""  width="624"  height="185"  srcset="https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard4.png 624w, https://cdn.vki.cc/wp-content/uploads/2017/08/clipboard4-300x89.png 300w"  sizes="auto, (max-width: 624px) 100vw, 624px" ></div>
<div>NGUI中判断鼠标是否在UI上面：UICamera.Raycast(Input.mousePosition)</div>
<div>前提，给UI添加Box Collider组件，不然无法检测。</div>
<h2 id="%e4%bd%bf%e7%94%a8resources-load%e5%8a%a0%e8%bd%bd%e8%b5%84%e6%ba%90">使用Resources.Load()加载资源</h2>
<p>首先需要下Asset目录下创建一个名为Resources的文件夹，这个命名是U3D规定的方式，然后把资源文件放进去，</p>
<p>也可以在Resources中再创建子文件夹，当然在代码加载时需要添加相应的资源路径。</p>
<h2 id="%e5%85%b3%e4%ba%8e-serializable">关于 Serializable</h2>
<p>一个对象序列化的接口，一个类只有实现了Serializable接口，它的对象才是可序列化的。因此如果要序列化某些类的对象，这些类就必须实现Serializable接口。而实际上，Serializable是一个空接口，没有什么具体内容，它的目的只是简单的标识一个类的对象可以被序列化。<br />
什么情况下需要序列化<br />
a）当你想把的内存中的对象写入到硬盘的时候；<br />
b）当你想用套接字在网络上传送对象的时候；<br />
c）当你想通过RMI传输对象的时候；<br />
再稍微解释一下:a)比如说你的内存不够用了，那计算机就要将内存里面的一部分对象暂时的保存到硬盘中，等到要用的时候再读入到内存中，硬盘的那部分存储空间就是所谓的虚拟内存。在比如过你要将某个特定的对象保存到文件中，我隔几天在把它拿出来用，那么这时候就要实现Serializable接口；<br />
b)在进行java的Socket编程的时候，你有时候可能要传输某一类的对象，那么也就要实现Serializable接口；最常见的你传输一个字符串，它是JDK里面的类，也实现了Serializable接口，所以可以在网络上传输。<br />
c)如果要通过远程的方法调用（RMI）去调用一个远程对象的方法，如在计算机A中调用另一台计算机B的对象的方法，那么你需要通过JNDI服务获取计算机B目标对象的引用，将对象从B传送到A，就需要实现序列化接口。</p>
<h2 id="%e5%b0%86string%e8%bd%ac%e5%8c%96%e4%b8%baenum">将String转化为Enum</h2>
<p class="title">Enum.Parse()方法，将一个或多个枚举常数的名称或数字值的字符串表示转换成等效的枚举对象。</p>
<p class="title">System.Enum.Parse(Type, String);</p>
<p class="title">System.Enum.Parse(Type, String, Boolean);  最后一个参数指定该操作是否不区分大小写。</p>
<p class="title">eg:</p>
<p class="title">WeaponType type = (WeaponType)System.Enum.Parse(typeof(WeaponType), &#8220;Sword&#8221;);</p>
<h2 id="Htitle" class="detailtitle"><span id="position%e5%92%8clocalposition">position和localposition</span></h2>
<p>1. position是根据世界原点为中心</p>
<p>2. localPosition是根据父节点为中心,如果没有父节点,localpositon和position是没有区别的</p>
<p>3.选中一个物体左上角Global和Local切换看物体世界坐标轴和本地坐标轴</p>
<h2 id="transform-translate%e4%b8%ad%e7%9a%84%e6%9c%ac%e5%9c%b0%e4%b8%8e%e4%b8%96%e7%95%8c%e5%9d%90%e6%a0%87%e7%b3%bb">transform.Translate()中的本地与世界坐标系</h2>
<pre class="pure-highlightjs"><code class="null">transform.Translate(Vector3.forward);
transform.Translate(transform.forward, Space.World);</code></pre>
<p>两个语句效果相同。</p>
<p>transform.Rotate()同理。</p>
<p><a href="https://vki.cc/greattruth/engine/258/">Unity学习笔记（不定时更新）</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vki.cc/greattruth/engine/258/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Unity3D API之Mathf</title>
		<link>https://vki.cc/greattruth/engine/138/</link>
					<comments>https://vki.cc/greattruth/engine/138/#respond</comments>
		
		<dc:creator><![CDATA[白露]]></dc:creator>
		<pubDate>Sun, 18 Jun 2017 03:47:13 +0000</pubDate>
				<category><![CDATA[引擎相关]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Unity]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<category><![CDATA[心得]]></category>
		<category><![CDATA[解析]]></category>
		<guid isPermaLink="false">http://www.icemaplen.com/?p=138</guid>

					<description><![CDATA[<p>一组常用的数学函数。 最近在研究U3D的API，感觉太多了不好记，所以在此做了个整理。 全文基于Unity官方文档，萌新能力不足，如果有错误，欢迎指出_(:з」∠)_ [info]静态变量[/info] PI public static float &#8230;</p>
<p><a href="https://vki.cc/greattruth/engine/138/">Unity3D API之Mathf</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></description>
										<content:encoded><![CDATA[<p>一组常用的数学函数。</p>
<p><span style="color: #999999;">最近在研究U3D的API，感觉太多了不好记，所以在此做了个整理。</span></p>
<p style="text-align: left;"><span style="color: #999999;">全文基于<span style="text-decoration: underline;"><a style="color: #999999; text-decoration: underline;" href="https://docs.unity3d.com/ScriptReference/index.html">Unity官方文档</a></span>，萌新能力不足，如果有错误，欢迎指出_(:з」∠)_</span></p>
<hr />
<p style="text-align: left;">[info]静态变量[/info]</p>
<h2 id="pi" style="text-align: left;">PI</h2>
<p>public static float <span class="sig-kw">PI</span>;【只读】</p>
<p>圆周率的值：3.14159236..</p>
<hr />
<p>[info]静态方法[/info]</p>
<h2 id="abs">Abs</h2>
<p>public static float <span class="sig-kw">Abs</span>(float <span class="sig-kw">f</span>);</p>
<p>求绝对值；</p>
<p>&nbsp;</p>
<p style="text-align: left;">今天写得够多了，先画个饼，明天再写_(:з」∠)_</p>
<p><a href="https://vki.cc/greattruth/engine/138/">Unity3D API之Mathf</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vki.cc/greattruth/engine/138/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Unity3D API之GameObject</title>
		<link>https://vki.cc/greattruth/engine/135/</link>
					<comments>https://vki.cc/greattruth/engine/135/#respond</comments>
		
		<dc:creator><![CDATA[白露]]></dc:creator>
		<pubDate>Sat, 17 Jun 2017 10:26:08 +0000</pubDate>
				<category><![CDATA[引擎相关]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Unity 3D]]></category>
		<category><![CDATA[解析]]></category>
		<guid isPermaLink="false">http://www.icemaplen.com/?p=135</guid>

					<description><![CDATA[<p>在Unity场景中所有实体的基类。 最近在研究U3D的API，感觉太多了不好记，所以在此做了个整理。 全文基于Unity官方文档，萌新能力不足，如果有错误，欢迎指出_(:з」∠)_ [info]变量[/info] activeInHierarchy &#8230;</p>
<p><a href="https://vki.cc/greattruth/engine/135/">Unity3D API之GameObject</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></description>
										<content:encoded><![CDATA[<p>在Unity场景中所有实体的基类。</p>
<p><span style="color: #999999;">最近在研究U3D的API，感觉太多了不好记，所以在此做了个整理。</span></p>
<p style="text-align: left;"><span style="color: #999999;">全文基于<span style="text-decoration: underline;"><a style="color: #999999; text-decoration: underline;" href="https://docs.unity3d.com/ScriptReference/index.html">Unity官方文档</a></span>，萌新能力不足，如果有错误，欢迎指出_(:з」∠)_</span></p>
<hr />
<p style="text-align: center;">[info]变量[/info]</p>
<h2 id="activeinhierarchy" class="heading inherit">activeInHierarchy</h2>
<p>public bool <span class="sig-kw">activeInHierarchy</span>;</p>
<p>返回一个bool值，判断游戏物体是否在程序运行时被激活。</p>
<p><a href="http://i4.piimg.com/591392/6bee84458bdb21f2.png" target="_blank" rel="noopener noreferrer"><img  decoding="async"  src="http://i4.piimg.com/591392/6bee84458bdb21f2.png"  alt="Unity3D API之GameObject" ></a></p>
<p>如果父物体被禁用，那么无论面板中是否勾选上，都将返回false。</p>
<h2 id="activeself" class="heading inherit">activeSelf</h2>
<p>public bool <span class="sig-kw">activeSelf</span>;【只读】</p>
<p>返回一个bool值，判断物体在本地活跃状态，不考虑父物体的状态。</p>
<p>即使返回true，如果父物体没有被启用，那么该物体也不会起作用。</p>
<h2 id="isstatic" class="heading inherit">isStatic</h2>
<p>public bool <span class="sig-kw">isStatic</span>;</p>
<p>返回一个bool值，判断物体是否为静态。</p>
<h2 id="layer" class="heading inherit">layer</h2>
<p>public int <span class="sig-kw">layer</span>;</p>
<p>游戏物体所在的层级，范围在[0,31]。</p>
<p>通常用来使摄像机有选择性的渲染或者忽略射线。</p>
<h2 id="scene" class="heading inherit">scene</h2>
<p>public SceneManagement.Scene <span class="sig-kw">scene</span>;</p>
<p>游戏物体所处的场景。</p>
<h2 id="tag" class="heading inherit">tag</h2>
<p>public string <span class="sig-kw">tag</span>;</p>
<p>游戏物体的标签。常用来区分游戏物体的类别。</p>
<h2 id="transform" class="heading inherit">transform</h2>
<p>public Transform <span class="sig-kw">transform</span>;</p>
<p>游戏物体的transform信息。</p>
<h2 id="name-%e3%80%90%e7%bb%a7%e6%89%bf%e3%80%91%e3%80%90%e7%88%b6%e7%b1%bb%ef%bc%9aobject%e3%80%91">name 【继承】【父类：Object】</h2>
<p>public string <span class="sig-kw">name</span>;</p>
<p>游戏对象的名称。</p>
<p>组件和游戏对象共享的名称。</p>
<hr />
<p style="text-align: center;">[info]构造器[/info]</p>
<div class="signature-CS sig-block">public <span class="sig-kw">GameObject</span>();</div>
<div class="signature-CS sig-block">public <span class="sig-kw">GameObject</span>(string <span class="sig-kw">name</span>);</div>
<div class="signature-CS sig-block">public <span class="sig-kw">GameObject</span>(string <span class="sig-kw">name</span>, params Type[] <span class="sig-kw">components</span>);</div>
<div class="signature-CS sig-block"></div>
<div class="signature-CS sig-block">[kbd]name[/kbd] 创建游戏物体时赋予的名字；</div>
<div class="signature-CS sig-block">[kbd]components[/kbd] 创建游戏物体时添加的组件集合，多个组件之间逗号隔开；</div>
<h2 id="%e6%b3%a8%e6%84%8f%ef%bc%9a" class="signature-CS sig-block">注意：</h2>
<p>创建游戏物体至少且必须会有一个Transform组件；</p>
<pre class="pure-highlightjs"><code class="cs">GameObject player;
player = new GameObject("Player");</code></pre>
<hr />
<p style="text-align: center;">[info] 实例方法[/info]</p>
<h2 id="comparetag" class="heading inherit">CompareTag</h2>
<p>public bool <span class="sig-kw">CompareTag</span>(string <span class="sig-kw">tag</span>);</p>
<p>判断物体的标签是不是[kbd]tag[/kbd]。</p>
<pre class="codeExampleCS">if (other.gameObject.CompareTag("Player"))
            Destroy(other.gameObject);</pre>
<p>（怎么感觉用处不大呢_(:з」∠)_ ）</p>
<h2 id="getcomponent" class="heading inherit">GetComponent</h2>
<p>此方法用于获取游戏物体中第一个符合Type类型的组件。</p>
<p>public T GetComponent&lt;T&gt;();【常用】</p>
<p>[kbd]T[/kbd] 需要检索的组件类型;</p>
<p>public Component <span class="sig-kw">GetComponent</span>(Type <span class="sig-kw">type</span>);</p>
<p>[kbd]type[/kbd] 需要检索的组件类型;</p>
<p>public Component <span class="sig-kw">GetComponent</span>(string <span class="sig-kw">type</span>);</p>
<p>[kbd]type[/kbd] 需要检索的组件名;</p>
<pre class="pure-highlightjs"><code class="cs">Transform transform = GetComponent&lt;Transform&gt;();</code></pre>
<p>使用字符串获取组件的方法可能效率较低，但是适用于从JavaScript中获取C#脚本之类的场合。</p>
<h2 id="getcomponents" class="heading inherit">GetComponents</h2>
<p>public Component[] <span class="sig-kw">GetComponents</span>(Type <span class="sig-kw">type</span>);</p>
<p>作用同上，不过返回的是组件集合。</p>
<p>注意：</p>
<p>在使用该方法时：</p>
<pre class="pure-highlightjs"><code class="cs">Components[] cjs = GetComponents(typeof(Example)) as Component[];   //正确</code></pre>
<p>不可以这样写：</p>
<pre class="pure-highlightjs"><code class="cs">Components[] cjs = GetComponents(typeof(Example)) as Example[];     //错误</code></pre>
<p>因为Example不是Component，而是其子类，建议使用其他泛型方式。</p>
<p>GetComponentsInChildren()同理。</p>
<h2 id="getcomponentinchildren" class="heading inherit">GetComponentInChildren</h2>
<p>获取子物体的组件；</p>
<div class="signature-CS sig-block">public Component <span class="sig-kw">GetComponentInChildren</span>(Type <span class="sig-kw">type</span>);</div>
<div class="signature-CS sig-block">public Component <span class="sig-kw">GetComponentInChildren</span>(Type <span class="sig-kw">type</span>, bool <span class="sig-kw">includeInactive</span>);</div>
<div class="signature-CS sig-block"></div>
<div class="signature-CS sig-block">[kbd]type[/kbd] 需要检索的组件类型;</div>
<div class="signature-CS sig-block">[kbd]includeInactive[/kbd] 是否检索未激活的子物体；</div>
<div class="signature-CS sig-block"></div>
<div class="signature-CS sig-block"></div>
<div class="signature-CS sig-block">其他同GetComponent；</div>
<div class="signature-CS sig-block">
<h2 id="getcomponentsinchildren" class="heading inherit">GetComponentsInChildren</h2>
<p>获取子物体上的指定组件集合。</p>
<p>public Component[] <span class="sig-kw">GetComponentsInChildren</span>(Type <span class="sig-kw">type</span>);</p>
<p>public Component[] <span class="sig-kw">GetComponentsInChildren</span>(Type <span class="sig-kw">type</span>, bool <span class="sig-kw">includeInactive</span>);</p>
<p>同GetComponents和GetComponentInChildren;</p>
<h2 id="getcomponentsinparent" class="heading inherit">GetComponentsInParent</h2>
<div class="signature-CS sig-block">public T[] GetComponentsInParent&lt;T&gt;();<br />
public T[] GetComponentsInParent&lt;T&gt;(bool includeInactive);<br />
public Component[] GetComponentsInParent(Type type, bool includeInactive = false);</div>
<p>获取父物体上指定的组件集合，包括父物体的父物体等等。</p>
<p>[kbd]T[/kbd]，[kbd]type[/kbd] 需要检索的组件类型;</p>
<p>[kbd]includeInactive[/kbd] 是否检索被禁用的组件；</p>
<p>另一个重载方法：</p>
<div class="subsection">
<div class="signature">
<div class="signature-CS sig-block">public void <span class="sig-kw">GetComponentsInParent</span>(bool <span class="sig-kw">includeInactive</span>, List&lt;T&gt; <span class="sig-kw">results</span>);</div>
<div class="signature-CS sig-block">[kbd]results[/kbd] 保存检索到的组件的集合。</div>
<div class="signature-CS sig-block">
<pre class="codeExampleCS">List&lt;HingeJoint&gt; hingeJoints = new List&lt;HingeJoint&gt;();

GetComponentsInParent&lt;HingeJoint&gt;(false, hingeJoints);</pre>
</div>
</div>
</div>
</div>
<div class="clear">
<h2 id="addcomponent" class="heading inherit">AddComponent</h2>
<p>给一个游戏物体添加个组件。</p>
<p>public T <span class="sig-kw">AddComponent&lt;T&gt;</span>(); 【常用】</p>
<p>[kbd]T[/kbd]  需要添加的组件类型;</p>
<p>public Component <span class="sig-kw">AddComponent</span>(Type <span class="sig-kw">componentType</span>);</p>
<p>[kbd]componentType[/kbd] 需要添加的组件类型;</p>
<p>Obsolete public Component <span class="sig-kw">AddComponent</span>(string <span class="sig-kw">className</span>);</p>
<p>[kbd] <span class="sig-kw">className</span>[/kbd] 需要添加的组件名;</p>
</div>
<div class="clear">
<pre class="pure-highlightjs"><code class="cs">SphereCollider sc = gameObject.AddComponent&lt;SphereCollider&gt;() as SphereCollider;
SphereCollider sc = gameObject.AddComponent(typeof(SphereCollider)) as SphereCollider;
SphereCollider sc = gameObject.AddComponent("SphereCollider") as SphereCollider;</code></pre>
<h2 id="setactive" class="heading inherit">SetActive</h2>
<p>public void <span class="sig-kw">SetActive</span>(bool <span class="sig-kw">value</span>);</p>
<p>激活或禁用该对象。</p>
<pre class="pure-highlightjs"><code class="cs">gameObject.SetActive(false);</code></pre>
<p>一个游戏物体可能由于父物体没有激活而没有被激活，这种情况下，调用SetActive()方法将不会使它生效，但是却可以改变他的本地状态，即可以使用activeSelf查看。此时一旦父物体被激活它就会生效。</p>
</div>
<div class="clear"> 如果禁用掉该对象的话将会使它的所有组件生效。</div>
<div class="clear">
<h2 id="sendmessage" class="heading inherit">SendMessage</h2>
<p>public void <span class="sig-kw">SendMessage</span>(string <span class="sig-kw">methodName</span>, object <span class="sig-kw">value</span> = null, SendMessageOptions <span class="sig-kw">options</span> = SendMessageOptions.RequireReceiver);</p>
<p>向一个游戏物体发送消息，调用该物体的所有组件中的目标方法；</p>
<p>[kbd]methodName[/kbd] 需要调用的方法的名字；</p>
<p>[kbd]value[/kbd] 传递给调用方法的参数，可选；</p>
<p>[kbd]options[/kbd] 如果目标游戏物体不存在该方法时是否报错；</p>
<pre class="codeExampleCS">public class ExampleClass : MonoBehaviour {
    void ApplyDamage(float damage) {
        print(damage);
    }
    void Example() {
        gameObject.SendMessage("ApplyDamage", 5.0F);
    }
}</pre>
<p>被调用的方法可以选择是否忽略接收参数 [kbd]object <span class="sig-kw">parameter</span>[/kbd]和消息设置[kbd]SendMessageOptions <span class="sig-kw">options</span>[/kbd] ；</p>
<p>当消息设置为【SendMessageOptions.RequireReceiver】时如果没有一个组件接收到广播的消息的话将会报错。</p>
<p>消息不会发送给未激活的游戏物体（setActive()）；</p>
<h2 id="sendmessageupwards" class="heading inherit">SendMessageUpwards</h2>
<p>public void <span class="sig-kw">SendMessageUpwards</span>(string <span class="sig-kw">methodName</span>, object <span class="sig-kw">value</span> = null, SendMessageOptions<span class="sig-kw">options</span> = SendMessageOptions.RequireReceiver);</p>
</div>
<p>向一个游戏物体发送消息，调用该物体和其父物体的所有组件中的目标方法；</p>
<p>其他同上；</p>
<div class="clear">
<h2 id="broadcastmessage" class="heading inherit">BroadcastMessage</h2>
<p>public void <span class="sig-kw">BroadcastMessage</span>(string <span class="sig-kw">methodName</span>, object <span class="sig-kw">parameter</span> = null, SendMessageOptions <span class="sig-kw">options</span> = SendMessageOptions.RequireReceiver);</p>
<p>广播消息，调用该游戏物体和其所有子物体身上方法名为[kbd]methodName[/kbd]的方法；</p>
<pre class="codeExampleCS">public class ExampleClass : MonoBehaviour {
    void ApplyDamage(float damage) {
        print(damage);
    }
    void Example() {
        gameObject.BroadcastMessage("ApplyDamage", 5.0F);
    }</pre>
<p>被调用的方法可以选择是否忽略接收参数 [kbd]object <span class="sig-kw">parameter</span>[/kbd]和消息设置[kbd]SendMessageOptions <span class="sig-kw">options</span>[/kbd] ；</p>
<p>当消息设置为【SendMessageOptions.RequireReceiver】时如果没有一个组件接收到广播的消息的话将会报错。</p>
<p class="heading inherit" style="text-align: center;">[info] 静态方法[/info]</p>
<h2 id="createprimitive" class="heading inherit">CreatePrimitive</h2>
<div class="subsection">
<div class="signature">
<div class="signature-CS sig-block">public static GameObject <span class="sig-kw">CreatePrimitive</span>(PrimitiveType <span class="sig-kw">type</span>);</div>
<div class="signature-CS sig-block">创建一个带有原始渲染器和碰撞器的游戏物体。</div>
</div>
</div>
<div class="subsection">
<p>[kbd]type[/kbd] 需要创建的游戏物体类型；</p>
<p>[successbox title=&#8221;PrimitiveType&#8221;]Sphere，Capsule，Cylinder， Cube，Plane，Quad[/successbox]</p>
<h2 id="find" class="heading inherit">Find</h2>
<p>public static GameObject <span class="sig-kw">Find</span>(string <span class="sig-kw">name</span>);</p>
<p>通过[kbd]name[/kbd]查找游戏物体并返回该游戏对象。</p>
<pre class="pure-highlightjs"><code class="cs">public class ExampleClass : MonoBehaviour {
    public GameObject hand;
    void Example() {
        hand = GameObject.Find("Hand");
        hand = GameObject.Find("/Hand");
        hand = GameObject.Find("/Monster/Arm/Hand");
        hand = GameObject.Find("Monster/Arm/Hand");
    }
}</code></pre>
<p>这个方法只会查找已启用的游戏对象，如果找不到就返回【null】；</p>
<p>如果name中包含&#8217;/&#8217;，将会在层级面板中像查看目录那样寻找；</p>
<p>因为比较占用资源，所以不建议每帧都调用Find()方法。可以在Start()总调用，或者使用FIndWithTag来代替；</p>
<h2 id="findwithtag" class="heading inherit">FindWithTag</h2>
<div class="subsection">
<div class="signature">
<div class="signature-CS sig-block">public static GameObject <span class="sig-kw">FindWithTag</span>(string <span class="sig-kw">tag</span>);</div>
</div>
</div>
<div class="subsection">
<p>通过[kbd]tag[/kbd]标签查找游戏物体并返回该游戏对象。</p>
<p>这个方法只会查找已启用的游戏对象，如果找不到就返回【null】；</p>
<p>在使用标签之前一定要在标签管理器中声明；</p>
<h2 id="findgameobjectswithtag" class="heading inherit">FindGameObjectsWithTag</h2>
<p>通过[kbd]tag[/kbd]标签查找游戏物体集合。</p>
<p>这个方法只会查找已启用的游戏对象，如果找不到就返回空集合；</p>
<p>如果标签不存在，字符串为空或者null，将抛出异常；</p>
<h2 id="destroy-%e3%80%90%e7%bb%a7%e6%89%bf%e3%80%91%e3%80%90%e7%88%b6%e7%b1%bb%ef%bc%9aobjective%e3%80%91" class="heading inherit">Destroy 【继承】【父类：Objective】</h2>
<p>public static void <span class="sig-kw">Destroy</span>(Object <span class="sig-kw">obj</span>);</p>
<p>public static void <span class="sig-kw">Destroy</span>(Object <span class="sig-kw">obj</span>, float <span class="sig-kw">t</span> = 0.0F);</p>
<p>移除一个游戏物体或组件。</p>
<p>[kbd]obj[/kbd] 要销毁的游戏对象；</p>
<p>[kbd]t[/kbd] 延迟销毁的时间，单位为秒；</p>
<p>实际销毁的时间在当前循环之后，下次渲染之前如果需要立即销毁，使用DestroImmediately()；</p>
<h2 id="destroyimmediate-%e3%80%90%e7%bb%a7%e6%89%bf%e3%80%91%e3%80%90%e7%88%b6%e7%b1%bb%ef%bc%9aobjective%e3%80%91" class="heading inherit">DestroyImmediate 【继承】【父类：Objective】</h2>
<p>public static void <span class="sig-kw">DestroyImmediate</span>(Object <span class="sig-kw">obj</span>, bool <span class="sig-kw">allowDestroyingAssets</span> = false);</p>
<p>立即销毁一个游戏对象或组件。</p>
<p>[kbd]allowDestroyingAssets[/kbd] 是否允许assers也被销毁；</p>
<p>可能会发生不可预知的错误，所以如果非特殊需要，建议使用Destroy()；</p>
<h2 id="dontdestroyonload%e3%80%90%e7%bb%a7%e6%89%bf%e3%80%91%e3%80%90%e7%88%b6%e7%b1%bb%ef%bc%9aobjective%e3%80%91" class="heading inherit">DontDestroyOnLoad【继承】【父类：Objective】</h2>
<p>public static void <span class="sig-kw">DontDestroyOnLoad</span>(Object <span class="sig-kw">target</span>);</p>
<p>使物体不要在加载新的游戏场景时销毁。</p>
<pre class="codeExampleCS">public class ExampleClass : MonoBehaviour {
    void Awake() {
        DontDestroyOnLoad(transform.gameObject);
    }
}</pre>
<p>以为Unity总是在加载新的游戏场景时总会销毁旧场景的所有物体，所有才有了此方法。。。</p>
<p>在Awake()中使用；</p>
<p>如果是游戏物体或组件的话它的Transform信息也将被保留；</p>
<blockquote><p> 不知不觉竟然写了五千多字了。。</p>
<p>脑阔痛 _(:з」∠)_</p></blockquote>
<h2 id="instantiate-%e3%80%90%e7%bb%a7%e6%89%bf%e3%80%91%e3%80%90%e7%88%b6%e7%b1%bb%ef%bc%9aobjective%e3%80%91" class="heading inherit">Instantiate 【继承】【父类：Objective】</h2>
<div class="signature-CS sig-block">public static Object <span class="sig-kw">Instantiate</span>(Object <span class="sig-kw">original</span>);</div>
<div class="signature-CS sig-block">public static Object <span class="sig-kw">Instantiate</span>(Object <span class="sig-kw">original</span>, Transform <span class="sig-kw">parent</span>);</div>
<div class="signature-CS sig-block">public static Object <span class="sig-kw">Instantiate</span>(Objec t<span class="sig-kw">original</span>, Transform <span class="sig-kw">parent</span>, bool <span class="sig-kw">instantiateInWorldSpace</span>);</div>
<div class="signature-CS sig-block">public static Object <span class="sig-kw">Instantiate</span>(Object <span class="sig-kw">original</span>, Vector3 <span class="sig-kw">position</span>, Quaternion <span class="sig-kw">rotation</span>);</div>
<div class="signature-CS sig-block">public static Object <span class="sig-kw">Instantiate</span>(Object <span class="sig-kw">original</span>, Vector3 <span class="sig-kw">position</span>, Quaternion <span class="sig-kw">rotation</span>, Transform <span class="sig-kw">parent</span>);</div>
</div>
</div>
</div>
<div class="signature-CS sig-block">实例化一个游戏对象并返回该对象。</div>
<div class="signature-CS sig-block"><span class="sig-kw">[kbd]original[/kbd] 需要实例化的游戏对象，常是预制体；</span></div>
<div class="signature-CS sig-block">[kbd]parent[/kbd] 父物体的Transform（如果需要制定父物体的话）；</div>
<div class="signature-CS sig-block">[kbd]instantiateInWorldSpace[/kbd] 如果指定了父物体，需要相对于父物体来确定新物体的所在位置的话，就设为【false】；反之如果要保留新物体本身在世界坐标系的位置信息，就设为【true】；</div>
<div class="signature-CS sig-block">[kbd]position[/kbd] 新游戏对象的位置；</div>
<div class="signature-CS sig-block">[kbd]rotation[/kbd] 新游戏对象的旋转信息；</div>
<div class="signature-CS sig-block">
<pre class="pure-highlightjs"><code class="cs">Instantiate(prefab, new Vector3(i * 2.0F, 0, 0), Quaternion.identity);</code></pre>
<p>新游戏物体的子物体也会跟着实  【父类：Objective】</p>
<p>public static Object <span class="sig-kw">FindObjectOfType</span>(Type <span class="sig-kw">type</span>);</p>
</div>
<p>查找指定类型的对象。</p>
<pre class="pure-highlightjs"><code class="cs">GUITexture texture = (GUITexture)FindObjectOfType(typeof(GUITexture));</code></pre>
<p>返回第一个找到的；</p>
<p>该方法效率较低，不建议每帧都调用；</p>
<h2 id="findobjectsoftype-%e3%80%90%e7%bb%a7%e6%89%bf%e3%80%91%e3%80%90%e7%88%b6%e7%b1%bb%ef%bc%9aobjective%e3%80%91" class="heading inherit">FindObjectsOfType 【继承】【父类：Objective】</h2>
<p>public static Object[] <span class="sig-kw">FindObjectsOfType</span>(Type <span class="sig-kw">type</span>);</p>
<p>查找指定类型的对象集合。</p>
<p>其他同上；</p>
<p style="text-align: center;">[info]操作符[/info]</p>
<h2 id="bool" style="text-align: left;">bool</h2>
<p>描述游戏物体是否存在。</p>
<pre class="codeExampleCS">public class ExampleClass : MonoBehaviour {
    void Example() {
        if (rigidbody)
            Debug.Log("Rigidbody attached to this transform");
        
    }
}</pre>
<hr />
<p style="text-align: center;"><span style="color: #999999;">完</span></p>
<p><a href="https://vki.cc/greattruth/engine/135/">Unity3D API之GameObject</a>最先出现在<a href="https://vki.cc">初晴神社</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://vki.cc/greattruth/engine/135/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
