Convert input.GetKey into touch and hold function

Hi,

Here’s what the game and the mechanic looks like:

This is what I currently have:

        if (Input.GetKey (KeyCode.Q))
            angle = -Time.deltaTime * 128;
        else if (Input.GetKey (KeyCode.W))
            angle = Time.deltaTime * 128;
        else
        {

This works very well when I run the game on a computer, but obviously not when I build it and run on android.

I want to change the code so that the dark grey object moves not by pressing Q or W but by touching and holding.

Could anyone please guide me on this one?

Shoot a ray from the touch position from the camera ?

Oh. How to do this?

Unity has a example of this on there input touch API

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    void Update() {
            if (Input.GetTouch(0).phase == TouchPhase.Began) {
               
                // Construct a ray from the current touch coordinates
                RaycastHit hit;
                Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
                if (Physics.Raycast(ray, out hit))
                {
                    // Use the name or a tag object to make sure it's the dark grey one
                   // If it is perform the moment code
 
                }             
        }
    }
}

Something like that

Hi, thanks. Doesnt seem to work for me.

I tried to edit the original code:

    // Update is called once per frame
    void Update () {
        float angle = 0;
        bool player_stand;
        bool player_stand_this;

        GameObject player = GameObject.Find("Player");
        MoveCharacter script = player.GetComponent("MoveCharacter") as MoveCharacter;
        player_stand = (script.StandingFloor.GetComponent("Rotating") != null);
        player_stand_this = (script.StandingFloor == gameObject);

        if (!playerRot && player_stand) return;

        if (Input.GetKey (KeyCode.Q))
            angle = -Time.deltaTime * 128;
        else if (Input.GetKey (KeyCode.W))
            angle = Time.deltaTime * 128;
        else
        {
            float dst = Mathf.Floor((m_Angle + 45) / 90) * 90;
            angle = dst - m_Angle;
            if (Mathf.Abs(angle) > 1) angle *= 0.125f;
            if (rotating && angle == 0) {
                rotating = false;
                Vector3 pos = transform.position;
                transform.position = new Vector3(Mathf.Round(pos.x), Mathf.Round(pos.y), Mathf.Round(pos.z));
                if (player_stand_this)
                {
                    script.RecalcPlayerPos();
                }
            }
        }

into this:

// Update is called once per frame
    void Update () {
        float angle = 0;
        bool player_stand;
        bool player_stand_this;

        GameObject player = GameObject.Find("Player");
        MoveCharacter script = player.GetComponent("MoveCharacter") as MoveCharacter;
        player_stand = (script.StandingFloor.GetComponent("Rotating") != null);
        player_stand_this = (script.StandingFloor == gameObject);

        if (!playerRot && player_stand) return;

        if (Input.GetTouch(0).phase == TouchPhase.Began) {
            // Construct a ray from the current touch coordinates
            RaycastHit hit;
            Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
            if (Physics.Raycast(ray, out hit))
            {
                GameObject obj = hit.transform.gameObject;

                {
            float dst = Mathf.Floor((m_Angle + 45) / 90) * 90;
            angle = dst - m_Angle;
            if (Mathf.Abs(angle) > 1) angle *= 0.125f;
            if (rotating && angle == 0) {
                rotating = false;
                Vector3 pos = transform.position;
                transform.position = new Vector3(Mathf.Round(pos.x), Mathf.Round(pos.y), Mathf.Round(pos.z));
                if (player_stand_this)
                {
                    script.RecalcPlayerPos();
                }
            }
        }

But nothing happens. It’s not rotating. I must have done it all wrong

Yeah so basically the ray shoots out from the camera to where you are touching, the objects you want to hit need to have a collider on them. You can then sue that to check the tag or name to make sure its the dark one then perform the code.

if(hit.gameObject.tag == "DarkGreyObject") {
    // Do rotation
}

The issue im seeing is you want to rotate either negatively or positively, a single touch could only rotate in one direction. you will probably want another method for example you can click the piece then click either the left side or right side of the screen to rotate it by how ever much like 90 degrees or steps of 15 or 25.

Yes I had this in mind but I thought it would be too complicated as I am only weeks into Unity. I’ve been building games using Buildbox, and that’s a engine which requires no coding skills :slight_smile: But I want to learn C# now. Thanks for helping me out :slight_smile:

I get this error as I try to add the string you wrote:

Severity    Code    Description    Project    File    Line    Suppression State
Error    CS1061    'RaycastHit' does not contain a definition for 'GameObject' and no extension method 'GameObject' accepting a first argument of type 'RaycastHit' could be found (are you missing a using directive or an assembly reference?)    UnityValley-master.CSharp    D:\DOWNLOADS\ny2\UnityValley-master\Assets\Rotating.cs    52    Active

Whoops yeah use this and put it within the physics ray cast out bit:

if(Physics.Raycast(ray, out hit))
{ 
  if(hit.collider.tag == "DarkGreyObject")
   {
        // Do rotation
    }
}

Thanks. Still some muffins. I keep getting this error at line 48:

Encapsulate the touch code with this check first to make sure there is actually a touch if not then don’t check for the touch.

if (Input.touchCount > 0)
{
     //all the other code goes  in this
     // if(Input.GetTouch(0).phase == TouchPhase.Begin) etc
  
}

Okay, no errors now, working with this:

 if (Input.touchCount > 0)
        {
           if (Input.GetTouch(0).phase == TouchPhase.Began) {
                // Construct a ray from the current touch coordinates
                RaycastHit hit;
                Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(0).position);
                if (Physics.Raycast(ray, out hit))
                {
                    if (hit.collider.tag == "Floor") {
                    }

The tag of the dark grey object is “Floor”, but nothing happens as I click it. (I am testing on computer, but a mouseclick equals a tap on a mobile device, right?)

No mouse input and touch are different you would be best testing it on the device, the code there creates a ray from the place you touch from the camera into the scene. it then checks if it has hit a collider and if it has it checks if that game object has the tag “Floor” (you set the tag on the object in the inspector). If it does then you can run a method, as discussed earlier you will probably want the object to maybe highlight then allow users to click on either the left or the right side of the screen to cause a rotation.

if (hit.collider.tag == "Floor")
{
      RotateEnabled();               
}

With the method call you can maybe enable buttons for rotate left or right and these replace your w and q controls and allow you to call the following functions:

public void RotateLeft()
{
angle = -Time.deltaTime * 128;
}

public void RotateRight()
{
angle = Time.deltaTime * 128;
}

Once they have committed to the rotation, RotateEnable disables the buttons and highlight of the object and pops it in place and waits for the next time its tapped.