Between two points or only to the left nonestop or only to the right nonestop.
In this code i spin the cylinder but i can't move it to the sides:
using UnityEngine;
using System.Collections;
public class MakeTwoPoints3D : MonoBehaviour
{
public float speed = 10f;
public float delta = 15.5f; // Amount to move left and right from the start point
public float moveSpeed = 5.0f;
private Vector3 startPos;
void Start()
{
startPos = transform.position;
}
void Update()
{
transform.Rotate(Vector3.up, speed * Time.deltaTime);
transform.position += transform.right * Time.deltaTime * moveSpeed;
}
}
If i make transform.right it will move the cylinder in circle on place up and down in circle. If i make transform.up it will move it to me i mean like forward but to the camera but at least it will move it. And if i make transform.Forward again it will make circles and will remove the cylinder in circles up down.
I can't figure out how to move it to the sides.
You need use Vector3.right instead of transform.right.
void Update()
{
transform.Rotate(Vector3.up, speed * Time.deltaTime);
transform.position += Vector3.right * Time.deltaTime * moveSpeed;
}
When you use transform.right, the Vector3 will adopt the local rotations of that object's transform. Meaning, if the object was rotated 45 degrees around the Y axis, your transform.right vector would be on an angle. If you keep translating an object along it's local axis while you rotate it, it will travel in a circle.
On the other hand, Vector3.right is always in world space so it will always face "true" right.
Related
I'm making a sphere move over a plane object. I'm trying to make the movement similar to the movement of a wheel, but I don't want to use the Wheel Collider component. I am using torque to move the sphere back and forth and I am using the rigidbody rotation (Because I read that it is not a good practice to perform these transformations directly on the geometry), but the rotation (steering) part is not working, the sphere continues to follow in same direction even rotating. Here's code below:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SphereMovement : MonoBehaviour
{
float maxTorque = 30.0f;
float maxSteerAngle = 30.0f;
void Start()
{
}
void FixedUpdate()
{
var deltaRotation = GetComponent<Rigidbody>().rotation * Quaternion.Euler(new Vector3(maxSteerAngle * Input.GetAxis("Horizontal") * Time.deltaTime, 0, 0));
GetComponent<Rigidbody>().rotation = deltaRotation;
GetComponent<Rigidbody>().AddTorque(new Vector3(maxTorque * Input.GetAxis("Vertical") * Time.deltaTime, 0, 0));
}
}
Can someone help me?
Cache your GetComponent calls to improve performance (see below)
You are applying torque into global x direction, you probably want to move "forward" (depending on the rotation of the wheel). transform.forward is your friend
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SphereMovement : MonoBehaviour
{
float maxTorque = 30.0f;
float maxSteerAngle = 30.0f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
var deltaRotation = rb .rotation * Quaternion.Euler(new Vector3(maxSteerAngle * Input.GetAxis("Horizontal") * Time.deltaTime, 0, 0));
GetComponent<Rigidbody>().rotation = deltaRotation;
GetComponent<Rigidbody>().AddTorque(transform.forward * (maxTorque * Input.GetAxis("Vertical") * Time.deltaTime);
}
}
If your setup is otherwise rotated, you can try transform.right or transform.up
edit:
when you rotate your wheel, the "forward" will spin as well, so you need to ignore the y. (assuming an almost flat surface for now, you mentioned a plane)
So you would think this works:
Vector3 direction = transform.forward;
direction.y = 0;
direction = direction.normalized;
GetComponent<Rigidbody>().AddTorque(direction * (maxTorque *
Input.GetAxis("Vertical") * Time.deltaTime);
But Then it would go back or forth, depending on the current rotation.
So that won't work.
Another Idea: You could add an empty parent and rotate that on the y axis to "steer" while the child is rotated to do the actual "forward movement" like a wheel rooling over concrete.
Option without parent:
You simply apply Torque in local space using Rigidbody.AddRelativeTorque
Like this (we use Vector3.forward, don't confuse it with transform.forward! Vector3.forward is simply Vector3(0, 0, 1). but in local space that's fine because the rotation is still considered)
void FixedUpdate()
{
var deltaRotation = rb .rotation * Quaternion.Euler(new Vector3(maxSteerAngle * Input.GetAxis("Horizontal") * Time.deltaTime, 0, 0));
GetComponent<Rigidbody>().rotation = deltaRotation;
GetComponent<Rigidbody>().AddRelativeTorque(Vector3.forward * (maxTorque * Input.GetAxis("Vertical") * Time.deltaTime);
}
The problem is here:
GetComponent<Rigidbody>().AddTorque(new Vector3(maxTorque * Input.GetAxis("Vertical") * Time.deltaTime, 0, 0));
Your torque is always being applied along the global X axis, so it doesn't matter which way the sphere object is rotated. Think of it like this -- no matter which way you rotate a soccer ball, if you spin it in a northwards direction, it will roll north. For your approach to work, you need to take your torque force and apply it along the vector you want to move, rather than always the global X axis.
here is my quite simple code, basically rotating around a target on the x and y. but if i press both at the same time, it rotates on the z, flipping the camera. is there a way that i can lock the z axis?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Camera_Logic : MonoBehaviour
{
public float rotateSpeed;
public Transform rotateTarget;
void Start()
{
}
void Update()
{
float rotateAxisX = Input.GetAxisRaw("Horizontal");
float rotateAxisY = Input.GetAxisRaw("Vertical");
transform.RotateAround(rotateTarget.transform.position, Vector3.up * -rotateAxisX, rotateSpeed * Time.deltaTime);
transform.RotateAround(rotateTarget.transform.position, Vector3.right * rotateAxisY, rotateSpeed * Time.deltaTime);
}
}
If you are rotating respect to the world axis, with Vector3.up and Vector3.right, you cannot lock local axis z. Its orientation moves inherently in the respect to world axis rotation.
I think that what you might need is to rotate respect the local axis of the object.
Instead of world axis Vector3.up and Vector3.right use the local object up and right respectively as follows:
void Update()
{
float rotateAxisX = Input.GetAxisRaw("Horizontal");
float rotateAxisY = Input.GetAxisRaw("Vertical");
transform.RotateAround(rotateTarget.transform.position, rotateTarget.up * -rotateAxisX, rotateSpeed * Time.deltaTime);
transform.RotateAround(rotateTarget.transform.position, rotateTarget.right * rotateAxisY, rotateSpeed * Time.deltaTime);
}
This way you will rever rotate respect object's z axis. However z orientation will be changing also as the orientation respect one axis, involves the orientation change of the other two.
Now I'm a beginner game developer and I'm working on a game so I have set the camera motion that when you move the mouse the player rotates however I want to make the WASD keys work to the direction the player is rotated. Basically when I rotate the camera to the left the W key still moves the player on the Z dimension. How can I fix this?
Here's my player rotation code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraMovement : MonoBehaviour
{
public float speedH = 2.0f;
public float speedV = 2.0f;
private float yaw = 0.0f;
private float pitch = 0.0f;
// Use this for initialization
void Start()
{
}
// Update is called once per frame
void Update()
{
yaw += speedH * Input.GetAxis("Mouse X");
pitch -= speedV * Input.GetAxis("Mouse Y");
transform.eulerAngles = new Vector3(pitch, yaw, 0.0f);
}
}
Moving in the direction the character is facing is a simple work for Transform.forward and Transform.right because you need to move the player based on local position and rotation and not the world one.
For example, you could have
void Move (float h, float v)
{
movement.Set (h, 0f, v);
movement = movement.normalized * speed * Time.deltaTime;
playerRigidbody.MovePosition (transform.position + (transform.forward * movement.z) + (transform.right * movement.x));
}
The Rigidbody is what you need to move it, if you want an object that is always moving in the direction is facing you could easily do a
transform.position += transform.forward * Time.deltaTime * movementSpeed;
In this case, to go back you should subtract instead of add.
But use my first suggestion for your player :D
EDIT
In your update you can add
Move(yaw, pitch);
I need to make the object move around the scene and jump, but every time the object rotates it changes the axis of motion. How can I ensure that the rotation of the object does not influence its movement?
public float forca = 300f;
public Rigidbody2D Bola;
public float movdir = 5f;
public float moveesq = -5f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
Bola.AddForce(new Vector2(0, forca * Time.deltaTime), ForceMode2D.Impulse);
}
if (Input.GetKey(KeyCode.RightArrow))
{
Bola.transform.Translate(new Vector2(movdir * Time.deltaTime, 0));
}
if (Input.GetKey(KeyCode.LeftArrow))
{
Bola.transform.Translate(new Vector2(moveesq * Time.deltaTime, 0));
}
transform.Translate takes an optional parameter relativeTo with a default value Space.Self → movement in local X-axis
If relativeTo is left out or set to Space.Self the movement is applied relative to the transform's local axes. (the x, y and z axes shown when selecting the object inside the Scene View.) If relativeTo is Space.World the movement is applied relative to the world coordinate system.
You can convert this into the global X-axis (independent from the objects orientation) by simply passing Space.World as last parameter:
if (Input.GetKey(KeyCode.RightArrow))
{
Bola.transform.Translate(new Vector2(movdir * Time.deltaTime, 0), Space.World);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
Bola.transform.Translate(new Vector2(moveesq * Time.deltaTime, 0), Space.World);
}
AddForce however takes world space coordinates anyway so there you already are independent of the objects orientation.
However, since there is a rigidbody involved you should not set the position using the Transform component at all. You should rather go through Rigidbody2D.MovePosition
if (Input.GetKey(KeyCode.RightArrow))
{
Bola.MovePosition(Bola.position + Vector2.right * movdir * Time.deltaTime);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
Bola.MovePosition(Bola.position + Vector2.right * moveesq * Time.deltaTime);
}
Yoi should this then rather also in FixedUpdate
Multiply by transform.forward
Currently your movement vectors are in absolute coordinates. You want them in local coordinates. The easiest way to do this is to multiple by transform.forward (for forward motion) and transform.right (for strafing motion).
I want to rotate camera around an fbx object when a key is being pressed using unity 3d.How it do? I tried some examples but its not working. First i create a game object and add main camera child of it.
public class CameraOrbit : MonoBehaviour
{
public Transform target;
public float speed = 1f;
private float distance;
private float currentAngle = 0;
void Start()
{
distance = (new Vector3(transform.position.x, 0, transform.position.z)).magnitude;
}
void Update()
{
currentAngle += Input.GetAxis("Horizontal") * speed * Time.deltaTime;
Quaternion q = Quaternion.Euler(0, currentAngle, 0);
Vector3 direction = q * Vector3.forward;
transform.position = target.position - direction * distance + new Vector3(0, transform.position.y, 0);
transform.LookAt(target.position);
}
}
I dont have access to unity at the moment so i might have messed something up.
The idea is keep an angle that you change based on input. Create a Quaternion from the angle (the Quaternion say how to rotate a vector to a certain direction), then rotate a Vector to that direction. Starting from the targets position move in that direction a certain distance and then look at the targets position.
This only implements rotation around the y axis, if you want rotation around the x axis all you need is another angle variable and then change to this Quaternion.Euler(currentAngleX, currentAngleY, 0);