目录
结束标志1
人物从平台上落下,即小人走到空的地方,跳了一下没有检测到碰撞,则游戏结束
在Character下面创建一个空物体,我们将空物体放在任务底部(射线是从它下面发下去的),在跳起落下的一课判断有没有射中平台的Clidder,射中活,不中亡
做完这些记得Apply,应用到所有里
然后转到Character加载的代码文件PlayerController.cs中
记录下原始代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class PlayerController : MonoBehaviour {
/// <summary>
/// 是否向左移动,反之向右
/// </summary>
private bool isMoveLeft = false;
/// <summary>
/// 添加一个过滤,如果当前玩家正在跳跃就给它忽略掉
/// 如果没有在跳跃,就让其跳跃(不然一直点会一直立在空中)
/// </summary>
private bool isJumping = false;
private Vector3 nextPlatformLeft, nextPlatformRight;
private ManageVars vars;
private void Awake()
{
vars = ManageVars.GetManageVars();
}
// Update is called once per frame
void Update () {
if (GameManager.Instance .IsGameStarted==false||GameManager.Instance .IsGameOver)
{
return;
}
if (Input .GetMouseButton (0)&&isJumping==false)
{
EventCenter.Broadcast(EventDefine.DecidePath);
isJumping = true;
Vector3 mousePos = Input.mousePosition;
//点击的是左边屏幕
if (mousePos.x <= Screen.width / 2)
{
isMoveLeft = true;
}
else if (mousePos.x > Screen.width / 2)
{
isMoveLeft = false;
}
Jump();
}
}
private void Jump()
{
if (isMoveLeft)
{
transform.localScale = new Vector3(-1, 1, 1);
transform.DOMoveX(nextPlatformLeft.x ,0.2f);
//有重力效果
transform.DOMoveY(nextPlatformLeft.y+0.6f, 0.01f);
}
//
else
{
transform.localScale = Vector3.one;
transform.DOMoveX(nextPlatformRight.x, 0.2f);
transform.DOMoveY(nextPlatformRight.y + 0.6f, 0.01f);
}
}
/// <summary>
///碰撞检测条件:
///1、双方都有Collider2D组件
///2、其中一方还要有RigidBody组件(给该物体物理性质,如自由落体...)
///3、这里使用OnTriggerEnter2D函数,要有一个组件勾选isTrigger组件
///但是在他们任意两个上面勾选isTrigger,小人都会掉下来,但是不勾选此方法无法生效
///4、因而我们在人物身上再加一个CircleCollider(专门负责isTrigger)
///5、锁定住Character的RigidBody里的Constraints里面的Freeze Rotation z,
///不然会重心不稳来回倒(撞一撞)
///6、落到平台上说明跳跃结束,将isJumping设为false
/// </summary>
/// <param name="collision"></param>
private void OnTriggerEnter2D(Collider2D collision)
{
isJumping = false;
if (collision.tag=="Platform")
{
Vector3 currentPlatformPos = collision.gameObject.transform.position;
nextPlatformLeft = new Vector3(currentPlatformPos .x-
vars .nextXPos ,currentPlatformPos .y+vars .nextYPos,currentPlatformPos.z);
nextPlatformRight = new Vector3(currentPlatformPos.x +
vars.nextXPos, currentPlatformPos.y + vars.nextYPos, currentPlatformPos.z);
}
}
}
现在要改的是Update中的东西
如果人物在向下落,向下落我们需要拿到其身上的Rigidbody
初始化:
private Rigidbody2D my_body;
在Awake()函数中赋值
my_body = GetComponent<Rigidbody2D>();
如果人物往下落,并且射线检测没有检测到(落不到platform上),且游戏还没有结束,则判断现在游戏结束
然后再将Box Clidder 2D这个属性取消勾选
我们需要拿到Character身上的Render
private SpriteRenderer spriteRenderer;
在Awake()函数中赋值
spriteRenderer = GetComponent<SpriteRenderer>();
在Update()中判断一下:
//游戏结束判断
//如果玩家Y轴方向的速度<0(即在下落),进行射线检测
//如果人物往下落,并且射线检测没有检测到(落不到platform上),且游戏还没有结束
//则判断现在游戏结束
if (my_body.velocity.y<0&& IsRayPlatform()==false&&GameManager.Instance.IsGameOver==false)
{
//跳的时候要将小人的层级
spriteRenderer.sortingLayerName = "Default";
//拿到其身上额BoxClidder
GetComponent<BoxCollider2D>().enabled = false;
//至此完成对人物的处理
GameManager.Instance.IsGameOver = true;
//调用结束面板
//TO DO
}
射线检测方法
这个就是我们之前加在Character身上的小Clidder(射线起始点),定义出来:
public Transform rayDown;
定义出检测的是哪一层:
public LayerMask platformLayer;
/// <summary>
/// 定义一个射线检测的方法
/// </summary>
private bool IsRayPlatform()
{
//起点(rayDown)位置,方向,距离,哪一个层级(先去定义出来,platform这一层)
RaycastHit2D hit =Physics2D.Raycast(rayDown.position,Vector2.down,1f, platformLayer);
//最外层判断是否射到物体是安全校验
if (hit.collider!=null)
{
//平台的标签(平台的名字)叫Platform
if (hit.collider.tag == "Platform")
{
return true;
}
}
return false;
}
设置Platform层
再然后选择所有的平台,所有Tag是Platform的Layer也设置为Platform,但是选中不更改子物体的层级(之后还有别的用处) ,
然后我们再把修改过的Character Apply一下
记得要修改:
结束标志2(碰到钉子有特效)
不是让人物掉下去,而是让人物消失(直接distroy掉),然后播放一个死亡的栗子特效
做法:小人正在跳(isJumping)的时候向左右两边射线检测,如果检测到的物体是障碍物时,我们就让其触发死亡特效2
定义射线起始点
Ctrl+D可以复制一份
代码里修改:
public Transform rayDown,rayRight,rayLeft;
同时我们需要在层级里加一个障碍物层,用来对障碍物进行射线检测的:obstacleLayer
public LayerMask platformLayer,obstacleLayer;
然后方法同上,建立obstacal层
增加一个障碍物的标签
钉子我们晚些再管,我们先把其他组合平台的Obstacle全选,并将其的Layers设置成Obstacle(方法如上),但是这里选择Yes!!!
记得点击Apply!!!
方法同上修改SpikePlatformeRight
添加一个检测障碍物的射线检测方法函数
/// <summary>
/// 定义一个射线检测的方法(是否检测到障碍物)
/// </summary>
private bool IsRayObstacle()
{
//起点(rayDown)位置,方向,距离,哪一个层级(先去定义出来,platform这一层)
RaycastHit2D leftHit = Physics2D.Raycast(rayLeft.position, Vector2.left, 20f, obstacleLayer);
RaycastHit2D rightHit = Physics2D.Raycast(rayRight.position, Vector2.right, 20f, obstacleLayer);
//最外层判断是否射到物体是安全校验
if (leftHit.collider != null)
{
//如果左边的射线检测到平台的标签(平台的名字)叫Obstacle,且是向左跳,则true
if (leftHit.collider.tag == "Obstacle"&& isMoveLeft==true)
{
return true;
}
}
if (rightHit.collider != null)
{
//如果右边的射线检测到平台的标签(平台的名字)叫Obstacle,且是向右跳,则true
if (leftHit.collider.tag == "Obstacle"&& isMoveLeft==false)
{
return true;
}
}
return false;
}
在Update ()函数中再添加一种关于死亡的if判断
if (isJumping && IsRayObstacle() && GameManager.Instance.IsGameOver==false)
{
GameManager.Instance.IsGameOver = true;
Destroy(gameObject);
}
小贴士:(显示射线)
在Update()里添加显示射线的代码,可以方便我们观察射线有多长,是否够我们接触到撞击面(boxclidder)射线检测是射线和boxclidder相接触才出发的
//绘制射线需要传递的是射线起点,方向*长度,颜色
Debug.DrawRay(rayDown.position, Vector2.down*20,Color.red);
Debug.DrawRay(rayLeft.position, Vector2.left*20, Color.red);
Debug.DrawRay(rayRight.position, Vector2.right*20, Color.red);
修改后的新代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
public class PlayerController : MonoBehaviour {
public Transform rayDown, rayLeft, rayRight;
/// <summary>
/// 定义出检测的是哪一层
/// </summary>
public LayerMask platformLayer,obstacleLayer;
/// <summary>
/// 是否向左移动,反之向右
/// </summary>
private bool isMoveLeft = false;
/// <summary>
/// 添加一个过滤,如果当前玩家正在跳跃就给它忽略掉
/// 如果没有在跳跃,就让其跳跃(不然一直点会一直立在空中)
/// </summary>
private bool isJumping = false;
private Vector3 nextPlatformLeft, nextPlatformRight;
private ManageVars vars;
private Rigidbody2D my_body;
private SpriteRenderer spriteRenderer;
private void Awake()
{
vars = ManageVars.GetManageVars();
spriteRenderer = GetComponent<SpriteRenderer>();
my_body = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update () {
//绘制射线需要传递的是射线起点,方向*长度,颜色
Debug.DrawRay(rayDown.position, Vector2.down*20,Color.red);
Debug.DrawRay(rayLeft.position, Vector2.left*20, Color.red);
Debug.DrawRay(rayRight.position, Vector2.right*20, Color.red);
if (GameManager.Instance .IsGameStarted==false||GameManager.Instance .IsGameOver)
{
return;
}
if (Input .GetMouseButton (0)&&isJumping==false)
{
EventCenter.Broadcast(EventDefine.DecidePath);
isJumping = true;
Vector3 mousePos = Input.mousePosition;
//点击的是左边屏幕
if (mousePos.x <= Screen.width / 2)
{
isMoveLeft = true;
}
else if (mousePos.x > Screen.width / 2)
{
isMoveLeft = false;
}
Jump();
}
//游戏结束判断
//如果玩家Y轴方向的速度<0(即在下落),进行射线检测
//如果人物往下落,并且射线检测没有检测到(落不到platform上),且游戏还没有结束
//则判断现在游戏结束
if (my_body.velocity.y<0&& IsRayPlatform()==false&&GameManager.Instance.IsGameOver==false)
{
//跳的时候要将小人的层级
spriteRenderer.sortingLayerName = "Default";
//拿到其身上额BoxClidder
GetComponent<BoxCollider2D>().enabled = false;
//至此完成对人物的处理
GameManager.Instance.IsGameOver = true;
//调用结束面板
//TO DO
}
if (isJumping && IsRayObstacle() && GameManager.Instance.IsGameOver==false)
{
GameManager.Instance.IsGameOver = true;
Destroy(gameObject);
}
}
/// <summary>
/// 定义一个射线检测的方法(是否检测到平台)
/// </summary>
private bool IsRayPlatform()
{
//起点(rayDown)位置,方向,距离,哪一个层级(先去定义出来,platform这一层)
RaycastHit2D hit =Physics2D.Raycast(rayDown.position,Vector2.down,20f, platformLayer);
//最外层判断是否射到物体是安全校验
if (hit.collider!=null)
{
//平台的标签(平台的名字)叫Platform
if (hit.collider.tag == "Platform")
{
return true;
}
}
return false;
}
/// <summary>
/// 定义一个射线检测的方法(是否检测到障碍物)
/// </summary>
private bool IsRayObstacle()
{
//起点(rayDown)位置,方向,距离,哪一个层级(先去定义出来,platform这一层)
RaycastHit2D leftHit = Physics2D.Raycast(rayLeft.position, Vector2.left, 20f, obstacleLayer);
RaycastHit2D rightHit = Physics2D.Raycast(rayRight.position, Vector2.right, 20f, obstacleLayer);
//最外层判断是否射到物体是安全校验
if (leftHit.collider != null)
{
//如果左边的射线检测到平台的标签(平台的名字)叫Obstacle,且是向左跳,则true
if (leftHit.collider.tag == "Obstacle"&& isMoveLeft==true)
{
return true;
}
}
if (rightHit.collider != null)
{
//如果右边的射线检测到平台的标签(平台的名字)叫Obstacle,且是向右跳,则true
if (rightHit.collider.tag == "Obstacle"&&isMoveLeft==false)
{
return true;
}
}
return false;
}
private void Jump()
{
if (isMoveLeft)
{
transform.localScale = new Vector3(-1, 1, 1);
transform.DOMoveX(nextPlatformLeft.x ,0.2f);
//有重力效果
transform.DOMoveY(nextPlatformLeft.y+0.6f, 0.01f);
}
//
else
{
transform.localScale = Vector3.one;
transform.DOMoveX(nextPlatformRight.x, 0.2f);
transform.DOMoveY(nextPlatformRight.y + 0.6f, 0.01f);
}
}
/// <summary>
///碰撞检测条件:
///1、双方都有Collider2D组件
///2、其中一方还要有RigidBody组件(给该物体物理性质,如自由落体...)
///3、这里使用OnTriggerEnter2D函数,要有一个组件勾选isTrigger组件
///但是在他们任意两个上面勾选isTrigger,小人都会掉下来,但是不勾选此方法无法生效
///4、因而我们在人物身上再加一个CircleCollider(专门负责isTrigger)
///5、锁定住Character的RigidBody里的Constraints里面的Freeze Rotation z,
///不然会重心不稳来回倒(撞一撞)
///6、落到平台上说明跳跃结束,将isJumping设为false
/// </summary>
/// <param name="collision"></param>
private void OnTriggerEnter2D(Collider2D collision)
{
isJumping = false;
if (collision.tag=="Platform")
{
Vector3 currentPlatformPos = collision.gameObject.transform.position;
nextPlatformLeft = new Vector3(currentPlatformPos .x-
vars .nextXPos ,currentPlatformPos .y+vars .nextYPos,currentPlatformPos.z);
nextPlatformRight = new Vector3(currentPlatformPos.x +
vars.nextXPos, currentPlatformPos.y + vars.nextYPos, currentPlatformPos.z);
}
}
}