5

我正在 Unity 中编写 2D 平台游戏,并试图让玩家停留在移动平台上。我已经搜索和修补了一两天了,但我没有任何运气。

基本上,我被告知要在角色接触时尽量让角色随着平台移动。首先,如果我使用与 OnTriggerEnter() 相关的任何内容,玩家将直接通过平台。如果我执行 OnCollisionEnter()(在播放器上使用 CharacterController,在平台上使用 BoxCollider),则什么也不会发生。这是我发现建议最多的两件事。另一个是用平台养育玩家,但这显然会导致“问题”(经常说,从未解释过)。

那么,我怎样才能让玩家留在移动平台上呢?这是移动平台的代码:

public class MovingPlatform : MonoBehaviour
{
private float useSpeed;
public float directionSpeed = 9.0f;
float origY;
public float distance = 10.0f;

// Use this for initialization
void Start () 
{
    origY = transform.position.y;
    useSpeed = -directionSpeed;
}

// Update is called once per frame
void Update ()
{
    if(origY - transform.position.y > distance)
    {
        useSpeed = directionSpeed; //flip direction
    }
    else if(origY - transform.position.y < -distance)
    {
        useSpeed = -directionSpeed; //flip direction
    }
    transform.Translate(0,useSpeed*Time.deltaTime,0);
}

这里是玩家移动的代码(更新中):

CharacterController controller = GetComponent<CharacterController>();
    float rotation = Input.GetAxis("Horizontal");
    if(controller.isGrounded)
    {
        moveDirection.Set(rotation, 0, 0); //moveDirection = new Vector3(rotation, 0, 0);
        moveDirection = transform.TransformDirection(moveDirection);

        //running code
        if(Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) //check if shift is held
        { running = true; }
        else
        { running = false; }

        moveDirection *= running ? runningSpeed : walkingSpeed; //set speed

        //jump code
        if(Input.GetButtonDown("Jump"))
        {
            //moveDirection.y = jumpHeight;
            jump ();
        }
    }
    moveDirection.y -= gravity * Time.deltaTime;
    controller.Move(moveDirection * Time.deltaTime);

编辑:我认为这可能与我如何定义播放器和平台有关,但我尝试了不同的组合。如果平台是一个触发器(在它的对撞机上),玩家会一直通过它。如果没有,我不能使用 OnTrigger 函数。我在播放器和平台上都有一个刚体,但它似乎没有影响任何东西。当玩家在某些设置中确实进入平台时,他会感到不安,并且经常会以失败告终。

4

5 回答 5

1

这不是最好的方法,但您可以执行从播放器到移动平台的 RayCast。如果 RayCast 击中“MovingPlatform”,您可以检查 Y 轴上的差异以确定玩家是否足够接近它以被视为“OnThePlatform”。然后你可以像往常一样调整玩家的位置。

一个例子是:

private bool isOnMovingPlatform;
private float offsetToKeepPlayerAbovePlatform = 2.2f;
private float min = 0.2f;
private float max = 1.2f;

private void Update()
{
RaycastHit hit;
if(Physics.Raycast (player.position, player.TransformDirection(Vector3.down), out hit))
{
    if(hit.transform.name.Contains("MovingPlatform"))
    {
        Transform movingPlatform  = hit.collider.transform;

        if(movingPlatform.position.y - player.position.y <= min && movingPlatform.position.y - player.position.y >= max)
        {
            isOnMovingPlatform = true;
        }
        else
        {
            isOnMovingPlatform = false;
        }
    }

    if(isOnMovingPlatform)
    {
        player.position = new Vector3(hit.transform.x, hit.transform.y + offsetToKeepPlayerAbovePlatform, 0);
    }
}
}
于 2013-03-26T18:31:57.037 回答
1

您需要的似乎是平台上的第二个对撞机。主对撞机必须isTrigger = false确保您的角色控制器正常工作。第二个运行时isTrigger = true,它的唯一功能是检测玩家在OnTriggerEnter被调用时是否依附在平台上并离开平台OnTriggerExit

因为你不能有 2 个相同类型的碰撞器(我猜你需要盒子碰撞器),所以在你的平台游戏对象下构建一个空子对象并将盒子碰撞器分配给它。我通常会使用一种名为 ActionMaterial 的特殊物理材料来清洁我的东西。如果您正在使用图层并调整了碰撞矩阵,请确保您的碰撞由 physX 处理。

于 2013-03-26T19:25:00.667 回答
0

这个 Unity Answers 页面可能会有所帮助。

于 2013-03-27T12:30:26.763 回答
0

您也可以简单地使玩家游戏对象变换父级等于平台的变换。这允许玩家在其上时仍保持移动。至于检测,Raycast 有点慢,但可以完成工作。

于 2015-11-22T17:32:57.617 回答
0

我们通过使用 SliderJoint2d 并在移动平台上将角色的重力比例设置为零来解决了这个问题。以下是完整说明的链接:

http://spacelizardstudio.com/devblog/index.php/2016/03/02/unity-a-guide-to-moving-platforms/

于 2016-03-02T15:47:41.507 回答