Unity引擎2D游戏开发,撞墙判定和等候计时

发布时间 2023-12-25 17:10:59作者: 心霖の雨

撞墙判定

将野猪绑定Physics Check脚本,并将Ground Layer选中Ground,调整Button Offset到脚边,Check Radius为0.1,即可判定悬崖
image

physics Check脚本中添加一些变量,用于墙壁判定逻辑

public bool touchLeftWall;
public bool touchRightWall;

public Vector2 leftOffset;
public Vector2 rightOffset;

接着在Check()方法中,写入以下代码

// 墙体判断
touchLeftWall = Physics2D.OverlapCircle((Vector2)transform.position + leftOffset, checkRadius, groundLayer);
touchLeftWall = Physics2D.OverlapCircle((Vector2)transform.position + rightOffset, checkRadius, groundLayer);

接着在OnDrawGizmosSelected()方法中写入以下代码进行绘制

Gizmos.DrawWireSphere((Vector2)transform.position + leftOffset, checkRadius);
Gizmos.DrawWireSphere((Vector2)transform.position + rightOffset, checkRadius);

然后野猪和玩家身上会多出两个锚点,将那两个锚点进行移动,移动至身体两侧
image

image

自动获取碰撞体锚点

Physics Check代码中,添加一行全局变量

// 自动或手动找到碰撞体位置
public bool manual;

Awake()方法内,增加如下代码

if(!manual)
{
    rightOffset = new Vector2((capsuleCollider.bounds.size.x + capsuleCollider.offset.x) / 2, capsuleCollider.bounds.size.y / 2);
    leftOffset = new Vector2(-rightOffset.x, rightOffset.y);
}

解决碰撞体碰撞却没有判定的问题

将Composite Collider 2D中Geometry Type修改为Polygons
image

Outlines为,边缘线部分进行判定
Polygons为,内部整体作为判定

碰墙转身

Enemy中,添加一个新的全局变量

PhysicsCheck physicsCheck;

Awake()中,获取该组件

physicsCheck = GetComponent<PhysicsCheck>();

Update()中,添加判定代码

if (physicsCheck.touchLeftWall || physicsCheck.touchRightWall)
{
    transform.localScale = new Vector3(faceDirect.x, 1, 1);
}

只要判定碰撞到墙,则将Scale的X轴进行翻转

计时器延迟转身

Enemy中添加三个全局变量

[Header("计时器")]
public float waitingTime;
public float waitingTimeCounter;
public bool wait;

Awake()方法中,初始化waitingTimeCounter

waitingTimeCounter = waitingTime;

编写TimeCounter()方法,进行计时

public void TimeCounter()
{
    if(wait)
    {
        waitingTimeCounter -= Time.deltaTime;
        if(waitingTimeCounter < 0)
        {
            wait = false;
            waitingTimeCounter = waitingTime;
            transform.localScale = new Vector3(faceDirect.x, 1, 1);
        }
    }
}

改写Update()方法,并将walk的布尔值改为false,这样使得撞墙时,不播放走路动画

if ((physicsCheck.touchLeftWall && faceDirect.x < 0) || (physicsCheck.touchRightWall && faceDirect.x > 0))
{
    wait = true;
    animator.SetBool("walk",false);
}
TimeCounter();

解决野猪抽搐与未碰墙即转身的问题

Update()方法内的if语句只判定面朝方向的锚点

private void Update()
{
    // 实时方向
    faceDirect = new Vector3(-transform.localScale.x, 0, 0);
    if ((physicsCheck.touchLeftWall && faceDirect.x < 0) || (physicsCheck.touchRightWall && faceDirect.x > 0))
    {
        wait = true;
        animator.SetBool("walk",false);
    }
    TimeCounter();
}