Quaternion lerping not working as expected in Unity with c# - c#

I have tried my own methods but I have not been able to get a method that works, here is an example gif: https://gyazo.com/5cd4b74ee45240d3ff9ee13ae6ca6af6
And here is the code that is used in that gif:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class NewBehaviourScript : MonoBehaviour {
public GameObject moving;
float lerpTime = 5f;
float currentLerpTime;
float moveDistance = 10f;
Quaternion startPos;
Quaternion endPos;
protected void Start()
{
startPos = moving.transform.rotation;
endPos = new Quaternion(0, 0, 0, 0);
}
protected void Update()
{
//reset when we press spacebar
if (Input.GetKeyDown(KeyCode.Space))
{
currentLerpTime = 0f;
}
//increment timer once per frame
currentLerpTime += Time.deltaTime;
if (currentLerpTime > lerpTime)
{
currentLerpTime = lerpTime;
}
//lerp!
float perc = currentLerpTime / lerpTime;
print(perc);
moving.transform.rotation = Quaternion.Lerp(startPos, endPos, perc);
}
}
It does not change until it reaches alpha 1 and I'm not sure why.
If you have any clue why it's doing this and know how to help me please write a comment.

Related

How to make an object move endlessly?

I want to move an object from position A to position B on X axis endlessly. But it does move and comeback only once. How to make it continuosly? I've tried Vector3.Lerp or just creating new Vector3 but it only teleports.
`
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingTarget : MonoBehaviour
{
[SerializeField] private Vector3 firstPosition = new Vector3(-14f, 2.5f, 17f);
[SerializeField] private Vector3 secondPosition = new Vector3(14f, 2.5f, 17f);
public float speed = 10f;
void Start()
{
transform.position = firstPosition;
}
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, secondPosition, Time.deltaTime * speed);
if(transform.position == secondPosition)
{
secondPosition = firstPosition;
}
}
}
`
As alternative you could also use Mathf.PingPong like e.g.
// By default afaik a full cycle takes 2 seconds so in order to normalize
// this to one second we will divide by this times 2 later
public float cycleDuration = 1;
private void Update ()
{
transform.position = Vector3.Lerp(firstPosition, secondPosition, Mathf.PingPong(Time.time / (cycleDuration * 2f), 1f));
}
In case your object is spawned later in the game you might want to rather always start at the first position and do
private float timer;
private void Update ()
{
transform.position = Vector3.Lerp(firstPosition, secondPosition, Mathf.PingPong(timer / (cycleDuration * 2f), 1f));
timer += Time.deltaTime;
}
I don't use Unity, but since nobody else answered....
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MovingTarget : MonoBehaviour
{
[SerializeField] private Vector3 firstPosition = new Vector3(-14f, 2.5f, 17f);
[SerializeField] private Vector3 secondPosition = new Vector3(14f, 2.5f, 17f);
private Vector3 target;
public float speed = 10f;
void Start()
{
transform.position = firstPosition;
target = secondPosition;
}
void Update()
{
transform.position = Vector3.MoveTowards(transform.position, target, Time.deltaTime * speed);
if (transform.position == firstPosition)
{
target = secondPosition;
}
else if (transform.position == secondPosition)
{
target = firstPosition;
}
}
}

How to randomly speed up my game object in unity 2D

Hey so I dont know how to implement a random speedup to my gameobject ive been stuck for a while if some would help me it would be very much appericated.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hexagon : MonoBehaviour
{
public Rigidbody2D rb;
public float shrinkSpeed = 3f;
// Start is called before the first frame update
void Start()
{
rb.rotation = Random.Range(0f, 360f);
transform.localScale = Vector3.one * 10f;
}
// Update is called once per frame
void Update()
{
transform.localScale -= Vector3.one * shrinkSpeed * Time.deltaTime * 2;
if(transform.localScale.x <= .05f)
{
Destroy(gameObject);
}
}
}
private void RandomSpeedUp()
{
float minSpeedUp = 1.3f; //30% speed boost
float maxSpeedUp = 1.75f; //75% speed boos
rb.velocity*= Random.Range(minSpeedUp, maxSpeedUp);
}
This should be a good starting point

Unity 2D - Moving Any Object Between Two (or more) Spaces

new Unity person, and new coder in general. I'm trying to have an object move back and forth between two spots. I have it right now going from Point 1 to Point 2, but it stops. I tried a do loop, and to call back the Move() function again but it just froze Unity.
I'm guessing I need some sort of Loop, but not sure where to do it? I wouldn't mind having the ability to add more spots as well. I have waypoints in Unity itself, tied to the Object. Thanks!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZombiePathing : MonoBehaviour
{
[SerializeField] List<Transform> waypoints;
[SerializeField] float moveSpeed = 2f;
int waypointIndex = 0;
void Start()
{
transform.position = waypoints[waypointIndex].transform.position;
}
// Update is called once per frame
void Update()
{
Move();
}
private void Move()
{
if (waypointIndex <= waypoints.Count -1)
{
var targetPosition = waypoints[waypointIndex].transform.position;
var movementThisFrame = moveSpeed * Time.deltaTime;
transform.position = Vector2.MoveTowards
(transform.position, targetPosition, movementThisFrame);
if (transform.position == targetPosition)
{
waypointIndex++;
}
}
}
}
just add an index equal to 1 or -1 depends on the current transform,
I wrote this code very quickly so it's unsorted, and I do my best to make it very close to your code with some edits.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ZombiePathing : MonoBehaviour
{
[SerializeField] List<Transform> waypoints;
[SerializeField] float moveSpeed = 2f;
Vector3 targetPosition;
int waypointIndex = 0;
int index = 1;
void Start()
{
transform.position = waypoints[waypointIndex].position;
UpdateTransform();
}
void Update()
{ transform.position = Vector2.MoveTowards
(transform.position, targetPosition, moveSpeed * Time.deltaTime);
if (transform.position == targetPosition) UpdateTransform();
}
private void UpdateTransform()
{
waypointIndex += index;
targetPosition = waypoints[waypointIndex].position;
if (waypointIndex >= waypoints.Count -1) index = -1;
else if (waypointIndex <= 0 && index == -1)index = 1;
}
}

How To randomize timer duration between two floats

Currently, This code spawns my prefab with only 1 float aka 1 second or w.e. I'm wanting to spawn my prefab between a minimum float and maximum float but not sure what to do because I'm novice and still learning c# and unity.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Spawn : MonoBehaviour
{
[SerializeField]
public GameObject coin;
[SerializeField]
float fTimeIntervals;
[SerializeField]
Vector2 v2SpawnPosJitter;
float fTimer = 0;
public CurrencyManager cm;
// Start is called before the first frame update
void Start()
{
fTimer = fTimeIntervals;
}
// Update is called once per frame
void Update()
{
fTimer -= Time.deltaTime;
if (fTimer <= 0)
{
fTimer = fTimeIntervals;
Vector2 v2SpawnPos = transform.position;
v2SpawnPos += Vector2.right * v2SpawnPosJitter.x * (Random.value - 0.5f);
v2SpawnPos += Vector2.up * v2SpawnPosJitter.y * (Random.value - 0.5f);
GameObject cmscript = Instantiate(coin, v2SpawnPos, Quaternion.identity, GameObject.FindGameObjectWithTag("Canvas").transform);
cmscript.GetComponent<AutoDestroy>().CM = cm;
}
}
}
Split your fTimeIntervals field into a fMaxTimeInterval field and a fMinTimeInterval field then use Random.Range when you reset the timer to set it to a value between those intervals. You can even make a ResetTimer method to do this in Start and Update so if you change how you do it, you only have to change it in one place:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Spawn : MonoBehaviour
{
[SerializeField]
public GameObject coin;
[SerializeField]
float fMinTimeInterval;
[SerializeField]
float fMaxTimeInterval;
[SerializeField]
Vector2 v2SpawnPosJitter;
float fTimer = 0;
public CurrencyManager cm;
// Start is called before the first frame update
void Start()
{
ResetTimer();
}
// Update is called once per frame
void Update()
{
fTimer -= Time.deltaTime;
if (fTimer <= 0)
{
ResetTimer();
Vector2 v2SpawnPos = transform.position;
v2SpawnPos += Vector2.right * v2SpawnPosJitter.x * (Random.value - 0.5f);
v2SpawnPos += Vector2.up * v2SpawnPosJitter.y * (Random.value - 0.5f);
GameObject cmscript = Instantiate(coin, v2SpawnPos, Quaternion.identity, GameObject.FindGameObjectWithTag("Canvas").transform);
cmscript.GetComponent<AutoDestroy>().CM = cm;
}
}
void ResetTimer()
{
fTimer = Random.Range(fMinTimeInterval,fMaxTimeInterval);
}
}
Didn't really understand what you meant, did you mean the timer?
Use random.range if you want a random number between min/max value
https://docs.unity3d.com/ScriptReference/Random.Range.html

How to completely prevent the player from going offscreen in Unity?

For the entire day, I been trying to find a good solution to completely stop the player from going offscreen without hard coding.
I have this script called player controller and all it does so far is allow the player to move along the x-axis. It also has an additional function that clamps the player's movement in the x-axis. Here it is.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public const float MAX_SPEED = 5.0f;
// Update is called once per frame
void Update()
{
transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
clampPlayerMovement();
}
void clampPlayerMovement()
{
Vector3 pos = Camera.main.WorldToViewportPoint(transform.position);
pos.x = Mathf.Clamp01(pos.x);
transform.position = Camera.main.ViewportToWorldPoint(pos);
}
}
The problem with this script is that it doesn't completely stops the player from going offscreen(half of the player's body still goes offscreen).
So this is what I tried next.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public const float MAX_SPEED = 5.0f;
private float xLeft;
private float xRight;
void Start()
{
float pivotX = GetComponent<SpriteRenderer>().sprite.pivot.x;
float pixelsPerunit = GetComponent<SpriteRenderer>().sprite.pixelsPerUnit;
float textureWidth = GetComponent<SpriteRenderer>().sprite.texture.width;
//Units on the left from the sprite's pivot.
xLeft = pivotX / pixelsPerunit;
//Units on the right from the sprite's pivot.
xRight = (textureWidth - pivotX) / pixelsPerunit;
}
// Update is called once per frame
void Update()
{
transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
clampPlayersMovement();
}
void clampPlayersMovement()
{
Vector3 pos = transform.position;
Vector3 posMin = transform.position;
Vector3 posMax = transform.position;
posMin.x = posMin.x - xLeft;
posMax.x = posMax.x + xRight;
pos = Camera.main.WorldToViewportPoint(pos);
posMin = Camera.main.WorldToViewportPoint(posMin);
posMax = Camera.main.WorldToViewportPoint(posMax);
pos.x = Mathf.Clamp(pos.x, posMin.x, posMax.x);
transform.position = Camera.main.ViewportToWorldPoint(pos);
}
}
Unfortunately, this code is no good. In fact, it is even worse because it does not stop the player from going offscreen at all.
So at this point I'm stuck between a rock and a hard place. Any suggestions would be vastly appreciated.
After long searching I finally found an answer.
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public const float MAX_SPEED = 5.0f;
private float halfPlayerSizeX;
void Start()
{
halfPlayerSizeX = GetComponent<SpriteRenderer>().bounds.size.x / 2;
}
// Update is called once per frame
void Update()
{
transform.Translate(Input.GetAxis("Horizontal") * MAX_SPEED * Time.deltaTime, 0.0f, 0.0f);
clampPlayerMovement();
}
void clampPlayerMovement()
{
Vector3 position = transform.position;
float distance = transform.position.z - Camera.main.transform.position.z;
float leftBorder = Camera.main.ViewportToWorldPoint(new Vector3(0, 0, distance)).x + halfPlayerSizeX;
float rightBorder = Camera.main.ViewportToWorldPoint(new Vector3(1, 0, distance)).x - halfPlayerSizeX;
position.x = Mathf.Clamp(position.x, leftBorder, rightBorder);
transform.position = position;
}
}
The only thing that I don't get is why do I need to subtract the z position from both the gameobject and the camera? why not the x position?

Categories

Resources