Comments and answers for "Crosshair Sway"
http://answers.unity.com/questions/1253748/crosshair-sway.html
The latest comments and answers for the question "Crosshair Sway"Comment by Cresspresso on Cresspresso's comment
http://answers.unity.com/comments/1254140/view.html
No problemSun, 09 Oct 2016 18:42:17 GMTCresspressoComment by splitter20 on splitter20's answer
http://answers.unity.com/comments/1254075/view.html
Thank you again! It all works perfect. I'm not sure how or if I can Accept/Upvote the commented script, but thank you nonetheless. I truly didn't even think about adding a timer to keep track of the script time.Sun, 09 Oct 2016 15:25:58 GMTsplitter20Comment by Cresspresso on Cresspresso's comment
http://answers.unity.com/comments/1253900/view.html
I have reworked it from scratch. When breath is held, it will instantly stop moving, and when breath is no longer held it will continue from where it left off.
When the script is enabled (zoom in) it will begin its sway from a random position. When it is disabled (zoom out) it will re-center the camera.
I also changed the amplitude to be randomly chosen from just positive values; a range of both negative and positive values can make jagged movements.
using UnityEngine;
public class Sway : MonoBehaviour
{
public float speed = 0.7f;
float maxRotationy = 1f;
float maxRotationx = 1f;
public float amplitude;
public bool holdBreath = true;
private float timeElapsed = 0f;
void OnEnable()
{
timeElapsed = Time.time; // set to Time.time or any random value
UpdateRotation();
}
void OnDisable()
{
transform.localRotation = Quaternion.identity; // re-center camera when zoomed out
}
void Update()
{
if (!holdBreath)
timeElapsed += Time.deltaTime; // only increase elapsed time if not holding breath
UpdateRotation();
}
void UpdateRotation()
{
transform.localRotation = Quaternion.Euler(maxRotationx * Mathf.Sin(timeElapsed * speed * 2) * amplitude, maxRotationy * Mathf.Sin(timeElapsed * speed), 0f);
if (transform.localRotation.eulerAngles.x <= 0.005f && transform.rotation.eulerAngles.x >= -0.005f)
{
amplitude = Random.Range(0.1f, 0.5f);
}
}
}Sun, 09 Oct 2016 06:18:30 GMTCresspressoComment by splitter20 on splitter20's answer
http://answers.unity.com/comments/1253869/view.html
The only problem is when bool HoldBreath is true the crosshair is centered. I am trying to freeze/hold the exact position when HoldBreath was set true and then continue back on the sway once it is set false. If I set eulerangles to transform.rotation when holdbreath is true, it goes back to snapping.Sun, 09 Oct 2016 03:38:16 GMTsplitter20Comment by splitter20 on splitter20's answer
http://answers.unity.com/comments/1253865/view.html
You were spot on with this answer for what I am trying to accomplish. The Time.time and fraction really made it work and there is no more snapping. Thank you for your response!Sun, 09 Oct 2016 03:15:00 GMTsplitter20Answer by Cresspresso
http://answers.unity.com/answers/1253781/view.html
This is my first time answering a question on Unity Answers, so here goes.
The problem with the 'sine wave continuing to run' is that you are passing Time.time into the Mathf.Sin function.
One way to overcome this problem is to reset the camera's local rotation to look straight forward when holdBreath is true. To make the transition seem smooth, we can set a float 'fraction' to multiply by maxRotationx/y, so when fraction==0 the camera is centered, and when fraction==1 it is at maximum sway.
Add these fields below [ public bool holdBreath = true; ]
public float returnTime = 0.5f;
private float fraction = 0f;
Then add these in Update()
if (holdBreath)
fraction = Mathf.Clamp(fraction - 1f/returnTime * Time.deltaTime, 0f, 1f);
else
fraction = Mathf.Clamp(fraction + 1f/returnTime * Time.deltaTime, 0f, 1f);
Then change the original [ if (!holdBreath) ] to
if (fraction > 0f)
And then multiply the x and y components by [ fraction ] like so
transform.localRotation = Quaternion.Euler(maxRotationx * Mathf.Sin(Time.time * speed * 2) * amplitude * fraction, maxRotationy * Mathf.Sin(Time.time * speed) * fraction, 0f);
And if the script is disabled, we need to re-center the camera. Replace OnEnabled() with this
void OnDisable()
{
transform.localRotation = Quaternion.identity;
fraction = 0f;
}
The final script should look like this
using UnityEngine;
public class Sway : MonoBehaviour
{
public float speed = 0.7f;
float maxRotationy = 1f;
float maxRotationx = 1f;
public float amplitude;
public bool holdBreath = true;
public float returnTime = 0.5f;
private float fraction = 0f;
void OnDisable()
{
transform.localRotation = Quaternion.identity;
fraction = 0f;
}
void Update()
{
if (holdBreath)
{
fraction = Mathf.Clamp(fraction - 1f/returnTime * Time.deltaTime, 0f, 1f);
}
else
{
fraction = Mathf.Clamp(fraction + 1f/returnTime * Time.deltaTime, 0f, 1f);
}
if (fraction > 0f)
{
transform.localRotation = Quaternion.Euler(maxRotationx * Mathf.Sin(Time.time * speed * 2) * amplitude * fraction, maxRotationy * Mathf.Sin(Time.time * speed) * fraction, 0f);
if (transform.localRotation.eulerAngles.x <= 0.005f && transform.rotation.eulerAngles.x >= -0.005f)
{
amplitude = Random.Range(-0.25f, 0.5f);
}
}
}
}
'fraction' could be smoothed with an AnimationCurve, but those are the basics.Sat, 08 Oct 2016 21:49:41 GMTCresspresso