I have made a rocket in Unity that goes up and after 5 seconds lands. However, it lands like this:
I have to make it land upside down. How can I make this through code?
My current code as it is:
double t = 5.0;
void Update () {
GameObject Paraquedas;
GameObject CorpoNariz;
CorpoNariz = GameObject.Find("Corpo_Nariz");
Paraquedas = GameObject.Find("Paraquedas");
rigidbody.AddForce(transform.up * 15);
t -= Time.deltaTime;
if (t <= 0) {
Destroy (CorpoNariz);
Paraquedas.renderer.enabled = true;
transform.Rotate(Time.deltaTime, 0, 0);
rigidbody.AddForce(-transform.up * 50);
rigidbody.drag = 5;
}
}
}
Here's the script reference for transform.Rotate of Unity
http://docs.unity3d.com/Documentation/ScriptReference/Transform.Rotate.html
Try version 3 of Rotate functions. See the given example here:
void Rotate(Vector3 axis, float angle, Space relativeTo = Space.Self);
using UnityEngine;
using System.Collections;
public class Example : MonoBehaviour {
void Update() {
transform.Rotate(Vector3.right, Time.deltaTime);
transform.Rotate(Vector3.up, Time.deltaTime, Space.World);
}
}
Simply change the scale Y from 1 to -1 will do.
gameObject.transform.localScale = new Vector3(1,-1,1);
Related
Im working on an 3d rpg top down view in Unity. Something like the zelda links awakening remake.
What im trying to achieve ist that the player rotates to the direction you press and then just goes forwards and this in only 8 directions.
I already got this working with WASD and the dpad, there it obviously works because you cant press in between two buttons if you know what i mean.
But i need a way to clamp the joystick input to only the 8 directions. How can i achieve this ? I hope you understand what i mean. This is the code ive already written. Note that im using the new input system.
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
private PlayerInputActions playerInput;
private Rigidbody rb;
[SerializeField]
private float playerSpeed;
private float angle;
private Quaternion targetRotation;
private Vector2 input;
private Transform cam;
void Awake()
{
playerInput = new PlayerInputActions();
rb = GetComponent<Rigidbody>();
}
void Start()
{
cam = Camera.main.transform;
}
void Update()
{
GetInput();
if (input.x == 0 && input.y == 0) return;
CalculateDirection();
Rotate();
Move();
}
void GetInput()
{
input.x = playerInput.Player.Move.ReadValue<Vector2>().x;
input.y = playerInput.Player.Move.ReadValue<Vector2>().y;
}
void CalculateDirection()
{
if (input.sqrMagnitude > 1.0f)
input = input.normalized;
angle = Mathf.Atan2(input.x, input.y);
angle = Mathf.Rad2Deg * angle;
angle += cam.eulerAngles.y;
}
void Rotate()
{
targetRotation = Quaternion.Euler(0, angle, 0);
transform.rotation = targetRotation;
}
void Move()
{
//transform.position += transform.forward * 5 * Time.deltaTime;
rb.velocity = transform.forward * 200 * Time.fixedDeltaTime;
}
void OnEnable()
{
playerInput.Enable();
}
void OnDisable()
{
playerInput.Disable();
}
} ```
You can do something like this to keep results in the same way that you're working at moment
private void CalculateDirection (InputAction.CallbackContext context)
{
var input = context.ReadValue<Vector2>();
var x = Mathf.Abs(input.x) <= .1f ? 0f : // Deadzone
input.x > 0 ? 1f : -1f; // Direction
var y = Mathf.Abs(input.y) <= .1f ? 0f :
input.y > 0 ? 1f : -1f;
var angle = Mathf.Atan2(x, y);
angle = Mathf.Rad2Deg * angle;
}
As you are working with gamepad stick and values here can be a range between -1..1 and when you get interactions from your keyboard buttons values are coming in 0, 1, or -1, similar to the Input.GetAxisRaw() in older input system, we don't need to normalize it.
This approach should work but I have a feeling that this will give some weird behaviors when controlling with the stick, I mean, maybe if you try to go up the player ends going to some side (UpRight or UpLeft) because the range for upper, down, right and left aren't really wide, I hope to be wrong but if I'm right you'll probably need to bite the bullet and manually decide a range/angle for each of the 8 sides. Try the above code and if you need help manually creating it just come back here and we try again.
N
when I command or set an enemy to go left and then at reaching a particular state or position i say my enemy to go right but it is not going right and not reaching to perfect position here is the code I think there is no issue in the code but it is not working properly so here are some images of the code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class enem : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
transform.position = transform.position + new Vector3(-3f, 0f, 0f)* 1 * Time.deltaTime;
if (transform.position.x > -29)
{
transform.position = transform.position + new Vector3(3f, 0f, 0f) * 1 * Time.deltaTime;
}
}
}
Before adding any bool logic, try first simply moving your element:
using UnityEngine;
public class SimeMoveMove : MonoBehaviour
{
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
transform.position += new Vector3(3f, 0f, 0f);
}
}
}
I smiled a little the moment I understood what you were trying to do.
I wrote the code imagining the result you were trying to make!
Create a cube, attach this code as component, and run the game.
// Gift for you friend
public class MoveTest : MonoBehaviour
{
private int _direction = 1;
void Start()
{
transform.position = Vector3.zero;
}
void Update()
{
Vector3 position = transform.position;
int direction = ShouldWeSwitchDirection(position.x, 0f);
if (direction != 0)
{
_direction = direction;
}
transform.position += _direction * new Vector3(3f, 0f, 0f) * 3f * Time.deltaTime;
}
private int ShouldWeSwitchDirection(float value, float center = 0f)
{
float direction = Mathf.Sign(value - center);
float distance = Mathf.Abs(value - center);
// If X Position is larger than 29
if (Mathf.Abs(distance) > 29)
{
// If X is on right side
if (direction >= 0)
{
return -1;
}
// If X is on left side.
else
{
return 1;
}
}
else
{
return 0;
}
}
}
I have two doors in my game. Initially they are closed. After that they open and will stop at specific points (pic attached as a sample). So far I have written a script, which rotates the door continuously. I want to stop them, like at 45 angle, need kind suggestion.
using UnityEngine;
using System.Collections;
public class rotate : MonoBehaviour
{
public string rotate_along = "y";
public float speed = 10.0f;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update ()
{
if (rotate_along == "y") {
this.transform.Rotate (0, speed, 0);
} else if (rotate_along == "x") {
this.transform.Rotate (speed * Time.deltaTime, 0, 0);
} else if (rotate_along == "z") {
this.transform.Rotate (0, 0, speed * Time.deltaTime);
} else {
print ( "please! check your cordinate for rotating for "+gameObject.name );
}
}
}
I suggest you to use Lerp or Slerp for this:
void Update() {
transform.rotation = Quaternion.Lerp(from.rotation, to.rotation, Time.time * speed);
}
[Source]
This will move your doors naturally smoothly like in real world and will let you avoid coding horror in vector space. Unity community has pretty much a lot of examples how quaternions works. Here you can find brief explanation of what is difference:
http://answers.unity3d.com/questions/389713/detaliled-explanation-about-given-vector3slerp-exa.html
You are rotating the doors at a constant velocity without setting a maximum angle..
Something like this should do the trick.. But I haven't been able to test it.
using UnityEngine;
using System.Collections;
public class rotate : MonoBehaviour
{
public string rotate_along = "y";
public float speed = 10.0f;
private float _currentAngle = 0.0f;
private float _targetAngle = 45.0f;
private float _completed = false;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (_completed)
return;
float angle = speed * Time.deltaTime
if (_currentAngle + angle > _targetAngle)
{
angle = _targetAngle - _currentAngle;
_completed = true;
}
if (rotate_along == "y")
{
this.transform.Rotate (0, angle, 0);
}
else if (rotate_along == "x")
{
this.transform.Rotate (angle, 0, 0);
} else if (rotate_along == "z")
{
this.transform.Rotate (0, 0, angle);
}
else
{
print ( "please! check your cordinate for rotating for "+gameObject.name );
}
_currentAngle += angle;
}
}
I have the following code for my 2D game, it makes object randomly wonder on the screen. What I am having issues with, is when an object looks at the point it is going to, I would like it to rotate as it moves forward. What is happening now, is it rotates instantly to the point it is going towards. So, how can I get it to rotate slowly and move forward at the same time?
using UnityEngine;
using System.Collections;
public class Wonder : MonoBehaviour {
protected Vector2 wayPoint;
protected float speed;
// Use this for initialization
void Start () {
speed = gameObject.GetComponent<Move>().playerSpeed;
wonder();
}
void wonder(){
wayPoint = Random.insideUnitCircle * 10;
}
// Update is called once per frame
void Update () {
Vector2 dir = wayPoint - new Vector2(transform.position.x, transform.position.y);
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(new Vector3(0, 0,Mathf.Atan2 (dir.y, dir.x) * Mathf.Rad2Deg - 90));
transform.position = Vector2.MoveTowards(transform.position, wayPoint, Time.deltaTime * speed);
float magnitude = (new Vector2(transform.position.x, transform.position.y) - wayPoint).magnitude;
if(magnitude < 3){
wonder();
}
}
}
Here is an example Image:
So, once the ship gets to its point another will be created and it will move there. I am thinking I will have to have a list of 5+ points, then calculate the arch the ship needs to take adding new points as the ship hits a way point then removing old ones after. I am not sure how to do this though...
using UnityEngine;
using System.Collections;
public class Wander : MonoBehaviour {
protected Vector3 velocity;
protected Vector2 waypoint;
protected float speed;
// Use this for initialization
void Start () {
speed = gameObject.GetComponent<Move>().playerSpeed;
RandomizeWaypoint();
}
void RandomizeWaypoint(){
waypoint = Random.insideUnitCircle * 10;
}
// Update is called once per frame
void Update () {
transform.position = Vector3.SmoothDamp( transform.position, waypoint, ref velocity, Time.deltaTime * speed );
transform.rotation = Quaternion.AngleAxis( Mathf.Atan2( velocity.y, velocity.x ) * Mathf.Rad2Deg, Vector3.forward );
if( Vector3.Distance( transform.position, waypoint ) < 3 ){
RandomizeWaypoint();
}
}
}
Untested. Vector3.SmoothDamp can be pretty handy. Note the spelling also.
I'm new to programming in C#.
I have a sphere rigid body on a plane in unity.
I want to make this sphere jump when the spacebar is pressed and then bounce twice before coming to rest again when the key is released.
This will not always be on the plane it will sometimes be on an object and I would like the height of the bounce to reflect the distance dropped from the initial jump.
I currently have a camera facing onto the sphere from a side and have it following the ball from a set distance. The sphere can move in any direction but the camera always stays on the same side and distance from the sphere.
The issue is that my code currently says (to my knowledge) IF the spacebar is not pressed try to move the sphere's Y position down, then if the spacebar is pressed make the sphere jump and then come back down on spacebar release.
The way this code is written makes my plane jump as the ball is constantly bouncing into it when spacebar is not being pressed but if I take that part out the ball refuses to drop.
Example Code :
public class RollAdvancedScript : MonoBehaviour
{
public Transform camera;
public float posY;
void lol()
{
posY = transform.position.y;
}
void Update()
{
if (Input.GetKey(KeyCode.D))
{
Vector3 vectorToUse = camera.right;
vectorToUse.y = 0;
transform.position += vectorToUse * Time.deltaTime * 5;
}
if (Input.GetKey(KeyCode.A))
{
Vector3 vectorToUse = -camera.right;
vectorToUse.y = 0;
transform.position += vectorToUse * Time.deltaTime * 5;
}
if (Input.GetKey(KeyCode.S))
{
Vector3 vectorToUse = -camera.forward;
vectorToUse.y = 0;
transform.position += vectorToUse * Time.deltaTime * 5;
}
if (Input.GetKey(KeyCode.W))
{
Vector3 vectorToUse = camera.forward;
vectorToUse.y = 0;
transform.position += vectorToUse * Time.deltaTime * 5;
}
if (Input.GetKey(KeyCode.Space))
{
Vector3 vectorToUse = camera.up;
transform.position += vectorToUse * Time.deltaTime * 10;
}
else
{
if ( posY >= 0)
{Vector3 vectorToUse = camera.up;
transform.position -= vectorToUse * Time.deltaTime * 10;
}
else
{
Vector3 vectorToUse = camera.up;
vectorToUse.y = 0;
transform.position -= vectorToUse * Time.deltaTime * 10;
}
}
}
}
Example Image:
Please ignore the shadow as it's not working correctly just now.
TLDR; The best way to make an object jump and fall with a bounce on Keypress when moving in relation to a fixed camera position?
Are you trying to handle this in animation or in physics? Looking at the code it looks like pure controller animation, so I'd suggest that you track your jump state explicitly instead of just using the y > 0 check every update. It's a lot easier to see what's going on if you know the state of the object.
Your code makes it look like you pop up by (10 * deltaTime) when you hit space and then immediately pop down by 10 until you are below zero. Are you expecting the player to hold down space to fly, jetpack-style? Otherwise you should give an initial impulse up and then subtract from it to give a smooth fall.
Here's a very simple example. The up vector is world up (not Camera up as in your example) but if you're camera is not rolling the result would be the same.
public class DoJump : MonoBehaviour {
public float JumpSpeed = .25f;
public bool Jumping;
Vector3 jumpVec;
void Start () {
Jumping = false;
}
void Update () {
if (Jumping)
{
transform.position += jumpVec * Time.deltaTime;
jumpVec += (Vector3.down * Time.deltaTime);
//accelerate downward one unit per second per second
}
else
{
if (Input.anyKeyDown)
{
Jumping = true;
jumpVec = Vector3.up * (JumpSpeed * Time.SmoothDeltaTime);
// impulse up # jumpSpeed units per second
}
}
}
void LateUpdate()
{
if (transform.position.y < 0)
{
transform.position = new Vector3(transform.position.x, 0, transform.position.z);
Jumping = false;
}
}
}
If you're going to have uneven terrain, you should probably use physics colliders or raycast to know when to stop falling.
This is my code, hope it can help you:
public class Player : MonoBehaviour
{
public float m_gravity=10f;
void Jump()
{
if (m_ch.isGrounded) //this is the point
{
m_Gravity = 10;
if (Input.GetKeyDown(KeyCode.Space))
{
m_Gravity = -8;
}
}
else
{
m_Gravity += 10f * Time.deltaTime;
if (m_Gravity >= 10) { m_Gravity = 10; }
}
}
}