2016-04-17 13 views
4

Ich arbeite an 2D unendlich Runner. Ich habe unter Code, um Eingaben vom Bildschirm wischen, um zu springen, zu gleiten und schnell zu laufen. Ich stelle jumpHeight vom Herausgeber zur Verfügung und Wert ist 500 mit der Rahmenrate von 30. Code funktioniert im Allgemeinen gut, aber manchmal springt Spieler zu hoch für das Aufwischen. Ein ähnlicher Code funktioniert wie erwartet, wenn die Eingabe über Tastatur erfolgt. Warum dies geschieht, übersteigt mein Verständnis von Einheit. Jede Hilfe wird sehr geschätzt.Android wischen und addforce Einheit

using UnityEngine; 
public class PlayerControl : MonoBehaviour 
{ 

    public float ForwardSpeed = 3.7f; //moves player in forward direction 
    public float speedOffset = 0.0f; //offset speed of player 
    public float JumpHeight = 250; //moves player in verticle direction 
    bool grounded = false; //checks if player is grounded or not 
    public Transform groundCheck; 
    float groundCheckRadius = 0.3f; //radius of groundcheck circle to check grounded bool 
    public LayerMask groundLayer; 
    Vector2 fingerStart; 
    Vector2 fingerEnd; 

    void Update() 
    { 
     foreach (Touch touch in Input.touches) 
     { 
      if (touch.phase == TouchPhase.Began) 
      { 
       fingerStart = touch.position; 
       fingerEnd = touch.position; 
      } 

      if (touch.phase == TouchPhase.Moved) 
      { 
       fingerEnd = touch.position; 
       if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe 
       { 
        if (fingerEnd.y - fingerStart.y > 50)//up swipe 
        { 
         Jump(); 
        } 
        else if (fingerEnd.y - fingerStart.y < -50)//Down swipe 
        { 
         //Slide(); 
        } 
        fingerStart = touch.position; 
       } 
      } 
      if (touch.phase == TouchPhase.Stationary) 
      { 
       RunFast(); 
      } 
      if (touch.phase == TouchPhase.Ended) 
      { 
       fingerEnd = touch.position; 
       if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe 
       { 
        if (fingerEnd.y - fingerStart.y > 50)//up swipe 
        { 
         Jump(); 
        } 
        else if (fingerEnd.y - fingerStart.y < -50)//Down swipe 
        { 
         //Slide(); 
        } 
       } 
      } 
     } 



     if (Input.GetButton("Fire1")) 
     { 
      speedOffset = 2.5f; 
     } 
     else 
     { 
      speedOffset = 0.0f; 
     } 


     if (grounded && Input.GetKeyDown(KeyCode.UpArrow)) 
     { 
      grounded = false; 
      GetComponent<Rigidbody2D>().AddForce(new Vector2(0, JumpHeight)); 
     } 

     //check if circle overlaps with ground layer 
     grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer); 
     //Debug.Log(grounded); 


    } 



    void FixedUpdate() 
    { 
     //set players forward velocityto forward speed variable 
     Vector2 PlayerForwardvelocity = GetComponent<Rigidbody2D>().velocity; 
     // Vector2 PlayerJumpHeight = GetComponent<Rigidbody2D>().AddForce() 
     PlayerForwardvelocity.x = ForwardSpeed + speedOffset; 
     GetComponent<Rigidbody2D>().velocity = PlayerForwardvelocity; 
    } 

    void Jump() 
    { 
     if (grounded) 
     { 
      GetComponent<Rigidbody2D>().AddForce(new Vector2(0, JumpHeight)); 
      speedOffset = 0.0f; 
     } 

    } 

    void RunFast() 
    { 
     if (Input.GetButton("Fire1")) 
     { 
      speedOffset = 2.5f; 
     } 
     else 
     { 
      speedOffset = 0.0f; 
     } 
    } 
} 
+0

Laden Sie eine vollständige Version des kompilierenden Codes hoch. Ich brauche es, damit ich es mir durch Debugging ansehe. Sie können andere Funktionen entfernen, die nicht relevant sind. – Programmer

+0

@Programmer Danke für die Antwort. Ich habe den Code bearbeitet. Einfach an ein Spielerobjekt anhängen. Ich habe ein Problem mit verschiedenen Gesten zum Wischen wie ein schneller Wisch, langsamer Ziehen, langer Ziehen. Speziell für einen langen Up-Drag-Spieler springt er sehr hoch. – RxC

+0

Eine Sache kam mir in den Sinn. Bei meinem Projekt habe ich Probleme mit AddForce, ich kann es nicht genau erklären, aber es sieht so aus, als ob Force in falscher Situation hinzugefügt wird, wenn bereits eine Kraft hinzugefügt wurde, könnte es ein Problem geben. Versuchen Sie z. B. zurückzusetzen. Geschwindigkeit auf Y, kurz bevor Sie Sprungkraft hinzufügen. –

Antwort

1

Sie haben 2 Probleme mit Ihrem Code.

Ihr erstes Problem liegt in dieser Codezeile:

grounded = Physics2D.OverlapCircle(groundCheck.position, groundCheckRadius, groundLayer); 

Diese Codezeile versagt. grounded ist immer true. Aus diesem Grund wird der Sprung zu oft aufgerufen, solange der Spieler nicht geerdet ist.

Ersetzen Sie diese Codezeile mit

Collider2D playerCollider = gameObject.GetComponent<Collider2D>(); 
grounded = Physics2D.OverlapCircle(playerCollider.transform.position, 1, groundLayer); 

ODER

Collider2D playerCollider = gameObject.GetComponent<Collider2D>(); 
grounded = playerCollider.IsTouchingLayers(groundLayer.value); 

Ein weiteres Problem mit Ihrem Code ein false report.Sometimes ist, Collider überlappende Renditen true auch wenn es false ist. Ich habe versucht, diesen Teil des Codes zur LateUpdate-Funktion zu verschieben, aber das hat es nicht behoben.

Sie können es beheben, indem Sie einen Timer implementieren. Der Timer wird auf zurückgesetzt und beginnt mit 0,5, wenn der Spieler springt. Springe nicht, wenn der Timer den Wert, auf den er zählt, nicht erreicht hat. .5 to 1 ist ein perfekter Wert dafür. Erhöhen Sie den Timer um Time.deltaTime. Unten ist Ihr ganzer Code mit Timer und Fixes.

public class PlayerControl : MonoBehaviour 
{ 

    public float ForwardSpeed = 3.7f; //moves player in forward direction 
    public float speedOffset = 0.0f; //offset speed of player 
    public float JumpHeight = 250; //moves player in verticle direction 
    bool grounded = false; //checks if player is grounded or not 
    public Transform groundCheck; 
    float groundCheckRadius = 0.3f; //radius of groundcheck circle to check grounded bool 
    public LayerMask groundLayer; 
    Vector2 fingerStart; 
    Vector2 fingerEnd; 

    public float resetTimer = 0.5f; //.5 second 
    float timerCounter = 0; 
    Collider2D playerCollider = null; 

    Rigidbody2D playerRigidBody; 


    void Start() 
    { 
     playerRigidBody = GetComponent<Rigidbody2D>(); 
     playerCollider = gameObject.GetComponent<Collider2D>(); 
    } 

    void Update() 
    { 

     foreach (Touch touch in Input.touches) 
     { 
      if (touch.phase == TouchPhase.Began) 
      { 
       fingerStart = touch.position; 
       fingerEnd = touch.position; 
      } 

      if (touch.phase == TouchPhase.Moved) 
      { 
       fingerEnd = touch.position; 
       if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe 
       { 
        if (fingerEnd.y - fingerStart.y > 50)//up swipe 
        { 
         Jump(); 
        } 
        else if (fingerEnd.y - fingerStart.y < -50)//Down swipe 
        { 
         //Slide(); 
        } 
        fingerStart = touch.position; 
       } 
      } 
      if (touch.phase == TouchPhase.Stationary) 
      { 
       RunFast(); 
      } 
      if (touch.phase == TouchPhase.Ended) 
      { 
       fingerEnd = touch.position; 
       if (Mathf.Abs(fingerEnd.y - fingerStart.y) > 50)//Vertical swipe 
       { 
        if (fingerEnd.y - fingerStart.y > 50)//up swipe 
        { 
         Jump(); 
        } 
        else if (fingerEnd.y - fingerStart.y < -50)//Down swipe 
        { 
         //Slide(); 
        } 
       } 
      } 
     } 



     if (Input.GetButton("Fire1")) 
     { 
      speedOffset = 2.5f; 
     } 
     else 
     { 
      speedOffset = 0.0f; 
     } 


     if (grounded && Input.GetKeyDown(KeyCode.UpArrow)) 
     { 
      grounded = false; 
      playerRigidBody.AddForce(new Vector2(0, JumpHeight)); 
     } 

     //check if circle overlaps with ground layer 
     grounded = Physics2D.OverlapCircle(playerCollider.transform.position, 1, groundLayer); 
     //OR Use grounded = playerCollider.IsTouchingLayers(groundLayer.value); 

     //Increment Timer if it is still less than resetTimer 
     if (timerCounter < resetTimer) 
     { 
      timerCounter += Time.deltaTime; 
     } 
    } 


    void FixedUpdate() 
    { 
     //set players forward velocityto forward speed variable 
     Vector2 PlayerForwardvelocity = playerRigidBody.velocity; 
     // Vector2 PlayerJumpHeight = playerRigidBody.AddForce() 
     PlayerForwardvelocity.x = ForwardSpeed + speedOffset; 
     playerRigidBody.velocity = PlayerForwardvelocity; 
    } 

    void Jump() 
    { 
     if (grounded) 
     { 
      //Exit if timer has not reached the required value to jump again 
      if (timerCounter < resetTimer) 
      { 
       Debug.Log("Failed To Jump because timer has not yet reached"); 
       return; //Exit 
      } 

      timerCounter = 0; //Reset Timer 

      playerRigidBody.AddForce(new Vector2(0, JumpHeight)); 
      speedOffset = 0.0f; 
      Debug.Log("Jumped"); 
     } 
     else 
     { 
      Debug.Log("Not on the Ground"); 
     } 

    } 

    void RunFast() 
    { 
     if (Input.GetButton("Fire1")) 
     { 
      speedOffset = 2.5f; 
     } 
     else 
     { 
      speedOffset = 0.0f; 
     } 
    } 
} 
Verwandte Themen