当我的玩家与汽车处于同一坐标时,我正在尝试编写脚本,玩家现在可以控制汽车,因此玩家在汽车中,我正在做位置,不要知道在两者上放置一些碰撞器是否更容易。 播放器脚本只有
公共浮动 pspeed = 50;
公共浮动 cspeed = 10;
public bool isoncar;
在我的无效 Start() 上
player = GetComponent();
isoncar = false;
汽车
public class playerincar : playercontroller
{
public Rigidbody2D car;
// position x and y for player and car
public float pposx, pposy, cposx, cposy,vertical, horizontal;
// Start is called before the first frame update
void Start()
{
car = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
horizontal = Input.GetAxisRaw("Horizontal");
vertical = Input.GetAxisRaw("Vertical");
}
void FixedUpdate()
{
pposx = player.transform.position.x;
pposy = player.transform.position.y;
cposx = car.transform.position.x;
cposy = car.transform.position.y;
if (pposx == cposx && pposy == cposy)
{
isoncar = true;
}
else
{
isoncar = false;
}
if (isoncar == true)
{
car.velocity = new Vector2(horizontal * cspeed, vertical * cspeed);
}
else
{
player.velocity = new Vector2(horizontal * pspeed, vertical * pspeed);
}
}
}
答案 0 :(得分:0)
在尝试比较位置时,您肯定会遇到 floating-point precision
问题。如果你想保持相同的检查,不要使用比较运算符直接比较,而是使用 epsilon 并取值之间差异的绝对值。
float DISTANCE_EPSILON = 0.001f;
if(Mathf.Abs(pposx - cposx) <= DISTANCE_EPSILON && Mathf.Abs(pposy - cposy) <= DISTANCE_EPSILON)
{
...
}
除了进行单独的坐标检查,您还可以使用名为 Vector2.Distance
的方法,该方法将为您提供两个 Vector2
位置之间的长度。
float DISTANCE_EPSILON = 0.001f;
if(Vector2.Distance(player.transform.position, car.transform.position <= DISTANCE_EPSILON)
{
...
}
但是,正如您所提到的,最好使用碰撞来检测玩家何时接触汽车。不过,我会考虑使用触发器而不是碰撞。触发器与碰撞类似,因为它会检测两个对象何时以某种方式重叠,但它不会由于碰撞的物理排斥而限制移动,而是允许对象在彼此之上自由移动。
我仍然会在您的播放器上使用实际的碰撞器,但使用子碰撞器来了解汽车何时离玩家足够近可以进入。为汽车对象分配一个标签,以便触发器仅检测到汽车。由于它使用触发器,您将使用 OnTriggerEnter2D
而不是 OnCollisionEnter2D
。它可能看起来像
private void OnTriggerEnter2D(Collider2D col)
{
if(col.tag == "Car")
{
...
}
}
如果您想使用触发器来检测汽车何时主动接触或靠近玩家,您还需要使用 OnTriggerExit2D
来确定汽车何时不再处于玩家的范围内。< /p>