I have an integer that updates itself from 0 - 599 which I'm trying to normalize and pass to another variable. My first integer value is just a single int. It isn't in a list or anything.
What I'm trying to do is tie in a color lerp time length based on the length of integer value. This integer value is iterating through a list of meshes to be displayed. It looks like this:
int meshNum;
public void AnimateMesh()
{
if(playAnim)
{
meshToChange.GetComponent<MeshFilter>().mesh = fluidMesh[meshNum];
if(meshNum < 599)
meshNum++;
else
meshNum = 0;
}
else
{
meshNum = 0;
}
}
And my lerp code for the color is this:
diffuse_Material.color = Color.Lerp(Color.blue, Color.red, speedCount);
What I'm wanting to change speedCount in my lerp method to a variable that is matched with the length of the animation. My lerp isn't always on screen, but the animation is, when I want the lerp to appear, I want to it be the same each time it appears no matter where the animation currently is.
Color.Lerp expects a parameter from 0 .. 1. The simplest way would be to simply give it (float)meshNum / 599f.
float number = (float)randomizedNumber / 599.0f;
since your max value is 599, anyway this color difference would'nt be noticed or event will be rounded since RGB has only 256 values for eash base color.
Related
I`m making a 2d game based on levels in which, each level, you have three checkpoints in the score tracking bar. The player must reach the lowest checkpoint to be able to pass to the next level, but will get a bonus if he reaches the 2nd and 3rd checkpoints.
I tought on using a Slider as the scoring bar. My question is:
Is there a way to store a specific value of the Slider's bar in the Start method and Instantiate a marker prefab at that position? Here's an example:
The Max Value of the Slider at Level 1 is 100.
I want to Instantiate the first marker, with some padding in the y, in the 50`s position of the slider, the second in the 75 position and the third in the 100 position.
My current logic is that I need to, somehow, get the value I want and find his Transform, but I can`t find a way to code this, I have no idea how to get the position I want.
Here are some images to illustrate what i`m trying to do:
i would get the width attribute of the slider, then divide that by sliderMax, the result will be the the width of a single % on the slider. you can then add or subract multiple of this to get a percentages place on the bar.
example: slider.x=50
slider.width=200;
increment = slider.width/100; //this will result in two, giving you two pixels per percent.
so your 50 percent placement would be: sliderx+(increment*50);
keep in mind this is all pseudo code, designed to give you an idea of how to acheive your desired result
I found the solution!
Based on the insights i managed to do this:
void SpawnCheckPoint() {
mySlider.maxValue = gameLevel[currentLevel].maxValue; //Set the slider's Max Value to the max value of the level.
float sliderMaxValue = mySlider.maxValue;
float sliderWidth = slider.GetComponent<RectTransform>().sizeDelta.x; //Get the width of the Slider.
float zeroValue = slider.transform.position.x - (sliderWidth / 2); //Get the leftmost corner of the slider.
//Loop to Instantiate the 3 checkpoints.
for (int i = 0; i < gameLevel[currentLevel].values.Length; i++) {
float valueToIncrement = (gameLevel[currentLevel].values[i] / sliderMaxValue); //Get the % of the checkpoint based on the max value of the level.
float newPos = (sliderWidth * valueToIncrement); //New position in screen
//Instantiate the object as a child of the Slider
GameObject checkpoint = Instantiate(checkPoint, new Vector3(zeroValue + newPos - xPadding, slider.transform.position.y - yPadding, slider.transform.position.z),
Quaternion.identity, GameObject.FindGameObjectWithTag("Slider").transform);
}
}
It's probably not the best way to do what i want but it's working just fine.
Thank you all who tried to help me, your insights were very useful.
I am currently working on a dynamic skybox. My skybox is composed of 3 separate scripts:
CustomList ,CustomListEditor., TOD.CS
CustomList.cs has class that stores variables for what each variable will be at a specific time. Example: time, cloud color horizon color ect.
CustomListEditor.cs is a custom inspector to set values and Add/Remove them to a list of Times of Day (TOD).
TOD.cs is where am calculating time passing and lerping variables from one TOD to another.
The problem I am currently having: I am unable to evenly lerp each TOD. basically the problem I am having is that my lerp is not running smoothly between each Time of Day and is instead having portions that run slower and some that run faster. I Acknowledge this is a Math problem and I am not entirely sure how to go about getting the correct equation to make this work properly.
if anyone could help that would be amazing. Here is an i drew up of time and the separate time of days. keep in mind the TOD's could be placed anywhere in time so the number values are not definite in the example.
<!-- language: lang-c# -->
public float TODspeed = 0.02
private float currentValue = 0.00f
public int TODindex = 0;
public Color horizon;
void Start()
{
GetTarget = new SerializedObject(this.GetComponent<CustomList>());
ThisList = GetTarget.FindProperty("MyList"); // Find the List in our script and create a refrence of it
SerializedProperty MyListRef = ThisList.GetArrayElementAtIndex(TODindex);
SerializedProperty myHorizon = MyListRef.FindPropertyRelative("horizon");
horizon = myHorizon.colorValue;
}
void Update()
{
//Grab serialized properties from my List
//MyListRef is getting a reference of the current TOD
SerializedProperty MyListRef = ThisList.GetArrayElementAtIndex(TODindex);
//NextListRef is getting a reference of the next TOD that we will be lerping to.
SerializedProperty NextListRef = ThisList.GetArrayElementAtIndex(TODindex + 1);
SerializedProperty myTime = NextListRef.FindPropertyRelative("time");
//mixTime is supposed to be my equation for the speed of the times of day. I presume that this code is incorrect and I have no idea how to fix it.
float mixTime = TODspeed * (myTime.floatValue - MyListRef.FindPropertyRelative("time").floatValue);
//This is where I lerp my TOD variables, so long as CurrentValue ,which is the game time, is less than the next TOD's time value.
if (currentValue < myTime.floatValue)
{
currentValue += (Time.deltaTime*TODspeed);
horizon = Color.Lerp(horizon, nextHorizon.colorValue, mixTime);
this.GetComponent<CustomList>().atmosphereGradient.SetColor("_BottomColor", horizon);
}
// if game time is greater than my next TOD's time variable, It will compare the TODIndex to what would be the last TOD in the script. If it is smaller than the last TOD it will incriment , If it is bigger or equal to it, it will restart to time of days.
if (currentValue >= myTime.floatValue)
{
int compareValue = ThisList.arraySize - 2;
if (TODindex < compareValue)
{
TODindex++;
}
else if (TODindex >= compareValue)
{
TODindex = 0;
currentValue = 0.00f;
}
}
}
Your problem is in the line
horizon = Color.Lerp(horizon, nextHorizon.colorValue, mixTime);
you allways interpolate between the current value and the target value => the difference between those is everytime smaller => the "fading" gets slower an slower in time.
What you want to do instead is a constant fading between the original and the target value. I don't see where horizon is declared but you should instead store the original Color outside of Update e.g. as startColor and than change your line to
horizon = Color.Lerp(startColor, nextHorizon.colorValue, mixTime);
Note: I don't completely understand the rest of your code but as I understood your problem was mostly the lerping effect so I assumed that the rest works fine.
I have a trackbar associated with a picture box where I am drawing an image based on the selected zoom factor. The range is from 1% to 1,000% so the lower you slide it, the faster it appears to zoom out.
This is expected but not desired. Is there a way to scale interpret the slider values so that zooming appears more natural to the user, specially in the < 50% range.
This is easily done:
myTrackBar.Minimum = 0;
myTrackBar.Maximim = 3000;
...
public double RealValue
{
get
{
var trackPos = myTrackBar.Value;
return Math.Pow(10.0, trackPos / 1000.0);
}
set
{
var logValue = Math.Log10(value) * 1000;
myTrackBar.Value = (int) logValue;
}
}
To understand how this works, consider your range - 1 to 1000, or expressed as powers of 10 it is 1e0 to 1e3. Hence if we give the track bar a range from 0 to 3 and raise 10 to the value, we get a nice exponential set of values, just like you want.
But if we set the range to 0..3 we could only select from 4 different values: 0, 1, 2, 3 which would translate into 1, 10, 100 and 100 respectively.
To give us values inbetween, we simply multiply the range by a thousand, giving us 3001 different values that the track bar can keep track off, and then divide the trackbar's value by a thousand.
I'm having a small problem with this function, MathHelper.Lerp(float f1, float f2, float amount). What I'm trying to accomplish is this: I'm having a DataTable in my program with angles and a value correspinding towards this angle value. When you choose an angle not present in the Table I want to use Linear Interpolation to manage this. I want something to replace my first implementation of this which looked like this:
else if(angle >= 50 && marklast < 65)
{
DataRow row1 = table.Rows.Find(50);
DataRow row2 = table.Rows.Find(65);
someVariable = SomeMethod(row1, row2);
}
So now I have a lot of these If statments and would like an other way of doing this with the MathHelper.Lerp, problem is I'm having a hard time getting the function, what is amount? And would you modify this in a good way for my implementation?
Amount is a value in 0..1 range.
if it is 0 lerp return source value,
if it is 1 lerp return target value,
if it is a value between 0..1 lerp will return a linear interpolated value between the source and the target values.
I'm not sure you want to do... I think is something like this:
Amount = (angle - 50)/(65-50);
InterpolatedValue = MathHelper.Lerp(row1.Value, row2.Value, Amount);
I am trying to write my own Game of Life, with my own set of rules. First 'concept', which I would like to apply, is socialization (which basicaly means if the cell wants to be alone or in a group with other cells). Data structure is 2-dimensional array (for now).
In order to be able to move a cell to/away from a group of another cells, I need to determine where to move it. The idea is, that I evaluate all the cells in the area (neighbours) and get a vector, which tells me where to move the cell. Size of the vector is 0 or 1 (don't move or move) and the angle is array of directions (up, down, right, left).
This is a image with representation of forces to a cell, like I imagined it (but reach could be more than 5):
Let's for example take this picture:
Forces from lower left neighbour: down (0), up (2), right (2), left (0)
Forces from right neighbour : down (0), up (0), right (0), left (2)
sum : down (0), up (2), right (0), left (0)
So the cell should go up.
I could write an algorithm with a lot of if statements and check all cells in the neighbourhood. Of course this algorithm would be easiest if the 'reach' parameter is set to 1 (first column on picture 1). But what if I change reach parameter to 10 for example? I would need to write an algorithm for each 'reach' parameter in advance... How can I avoid this (notice, that the force is growing potentialy (1, 2, 4, 8, 16, 32,...))? Can I use specific design pattern for this problem?
Also: the most important thing is not speed, but to be able to extend initial logic.
Things to take into consideration:
reach should be passed as a parameter
i would like to change function, which calculates force (potential, fibonacci)
a cell can go to a new place only if this new place is not populated
watch for corners (you can't evaluate right and top neighbours in top-right corner for example)
It should not be difficult to write your algorithm to search all of the cells within the reach distance of a particular cell C. Each cell that has an inhabitant would have a particular force of repulsion on cell C. This force of repulsion is based on the distance from the cell to cell C. In the example that you have given, that force of repulsion is based upon the L-1 distance and is 2^(reach-distance). Each repulsion force is then added together to create a cumulative force that dictates the direction in which to move the inhabitant in cell C.
You do not need to write an algorithm for each different reach. The magnitude of the force can be determined via a simple formula. If you change that formula to something else such as a Fibonacci number, you should still be able to calculate the magnitude as needed based upon the distance and the reach.
Here is some rough code written in pseudo-Java showing the basic ideas: http://codepad.org/K6zxnOAx
enum Direction {Left, Right, Up, Down, None};
Direction push(boolean board[][], int testX, int testY, int reach)
{
int xWeight = 0;
int yWeight = 0;
for (int xDist=-reach; xDist<=+reach; ++xDist)
{
for (int yDist=-reach; yDist<=+reach; ++yDist)
{
int normDist = abs(xDist) + abs(yDist);
if (0<normDist && normDist<reach)
{
int x = testX + xDist;
int y = testY + yDist;
if (0<=x && x<board.length && 0<=y && y<board[0].length)
{
if (board[x][y])
{
int force = getForceMagnitude(reach, normDist);
xWeight += sign(xDist) * force;
yWeight += sign(yDist) * force;
}
}
}
}
}
if (xWeight==0 && yWeight==0) return Direction.None;
if (abs(xWeight) > abs(yWeight))
{
return xWeight<0 ? Direction.Left : Direction.Right;
}
else
{
return yWeight<0 ? Direction.Up : Direction.Down;
}
}
int getForceMagnitude(int reach, int distance)
{
return 1<<(reach-distance);
}
Write a function to loop over the neighbors:
Use min/max to clamp the bounds of the matrix.
Use a for loop to loop over all neighbors.
Modify the for loop bounds to represent reach.
:
def CalculateForceOnCell(x, y):
force_on_x_y = [0,0,0,0]
for i in range(max(0, x-reach), min(WIDTH, x+reach)+1):
limited_reach = reach - abs(x-i)
for j in range(max(0, y - limited_reach), min(HEIGHT, y + limited_reach + 1)):
force_coefficient = limited_reach + 1
AddNeighborForce(force_on_x_y, (x, y), (i, j), force_coefficient)
return force_on_x_y