当前位置:   article > 正文

13.Unity2D 横版 可上下左右移动的双向平台(双向行走+可移动+单独判定)+随机平台生成_unity随机生成横版地图

unity随机生成横版地图

 

 总目录https://blog.csdn.net/qq_54263076/category_11900070.html?spm=1001.2014.3001.5482

大多数平台教程全是碰撞体的可移动平台,并没有可跳上的平台,并且要求按下键会从平台上跳下来。有也只是通过控制平台的“2D平台效果碰撞体”组件的单向平台的旋转偏移来做,但是这样会出现一个问题,当有多个人或者多个NPC在同一个平台上,如果有一个人按下键会导致所有人都跳下来,虽然其他人并没有按下键。如同下面:(看不懂原理没关系,就看个示范结果)

 

所以为了解决这个问题,我们需要对能进行跳跃平台的人物自己碰撞体短时间消失,射线检测是必要的。如果不懂射线检测,欢迎看我下面的博客

11.Unity2D 横版 简单AI 之背后受击转身+寻路跟随敌人+模块化+射线检测_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客Unity2D 横版 简单AI 之背后受击转身+寻路跟随敌人+模块化+射线检测。回顾上节课,我们已经完成了范围内检索敌人自动攻击,随机移动功能。1.敌人背后受击转身+背部攻击伤害翻倍2.寻路跟随敌人随机移动的坏处就是看到敌人(主角)会略过去,按照自己的行为行走,所以我们要再写一个行为脚本,用来看到敌人后的行为,当然如果没有看到敌人还是随机移动的函数,其中黄线为视线线,变红色为找到主角,并记录此时主角的位置......https://blog.csdn.net/qq_54263076/article/details/125756448?spm=1001.2014.3001.5501并且能进行跳跃平台的人物(主角+NPC)都有CharacterPanel脚本,所以将平台检测写入这个脚本就行。

开始

1.可上下左右移的可跳上去的碰撞体平台

(1)创建平台预制体。精灵渲染组件+碰撞+平台效果碰撞器(可以单方面跳上去,但不能跳下来)。

 (2)创建platformMove脚本,用来控制平台上下或左右循环移动,加入这个预制体

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class platformMove : MonoBehaviour
  5. {
  6. public float waitTime = 0.5f;//定值等待时间
  7. private float _waitTime ;//等待时间
  8. public float Speed = 1;//速度
  9. public Vector3 StartPoi;//起始位置
  10. public Vector3 EndPoi;//需要移动目标位置
  11. private bool IsStoE=true;//是否是起始点到终止点的状态
  12. platformMove(Vector3 EndPoi)//构造函数,赋值终点
  13. {
  14. this.EndPoi = EndPoi;
  15. }
  16. // Start is called before the first frame update
  17. void Start()
  18. {
  19. _waitTime = waitTime;
  20. StartPoi = transform.position;//初始化起始位置
  21. /* EndPoi = transform.position + 2 * Vector3.right;//用来测试,实际的目标点是通过赋值*/
  22. }
  23. // Update is called once per frame
  24. void Update()
  25. {
  26. Vector2 StoE = (EndPoi - StartPoi).normalized;//起始点指向终止点的单位方向向量
  27. if (_waitTime > 0)
  28. {
  29. _waitTime -= Time.deltaTime;
  30. }
  31. else
  32. {
  33. if (IsStoE)//是起始点到终止点的状态
  34. {
  35. gameObject.transform.Translate(Speed * Time.deltaTime * StoE);
  36. if (Vector2.Dot((EndPoi- transform.position),StoE)<0)//如果到达终点 点乘夹角是180
  37. {
  38. _waitTime = waitTime;//等待时间重置
  39. IsStoE = false;//改变状态
  40. }
  41. }
  42. else {
  43. gameObject.transform.Translate(-Speed * Time.deltaTime * StoE);
  44. if (Vector2.Dot((StartPoi - transform.position), -StoE) < 0)//如果到达起点 点乘夹角是180
  45. {
  46. _waitTime = waitTime;//等待时间重置
  47. IsStoE = true;//改变状态
  48. }
  49. }
  50. }
  51. }
  52. }

(3)在随机生成地图的脚本中加入随机生成各种平台(可忽略

12.Unity2D 横版 TileMap随机生成简易横版瓦片地图+随机生成环境(花草树石)精灵图+2d-extras+协程的应用_ζั͡ ั͡雾 ั͡狼 ั͡✾的博客-CSDN博客_tilemap 随机Unity2D 横版 TileMap随机生成简易横版瓦片地图+随机生成环境(花草树石)精灵图+2d-extras+协程的应用。思路就是先生成瓦片,再进行创建能通过的通道。生成瓦片的时候先随机生成瓦片起始点,再通过一个协程从瓦片起始点开始延长不等长度(因为是横版游戏,在横向上的延伸要求高)注意需要修改环境瓦片地图的平铺轴和精灵图片的锚点位置,确保随机生成的精灵图是接触与地面而不是悬空的。(由于随机生成的环境精灵图大小不一样,但锚点都在中间,所以需要修改锚点) ...https://wulang.blog.csdn.net/article/details/125777090?spm=1001.2014.3001.5502

首先新建一个空物体用来统一管理生成平台预制体,及其图层

地图生成脚本更新(在调试阶段为了快速生成地图,我将yeid return从for循环外移出去了,以后写加载条的时候可以再放回去减少性能消耗)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.Tilemaps;
  5. public class GroundTIleMap : MonoBehaviour
  6. {
  7. public Tilemap ground_tilemap;//拖动获取地面瓦片地图
  8. public Tilemap environ_tilemap;
  9. public TileBase groundTile;//拖动获取地面规则瓦片Rule Tile,-
  10. public TileBase environTile;//拖动获取环境规则瓦片
  11. public Vector2Int lowerLeftCoo = new Vector2Int(-18, -7);//地图起始左下角位置
  12. public int width = 20;//地图宽度
  13. public int length = 100;//地图长度
  14. public float groundStartPro = 0.10f;//生成地面起始点的概率
  15. public Vector2Int groundLenRan = new Vector2Int(3, 10);//起始地面点生成的长度范围
  16. public float environmentRich = 0.5f;//环境丰富度
  17. public GameObject[] itemsRandom;//随机物品组
  18. public float itemsRich = 0.05f;//随机物品丰富度
  19. public GameObject[] platformRandom;//随机平台组
  20. public float platformRich = 0.05f;//平台丰富度
  21. private List<Vector2Int> canEndPlat=new List<Vector2Int>();//可能的平台终点落点
  22. // Start is called before the first frame update
  23. void Start()
  24. {
  25. StartCoroutine(GroundStartPoi());
  26. }
  27. // Update is called once per frame
  28. IEnumerator GroundStartPoi()//生成地面起始点 用协程可以缓慢一步步生成地图,性能消耗少
  29. {
  30. yield return null;
  31. ground_tilemap.ClearAllTiles();
  32. Debug.Log("开始生成地面");
  33. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  34. {
  35. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y); j++)
  36. {
  37. /* yield return null;*/
  38. bool IsGround = j < (this.width + 3) ? (Random.value <= groundStartPro) : (Random.value <= groundStartPro + 0.05);//三元表达式,地面三行更容易生成地面起始点
  39. if (IsGround) StartCoroutine(GroundExtension(i, j));
  40. }
  41. }
  42. Debug.Log("结束生成地面");
  43. StartCoroutine(ClearChannel());//执行完GroundStartPoi(),GroundExtension()生成地面,开始清除产生能走的通道
  44. }
  45. IEnumerator GroundExtension(int i, int j)//从地面起始点开始延长
  46. {
  47. yield return null;
  48. int groundLen = Random.Range(groundLenRan.x, groundLenRan.y);
  49. for (int m = i; m <= i + groundLen; m++)
  50. {
  51. /* yield return null;*/
  52. ground_tilemap.SetTile(new Vector3Int(m, j, 0), groundTile);
  53. }
  54. }
  55. //清除,产生通道,思路就是从底层有方块的地方,开始判断上面。如果没有方块的话,就清除俩层/三层的通道
  56. IEnumerator ClearChannel()
  57. {
  58. yield return null;
  59. Debug.Log("开始产生通道");
  60. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  61. {
  62. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y - 1); j++)//最高层上面必然没有方块,不需要判断,-1
  63. {
  64. if (ground_tilemap.GetTile(new Vector3Int(i, j, 0)) != null&& ground_tilemap.GetTile(new Vector3Int(i, j + 1, 0)) == null)//如果此处不为空方块,如果此处上方为空方块
  65. {
  66. ground_tilemap.SetTilesBlock(new BoundsInt(i - 2, j + 1, 0, 3, 3, 1), new TileBase[] { null, null, null, null, null, null, null, null, null });//将上方3x3格子置空
  67. }
  68. /* yield return null;*/
  69. }
  70. }
  71. Debug.Log("产生通道完成");
  72. StartCoroutine(GeneratePlatform());
  73. }
  74. IEnumerator GeneratePlatform()
  75. {
  76. yield return null;
  77. Debug.Log("开始生成平台");
  78. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  79. {
  80. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y); j++)
  81. {//Y平台
  82. if (ground_tilemap.GetTile(new Vector3Int(i, j, 0)) != null && ground_tilemap.GetTile(new Vector3Int(i, j + 1, 0)) == null)//起点 如果此处不为空方块,且上方为空
  83. {
  84. if (Random.value < platformRich*0.5)//随机
  85. {
  86. Vector2Int EndCellPoi = CanYEndPlat(i, j);
  87. if (EndCellPoi != Vector2Int.zero)//当y轴落点不为0,即列表返回了一个数据
  88. {
  89. //清空目标点与生成点的地面瓦片
  90. for (int n = j + 1; n < EndCellPoi.y; n++)
  91. {
  92. ground_tilemap.SetTile(new Vector3Int(i, n, 0), null);
  93. }
  94. //随机选取平台生成
  95. int r = Random.Range(0, platformRandom.Length);
  96. GameObject plat = platformRandom[r];
  97. plat.GetComponent<platformMove>().EndPoi = ground_tilemap.CellToWorld(new Vector3Int(EndCellPoi.x, EndCellPoi.y, 0));//平台赋值终点 转世界坐标
  98. //生成平台在PlatForm下统一图层管理
  99. Instantiate(plat, ground_tilemap.CellToWorld(new Vector3Int(i, j + 1, 0)), Quaternion.Euler(0, 0, 0), GameObject.Find("PlatForm").transform);
  100. };
  101. }
  102. }
  103. //X平台
  104. if (ground_tilemap.GetTile(new Vector3Int(i, j, 0)) == null && ground_tilemap.GetTile(new Vector3Int(i-1, j , 0)) == null)//起点 如果此处为空方块,且左边方为空
  105. {
  106. Debug.Log( " " + new Vector3Int(i, j, 0));
  107. if (Random.value < platformRich * 0.5)//随机
  108. {
  109. Vector2Int EndCellPoi = CanXEndPlat(i, j);
  110. if (EndCellPoi != Vector2Int.zero)//当x轴落点不为0,即列表返回了一个数据
  111. {
  112. //清空目标点与生成点的地面瓦片
  113. for (int m = i + 1; m < EndCellPoi.x; m++)
  114. {
  115. ground_tilemap.SetTile(new Vector3Int(m, j, 0), null);
  116. }
  117. //随机选取平台生成
  118. Debug.Log(EndCellPoi + " " + new Vector3Int(i, j, 0));
  119. int r = Random.Range(0, platformRandom.Length);
  120. GameObject plat = platformRandom[r];
  121. plat.GetComponent<platformMove>().EndPoi = ground_tilemap.CellToWorld(new Vector3Int(EndCellPoi.x, EndCellPoi.y, 0));//平台赋值终点 转世界坐标
  122. //生成平台在PlatForm下统一图层管理
  123. Instantiate(plat, ground_tilemap.CellToWorld(new Vector3Int(i, j, 0)), Quaternion.Euler(0, 0, 0), GameObject.Find("PlatForm").transform);
  124. };
  125. }
  126. }
  127. }
  128. }
  129. Debug.Log("结束生成平台");
  130. StartCoroutine(GenerateEnviron());
  131. }
  132. //可能Y轴上平台终点落点
  133. private Vector2Int CanYEndPlat(int i, int j)
  134. {
  135. canEndPlat.Clear();//清空可能终点落点列表
  136. for (int y = i + 1; y < (this.width + lowerLeftCoo.y); y++)
  137. {
  138. if (((ground_tilemap.GetTile(new Vector3Int(i, y, 0)) != null && ground_tilemap.GetTile(new Vector3Int(i, y + 1, 0)) == null)
  139. || (ground_tilemap.GetTile(new Vector3Int(i, y, 0)) == null && (ground_tilemap.GetTile(new Vector3Int(i - 1, y, 0)) != null || ground_tilemap.GetTile(new Vector3Int(i + 1, y, 0)) != null))
  140. )&& Mathf.Abs(y - j) > 3)//找到起点头上的方块为可能落点(起码要高度大于三)(有方块且头顶为空方块的地方,没方块的地方隔壁却有方块的地方)
  141. {
  142. canEndPlat.Add(new Vector2Int(i, y+1));
  143. }
  144. }
  145. if (canEndPlat.Count != 0)
  146. { //随机返回一个可能落点
  147. int r = Random.Range(0, canEndPlat.Count);
  148. return canEndPlat[r];
  149. }
  150. else { return Vector2Int.zero; }
  151. }
  152. //可能X轴上平台终点落点
  153. private Vector2Int CanXEndPlat(int i,int j) {
  154. canEndPlat.Clear();//清空可能终点落点列表
  155. for(int x=i+1;x< (this.length + lowerLeftCoo.x); x++)
  156. {
  157. if ((ground_tilemap.GetTile(new Vector3Int(x, j - 2, 0)) == null && ground_tilemap.GetTile(new Vector3Int(x, j +2, 0)) == null
  158. && ground_tilemap.GetTile(new Vector3Int(x, j -1, 0)) == null && ground_tilemap.GetTile(new Vector3Int(x, j+1, 0)) == null
  159. && ground_tilemap.GetTile(new Vector3Int(x, j, 0)) == null && ground_tilemap.GetTile(new Vector3Int(x+1,j , 0)) != null)
  160. &&(Mathf.Abs(x - i) > 2&& Mathf.Abs(x - i)< 6))//可能落点上下各俩块都为空,且右边有方块
  161. {
  162. canEndPlat.Add(new Vector2Int(x, j));
  163. }
  164. }
  165. if(canEndPlat.Count!=0)
  166. { //随机返回一个可能落点
  167. int r = Random.Range(0, canEndPlat.Count);
  168. return canEndPlat[r];
  169. }
  170. else { return Vector2Int.zero; }
  171. }
  172. //生成环境
  173. IEnumerator GenerateEnviron()
  174. {
  175. yield return null;
  176. Debug.Log("开始生成花草和随机物品");
  177. for (int i = lowerLeftCoo.x; i < (this.length + lowerLeftCoo.x); i++)
  178. {
  179. for (int j = lowerLeftCoo.y; j < (this.width + lowerLeftCoo.y); j++)
  180. {
  181. if (ground_tilemap.GetTile(new Vector3Int(i, j, 0)) == groundTile && ground_tilemap.GetTile(new Vector3Int(i, j + 1, 0)) == null)//如果此处为地面,上面为空方块
  182. {
  183. //花草
  184. if (Random.value < environmentRich)//随机
  185. { environ_tilemap.SetTile(new Vector3Int(i, j + 1, 0), environTile); }
  186. //随机物品
  187. if (Random.value < itemsRich)//随机
  188. {
  189. int index = Random.Range(0, itemsRandom.Length );
  190. Instantiate(itemsRandom[index], environ_tilemap.CellToWorld(new Vector3Int(i, j + 2, 0)), Quaternion.Euler(0, 0, 0),GameObject.Find("ItemsManager").transform); //坐标转换}
  191. }
  192. /* yield return null;*/
  193. }
  194. }
  195. }
  196. Debug.Log("结束生成花草和随机物品");
  197. }
  198. }

2.双向平台(实际是在按住下键瞬间取消了角色的碰撞体)

给平台预制体添加标签platform

角色的控制脚本更新

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. public class playerControl : MonoBehaviour
  5. {
  6. private Rigidbody2D rig;//2D刚体
  7. private CharacterPanel characterPanel;//获取角色面板
  8. private Animator ani;//动画控制器
  9. private AnimatorStateInfo state;//动画状态
  10. // Start is called before the first frame update
  11. void Start()
  12. {
  13. rig = GetComponent<Rigidbody2D>();//获取刚体
  14. ani = GetComponent<Animator>();//获取动画控制器
  15. characterPanel = GetComponent<CharacterPanel>();//获取角色面板
  16. }
  17. // Update is called once per frame
  18. void Update()
  19. {
  20. move();//移动函数
  21. attack();//攻击函数-四连击
  22. }
  23. private void move()
  24. { //水平,垂直俩个轴系
  25. float h = Input.GetAxis("Horizontal");
  26. float v = Input.GetAxis("Vertical");
  27. float dir = Input.GetAxisRaw("Horizontal");//方向-1 0 1
  28. //跳跃
  29. if (v > 0 && transform.GetComponent<CharacterPanel>().Iscanjump == true)
  30. {
  31. characterPanel.jump();
  32. }
  33. //长按高跳
  34. if (rig.velocity.y > 0 && Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow) && transform.GetComponent<CharacterPanel>().Iscanjump == false)
  35. {
  36. rig.velocity += Vector2.up * 0.2f;//长按高跳额外得到向上速度
  37. }
  38. //方向改变
  39. if (dir != 0)
  40. {
  41. transform.localScale = new Vector3(dir * Mathf.Abs(transform.localScale.x), transform.localScale.y, transform.localScale.z);//通过改变scale改变方向
  42. }
  43. //按键左右移动
  44. Vector3 vt = new Vector3(h, 0, 0).normalized;//vt为俩个轴系合成的方向向量,normalized单位化
  45. //移动动画
  46. if (dir != 0)
  47. {
  48. ani.SetBool("Ismove", true);
  49. }
  50. else { ani.SetBool("Ismove", false); }
  51. //空中左右移动,为地面jumpcharacterPanel.speedVertiacal倍
  52. if (h != 0 && transform.GetComponent<CharacterPanel>().Iscanjump == false)
  53. {
  54. gameObject.transform.Translate(vt * characterPanel.speed * characterPanel.jumpspeedVertiacal * Time.deltaTime);//通过这个函数来使用vt使得左右移动
  55. }
  56. //地面左右移动
  57. else { gameObject.transform.Translate(vt * characterPanel.speed * Time.deltaTime); }
  58. //按下键从平台上跳下来
  59. if (Input.GetKeyDown(KeyCode.S))
  60. {
  61. RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(0, -1),
  62. Mathf.Infinity, LayerMask.GetMask("tilemap"));
  63. if (hit.collider.CompareTag("platform"))//检测到平台
  64. {
  65. transform.GetComponent<Collider2D>().enabled = false;
  66. StartCoroutine(EnableCollider());
  67. }
  68. Debug.DrawRay(transform.position, new Vector2(0, -1), Color.blue);
  69. }
  70. }
  71. IEnumerator EnableCollider()
  72. {
  73. yield return new WaitForSeconds(0.15f);
  74. transform.GetComponent<Collider2D>().enabled = true;
  75. }
  76. private void attack() {
  77. state = ani.GetCurrentAnimatorStateInfo(0);
  78. //判断播放完
  79. if ((state.IsName("attack1") || state.IsName("attack2") || state.IsName("attack3") || state.IsName("attack4")) && state.normalizedTime >= 1.0f)
  80. {
  81. ani.SetInteger("attack", 0);
  82. }
  83. if (Input.GetKey(KeyCode.J))
  84. {
  85. if (state.IsName("idle")|| state.IsName("move") && ani.GetInteger("attack")==0 )
  86. {
  87. ani.SetInteger("attack", 1);
  88. } else if (state.IsName("attack1")&& ani.GetInteger("attack") == 1 )
  89. {
  90. ani.SetInteger("attack", 2);
  91. }
  92. else if (state.IsName("attack2") && ani.GetInteger("attack") == 2)
  93. {
  94. ani.SetInteger("attack", 3);
  95. }
  96. else if (state.IsName("attack3") && ani.GetInteger("attack") == 3)
  97. {
  98. ani.SetInteger("attack", 4);
  99. }
  100. }
  101. if (state.normalizedTime >=1.0f)
  102. {
  103. ani.SetFloat("normalizedTime", state.normalizedTime);
  104. }
  105. }
  106. }

为了防止平台到地面时按下键取消碰撞盒导致穿过地面,和由于离散检测敌人和角色有时会穿过地面,我们可以在角色共有脚中加入防本卡脱离机制,也是通过射线检测完成的

CharacterPanel脚步更新(如果不管这个bug可以忽略此内容)

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.UI;
  5. public class CharacterPanel : MonoBehaviour
  6. {
  7. public bool Iscanjump = false;//是否能跳跃,默认不能
  8. public float Hpmax = 100;//最大生命
  9. public float Hp = 100;//生命
  10. public float Atk = 10;//攻击力
  11. public float AtkRan = 1;//攻击浮动
  12. public float Def = 10;//防御力
  13. public float lookdir;//获取初始Scale.x,用于转向
  14. public float dropConst = 15;//下坠常数
  15. public float speed = 10;//地面移动速度
  16. public float jumpspeedUp = 20;//上升速度
  17. public float jumpspeedVertiacal = 0.5f;//空中左右移动速度
  18. private Rigidbody2D rig;//2D刚体
  19. private Animator ani;
  20. private Transform Canvas;//获取角色个人UI面板
  21. // Start is called before the first frame update
  22. void Start()
  23. {
  24. Canvas = transform.Find("Canvas");
  25. ani = transform.GetComponent<Animator>();
  26. rig = GetComponent<Rigidbody2D>();//获取刚体
  27. }
  28. // Update is called once per frame
  29. void FixedUpdate()
  30. {
  31. lookdir = transform.localScale.x;
  32. check();
  33. //跳跃优化手感
  34. Quickjump();
  35. //检测卡地面脱离
  36. OutLockGround();
  37. }
  38. //标准化检查
  39. private void check()
  40. {
  41. if (Hp > Hpmax) Hp = Hpmax;//血量不超过上限
  42. if (Hp <= 0) { Hp = 0;death(); };//血量不超过下限,且死亡
  43. }
  44. //受伤,其他脚本调用
  45. public void hurt(float atk)
  46. {
  47. float hurtnum= (20 * atk / (20 + Def)) + Random.Range(-AtkRan, AtkRan);
  48. //受伤动画 为什么要将触发器中的受伤动画移动在角色面板的hurt函数下?因为受伤不仅有角色攻击受伤,还有陷阱,掉落等伤害,所以直接血量减少时播放受伤动画更加好
  49. transform.GetComponent<Animator>().SetBool("Ishurt", true);
  50. StartCoroutine(endHurt());//开启协程结束受伤动画
  51. //伤害数值显示
  52. Canvas.GetComponent<CharaCanvas>().ShowHurtText(hurtnum);
  53. Hp -= hurtnum;
  54. }
  55. IEnumerator endHurt()
  56. {
  57. yield return 0;//此处暂停,下一帧执行
  58. transform.GetComponent<Animator>().SetBool("Ishurt", false);
  59. }
  60. //死亡
  61. private void death()
  62. {
  63. ani.SetBool("Isdeath",true);
  64. }
  65. //跳跃
  66. public void jump()
  67. {
  68. if (Iscanjump == true)
  69. {
  70. rig.velocity = new Vector2(0, jumpspeedUp);//设置刚体速度,给予向量
  71. }
  72. }
  73. //优化跳跃手感,迅速下落,放入帧频率更新函数里面
  74. public void Quickjump()
  75. {
  76. float a = dropConst * 5 - Mathf.Abs(rig.velocity.y);//通过下坠常数,空中速度快为0时,下坠常数a越大,即越快速 度过这个状态
  77. rig.velocity -= Vector2.up * a * Time.deltaTime;
  78. }
  79. //卡住地面脱离
  80. public void OutLockGround()
  81. {
  82. RaycastHit2D hit = Physics2D.Raycast(transform.position, new Vector2(0, -1),
  83. 0.5f, LayerMask.GetMask("tilemap"));
  84. if (hit.collider.CompareTag("ground"))//检测到地面
  85. {
  86. transform.Translate(new Vector3(0,1,0));
  87. }
  88. Debug.DrawRay(transform.position, new Vector2(0, -1), Color.blue);
  89. }
  90. //以下是敌人的调运行为函数,主角有自己的控制脚本
  91. //转向
  92. public void Turndir()
  93. {
  94. transform.localScale = new Vector3(-lookdir, transform.localScale.y, transform.localScale.z);//通过改变scale改变方向
  95. }
  96. //移动
  97. public void move()
  98. {
  99. if (lookdir == 0) lookdir =0.001f;//预防除零问题弹错
  100. Vector3 vt = new Vector3(lookdir/Mathf.Abs(lookdir), 0, 0);
  101. //空中左右移动,为地面jumpcharacterPanel.speedVertiacal倍
  102. if (Iscanjump == false)
  103. {
  104. gameObject.transform.Translate(jumpspeedVertiacal * speed * Time.deltaTime * vt);//通过这个函数来使用vt使得左右移动
  105. }
  106. //地面左右移动
  107. else { gameObject.transform.Translate(speed * Time.deltaTime * vt); }
  108. ani.SetBool("Ismove", true);
  109. }
  110. //等待
  111. public void idle()
  112. {
  113. ani.SetBool("Ismove", false);
  114. }
  115. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/178675
推荐阅读
相关标签
  

闽ICP备14008679号