im making a gravity thing so when you right click it should make the character and camera rotate but im not really sure how to make the camera rotate. this is the code i have for the gravity.
if (Input.GetMouseButtonDown(1) && grounded)
{
Physics.gravity = new Vector3(0, 10.0f, 0);
}
if (Input.GetMouseButtonDown(0) && grounded)
{
Physics.gravity = new Vector3(0, -10.0f, 0);
}
public Transform cam;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(1) && grounded)
{
Physics.gravity = new Vector3(0, 10.0f, 0);
cam.rotation = Quaternion.Euler(0f, 0f, 180f);
}
if (Input.GetMouseButtonDown(0) && grounded)
{
Physics.gravity = new Vector3(0, -10.0f, 0);
cam.rotation = Quaternion.Euler(0f, 0f, 0f);
}
}
Related
I have such a problem, maybe someone will help. I am making a game and I need to make a dice that goes in the direction opposite to the click. For example, clicking on the back of a cube moves it forward, etc. Gravity must act on the cube as shown in the figure below. Unfortunately, the cube does not change height, but only the position of X and Z. Please help.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveCube : MonoBehaviour
{
Vector3 movePosition;
public float time = 0.02f;
[HideInInspector]
public bool blockClick = false;
private void Start()
{
movePosition = transform.position;
}
private void Update()
{
blockClick = false;
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit raycastHit;
if (Physics.Raycast(ray, out raycastHit))
{
string hitName = raycastHit.transform.name;
if (hitName == "MoveCube")
{
move(raycastHit);
blockClick = true;
}
}
}
transform.position = Vector3.Lerp(
transform.position,
movePosition,
time);
}
public void move(RaycastHit raycastHit)
{
Vector3 incomingVec = raycastHit.normal - Vector3.up;
// South
if (incomingVec == new Vector3(0, -1, -1))
{
movePosition = movePosition + new Vector3(0, 0, 1);
return;
}
// North
if (incomingVec == new Vector3(0, -1, 1))
{
movePosition = movePosition + new Vector3(0, 0, -1);
return;
}
// West
if (incomingVec == new Vector3(-1, -1, 0))
{
movePosition = movePosition + new Vector3(1, 0, 0);
return;
}
// East
if (incomingVec == new Vector3(1, -1, 0))
{
movePosition = movePosition + new Vector3(-1, 0, 0);
return;
}
}
}
From what I know, changing the transform.position of a gameObject with a rigidbody will mess with Unity's physics, and it won't work as intended. I suggest trying to apply a force from the position of the mouse's click instead of moving the cube's position manually (if this makes sense to do for your purposes). Here is the documentation for Rigidbody.AddForce
I want to code the car's rotation system as I move left and right. I use the following code for this.
float steer = Input.GetAxis("Horizontal");
float finalangel = steer * 45f;
wheelcoll[0].steerAngle = finalangel;
But I want to set it for the phone. When the user touches the screen of the phone and keeps his hand on the screen of the phone, the car goes to the left and stays. When the user removes his hand from the phone, the car returns to its original position. But when doing this process, I want the car to turn in the right direction.
How can I do this?
I tried this too:
[SerializeField] Rigidbody rb;
public Vector3 targetpostion;
public int Speed;
public bool FirstLaneBlueCar;
public bool BlueCar;
public Vector2 Xpos;
public float rotatlerptime;
bool rottrue;
void Start()
{
rottrue = false;
BlueCar = false;
}
void Update()
{
if (Input.GetMouseButtonDown(0))
{
BlueCar = true;
rottrue = true;
LeftButtonPressed();
}else if (Input.GetMouseButtonUp(0))
{
BlueCar = true;
rottrue = true;
LeftButtonPressed();
}
if (!rottrue)
{
if (transform.position.x <= 4f)
{
Debug.Log(">-.5");
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime);
}
if (transform.position.x >= 3f)
{
Debug.Log(">.5f");
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 0, 0), rotatlerptime * Time.deltaTime);
}
}
}
private void FixedUpdate()
{
transform.Translate(targetpostion, Space.World);
if (BlueCar)
{
if (FirstLaneBlueCar)
{
if (rottrue)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, -60f, 0), rotatlerptime * Time.deltaTime);
Invoke("rot2", .1f);
}
Invoke("left", .1f);
}
else
{
if (rottrue)
{
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(0, 60f, 0), rotatlerptime * Time.deltaTime);
Invoke("rot2", .1f);
}
Invoke("right", .1f);
}
}
}
public void rot2()
{
rottrue = false;
}
void left()
{
transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.y, transform.position.y, transform.position.z), .08f);
}
void right()
{
transform.position = Vector3.Lerp(transform.position, new Vector3(-Xpos.x, transform.position.y, transform.position.z), .08f);
}
public void LeftButtonPressed()
{
if (FirstLaneBlueCar)
{
FirstLaneBlueCar = false;
}
else
{
FirstLaneBlueCar = true;
}
}
You can track the first touch position, and make the respective calculations in the Update method, comparing the previous touch position with the current one.
private void Update()
{
if (Input.touches.Length < 1)
return;
var touch = Input.touches[0];
var deltaPosition = touch.deltaPosition;
// Move the car according to the shift in touch position
}
You can also save the touch ID when the touch has just begun, so you can track the same touch later (user can have multiple fingers on the screen).
Use Touch.fingerId for that.
I have a 2d platformer and there are these enemies with a patrol system as so:
public TextMeshProUGUI m_Object;
public SpriteRenderer sp;
public Transform groundCheck;
bool isFacingRight = true;
RaycastHit2D hit;
private void Update()
{
hit = Physics2D.Raycast(groundCheck.position, -transform.up, 1f, groundLayers);
}
private void FixedUpdate()
{
if(hit.collider != false)
{
if (isFacingRight)
{
rb.velocity = new Vector2(speed, rb.velocity.y);
}
else
{
rb.velocity = new Vector2(-speed, rb.velocity.y);
}
}
else
{
isFacingRight = !isFacingRight;
sp.transform.localScale = new Vector3(-transform.localScale.x, 1f, 1f);
Debug.Log(transform.localScale.x);
float placeholder = sp.transform.localScale.x;
m_Object.transform.localScale = new Vector3(placeholder, 1f, 1f);
Debug.Log(m_Object.transform.localScale.x);
}
}
In the end part I am trying to flip the text so it stays facing the logical way however it is not working since when it hits the edge the text disappears and when it its the other edge the text comes back.
Any Ideas would be appreciated.
public Rigidbody rb;
public bool cubeIsOnTheGround = true;
public float speed = 10;
Vector3 direction;
// Start is called before the first frame update
void Start()
{
rb.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
Vector3 input = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical"));
direction = input.normalized;
if (Input.GetButtonDown("Jump"))
{
rb.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
}
if (cubeIsOnTheGround == true)
{
if (Input.GetButtonDown("Jump"))
{
rb.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
cubeIsOnTheGround = false;
}
}
}
void FixedUpdate()
{
rb.position += direction * speed * Time.deltaTime;
}
void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Ground"))
{
cubeIsOnTheGround = true;
}
}
The if statemnt boolIsOnTheGround is not working. What I'm trying to do is check whether the cube is on the ground so I kno when you can jump. The cube just bounces infinitely by pressing space.
In your code you have two if-blocks where you jump:
if (Input.GetButtonDown("Jump"))
{
rb.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
}
if (cubeIsOnTheGround == true)
{
if (Input.GetButtonDown("Jump"))
{
rb.AddForce(new Vector3(0, 5, 0), ForceMode.Impulse);
cubeIsOnTheGround = false;
}
}
The first if-block does not check cubeIsOnTheGround, so it will jump as long as the jump button is pressed. If you remove the first block this behavior should stop.
After holding down on a combination keys of AS,SD,DW or WA to move my object, it will successfully move diagonally and rotate to the correct position, but after releasing the keys, it will rotate back to either 0,90,180 or 360 depending on the nearest rotation after releasing my keys, I guess it's because of that 1 frame that I left the keys touched, so it ran that code and moved it to 0,90,180,360. But I don't know how to solve it.
I hope I've provided enough information, and thanks for helping out.
I'm pressing onto AW keys together
After releasing the keys, it doesn't stay that way but moves to either left or top
PlayerMovement.cs
using UnityEngine;
using System.Collections;
public class playerMovement : MonoBehaviour {
private float speedWalk = 7.5f;
private float speedRotate = 7.5f;
private GameObject raycastObject;
// Update is called once per frame
void FixedUpdate ()
{
//Non-Diagonal Movements
if (Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.D)) //player movement up
{
transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.D)) //player movement down
{
transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S)) //player movement right
{
transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
}
if (Input.GetKey(KeyCode.A) && !Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.W) && !Input.GetKey(KeyCode.S)) //player movement left
{
transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
}
//Diagonal Movements **########** I think this is the problem.
if (Input.GetKey(KeyCode.A) && Input.GetKey(KeyCode.W)) //player movement Top Left
{
transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
}
if (Input.GetKey(KeyCode.W) && Input.GetKey(KeyCode.D)) //player movement Top Right
{
transform.localPosition += new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
}
if (Input.GetKey(KeyCode.D) && Input.GetKey(KeyCode.S)) //player movement Bottom Right
{
transform.localPosition += new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.A)) //player movement Bottom Left
{
transform.localPosition -= new Vector3(0.0f, 0.0f, speedWalk * Time.deltaTime);
transform.localPosition -= new Vector3(speedWalk * Time.deltaTime, 0.0f, 0.0f);
}
}
}
playerRotateMouse.cs
using UnityEngine;
using System.Collections;
public class playerRotateMouse : MonoBehaviour
{
public Transform Player;
private float speed = 7.5f;
Quaternion targetRotation;
void FixedUpdate()
{
Plane playerPlane = new Plane(Vector3.up, transform.position);
// Generates a ray from cursor
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
float hitdist = 0.0f;
if (Input.GetButtonDown("Fire1") || Input.GetButtonDown("Fire2"))
{
if (playerPlane.Raycast(ray, out hitdist))
{
Vector3 targetPoint = ray.GetPoint(hitdist);
Debug.DrawRay(transform.position, targetPoint, Color.green);
targetRotation = Quaternion.LookRotation(targetPoint - transform.position);
}
}
// Smooth rotation towards point.
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
//Rotate base on key pressed
if (Input.GetKey(KeyCode.W) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate up
{
targetRotation = Quaternion.LookRotation(Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.S) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate down
{
targetRotation = Quaternion.LookRotation(Vector3.forward * -1);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.D) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate right
{
targetRotation = Quaternion.LookRotation(Vector3.right);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
if (Input.GetKey(KeyCode.A) && !(Input.GetButton("Fire1") || Input.GetButton("Fire2"))) //player rotate left
{
targetRotation = Quaternion.LookRotation(Vector3.left);
transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, speed * Time.deltaTime);
}
}
}
I would save a last timestamp, and check if the second key release is within a certain timeframe. If it is release within (for example) 20ms, don't reset it is pressed.
For example: (pseudo)
private bool[] _directionKeysPressed = new bool[4];
private DateTime _previousKeyRelease;
private void KeyDown(object sender, EventArgs e)
{
_keyPressedCount++;
switch(keys)
{
case(W): _directionKeysPressed[0] = true;
case(D): _directionKeysPressed[1] = true;
// .................
}
}
private void KeyUp(object sender, EventArgs e)
{
_keyPressedCount--;
if(_keyPressedCount == 0)
{
// all keys released
_directionKeysPressed[] <--- last direction...
// reset all bools
return;
}
// ONLY if the key is released outside the 20 ms, reset the key.
if(_previousKeyRelease.AddMilliseconds(20) < DateTime.UTCNow)
{ // RESET KEY
switch(keys)
{
case(W): _directionKeysPressed[0] = false;
case(D): _directionKeysPressed[1] = false;
// .................
}
}
_previousKeyRelease = DateTime.UTCNow;
}
Personally I would do this with an bitfield in a Int32, but it is more clear with an array of bool.