Move doors in unity3d, at specific points through script C# - c#

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;
}
}

Related

How To Rotate Objects Using C# Script In Unity2d?

So I'm Trying To Rotate My Coin Object to 0z if Y is above 0.17f and if its not will rotate back to 90z , the first if statement works fine but the other one keeps rotating my coin and i don't know why...? I'm Completely New To Unity and C# Lang !
Anyway Here's my code :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CoinScript : MonoBehaviour
{
public GameObject coin;
bool isRotated = false;
// Update is called once per frame
void FixedUpdate()
{
if (coin.transform.position.y > 0.17f && coin.transform.rotation.z >= 0f && !isRotated)
{
coin.transform.Rotate(coin.transform.rotation.x,coin.transform.rotation.y,-1f );
if (coin.transform.rotation.z <= 0f)
{
isRotated = true;
}
}else if (coin.transform.position.y < 0.17f && coin.transform.rotation.z <= 90f && isRotated)
{
coin.transform.Rotate(coin.transform.rotation.x,coin.transform.rotation.y,1f);
if (coin.transform.rotation.z >= 90f)
{
isRotated = false;
}
}
}
}
Transform.rotation is a Quaternion!
As the name suggests a Quaternion (also see Wikipedia -> Quaternion has not three but four components x, y, z and w. All these move within the range -1 to +1. Unless you really know exactly what you are doing you never touch these components directly.
If I understand you correctly you rather want to do something like e.g.
public class CoinScript : MonoBehaviour
{
public Transform coin;
public float anglePerSecond = 90;
private void FixedUpdate()
{
var targetRotation = coin.position.y > 0.17f ? Quaternion.identity : Quaternion.Euler(0, 0, 90);
coin.rotation = Quaternion.RotateTowards(coin.rotation, targetRotation, anglePerSecond * Time.deltaTime);
}
}

unity c# issue unable to get perfect position of a enemy in unity c# script using transform.position

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;
}
}
}

Make a Tank Aim Properly

Hi I am trying to make my tank fire, but it doesn't seem to work.
My tank's gun has a firing point which is used to fire the object. FirePoint is the point from which the laser beam is instantiated. When I turn my turret though the point goes off. The point is a child of the gun turret. What do I need to do? If I haven't explained it enough, please ask and I will try my best to help.
This is my player controller script.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public float Speed = 0;
public float MaxSpeed;
public float TurnSpeed;
public float AccelRate = 1;
public float BrakeSpeed = 1;
public GameObject LaserBeam;
public GameObject FirePoint;
public Vector3 Offset;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
// Increase forward when up arrow pressed
if (Input.GetKey(KeyCode.UpArrow))
{
Speed = Speed + AccelRate;
}
// Move backward when down arrow pressed
if (Input.GetKey(KeyCode.DownArrow))
{
Speed = Speed - AccelRate;
}
// Turn when left arrow pressed
if (Input.GetKey(KeyCode.LeftArrow))
{
transform.Rotate(Vector3.down * Time.deltaTime * TurnSpeed);
}
// Turn when right arrow pressed
if (Input.GetKey(KeyCode.RightArrow))
{
transform.Rotate(Vector3.up * Time.deltaTime * TurnSpeed);
}
// Reset vehicle rotation
if (Input.GetKey(KeyCode.Return))
{
transform.eulerAngles = new Vector3(0, 0, 0);
}
// Press the brakes
if (Input.GetKey(KeyCode.Space) && (Speed > 0 || Speed < 0))
{
Speed = Speed - BrakeSpeed;
if (Speed < 0) { Speed = 0; }
}
//Ensure vehicle does not pass the maxspeed
if (Speed > MaxSpeed)
{
Speed = MaxSpeed;
}
//Move vehicle
transform.Translate(Vector3.right * Time.deltaTime * Speed);
if (Input.GetKey(KeyCode.UpArrow) == false && Speed > 0)
{
Speed = Speed - AccelRate;
}
//Fire
if (Input.GetKeyDown(KeyCode.F))
{
Instantiate(LaserBeam, FirePoint.transform.position + Offset, FirePoint.transform.rotation);
}
}
}
I fixed it! I simply set the offset to 0,0,0 and it worked.

Simple resetting timer method to help lerp between a materials alpha values 1 - 0

I am working on a 'Shield' script (sci-fi, not RPG, imagine a spaceship) that only becomes active once a collision has happened. I'm trying to achieve this by having the alpha value of the material be set to 0f - then once 'hit' going straight up to 1f and then lerping back down to 0f. Rinse, repeat. However i'm having a problem coming up with the timer element of the lerp. The timers i've looked at tend to involve the update method or do not allow me to use it in the lerp. This is my code so far:
using UnityEngine;
using System.Collections;
public class Shield : MonoBehaviour {
public int shieldHealth;
private SpriteRenderer sRend;
private float alpha = 0f;
void Start () {
shieldHealth = 10;
sRend = GetComponentInChildren<SpriteRenderer>();
}
void OnCollisionEnter2D (Collision2D other) {
shieldHealth --;
LerpAlphaOfShield ();
if(shieldHealth <= 0) {
Destroy(this.gameObject);
}
}
void LerpAlphaOfShield () {
float lerp = Mathf.SmoothStep(1.0f, 0.0f, /*missing timer*/);
alpha = Mathf.Lerp(0.0f, 1.0f, lerp);
sRend.material.color = new Color(1, 1, 1, alpha);
}
}
Now i've thought that the SmoothStep part may be unnecessary once I have a timer, however this part I found in another question that was originally a PingPong that allowed the alpha values to go back and forth: I was trying to get it to do it just once then, obviously, reset with a timer.
Thanks in advance for any advice!
SOLUTION
I finally came up with this to reset and trigger again every hit and turn the alpha values of the shield from 1 - 0 in 1 second. If anyone thinks this code that I have could be improved please let me know, I would be very interested!
using UnityEngine;
using System.Collections;
public class Shield : MonoBehaviour {
public int shieldHealth;
private SpriteRenderer sRend;
private float alpha = 0f;
private bool hasCollided = false;
private float timer = 1f;
void Start () {
shieldHealth = 10;
sRend = GetComponentInChildren<SpriteRenderer>();
}
void Update () {
timer -= Time.deltaTime;
if(timer >= 0.001) {
alpha = Mathf.Lerp(0.0f, 1.0f, timer);
sRend.material.color = new Color(1, 1, 1, alpha);
}
if (timer <= 0) {
hasCollided = false;
}
}
void OnCollisionEnter2D (Collision2D other) {
shieldHealth --;
hasCollided = true;
timer = 1f;
if(shieldHealth <= 0) {
Destroy(this.gameObject);
}
}
}
A possible solution is to do this:
public float lerpSpeed = 5f;
float currAlpha;
float goal = 0f;
void Update()
{
currAlpha = Mathf.Lerp(currAlpha, goal, lerpSpeed * Time.deltaTime;
sRend.material.color = new Color(1f, 1f, 1f, alpha);
if(1f - currAlpha > .001f)
{
goal = 0f;
}
}
And then in the OnCollisionEnter2D function set goal = 1f;
lerpSpeed is a variable you can play with to change how fast it lerps.

How to make a GameObject upside down through code?

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);

Categories