You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

攻击时Collider未触发导致史莱姆不消失的技术问题求助

问题描述

我按照视频步骤实现功能,但剑的Collider激活时,史莱姆并未消失。即使开启了史莱姆的Collider Trigger,两者仍无交互。
预期效果:点击时剑的Collider激活,击中史莱姆后该对象销毁。


相关代码

Enemy脚本

public class Enemy : MonoBehaviour
{
    public Enemy enemy;

    public float health = 1;
    public float maxhealth = 1;

    public void Start()
    {
        health = maxhealth;
    }

    public float Health
    {
        set
        {
            health = value;
            if (health <= 0)
            {
                TakeDamage();
            }
        }
        get
        {
            return health;
        }
    }

    public void TakeDamage()
    {
        Destroy(gameObject);
    }
}

swordattack脚本

public class swordattack : MonoBehaviour
{
    public Collider2D swordcollider;
    public float damage = 3;
    
    Vector2 rightattackoff;

    private void Start()
    {
        rightattackoff = transform.position;
    }

    public void AttackRight()
    {
        swordcollider.enabled = true;
        transform.localPosition = rightattackoff;
    }

    public void AttackLeft()
    {
        swordcollider.enabled = true;
        transform.localPosition = new Vector3(rightattackoff.x * -1, rightattackoff.y);
    }

    public void StopAttack()
    {
        swordcollider.enabled = false;
    }

    private void OnTriggerEnter2D(Collider2D other)
    {
        Debug.Log("afsafhagfagjksdjg");
        if (other.gameObject.CompareTag("Enemy"))
        {
            Enemy enemy = other.GetComponent<Enemy>();
            if(enemy != null)
            {
                enemy.Health -= damage;
            }
        }
    }
}

playercontrol脚本

public class playercontrol : MonoBehaviour
{
    public float moveSpeed = 1f;
    public float collisionOffset = 0.05f;
    public ContactFilter2D movementFilter;
    public swordattack swordAttack;

    Vector2 movementInput;
    Rigidbody2D rig;
    List<RaycastHit2D> castCollisions = new List<RaycastHit2D>();
    Animator animator;
    SpriteRenderer spRen;
    bool canMove = true;

    void Start()
    {
        rig = GetComponent<Rigidbody2D>();
        animator = GetComponent<Animator>();
        spRen = GetComponent<SpriteRenderer>();
    }

    private void FixedUpdate()
    {
        if (canMove)
        {
            if (movementInput != Vector2.zero)
            {
                bool success = TryMove(movementInput);
                if (!success)
                {
                    success = TryMove(new Vector2(movementInput.x, 0));
                    if (!success)
                    {
                        success = TryMove(new Vector2(0, movementInput.y));
                    }
                }
                animator.SetBool("isMoving", success);
            }
            else
            {
                animator.SetBool("isMoving", false);
            }

            if (movementInput.x < 0)
            {
                spRen.flipX = true;
            }
            else if (movementInput.x > 0)
            {
                spRen.flipX = false;
            }
        }
    }

    private bool TryMove(Vector2 direction)
    {
        int count = rig.Cast(
                direction,
                movementFilter,
                castCollisions,
                moveSpeed * Time.fixedDeltaTime + collisionOffset);
        if (count == 0)
        {
            rig.MovePosition(rig.position + direction * moveSpeed * Time.fixedDeltaTime);
            return true;
        }
        else
            return false;
    }

    void OnMove(InputValue movementValue)
    {
        movementInput = movementValue.Get<Vector2>();
    }

    void OnFire()
    {
        animator.SetTrigger("swordAttack");
    }

    public void SwordAttack()
    {
        LockMovement();
        if (spRen.flipX == true)
        {
            swordAttack.AttackLeft();
        }
        else
        {
            swordAttack.AttackRight();
        }
    }

    public void EndSwordAttack()
    {
        UnlockMovement();
        swordAttack.StopAttack();
    }

    void LockMovement()
    {
        canMove = false;
    }

    void UnlockMovement()
    {
        canMove = true;
    }
}

修复方案

1. 基础配置检查

  • 确认史莱姆对象的Tag设置为"Enemy",且挂载了Enemy脚本
  • 剑的Collider2D必须勾选Is Trigger=true,史莱姆的Collider不需要设为Trigger(Trigger仅需一方开启)
  • 检查物理层碰撞矩阵(Edit → Project Settings → Physics2D → Layer Collision Matrix),确保剑所在层与Enemy层的碰撞权限是开启的

2. 修复Enemy脚本冗余与日志排查

删掉冗余的public Enemy enemy;字段,添加日志确认逻辑触发:

public class Enemy : MonoBehaviour
{
    public float health = 1;
    public float maxhealth = 1;

    public void Start()
    {
        health = maxhealth;
    }

    public float Health
    {
        set
        {
            health = value;
            Debug.Log($"Enemy当前血量: {health}");
            if (health <= 0)
            {
                TakeDamage();
            }
        }
        get
        {
            return health;
        }
    }

    public void TakeDamage()
    {
        Debug.Log("Enemy被销毁");
        Destroy(gameObject);
    }
}

3. 修正剑的位置逻辑

swordattack脚本中,初始位置应使用本地坐标而非世界坐标,避免攻击时位置偏移:

private void Start()
{
    rightattackoff = transform.localPosition; // 替换transform.position
}

4. 验证动画事件时机

检查动画控制器中swordAttack动画的关键帧,确保SwordAttack()和EndSwordAttack()事件绑定在碰撞框确实覆盖敌人的帧区间内,避免Collider刚启用就被关闭。

内容的提问来源于stack exchange,提问作者Rigel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 02:43:13