0

私は 2D ゲームを書いていて、動くプラットフォームを動作させようとしています。以前の調査を行った後、ほとんど機能しています。コライダーを持つ 2 つのプラットフォーム オブジェクトを用意するという考え方です。移動プラットフォームの子 (トリガーの子) のコードはここで設定されます。

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 は、プレイヤーがプラットフォームの最上部にいる間のみ、これが true のままであることを確認する試みです。プレーヤーがトリガー内にある間、プレーヤーがプラットフォームの上にある場合は、接続されたままになります。そうでなければ、そうではありません。これは、下端で何も起こらないようにするためです。

OnTriggerExit 関数は、トリガーを終了するときに、プレーヤー オブジェクトを子として削除するだけです。

これはある程度機能しています (ただし、十分ではないことはわかっています)。時々機能しますが、プレーヤーは非常にぎくしゃくします。また、プラットフォームの上に立って降りる途中で、TriggerStay 関数が呼び出されないように見えます (プレイヤーがトリガー内にいないことを意味します)。これは、Debug の「stay」ステートメントで確認できます。最後に、プレイヤーがプラットフォームを突き抜けて落ちることもあります。

このコードのどの部分が、プレーヤーがプラットフォームを通り抜けたり、上に行く途中で非常に震えたりすることを可能にしますか? 私は何か重要なものを見逃していますか?さらにコードが必要な場合は、お知らせください。

以下は、非トリガー プラットフォーム (トリガー プラットフォームの親であり、同じ位置にある) の移動のコードです。その後、Player の Update 機能についても共有します。

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

私が含めていた問題

  1. 移動プラットフォームは Translate を使用して作成されました。リジッドボディとリジッドボディ.Move関数を使って書き直しました。これはすぐには役に立ちませんでしたが...
  2. プレーヤーにアタッチした CharacterMotor スクリプト (Unity がこれを提供) に移動プラットフォームのサポートが含まれていることに気付きました。MovementTransfer の値を PermaLocked に設定し、スクリプトの [Use FixedUpdate] ボックスのチェックを外したところ、99% の確率で動作するようになりました。私は一度、特定の行動をしてすり抜けたことがありますが、それを再現することはできません.

これが答えを探している人に役立つことを願っています!

于 2013-04-03T05:39:08.160 に答える
0

これはトリガー ボックスの高さに大きく依存しますが、調べる価値はあります。内にTriggerStay、プレーヤーの y 座標に関する IF ステートメントがあります。トリガー ボックスがかなり大きく、プラットフォームの速度が十分に速い場合、アップの途中と更新ティックの間で、プレーヤーの Y 座標がトリガーの Y 座標よりも一時的に小さくなる可能性があります。これにより、彼は親子関係を失い、数ティック後にそれを取り戻すことができます. これが「ジッタリング」の原因である可能性があります。

于 2013-03-28T07:28:02.933 に答える