【问题标题】:Enabling and Disabling Collider based on direction in Unity在 Unity 中根据方向启用和禁用碰撞器
【发布时间】:2019-03-24 23:49:21
【问题描述】:

我认为这很简单,但由于某种原因,我无法弄清楚。我的玩家周围有 4 个子游戏对象,每个都有自己的对撞机。我需要能够根据角色移动的方向启用和禁用子游戏对象。因此,如果玩家向右移动,则左侧、顶部和底部碰撞器将被禁用,而仅右侧碰撞器处于活动状态。如果玩家向上移动,则左侧、右侧和底部碰撞器将被禁用,只留下顶部碰撞器。其他两个方向的原理相同。但是由于某种原因,我的代码适用于左右方向,但是当我的角色向上或向下移动时,它会禁用除左侧碰撞器之外的所有内容。我能得到一些帮助吗?这是我的代码:

public BasicNPCPrototype NPCPrototype;
    private bool nearNPC = false;

    public bool facingRight;
    public bool facingUp;

    public GameObject RightCollider;
    public GameObject LeftCollider;
    public GameObject TopCollider;
    public GameObject BottomCollider;

    // Use this for initialization
    protected override void Start()
    {
        base.Start();
    }

    // Update is called once per frame
    protected override void Update()
    {
        // Call the GetInput Function
        GetInput();

        // Call the CheckIfNear function
        CheckIfNear();

        // Call the CheckDirection function
        CheckDirection();

        // Call the DisableInteractionColliders function
        DisableInteractionColliders();

        base.Update();
    }

    void GetInput()
    {
        if(playerActive)
        {
            direction = Vector2.zero;

            // Get the horizontal Axis and put in the X value of "direction"
            direction.x = Input.GetAxisRaw("Horizontal");
            // Get the Vertical Axis and put in the Y value of "direction"
            direction.y = Input.GetAxisRaw("Vertical");
        }    
    }

    // Look at our movement direction and decide which way were facing
    void CheckDirection()
    {
        if (direction.x > 0)
        {
            facingRight = true;
            facingUp = false;
        }
        else if (direction.x < 0)
        {
            facingRight = false;
            facingUp = false;
        }

        if (direction.y > 0) // && !facingRight)
        {
            facingUp = true;
            facingRight = false;
        }
        else if (direction.y < 0) // && !facingRight)
        {
            facingUp = false;
            facingRight = false;
        }

    }

    // Look at what direction the Player is facing and disable/enable the correct colliders to account for it
    void DisableInteractionColliders()
    {
        // WIP
        if(facingRight)
        {
            RightCollider.SetActive(true);
            LeftCollider.SetActive(false);
            TopCollider.SetActive(false);
            BottomCollider.SetActive(false);
        } else if(!facingRight)
        {
            LeftCollider.SetActive(true);
            RightCollider.SetActive(false);
            TopCollider.SetActive(false);
            BottomCollider.SetActive(false);
        }

         else if(facingUp)
        {
            TopCollider.SetActive(true);
            RightCollider.SetActive(false);
            LeftCollider.SetActive(false);
            BottomCollider.SetActive(false);
        } else if(!facingUp)
        {
            BottomCollider.SetActive(true);
            RightCollider.SetActive(false);
            LeftCollider.SetActive(false);
            TopCollider.SetActive(false);
        }
    }

如果更容易阅读,您可以在 PasteBin 上阅读:https://pastebin.com/y1jQT17w

忽略 CheckIfNear();调用更新函数,因为那是为了未来的计划,但它目前是空的。

【问题讨论】:

    标签: c# unity3d 2d collider


    【解决方案1】:
        if(facingRight)
        {
            RightCollider.SetActive(true);
            LeftCollider.SetActive(false);
            TopCollider.SetActive(false);
            BottomCollider.SetActive(false);
        } 
        else if(!facingRight)
        {
            LeftCollider.SetActive(true);
            RightCollider.SetActive(false);
            TopCollider.SetActive(false);
            BottomCollider.SetActive(false);
        }
    
        else if(facingUp)
        {
            TopCollider.SetActive(true);
            RightCollider.SetActive(false);
            LeftCollider.SetActive(false);
            BottomCollider.SetActive(false);
        } 
        else if(!facingUp)
        {
            BottomCollider.SetActive(true);
            RightCollider.SetActive(false);
            LeftCollider.SetActive(false);
            TopCollider.SetActive(false);
        }
    

    facesRight 是 True 或 False。这意味着您的第一对 if 语句(if(facingRight)if(!facingRight))始终为真,因此您的代码永远不会到达第三个 if 语句,并且您的变量 facesUp 永远不会被使用。

    如果我是你,我会分配一个整数来存储方向并使用开关选择对撞机。像这样:

    int dir = 0;
    
    void CheckDirection()
    {
        if (direction.x > 0)
        {
            dir = 1;
        }
        else if (direction.x < 0)
        {
            dir = 2;
        }
    
        if (direction.y > 0)
        {
            dir = 3;
        }
        else if (direction.y < 0)
        {
            dir = 4;
        }
    
    }
    

    .

    void DisableInteractionColliders()
    {
            LeftCollider.SetActive(false);
            RightCollider.SetActive(false);
            TopCollider.SetActive(false);
            BottomCollider.SetActive(false);
    
            switch(dir)
            {
                case 1: RightCollider.SetActive(true);
                        break;
                case 2: LeftCollider.SetActive(true);
                        break;
                case 3: TopCollider.SetActive(true);
                        break;
                case 4: BottomCollider.SetActive(true);
                        break;
    
                default: break;
            }
    }
    

    【讨论】:

    • 好的,但是,这导致了一个我也没有预见到并且不知道如何解决的问题,脚本顶部有一个名为near NPC的变量。当对撞机接触 NPC 时,将变量设置为 true,但是当玩家离开并且 nearNPC 仍设置为 true 时,对撞机将被禁用,允许玩家在靠近 NPC 后从任何地方与 NPC 交谈,我将更新我的脚本在这里和在 pastebin 上展示这一点。但是我该如何解决呢?
    • 通常您会保持所有 RayCast 或 Colliders 处于活动状态,并使用它们来防止向某个方向移动。在您的情况下,您将保持所有 4 个对撞机处于活动状态,并在 Move() 或 CheckDirection() 函数中禁用某个方向的运动。
    • 碰撞器是触发器,我的问题是当玩家靠近时我不需要与 NPC 交谈,而是在玩家按下键时。这是完整的脚本以及您提供的更新:pastebin.com/ZsdDQs3s
    • @UltraGamer 加入我的this room
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-25
    • 1970-01-01
    • 2020-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多