Unity,如何在单个对象上拥有多个2D碰撞器

huangapple go评论62阅读模式
英文:

Unity, how to have multiple 2D collider on single object

问题

I have a tower defense game. I want to modify the walk animation of enemies, so that depending on their position on the map, I can use front, left, right walk animations.

我有一个塔防游戏。我想修改敌人的行走动画,根据他们在地图上的位置,我可以使用前、左、右行走动画。

I want to use 2D colliders, so that when enemies enter the new zone, I can detect it with TriggerEnter and change the walk animation.

我想使用2D碰撞器,这样当敌人进入新区域时,我可以使用TriggerEnter来检测并更改行走动画。

Which kind of collider should I use to achieve this? I mean, which collider should I use to have different colliders side by side like in the image?

要实现这个,我应该使用哪种类型的碰撞器?我的意思是,我应该使用哪种碰撞器才能像图片中那样并排放置不同的碰撞器?

Thanks.

谢谢。

Update:
In this example, you can see enemies moving following a path, and in this situation, I should detect the position to have another animation, for example, profile walk.

更新:
在这个示例中,你可以看到敌人沿着路径移动,而在这种情况下,我应该检测位置以获得另一种动画,例如侧面行走。

英文:

I have a tower defense game. I want to modify the walk animation of ennemies, so that depending of their position on the map, i can use front, left, right walk animations.

I want to use 2D colliders, so that when an ennemies enter inside the new zone, i can detect with TriggerEnter and change the animation of the Walk.

Which kind of collider should i use to achieve this ? I mean, Which collider should I use to have different colliders side by side like in the image ?

Thanks.

Unity,如何在单个对象上拥有多个2D碰撞器

Update:
In this example you can see ennemies moving following a path and in this situation, i should detect the position to have another animation, for example profile walk.
Unity,如何在单个对象上拥有多个2D碰撞器

答案1

得分: 1

以下是翻译好的部分:

  1. 第一种方法

您可以将当前的X轴与下一个X轴位置进行比较,然后简单地在X轴上翻转您的精灵。

private float _currentPosOnXAxis;
public SpriteRenderer _spriteRenderer;

private void Update()
{
    FaceDirection();
}

private void FaceDirection()
{
    if(transform.position.x <= _currentPosOnXAxis)
    {
        _spriteRenderer.flipX = true;
    }
    else
    {
        _spriteRenderer.flipX = false;
    }

    _currentPosOnXAxis = transform.position.x;
}
  1. 第二种方法

第二种方法与您已经尝试过的方法类似。基本上,您使用多个检查点对象,不是作为触发器,而是作为位置点。您有一个世界上每个敌人都应该按特定顺序遵循的点的列表,然后检查敌人的X位置与下一个检查点X位置。

因此,您检查的是如果敌人的X位置大于检查点X位置,那么意味着敌人在检查点的右侧,所以敌人正在向左移动,但如果敌人的X位置小于检查点X位置,那么意味着敌人在左侧并且正在向右移动。

您可以使用所有检查点的列表,从索引0开始,并使用触发器确定敌人是否通过了检查点并增加索引号。

public SpriteRenderer _spriteRenderer;
public List<Transform> _checkpointsTransforms;
private int _currentIndex = 0;
private float _checkpointXPosition = _checkpointsTransforms[_currentIndex];

private void Update()
{
    if(transform.position.x > _checkpointXPosition)
    {
        _spriteRenderer.flipX = true;
    }
    else
    {
        _spriteRenderer.flipX = false;
    }
}

private void OnTriggerEnter2D(Collider2D col)
{
    if(col.CompareTag("CheckPoint"))
    {
       _currentIndex++;
       if(_currentIndex < _checkpointsTransforms.Count)
       {
           _checkpointXPosition = _checkpointsTransforms[_currentIndex].position.x;
       }
    }
}

注意: 请记得根据需要设置您的Tag。我建议使用第一种方法,因为它更快速,需要更少的内存。另外,第二种方法意味着对于每个地图,您需要创建所有所需的检查点,所有敌人都应该有对这些检查点的引用等等。

英文:

There are 2 ways to achieve the face direction.

  1. First Method

You can compare the current X-Axis with the next one and simply flip your sprite on the X-Axis.

private float _currentPosOnXAxis;
public SpriteRenderer _spriteRenderer;

private void Update()
{
    FaceDirection();
}

private void FaceDirection()
{
    if(transform.position.x &lt;= _currentPosOnXAxis)
    {
        _spriteRenderer.flipX = true;
    }
    else
    {
        _spriteRenderer.flipX = false;
    }

    _currentPosOnXAxis = transform.position.x;
}
  1. Second Method

The second method is similar to what you have already tried. Basically you use multiple checkpoints objects not as triggers but as position points. You have a list of points on the world that each enemy should follow in a specific order and you check the enemy's X position with the next checkpoint X position.

So what you check is that if the enemy's X position is bigger than the checkpoint X position, that means the enemy is on the right side of the checkpoint so the enemy is moving to the left, but if the enemy's X position is less than the checkpoint X position, that means the enemy is on the left side and is moving to the right.

You can use a list of all the checkpoints and you start from 0 index and you can use a trigger to determine that the enemy has pass through the checkpoint and increase the index number.

public SpriteRenderer _spriteRenderer;
public List&lt;Transform&gt; _checkpointsTransforms;
private int _currentIndex = 0;
private float _checkpointXPosition = _checkpointsTransforms[_currentIndex];


private void Update()
{
    if(transform.position.x &gt; _checkpointXPosition)
    {
        _spriteRenderer.flip = true;
    }
    else
    {
        _spriteRenderer.flip = false;
    }
}

private void OnTriggerEnter2D(Collider2D col)
{
    if(col.CompareTag(&quot;CheckPoint&quot;))
    {
       _currentIndex++;
       if(currentIndex &lt; _checkpointsTransforms.Count)
       {
           _checkpointXPosition = _checkpointsTransforms[_currentIndex];
       }
    }
}

Note: Remember to set your Tag accordingly

I would recommend the first method because is much more faster and it requires less memory. Also the second method it means that for each map you need to create all the checkpoints that you need and all the enemies should have a reference to those checkpoints and so on.

答案2

得分: 0

我最终采用了这个解决方案。谢谢大家。

Vector2 currentDirection = (points.ways[wayIndex].wayPoints[wayPointIndex].position - transform.position).normalized;
if (Mathf.Abs(currentDirection.x) >= Mathf.Abs(currentDirection.y))
{
//角色正在横向移动
if (currentDirection.x > 0)
{
print("向右移动");
}
else
{
print("向左移动");
}
}
else
{
//角色正在纵向移动

if (currentDirection.y > 0)
{
    print("向上移动");
}
else
{
    print("向下移动");
}

}

英文:

I finally used this solution. Thank you all

            Vector2 currentDirection = (points.ways[wayIndex].wayPoints[wayPointIndex].position - transform.position).normalized;
        if (Mathf.Abs(currentDirection.x) &gt;= Mathf.Abs(currentDirection.y))
        {
            //Character is moving sideways
            if (currentDirection.x &gt; 0)
            {
                print(&quot;Move Rigth&quot;);
            }
            else
            {
                print(&quot;Move Left&quot;);
            }
        }
        else
        {
            //Character is moving straight

            if (currentDirection.y &gt; 0)
            {
                print(&quot;Move Up&quot;);

            }
            else
            {
                print(&quot;Move Down&quot;);

            }
        }

huangapple
  • 本文由 发表于 2023年5月8日 01:43:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76195400.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定