【Unity 2D游戏开发教程】哔哩哔哩_bilibili
快捷键
作用
shift + 空格
局部工作区全屏、恢复
鼠标滚轮滚动
场景放大缩小
鼠标滚轮按住
变成小手,类似ps
鼠标右键
移动视角(旋转)
在场景中选中某个object按delete
删除
ctrl + D
复制对象
1 2 3 4 5 6 7 ├─Assets ├─Animations ├─Materials ├─Prefabs ├─Scripts ├─Sences └─Sprites
添加组件rect修改锚定点
组件:
Rigidbody 2D钢体
void FixedUpdate()
Input.GetAxisRaw(“Horizontal”); -1, 0, 1
Input.GetAxis(“Horizontal”); 平滑变化
【Unity 2D游戏开发教程】
第1课 如何在Unity中快速导入序列帧动画 Aseprite动画帧导出
切割
画像素动画的软件Aseprite
多张图片拖入会被识别为动画
第2课 如何在Unity中实现Player左右移动 2D Movement
加钢体Rigidbody 2D:碰撞检测改为连续检测,睡眠模式改成不睡眠,忽略z轴
加Capsule Collider 2D:
加Box Collider 2D:设置为可触发
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerContraller : MonoBehaviour { public float runSpeed; private Rigidbody2D myRigidbody; void Start () { myRigidbody = GetComponent<Rigidbody2D>(); } void Update () { Run(); } void Run () { float moveDir = Input.GetAxis("Horizontal" ); Vector2 playerVel = new Vector2(moveDir * runSpeed, myRigidbody.velocity.y); myRigidbody.velocity = playerVel; } }
第3课 如何在Unity中实现Player移动时Idle和Run动画切换
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerContraller : MonoBehaviour { public float runSpeed; private Rigidbody2D myRigidbody; private Animator myAnim; void Start () { myRigidbody = GetComponent<Rigidbody2D>(); myAnim = GetComponent<Animator>(); } void Update () { Flip(); Run(); } void Flip () { bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; if (playerHasXAxisSpeed) { if (myRigidbody.velocity.x > 0.1f ) { transform.localRotation = Quaternion.Euler(0 , 0 , 0 ); } if (myRigidbody.velocity.x < -0.1f ) { transform.localRotation = Quaternion.Euler(0 , 180 , 0 ); } } } void Run () { float moveDir = Input.GetAxis("Horizontal" ); Vector2 playerVel = new Vector2(moveDir * runSpeed, myRigidbody.velocity.y); myRigidbody.velocity = playerVel; bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; myAnim.SetBool("Run" , playerHasXAxisSpeed); } }
第4课 如何在Unity中实现Player跳跃Jump功能
Project settings -> Input Manager:查看输入
只有在地面才能跳
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerContraller : MonoBehaviour { public float runSpeed; public float jumpSpeed; private Rigidbody2D myRigidbody; private Animator myAnim; private BoxCollider2D myFeet; private bool isGround; void Start () { myRigidbody = GetComponent<Rigidbody2D>(); myAnim = GetComponent<Animator>(); myFeet = GetComponent<BoxCollider2D>(); } void Update () { Flip(); Run(); Jump(); CheckGround(); } void Flip () { bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; if (playerHasXAxisSpeed) { if (myRigidbody.velocity.x > 0.1f ) { transform.localRotation = Quaternion.Euler(0 , 0 , 0 ); } if (myRigidbody.velocity.x < -0.1f ) { transform.localRotation = Quaternion.Euler(0 , 180 , 0 ); } } } void CheckGround () { isGround = myFeet.IsTouchingLayers(LayerMask.GetMask("Ground" )); Debug.Log(isGround); } void Run () { float moveDir = Input.GetAxis("Horizontal" ); Vector2 playerVel = new Vector2(moveDir * runSpeed, myRigidbody.velocity.y); myRigidbody.velocity = playerVel; bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; myAnim.SetBool("Run" , playerHasXAxisSpeed); } void Jump () { if (isGround && Input.GetButtonDown("Jump" )) { Vector2 jumpVel = new Vector2(0.0f , jumpSpeed); myRigidbody.velocity = Vector2.up * jumpVel; } } }
第5课 如何在Unity中实现Player移动跳跃时Jump, Fall, Idle, Run动
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerContraller : MonoBehaviour { public float runSpeed; public float jumpSpeed; private Rigidbody2D myRigidbody; private Animator myAnim; private BoxCollider2D myFeet; private bool isGround; void Start () { myRigidbody = GetComponent<Rigidbody2D>(); myAnim = GetComponent<Animator>(); myFeet = GetComponent<BoxCollider2D>(); } void Update () { Flip(); Run(); Jump(); CheckGround(); SwitchAnimation(); } void Flip () { bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; if (playerHasXAxisSpeed) { if (myRigidbody.velocity.x > 0.1f ) { transform.localRotation = Quaternion.Euler(0 , 0 , 0 ); } if (myRigidbody.velocity.x < -0.1f ) { transform.localRotation = Quaternion.Euler(0 , 180 , 0 ); } } } void CheckGround () { isGround = myFeet.IsTouchingLayers(LayerMask.GetMask("Ground" )); Debug.Log(isGround); } void Run () { float moveDir = Input.GetAxis("Horizontal" ); Vector2 playerVel = new Vector2(moveDir * runSpeed, myRigidbody.velocity.y); myRigidbody.velocity = playerVel; bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; myAnim.SetBool("Run" , playerHasXAxisSpeed); } void Jump () { if (isGround && Input.GetButton("Jump" )) { myAnim.SetBool("Jump" , true ); Vector2 jumpVel = new Vector2(0.0f , jumpSpeed); myRigidbody.velocity = Vector2.up * jumpVel; } } void SwitchAnimation () { myAnim.SetBool("Idle" , false ); if (myAnim.GetBool("Jump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("Jump" , false ); myAnim.SetBool("Fall" , true ); } } else if (isGround) { myAnim.SetBool("Fall" , false ); myAnim.SetBool("Idle" , true ); } } }
第6课 如何在Unity中实现Player二段跳跃Double Jump
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerContraller : MonoBehaviour { public float runSpeed; public float jumpSpeed; public float doubleJupmSpeed; private Rigidbody2D myRigidbody; private Animator myAnim; private BoxCollider2D myFeet; private bool isGround; private bool canDoubleJump; void Start () { myRigidbody = GetComponent<Rigidbody2D>(); myAnim = GetComponent<Animator>(); myFeet = GetComponent<BoxCollider2D>(); } void Update () { Flip(); Run(); Jump(); CheckGround(); SwitchAnimation(); } void Flip () { bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; if (playerHasXAxisSpeed) { if (myRigidbody.velocity.x > 0.1f ) { transform.localRotation = Quaternion.Euler(0 , 0 , 0 ); } if (myRigidbody.velocity.x < -0.1f ) { transform.localRotation = Quaternion.Euler(0 , 180 , 0 ); } } } void CheckGround () { isGround = myFeet.IsTouchingLayers(LayerMask.GetMask("Ground" )); Debug.Log(isGround); } void Run () { float moveDir = Input.GetAxis("Horizontal" ); Vector2 playerVel = new Vector2(moveDir * runSpeed, myRigidbody.velocity.y); myRigidbody.velocity = playerVel; bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; myAnim.SetBool("Run" , playerHasXAxisSpeed); } void Jump () { if (Input.GetButtonDown("Jump" )) { if (isGround) { myAnim.SetBool("Jump" , true ); Vector2 jumpVel = new Vector2(0.0f , jumpSpeed); myRigidbody.velocity = Vector2.up * jumpVel; canDoubleJump = true ; } else if (canDoubleJump) { myAnim.SetBool("DoubleJump" , true ); canDoubleJump = false ; Vector2 jumpVel = new Vector2(0.0f , doubleJupmSpeed); myRigidbody.velocity = Vector2.up * jumpVel; } } } void SwitchAnimation () { myAnim.SetBool("Idle" , false ); if (myAnim.GetBool("Jump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("Jump" , false ); myAnim.SetBool("Fall" , true ); } } else if (isGround) { myAnim.SetBool("Fall" , false ); myAnim.SetBool("Idle" , true ); } if (myAnim.GetBool("DoubleJump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("DoubleJump" , false ); myAnim.SetBool("DoubleFall" , true ); } } else if (isGround) { myAnim.SetBool("DoubleFall" , false ); myAnim.SetBool("Idle" , true ); } } }
第7课 如何在Unity中实现人物攻击Player Attack(动画篇)
恢复需要延迟时间,所以不需要置零了
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerContraller : MonoBehaviour { public float runSpeed; public float jumpSpeed; public float doubleJupmSpeed; private Rigidbody2D myRigidbody; private Animator myAnim; private BoxCollider2D myFeet; private bool isGround; private bool canDoubleJump; void Start () { myRigidbody = GetComponent<Rigidbody2D>(); myAnim = GetComponent<Animator>(); myFeet = GetComponent<BoxCollider2D>(); } void Update () { Flip(); Run(); Jump(); Attack(); CheckGround(); SwitchAnimation(); } void Flip () { bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; if (playerHasXAxisSpeed) { if (myRigidbody.velocity.x > 0.1f ) { transform.localRotation = Quaternion.Euler(0 , 0 , 0 ); } if (myRigidbody.velocity.x < -0.1f ) { transform.localRotation = Quaternion.Euler(0 , 180 , 0 ); } } } void CheckGround () { isGround = myFeet.IsTouchingLayers(LayerMask.GetMask("Ground" )); } void Run () { float moveDir = Input.GetAxis("Horizontal" ); Vector2 playerVel = new Vector2(moveDir * runSpeed, myRigidbody.velocity.y); myRigidbody.velocity = playerVel; bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; myAnim.SetBool("Run" , playerHasXAxisSpeed); } void Jump () { if (Input.GetButtonDown("Jump" )) { if (isGround) { myAnim.SetBool("Jump" , true ); Vector2 jumpVel = new Vector2(0.0f , jumpSpeed); myRigidbody.velocity = Vector2.up * jumpVel; canDoubleJump = true ; } else if (canDoubleJump) { myAnim.SetBool("DoubleJump" , true ); canDoubleJump = false ; Vector2 jumpVel = new Vector2(0.0f , doubleJupmSpeed); myRigidbody.velocity = Vector2.up * jumpVel; } } } void Attack () { if (Input.GetButtonDown("Attack" )) { myAnim.SetTrigger("Attack" ); } } void SwitchAnimation () { myAnim.SetBool("Idle" , false ); if (myAnim.GetBool("Jump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("Jump" , false ); myAnim.SetBool("Fall" , true ); } } else if (isGround) { myAnim.SetBool("Fall" , false ); myAnim.SetBool("Idle" , true ); } if (myAnim.GetBool("DoubleJump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("DoubleJump" , false ); myAnim.SetBool("DoubleFall" , true ); } } else if (isGround) { myAnim.SetBool("DoubleFall" , false ); myAnim.SetBool("Idle" , true ); } } }
第8课 如何在Unity中实现人物攻击Player Attack(Hitbox篇)
PlayerAttack.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerAttack : MonoBehaviour { public int damage; public float startTime; public float disableTime; private Animator anim; private PolygonCollider2D collider2D; void Start () { anim = GameObject.FindGameObjectWithTag("Player" ).GetComponent<Animator>(); collider2D = GetComponent<PolygonCollider2D>(); } void Update () { Attack(); } void Attack () { if (Input.GetButtonDown("Attack" )) { anim.SetTrigger("Attack" ); StartCoroutine(StartAttack()); } } IEnumerator StartAttack () { yield return new WaitForSeconds (startTime ) ; collider2D.enabled = true ; StartCoroutine(DisableHitBox()); } IEnumerator DisableHitBox () { yield return new WaitForSeconds (disableTime ) ; collider2D.enabled = false ; } }
第9课 如何在Unity中实现人物攻击Player Attack(Enemy篇)
PlayerAttack.cs
1 2 3 4 5 6 7 private void OnTriggerEnter2D (Collider2D other ) { if (other.gameObject.CompareTag("Enemy" )) { other.GetComponent<Enemy>().TakeDamege(damage); } }
Enemy_Bat.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 using System.Collections;using System.Collections.Generic;using UnityEngine;public class Enemy_Bat : Enemy { public void Start () { } public void Update () { base .Update(); } }
Enemy.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public abstract class Enemy : MonoBehaviour { public int health; public int damage; public void Start () { } public void Update () { if (health <= 0 ) { Destroy(gameObject); } } public void TakeDamege (int damage ) { health -= damage; } }
第10课 如何在Unity中实现敌人受伤后红色闪烁功能 Enemy Re
Enemy_Bat.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 using System.Collections;using System.Collections.Generic;using UnityEngine;public class Enemy_Bat : Enemy { public void Start () { base .Start(); } public void Update () { base .Update(); } }
Enemy.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public abstract class Enemy : MonoBehaviour { public int health; public int damage; public float flashTime; private SpriteRenderer sr; private Color oriColor; public void Start () { sr = GetComponent<SpriteRenderer>(); oriColor = sr.color; } public void Update () { if (health <= 0 ) { Destroy(gameObject); } } public void TakeDamege (int damage ) { health -= damage; FlashColor(flashTime); } void FlashColor (float time ) { sr.color = Color.red; Invoke("ResetColor" , time); } void ResetColor () { sr.color = oriColor; } }
第11课 如何在Unity中实现简单敌人AI功能 Enemy AI
Enemy_Bat.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class Enemy_Bat : Enemy { public float speed; public float startWaitTime; public Transform movePose; public Transform leftDownPos; public Transform rightUpPos; private float waitTime; public void Start () { base .Start(); waitTime = startWaitTime; movePose.position = GetRandomPos(); } public void Update () { base .Update(); transform.position = Vector2.MoveTowards(transform.position, movePose.position, speed * Time.deltaTime); if (Vector2.Distance(transform.position, movePose.position) < 0.1f ) { if (waitTime <= 0 ) { movePose.position = GetRandomPos(); waitTime = startWaitTime; } else { waitTime -= Time.deltaTime; } } } Vector2 GetRandomPos () { Vector2 rndPos = new Vector2(Random.Range(leftDownPos.position.x, rightUpPos.position.x), Random.Range(leftDownPos.position.y, rightUpPos.position.y)); return rndPos; } }
第12课 如何在Unity中实现敌人掉血的粒子特效 Enemy Blood Effe
BloodEffect.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 using System.Collections;using System.Collections.Generic;using UnityEngine;public class BloodEffect : MonoBehaviour { public float timeToDestory; void Start () { Destroy(gameObject, timeToDestory); } void Update () { } }
Enemy.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public abstract class Enemy : MonoBehaviour { public int health; public int damage; public float flashTime; public GameObject bloodEffect; private SpriteRenderer sr; private Color oriColor; public void Start () { sr = GetComponent<SpriteRenderer>(); oriColor = sr.color; } public void Update () { if (health <= 0 ) { Destroy(gameObject); } } public void TakeDamege (int damage ) { health -= damage; FlashColor(flashTime); Instantiate(bloodEffect, transform.position, Quaternion.identity); } void FlashColor (float time ) { sr.color = Color.red; Invoke("ResetColor" , time); } void ResetColor () { sr.color = oriColor; } }
第13课 如何在Unity中实现相机跟随Player功能 Camera Follow
CameraFollow.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class CameraFollow : MonoBehaviour { public Transform target; public float smoothing; void Start () { } void LateUpdate () { if (target != null ) { if (transform.position != target.position) { Vector3 targetPos = target.position; transform.position = Vector3.Lerp(transform.position, targetPos, smoothing); } } } void Update () { } }
第14课 如何在Unity中实现相机震动抖动 Camera Shake
CameraShake.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class CameraShake : MonoBehaviour { public Animator camAnim; void Start () { } void Update () { } public void Shake () { camAnim.SetTrigger("Shake" ); } }
GameController.cs
1 2 3 4 5 6 7 8 using System.Collections;using System.Collections.Generic;using UnityEngine;public class GameController : MonoBehaviour { public static CameraShake camShake; }
Enemy.cs
1 2 3 4 5 6 7 public void TakeDamege (int damage ) { health -= damage; FlashColor(flashTime); Instantiate(bloodEffect, transform.position, Quaternion.identity); GameController.camShake.Shake(); }
CameraFollow.cs
1 2 3 4 void Start () { GameController.camShake = GameObject.FindGameObjectWithTag("CameraShake" ).GetComponent<CameraShake>(); }
第15课 如何在Unity中限制相机的移动范围 Camera Limit
CameraFollow.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class CameraFollow : MonoBehaviour { public Transform target; public float smoothing; public Vector2 minPosition; public Vector2 maxPosition; void Start () { GameController.camShake = GameObject.FindGameObjectWithTag("CameraShake" ).GetComponent<CameraShake>(); } void LateUpdate () { if (target != null ) { if (transform.position != target.position) { Vector3 targetPos = target.position; targetPos.x = Mathf.Clamp(targetPos.x, minPosition.x, maxPosition.x); targetPos.y = Mathf.Clamp(targetPos.y, minPosition.y, maxPosition.y); transform.position = Vector3.Lerp(transform.position, targetPos, smoothing); } } } void Update () { } public void SetCamPosLimit (Vector2 minPos, Vector2 maxPos ) { minPosition = minPos; maxPosition = maxPos; } }
第16课 如何在Unity中实现Player受伤闪烁功能
PlayerHealth.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerHealth : MonoBehaviour { public int health; public int blinks; public float time; private Renderer myRender; void Start () { myRender = GetComponent<Renderer>(); } void Update () { } public void DamagePlayer (int damage ) { health -= damage; if (health <= 0 ) { Destroy(gameObject); } BlinkPlayer(blinks, time); } void BlinkPlayer (int numBlinks, float seconds ) { StartCoroutine(DoBlink(numBlinks, seconds)); } IEnumerator DoBlink (int numBlinks, float seconds ) { for (int i = 0 ; i < numBlinks * 2 ; i++) { myRender.enabled = !myRender.enabled; yield return new WaitForSeconds (seconds ) ; } myRender.enabled = true ; } }
Enemy.cs
1 2 3 4 5 6 7 8 9 10 private void OnTriggerEnter2D (Collider2D other ) { if (other.gameObject.CompareTag("Player" ) && other.GetType().ToString() == "UnityEngine.CapsuleCollider2D" ) { if (playerHealth != null ) { playerHealth.DamagePlayer(damage); } } }
第17课 如何在Unity中实现Player死亡功能 Player Death
解决吸墙,摩擦力导致的
新建2D材质,摩擦力置零,挂载到Player胶囊碰撞体上
死亡动画效果
PlayerHealth.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerHealth : MonoBehaviour { public int health; public int blinks; public float time; public float dieTime; private Renderer myRender; private Animator anim; void Start () { myRender = GetComponent<Renderer>(); anim = GetComponent<Animator>(); } void Update () { } public void DamagePlayer (int damage ) { health -= damage; if (health <= 0 ) { anim.SetTrigger("Die" ); Invoke("KillPlayer" , dieTime); } BlinkPlayer(blinks, time); } void KillPlayer () { Destroy(gameObject); } void BlinkPlayer (int numBlinks, float seconds ) { StartCoroutine(DoBlink(numBlinks, seconds)); } IEnumerator DoBlink (int numBlinks, float seconds ) { for (int i = 0 ; i < numBlinks * 2 ; i++) { myRender.enabled = !myRender.enabled; yield return new WaitForSeconds (seconds ) ; } myRender.enabled = true ; } }
第18课 如何正确理解Unity中的Layer和Sorting Layer
Layer:处理所有碰撞相关的内容
Sorting Layer:处理显示顺序的内容
有bug就看看layer碰撞设置
第19课 如何在Unity中使用2D TileMap功能
直接加Tilemap Collider 2D效率不高,可以加一个组件Composite Collider 2D,然后钢体Body Type属性改为static静态,最后勾上Tilemap Collider 2D中的Used By Composite
第20课 如何在Unity中实现Player生命值血条功能 Player Health B
HealthBar.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class HealthBar : MonoBehaviour { public Text healthText; public static int HealthCurrent; public static int HealthMax; private Image healthBar; void Start () { healthBar = GetComponent<Image>(); } void Update () { healthBar.fillAmount = (float )HealthCurrent / (float )HealthMax; healthText.text = HealthCurrent.ToString() + "/" + HealthMax.ToString(); } }
PlayerHealth.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerHealth : MonoBehaviour { public int health; public int blinks; public float time; public float dieTime; private Renderer myRender; private Animator anim; void Start () { HealthBar.HealthMax = health; HealthBar.HealthCurrent = health; myRender = GetComponent<Renderer>(); anim = GetComponent<Animator>(); } void Update () { } public void DamagePlayer (int damage ) { health -= damage; if (health < 0 ) health = 0 ; HealthBar.HealthCurrent = health; if (health <= 0 ) { anim.SetTrigger("Die" ); Invoke("KillPlayer" , dieTime); } BlinkPlayer(blinks, time); } void KillPlayer () { Destroy(gameObject); } void BlinkPlayer (int numBlinks, float seconds ) { StartCoroutine(DoBlink(numBlinks, seconds)); } IEnumerator DoBlink (int numBlinks, float seconds ) { for (int i = 0 ; i < numBlinks * 2 ; i++) { myRender.enabled = !myRender.enabled; yield return new WaitForSeconds (seconds ) ; } myRender.enabled = true ; } }
第21课 如何在Unity中实现Player受伤时屏幕红闪功能 Screen Flas
修改了粒子效果不显示的bug
ScreenFlash.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class ScreenFlash : MonoBehaviour { public Image img; public float time; public Color flashColor; private Color defaultColor; void Start () { defaultColor = img.color; } void Update () { } public void FlashScreen () { StartCoroutine(Flash()); } IEnumerator Flash () { img.color = flashColor; yield return new WaitForSeconds (time ) ; img.color = defaultColor; } }
修改角色死亡还能动的bug
GameController.cs
1 2 3 4 5 6 7 8 9 using System.Collections;using System.Collections.Generic;using UnityEngine;public class GameController : MonoBehaviour { public static bool isGameAlive; public static CameraShake camShake; }
PlayerHealth.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerHealth : MonoBehaviour { public int health; public int blinks; public float time; public float dieTime; private Renderer myRender; private Animator anim; private ScreenFlash sf; private Rigidbody2D rb2d; void Start () { HealthBar.HealthMax = health; HealthBar.HealthCurrent = health; myRender = GetComponent<Renderer>(); anim = GetComponent<Animator>(); sf = GetComponent<ScreenFlash>(); rb2d = GetComponent<Rigidbody2D>(); } void Update () { } public void DamagePlayer (int damage ) { sf.FlashScreen(); health -= damage; if (health < 0 ) health = 0 ; HealthBar.HealthCurrent = health; if (health <= 0 ) { rb2d.velocity = new Vector2(0 , 0 ); GameController.isGameAlive = false ; anim.SetTrigger("Die" ); Invoke("KillPlayer" , dieTime); } BlinkPlayer(blinks, time); } void KillPlayer () { Destroy(gameObject); } void BlinkPlayer (int numBlinks, float seconds ) { StartCoroutine(DoBlink(numBlinks, seconds)); } IEnumerator DoBlink (int numBlinks, float seconds ) { for (int i = 0 ; i < numBlinks * 2 ; i++) { myRender.enabled = !myRender.enabled; yield return new WaitForSeconds (seconds ) ; } myRender.enabled = true ; } }
PlayerContraller.cs
1 2 3 4 5 6 7 8 9 10 11 void Update () { if (GameController.isGameAlive) { Flip(); Run(); Jump(); CheckGround(); SwitchAnimation(); } }
Spikes.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class Spikes : MonoBehaviour { public int damage; private PlayerHealth playerHealth; void Start () { playerHealth = GameObject.FindGameObjectWithTag("Player" ).GetComponent<PlayerHealth>(); } void Update () { } void OnTriggerEnter2D (Collider2D other ) { if (other.CompareTag("Player" ) && other.GetType().ToString() == "UnityEngine.PolygonCollider2D" ) { playerHealth.DamagePlayer(damage); } } }
PlayerHealth.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerHealth : MonoBehaviour { public int health; public int blinks; public float time; public float dieTime; public float hitBoxCdTime; private Renderer myRender; private Animator anim; private ScreenFlash sf; private Rigidbody2D rb2d; private PolygonCollider2D polygonCollider2D; void Start () { HealthBar.HealthMax = health; HealthBar.HealthCurrent = health; myRender = GetComponent<Renderer>(); anim = GetComponent<Animator>(); sf = GetComponent<ScreenFlash>(); rb2d = GetComponent<Rigidbody2D>(); polygonCollider2D = GetComponent<PolygonCollider2D>(); } void Update () { } public void DamagePlayer (int damage ) { sf.FlashScreen(); health -= damage; if (health < 0 ) health = 0 ; HealthBar.HealthCurrent = health; if (health <= 0 ) { rb2d.velocity = new Vector2(0 , 0 ); GameController.isGameAlive = false ; anim.SetTrigger("Die" ); Invoke("KillPlayer" , dieTime); } BlinkPlayer(blinks, time); polygonCollider2D.enabled = false ; StartCoroutine(ShowPlayerHitBox()); } IEnumerator ShowPlayerHitBox () { yield return new WaitForSeconds (hitBoxCdTime ) ; polygonCollider2D.enabled = true ; } void KillPlayer () { Destroy(gameObject); } void BlinkPlayer (int numBlinks, float seconds ) { StartCoroutine(DoBlink(numBlinks, seconds)); } IEnumerator DoBlink (int numBlinks, float seconds ) { for (int i = 0 ; i < numBlinks * 2 ; i++) { myRender.enabled = !myRender.enabled; yield return new WaitForSeconds (seconds ) ; } myRender.enabled = true ; } }
首先如果Player在MovingPlatform下的话,是可以一起移动的,所以将这么修改
MovingPlatform.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class MovingPlatform : MonoBehaviour { public float speed; public float waitTime; public Transform[] movePos; private int i; private float oriWaitTime; private Transform playerDefTransform; void Start () { i = 1 ; oriWaitTime = waitTime; playerDefTransform = GameObject.FindGameObjectWithTag("Player" ).transform.parent; } void Update () { transform.position = Vector2.MoveTowards(transform.position, movePos[i].position, speed * Time.deltaTime); if (Vector2.Distance(transform.position, movePos[i].position) < 0.1f ) { if (waitTime < 0.0f ) { if (i == 0 ) i = 1 ; else i = 0 ; waitTime = oriWaitTime; } else { waitTime -= Time.deltaTime; } } } void OnTriggerEnter2D (Collider2D other ) { if (other.CompareTag("Player" ) && other.GetType().ToString() == "UnityEngine.BoxCollider2D" ) { other.gameObject.transform.parent = gameObject.transform; } } void OnTriggerExit2D (Collider2D other ) { if (other.CompareTag("Player" ) && other.GetType().ToString() == "UnityEngine.BoxCollider2D" ) { other.gameObject.transform.parent = playerDefTransform; } } }
画Tilemap的时候按住Shift是删除
实现下面可以穿过,上面不行穿过:添加组件Platform Effector 2D,Composite Collider 2D组件勾选Used By Effector
实现按下键通过,可以暂时取消碰撞
PlayerContraller.cs
自己修改了在空中也可以跳一次,以及从地面下落的动画切换
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerContraller : MonoBehaviour { public float runSpeed; public float jumpSpeed; public float doubleJupmSpeed; public float restoreTime; private Rigidbody2D myRigidbody; private Animator myAnim; private BoxCollider2D myFeet; private bool isGround; private bool canDoubleJump; private bool isOnOneWayPlatform; void Start () { myRigidbody = GetComponent<Rigidbody2D>(); myAnim = GetComponent<Animator>(); myFeet = GetComponent<BoxCollider2D>(); } void Update () { if (GameController.isGameAlive) { Flip(); Run(); Jump(); CheckGround(); SwitchAnimation(); OneWayPlatformCheck(); } } void Flip () { bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; if (playerHasXAxisSpeed) { if (myRigidbody.velocity.x > 0.1f ) { transform.localRotation = Quaternion.Euler(0 , 0 , 0 ); } if (myRigidbody.velocity.x < -0.1f ) { transform.localRotation = Quaternion.Euler(0 , 180 , 0 ); } } } void CheckGround () { isGround = myFeet.IsTouchingLayers(LayerMask.GetMask("Ground" )) || myFeet.IsTouchingLayers(LayerMask.GetMask("MovingPlatform" )) || myFeet.IsTouchingLayers(LayerMask.GetMask("OneWayPlatform" )); isOnOneWayPlatform = myFeet.IsTouchingLayers(LayerMask.GetMask("OneWayPlatform" )); } void Run () { float moveDir = Input.GetAxis("Horizontal" ); Vector2 playerVel = new Vector2(moveDir * runSpeed, myRigidbody.velocity.y); myRigidbody.velocity = playerVel; bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; myAnim.SetBool("Run" , playerHasXAxisSpeed); } void Jump () { if (isGround) canDoubleJump = true ; if (Input.GetButtonDown("Jump" )) { if (isGround) { myAnim.SetBool("Jump" , true ); Vector2 jumpVel = new Vector2(0.0f , jumpSpeed); myRigidbody.velocity = Vector2.up * jumpVel; } else if (canDoubleJump) { myAnim.SetBool("DoubleJump" , true ); canDoubleJump = false ; Vector2 jumpVel = new Vector2(0.0f , doubleJupmSpeed); myRigidbody.velocity = Vector2.up * jumpVel; } } } void SwitchAnimation () { myAnim.SetBool("Idle" , false ); if (myAnim.GetBool("Jump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("Jump" , false ); myAnim.SetBool("Fall" , true ); } } else if (isGround) { myAnim.SetBool("Fall" , false ); myAnim.SetBool("Idle" , true ); } if (myAnim.GetBool("DoubleJump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("DoubleJump" , false ); myAnim.SetBool("DoubleFall" , true ); } } else if (isGround) { myAnim.SetBool("DoubleFall" , false ); myAnim.SetBool("Idle" , true ); } if (!isGround && !myAnim.GetBool("Idle" ) && !myAnim.GetBool("DoubleFall" ) && !myAnim.GetBool("DoubleJump" ) && !myAnim.GetBool("Jump" ) && !myAnim.GetBool("Attack" ) && !myAnim.GetBool("Run" )) { myAnim.SetBool("Idle" , false ); myAnim.SetBool("Fall" , true ); } } void OneWayPlatformCheck () { if (isGround && gameObject.layer != LayerMask.NameToLayer("Player" )) { gameObject.layer = LayerMask.NameToLayer("Player" ); } float moveY = Input.GetAxis("Vertical" ); if (isOnOneWayPlatform && moveY < -0.1f ) { gameObject.layer = LayerMask.NameToLayer("OneWayPlatform" ); Invoke("RestorePlayerLayer" , restoreTime); } } void RestorePlayerLayer () { if (!isGround && gameObject.layer != LayerMask.NameToLayer("Player" )) { gameObject.layer = LayerMask.NameToLayer("Player" ); } } }
第25课 如何在Unity中实现Player爬梯子功能 2D Ladder
自己修改了代码
梯子顶部可以和单项木板一起用
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class PlayerContraller : MonoBehaviour { public float runSpeed; public float jumpSpeed; public float doubleJupmSpeed; public float climbSpeed; public float restoreTime; private Rigidbody2D myRigidbody; private Animator myAnim; private BoxCollider2D myFeet; private bool isGround; private bool canDoubleJump; private bool isOnOneWayPlatform; private bool isLadder; private bool isClimbing; private float playerGravity; void Start () { myRigidbody = GetComponent<Rigidbody2D>(); myAnim = GetComponent<Animator>(); myFeet = GetComponent<BoxCollider2D>(); playerGravity = myRigidbody.gravityScale; } void Update () { if (GameController.isGameAlive) { Flip(); Run(); Jump(); Climb(); CheckGround(); CheckLadder(); SwitchAnimation(); OneWayPlatformCheck(); } } void Flip () { bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; if (playerHasXAxisSpeed) { if (myRigidbody.velocity.x > 0.1f ) { transform.localRotation = Quaternion.Euler(0 , 0 , 0 ); } if (myRigidbody.velocity.x < -0.1f ) { transform.localRotation = Quaternion.Euler(0 , 180 , 0 ); } } } void CheckGround () { isGround = myFeet.IsTouchingLayers(LayerMask.GetMask("Ground" )) || myFeet.IsTouchingLayers(LayerMask.GetMask("MovingPlatform" )) || myFeet.IsTouchingLayers(LayerMask.GetMask("OneWayPlatform" )); isOnOneWayPlatform = myFeet.IsTouchingLayers(LayerMask.GetMask("OneWayPlatform" )); } void CheckLadder () { isLadder = myFeet.IsTouchingLayers(LayerMask.GetMask("Ladder" )); } void Run () { float moveDir = Input.GetAxis("Horizontal" ); Vector2 playerVel = new Vector2(moveDir * runSpeed, myRigidbody.velocity.y); myRigidbody.velocity = playerVel; bool playerHasXAxisSpeed = Mathf.Abs(myRigidbody.velocity.x) > Mathf.Epsilon; myAnim.SetBool("Run" , playerHasXAxisSpeed); } void Jump () { if (isGround) canDoubleJump = true ; if (Input.GetButtonDown("Jump" )) { if (isGround) { myAnim.SetBool("Jump" , true ); Vector2 jumpVel = new Vector2(0.0f , jumpSpeed); myRigidbody.velocity = Vector2.up * jumpVel; } else if (canDoubleJump) { myAnim.SetBool("DoubleJump" , true ); canDoubleJump = false ; Vector2 jumpVel = new Vector2(0.0f , doubleJupmSpeed); myRigidbody.velocity = Vector2.up * jumpVel; } } } void Climb () { if (isOnOneWayPlatform) isLadder = false ; if (isLadder) { float moveY = Input.GetAxis("Vertical" ); if (moveY > 0.5f || moveY < -0.5f ) { myAnim.SetBool("Climbing" , true ); myRigidbody.gravityScale = 0.0f ; myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, moveY * climbSpeed); isClimbing = true ; } else { if (isClimbing) { myRigidbody.velocity = new Vector2(myRigidbody.velocity.x, 0.0f ); } } } else { isClimbing = false ; myAnim.SetBool("Climbing" , false ); myRigidbody.gravityScale = playerGravity; } } void SwitchAnimation () { myAnim.SetBool("Idle" , false ); if (myAnim.GetBool("Jump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("Jump" , false ); myAnim.SetBool("Fall" , true ); } } else if (isGround) { myAnim.SetBool("Fall" , false ); myAnim.SetBool("Idle" , true ); } if (myAnim.GetBool("DoubleJump" )) { if (myRigidbody.velocity.y < 0.0f ) { myAnim.SetBool("DoubleJump" , false ); myAnim.SetBool("DoubleFall" , true ); } } else if (isGround) { myAnim.SetBool("DoubleFall" , false ); myAnim.SetBool("Idle" , true ); } } void OneWayPlatformCheck () { if (isGround && gameObject.layer != LayerMask.NameToLayer("Player" )) { gameObject.layer = LayerMask.NameToLayer("Player" ); } float moveY = Input.GetAxis("Vertical" ); if (isOnOneWayPlatform && moveY < -0.1f ) { gameObject.layer = LayerMask.NameToLayer("OneWayPlatform" ); Invoke("RestorePlayerLayer" , restoreTime); } } void RestorePlayerLayer () { if (!isGround && gameObject.layer != LayerMask.NameToLayer("Player" )) { gameObject.layer = LayerMask.NameToLayer("Player" ); } } }
第26课 如何在Unity中实现Player捡起金币和怪物金币掉落功能 G
没有sample选项:animation窗口右上角的小按钮 点一下 展开的菜单里 有个 show samples之类的选项 点一下就出来了
CoinItem.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;public class CoinItem : MonoBehaviour { void Start () { } void Update () { } void OnTriggerEnter2D (Collider2D other ) { if (other.gameObject.CompareTag("Player" ) && other.GetType().ToString() == "UnityEngine.CapsuleCollider2D" ) { CoinUI.currentCoinQuantity += 1 ; Destroy(gameObject); } } }
CoinUI.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class CoinUI : MonoBehaviour { public int startCoinQuantity; public Text coinQuantity; public static int currentCoinQuantity; void Start () { currentCoinQuantity = startCoinQuantity; } void Update () { coinQuantity.text = currentCoinQuantity.ToString(); } }
Enemy.cs
1 2 3 4 5 6 7 8 9 public GameObject dropCoin;public void Update () { if (health <= 0 ) { Instantiate(dropCoin, transform.position, Quaternion.identity); Destroy(gameObject); } }
第27课 如何在Unity中实现Player靠近招牌时显示文字对话框功能
Sign.cs
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 using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.UI;public class Sign : MonoBehaviour { public GameObject dialogBox; public Text text; public string textContent; private bool isPlayerInSign; void Start () { } void Update () { if (Input.GetKeyDown(KeyCode.E) && isPlayerInSign) { text.text = textContent; dialogBox.SetActive(true ); } } void OnTriggerEnter2D (Collider2D other ) { if (other.gameObject.CompareTag("Player" ) && other.GetType().ToString() == "UnityEngine.CapsuleCollider2D" ) { isPlayerInSign = true ; } } void OnTriggerExit2D (Collider2D other ) { if (other.gameObject.CompareTag("Player" ) && other.GetType().ToString() == "UnityEngine.CapsuleCollider2D" ) { isPlayerInSign = false ; dialogBox.SetActive(false ); } } }
改名了Universal RP
超级bug,不会用