Unity3D官方教程爬坑

全是在学官教时遇到的坑,然后数小时后爬出来.同时会添加到处学来的的Unity技巧

----------------------------------------------------------

代码:

1.使游戏对象运动的N种方式

更全面的移动方式参考

1、rigidbody.addforce(Vector3 * speed) (见roll-a-ball)

2、rigidbody.velocity(vector3 * speed);(见space shooter,改变位置向量,非常的生硬)


3、rigidbody.MovePositon(vector 3) & rigidbody.MoveRotation(quaternion)(包含移动和转向,细腻,常用。见survival shooter player的移动)(转向包括光标指向转向,和键盘输入转向(见Tanks!))

4、transform.translate(方向 * 速度 * Time.deltatime)

见survival shooter内敌人被消灭后下沉并回收

MoveTowards vs. Lerp vs. Slerp vs. SmoothDamp

2.镜头跟随移动游戏对象移动,脚本内用LateUpdate()而非FixedUpdate()(见roll-a-balll)

3.Random.Range(min,max),如果两个数都是float则前后都算,如果两个数是int则包前不包后

4.FindObjectOfType<Inventory>()  vs  GetComponent<Inventory>()

FindObjectOfType①为外部调用,在所有场景和游戏对象里找,不是很快;通常放在Start()内。

GetComponent②为内部调用,只在挂着该脚本的游戏对象上的其他组件找,他们都在一个inspector里,比如rigidbody,renderer,collider等。

②替代①的方式是给脚本所在的对象选择tag,再用【FindGameObjectWithTag("tag的名字“).GetComponent<脚本>()】放入Awake()内。

也可以直接 在脚本开头public Inventory inventory; 然后在inspecotor界面把挂着Inventory脚本的游戏对象拖入框。[Adventure Game]

5.Debug

在space shooter中,行星在游戏界面内存在,运行尝试是否子弹能消除时发现行星不见了,这时候在行星的脚本里加了一段“Debug.Log(other.name)”把将行星摧毁的物体的名称发送到了unity的console内。

6.coroutine

在土豆视频内spaceshoot官方教程中行星波生成里解释的很清楚(因为有中文字幕)。coroutine就是等某一段或几段设定好的时间后循环方法内的代码。

调用这种异步(即有时间间隔)的方法要用语句 startCoroutine (方法()); 。含异步的方法要用IEnumerator来代替void,yield return new WaitForSecond(设定好的时间);是指等这段时间后继续循环,写在for语句内表示等N秒后i++,写在循环前表示等N秒后开始while循环(把for循环放入while循环内,判断条件可以按需求写,在 space shooter里想要的是行星不停出直到飞船被毁为止,所以判断条件写的是true(意思是true就是true,一直循环),再在while循环的末尾加上for循环的间隔)。

关于yield return,这篇文章就说的很清楚了:http://www.cnblogs.com/wangchengfeng/p/3724377.html

7.游戏对象的回收(包括落下的行星,行星被射击时的爆炸效果)

在space shooter内行星和飞行的子弹靠的是外置一个boundary(cube,box collider)并用脚本(onTriggerExit)来回收游戏对象。

但行星的爆炸特效并不与boundary碰撞,所以会冗余。在所有爆炸特效下挂载脚本在void start内用Destroy(gameObject, 设定的时间);语句使每帧检测超过设定的时间后被挂载的游戏对象销毁,在survival shooter内对敌人的回收也是如此(先下沉,下沉N秒后摧毁)。

8.unity内脚本的实例化关系

见space shooter内计分板的讲解,即在脚本内写一个public的方法,要在其他脚本内调用要先指定是要调用脚本的哪个实例(即使在只有一个实例的情况下)。

9.Input.GetAxisRaw(); vs Input.GetAxis ();

Raw是指非平滑输入,即输入值只有-1,0,1(左,无输入,右)。这种输入的作用让角色单位输入变小,在操作感官上更有灵敏性,角色反应更快更流畅。(见survival shooter内Player的移动)


10.Time.time vs Time.deltaTime

Time.time是游戏从开始到此刻的持续时间

Time.deltaTime是游戏上一帧的持续时间(增量时间),每一帧完成的秒数都不同,所以在需要固定增量时(比如每秒移动10,每0.5秒攻击一次),要在数值上乘以Time.deltaTime(即单位),否则将变成(每帧移动10,每帧攻击2次)

11.在脚本实例(A)内引用其他脚本实例(B)内方法

【】如果A和B脚本实例都挂在同一对象上(比如survival shooter的敌人上同时挂载Enemy Health和Enemy Attack),则在A内private EnemyAttack enemyAttack;
然后在Awake()内  enemyAttack = GetComponent<EnemyAttack> ();就可以直接调用了。

【】如果A和B在不同对象上(比如survival shooter的Enmey Attack和Player Health)则在A内private PlayerHealth playerHealth;

然后在Awake()内先要player = GameObject.FindGameObjectWithTag<"Player">();找到挂B脚本的对象(该对象必须添加“Player”的Tag)。

然后再playerHealth = player.GetComponent<PlayerHealth>();,才可调用。

如果是在场景里的GameObject上挂的脚本则可直接Public GameObject xx; 然后在Inspector里拖入。但如果是存成Prefab的的游戏对象上挂的脚本,引用方式必须是上面通过Tag寻找,而且要注意脚本加载顺序找不到引用报错。

还有一种见Adventure Game(仅用于Editor继承),下面的target是Editor特有的字段,表示该Editor的对象,第二个红框里的句子只是把target转换成了ConditionCollection类型,在这之前target仅仅是个Object类型不明

【】如果B在A的子对象上(比如survival shooter的PlayerShooting挂在游戏对象Player的子对象GunBarrelEnd上),在A内引用B的则private PlayerShooting playerShooting;

然后在Awake内playerShooting = GetComponentInChildren<PlayerShooting>();

【】还有一种情况,玩家开枪射击敌人,使敌人生命值降低。player下的游戏对象枪上所挂的脚本PlayerShooting要引用某个敌人上的EnemyHealth来调用生命值降低方法。

则以射线碰撞Raycast,撞到层为“shootable”后返回碰撞点信息,在信息点上再找其脚本实例。(见survival shoot的playershooting脚本)

【】如果一个变量声明方式为public static xx(类型) xx(名称),则在其他脚本内调用不用先声明上面的那一套,直接使用就是。(一般用于分数等不可改元素)

【】游戏内的GameController,SoundController,DataBase等都可以直接在场景里建同名空对象,挂上对应的脚本,设置他们用单例在Awake里加载比较不容易出错。特别是在不同对象在不同场景里无法拖拽引用的情况(见Quiz Game)

【】上面说到trigger可以探测是否挂载特定脚本(EnemyHealth)来判断是否是指定对象(Enemy)。

比如在GameGrind装备系统教程里装备叠加方法中,就用到指定格子下装备上的脚本

那如果要更新该装备下的Text呢,则是该脚本.transform就指代该脚本所在的游戏对象。


12.脚本头的“using ...”(见2D Roguelike 4内BoardManager蛮牛)

using System; 这样就可以在脚本里使用Serializable属性。Serializable可以让变量在Inspector里展开或收起。

using System.Collections.Generic;,这样可以使用List

using Random = UnityEngine.Random; 因为系统和unity引擎都有 Random的命名空间。

using UnityEngine.EventSystem; 为了使用Eventsystem的功能,比如在背包拖拽装备(见装备系统)

using System.IO; 为了查找加载文件,比如LitJson(见装备系统)

13.将脚本里的Public属性隐藏,或显示Private属性

有时一些Public属性我们需要在其他脚本调用,但已经调整好了,不想再Inspector内显示

可以在脚本内该属性的上一行加上【HideInInspector】该属性将不会再Inspector面板内显示

显示private属性则在属性上方加上【SerializeField】。

如果不想加语句直接想看到一个脚本内的所有变量并调试,Unity有Debug模式,会显示该游戏对象的所有隐藏组件,包括其脚本的所有属性。Inspector面板右上角选择Debug就好了。

14.脚本内代码分块

有时候代码很长,想分块代码并收起以方便查看,可在想收起的代码块上一行写  #region 代码块名称,结尾写#endregion。

15.for,switch循环和while,if等自动补全代码格式

比如for循环 for(int i =0; i <`````),可以打下for后按两下Tab键系统自动补齐格式

16.脚本内引用工程项目内文件的路径变动问题

在装备系统教程里,我们引用了记录了装备信息Json的文件,如果打包游戏的话会发现游戏无法正常读取该文件,是因为随着打包文件,Json文件的路径也会变化,这时候把该文件放在一个Unity规定的特定文件夹,并用其他语句引用。

具体参见Unity Manual:Streaming Assets页面

17.脚本内注释每个字段并在unity Inspector上悬停显示字段

参数字段太多了不知道什么意思,在声明句上加上[Tooltip(“XX”)],在unity内鼠标停在该属性上出现注释

18.让Unity 内的Button变灰不能摁

用Button.Interactable = false;

19.代码内引用其他GameObject的方法(Find & FindWithTag)

Unity里有3种引用方式

Find 和 FindWithTag都需要该GameObject必须时active的。

1.比如点击Button弹出一个界面,这个界面在平时是隐藏的。

操作方法是:在Unity里该界面Active,然后在Start()或Awake()里用Find或FindWithTag找到然后再SetActive(false),然后就可以使用了。

Find是在所有Active的游戏对象里找,FindWithTag是在所有标签对象里找,所以FindWithTag效率更高,官方不建议在Update()里使用Find因为太耗性能。

2.再比如经常要检测其他对象,比如trigger里的是Enemy还是其他的东西。

这时候除了给Enemy标上Tag,检测other.tag == "Enemy"之外,还有一种方法是if(!other.GetComponent<EnemyHealth>())通过检测trigger物上有没有指定脚本来判断是否是制定物。

20.脚本内比较字符串大小

可直接使用if(str1 == str2)或 if(str1.Equals(str2)) 

注意string是区分大小写的,我在比较后List元素Add,不停跳出索引有问题的Bug。花了2个半小时才找到原来是str1的首字母时大写的,str2的首字母小写,结果全是false导致没有任何元素添加进List。

21.List清除元素/查找元素/查看是否包含元素

List.Clear(); 清除List内的所有元素,保持List的基本属性(比如List<Enemy> enemy清空后没有元素,但属性仍然是<Enemy>)。

List.Remove(xxx); 清除xxx表达式满足的所有元素,比如删除一个List<int>内为偶数的所有元素:

参考:http://blog.csdn.net/yl2isoft/article/details/17059093

参考:https://msdn.microsoft.com/en-us/library/wdka673a(v=vs.110).aspx

List.Find(xx)

如果找到该语句要求的元素则返回该元素,如果没找到则返回的是该元素类型的默认值,而不是null。参考

List.Contains()

如果找到返回true,其他情况返回false。参考

List.FindIndex(xx)

如果找到该语句要求的元素则返回该元素的的索引,否则返回-1。参考

List的用法 参考

22. console提示:NullReferenceException: Object reference not set to an instance of an object

意思为没有引用.

一种可能是该脚本A引用条目本体所在的脚本B,的执行速度要快,所以造成没有引用。这时候调整脚本执行顺序就好。

另一种可能是该Object本体就在该脚本,那么在脚本初始声明该Object时没有初始化。

(比如把PlayerData playerData = new PlayerData()里后面的初始化语句忘了就会出现上述BUG)

还有一种可能是Prefab在面板上未Apply,比如Prefab GameManager要拖拽引用 DataManager,DataManager必须也存成Prefab,然后把作为Prefab的DataManager拖入才算是引用成功。如果在Hierarchy下的DataManager新增了脚本却忘记Apply,则Prefab DataManager没有挂载新脚本,GameManager在运行时就找不到该脚本而报错。

23.Destory DontDestoryOnLoad GameObject

GameManager通常是DontDestoryOnLoad的,比如Roguelike里就一直存在。那如果想从某一场景切换到另一场景时会发现原先场景的GameManager还是存在,这时候要删除该GameManager GameObject有两种方式:

参考

1.

2.

不过图中的处理不是太好,应该在GameManager 对象所挂的脚本上,写入上面的代理。而代理的启用&取消通常在OnEnable() & OnDisable()里,代理必须取消,否则将导致内存泄漏。

关于delegates和C#内Events的说明见Adventure Game教程。教程

24.Unity内的双击

using UnityEngine;  
using UnityEngine.UI;  
using UnityEngine.EventSystems;  
  
public class MJCard : MonoBehaviour,IPointerClickHandler {  
  
    float lastClickTime;  //不要申明在方法内
 
    public void OnPointerClick(PointerEventData eventData)  
    {    
        if (Time.time - lastClickTime < 0.2)  
        {  
            Debug.log("双击");  
        }  
       lastClickTime = Time.time;  
    }

25.点击框外区域关闭对话框(Popup)

要点击对话框Child外区域关闭Child的最简单办法:新建一个Panel命名为Parent,拉伸到全屏,设为透明,把child拉为子对象。然后在该Parent上挂脚本

点击透明Panel就会关闭子对象。

26.物体抛物线移动

27.怎样修改Image的alpha

不可以直接image.color.a进行修改,会提示无法转换,必须中转一下。

28.怎样使对象在移动时转向(比如在2D里)

一般向左向右都是改scale,比如原本向右的改为向左就把scale.x改为-1,移动的时候改transform.localscale。

但这一项不可以直接修改,而是要像image.color.a一样中转一下。

参考:https://www.youtube.com/watch?v=e7I315b74HY

29.怎样平滑的在N秒内填充slider

30.用MD5加密资料的方法

参考来源

31.Unity中渐隐/闪烁/淡出的实现

参考(渐隐/闪烁)

淡出

32.Unity内加载(Load)资源

比如加载image的对象Sprite,一般我们的资源都放在Resourses文件夹(注意,一定是复数形式),用Resources.Load<你要加载的形式,比如Sprite>(“该文件在Resources文件夹下的路径”)就好了。

官方API 额外的参考 打包时的资源加载问题

33.Unity修改transform.rotation的两种方法

transform.localPosition和transform.localScale都是直接赋值三元数,给旋转赋值需要用 
  方法一: 
  xxx.transform.localEulerAngles = new Vector3 (0.0f,0.0f,0.0f); 
  方法二: 
   xxx.transform.rotation=Quaternion.Euler(0.0f,0.0f,0.0f);
参考

34.Json内中文为解析后为乱码的解决

json文件一般都是用记事本打开的,打开后另存为选择编码方式为UTF-8保存并覆盖就可以显示了。参考

35.Unity点击鼠标移动2d对象并播放移动动画

移动

动画播放

两个方法在FixedUpdate内执行就好。

注意先把对象的世界坐标转换,计算偏移量后再换回。

还有就是应使用GetMouseButton() 而非GetMouseButtonDown(),因为如果鼠标长按而不是点击的话GetMouseButtonDown()在之后帧都返回false。

36.Unity内的数据保存路径

参考来源

37.引用其他脚本内函数避开次次实例化的方法

① roguelike官教里的fightmanager方法

② 和第一种很像,使用T.GetInstance().xxxxxx来使用

③ 一次性读取数据(不需要写入的情况),然后直接调用

38.Unity内拖拽UI和物体

参考

① 拖拽overlay模式下的ui

② 拖拽世界坐标/camera模式下的UI元素

还有在鼠标点显示信息框等也是先把Input.mouseposition用上面的方法转换后再定位。

悬停框所在的像素显示之前在overlay模式下设置的是100,在camera模式下会很模糊,改为小数(比如1或者2)。

③ 拖拽3d物体

见上面参考链接

39.UI元素显示在最上

overlay永远存在于最上(离屏幕最近),多个overlay的层级取决于sort layer。sort layer越大越上。参考

camera取决于plane distance(canvas所在平面离摄像机的距离,可存在于其他gameobject后),sorting layer(多个camera模式的canvas用此排序),order in layer(多个canvas在同一sorting layer时的排序)。

平常的overlay canvas想暂时在camera canvas后显示时,可直接gameobject.setActive(false),之后再设置为true。

overlay模式下的joystick则不可以,等setactive true后因为要注册horizontal和vertical导致joystick不能用。暂时的方式是先把该joystick设置为camera并指定camera。之后恢复为overlay模式。

40.移动端触屏修改

使用官方joystick组件的(比如player移动)则在电脑端移动端都可使用。

电脑端的点击,双击,拖拽等事件在移动端依旧可以使用(电脑端的左键相当于移动端的触摸点击)。

长按则可利用IPointerDownHandler 和 IPointerUpHandler 参考

41.ios获得设备标识码(UDID)

自己机器的UDID可以通过连接iTunes获得,但代码SystemInfo.deviceUniqueIdentifier 在ios7之后获得的是UIDevice identifierForVendor(unity API)。参考链接

所以单机使用该条就够了,联机则参考

42.在游戏内鼠标绘制一条线并添加碰撞器,即拯救狗头里的画线功能

参考

43.

Unity:

1.无法创建新项目,重启Unity,或者重新登录Unity账号。

2.打包发布时,Build Settings 提示”Because you are not a member of this project this build will not access Unity services.”,重启Unity,或者重新登录Unity账号。

3.2D游戏更改整体背景大小,不要设置背景的Scale,设置摄像机的Size。

4.Console提示

保存了脚本回到unity发现提示“There are inconsistent line endings in the 'Assets/Scripts/CameraController.cs' script. Some are Mac OS X (UNIX) and some are Windows.”?,点击VS下File→Advanced Save Options→Line Endings选择Windows(CR LF),确定后再保存一遍OK了。

或者在VS内先关闭这个script,再在File下“最近使用过的文件”打开该script,VS会跳出对话框,YES后再保存一遍就好。

5.碰撞器(Collider)判断

是否有接触的条件是两方都有碰撞器,且至少一方有rigidbody组件。如果任何一方勾选了Is Trigger(勾选这个的是被碰撞对象,比如小方块被碰撞后消失,则勾选小方块,而不是小球),可触发检测是否进入碰撞范围,并按脚本对应表现。所以双方都没勾选触发,可碰撞,不可有其他交互。

6.盒子内的碰撞

要一个平面上的球不滚出平面,直接为平面加Box Collider是不可行的,球滚到边缘会直接粘到平面外缘不动了。自身多个碰撞器重叠如果有一个以上未勾选Istrigger会把重叠部分处理成一体。所以要在平面四条边放四个条状碰撞器粘成一个框状的。[2D  UFO]

7.2d模式下所有动的游戏对象(即使只是旋转,不移动)也要添加rigidbody2D

不然尽管挂上脚本不添加rigidbody也可以移动,但是unity每一帧都会重新定位加载计算该对象,会对性能产生极大损耗。[2D UFO]

8.Rigidbody.isKinematic

在脚本和rigidbody组件内选项使用。对象选择Kinematic后,碰撞、力、关节不再对对象产生影响。该对象的移动或运动将完全由Animation(动画)控制或者脚本编辑对象的位置改变来控制。(2D Roguelike,不想player满场乱飞,就是一步一移动,所以用这个。之前的SpaceShooter,RollABall等没有勾选此选项,即默认的Dynamic。Static是将对象设为像背景一样的物件,不可移动不可受力,但是可以和其他dynamic物体碰撞)

9.unity中的sprite(精灵)

unity2D游戏中的所有对象都叫精灵(比如2D Roguelike中的Player,Enemy,以及Floor这些不动的元素),精灵每个都用Sprite Renderer而不是Mesh Renderer。

10.Layer vs Tag

tag是为了对object分类,通常用于脚本(GameObject.FindWithTag())来快速搜索对象。Layer用于区分摄像机的渲染&射线投射对象,灯光的特定照射和物体的碰撞等。Layer虽然可以自己添加并命名,但layer在系统内是以编号区分的,所以layer的属性是int。(比如 int blockingLayer)。sorting layer在Sprite Renderer选项内,因为2D物体是可以覆盖的,所以Sorting Layer最底层的最先渲染,处于场景的最上方。

11.UNITY里的文本

unity的文本层和游戏层不同,游戏层以像素计数,文本层以比例计数,左下角为(0,0),右上角为(1,1),所以要把文本放在左上角只要更改position为(0,1,0)。

要是想给文本留些空隙而不是死贴着边框,在pixel offset里调整(x,y)的像素相对移动(见space shooter内文本的设置)

12.Animation组件内Parameters trigger vs bool

动画状态转换的参数有四种类型:int,float,bool,trigger。前三种都很好理解,第四种是一次性的bool,比如人物死亡触发trigger,发呆和行走转换用bool。

比如SurvivalShooter里人物行走用bool来转换

像攻击比如Roguelike里的Chop和Hit就用trigger来转换。NPC释放一次性动画用Trigger。

13.Unity里快速查找Component讲解

   不用在浏览器内打开官网再输入查询,直接点组件右上角的小书图标。

14.场景搭建时用Snap Setting

比如一排围墙,普通用Duplicate,然后手动一点一点挪(比如roll-a-ball),要对齐及其痛苦。我们可以在上方工具栏Edit→Snap Setting里设置好移动单位,移动下一个Duplicate Object时按住Ctrl键同时移动,就可以设置好的单位轻松移好。选定一堆小方块,然后摁Snap All Axes就会自动帮排列整齐(像Word里的对齐)。

15.锁定Inspector面板方便拖拽对象或属性

 Unity经常需要确定组件内引用的是哪个对象,我们常在Hierarchy或Project下找到对象然后拖进栏内,但有时文件太多,点击到对象Inspector直接显示该对象的组件群,而不是我们需要拖拽的组件群。这时先把Inspector锁住,再开始查找,拖拽就很方便了。

16.Unity Color取色

在选择如背景Color时,点击小滴管可以取色,不仅可以取Unity Scene窗口里的颜色,也可以取其他颜色,比如一幅网上图取色,我们把浏览器和Unity并行放置,点击取色然后点击图片上需要的颜色就可以了。

17.Unity工程2D和3D模式的区别

unity其实不存在2D或3D的区别,只是摄像机是Orthographic或Perspective的区别。正交模式下镜头没有Z轴就成了2D模式。

具体区别:

2D:

镜头为Orthographic;

Scene面板为2Dmode;

Windows→Lighting→Setting里Skybox为None,AmbientSource为color,Realtime Lighting和Mixed Lighting都取消GI勾选。

3D:

镜头为Perspective;

Scene面板为3Dmode;

Skybox为Default,AmibientSource为Skybox,两个选项都勾选。

关于镜头选择模式,像素型的素材,如果在调整了sprite各种选项后,依然被压缩到高糊状态,尝试把镜头模式换为perspective,再次运行后就发现OK啦。

18.Unity内脚本加载顺序

Edit→Project Settings→Script execution Order里可以设置各脚本的执行顺序和指定多少时间后该脚本开始加载。

为了防止这种BUG:脚本引用json数据,添加json数据List脚本还没加载完,搜索数据并执行其他方法的脚本已经开始运行了。

包括GameController,DataBase等需要提前加载的脚本可放到前面。

19.Unity内image/button等上面叠加序列帧动画

比如在场景切换时一般就显示一个黑图做幕布的效果(比如2DRougelike里的level升级时的Day N),如果想要在这块黑布上再播放动画,把动画拖入Canvas或给黑布Image下加Animator都是没有用的。

比如UICanvas下有一个UIImage为黑色,UIImage下有一个UIText用来显示Day 1.现在要再UIImage上显示帧动画。则再UIImage下再新建一个子Image,比如命名为AnimationImage,然后再选中AnimationImage的情况下,打开Animation窗口,点击creat,选好名字和文件夹,新建好动画后,把序列帧动画包含的sprite全部拖入Animation窗口,调整下播放速度就可以了。

参考:http://blog.csdn.net/mynameiszhuli/article/details/77951668

20.在NPC头上显示对话框,或地图上显示指引箭头

这时候UI作为整个地图的一部分,应该新建一个Canvas设置为WorldSpace。把Canvas拉到所需大小和位置。

比如对话框,有Panel有Text,单纯设置WorldSpace是没法正确显示的。

应该将Dynamic Pixels Per Unit设置的尽量大一些,这个选项表示如Text等的每一单位渲染的像素,值越大Text可以显示的越小。

然后Reference Pixels Per Unit设置为1,表示图片等资源等比像素像素,这样就不会造成如Panel,Image等的虚化。

比如NPC头顶的DialogueBox,NameText字号选择为1,调整canvas像素大小,然后把DialogueText设置为Best Fit,就会自适应Text大小。

21.血条跟随

血条小小的跟在玩家头上,需要Slider所在的Canvas跟随当前主相机。参考

22.Unity设置横屏的方法等相关

参考来源

23.Unity屏幕分辨率自适应

参考来源

要点:

1.UI所在的Canvas设置为screen space-overlay及scale with screen size & expand。

2.UI内部件对应的设置锚点,比如某button保持在左下角则该button的锚点设为左下。

3.勾选Pixel Perfect(防止由高分辨率转为低分辨率时字体模糊)

4.Reference Resolution填为你在制作时的分辨率。比如我在1920*1080时制作的UI,现在要做自适应时填成该分辨率,则在测试时不同分辨率依然保持同样位置大小。

24.Unity快速添加不规则碰撞器Polygoncollider

参考来源

可快速给不规则物体添加collider。

25.明明离对象边缘很远但是碰撞器已经检测到了碰撞

因为对象使用图片精灵边缘有透明部分,可以通过设置Image.alphaHitTestMinimumThreshold的数值来改变,一般设置为0.5解决。参考来源​​​​​​​

26.





 

  • 23
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值