找到并添加直接位于另一个下方的刚体的速度? (Unity + C#)

时间:2016-03-22 02:55:42

标签: c# .net 2d platform

我有一个问题,我现在几天都无法解决,如果没有它工作我无法继续我的项目,所以非常感谢你的帮助!

我想要做的就是找到'直接位于我的2D精灵下面的物体的速度(也包含一个刚体和二维盒子对撞机),然后将该速度(在同一方向上)添加到“查看”的物体上。为了它。

我觉得光线投射可能是答案的一部分,但我不确定如何使用它,特别是在这种情况下。

这背后的想法是我有一个平台,可以携带堆叠在彼此之上的物体,所以你移动鼠标,它操纵平台的速度,但这会导致顶部的物体向后飞,没有问题高摩擦力。

以下是平台代码:

void Update()
{

    float distance_to_screen = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;

    Vector3 pos_move = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, distance_to_screen));

    mouseDelta = pos_move - lastMousePosition;

    acceleration = mouseDelta.x * 0.4f;
    platformVelocity += acceleration;
    platform.velocity = new Vector2(platformVelocity, 0) * speed;

    lastMousePosition = pos_move;

}

感谢您抽出宝贵时间阅读本文,我非常感谢您提供的任何帮助!

4 个答案:

答案 0 :(得分:0)

是否有必要'找到'那个对象? '发现'可能很困难&成本的计算。

你能否持有'under-thing'引用并将其传递给'above-thing'?

答案 1 :(得分:0)

我假设您在对象上有一些方法可以检查它是否在移动平台上。一种选择是在这些对象上添加IsOnMovingPlatform标志。然后使用类似的方法检查是否有任何对象位于“IsOnMovingPlatform == true”对象之上。继续对该方法进行传递,直到你没有提出任何更多的标志设置为true。

答案 2 :(得分:0)

所以,我试图理解你的问题,我想我可能知道你在谈论什么。 你是说你希望你的游戏对象(2d精灵)在移动时留在平台上吗?我遇到了同样的问题,平台在移动,我的播放器(游戏对象)滑落 - 这就是我修复它的方法。

向平台添加一个盒子对撞机(触发器)。当玩家进入平台时,让玩家改变平台。这样,当平台移动时 - 无论速度如何,玩家都随之移动。

例如:

void OnTriggerEnter2D(Collider2d collider){
if(collider.tag.equals("Player")){ // you only want the player to work
 // attach script to platform for "this.transform" to work
   collider.transform.SetParent(this.transform); 

 }
}

然后,取消变换“否则,即使玩家离开平台,它也会随平台移动。

void OnTriggerExit(Collider2d collider){
// assuming your player isn't supposed to have a parent!
    collider.transform.parent = null;
}

很抱歉,如果我误解了你的问题!如果这是你想要的,找不到平台的速度。此外,这是未编译的代码 - 如果您有问题,请告诉我。

编辑:

要添加一些赠品,在玩家与平台接触的整个持续时间内,我们可以添加一点负面力量来推动玩家一点点!

我们通过使用OnTriggerStay2D来做到这一点(假设你的游戏是2d,否则使用OnTriggerStay)。

例如:

void OnTriggerStay2D(Collider2d collider){
  if(collider.tag.equals("Player")){
    collider.getComponent<Rigidbody2D>().addForce(new vector2(forceToAdd, 0));
  }
}

现在,“forceToAdd”变量应该基于平台的速度和方向。你的平台上有刚体吗?如果是这样,你可以通过从平台(getcomponent())中检索刚体来获得你的力变量,并从中获得X速度。使用此速度,尝试将其除以数字直到找到合适的值,然后将其乘以-1(因为您想要将玩家推向平台行程的相反方向),那么这将是您的forceToAdd!

但是,如果您的平台没有使用Rigidbody,那么您可以这样做的方法是在脚本中记录x位置(只需两个位置,然后减去这些位置以在更新方法中找到距离),乘以 - 1,尝试用数字除(用此实验),这可以成为你添加变量的力量。

另外,我的OnTriggerStay2d代码很粗糙,拼写可能有点不对 - 但这会给你一个大致的解决方案!另外..我认为不应该在每个框架中完成一个刚体的组件,一种解决方法是将刚体组件作为脚本中的全局变量,然后在OnTriggerEnter2d上设置刚体,这个它只能检索一次(而不是每一帧),我认为它会更有效!

祝你好运!如果您有任何疑问,请尝试帮助!

答案 3 :(得分:0)

这是一个raycast2d版本,我测试了它,它比触发器对撞机版本好得多:)。

使用UnityEngine; 使用System.Collections;

public class RaycastFeetDeleteLater : MonoBehaviour {

[SerializeField] private float raycastDist = 0.1f;
[SerializeField] Transform feet;
[SerializeField] private float xForceDampener = 0.1f;
private Rigidbody2D rb2d;


// Use this for initialization
void Start () {
    rb2d = GetComponent<Rigidbody2D> ();
}

// Update is called once per frame
void FixedUpdate () {
    RaycastDown ();
}

private void RaycastDown(){
    RaycastHit2D hit = Physics2D.Raycast (feet.position, Vector2.down, raycastDist);
    if (hit.collider != null) {
        print (hit.transform.tag);
        if (hit.collider.tag.Equals ("Platform")) {
            transform.SetParent (hit.transform);
            Vector2 force = new Vector2 ((hit.transform.gameObject.GetComponent<Rigidbody2D> ().velocity.x * xForceDampener) * -1, 0);
            print (force);
            rb2d.AddForce (force);
        } else if (transform.parent != null) {
            print ("UNPARENT");
            transform.parent = null;
        } 
    } else {
        if (transform.parent != null) {
            transform.parent = null;
        }
    }
    Debug.DrawRay (feet.position, Vector3.down, Color.green, raycastDist);

  }
}

此脚本附加到播放器!不需要在平台上安装脚本,这是我之前的方法很痛苦的主要原因:P

基本上这个脚本执行以下操作: - 在开始时获取玩家的rigidbody2d(我们将尽快向玩家添加力量,所以不妨将它存储在变量中!

  • 在FixedUpdate上(不同于Update,在物理更新时调用FixedUpdate,每帧调用Update)我已经读过光线投射应该使用FixedUpdate,我想因为它是一种物理方法!

  • RaycastDown直接从脚部位置拍摄2D光线投射(获取脚,创建玩家的子对象,将脚的位置放在玩家的下方,而不是玩家 - 我将解释为什么在一秒钟内为什么会弄乱一切!然后将游戏对象拖到脚本的“脚”插槽上。)

  • Raycast从脚下直接向下拍摄,距离可以在编辑器中更改(raycastDist)我发现0.1f的距离非常适合我的需要,但是为你的游戏玩弄它!您可以通过使用Debug.DrawRay实际看到Ray的绘图,如代码中所示,光线仅在编辑器中可见 - 而不是游戏视图!但这会有所帮助,特别是在定位脚时。

  • 检查它是否碰到了带有碰撞器的物体,如果是,请检查对象标签是否为平台(将平台设置为新标签并称之为平台)。

  • 如果它击中平台,则将玩家的父级设置为平台(如最后一个脚本)并开始向玩家施加一点力量,使平台正在行进的负面方向(我们得到僵硬的身体)平台找到它的速度。)

  • 如果光线投射没有撞到平台,请将其取消,以便播放器可以自由移动。

基本上就是这样,但是...... 请注意:

  • 此脚本需要在播放器上,而不是任何播放器子对象,因为此脚本将从任何平台上取消播放器 - 如果您在播放器的子对象上有脚本,它将从玩家 - 这太可怕了。所以脚本必须在播放器的根游戏对象上。如果由于某种原因你不能这样做,有办法解决这个问题。

  • 如前所述,“脚”子对象必须在玩家的下方 - 这是因为当Raycast2d“触发”它会发现第一个对象有一个碰撞的碰撞器 - 所以如果你有光线投射的开始击中了玩家的对撞机,然后它将始终显示光线投射击中玩家,而不是平台。因此,为了解决这个问题,需要从脚部射出射线,并让脚位于球员下方一点点位置。为了解决这个问题,我添加了一个print语句,它将打印到控制台上的光线投射对象,如果它没有说“平台”,那么你需要降低脚! :)

  • 此外,我不确定你是如何移动你的平台的 - 但如果平台的速度总是打印“0,0”,那么因为你正在直接移动平台位置,而不是移动它力(当我测试这个脚本时,这发生在我身上)。通过“AddForce”移动平台,我解决了这个问题。同样取决于你的平台的“质量”,你可能需要大幅度增加我应该实际标记为“xForceMultiplier”的“xForceDampener”,因为我在测试时发现我需要将它设置得更高 - 就像在60,而不是0.25我之前认为会好的..

希望这有帮助:D

编辑:在需要时链接2D Raycast的统一文档 http://docs.unity3d.com/ScriptReference/Physics2D.Raycast.html