2
\$\begingroup\$

I'm working on 2D mobile game, and I'm using the Standard Asset(Mobile) Single Joystick prefab to move the Player. Currently my player moves on the X and Y axis.

How can I move my player on the z axis?

I want to do it Like this.move player on z axis

This is Joystick Script fromStander Assets Mobile

using UnityEngine;


[RequireComponent(typeof(GUITexture))]
public class Joystick : MonoBehaviour
{
    class Boundary {
        public Vector2 min = Vector2.zero;
        public Vector2 max = Vector2.zero;
    }

    private static Joystick[] joysticks;                                  // A static collection of all joysticks
    private static bool enumeratedJoysticks = false;
    private static float tapTimeDelta = 0.3f;                               // Time allowed between taps

    public bool touchPad;
    public Vector2 position = Vector2.zero;
    public Rect touchZone;
    public Vector2 deadZone = Vector2.zero;                                         // Control when position is output
    public bool normalize = false;                                                  // Normalize output after the dead-zone?
    public int tapCount;

    private int lastFingerId = -1;                                                          // Finger last used for this joystick
    private float tapTimeWindow;                                                    // How much time there is left for a tap to occur
    private Vector2 fingerDownPos;
    //private float fingerDownTime;
    //private float firstDeltaTime = 0.5f;

    private GUITexture gui;
    private Rect defaultRect;                                                               // Default position / extents of the joystick graphic
    private Boundary guiBoundary = new Boundary();                  // Boundary for joystick graphic
    private Vector2 guiTouchOffset;                                         // Offset to apply to touch input
    private Vector2 guiCenter;                                                      // Center of joystick

    void Start() {
        gui = (GUITexture)GetComponent(typeof(GUITexture));

        defaultRect = gui.pixelInset;
        defaultRect.x += transform.position.x * Screen.width;// + gui.pixelInset.x; // -  Screen.width * 0.5;
        defaultRect.y += transform.position.y * Screen.height;// - Screen.height * 0.5;

        transform.position = Vector3.zero;

        if (touchPad) {
            // If a texture has been assigned, then use the rect ferom the gui as our touchZone
            if ( gui.texture )
                touchZone = defaultRect;
        } else {
            guiTouchOffset.x = defaultRect.width * 0.5f;
            guiTouchOffset.y = defaultRect.height * 0.5f;

            // Cache the center of the GUI, since it doesn't change
            guiCenter.x = defaultRect.x + guiTouchOffset.x;
            guiCenter.y = defaultRect.y + guiTouchOffset.y;

            // Let's build the GUI boundary, so we can clamp joystick movement
            guiBoundary.min.x = defaultRect.x - guiTouchOffset.x;
            guiBoundary.max.x = defaultRect.x + guiTouchOffset.x;
            guiBoundary.min.y = defaultRect.y - guiTouchOffset.y;
            guiBoundary.max.y = defaultRect.y + guiTouchOffset.y;
        }
    }

    public Vector2 getGUICenter() {
        return guiCenter;
    }

    void Disable() {
        gameObject.active = false;
        //enumeratedJoysticks = false;
    }

    private void ResetJoystick() {
        gui.pixelInset = defaultRect;
        lastFingerId = -1;
        position = Vector2.zero;
        fingerDownPos = Vector2.zero;
    }

    private bool IsFingerDown() {
        return (lastFingerId != -1);
    }

    public void LatchedFinger(int fingerId) {
        // If another joystick has latched this finger, then we must release it
        if ( lastFingerId == fingerId )
            ResetJoystick();
    }

    void Update() {
        if (!enumeratedJoysticks) {
            // Collect all joysticks in the game, so we can relay finger latching messages
            joysticks = (Joystick[])FindObjectsOfType(typeof(Joystick));
            enumeratedJoysticks = true;
        }

        int count = Input.touchCount;

        if ( tapTimeWindow > 0 )
            tapTimeWindow -= Time.deltaTime;
        else
            tapCount = 0;

        if ( count == 0 )
            ResetJoystick();
        else
        {
            for(int i = 0; i < count; i++) {
                Touch touch = Input.GetTouch(i);
                Vector2 guiTouchPos = touch.position - guiTouchOffset;

                bool shouldLatchFinger = false;
                if (touchPad) {
                    if (touchZone.Contains(touch.position))
                        shouldLatchFinger = true;
                }
                else if (gui.HitTest(touch.position)) {
                    shouldLatchFinger = true;
                }

                // Latch the finger if this is a new touch
                if (shouldLatchFinger && (lastFingerId == -1 || lastFingerId != touch.fingerId )) {

                    if (touchPad) {
                        //gui.color.a = 0.15;
                        lastFingerId = touch.fingerId;
                        //fingerDownPos = touch.position;
                        //fingerDownTime = Time.time;
                    }

                    lastFingerId = touch.fingerId;

                    // Accumulate taps if it is within the time window
                    if ( tapTimeWindow > 0 )
                        tapCount++;
                    else {
                        tapCount = 1;
                        tapTimeWindow = tapTimeDelta;
                    }

                    // Tell other joysticks we've latched this finger
                    //for (  j : Joystick in joysticks )
                    foreach (Joystick j in joysticks) {
                        if (j != this)
                            j.LatchedFinger( touch.fingerId );
                    }
                }

                if ( lastFingerId == touch.fingerId ) {
                    // Override the tap count with what the iPhone SDK reports if it is greater
                    // This is a workaround, since the iPhone SDK does not currently track taps
                    // for multiple touches
                    if ( touch.tapCount > tapCount )
                        tapCount = touch.tapCount;

                    if ( touchPad ) {
                        // For a touchpad, let's just set the position directly based on distance from initial touchdown
                        position.x = Mathf.Clamp( ( touch.position.x - fingerDownPos.x ) / ( touchZone.width / 2 ), -1, 1 );

                        position.y = Mathf.Clamp( ( touch.position.y - fingerDownPos.y ) / ( touchZone.height / 2 ), -1, 1 );
                    } else {
                        // Change the location of the joystick graphic to match where the touch is
                        Rect r = gui.pixelInset;
                        r.x =  Mathf.Clamp( guiTouchPos.x, guiBoundary.min.x, guiBoundary.max.x );
                        r.y =  Mathf.Clamp( guiTouchPos.y, guiBoundary.min.y, guiBoundary.max.y );
                        gui.pixelInset = r;
                    }

                    if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled)
                        ResetJoystick();
                }
            }
        }

        if (!touchPad) {
            // Get a value between -1 and 1 based on the joystick graphic location
            position.x = ( gui.pixelInset.x + guiTouchOffset.x - guiCenter.x ) / guiTouchOffset.x;
            position.y = ( gui.pixelInset.y + guiTouchOffset.y - guiCenter.y ) / guiTouchOffset.y;
        }

        // Adjust for dead zone
        var absoluteX = Mathf.Abs( position.x );
        var absoluteY = Mathf.Abs( position.y );

        if (absoluteX < deadZone.x) {
            // Report the joystick as being at the center if it is within the dead zone
            position.x = 0;
        }
        else if (normalize) {
            // Rescale the output after taking the dead zone into account
            position.x = Mathf.Sign( position.x ) * ( absoluteX - deadZone.x ) / ( 1 - deadZone.x );
        }

        if (absoluteY < deadZone.y) {
            // Report the joystick as being at the center if it is within the dead zone
            position.y = 0;
        }
        else if (normalize) {
            // Rescale the output after taking the dead zone into account
            position.y = Mathf.Sign( position.y ) * ( absoluteY - deadZone.y ) / ( 1 - deadZone.y );
        }

    }

}

And This is My joystick input script

using UnityEngine;
using System.Collections;

public class JoystickInput : MonoBehaviour {

    public Joystick joysticks;           // Reference to joystick prefab
    public float speed = 10;             // Movement speed
    public bool useAxisInput = true;   // Use Input Axis or Joystick
    private float h = 0, v = 0;         // Horizontal and Vertical values

    // Update is called once per frame
    void Update () {
        // Get horizontal and vertical input values from either axis or the joystick.
        if (!useAxisInput) {
            h = joysticks.position.x;
            v = joysticks.position.y;
        }
        else {
            h = Input.GetAxis("Horizontal");
            v = Input.GetAxis("Vertical");
        }

        // Apply horizontal velocity
        if (Mathf.Abs(h) > 0) {
            rigidbody2D.velocity = new Vector2(h * speed, rigidbody2D.velocity.y);
        }

        // Apply vertical velocity
        if (Mathf.Abs(v) > 0) {
            rigidbody2D.velocity = new Vector2(rigidbody2D.velocity.x, v * speed);
        }
    }
}

i mean like this..

is this not a 2D game ?

\$\endgroup\$
3
\$\begingroup\$

So what you're doing is a pseudo-3D game then. The world works in 3D coordinates, but you just display stuff in 2D.

To do things like these, you probably want to keep the character coordinates in 3D, and use these to calculate the sprite coordinates in 2D.

It's totally up to you how you want your game to be controlled, but if for example, you use the X axis in the controller to control horizontal movement, the Y axis to control depth movement, and a button to jump, then you would have something like this (in pseudocode)

-- characterPos, this is a 3D vector
vector3 characterPos

-- ground movement
if input.right then
    characterPos.x++
else if input.left then
    characterPos.x--
end
if input.up then
    characterPos.z++
else if input.down then
    characterPos.z--
end

-- super trivial jump+gravity
if input.button then
    characterPos.y++
end
characterPos.y -= 0.2
if characterPos.y < 0 then
    characterPos.y = 0
end

-- convert character coordinates to screen coordinates
-- x and y work as normal. z is represented as movement
-- in both x and y
-- We suppose y is positive upwards
vector2 spritePos
spritePos.x = characterPos.x + characterPos.z
spritePos.y = characterPos.z + characterPos.y

This uses a really trivial gravity implementation. If you want a more realistic gravity simulation, you may want to check this answer

How to implement this in your language and engine of choice is left as an exercise to the reader.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.