How to choose when fortune wheel stop in unity? - c#

There is a lot of code about normal fortune wheels but I can't find anything about how to control where the wheel stops?
My fortune wheel should work like this: 1->5,8->12 have a 90% chance that the arrow stops there, 6 has a 1% chance, others have 9%.
And I need it to accumulate and increase during play, example: after 1 turn arrow have 2% chance of stop at 6 instead of 1%.
public List<int> prize;
public List<AnimationCurve> animationCurves;
private bool spinning;
private float anglePerItem;
private int randomTime;
private int itemNumber;
BoxCollider2D m_collider;
void Start()
{
spinning = false;
anglePerItem = 360/prize.Count;
}
void Update()
{
if (Input.GetKeyDown (KeyCode.Space) && !spinning) {
randomTime = Random.Range (1, 4);
itemNumber = Random.Range (0, prize.Count);
float maxAngle = 1080 * randomTime + (itemNumber * anglePerItem);
StartCoroutine (SpinTheWheel (5 * randomTime, maxAngle));
}
}
IEnumerator SpinTheWheel (float time, float maxAngle)
{
spinning = true;
float timer = 0.0f;
float startAngle = transform.eulerAngles.z;
maxAngle = maxAngle - startAngle;
int animationCurveNumber = Random.Range (0, animationCurves.Count);
Debug.Log ("Animation Curve No. : " + animationCurveNumber);
while (timer < time) {
//to calculate rotation
float angle = maxAngle * animationCurves [animationCurveNumber].Evaluate (timer / time) ;
transform.eulerAngles = new Vector3 (0.0f, 0.0f, angle + startAngle);
timer += Time.deltaTime;
yield return 0;
}
transform.eulerAngles = new Vector3 (0.0f, 0.0f, maxAngle + startAngle);
spinning = false;
Debug.Log( itemNumber);
Debug.Log ("Prize: " + prize [itemNumber]);//use prize[itemNumnber] as per requirement
}

First of all: Your percentages don't sum up
if as you describe 1..5 and 8..12 together cover 90% then there is only 10% left to share between 6 and 7.
So from your description each 1,2,3,4,5,8,9,10,11 and 12 would have an indivdual percentage of 9%. 6 would have 1% and since only 9% are left also 7 would have 9%.
I leave it at this for now but you probably will want to fix these weights according to your needs.
What you want then is a weighted random e.g. like
private Dictionary<int, int> weights = new Dictionary<int, int>
{
// Value | Weight TODO: Make sure these sum up to 100
{1, 9},
{2, 9},
{3, 9},
{4, 9},
{5, 9},
{6, 1},
{7, 9},
{8, 9},
{9, 9},
{10, 9},
{11, 9},
{12, 9}
};
// for storing the weighted options
private readonly List<int> weightedOptions = new List<int>();
private void Start()
{
// first fill the randomResults accordingly to the given weights
weightedOptions.Clear();
foreach (var kvp in weights)
{
// add kvp.Key to the list kvp.value times
for (var i = 0; i < kvp.Value; i++)
{
weightedOptions.Add(kvp.Key);
}
}
}
public int GetRandomNumber()
{
// get a random index from 0 to 99 (or how much items you have - 1)
var randomIndex = Random.Range(0, weightedOptions.Count);
// get the according value
return weightedOptions[randomIndex];
}
It is unclear how you then want to implement
after 1 turn arrow have 2% chance of stop at 12 instead of 1%
you can't increase the probability of one single number without decreasing the probability of one or all other numbers at the same time since they always sum up to 100%.
So first think about: Which number(s) should increase its(their) probability and which one(s) should decrease in exchange?
With your code
Now having your actual code I would modify it and implement before mentioned weighted list and then make the rotation pure angle based like
// instead of a Dictionary in order to be able to adjust the values via the Inspector
// (there are also more fancy solutions like SerializedDictionary with a special drawer for this purpose)
[Serializable]
public class WeightedValue
{
public int Value;
public int Weight;
public WeightedValue(int value, int weight)
{
Value = value;
Weight = weight;
}
}
// just a struct to get both the index and value at the same time
private struct RandomInfo
{
public readonly int Index;
public readonly int Value;
public readonly IReadOnlyList<int> WeightedOptions;
public readonly int AmountOfFullRotations;
public RandomInfo(List<int> weightedOptions, int minRotations, int maxRotations)
{
WeightedOptions = weightedOptions;
// get a random index
Index= Random.Range(0, WeightedOptions.Count);
// get the actual according value
Value = WeightedOptions[Index];
AmountOfFullRotations = Random.Range(minRotations, maxRotations);
}
}
public List<WeightedValue> PricesWithWeights = new List<WeightedValue>
{
// Value | Weight TODO: Make sure these sum up to 100
new WeightedValue(1, 9),
new WeightedValue(2, 9),
new WeightedValue(3, 9),
new WeightedValue(4, 9),
new WeightedValue(5, 9),
new WeightedValue(6, 1),
new WeightedValue(7, 9),
new WeightedValue(8, 9),
new WeightedValue(9, 9),
new WeightedValue(10, 9),
new WeightedValue(11, 9),
new WeightedValue(12, 9)
};
// minimum full rotations
// adjust in the Inspector
public int MinRotations = 2;
// maximum full rotations
// adjust in the Inspector
public int MaxRotations = 6;
// seconds one complete rotation shall take
// adjust in the Inspector
public float SpinDuration = 5;
// you can't assign this directly since you want it weighted
private readonly List<int> _weightedList = new List<int>();
private bool _spinning;
private float _anglePerItem;
private void Start()
{
_spinning = false;
_anglePerItem = 360f / PricesWithWeights.Count;
_weightedList.Clear();
// first fill the randomResults accordingly to the given wheights
foreach (var kvp in PricesWithWeights)
{
// add kvp.Key to the list kvp.value times
for (var i = 0; i < kvp.Weight; i++)
{
_weightedList.Add(kvp.Value);
}
}
}
private void Update()
{
// spinning is less expensive to check so do it first
if (!_spinning && Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine(SpinTheWheel());
// or pass in a callback to actually do something with the random result
//StartCoroutine(SpinTheWheel(OptionalCallbackMethod));
}
}
//private void OptionalCallbackMethod(int result)
//{
// Debug.Log($"Congratulations! You just have won option {result}!")
//}
// Selects a random target option and a random amount of full spins before reaching the target
// then internally runs the parameterized overload
private IEnumerator SpinTheWheel(Action<int> onResult = null)
{
// What you had
//itemNumber = Random.Range(0, prize.Count);
// returns a random index .. not the actual value at this index
// this now has all information we need
var randomInfo = new RandomInfo(_weightedList, MinRotations, MaxRotations);
var itemNumberAngle = randomInfo.Index * _anglePerItem;
var currentAngle = transform.eulerAngles.z;
// reset/clamp currentAngle to a value 0-360 since itemNumberAngle will be in this range
while (currentAngle >= 360)
{
currentAngle -= 360;
}
while (currentAngle < 0)
{
currentAngle += 360;
}
// Now we can compose the actual total target rotation
// depends on your setup of course .. For my example below I will use it negative (rotation clockwise) like
var targetAngle = -(itemNumberAngle + 360f * randomInfo.AmountOfFullRotations);
Debug.Log($"Will spin {randomInfo.AmountOfFullRotations} times before ending at {randomInfo.Value} with an angle of {itemNumberAngle}", this);
Debug.Log($"The odds for this were {PricesWithWeights[randomInfo.Index].Weight / (float)PricesWithWeights.Sum(p => p.Weight):P} !");
yield return SpinTheWheel(currentAngle, targetAngle, randomInfo.AmountOfFullRotations * SpinDuration, randomInfo.Value, onResult);
}
// spins the wheel from the given fromAngle until the given toAngle within withinSeconds seconds
// using an eased in and eased out rotation
private IEnumerator SpinTheWheel(float fromAngle, float toAngle, float withinSeconds, int result, Action<int> onResult = null)
{
_spinning = true;
var passedTime = 0f;
while (passedTime < withinSeconds)
{
// here you can use any mathematical curve for easing the animation
// in this case Smoothstep uses a simple ease-in and ease-out
// so the rotation starts slow, reaches a maximum in the middle and ends slow
// you could also e.g. use SmoothDamp to start fast and only end slow
// and you can stack them to amplify their effect
var lerpFactor = Mathf.SmoothStep(0, 1, (Mathf.SmoothStep(0, 1, passedTime / withinSeconds)));
transform.localEulerAngles = new Vector3(0.0f, 0.0f, Mathf.Lerp(fromAngle, toAngle, lerpFactor));
passedTime += Time.deltaTime;
yield return null;
}
transform.eulerAngles = new Vector3(0.0f, 0.0f, toAngle);
_spinning = false;
Debug.Log("Prize: " + result);
// if provided invoke the given callback
onResult?.Invoke(result);
}

Related

Fade out images in order

Is basically a mathematical question, would like to know what would be a good solution.
Problem: I have 25 images placed in one line. I want the images to fade out in the order. That is the first image should be completely opaque and last image should be completely transparent.
I have placed all these images in an order inside one parent.
My solution: I am just providing a fixed number that iterates itself for the alpha.
What I am looking for: a formula so that this "fixed" number can be dynamically changed by number of images present.
void Start () {
int color = 10; //my fixed number
foreach (Transform child in transform) {
child.gameObject.GetComponent<Image>().color = new Color32(255, 255, 255, (byte) (255 - color));
color += 10; //iterating for the next child
}
}
What about simply calculating the step:
void Start ()
{
if(transform.childCount <= 1)
{
Debug.LogWarning("Requires at least 2 children!");
return;
}
var alphaStep = 1f / (transform.childCount - 1);
var alpha = 1f;
foreach (Transform child in transform)
{
child.GetComponent<Image>().color = new Color(1f, 1f, 1f, alpha);
alpha -= alphaStep;
}
}
Or if you want full control over the maximum and minimum alpha you could use e.g.
public float minAlpha = 0f;
public float maxAlpha = 1f;
and then
var alphaStep = 1f / (transform.childCount - 1);
for (var i = 0; i < transform.childCount; i++)
{
var factor = i / (transform.childCount - 1);
transform.GetChild(i).GetComponent<Image>().color = new Color(1f, 1f, 1f, Mathf.Lerp(maxAlpha, minAlpha, factor));
}
I would recomend use an Array to iterate through your elements more freely.
With that you could go something like... (coding in SO, not tested)
Image[] images; //this should reference the array constructed elsewhere where you load the images.
private void Start() {
for (int i = 0; i < images.Length; i++) {
int alpha = 255 - (Mathf.CeilToInt(255 / images.Length) * i + 1);
images[i].color = Color32(255,255,255,alpha);}
}
That will probably do what you want.
By the way, not shure why you using Color32 but working with "float" RGBA will rid you from that ceil and give you more precission.

Tube mesh generation in unity

I've created a procedural mesh script while watching one of Freya Holmér's improvised live course vods, and re purposed the code to create a procedural tube mesh with subdivision and plenty of other niche features.
But, after looking over the code and the lesson, I still cannot for the life of me figure out why sometimes I will get an:
argument out of range exception
...and sometimes I won't depending on the level of subdivision; also, entire faces wont be generated by the script.
TL;DR Problems list:
Argument out of range exception (Depending on level of subdivision).
Entire sides/faces of the tube mesh will not be generated, even when no errors are provided.
These problems are stemming from line 154 in the UpdateTris() method.
Code
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
using OpenNexus.ExtraGizmos;
#endif
using OpenNexus.BaseMath;
using OpenNexus.MeshFormat;
namespace OpenNexus.Procedurals
{
[RequireComponent(typeof(MeshFilter))]
public class TubeMesh : MonoBehaviour
{
private MeshFilter filter;
private Mesh mesh;
public List<Vector3> Points = new List<Vector3>()
{
new Vector3(0, 0, 0),
new Vector3(0, 1, 1),
new Vector3(0, 0, 2)
};
[Header("Bezier Data")]
public Precision BezierPrecision = Precision.Fast;
[Header("Tube Data")]
[Range(0.01f, 1f)]public float Radius = 0.01f;
[Range(3, 32)] public int Segments = 8;
[Range(3, 6)] public int Subdivisions = 3;
[Header("Mesh Data")]
public ProceduralMesh2D BaseProceduralMesh = new ProceduralMesh2D();
public List<Vector3> Vertices;
public List<int> Tris;
private void OnEnable()
{
if (!GetComponent<MeshRenderer>()) // Check for and add missing mesh renderer.
gameObject.AddComponent<MeshRenderer>();
if (filter == null) // Check for and assign mesh filter variable.
filter = GetComponent<MeshFilter>();
if (mesh == null) // Check for and instantiate a new mesh object.
mesh = new Mesh();
mesh.name = "TubeMesh"; // Set name to mesh object.
filter.sharedMesh = mesh; // Set MeshFilter's shared mesh variable to new mesh object.
}
private void Update()
{
/*
Data reset
------------------------------
*/
// Reset base mesh data.
BaseProceduralMesh.Vertices = new List<Vertex>();
BaseProceduralMesh.LineIndex = new List<int>();
// Reset mesh data.
Vertices = new List<Vector3>();
Tris = new List<int>();
/*
Data update
------------------------------
*/
// Update base mesh.
UpdateBaseMesh();
// Update mesh data.
UpdateVertices();
UpdateTris();
}
private void LateUpdate() => UpdateMesh();
private BezierPoint GetBezierPoint(int index)
{
float _t = index / (Segments - 1f);
BezierPoint _bp = BezierMath.QuadraticBezier(Points, BezierPrecision, _t);
return _bp;
}
private void UpdateBaseMesh()
{
// Generate base vertices.
for (int i = 0; i < Subdivisions; i++)
{
float _point = i / (float)Subdivisions;
float _radius = _point * Floats.TAU;
Vertex _vertex = new Vertex(VectorThrees.UnitVectorByAngle(_radius) * Radius);
BaseProceduralMesh.Vertices.Add(_vertex);
}
// Generate base LineIndexes.
for (int i = 0; i < BaseProceduralMesh.VertexCount; i++)
{
BaseProceduralMesh.LineIndex.Add(i);
}
BaseProceduralMesh.LineIndex.Add(0);
}
private void UpdateVertices()
{
for (int i = 0; i < Segments; i++)
{
BezierPoint _point = GetBezierPoint(i);
for (int j = 0; j < BaseProceduralMesh.VertexCount; j++)
{
Vertices.Add(_point.LocalToWorldPosition(BaseProceduralMesh.Vertices[j].Point));
}
}
}
private void UpdateTris()
{
for (int s = 0; s < Segments - 1; s++)
{
int _root = s * BaseProceduralMesh.VertexCount;
int _rootNext = (s + 1) * BaseProceduralMesh.VertexCount;
for (int i = 0; i < BaseProceduralMesh.EdgeCount; i+=2)
{
int _lineA = BaseProceduralMesh.LineIndex[i];
int _lineB = BaseProceduralMesh.LineIndex[i + 1];
int _currentA = _root + _lineA;
int _currentB = _root + _lineB;
int _nextA = _rootNext + _lineA;
int _nextB = _rootNext + _lineB;
Tris.Add(_currentA);
Tris.Add(_nextA);
Tris.Add(_nextB);
Tris.Add(_currentA);
Tris.Add(_nextB);
Tris.Add(_currentB);
}
}
}
private void UpdateMesh()
{
mesh.Clear();
mesh.SetVertices(Vertices);
mesh.SetTriangles(Tris, 0);
mesh.RecalculateNormals();
}
#if UNITY_EDITOR
private void OnDrawGizmos()
{
// Draw psudo mesh with gizmos.
/*
Draw segment/edge loops
-------------------------------------
*/
for (int i = 0; i < Segments; i++) // Debug each segment, and what their 2D mesh segment should look like.
{
BezierPoint _point = GetBezierPoint(i);
WireGizmos.DrawWireCircle(_point.Position, _point.Rotation, Radius, Subdivisions);
}
Gizmos.color = Color.red;
for (int i = 0; i < Vertices.Count; i++) // Debug each vertex.
{
Gizmos.DrawSphere(Vertices[i], 0.01f);
Handles.Label(Vertices[i], "\n\nVertex: " + i + "\n\nVertex position:\n" + Vertices[i].ToString());
}
for (int i = 0; i < Tris.Count; i++)
{
Gizmos.DrawLine(Vertices[Tris[i]], Vertices[Tris[(i + 1) % Tris.Count]]);
}
}
#endif
}
}
I've already looked over my code compared to the code in the video, it's fundamentally the same, with the main differences being, how I'm creating the 2D mesh format for the script to work with, and the structure of the code.
After looking back at what they had done compared to mine, I just don't see how I'm running into this issue.
Things I've tried
Change the loop iteration i+=2 -to- i++ (This spits out the exception, but generates the first section of the tube before getting stuck between the second vertex in the next segment, and vert 0).
Every suggestion I try from this question, I will update the "Things I've tried..." list.
Please let me know if I need to clarify anything in this post, and if you wish to see the other classes/structs referenced in this script.
After a day of resting, and the a couple of hours of testing different values and questioning the code. I've found the problem.
The real issue
The nested for loop in the UpdateTris() method was going up by twos assuming I was making a hard edge mesh with pared vertices. This caused the loop to skip over an entire face of the mesh, and causing the
ArgumentOutOfRangeException
...when the Subdivision value was an even number.
My solution
I had to bring it back to the default single iteration (since I was trying to make a smooth lighting mesh), the second issue with the for loop was the iteration limit BaseProceduralMesh.LineCount needing to be subtracted by one since that was causing another
ArgumentOutOfRangeException

Place 3 Objects Randomly In 3 Specified Positions in Unity3D

How do I place 3 gameobjects in random positions range without any of the object having same position as the other 2? How do I achieve this?
So far..
public GameObject[] sprites;
int[] Position = new int[3] { 0, 5, -5 };
int resultSprite1;
int resultSprite2;
int resultSprite3;
int y;
int z;
Vector3 pos;
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.R))
{
resultSprite1 = Position[Random.Range(0, Position.Length)];
y = 0;
z = 0;
pos = new Vector3(resultSprite1, y, z);
sprites[0].transform.position = pos;
resultSprite2 = Position[Random.Range(0, Position.Length)];
y = 0;
z = 0;
pos = new Vector3(resultSprite2, y, z);
sprites[1].transform.position = pos;
resultSprite3 = Position[Random.Range(0, Position.Length)];
y = 0;
z = 0;
pos = new Vector3(resultSprite3, y, z);
sprites[2].transform.position = pos;
}
}
How to achieve this so that no two objects share same positions. All of them should be independent of one another.
Thanks.
List<int> usedNumbers = new List<int> ();
void Update ()
{
if (Input.GetKeyDown (KeyCode.R))
{
//Since it works on update. You should clear the last list before creating a new one.
usedNumbers.Clear();
for (int i = 0; i < Position.Length; i++)
{
do
{
number = Random.Range (0, Position.Length);
} while (usedNumbers.Contains (number));
//You have your unique number here.
sprites[i].transform.position = new Vector3 (Position[number], 0f, 0f);
//Do not forget to store your number in usedNumbersList.
usedNumbers.Add (number);
}
}
}

How to assign integers to objects in a list?

So I've got objects in a list, and I'm trying to assign an angle to each to travel at. Currently I've got two lists:
List<double> BulletAngles = new List<double>();
List<OvalShape> Bullets = new List<OvalShape>();
My view on how lists work is obviously very off. Right now the bullets are traveling based on this code:
foreach (OvalShape b in Bullets)
{
int i = Bullets.IndexOf(b);
if (b.Location.X > -10 && b.Location.X < (this.Width - 6) + 10
&& b.Location.Y > -10 && b.Location.Y < (this.Height - 30) + 10)
{
b.Left += Convert.ToInt32(bulletSpeed * Math.Cos(BulletAngles[i]));
b.Top += Convert.ToInt32(bulletSpeed * Math.Sin(BulletAngles[i]));
}
}
The angle is all based on the mouses position when clicking, but when testing this, all bullets go in the direction of the first mouse click.
Here is also the code for setting the angle and placing in the bullet:
Point target = new Point(mousePos.X - origin.X, mousePos.Y - origin.Y);
OvalShape g = Bullet;
double y = Math.Atan2(target.Y, target.X);
g.Left = origin.X - (g.Width / 2);
g.Top = origin.Y - (g.Height / 2);
g.Visible = true;
BulletAngles.Add(y);
Bullets.Add(g);
Using the IndexOf method might not return the result you are looking for as this method determines equality using the default equality comparer.
While having properties relating to an object in two separate lists is problematic and would be better resolved by encapsulating the properties into a single object as suggested before. If you are trying get the index of an object as you iterate through a list it might be better to use a for statement instead of a foreach statement.
for (int index = 0; index < Bullets.Count; index++)
{
var b = Bullets[index];
if (b.Location.X > -10 && b.Location.X < (this.Width - 6) + 10
&& b.Location.Y > -10 && b.Location.Y < (this.Height - 30) + 10)
{
b.Left += Convert.ToInt32(bulletSpeed*Math.Cos(BulletAngles[index]));
b.Top += Convert.ToInt32(bulletSpeed * Math.Sin(BulletAngles[index]));
}
}
Here is an example using encapsulation:
public class OvalShapeBullet
{
private readonly OvalShape _ovalShape;
private Point _location;
private readonly double _angle;
private double _distance;
public OvalShapeBullet(Point orgin, Point target, OvalShape ovalShape)
{
_ovalShape = ovalShape;
_location = new Point(orgin.X - ((int)ovalShape.Width / 2), orgin.Y - ((int)ovalShape.Height / 2));
_distance = Math.Sqrt((orgin.X - target.X) ^ 2 + (orgin.Y - target.Y) ^ 2);
_angle = Math.Atan2(target.Y, target.X);
}
public Point Location { get { return _location; } }
public bool Visible
{
get { return _ovalShape.Visible; }
set { _ovalShape.Visible = value; }
}
/// <summary>
/// Attempts to move bullet to target
/// </summary>
/// <param name="distance">The distance the bullt will travel</param>
/// <returns>True if bullet connects with target</returns>
public bool TryMoveToTarget(float distance)
{
if (_distance <= 0)
return true; // check if bullet has travelled far enough
_location.X += (int)(distance * Math.Cos(_angle));
_location.Y += (int)(distance * Math.Sin(_angle));
_distance -= distance;
return _distance <= 0; // check if bullet has traveled far enough
}
}
Your code then becomes cleaner as the original statements become a single list declaration
List<OvalShapeBullet> Bullets = new List<OvalShapeBullet>();
Handling of creating a new object
Point target = new Point(mousePos.X - origin.X, mousePos.Y - origin.Y);
OvalShapeBullet g = new OvalShapeBullet(mousePos, target, Bullet);
g.Visible = true;
Bullets.Add(g);
and managing the movement of the bullets and checking for target connection
foreach (OvalShapeBullet b in Bullets)
{
if (b.TryMoveToTarget(bulletSpeed))
{
// handle bullet has hit the target
Bullets.Remove(b);
}
}

Sun Script RenderProbe on time of day

I'm tring to make a unity sun script that renders the light probe at certain time of the day taken from an array.
The day is from 0-1 interval ( 0 night, 0.25 sunrise, 0.5 midday, 0.75 sunset, 1 night)
To be honest even if I check the statement currentTimeOfDay == 0.75 when the value is reached the print does not occur
And how do I check the statement for multiple array?
public float secondsInFullDay = 120f;
[Range(0,1)]
public float currentTimeOfDay = 0f;
private float[] floatDay = new float[4] {0f, 0.25f, 0.5f, 0.75f};
public float timeMultiplier = 1f;
void Update() {
currentTimeOfDay += (Time.deltaTime / secondsInFullDay) * timeMultiplier;
if (currentTimeOfDay >= 1) {
currentTimeOfDay = 0;
}
if(currentTimeOfDay == floatDay[0]){
reflectionProbe.RenderProbe();
print ("refresh probe");
}
}
This only prints at 0 value
foreach (float x in floatDay){
if (x.Equals (currentTimeOfDay)){
print ("refresh probe");
}
}
L.E
I managed to check the statement against array but it prints multiple times that means that will cause unnecessary load
If the time timeMultiplier is set to 10 instead of 1 then the print is one time when reached the value.
Is there a way to multiply the array with a float and get new array?
private float[] floatDay = new float[4] {0, 250, 500, 750};
TimeOfDay = currentTimeOfDay * 1000 * timeMultiplier;
TimeOfDay = Mathf.Round(TimeOfDay);
foreach (float x in floatDay){
if (TimeOfDay == x){
reflectionProbe.RenderProbe();
print ("refresh probe");
}
}
L.E 2
fixed it , but doesn't seem that compact but it works
private float[] floatDay = new float[4] {0, 2500, 5000, 7500};
TimeOfDay = currentTimeOfDay * 10000 / timeMultiplier;
TimeOfDay = Mathf.Round(TimeOfDay);
foreach (float x in floatDay){
float y = x / timeMultiplier;
if (TimeOfDay == y){
reflectionProbe.RenderProbe();
print ("refresh probe");
}
}
This only prints at 0 value
foreach (float x in floatDay){
if (x.Equals (currentTimeOfDay)){
print ("refresh probe");
}
}
because floating points are never accurate. Your value in never exactly equal to the value you compare it to.
Use this instead:
foreach (float x in floatDay){
if (x > currentTimeOfDay - 1e-7f && x < currentTimeOfDay + 1e-7f){
print ("refresh probe");
}
}
if it still doesn't work, change 1e-7f to 1e-6f, 1e-5f, etc...

Categories