I'm new to Unity but I'm trying to rotate an object around the Y axis using controller input (right stick). So if the stick is pushed right, the object will rotate towards the right. Here is my code so far.
public class TurnBall : MonoBehaviour {
PlayerControls controls;
Vector2 aim;
void Awake() {
controls = new PlayerControls();
controls.Gameplay.Aim.performed += ctx => aim = ctx.ReadValue<Vector2>();
controls.Gameplay.Aim.canceled += ctx => aim = Vector2.zero;
}
void Update() {
transform.Rotate(0, aim.x, 0, Space.World);
}
void onEnable() {
controls.Gameplay.Enable();
}
void onDisable() {
controls.Gameplay.Disable();
}
}
Thanks in advance!!
Related
I'm trying to get an object to always be "in front" of the player, from a top down perspective. Here's screenshots demonstrating what I'm trying to do.
So as you can see, when the blue capsule (player) picks up the green capsule (item), the item correctly hovers in front of the player (indicated by the z-axis blue arrow), but when the player turns in any other direction, the item doesn't follow, and instead stays in exactly the same position relative to the player.
My player controller script looks as follows:
using UnityEngine;
public class PlayerController : MonoBehaviour {
public float movementSpeed = 10;
private Rigidbody body;
private Vector2 movement;
void Start() {
body = GetComponent<Rigidbody>();
}
void Update() {
movement.x = Input.GetAxis("Horizontal");
movement.y = Input.GetAxis("Vertical");
}
void FixedUpdate() {
body.velocity = new Vector3(movement.x * movementSpeed * Time.deltaTime, 0, movement.y * movementSpeed * Time.deltaTime);
// this is what updates the direction of the blue arrow in the direction of player movement
if(movement.x != 0 || movement.y != 0) {
body.rotation = Quaternion.LookRotation(body.velocity);
}
}
}
And here's my pickup script (where the item's position is supposed to be updated):
using UnityEngine;
public class Pickup : MonoBehaviour {
private GameObject item;
public float carryDistance = 1;
void OnCollisionEnter(Collision collision) {
if(collision.gameObject.CompareTag("Item")) {
item = collision.gameObject;
}
}
void Update() {
if(item) {
item.transform.position = transform.position + new Vector3(0, 0, carryDistance);
}
}
}
So to reiterate my question: How can I update the item's position such that it's always hovering next to the player on the side of the blue arrow?
You can achieve this by using players transform.forward
item.transform.position = transform.position + (transform.forward * carryDistance)
+ (Vector3.up * carryHeight);
Alternatively you can just add empty child gameobject to the player, position it in front of the player and use its transform position and rotation to position the picked up object.
public class Pickup : MonoBehaviour {
public Transform pickupPositionTransform;
private GameObject item;
public float carryDistance = 1;
void OnCollisionEnter(Collision collision) {
if(collision.gameObject.CompareTag("Item")) {
item = collision.gameObject;
}
}
void Update() {
if(item) {
item.transform.position = pickupPositionTransform.position;
item.transform.rotation = pickupPositionTransform.rotation;
}
}
}
I am creating a build in Unity 2019.4.12f1 and need to drag an object with Right Mouse button.
My C# skills are very limited, so far but i try.
This scripts is my attempt to be able to rotate a gameobject by holding right mouse button down and dragging ingame.
But it is wrong.
Can anyone help me correct it?ยด
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class mouseM : MonoBehaviour
{
bool dragging = false;
void Start()
{
if (Input.GetMouseButtonDown(1))
{
dragging = true;
}
}
void Update()
{
if (Input.GetMouseButtonDown(1))
{
yourOnMouseDownFunction();
dragging = true;
}
if (Input.GetMouseButtonUp(1))
{
yourOnMouseUpFunction();
dragging = false;
}
if (dragging)
{
yourOnMouseDragFunction();
}
}
}
I understood that You need to Drag Object in 3d World so Here is my Code just create new Script and attach to Object You Want to Drag it
Your Object that You need to Drag it should has a collider
using UnityEngine;
public class DragableObject : MonoBehaviour
{
private Vector3 mOffset;
private float mZCoord;
private void OnMouseDrag()
{
transform.position = GetMouseWorldPos() + mOffset;
}
private void OnMouseDown()
{
mZCoord = Camera.main.WorldToScreenPoint(gameObject.transform.position).z;
mOffset = transform.position - GetMouseWorldPos();
}
private Vector3 GetMouseWorldPos()
{
Vector3 mosePoint = Input.mousePosition;
mosePoint.z = mZCoord;
var result = Camera.main.ScreenToWorldPoint(mosePoint);
return result;
}
}
you can try it by adding it to sphere or cube and if you use custom shape you should insure that the collider is in suitable size or has a meshcollier
Demo
EDIT
using UnityEngine;
public class DragableObject : MonoBehaviour
{
private bool isMouseDragging;
private Vector3 screenPosition;
private Vector3 offset;
private GameObject target;
GameObject ReturnClickedObject(out RaycastHit hit)
{
GameObject targetObject = null;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray.origin, ray.direction * 10, out hit))
{
targetObject = hit.collider.gameObject;
}
return targetObject;
}
void Update()
{
if (Input.GetMouseButtonDown(1))
{
RaycastHit hitInfo;
target = ReturnClickedObject(out hitInfo);
if (target != null)
{
isMouseDragging = true;
Debug.Log("our target position :" + target.transform.position);
//Here we Convert world position to screen position.
screenPosition = Camera.main.WorldToScreenPoint(target.transform.position);
offset = target.transform.position - Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPosition.z));
}
}
if (Input.GetMouseButtonUp(1))
{
isMouseDragging = false;
}
if (isMouseDragging)
{
//tracking mouse position.
Vector3 currentScreenSpace = new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPosition.z);
//convert screen position to world position with offset changes.
Vector3 currentPosition = Camera.main.ScreenToWorldPoint(currentScreenSpace) + offset;
//It will update target gameobject's current postion.
target.transform.position = currentPosition;
}
}
}
You could try the Input.GetMouseButton method, this should return a value depending on if the button is held pressed.
This one works too, if someone needs in the future.
This is for rotate though.
Sorry, i dont know why it wont let me post as code, so i post an image.
enter image description here
This is just a simple thing I want to do. I have my cube gameobject rotating and I want to make it so when the camera sees the cube, it stops rotating. If you could steer me in the right direction, I'd appreciate it. thank you
public class cubeMove : MonoBehaviour, MoveObject
{
public Renderer rend;
public void Update () {
rend = GetComponent<Renderer>();
stopWhenSeen();
}
public void move()
{
transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
}
public void stopWhenSeen()
{
if (rend.enabled == false)
{
move();
}
}
}
Implement the OnBecameVisible and OnBecameInvisible MonoBehaviour's message :
private visible = false ;
// OnBecameVisible is called when the renderer became visible by any camera. INCLUDING YOUR EDITOR CAMERA
void OnBecameVisible()
{
visible = true ;
}
// OnBecameInvisible is called when the renderer is no longer visible by any camera. INCLUDING YOUR EDITOR CAMERA
void OnBecameInvisible()
{
visible = false;
}
void Update()
{
if( !visible )
move() ;
}
public void move()
{
transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
}
https://docs.unity3d.com/ScriptReference/Renderer-isVisible.html
You could try the .isVisible bool in your update method.
Here is a thread with other suggestions:
http://answers.unity3d.com/questions/8003/how-can-i-know-if-a-gameobject-is-seen-by-a-partic.html
I am making a 2d top down game where the player can rotate the camera around himself as he moves through the world.
Everything works fine when the player is moving around the world the camera follows him fine. if he standing still then the camera rotation also works very well. However as soon as I start to do both then there is a jittery in the camera that makes all other objects jitter besides the player.
Now in working with this problem I have found out that this could have to do with the fact that I use rigidbody2d.AddRelativeForce (so physics) to move the player and that his movements are checked in FixedUpdate.
https://forum.unity3d.com/threads/camera-jitter-problem.115224/ http://answers.unity3d.com/questions/381317/camera-rotation-jitterness-lookat.html
I have tried moving my camera rotation and the following scripts to LateUpdate, FixedUpdate, Update you name it. Nothing seems to work. I am sure that there is some sort of delay between movement of the camera and the rotation that is causing this. I am wondering if anyone has any feedback?
I have tried disabling Vsync, does not remove it entirely
I have tried interpolating and extrapolating the rigidbody and although there is a difference it does not remove it entirely. Ironically it seemd if I have it set to none, it works best.
Scripts:
To Follow character, script applied to a gameobject that has the camera as a child
public class FollowPlayer : MonoBehaviour {
public Transform lookAt;
public Spawner spawner;
private Transform trans;
public float cameraRot = 3;
private bool smooth = false;
private float smoothSpeed = 30f;
private Vector3 offset = new Vector3(0, 0, -6.5f);
//test
public bool changeUpdate;
private void Start()
{
trans = GetComponent<Transform>();
}
private void FixedUpdate()
{
CameraRotation();
}
private void LateUpdate()
{
following();
}
public void following()
{
Vector3 desiredPosition = lookAt.transform.position + offset;
if (smooth)
{
transform.position = Vector3.Lerp(transform.position, desiredPosition, smoothSpeed);
}
else
{
transform.position = desiredPosition;
}
}
void CameraRotation()
{
if (Input.GetKey("q"))
{
transform.Rotate(0, 0, cameraRot);
}
if (Input.GetKey("e"))
{
transform.Rotate(0, 0, -cameraRot);
}
}
public void SetTarget(string e)
{
lookAt = GameObject.Find(e).GetComponent<Transform>();
}
}
The character Controller, script applied to the Player, is called in FixedUpdate
private void HandleMovement()
{
if (Input.GetKey("w"))
{
rigid.AddRelativeForce(Vector2.up * speed);
}
if (Input.GetKey("s"))
{
rigid.AddRelativeForce(Vector2.down * speed);
}
if (Input.GetKey("a"))
{
if (facingRight)
{
Flip();
}
rigid.AddRelativeForce(Vector2.left * speed);
}
if (Input.GetKey("d"))
{
if (!facingRight)
{
Flip();
}
rigid.AddRelativeForce(new Vector2(1,0) * speed);
}
}
Try to use Coroutines. I modified some of my scripts to be more familiar to Your code, tried it, and I didn't see any jittery. I hope that will help You.
Camera Class:
public class CameraController : MonoBehaviour {
[SerializeField]
Transform CameraRotator, Player;
[SerializeField]
float rotationSpeed = 10f;
float rotation;
bool rotating = true;
void Start()
{
StartCoroutine(RotatingCamera());
}
IEnumerator RotatingCamera()
{
while (rotating)
{
rotation = Input.GetAxis("HorizontalRotation");
CameraRotator.Rotate(Vector3.up * Time.deltaTime * rotation * rotationSpeed);
CameraRotator.position = Player.position;
yield return new WaitForFixedUpdate();
}
}
private void OnDestroy()
{
StopAllCoroutines();
}
}
Player Class:
public class PlayerMovement : MonoBehaviour {
[SerializeField]
float movementSpeed = 500f;
Vector3 movementVector;
Vector3 forward;
Vector3 right;
[SerializeField]
Transform CameraRotator;
Rigidbody playerRigidbody;
float inputHorizontal, inputVertical;
void Awake()
{
playerRigidbody = GetComponent<Rigidbody>();
StartCoroutine(Moving());
}
IEnumerator Moving()
{
while (true)
{
inputHorizontal = Input.GetAxis("Horizontal");
inputVertical = Input.GetAxis("Vertical");
forward = CameraRotator.TransformDirection(Vector3.forward);
forward.y = 0;
forward = forward.normalized;
Vector3 right = new Vector3(forward.z, 0, -forward.x);
movementVector = inputHorizontal * right + inputVertical * forward;
movementVector = movementVector.normalized * movementSpeed * Time.deltaTime;
playerRigidbody.AddForce(movementVector);
yield return new WaitForFixedUpdate();
}
}
}
I fixed this problem finally:
First I made my cameraRotation() and follow() into 1 function and gave it a better clearer name:
public void UpdateCameraPosition()
{
if (Input.GetKey("q"))
{
transform.Rotate(0, 0, cameraRot);
}
else if (Input.GetKey("e"))
{
transform.Rotate(0, 0, -cameraRot);
}
Vector3 desiredPosition = lookAt.transform.position + offset;
transform.position = desiredPosition;
}
I then called that function from the character controller straight after the handling of movement. Both calls (handleMovement & cameraPosition) in fixedUpdate.
void FixedUpdate()
{
HandleMovement();
cameraController.UpdateCameraPosition();
}
and the jittering was gone.
So it seems it was imply because there was a slight delay between the two calls as the previous posts I read had said. But I had failed to be able to properly Set them close enough together.
Hope this helps someone.
using UnityEngine;
using System.Collections;
public class playSound : MonoBehaviour {
private bool destructionHasBegun = false;
public Transform BlueKey;
private void OnTriggerEnter()
{
audio.Play ();
destructionHasBegun = true;
}
private void Update()
{
if(destructionHasBegun)
{
DestroyWhenSoundComplete();
}
}
private void DestroyWhenSoundComplete()
{
if(!audio.isPlaying)
{
Destroy(gameObject);
GameObject textObject = (GameObject)Instantiate(Resources.Load("BlueKey"));
}
}
}
im trying to instantiate the bluekey prefab in a particular position how do i do this? thanks in advance
As per the Instantiate documentation, you can pass in a Vector3 worldspace position as a second parameter.
You'll also need to pass in a Quaternion for its initial rotation as the third parameter; Quaternion.identity is the equivalent of no rotation.
Vector3 newPosition = new Vector3(0, 0, 0);
Quaternion newRotation = Quaternion.identity;
GameObject textObject = (GameObject)Instantiate(Resources.Load("BlueKey"), newPosition, newRotation);