Hello, Currently my player keep moving forward and keep to move right or left if I keep touching the screen. What I want the player to do is to move a fixed amount of distance to the right or left when tap on the screen. Even if I keep touch it.
The code I have right now is mimic the GetAxis of the keyboard with the right sensitivity, if you like to see how it done in touch, here is the thread.
I can’t figure out what changes I need to make in my code to make it work that way. I have tried TouchPhase.Began but no luck. Here is the code I’m using now to control the player:
void Update() {
if (Input.touchCount > 0) {
touchPosition = Input.GetTouch (0).position;
if (touchPosition.x > screenCenter) {
target = 1;
}
if (touchPosition.x < screenCenter) {
target = -1;
}
moveHorizontal = Mathf.MoveTowards (moveHorizontal, target, sensitivity * Time.deltaTime);
} else {
moveHorizontal = Mathf.MoveTowards (moveHorizontal, 0, sensitivity * Time.deltaTime);
}
movement = new Vector3 (moveHorizontal, 0.0f, 0.0f);
}
void FixedUpdate () {
rb.velocity = movement * speedHorizontal;
//restrict movement to boundaries
if (transform.position.x <= xMin) {
transform.position = new Vector3 (xMin, transform.position.y, transform.position.z);
}
if (transform.position.x >= xMax) {
transform.position = new Vector3 (xMax, transform.position.y, transform.position.z);
}
//tilt the player when move horizontal
rb.rotation = Quaternion.Euler (0.0f, 0.0f, rb.velocity.x * -tilt);
//keep move forward while playing
rb.velocity += Vector3.forward * speedForward;
}
Here is what I have tried, got to move the player one step each touch, however the transform is fast and no tilt
Mix the two. Use the first code, but add the target changing between 1 and -1 only inside TouchPhase.Begin like in the second. Then use Mathf.MoveTowards() outside of the touch phase to move to the last selected target spot.
thank you for your replay. I tried what you suggested and it’s working except one problem: player is moving now only when tap on the screen which is what I wanted. but he is not moving in a fixed amount of distance. for example I want him to move 2 units on the X but he move in a different float value each time such as 1.869 units and if i try to move him back to 0 then he always come back to 0 at different values such as 0.126, 0.420 etc
do you have any idea what can I modify in the code to move him the fixed amount of distance?
maybe it’s something to do with the sensitivity of the touch or the update function?
I did Debuging to check how the player move in real time and to my surprise he is moving the amount needed all the way till the end of the distance but only in CODE. because in the EDITOR in the transform values I can see the X position is a Float…
Can I ask if what you want is to be able to move +/- 2 based on where you tap the screen?
If that’s the case, I think you can move all of your code to be within Update() and ignore fixed update (this part is semi unrelated, just an observation).
Adjust your ‘target’ by +/- 2 … set your velocity, and then clamp your position (so it doesn’t go off screen, as you’re already doing). And an additional clamp for the target position - I think that would work.
This assumes you want to use the physics system for collisions somehow/somewhere else, otherwise you could just as easily move the transform instead.
yes, that is what i want to achive. if you tap on left half of the screen, player move -2, if tap on the right half player move +2. the idea of clamp the target is sounds good. but i even cant think of how to actually implement that on real time in update… I have tried another way of code which make the player move exactly as I want but there is no tilt working. more than that, i’m able to rotate only to the right side and the rotation if full 360’ instead of 7’ i wish to each side. so if to solve the tilt issue, my player will be able to do what i tried…
Was the tilt working in your earlier example? If so, just keep it like that and try the suggestion that I made?
Also, quick question… can you only be in 1 of 3 positions? -2 , 0 , and +2? It seems that’s all you calculate, so just curious if you could be at -4 or -10 or -12 or 24 or anything else lol
As for clamping to the position, if you adjust the target with each tap, you could “clamp” … maybe for example:
if target = -4 then if position.x <= target , then position.x = target;
if target is positive, then you’d check if position.x >= target
Maybe I shouldn’t have used the word clamp, to avoid confusion.
If you’re always moving with velocity, and you were using such a setup, it might look like:
target = 4;
rb.velocity = (whatever speed);
if(transform.position.x >= target) {
transform.position = new Vector3(target, transform.posiition.y, transform.position.z);
rb.velocity = Vector3.zero; // stop the movement if you're at the target.. until a new touch/tap is made.
}
Those are just some ideas. If you move in other directions, as well, you’d have to alter the rb.velocity where I set it to zero – you may want to merely zero out the ‘x’ portion, instead.
sorry for confuse you… what i want to do is, move the player one step only on tap only and keep the tilt look the same. if I want to do this, for my grid, each step must be 2 units and up to 4 for each side (-4, 4) because of the 5 ways there…
one code i tried saved the tilt mechanics but didn’t move a fixed amount,
the other code i try is moving a fixed amount but no tilt LOL
ok so I have tried to clamp the transform and it is moving in a fixed distance and the rotation is working, but unfortunately the transform just jump from place to place and you can’t see any smooth movement. maybe because the clamp code cancel in realtime the Mathf.MoveTowards
in the Update when touch began i catch the last position.x of the rigidbody and then clamp it in the fixed update under the boundary restrict:
//restrict movement to boundaries
if (transform.position.x <= xMin) {
transform.position = new Vector3 (xMin, transform.position.y, transform.position.z);
}
if (transform.position.x >= xMax) {
transform.position = new Vector3 (xMax, transform.position.y, transform.position.z);
}
if (transform.position.x <= cathLastPosition + target) {
transform.position = new Vector3 (cathLastPosition + target, transform.position.y, transform.position.z);
}
if (transform.position.x >= cathLastPosition + target) {
transform.position = new Vector3 (cathLastPosition + target, transform.position.y, transform.position.z);
}
The only “gotcha” is that trying to stop on an exact spot using velocity alone is basically impossible, so it’s much easier to just use Rigidbody.MovePosition() instead.
Anyways, here’s the code I’ve come up with:
// new variables (set them at the top with your others)
private Vector3 targetPosition;
private Quaternion targetRotation;
private int lane = 0;
private void Awake()
{
// set these in your Awake():
targetPosition = transform.position;
targetRotation = Quaternion.identity;
}
private void Update()
{
if (Input.touchCount > 0)
{
if (Input.GetTouch(0).phase == TouchPhase.Began)
{
touchPosition = Input.GetTouch(0).position;
if (touchPosition.x > screenCentre)
lane += 1;
if (touchPosition.x < screenCentre)
lane -= 1;
lane = Mathf.Clamp(lane, -2, 2); // change to how many lanes you have
}
}
float laneWidth = 2f; // change from 2 if you need to
float laneTarget = lane * laneWidth;
targetPosition.x = Mathf.MoveTowards(targetPosition.x, laneTarget, speedHorizontal * Time.deltaTime);
targetPosition.z += speedForward * Time.deltaTime;
float tilt = laneTarget - targetPosition.x;
targetRotation = Quaternion.RotateTowards(targetRotation, Quaternion.Euler(0f, 0f, -tilt * 25f), 90f * Time.deltaTime);
}
private void FixedUpdate()
{
rigidbody.MovePosition(targetPosition);
rigidbody.MoveRotation(targetRotation);
}
And it should work like this:
Let me know if that’s not what you’re looking for.
Move position is a valid option, too. However, I think it’s a stretch to say I moved him wildly astray.
When you’re checking if you >= target or <= target you have to account for direction you’re going. I mentioned that. With fresh eyes, after some sleep, I could have also suggested that there are 5 values you store and you can cycle between with to set a moveTowards target.
In any event, hopefully with your help and/or mine, he is close to his solution working
Sorry methos5k, I didn’t mean that in an accusatory or defaming way. My apologies if that’s how it came across. I just meant that the OP was close to a solution and then you blew his mind with a different approach. I’ve edited my original post as clearly my tone was lost in text.
No worries, I appreciate you saying so. All is well, I was just hoping to get him to a working solution. Perhaps I didn’t take a prior solution well enough into account when posting.
I’ll wait and see what he writes back with to see what’s working