Here is my code for moving a 2D top-down object using the built in virtual joystick:
void Update ()
{
Vector2 moveVec = new Vector2(CrossPlatformInputManager.GetAxis("Horizontal"),
CrossPlatformInputManager.GetAxis("Vertical"));
Vector3 lookVec = new Vector3(CrossPlatformInputManager.GetAxis("Horizontal"),
CrossPlatformInputManager.GetAxis("Vertical"), 4000);
transform.rotation = Quaternion.LookRotation(lookVec, Vector3.back);
transform.Translate(moveVec * Time.deltaTime * speed);
}
Without the rotation code, the movement was perfect, after adding the rotation code the movement got all messed up, if the direction is down, it moves up.
But the rotation is exactly how it should.
Simply change the transform.Translate(moveVec * Time.deltaTime * speed); line to transform.Translate(moveVec * Time.deltaTime * speed, Space.World); : by default, the translation is made relatively to the transform own space (Space.Self).
Related
I have been experimenting with trying to recreate a 3rd person character controller from a Brackeys tutorial, but using the new input system and rigid body physics.
The rotation works properly, but moving forward or back moves me forward compared to the camera, and moving left or right moves me backward.
The desired effect is changing the input should change my rotation to match the input direction relative to the camera and then move in the direction the player model is facing
Here is where I'm at:
private Vector3 GetMoveInput()
{
return new Vector3(_input.MoveInput.x, 0f, _input.MoveInput.y); //convert input Vector2 into a Vector3
}
private void PlayerMove()
{
if (_playerMoveInput.magnitude > 0.01f){ //only update rotation if player is moving
float targetAngle = Mathf.Atan2(_playerMoveInput.x, _playerMoveInput.z) * Mathf.Rad2Deg + _mainCamera.eulerAngles.y;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref turnSmoothVelocity, turnSmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
//down here is where the problem lies I believe
_playerMoveInput = new Vector3(_playerMoveInput.x * _movementMultiplier * _rigidBody.mass,
_playerMoveInput.y,
_playerMoveInput.z * _movementMultiplier * _rigidBody.mass);
_rigidBody.AddRelativeForce(_playerMoveInput, ForceMode.Force);
}
}
I have tried setting y and z to 0f, multiplying by transform.forward, setting _playerMoveInput to transform.forward, and Quaternion.Euler(0f, angle, 0f) * transform.forward but no positive results.
I am trying to replicate the editor's camera for runtime use, and all is working as expected, but I am trying to Ease the movement and can't get it working right. Here is my code for the movement. It works correctly but isn't Eased out like I want.
Vector3 move = Vector3.zero;
if (Input.GetKey(KeyCode.W))
move += Vector3.forward * currentSpeed;
if (Input.GetKey(KeyCode.S))
move -= Vector3.forward * currentSpeed;
if (Input.GetKey(KeyCode.D))
move += Vector3.right * currentSpeed;
if (Input.GetKey(KeyCode.A))
move -= Vector3.right * currentSpeed;
if (Input.GetKey(KeyCode.E))
move += Vector3.up * currentSpeed;
if (Input.GetKey(KeyCode.Q))
move -= Vector3.up * currentSpeed;
transform.Translate(move);
I have tried a destination Vector3, setting that to move, then lerping the position to destination. This does Ease it as expected, but then the directions are all broken. Left moves forward, right moves back, and so on.
I have tried moving to fixedUpdate but still no luck.
Any help would be greatly appreciated!
Try to use CharacterController. It is component from Unity. It is easy to use and smooth.
public CharacterController controler;
public void Start(){
controller = GetComponent<CharacterController>();}
public void Move(){
controller.Move(moveDirection * Time.deltaTime);}
On youtube you can find tutorials from CharacterController.
After much experimentation, easing/smoothing can be achieved by doing the following in an update loop:
float x, y, z;
x = Input.GetAxis("Horizontal") * currentSpeed * Time.deltaTime;
z = Input.GetAxis("Vertical") * currentSpeed * Time.deltaTime;
y = 0;
transform.Translate(x,y,z);
I've been trying for some time now with different tutorials to get a nice firstperson (cockpit view) spaceship controll system. I tried using mouse only, keyboard only and combinations but I keep encountering the same problem with all tutorials. even this simple line of code does it:
transform.position += transform.forward * Time.deltaTime * 90f;
transform.Rotate( Input.GetAxis("Vertical"), Input.GetAxis("Horizontal"), 0.0f);
The problem I keep getting is that if I pitch its ok. it I yaw its ok. But If I do both (so I go diagonaly) it also rotates my ship on the Z axis and messes up my orientation. I tried locking the z rotation in the rigidbody but that does'nt help either. I tried making code myself alternating with apply torque and simply rotating, followed some tutorials including this one: Tutorial but keep getting the rotation problem.
What I want to make is a game that controlls like the old game Helbender
Does anyone of you know of a way that I can get spaceship controlls to work?
----EDIT-----
Got a bit further now. It doenst turn on my z axis anymore becouse I keep setting it to 0. Only problem now is that if I try to make a looping the ship flips around instead of nicely looping.
if (Input.GetKey("up"))
{
transform.Rotate(transform.right * -ShipPanSpeed * Time.deltaTime, Space.World);
}
if (Input.GetKey("down"))
{
transform.Rotate(transform.right * ShipPanSpeed * Time.deltaTime, Space.World);
}
if (Input.GetKey("left"))
{
transform.Rotate(transform.up * -ShipPanSpeed * Time.deltaTime,Space.World);
}
if (Input.GetKey("right"))
{
transform.Rotate(transform.up * ShipPanSpeed * Time.deltaTime,Space.World);
}
float z = transform.eulerAngles.z;
transform.Rotate(0, 0, -z);
You could always try to make one parent object for the Controls and then a child object (the spaceshit) that you can rotate for the pivot but not attach any movement beside rotation.
What i mean is that you can rotate the parent on the Y axis to make it rotate and move the transform forward or backward at the same time. If you want to pivot up or down you can transform forward at the sametime you transform up/down multiplied with the axis you want to pivot with
Example:
private void Update(){
//PARENT--------------------------------------------
// MOVING FORWARD AND BACKWARD
transform.position += transform.forward * Input.GetAxis("Vertical") * speed * Time.deltaTime();
// MOVING RIGHT AND LEFT
transform.position += transform.right * Input.GetAxis("Horizontal") * speed * Time.deltaTime();
//PIVOT UP AND DOWN
transform.position += transform.up * -Input.GetAxis("Mouse Y") * speed * Time.deltaTime();
//ROTATE AROUND THE Y AXIS
tranform.Rotate(0f, Input.GetAxis("Horizontal") * rotationspeed, 0f);
}
For the spaceship (child) for the pivot i would recommend you to make a emptyobject and set the chip to lookAt that object based on the input axis you use to move up/down and forward/backward.
Hope this helped or at least gave you a idea of how to make it :)
I am trying to do client side prediction a rotation. I was thinking this would work is similar to how I did the position. But I can't seem to find a way to rotate my Quaternion.
// These are synced over the network
private Vector3 bestGuessPosition;
private Vector3 velocity;
private Quaternion bestGuessRotation;
private Vector3 angularVelocity;
// Postion
bestGuessPosition = bestGuessPosition + (velocity * Time.deltaTime);
transform.position = Vector3.Lerp(transform.position, bestGuessPosition, Time.deltaTime * latencySmoothingFactor);
// Rotation (not working)
bestGuessRotation = bestGuessRotation + (angularVelocity * Time.deltaTime);
transform.rotation = Quaternion.Lerp(transform.rotation, bestGuessRotation, Time.deltaTime * latencySmoothingFactor);
How do I rotate my bestGuessRotation? There doesn't seem to be a .Rotate like there is on a Transform.
In Unity two Quaternions are combined using "multiplaction" * (order matters!)
You can convert your Vector3 rotation angularVelocity from Euler space to a Quaternion using Quaternion.Euler
bestGuessRotation *= Quaternion.Euler(angularVelocity * Time.deltaTime);
Btw also the position can easier be written as
bestGuessPosition += velocity * Time.deltaTime;
Just guessing you are using this in Update using Lerp might not be the best option here depending what exactly you expect from this rotation.
If using Lerp in Update for example as a simple smoothing algorithm you should remove the Time.deltaTime as the interpolation factor is a percentage value and in this case should stay the same.
i have start a project in unity 3d.I want to make a spaceship that moving forward,but when i pressed the ArrowUp then i want to change its y postion to
( currentpos+ 1.5 ) but i want this smoothly.
this is my code
transform.position += transform.forward * Time.deltaTime * 10f;
if (Input.GetKey (KeyCode.UpArrow))
transform.position = new Vector3 (transform.position.x, 5f,
transform.position.z);
through the above code the Y position of object can b changed but it work so fast and i want to make it smooth.
so please help me.
I think the best solution to your problem is to use Mathf.SmoothDamp.
Example:
private float targetY = 0f;
private float verticalVelocity = 0f;
private const float smoothTime = 1f;
private void Update()
{
transform.position += transform.forward * Time.deltaTime * 10f;
if (Input.GetKey(KeyCode.UpArrow))
{
targetY = 5f;
}
float y = Mathf.SmoothDamp(transform.position.y, targetY, ref verticalVelocity, smoothTime);
transform.position = new Vector3 (transform.position.x, y, transform.position.z);
}
This example will smoothly change the y coordinate to 5 over the course of 1 second (you can change the smoothTime constant for a different time).
Based in your own code the easiest way for you to work it out could be something like this
//this sets the X position
transform.position += transform.forward * Time.deltaTime * 10f;
//if the button is pressed then modify Y
if (Input.GetKey (KeyCode.UpArrow))
transform.position += new Vector3 (0, 5f * Time.deltaTime * y_speed,0);
y_speed could be a public float y_speed = 1.0f in your script so you could modify it from the inspector to get the effect you want to achieve.
Hope it helps!
Assuming your spaceship is a rigidbody, you should take a look at Rigidbody.AddForce
https://docs.unity3d.com/ScriptReference/Rigidbody.AddForce.html
By working with forces, you can get a smooth movement in all directions very easily, and tweak it within the Rigidbody's parameters (like mass) without fiddling in the script again. It's part of the Unity physics model.
If you only want to move in y-direction, input a vector like (0,1,0) but you can also input the Transform.forward vector of your spaceship's Gameobject. That way, it will always move the direction it is facing in.