0

我正在编写一个 2D 游戏,并试图让移动平台工作。在进行了一些先前的调查之后,我几乎可以正常工作。这个想法是有 2 个带有碰撞器的平台对象:1 个是可见对象,另一个是设置了 isTrigger 的不可见对象(因为玩家只会通过触发器)。移动平台子项(触发器之一)的代码在此处设置。

using UnityEngine;
using System.Collections;

public class MovingPlatformChild : MonoBehaviour
{
public string parentPlatform = "";

void Start ()
{
    transform.parent = GameObject.Find(parentPlatform).transform;
}

// Update is called once per frame
void Update ()
{

}

void OnTriggerEnter(Collider playerObject)
{
    Debug.Log ("enter moving platform");
    if(playerObject.gameObject.name.Contains("Player"))
    {
        playerObject.transform.parent = gameObject.transform;
    }
}
int i = 0;
void OnTriggerStay(Collider playerObject)
{
    Debug.Log ("stay" + i++);
    if(playerObject.transform.position.y >= transform.position.y)
    {
        playerObject.transform.parent = gameObject.transform;
    }
    else
    {
        playerObject.transform.parent=null;
    }
}
void OnTriggerExit(Collider playerObject)
{
    Debug.Log ("EXIT");
    if(playerObject.gameObject.name.Contains("Player"))
    {
        playerObject.transform.parent=null;
    }
}
}

Start() 函数只是使其成为可见平台的子级。这也可以直接在 Unity 编辑器中完成,而不是通过代码。

OnTriggerEnter 函数将播放器对象添加为触发平台对象的子对象,触发平台对象是可见平台的子对象。所以他们应该一起行动。

OnTriggerStay 试图验证仅当玩家在平台顶部时这仍然是正确的。当玩家在触发器内时,如果玩家在平台顶部,那么它会保持连接状态。否则,它不是。这样就不会在底端发生任何事情。

OnTriggerExit 函数只是在退出触发器时将播放器对象作为子对象移除。

这有点工作(但我们知道有点不够好)。它有时会起作用,但玩家会非常紧张。此外,在站在平台顶部下降的过程中,似乎没有调用 TriggerStay 函数(这意味着玩家不再在触发器内)。这是通过我的 Debug “stay” 语句观察到的。最后,有时玩家也会直接从平台跌落。

这段代码中有什么会让玩家跌倒平台,或者在上升过程中如此紧张?我错过了一些重要的东西吗?如果您需要更多代码,请告诉我。

下面是非触发平台(触发平台的父级,位置相同)的移动代码。之后我也会分享播放器的更新功能。

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);
}

现在播放器代码:

  void Update()
{
    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);
}

编辑:我在这张 imgur 专辑中添加了平台和播放器的规格:

http://imgur.com/a/IxgyS

4

2 回答 2

0

这在很大程度上取决于触发盒的高度,但值得研究。在你的TriggerStay中,你有一个关于玩家 y 坐标的 IF 语句。如果触发框相当大并且平台的速度足够快,那么在向上和更新滴答之间,玩家 Y 坐标可能会暂时小于触发 Y 坐标。这将导致他失去亲缘关系,只是在几刻之后又重新获得了它。这可能是“抖动”的原因。

于 2013-03-28T07:28:02.933 回答
0

我遇到的问题包括

  1. 移动平台是使用 Translate 编写的。我使用刚体和刚体.Move 函数重写了它。这并没有立即帮助,但是......
  2. 我意识到我附加到播放器的 CharacterMotor 脚本(Unity 提供了这个)包括移动平台支持。我将 MovementTransfer 值设置为 PermaLocked,并取消选中脚本上的“使用 FixedUpdate”框,现在 99% 的时间都可以正常工作。我曾经做过一次特定的行为并滑倒了,但我无法重现它。

希望这可以帮助任何可能正在寻找答案的人!

于 2013-04-03T05:39:08.160 回答