(Unity2D) 碰撞时切换运动风格
(Unity2D) Switch movement style on collision
我在自上而下的游戏中有一个玩家角色以 grid-like 移动(一次 1 个单位),但是当它碰到一块冰(正方形)时,我希望它切换到 lerp-movement, 滑到边缘, 停
目前我有 5 个不同的碰撞器作为每个冰块 children:冰对撞器本身,以及 4 个稍有距离的碰撞器,一个用于冰的每一侧。当它撞击冰对撞机时,根据它前进的方向,它应该会移动到相关的远距离对撞机。
像这样(很难看到主对撞机但它就在那里):
这是我一直用于向下键的代码(所有键基本相同):
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
Vector2 movementDown = new Vector2(0, -1);
RaycastHit2D hitDown = Physics2D.Raycast(transform.position, movementDown, 0.05f);
if (hitDown.collider && hitDown.collider.gameObject.tag == "barrier")
{
Debug.Log("N/A");
}
else if (onIce)
{
player.transform.position = Vector3.Lerp(transform.position, downIce.transform.position, 100 * Time.fixedDeltaTime);
}
else
{
player.transform.position += new Vector3(movementDown.x, movementDown.y, -0.1f);
}
}
编辑:更新 bool 'onIce':
的代码
void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice") {
onIce = true;
}
}
void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice")
{
onIce = false;
}
}
当您按下按钮时,Lerp 只会被调用一次。一种修复方法是使用协程:
IEnumerator Slide() {
var t = 0f;
var start = player.transform.position; //we will change the position every frame
//so for lerp to work, we need to save it here.
var end = downIce.transform.position;
while(t < 1f){
t += Time.deltaTime;
player.transform.position = Vector3.Lerp(start, end , t);
yield return null; //returning null waits until the next frame
}
}
然后你像这样使用它:
...
else if (onIce)
{
this.StartCoroutine(this.Slide());
}
else
...
我认为这仍然不是您在游戏中想要的,因为它会倾斜到对撞机的中心。如果是这种情况,您可以通过更改它计算协程中的结束变量的方式来轻松修复它,使播放器仅沿正确的轴滑动。
我在自上而下的游戏中有一个玩家角色以 grid-like 移动(一次 1 个单位),但是当它碰到一块冰(正方形)时,我希望它切换到 lerp-movement, 滑到边缘, 停
目前我有 5 个不同的碰撞器作为每个冰块 children:冰对撞器本身,以及 4 个稍有距离的碰撞器,一个用于冰的每一侧。当它撞击冰对撞机时,根据它前进的方向,它应该会移动到相关的远距离对撞机。
像这样(很难看到主对撞机但它就在那里):
这是我一直用于向下键的代码(所有键基本相同):
else if (Input.GetKeyDown(KeyCode.DownArrow))
{
Vector2 movementDown = new Vector2(0, -1);
RaycastHit2D hitDown = Physics2D.Raycast(transform.position, movementDown, 0.05f);
if (hitDown.collider && hitDown.collider.gameObject.tag == "barrier")
{
Debug.Log("N/A");
}
else if (onIce)
{
player.transform.position = Vector3.Lerp(transform.position, downIce.transform.position, 100 * Time.fixedDeltaTime);
}
else
{
player.transform.position += new Vector3(movementDown.x, movementDown.y, -0.1f);
}
}
编辑:更新 bool 'onIce':
的代码void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice") {
onIce = true;
}
}
void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "ice")
{
onIce = false;
}
}
当您按下按钮时,Lerp 只会被调用一次。一种修复方法是使用协程:
IEnumerator Slide() {
var t = 0f;
var start = player.transform.position; //we will change the position every frame
//so for lerp to work, we need to save it here.
var end = downIce.transform.position;
while(t < 1f){
t += Time.deltaTime;
player.transform.position = Vector3.Lerp(start, end , t);
yield return null; //returning null waits until the next frame
}
}
然后你像这样使用它:
...
else if (onIce)
{
this.StartCoroutine(this.Slide());
}
else
...
我认为这仍然不是您在游戏中想要的,因为它会倾斜到对撞机的中心。如果是这种情况,您可以通过更改它计算协程中的结束变量的方式来轻松修复它,使播放器仅沿正确的轴滑动。