在 Unity 中根据方向启用和禁用对撞机
Enabling and Disabling Collider based on direction in Unity
我认为这很简单,但出于某种原因,我无法弄清楚。我的玩家周围有 4 个子游戏对象,每个都有自己的对撞机。我需要能够根据角色移动的方向启用和禁用子游戏对象。因此,如果玩家向右移动,则左侧、顶部和底部碰撞器将被禁用,只留下右侧碰撞器处于活动状态。如果 Player 向上移动,那么 Left、Right 和 Bottom 碰撞器将被禁用,只留下 Top 碰撞器。其他2个方向同理。但出于某种原因,我的代码适用于左右方向,但是当我的角色向上或向下移动时,它会禁用除左侧碰撞器之外的所有内容。我能得到一些帮助吗?这是我的代码:
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();调用 teh update 函数,因为它是为了未来的计划,但它目前是空的。
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);
}
facingRight 为 True 或 False。这意味着您的第一对 if 语句(if(facingRight)
和 if(!facingRight)
)始终为真,因此您的代码永远不会到达第三个 if 语句并且永远不会使用变量 facingUp。
如果我是你,我会分配使用一个整数来存储方向,select 使用开关分配对撞机。像这样:
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;
}
}
我认为这很简单,但出于某种原因,我无法弄清楚。我的玩家周围有 4 个子游戏对象,每个都有自己的对撞机。我需要能够根据角色移动的方向启用和禁用子游戏对象。因此,如果玩家向右移动,则左侧、顶部和底部碰撞器将被禁用,只留下右侧碰撞器处于活动状态。如果 Player 向上移动,那么 Left、Right 和 Bottom 碰撞器将被禁用,只留下 Top 碰撞器。其他2个方向同理。但出于某种原因,我的代码适用于左右方向,但是当我的角色向上或向下移动时,它会禁用除左侧碰撞器之外的所有内容。我能得到一些帮助吗?这是我的代码:
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();调用 teh update 函数,因为它是为了未来的计划,但它目前是空的。
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);
}
facingRight 为 True 或 False。这意味着您的第一对 if 语句(if(facingRight)
和 if(!facingRight)
)始终为真,因此您的代码永远不会到达第三个 if 语句并且永远不会使用变量 facingUp。
如果我是你,我会分配使用一个整数来存储方向,select 使用开关分配对撞机。像这样:
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;
}
}