I'm trying to make objects fly to the left while spinning themselves.
Here is the MoveLeft script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveLeft : MonoBehaviour
{
private float moveLeftSpeed = 10;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.Translate(Vector3.left * Time.deltaTime * moveLeftSpeed);
}
}
And there is the SpinObjects script:
using System.Collections.Generic;
using UnityEngine;
public class SpinObjectsX : MonoBehaviour
{
public float spinSpeed = 50;
// Update is called once per frame
void Update()
{
transform.Rotate(new Vector3(0, Time.deltaTime * spinSpeed, 0));
}
}
I expect the object's movement will look like this, it just moves to the left and spins itself.
But when I use both scripts, the object moves very weirdly, it is still spinning itself but instead of moving to the left, it spins around something...
Both Translate and Rotate per default work in local space of according object unless you explicitly pass in Space.World as additional last parameter.
So, after rotating your object around the Y-axis it's local left vector is now rotated as well and pointing somewhere else.
=> When you do the local space translation towards left of the object it doesn't actually move left in the world.
In order to move left in absolute world space you want to use
transform.Translate(Vector3.left * Time.deltaTime * moveLeftSpeed, Space.World);
Related
I need some help in trying to change the position of an gameobject and its speed. I know to translate the gameObject but I don't know how to increase the speed of how it translates. I'm using the unity game engine by the way.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class lightning : MonoBehaviour
{
//This is lightning
private GameObject name;
// Start is called before the first frame update
void Start()
{
name=GameObject.Find("car");
}
// Update is called once per frame
void Update()
{
if (Input.Keydone("r")
door.transform.Translate(-Vector3.right * Time.deltaTime);
}
}
One workaround you can use is a black filter(preferably Image) on UI layer that covers the whole screen. You can change filter's opacity accordingly to achieve the feeling of 'dimmed' screen.
It sounds like you are having trouble with speed and acceleration.
I added a velocity variable and an acceleration variable with the two you can make objects go faster and faster with time.
Since this is Physics I'd recommend you to use a rigidbody on your gameobject
and manipulate its speed or to apply a force (force = mass * acceleration)
so by adding a force it will give the object an acceleration.
//This is lightning
private GameObject name;
private float speedFactor = 20;
private float accelearationFactor = 5;
// Start is called before the first frame update
void Start()
{
name=GameObject.Find("car");
}
// Update is called once per frame
void Update()
{
if (Input.Keydone("r") {
door.transform.Translate(-Vector3.right * speedFactor * Time.deltaTime);
speedFactor += accelearationFactor * Time.deltaTime;
}
}
I want my objects to fall when the player got to that scene . My game have a long map and I want them not to fall when I start the game .There is any code for player detection in the view? for the objects to fall?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class FallDown : MonoBehaviour
{
public float fallSpeed = 8.0f;
//Variables for starting position and length until reset
private Vector3 _startingPos;
public float FallDistance = 5f;
void Start()
{
transform.Translate(Vector3.down * fallSpeed * Time.deltaTime, Space.World);
// Save starting position
_startingPos = transform.position;
}
void Update()
{
transform.Translate(Vector3.down * fallSpeed * Time.deltaTime, Space.World);
// If the object has fallen longer than
// Starting height + FallDistance from its start position
if (transform.position.y > _startingPos.y + FallDistance)
{
transform.position = _startingPos;
}
}
}
While the answer above is correct, Colliders might not be what you want to implement in this case. Colliders are used to, well, detect collisions, while you want the objects to fall when the player is at a specific distance from them. For this, I'd suggest adding a reference to the player GameObject first:
private GameObject playerRef;
And in the Start function find the player:
playerRef = GameObject.Find("yourPlayerGameObjectNameHere");
Get the GameObjects that you want to fall either by finding them, like above, or by passing a public reference to them through the inspector. Afterwards, you can use Vector3.distance between each GameObject and the player, like so:
if( Vector3.Distance(player.transform.position, fallingObject.transform.position) < yourDistanceHere ){
// Make the object fall
}
Have you tried implementing this behavior using Colliders?
To do it so, all you've got to do is add both a Collider Component and a RigidBody to your player and to the falling objects.
Once you've added them and configured their parameters, you can check the collision by using the method OnColissionEnter. This method will be triggered every time that a collision is detected by the GameObject that is holding the script. In your case, the falling objects should hold it.
private void OnCollisionEnter(Collision other)
{
//MAKE THE OBJECTS FALL
}
I am creating a first person controller in Unity. Very basic stuff, camera is a child of Player capsule. Codes work, but I need help explaining what's going on.
*camera is child of Player in hierarchy
These are my questions:
In PlayerMovement, why are we translating in the Z-axis to achieve vertical movement when Unity is in Y-Up axis?
In CamRotation, I have no idea what is going on in Update(). Why are we applying horizontal movement to our Player, but then vertical movement to our Camera? Why is it not applied on the same GameObject?
What is mouseMove trying to achieve? Why do we use var?
I think we are getting a value of how much mouse has been moved, but what then does applying Vector2.Scale do to it?
Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
public float speed = 5.0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
float mvX = Input.GetAxis("Horizontal") * Time.deltaTime * speed;
float mvZ = Input.GetAxis("Vertical") * Time.deltaTime * speed;
transform.Translate(mvX, 0, mvZ);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CamRotation : MonoBehaviour {
public float horizontal_speed = 3.0F;
public float vertical_speed = 2.0F;
GameObject character; // refers to the parent object the camera is attached to (our Player capsule)
// initialization
void Start()
{
character = this.transform.parent.gameObject;
}
// Update is called once per frame
void Update()
{
var mouseMove = new Vector2(Input.GetAxisRaw("Mouse X"), Input.GetAxisRaw("Mouse Y"));
mouseMove = Vector2.Scale(mouseMove, new Vector2(horizontal_speed, vertical_speed));
character.transform.Rotate(0, mouseMove.x, 0); // to rotate our character horizontally
transform.Rotate(-mouseMove.y, 0, 0); // to rotate the camera vertically
}
}
XY is the plane for 2D Unity games. For 3D, you have Z-axis for height, and XY plane for positioning.
Note that different components from mouseMove are being applied (.x for character and .y for the camera). This means that the movement from the character is not equal to the movement from the camera; one should be faster/slower than the other.
var is a predefined C# keyword that lets the compiler figure out an appropriate type. In this case, it's the same as if you had written Vector2 as in Vector2 mouseMove = new Vector2(...);.
You are scaling the value from mouseMove, by multiplying its components by predefined values in your code. That's just it.
EDIT
You apply .x to your character because, as you commented after the line of code, you want to move it horizontally. As for the camera, .y is being applied because you want to move it vertically.
The negative value could be because the axis is inverted, so you make it negative so the camera has a natural movement. It's the same principle some games have in the setting, where they allow you to invert Y-axis.
I'm making a 2d game in Unity. I have a player sprite with this script attached. The right and left keys move perfect but when I try to get the space bar, it doesn't work
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
public class Player : MonoBehaviour {
public float moveSpeed;
public float jumpHeight;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
Rigidbody2D playerBody = GetComponent<Rigidbody2D>();
if (Input.GetKeyDown("space")){
print("fired");
//playerBody.velocity = new Vector2(playerBody.velocity.x, jumpHeight);
}
if (Input.GetKey(KeyCode.LeftArrow))
{
playerBody.velocity = new Vector2(-moveSpeed, playerBody.velocity.y);
}
if (Input.GetKey(KeyCode.RightArrow))
{
playerBody.velocity = new Vector2(moveSpeed, playerBody.velocity.y);
}
}
}
I have also tried Keycode.Space instead of "space" which didn't work either
Also for some reason, I cannot remove or replace the unity3d tag but it's for a 2d unity game.
Your code appears to be all good, so it may be an error with your console window. Make sure in the top right corner of the console you have the comment box highlighted so anytime you print something in the code, it will appear. Also, I would suggest you use forces to make your character jump instead of velocity. In this case, you said the player's vertical velocity to jumpHeight, but never change it back so your character will constantly be moving upward. You should change that line to:
playerBody.AddForce (transform.up * jumpHeight);
and you may need to adjust the jumpHeight accordingly.
I have tried both of these C#scripts to rotate my directional light:
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
void Update ()
{
transform.rotation = Quaternion.Euler(transform.eulerAngles.x + 1.0f,
transform.eulerAngles.y,
transform.eulerAngles.z);
}
}
and
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
void Update ()
{
transform.localEulerAngles = new Vector3(transform.localEulerAngles.x + 1.0f,
transform.localEulerAngles.y,
transform.localEulerAngles.z);
}
}
They both seem to function exactly the same: If I change transform.eulerAngles.y to transform.eulerAngles.y + 0.5f, the light will rotate along the y-axis, and the same works for the z-axis. However, when I try to do this with the x-axis, it will rotate until it hits 90º, at which point it will continue to attempt rotation but it immediately and continuously shoved back to 90º. If I reverse the direction, it does the same thing at -90º. For example, the rotation might be: 88.5,89.0,89.5,90.0, 90.5, 89.93, 90.24, 89.4, etc.
What is causing this clamping and how do I fix it?
I think this is what you are looking for: http://answers.unity3d.com/questions/187073/rotation-locks-at-90-or-270-degrees.html
In order to fix your problem, you need to use an additional vector, change it inside Update every frame, and then pass it to the eulerAngles propriety of the transform.
Vector3 vect = Vector3.zero;
float rotationSpeed = 10f;
void Start () {
vect = transform.eulerAngles; //Set the vect rotation equal to the game object's one
}
void Update ()
{
vect.x += rotationSpeed * Time.deltaTime;
//Pass unique eulerAngles representation to the object without letting Unity change it
transform.eulerAngles = vect;
}
This happens btw because there're multiple euler angles representation of a single physical rotation in the 3D space, and when you work directly on the eulerAngles propriety of the transform, Unity makes some work behind the scenes, which can lead to a gimbal lock.
Use Quaternions. It's what Unity3d uses internally and doesn't have any of the side effects of euler angles.
using System.Collections;
using UnityEngine;
public class LightRotator : MonoBehaviour
{
public Vector3 RotationAxis = Vector3.right;
Quaternion _startRotation;
float _rotationIncrement = 0;
void Start()
{
_startRotation = transform.rotation;
}
void Update ()
{
Quaternion rotationMod =
Quaternion.AngleAxis(_rotationIncrement, RotationAxis);
_rotationIncrement += 1;
transform.rotation = _startRotation * rotationMod;
}
}
However, you probably want to use something like Quaternion.RotateTowards or Quaternion.Lerp along with Time.time and a rate. You will get much smoother results that way.
if you only want to rotate along the X-axis then set the other axis as 0.