【Unity3D游戏开发】基础知识之Tags和Layers (三二)[转]
Tags和Layers分别表示是Unity引擎里面的标签和层,他们都是用来对GameObject进行标识的属性,Tags常用于单个GameObject,Layers常用于一组的GameObject。添加Tags和Layers的操作如下:
"Edit" -> "Project Settings" -> "Tags and Layers"来打开设置面板。
tag可以理解为一类元素的标记,如hero、enemy、apple-tree等。通过设置tag,可以方便地通过GameObject.FindWithTag()来寻找对象。GameObject.FindWithTag()只返回一个对象,要想获取多个tag为某值的对象,GameObject.FindGameObjectsWithTag()。
每个GameObject的Inspector面板最上方都也有个Layer选项,就在Tag旁边,unity已经有了几个层,我们新建个层,也叫UI,点击Add Layer,可以看到从Layer0到Layer7都灰掉了,那是不能用的,从第八个起可以用,Layer和tag还有一个很大的区别就是layer最多只能有32个层。
在使用过程中,使用Culling Mask、Layer Mask的地方实际指的就是layer。下面我们来看一段使用layer来检测碰撞的代码:
1 Ray ray1 = nguiCamera.camera.ScreenPointToRay(Input.mousePosition); 2 RaycastHit hit1; 3 LayerMask mask = 1 << LayerMask.NameToLayer("UI"); 4 if (Physics.Raycast(ray1, out hit1, 600, mask.value)) 5 { 6 return; 7 }
LayerMask的NameToLayer是通过层的名称返回该层的索引,如果是8,然后1<<8换算成LayerMask值,再用LayerMask的value就可以了。注意也必须设置collider才能接收碰撞,这里才能判断到。LayerMask实际上是一个位码操作,在Unity中Layers一共有32层,这个是不能增加或者减少的: 1 << LayerMask.NameToLayer("UI") 这一句实际上表示射线查询只在UI所在这个层级查找是返回的该名字所定义的层的层索引,注意是从0开始。
下面我们来看一个玩家控制的脚本,利用 Physics2D.Linecast检测物体是否碰撞到地面。
1 using UnityEngine; 2 using System.Collections; 3 4 public class PlayerControl : MonoBehaviour 5 { 6 [HideInInspector] 7 public bool facingRight = true; // For determining which way the player is currently facing. 8 [HideInInspector] 9 public bool jump = false; // Condition for whether the player should jump. 10 11 12 public float moveForce = 365f; // Amount of force added to move the player left and right. 13 public float maxSpeed = 5f; // The fastest the player can travel in the x axis. 14 public AudioClip[] jumpClips; // Array of clips for when the player jumps. 15 public float jumpForce = 1000f; // Amount of force added when the player jumps. 16 public AudioClip[] taunts; // Array of clips for when the player taunts. 17 public float tauntProbability = 50f; // Chance of a taunt happening. 18 public float tauntDelay = 1f; // Delay for when the taunt should happen. 19 20 21 private int tauntIndex; // The index of the taunts array indicating the most recent taunt. 22 private Transform groundCheck; // A position marking where to check if the player is grounded. 23 private bool grounded = false; // Whether or not the player is grounded. 24 private Animator anim; // Reference to the player's animator component. 25 26 27 void Awake() 28 { 29 // Setting up references. 30 // 在子对象里面找到groundCheck 31 groundCheck = transform.Find("groundCheck"); 32 // 获取当前的动画控制器 33 anim = GetComponent<Animator>(); 34 } 35 36 void Update() 37 { 38 // 是为能随时检测到groundCheck这个物体,添加一个名叫Ground的Layer,然后把场景中的所有代表地面的物体的Layer设为Ground 39 // 这里用到了2D射线检测Physics2D.Linecast() 40 // LayerMask实际上是一个位码操作,在Unity3d中Layers一共有32层,这个是不能增加或者减少的: 41 // 1 << LayerMask.NameToLayer("Ground") 这一句实际上表示射线查询只在Ground所在这个层级查找 是返回的该名字所定义的层的层索引,注意是从0开始 42 // 每个GameObject的Inspector面板最上方都也有个Layer选项,就在Tag旁边,unity3d已经有了几个层,我们新建个层,也叫UI,点击Add Layer,可以看到从Layer0到Layer7都灰掉了,那是不能用的,从第八个起可以用,所以在第八个建个UI的层。 43 // 一般情况下我们只用前两个参数,distance表示射线距离,默认是无限远,重点是最后一个参数layerMask,专门处理layer过滤的,是个整型,怎么用呢,是靠layer的二进制位来操作的 44 // LayerMask的NameToLayer是通过层的名称返回该层的索引,这里是8,然后1<<8换算成LayerMask值,再用LayerMask的value就可以了。 45 // 注意也必须设置collider才能接收碰撞,这里才能判断到。 46 grounded = Physics2D.Linecast(transform.position, groundCheck.position, 1 << LayerMask.NameToLayer("Ground")); 47 48 // If the jump button is pressed and the player is grounded then the player should jump. 49 // 如果点击了跳的按键,并且已经着陆,那么就可以跳起来 50 if(Input.GetButtonDown("Jump") && grounded) 51 jump = true; 52 } 53 54 // 因为主角游戏对象要使用到刚体力,所以一定要写在FixedUpdate里面,不能放在Update上 55 void FixedUpdate () 56 { 57 // Cache the horizontal input. 58 // 换取水平方向的移动距离 59 float h = Input.GetAxis("Horizontal"); 60 61 // The Speed animator parameter is set to the absolute value of the horizontal input. 62 // 设置动画的速度变量 63 anim.SetFloat("Speed", Mathf.Abs(h)); 64 65 // 给物体添加一个水平的力,让它移动的时候会产生惯性的效果 66 // If the player is changing direction (h has a different sign to velocity.x) or hasn't reached maxSpeed yet... 67 // 如果速度小于最大的速度 68 if(h * rigidbody2D.velocity.x < maxSpeed) 69 // ... add a force to the player. 70 rigidbody2D.AddForce(Vector2.right * h * moveForce); 71 72 // If the player's horizontal velocity is greater than the maxSpeed... 73 if(Mathf.Abs(rigidbody2D.velocity.x) > maxSpeed) 74 // ... set the player's velocity to the maxSpeed in the x axis. 75 rigidbody2D.velocity = new Vector2(Mathf.Sign(rigidbody2D.velocity.x) * maxSpeed, rigidbody2D.velocity.y); 76 77 // 转身 78 // If the input is moving the player right and the player is facing left... 79 if(h > 0 && !facingRight) 80 // ... flip the player. 81 Flip(); 82 // Otherwise if the input is moving the player left and the player is facing right... 83 else if(h < 0 && facingRight) 84 // ... flip the player. 85 Flip(); 86 87 // If the player should jump... 88 if(jump) 89 { 90 // Set the Jump animator trigger parameter. 91 // 触发跳的动画 92 anim.SetTrigger("Jump"); 93 94 // Play a random jump audio clip. 95 int i = Random.Range(0, jumpClips.Length); 96 AudioSource.PlayClipAtPoint(jumpClips[i], transform.position); 97 98 // Add a vertical force to the player. 99 // 添加一个垂直的力 100 rigidbody2D.AddForce(new Vector2(0f, jumpForce)); 101 102 // Make sure the player can't jump again until the jump conditions from Update are satisfied. 103 jump = false; 104 } 105 } 106 107 // 转身 108 void Flip () 109 { 110 // Switch the way the player is labelled as facing. 111 facingRight = !facingRight; 112 113 // Multiply the player's x local scale by -1. 114 Vector3 theScale = transform.localScale; 115 theScale.x *= -1; 116 transform.localScale = theScale; 117 } 118 119 120 public IEnumerator Taunt() 121 { 122 // Check the random chance of taunting. 123 float tauntChance = Random.Range(0f, 100f); 124 if(tauntChance > tauntProbability) 125 { 126 // Wait for tauntDelay number of seconds. 127 yield return new WaitForSeconds(tauntDelay); 128 129 // If there is no clip currently playing. 130 if(!audio.isPlaying) 131 { 132 // Choose a random, but different taunt. 133 tauntIndex = TauntRandom(); 134 135 // Play the new taunt. 136 audio.clip = taunts[tauntIndex]; 137 audio.Play(); 138 } 139 } 140 } 141 142 143 int TauntRandom() 144 { 145 // Choose a random index of the taunts array. 146 int i = Random.Range(0, taunts.Length); 147 148 // If it's the same as the previous taunt... 149 if(i == tauntIndex) 150 // ... try another random taunt. 151 return TauntRandom(); 152 else 153 // Otherwise return this index. 154 return i; 155 } 156 }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步