Search Unity

Space shooter mobile movement problem

Discussion in 'Getting Started' started by CyberInteractiveLLC, Mar 15, 2018.

  1. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    Hi, I've been following the "Space Shooter" Mobile conversion tutorial, after finishing I found that the touch movement here is a little laggy, so when dragging your finger around the ship is not moving excatly where your finger is but a bit behind... i have no experience with mobile controls, so where should i look at?

    this is the script for reference

    Player Controller:

    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. [System.Serializable]
    5. public class Done_Boundary
    6. {
    7.     public float xMin, xMax, zMin, zMax;
    8. }
    9.  
    10. public class Done_PlayerController : MonoBehaviour
    11. {
    12.     public float speed;
    13.     public float tilt;
    14.     public Done_Boundary boundary;
    15.  
    16.     public GameObject shot;
    17.     public Transform shotSpawn;
    18.     public float fireRate;
    19.     public SimpleTouchPad touchPad;
    20.     public SimpleTouchAreaButton areaButton;
    21.  
    22.     private float nextFire;
    23.     private Quaternion calibrationQuaternion;
    24.  
    25.     void Start () {
    26.         CalibrateAccelerometer ();
    27.     }
    28.    
    29.     void Update ()
    30.     {
    31.         if (areaButton.CanFire () && Time.time > nextFire)
    32.         {
    33.             nextFire = Time.time + fireRate;
    34.             Instantiate(shot, shotSpawn.position, shotSpawn.rotation);
    35.             audio.Play ();
    36.         }
    37.     }
    38.    
    39.     //Used to calibrate the Iput.acceleration input
    40.     void CalibrateAccelerometer () {
    41.         Vector3 accelerationSnapshot = Input.acceleration;
    42.         Quaternion rotateQuaternion = Quaternion.FromToRotation (new Vector3 (0.0f, 0.0f, -1.0f), accelerationSnapshot);
    43.         calibrationQuaternion = Quaternion.Inverse (rotateQuaternion);
    44.     }
    45.    
    46.     //Get the 'calibrated' value from the Input
    47.     Vector3 FixAcceleration (Vector3 acceleration) {
    48.         Vector3 fixedAcceleration = calibrationQuaternion * acceleration;
    49.         return fixedAcceleration;
    50.     }
    51.  
    52.     void FixedUpdate ()
    53.     {
    54. //      float moveHorizontal = Input.GetAxis ("Horizontal");
    55. //      float moveVertical = Input.GetAxis ("Vertical");
    56.        
    57. //      Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
    58.  
    59. //      Vector3 accelerationRaw = Input.acceleration;
    60.         //      Vector3 acceleration = FixAcceleration (accelerationRaw);
    61. //      Vector3 movement = new Vector3 (acceleration.x, 0.0f, acceleration.y);
    62.  
    63.         Vector2 direction = touchPad.GetDirection ();
    64.         Vector3 movement = new Vector3 (direction.x, 0.0f, direction.y);
    65.         rigidbody.velocity = movement * speed;
    66.        
    67.         rigidbody.position = new Vector3
    68.         (
    69.             Mathf.Clamp (rigidbody.position.x, boundary.xMin, boundary.xMax),
    70.             0.0f,
    71.             Mathf.Clamp (rigidbody.position.z, boundary.zMin, boundary.zMax)
    72.         );
    73.        
    74.         rigidbody.rotation = Quaternion.Euler (0.0f, 0.0f, rigidbody.velocity.x * -tilt);
    75.     }
    76. }
    Touch Pad

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4. using System.Collections;
    5.  
    6. public class SimpleTouchPad : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler {
    7.  
    8.     public float smoothing;
    9.  
    10.     private Vector2 origin;
    11.     private Vector2 direction;
    12.     private Vector2 smoothDirection;
    13.     private bool touched;
    14.     private int pointerID;
    15.  
    16.     void Awake () {
    17.         direction = Vector2.zero;
    18.         touched = false;
    19.     }
    20.  
    21.     public void OnPointerDown (PointerEventData data) {
    22.         if (!touched) {
    23.             touched = true;
    24.             pointerID = data.pointerId;
    25.             origin = data.position;
    26.         }
    27.     }
    28.  
    29.     public void OnDrag (PointerEventData data) {
    30.         if (data.pointerId == pointerID) {
    31.             Vector2 currentPosition = data.position;
    32.             Vector2 directionRaw = currentPosition - origin;
    33.             direction = directionRaw.normalized;
    34.         }
    35.     }
    36.  
    37.     public void OnPointerUp (PointerEventData data) {
    38.         if (data.pointerId == pointerID) {
    39.             direction = Vector3.zero;
    40.             touched = false;
    41.         }
    42.     }
    43.  
    44.     public Vector2 GetDirection () {
    45.         smoothDirection = Vector2.MoveTowards (smoothDirection, direction, smoothing);
    46.         return smoothDirection;
    47.     }
    48. }
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I'm not sure exactly how all this works together — the first script seems to be reading the accelerometer, while the second is finding the direction the pointer is dragged.

    But I do know this: that GetDirection method is just skanky. :p It sounds like a simple getter but in fact every time you call it, it's moving smoothDirection (which is its return value) towards the last computed direction. So if you call it 3 times in a frame, you'll get three different answers. And how fast it matches the last drag direction depends on how often you call it.

    I'm being harsh because I assume you got this from the tutorial, and people writing tutorials should know better. It might happen to work, but it's absolutely horrible design. smoothDirection should be updated in Update, and GetDirection should only return it (without side-effects). Whoever wrote that tutorial should be wearing the Hood of Shame.

    Anyway. If it's laggy, it could be due to the smoothing. Try increasing the value of that. We're going towards a normalized direction, so if you set smoothing to 2 or more, it should be equivalent to no smoothing at all.
     
  3. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    I played around with every value, the movement is still not good

    I found this script that is closer to what i need

    Creating a empty object with this script

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class TouchTest : MonoBehaviour {
    6.  
    7.     public static Vector3 finger;
    8.     public static Vector3 fingerPosition;
    9.  
    10.     public Boundary boundary;
    11.  
    12.     Camera cam;
    13.  
    14.     void Awake()
    15.     {
    16.         cam = Camera.main;
    17.     }
    18.     void Update()
    19.     {
    20.         foreach (Touch touch in Input.touches)
    21.         {
    22.             finger = touch.position;
    23.             fingerPosition = cam.ScreenToWorldPoint(finger);
    24.  
    25.             Vector3 bounds = new Vector3 ((Mathf.Clamp (fingerPosition.x, boundary.xMin, boundary.xMax)), 0.0f, (Mathf.Clamp (fingerPosition.z, boundary.zMin, boundary.zMax)));
    26.  
    27.             transform.position = fingerPosition;
    28.         }
    29.     }
    30. }
    Then the player just moves toward it but there's some problems with it

    first it moves the ship exactly at Y position of the camera, i just need it on X and Z, also when hitting the boundary, the player teleports back to stay within
     
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well the first problem is easily solved: after you get the fingerPosition on line 23, simply override the Y value by adding fingerPosition.y = transform.position.y; at line 24.

    (Though are you sure you want to move in X and Z? Most 2D games are set up in X and Y.)

    Next, on line 25, you're going to a lot of work to calculate a bounded position... which you then ignore/throw out, and set the transform position to your original, unbounded finger position on line 27. You probably want to use bounds instead of fingerPosition on line 27. (And in fact doing so would solve the first problem, too, assuming that y=0 is where you want your transform to be.)
     
  5. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    oh the boundary was meant for the player only

    Player script:

    Code (CSharp):
    1.         Vector3 smoothPos = Vector3.Lerp(rb.position, cubeToMoveTowards.position, 0.5f);
    2.  
    3.         Vector3 bounds = new Vector3 ((Mathf.Clamp (smoothPos.x, boundary.xMin, boundary.xMax)), transform.position.y, (Mathf.Clamp (smoothPos.z, boundary.zMin, boundary.zMax)));
    4.         rb.position = bounds;
    Empty object to follow (cubeToMovetowards in player script)

    Code (CSharp):
    1.     void FixedUpdate()
    2.     {
    3.         foreach (Touch touch in Input.touches)
    4.         {
    5.             finger = touch.position;
    6.             fingerPosition = cam.ScreenToWorldPoint(finger);
    7.  
    8.             transform.position = fingerPosition;
    9.         }
    10.     }
    the player still teleports around if i touch on further spot and not sure how to fix this
     
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Well you need to bounds-constrain it. And also fix the Y. Just like described two posts up.

    Also, here's a tip: you're not really making any use of multiple touches here. If you put multiple fingers down with the code above, the transform would simply jump around trying to be in all those places at once (which it can't do). So I think you're intending it to need only one touch. In that case, you should just use mousePosition, since that works on desktop (and within Unity) as well, making testing much easier/faster.
     
  7. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    Code (CSharp):
    1.     void FixedUpdate ()
    2.  
    3.     {
    4.  
    5.             Vector3 accelerationRaw = Input.acceleration;
    6.             Vector3 acceleration = FixAccelleration (accelerationRaw);
    7.             Vector3 movement = new Vector3 (acceleration.x, 0.0f, acceleration.y);
    8.  
    9.             rb.velocity = (movement * speed);
    10.  
    11.  
    12.  
    13.         Vector3 bounds = new Vector3 ((Mathf.Clamp (rb.position.x, boundary.xMin, boundary.xMax)), 0.0f, (Mathf.Clamp (rb.position.z, boundary.zMin, boundary.zMax)));
    14.         rb.position = bounds;
    15.  
    16.     }
    17.  
    18.     void CalibrateAccellerometer()
    19.     {
    20.         Vector3 accelerationSnapshot = Input.acceleration;
    21.         Quaternion rotateQuaternion = Quaternion.FromToRotation (new Vector3 (0.0f, 0.0f, -1.0f), accelerationSnapshot);
    22.         calibrationQuaternion = Quaternion.Inverse (rotateQuaternion);
    23.     }
    24.  
    25.     Vector3 FixAccelleration (Vector3 acceleration)
    26.     {
    27.         Vector3 fixedAcceleration = calibrationQuaternion * acceleration;
    28.         return fixedAcceleration;
    29.     }
    30. }
    my main problem is the player doesn't move instantly with the touch, it's lagging behind.. i need it to move instantly
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    With that code, I'm shocked that it moves with a touch at all. That code only reads the accelerometer.
     
  9. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    Sorry, i think this is the one ?

    Code (CSharp):
    1. using System.Collections;
    2. using UnityEngine.UI;
    3. using UnityEngine.EventSystems;
    4. using System.Collections.Generic;
    5. using UnityEngine;
    6.  
    7. public class SimpleTouchPad : MonoBehaviour, IPointerDownHandler, IDragHandler, IPointerUpHandler {
    8.     public float smoothing;
    9.  
    10.     private Vector2 origin;
    11.     private Vector2 direction;
    12.     private Vector2 smoothDirection;
    13.     private bool touched;
    14.     private int pointerID;
    15.  
    16.     void Awake ()
    17.     {
    18.         direction = Vector2.zero;
    19.         touched = false;
    20.     }
    21.     public void OnPointerDown (PointerEventData data)
    22.     {
    23.         if (!touched) {
    24.             touched = true;
    25.             pointerID = data.pointerId;
    26.             origin = data.position;
    27.         }
    28.     }
    29.  
    30.     public void OnDrag (PointerEventData data)
    31.     {
    32.         if (data.pointerId == pointerID) {
    33.             // Compare the difference between start point and current pointer pos
    34.             Vector2 currentPosition = data.position;
    35.             Vector2 directionRaw = currentPosition - origin;
    36.             direction = directionRaw.normalized;
    37.         }
    38.     }
    39.  
    40.     public void OnPointerUp (PointerEventData data)
    41.     {
    42.         if (data.pointerId == pointerID) {
    43.             // reset Everything
    44.             direction = Vector3.zero;
    45.             touched = false;
    46.         }
    47.     }
    48.  
    49.     public Vector2 GetDirection ()
    50.     {
    51.         smoothDirection = Vector2.MoveTowards (smoothDirection, direction, smoothing);
    52.         return smoothDirection;
    53.         return direction;
    54.     }
    55. }
     
  10. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    You've shown three different control scripts, and there seems to be some confusion about which one is actually in use. Could it be that you have multiple control scripts acting on this thing at the same time? That could certainly cause all sorts of weird behavior, including sluggish response.
     
  11. RichAllen2023

    RichAllen2023

    Joined:
    Jul 19, 2016
    Posts:
    1,026
    If you're a bit stuck, have a look on Facebook for a mate of mine called Johnathan Mendham, if you find him tell him I sent you, he's a Unity expert who's taught me loads of stuff.
     
  12. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    you can link me
     
  13. RichAllen2023

    RichAllen2023

    Joined:
    Jul 19, 2016
    Posts:
    1,026
    Why? Because you're too damn idle to type words into Facebook? Smh.
     
  14. RichAllen2023

    RichAllen2023

    Joined:
    Jul 19, 2016
    Posts:
    1,026
    Check your inbox, I just PMd you a link to his FB page rather than post it on the public forum.

    Next time try looking for people yourself, it's not that hard :)
     
  15. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    What? your friend is not the only one with that name in facebook, i'am supposed to magically know which of the Johnathan Mendham's is your friend?

    Next time try to have some basic logic.
     
  16. RichAllen2023

    RichAllen2023

    Joined:
    Jul 19, 2016
    Posts:
    1,026
    Check your inbox, I sent you a PM with a link to his page.

    But no, you're too lazy to click buttons, smh.
     
  17. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    I wasn't referring to that though, Do you actually read?

    Maybe you should go find my friend on facebook, just type the name Mark, if you don't find him you're too lazy bro.

    "smh"
     
  18. RichAllen2023

    RichAllen2023

    Joined:
    Jul 19, 2016
    Posts:
    1,026
    I have 3 things to say to you, GTFO, STFU and generally go over there and shove a Windows based Laptop up your arse.

    Contrary to popular belief I have a life beyond the Internet, you should try it sometime, it's rather good fun.
     
  19. CyberInteractiveLLC

    CyberInteractiveLLC

    Joined:
    May 23, 2017
    Posts:
    307
    Haha, You sound really upset! you say gtfo? You're the one who somehow managed to crawl his way into this thread, Well at least some parts of your brain function well enough to be able to click around in a internet forum, this is great but you should really teach yourself how social websites like Facebook or Twitter work.

    Also, What does this has to do with having a life? is this what happens when you get in any arguments you randomly scream "I have a life!"? , by the looks of your avatar, you don't seem to be enjoying it that much.
     
  20. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, guys, let's be nice. The Unity forums are generally one of the nicest, most supportive places on the internet. If the other guy isn't being helpful, or isn't appreciating your help, then just stop responding.

    At some point the moderators will step in and lock the thread, but I'm sure they'd rather we behave ourselves without adult supervision. :)
     
    Bill_Martini likes this.