![](/img/trans.png)
[英]How do I make Rigidbody2D.MovePosition move a gameobject in local space?
[英]How do I make a Rigidbody 2D move in the direction the user swiped in?
使用 Unity 2D 和 c#,我試圖讓手機游戲中的游戲對象能夠在用戶滑動的方向上連續平滑地移動。下面的代碼是我一直在嘗試開始工作的代碼我運行它,沒有任何反應。 每當我滑動時,游戲對象就會保持原位。 我對這種東西很陌生,所以我很難找出問題所在。 我認為這與第 38 到 62 行的 if 和 else 語句有關,但我不完全確定。 非常感謝你的幫助。
private Vector3 fp; //First touch position
private Vector3 lp; //Last touch position
private float dragDistance; //minimum distance for a swipe to be registered
private float speed = 10;
private Rigidbody2D rb;
private Vector2 moveVelocity;
void Start() {
dragDistance = Screen.height * 5 / 100; //dragDistance is 5% height of the screen
rb = GetComponent<Rigidbody2D>();
}
void Update() {
if (Input.touchCount == 1) // user is touching the screen with a single touch
{
Touch touch = Input.GetTouch(0); // get the touch
if (touch.phase == TouchPhase.Began) //check for the first touch
{
fp = touch.position;
lp = touch.position;
}
else if (touch.phase == TouchPhase.Moved) // update the last position based on where they moved
{
lp = touch.position;
}
else if (touch.phase == TouchPhase.Ended) //check if the finger is removed from the screen
{
lp = touch.position; //last touch position. Ommitted if you use list
//Check if drag distance is greater than ?% of the screen height
if (Mathf.Abs(lp.x - fp.x) > dragDistance || Mathf.Abs(lp.y - fp.y) > dragDistance)
{//It's a drag
//check if the drag is vertical or horizontal
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{ //If the horizontal movement is greater than the vertical movement...
if ((lp.x > fp.x)) //If the movement was to the right)
{ //Right swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
else
{ //Left swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y > fp.y) //If the movement was up
{ //Up swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
else
{ //Down swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
}
}
}
}
}
void FixedUpdate() {
rb.MovePosition(rb.position + moveVelocity * Time.fixedDeltaTime);
}
首先,您的情況完全相同:
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{ //If the horizontal movement is greater than the vertical movement...
if ((lp.x > fp.x)) //If the movement was to the right)
{ //Right swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
else
{ //Left swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y > fp.y) //If the movement was up
{ //Up swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
else
{ //Down swipe
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
}
}
他們都使用完全相同的兩行
Vector2 moveInput = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
moveVelocity = moveInput.normalized * speed;
我的猜測是Input.GetAxisRaw("Horizontal")
和Input.GetAxisRaw("Vertical")
始終為0
,因此根本不會發生任何移動。 據我所知,它僅適用於鍵盤和鼠標輸入,不適用於觸摸。
你不是寧願根據你的滑動方向而是做例如
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{
//If the horizontal movement is greater than the vertical movement...
if (lp.x > fp.x) //If the movement was to the right)
{ //Right swipe
moveVelocity = Vector2.right;
}
else
{ //Left swipe
moveVelocity = Vector2.left;
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y > fp.y) //If the movement was up
{ //Up swipe
moveVelocity = Vector2.up;
}
else
{ //Down swipe
moveVelocity = Vector2.down;
}
}
進而
void FixedUpdate()
{
rb.MovePosition(rb.position + moveVelocity * speed * Time.deltaTime);
}
請注意,而不是Time.fixedDeltaTime
為了讀取增量時間,建議使用
Time.deltaTime
代替,因為如果您在FixedUpdate
函數或Update
函數中,它會自動返回正確的增量時間。
或者你也可以直接分配rb.velocity
if (Mathf.Abs(lp.x - fp.x) > Mathf.Abs(lp.y - fp.y))
{
//If the horizontal movement is greater than the vertical movement...
if (lp.x > fp.x) //If the movement was to the right)
{ //Right swipe
rb.velocity = Vector2.right * speed;
}
else
{ //Left swipe
rb.velocity = Vector2.left * speed;;
}
}
else
{ //the vertical movement is greater than the horizontal movement
if (lp.y > fp.y) //If the movement was up
{ //Up swipe
rb.velocity = Vector2.up * speed;;
}
else
{ //Down swipe
rb.velocity = Vector2.down * speed;;
}
}
沒有FixedUpdate
。 由於您在此處僅更改 Rigidbody 的velocity
並且不直接移動它,因此可以在Update
執行此操作。
一般注意事項:
您應該使用switch-case
代替
switch(touch.phase)
{
case TouchPhase.Began:
fp = touch.position;
// No need to assign lp here actually
// lp = touch.position;
break;
case TouchPhase.Ended:
// lp could actually be a local variable - no need to make it a field
var lp = touch.position;
...
break;
}
由於您不使用在TouchPhase.Moved
分配的lp
值,因此您實際上可以完全跳過此塊。
您可以通過引入一個額外的變量來使您的if-else
檢查移動方向更具可讀性/更好地維護:
var lp = touch.position;
var difference = lp - fp;
if (difference.x > dragDistance || difference.y > dragDistance)
{
if (Mathf.Abs(difference.x) > Mathf.Abs(difference.y))
{
if (difference.x > 0)
{
// Right swipe
}
else
{
// Left swipe
}
}
else
{
if (difference.y > 0)
{
// Up swipe
}
else
{
// Down swipe
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.