2015-11-03 98 views
2

我在Unity中非常新,我试图在经典的2D地图上移动一个简单的正方形(超级马里奥像)。Unity中的水平移动

我使用addForce跳,它按计划进行。 但是现在,我试图水平移动我的角色。

首先,我试着用tramsform.translation(),我很快注意到这不是正确的方法,导致这种方法“传送”角色,如果它移动得太快,它可以传送到墙后。我也尝试使用addForce,但我希望我的角色具有恒定的速度,并且具有惯性,所以当我释放密钥时它不会立即停止。我也试着用.MovePosition(),但人物正在用这种方法摇晃(显然,由于重力)。

那么,什么是适当的方式来移动角色(Rigidbody2D)horizo​​ntaly?

这里是我的代码与试不同:

using UnityEngine; 
using System.Collections; 
public class test : MonoBehaviour { 
    private Rigidbody2D rb; 
    public Vector2 velocity; 
    public float jumpforce; 
    // Use this for initialization 
    void Start() { 
     rb = GetComponent<Rigidbody2D>(); 
    } 

// Update is called once per frame 
void Update() { 
    Debug.Log(velocity); 
    if (Input.GetKeyDown("space")){ 
     rb.AddForce(new Vector2(0, jumpforce), ForceMode2D.Impulse); 
    } 
    if (Input.GetKey("a")){ // move to the left 
     rb.AddForce(-velocity * Time.deltaTime, ForceMode2D.Impulse); 
     //rb.MovePosition(rb.position - velocity * Time.fixedDeltaTime); 
     //transform.Translate(-velocity); 
    } 
    if (Input.GetKey("d")){ // move to the right 
      rb.AddForce(velocity * Time.deltaTime, ForceMode2D.Impulse); 
      //rb.MovePosition(rb.position + velocity * Time.fixedDeltaTime); 
      //transform.Translate(velocity); 
     } 
    } 
} 
+0

您可能会研究角色控制器脚本 - 它们旨在模拟像刚体一样的物理行为,同时还支持倾向于提供角色移动的自定义逻辑。 – rutter

回答

2

如果你想有一个基础的“物理学”运动,那么你应该施加力的Rigidbody。作用于刚体的好处是它会考虑与物体(如墙壁)碰撞。

Here是一个很好的介绍教程(它是3D,但同样的概念适用于2D)。这是一些修正案教程中的代码,使其2D:

using UnityEngine; 
using System.Collections; 

public class PlayerController : MonoBehaviour { 

    public float speed; // Here we set a float variable to hold our speed value 

    private Rigidbody2D rb; // This is to hold the rigidbody component 

    // Start is called as you start the game, we use it to initially give values to things 
    void Start() 
    { 
     rb = GetComponent<Rigidbody2D>(); // Here we actually reference the rigidbody. 
    } 

    void FixedUpdate() 
    { 
     // We assign values based on our input here: 
     float moveHorizontal = Input.GetAxis ("Horizontal"); 
     float moveVertical = Input.GetAxis ("Vertical"); 

     // Here we assign those values to a Vector2 variable. 
     Vector2 movement = new Vector2 (moveHorizontal, moveVertical); 

     rb.AddForce (movement * speed); // Finally we apply the forces to the rigidbody 
    } 
} 

我们可以改变方式其中力作用在刚体通过改变AddForceForceMode2D参数。例如,ForceMode2D.Force

使用它的质量向刚体施加力。

ForceMode2D.Impulse

添加瞬时力冲动rigidbody2D,使用它的质量。

这对跳跃等事情更好。

  • 注意 - 这是更好地把基于物理的方法调用中FixedUpdate,而不是在Update,因为帧速率的依赖。
  • 另请注意 - 当您对物体施加力时,它会加速,因为您正在作用于一个物体(刚体)并基于其他力量减速(如friction等)如果您希望您的球员减速到停止而不是停止,考虑作用于玩家的力量。此外,如果您根据固定更新对刚体施加一次力,那么如果您选择ForceMode2D.Force,则会导致您想要的恒定速度,因为其他反向作用的力会平衡它(参见下图 - 图像为http://www.school-for-champions.com/ )。

enter image description here


编辑:关于由鲁特注释以上, here是二维字符控制器的入门教程。

2

个人而言,我使用这样的设置:

Rigidbody2D rb; 
[SerializeField] [Range(0, 1)] float LerpConstant; 
//Other stuff here 
FixedUpdate() { 
    float h = Input.GetAxisRaw("Horizontal"); 
    Vector2 movement = new Vector2(h, rb.velocity.y); 
    rb.velocity = Vector2.Lerp(rb.velocity, movement, LerpConstant); 
} 

线性插值仅仅意味着 “采取Vector2即 'x' 的从A到B的量,并返回它”。所以代码会创建一个运动矢量,即您的水平运动(用户输入),垂直运动(刚体已经具有的垂直运动),然后使当前速度等于它。通过直接修改速度,它可以确保您的运动保持平稳和持续,只要您知道如何正确执行。

+0

关于直接修改速度的好建议:) –