- Home /
Proper movement code for calculating leading shoots
Hello Unity community.
First of all, you will probably wonder what I exactly mean with that title. I wanted to make leading shoots to fire to mobile targets so that they will hit the target even though the target was in movement, so I found this page: http://wiki.unity3d.com/index.php/Calculating_Lead_For_Projectiles and copied these code, assuming it would work.
Then, when I tested my project, I noticed it wasn't working, the shoots where facing the target's current position. Later I noticed that Unity was assuming that the target velocity was 0, to be precise (0.0, 0.0, 0.0), the same as if the target was standing still.
At this point, I assumed that I had done my player movement wrong, so I need to know a movement code that Unity could recognise as a proper movement so that my leading shoots will work and the target.GetComponent().velocity would be greather than 0.
Here is my code:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class PlayerController : MonoBehaviour {
public float speed;
public float rotationSpeed;
void FixedUpdate ()
{ // Rotates right and left
transform.Rotate(0, -Input.GetAxis("Horizontal")*rotationSpeed*Time.deltaTime, 0,Space.World);
if (Input.GetKey("up")||Input.GetKey("w")){ // Goes forward
transform.Translate(0,0,Time.deltaTime*speed,Space.Self);
}
if(Input.GetKey ("down")||Input.GetKey("s")){ // Goes backward
transform.Translate(0,0,-Time.deltaTime*speed,Space.Self);
}
if (Input.GetKey ("e")){ // Goes right
transform.Translate(Time.deltaTime*speed,0, 0, Space.Self);
}
if (Input.GetKey ("q")){ // Goes left
transform.Translate(-Time.deltaTime*speed,0, 0, Space.Self);
}
}
}
I need to know if this code is right or, instead, a proper code that Unity could recognise as a movement (I tested the speed by writing "print(target.GetComponent().velocity)". Could you tell me if this is right?
Answer by Youri1er · Aug 20, 2015 at 01:13 PM
Hi,
Your problem is simple to resolve. Don't use transform translate ! First put a rigdbody on your player. Second use GetComponent().velocity = new vector3(.......);
You don't need to use Time.deltatime because velocity is update by unity with a Time.deltatime.
Say me if you don't arrive, i'll give you some code. But it's better to arrive alone to progress.
Thank you for answering Youri1er.
I have tried GetComponent().velocity but Unity tells me there is a compiler error, I tried GetComponent().velocity and it worked.
The velocity and the shoots are working perfectly, but without translate I can't move away of the X and Z axis, so even if I rotate the player, when I go forward it faces the Z axis.
Here is my code:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class PlayerController : $$anonymous$$onoBehaviour {
public float speed;
public float rotationSpeed;
void FixedUpdate ()
{
// Rotates right and left
transform.Rotate(0, -Input.GetAxis("Horizontal")*rotationSpeed*Time.deltaTime, 0,Space.World);
// Forward and backward
if (Input.Get$$anonymous$$ey ("w")){
GetComponent<Rigidbody>().velocity = new Vector3 (0.0f, 0.0f, speed);
}
if (Input.Get$$anonymous$$ey ("s")){
GetComponent<Rigidbody>().velocity = new Vector3 (0.0f, 0.0f, -speed);
}
// Goes right and left
if (Input.Get$$anonymous$$ey ("e")){
GetComponent<Rigidbody>().velocity = new Vector3 (speed, 0.0f, 0.0f);
}
if (Input.Get$$anonymous$$ey ("q")){
GetComponent<Rigidbody>().velocity = new Vector3 (-speed, 0.0f, 0.0f);
}
}
How could I move my player properly?
You can add two key, first to go up and second to go down. In General, video games use your move with one touch to jump
if(Input.Get$$anonymous$$ey("Space")) GetComponent().velocity = new Vector3 (speed, speed,0.0f);
But you can improve your code because if you press more than one touch your character block !
So you must do this :
Vector3 temp_$$anonymous$$ove_Direction;
if (Input.Get$$anonymous$$ey ("w")) temp_$$anonymous$$ove_Direction.z = 1;
if (Input.Get$$anonymous$$ey ("s")) temp_$$anonymous$$ove_Direction.z = -1;
// Goes right and left if (Input.Get$$anonymous$$ey ("e")) temp_$$anonymous$$ove_Direction.x = 1;
if (Input.Get$$anonymous$$ey ("q")) temp_$$anonymous$$ove_Direction.x = -1;
if (Input.Get$$anonymous$$ey ("Space")) temp_$$anonymous$$ove_Direction.y = 1;
if (Input.Get$$anonymous$$ey ("Shift")) temp_$$anonymous$$ove_Direction.y = -1;
temp_$$anonymous$$ove_Direction.Normalize ();
GetComponent().velocity = temp_$$anonymous$$ove_Direction * speed;
Thank you again Youri1er.
Your idea is amazing, I have learnt a lot thanks to you in just two days. I don't want to disturb you again, but I have another question: When I go up, down, jump... The object keeps moving to that direction, so if I go forward, it keeps going forward, if I jump, it starts going up and don't stop. And I can't move away from the X and Z axis, just as before. Should I do something that, for instance, when 0.2 seconds go on make the player's velocity return to 0 or something like that?
Yes that's an idea but i prefer to verify if there is no key pressed so i put velocity at Vector3.zero.
How objects should move is a big design decision. You should NOT change from translate to rigidbodies just because it might make one little thing easier.
Speed of a translated object can be calculated based on the movement variables. In this case, it's speed
times the direction for whatever key.
Now, if reading all the comments makes you realize that rigidbodies are better for your game, that's great. Or if you're learning Unity and just want to try some stuff (which I think is the case.) But for real, there's almost always a better way than a giant redo.