2013-03-26 111 views
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); 

编辑m定义了玩家和平台,但我尝试了不同的组合。如果平台是一个触发器(在其对撞机上),玩家就会一直贯彻它。如果没有,我不能使用OnTrigger函数。我有一个固定在播放器和平台上的刚体,但它似乎没有影响任何东西。当玩家在某些设置上进入平台时,他会不停地跳动,而且往往会结束。

+0

我从来没有使用Unity3D,但有可能像做'moveDirection + = theplatform。moveDirection'当角色在平台上? – mbeckish 2013-03-26 17:59:05

+0

我试过了,但我似乎遇到了OnTrigger和OnCollision函数的问题,这些函数将负责“玩家在平台上”时的情况。我认为这与我如何定义我的对象有关,但我不确定如何定义它们以使其可行。 – muttley91 2013-03-26 18:02:02

+0

此外,你需要确保角色的moveDirection.y永远不会比你的平台的moveDirection.y更少,否则你会遇到(除非Unity3D框架自动为你处理?) – mbeckish 2013-03-26 18:03:10

回答

1

你需要什么似乎是平台上的第二对撞机。主对撞机有isTrigger = false以确保你的角色控制器正在工作。第二个以isTrigger = true运行,其唯一功能是当OnTriggerEnter被调用时检测到玩家是附着到平台的类型,并且离开平台OnTriggerExit。因为你不能有2个相同类型的对撞机(我猜你需要箱子对撞机),所以在你的平台游戏对象下建立一个空的小孩,并指定箱子对撞机。我通常采用一种名为ActionMaterial的特殊物理材料来让我的东西变得干净。如果您使用图层并调整了碰撞矩阵,请确保碰撞由physX处理。

+0

我可以在同一个物体上使用两个不同的碰撞体(一个箱体,一个胶囊)来获得同样的效果,而不是使用两个物体并让它们都需要移动脚本? 另外,我没有使用图层,也没有调整碰撞矩阵。 – muttley91 2013-03-26 21:50:59

+0

允许有不同的对撞机。但请记住,胶囊对撞机的价格要高得多。因此,如果有立方体形状,最好使用子对象解决方案。没有图层,没有碰撞矩阵操作=>没有增加复杂性;)当你遇到性能问题时,你只需要那些东西。我正在为iOS开发,所以对我来说性能始终是个问题 – Kay 2013-03-26 21:57:18

+0

啊,够公平了!所以要清楚,你的意思是在场景中有两个游戏对象?你如何专门制造一个物体成为另一个物体的孩子? – muttley91 2013-03-26 22:16:10

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

只是好奇心,因为我即将尝试这个,最小值,最大值和偏移量,它们是否与平台的大小有关? – muttley91 2013-03-26 21:47:15

+0

不一定。最小和最大值只是范围,因此您知道玩家与平台相关的位置。例如,如果玩家的Y值高于最大值5,那么显然他不在平台上,反之亦然。改变范围,直到你得到一对漂亮的花车。理论上他们可能来自平台的高度,但他们不必这样做。 – 2013-03-26 22:05:07

0

This Unity Answers page可能会有所帮助。

+0

这确实很不错。但是您应该将其作为评论发布或提供更多信息。仅包含链接的答案将在SO上被杀害(我刚刚输了一些) – Kay 2013-03-27 16:14:15

0

你也可以简单地让玩家的游戏对象变换父母,等于平台的变换。这可以让玩家在玩游戏时保持移动。至于检测Raycast是有点慢,但完成工作。