我正在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功能。我有一个与玩家和平台相连的刚体,但它似乎没有任何影响。当玩家在某些设置中进入平台时,他会紧张不安,并且通常最终会失败。
答案 0 :(得分: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);
}
}
}
答案 1 :(得分:1)
你需要的东西似乎是平台上的第二个对撞机。主对撞机有isTrigger = false
以确保您的角色控制器正常工作。第二个用isTrigger = true
运行,其唯一的功能是在调用OnTriggerEnter
时检测到播放器是否附加到平台,并将平台保留在OnTriggerExit
上。
由于你不能拥有2个相同类型的碰撞器(我猜你需要箱式碰撞器),所以在你的平台游戏对象下建立一个空的孩子,并为它分配一个箱子对撞机。我通常会采用一种叫做ActionMaterial的特殊物理材料来让我的东西干净。如果您正在使用图层并且已经调整了碰撞矩阵,请确保您的碰撞由physX处理。
答案 2 :(得分:0)
This Unity Answers page可能有所帮助。
答案 3 :(得分:0)
你也可以简单地让玩家gameobjects变换父变换等于平台的变换。这允许玩家在他们上面时仍然保持移动。至于检测,Raycast有点慢,但完成工作。
答案 4 :(得分:0)
我们通过使用SliderJoint2d并在移动平台上将角色的重力比例设置为零来解决问题。以下是完整解释的链接:
http://spacelizardstudio.com/devblog/index.php/2016/03/02/unity-a-guide-to-moving-platforms/