Vic
Vic

Reputation: 23

Moving Game Object with UI Buttons

I am trying to set up control of Player game object by UI buttons. 2d top down view scene.

I want to transfer Player object smoothly on fixed distance (0.8 for Axix X for left-right direction and 2.4 for up-down)when I release left/right/up/down ui buttons.

Here i found code for smooth movement but there Player is moving all the time while ui button is pressed.

Can you help me to make it move on mouse up (pointer up) and to move for public x= 0.8f for left/right, and public y = 2.4f for up/down

And at the same time i want to use different speed (peblic) for moves on x and y Axis

Its ok if it should be totally other script using smth like transform.translate Kindly guide to for any possible solution for this. Thanks

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityStandardAssets.CrossPlatformInput;

public class PlayerControl : MonoBehaviour
{

    float movX;
    float movY;
    Rigidbody2D rb;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
    }

    void Update()
    {
        movX = CrossPlatformInputManager.GetAxisRaw("Horizontal");
        movY = CrossPlatformInputManager.GetAxisRaw("Vertical");

          rb.velocity = new Vector2(movX * 1, movY * 1);

    }
}

Upvotes: 2

Views: 1176

Answers (2)

Menyus777
Menyus777

Reputation: 7007

This script can be moved by the WASD keys. This should move your gameObject by the requested amount over x amount of time(speed). Currently it can be only moved when it'S reached its destionation but you can easily modify this :), by stopping the coroutine

using System.Collections;
using UnityEngine;

public class PlayerControl : MonoBehaviour
{
    // We gonna move by WASD keys

    [Header("Speed & Movement settings")]
    [SerializeField]
    float Speed = 2.0f;
    [SerializeField]
    float movSpeedX = 0.8f;
    [SerializeField]
    float movSpeedY = 2.4f;

    bool ReachedTarget = true;

    void Update()
    {
        if (ReachedTarget)
        {
            Vector2 dest = Vector2.zero;
            Vector2 currentPos = transform.position;
            if (Input.GetKeyUp(KeyCode.W))
            {
                dest = currentPos + (Vector2.up * movSpeedY);
                StartCoroutine(moveTo(dest, Speed));
            }
            else if (Input.GetKeyUp(KeyCode.S))
            {
                dest = currentPos + (Vector2.down * movSpeedY);
                StartCoroutine(moveTo(dest, Speed));
            }
            else if (Input.GetKeyUp(KeyCode.D))
            {
                dest = currentPos + (Vector2.right * movSpeedX);
                StartCoroutine(moveTo(dest, Speed));
            }
            else if (Input.GetKeyUp(KeyCode.A))
            {
                dest = currentPos + (Vector2.left * movSpeedX);
                StartCoroutine(moveTo(dest, Speed));
            }
        }
    }

    // Time to take is in seconds
    IEnumerator moveTo(Vector2 TargetPosition, float TimetoTake)
    {
        Vector2 originalPosition = transform.position;
        float Time_taken = 0f;
        ReachedTarget = false;
        while (Time_taken < 1)
        {
            Time_taken += Time.deltaTime / TimetoTake;
            // Interpolating between the original and target position this basically provides your "speed"
            transform.position = Vector2.Lerp(originalPosition, TargetPosition, Time_taken);
            yield return null;
        }
        Time_taken = 0;
        transform.position = TargetPosition;
        ReachedTarget = true;
    }
}

Upvotes: 1

LingSamuel
LingSamuel

Reputation: 584

I can't find any documentation of CrossPlatformInputManager, and I know nothing about it. But if you need to get the event of "release a key" instead of "press the key", try this: Input.GetKeyUp.

Description

Returns true during the frame the user releases the key identified by name.

You need to call this function from the Update function, since the state gets reset each frame. It will not return true until the user has pressed the key and released it again.

For the list of key identifiers see Conventional Game Input. When dealing with input it is recommended to use Input.GetAxis and Input.GetButton instead since it allows end-users to configure the keys.

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyUp("space"))
        {
            print("Space key was released");
        }
    }
}

If you want to stop the rigid body, you need to reset its velocity to zero. Or you can use Rigidbody2D.MovePosition to move it a certain distance.

Parameters

position The new position for the Rigidbody object.

Description

Moves the rigidbody to position.

Moves the rigidbody to the specified position by calculating the appropriate linear velocity required to move the rigidbody to that position during the next physics update. During the move, neither gravity or linear drag will affect the body. This causes the object to rapidly move from the existing position, through the world, to the specified position.

Because this feature allows a rigidbody to be moved rapidly to the specified position through the world, any colliders attached to the rigidbody will react as expected i.e. they will produce collisions and/or triggers. This also means that if the colliders produce a collision then it will affect the rigidbody movement and potentially stop it from reaching the specified position during the next physics update. If the rigidbody is kinematic then any collisions won't affect the rigidbody itself and will only affect any other dynamic colliders.

2D rigidbodies have a fixed limit on how fast they can move therefore attempting to move large distances over short time-scales can result in the rigidbody not reaching the specified position during the next physics update. It is recommended that you use this for relatively small distance movements only.

It is important to understand that the actual position change will only occur during the next physics update therefore calling this method repeatedly without waiting for the next physics update will result in the last call being used. For this reason, it is recommended that it is called during the FixedUpdate callback.

Note: MovePosition is intended for use with kinematic rigidbodies.

// Move sprite bottom left to upper right.  It does not stop moving.
// The Rigidbody2D gives the position for the cube.

using UnityEngine;
using System.Collections;

public class Example : MonoBehaviour
{
    public Texture2D tex;

    private Vector2 velocity;
    private Rigidbody2D rb2D;
    private Sprite mySprite;
    private SpriteRenderer sr;

    void Awake()
    {
        sr = gameObject.AddComponent<SpriteRenderer>();
        rb2D = gameObject.AddComponent<Rigidbody2D>();
    }

    void Start()
    {
        mySprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), new Vector2(0.5f, 0.5f), 100.0f);
        velocity = new Vector2(1.75f, 1.1f);
        sr.color = new Color(0.9f, 0.9f, 0.0f, 1.0f);

        transform.position = new Vector3(-2.0f, -2.0f, 0.0f);
        sr.sprite = mySprite;
    }

    void FixedUpdate()
    {
        rb2D.MovePosition(rb2D.position + velocity * Time.fixedDeltaTime);
    }
}

Both documents have an example. Or you don't want to user keyboard but UI buttons, try this: IPointerDownHandler and IPointerUpHandler

Description Interface to implement if you wish to receive OnPointerDown callbacks.

Detects ongoing mouse clicks until release of the mouse button. Use IPointerUpHandler to handle the release of the mouse button.

//Attach this script to the GameObject you would like to have mouse clicks detected on
//This script outputs a message to the Console when a click is currently detected or when it is released on the GameObject with this script attached

using UnityEngine;
using UnityEngine.EventSystems;

public class Example : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    //Detect current clicks on the GameObject (the one with the script attached)
    public void OnPointerDown(PointerEventData pointerEventData)
    {
        //Output the name of the GameObject that is being clicked
        Debug.Log(name + "Game Object Click in Progress");
    }

    //Detect if clicks are no longer registering
    public void OnPointerUp(PointerEventData pointerEventData)
    {
        Debug.Log(name + "No longer being clicked");
    }
}

Upvotes: 0

Related Questions