Unity | Get height from Heightmap at current mouse poisition - c#

I wanted to develop a small game. In this game I wanted to include a procedural map generation. It all worked great.
But now I want to find out the height of the heightmap at the mouse position and that doesn't make any sense and I don't understand it
Here a example:
Heightmap
I wrote this script in the void Update()
if (Input.GetMouseButtonDown(0))
{
Vector3 mousePos = Input.mousePosition;
float x = (mousePos.x / Screen.width) * mapWidth;
float y = (mousePos.y / Screen.height) * mapHeight;
//get height at mouse position
float[,] noiseMap = Noise.GenerateNoiseMap (mapWidth, mapHeight, seed, noiseScale, octaves, persistance, lacunarity, offset);
float height = noiseMap[(int)x, (int)y];
Debug.Log(height);
}
When I try this script above I get very strange values.
Like:
Here at a very black or high place i get: 0.5208731
And here at a white place i get: 0.7484959
But then:
at this white place i get: 0.2161063
Something isn't working here and i don't understand it.

Related

Drawing collider boundaries (Unity)

everyone!
I ran into the problem. I need to draw a radius of enemy attack. The radius needs to be equal radius of SphereCollider that is hanging on it. I've tried to do it with the help of LineRenderer which draws circle. Yeah, actually it draws circle correctly, but the radius of my circle is less than radius of collider on it, despite the fact that I've given the value of a variable from the GetComponent().
Does anyone know what the problem is?
Part of my code:
float x;
float z;
float change = 2 * (float)Math.PI / segments;
float angle = change;
x = Mathf.Sin(angle) * radius;
_line.SetPosition(0, new Vector3(x, 0, Mathf.Cos(angle) * radius));
for (int i = 1; i < (segments + + 2); i++)
{
x = Mathf.Sin(angle) * radius;
z = Mathf.Cos(angle) * radius;
yield return new WaitForSeconds(drawSpeed);
_line.SetPosition((int)i, new Vector3(x, 0, z));
angle += change;
}
In the comments you mentioned that you get your radius from
float radius = _collider.radius;
where _collider is your SphereCollider.
So note that the SphereCollider.radius
The radius of the sphere measured in the object's local space.
The sphere radius will be scaled by the transform's scale.
It appears to me that either your object or one of its parent is somehow scaled differently than 1,1,1 in which case the actual final radius will be influenced by that scale.
You would need to scale the radius accordingly by the transform.lossyScale like e.g.
// Get the lossyScale
// this is the localScale of all parent objects and this localScale combined
var lossyScale = _collider.transform.lossyScale;
// find the biggest extends of the lossyScale
// if you already know they are always equal anyway simply use e.g. lossyScale.x instead
float maxScale = 0;
for(var i = 0; i < 3; i++)
{
maxScale = Mathf.Max(maxScale, Mathf.Abs(lossyScale[i]);
}
float radius = _collider.radius * maxScale;
It's a little hacky, but I've used a sphere outline sprite for just this sort of thing. Just put it on the game object and make sure it is scaled same as your collider. No need for fancy line drawing.
Don't use collider component for the enemy attack range!
Instead of adding a circle collider component you should a collider via code & physics.
What should you do?
This is an example of using a collider via code & physics:
float theCircleRadios = /* You radios */;
Collider2D[] detectedEnemiesColliders = Physics2D.OverlapCircleAll(theCirclePosition, theCircleRadios, DetectedLayers);
Then make your line lineRenderer radios == theCircleRadios.

How to position objects in a 'radial-style' arrangement in Unity?

I'm trying to write a script in Unity which creates a type of radial menu around an object the player is directly facing, but the number of buttons in the menu is a variable.
I've generated the angles to the main menu the objects are supposed to appear at easily enough...
// int buttonCount = number of buttons
float buttonWidth = 360 / buttonCount;
for (int i = 1; i <= buttonCount; i++)
{
float maxAngle = buttonWidth * i;
float minAngle;
if (i == 0)
{
minAngle = 0f;
}
else if (i == buttonCount)
{
minAngle = 360 - buttonWidth;
}
else
{
minAngle = buttonWidth * (i - 1);
}
float buttonAngle = (minAngle + maxAngle) / 2;
}
...but now I'm trying to position the button objects at the corresponding angles around the central menu object and I don't know how?
This function takes as parameters the object you want the buttons to go around, the player gameobject so that you can orient the new buttons toward the player, the angle you want the button to be at, and the radius (distance the button will be from the buttonCenter). Its output is the button position in world space. You can call it for each button you want to add.
Vector3 positionButton(GameObject buttonCenter, GameObject player, float angle, float radius) {
//get the up and right vectors from the player object so we can orient the buttons
Vector3 up = player.transform.up;
Vector3 right = player.transform.right;
angle = Mathf.Deg2Rad * angle; //convert degrees to radians. radians=degrees * 2pi / 360
//cos(angle) give an x coordinate, on a unit circle centered around 0
//sin(angle) is the y coordinate on the unit circle
//take those values, multiply them by the up and right vectors to orient them to the player,
//multiply by the radius to move them the correct distance from the buttoncenter,
//and add the buttoncenter position so they circle around the correct point
Vector3 buttonPos =buttonCenter.transform.position + (radius * right * Mathf.Cos(angle)) + (radius* up * Mathf.Sin(angle));
return buttonPos;
}
First, define an origin and distance for each button from it. As you have the angles, you can apply trigonometry which should allow you to find the coordinate of a point given an angle, distance and origin point. The point will be defined by cos() and sin() of the angle.
Have a look at the 2nd section here

Formula to convert position axis into time

I have a cube which i am moving in circle shape (with horizontal key input) is below code suggested.
public class Oscillator : MonoBehaviour {
float timeCounter = 0;
float speed,width, height;
public float yPosition = 30;
// Use this for initialization
void Start () {
speed = 2; width = 10; height = 10;
}
// Update is called once per frame
void Update () {
timeCounter += Time.deltaTime * speed * Input.GetAxis("Horizontal");
float x = Mathf.Sin (timeCounter)* height;
float y = yPosition;
float z = Mathf.Cos (timeCounter) * width;
transform.position = new Vector3 (x, y, z);
}
}
Now my object is moving in circular shape which is fine. Now i want to translate my objects movement into time.
Let suppose
if my object x position is 1 then it should give me time 1.0
if it is 1.5 then it should give me 1.5
it increase or decrease according to x postion of my object (or possibly throught z).
I logged my object's x position which is starting from 0 to 9.999 and then become decrease 0, then -1 to -9 then it become decrease 0 and reached to its initial position. This circular movement x values are strange for me, i am unable to form any formula that can convert my x position into time.
Please can any one help me in this purely mathematics and 3d math problem?
You could try the following:
Get the vector between origin of the circle and the 0 of your circle, like 12 on a clock. This one is constant.
Then you have the vector between the origin of the circle and the current point.
Try the following:
Vector3 from = new Vector3(0,0,1); / This is your 12
Vector3 to = GetCurrentVector();
float angle = Quaternion.FromToRotation(Vector3.up, to - from).eulerAngles.z;
Debug.Log(angle / 360f);

Create 3D Room based on Line Drawing

I'm provide LineRenderer to draw the shape of Room in 2D and store the LineRenderer position values in DrawLine.storeLineRenderers list.(List2>)
My plan to create 3D room using 2D Shape , i.e LineRenderer's.
Following code gives convert to 3d, but not accurate
for(int i=1;i<=noOfLines;i++)
{
LineRenderer line =GameObject.Find("line" + i).GetComponent<LineRenderer>();
if(line!=null)
{
Vector3[] ss= DrawLine.storeLineRenderers[i - 1];
print(ss[0]); //Position Element 0 value (Vector3)
print(ss[1]); //Position Element 1 value (Vector3)
//generate 3d box (wall) here
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.name = "wall" + i;
cube.transform.localPosition =new Vector3(ss[0].x,ss[0].y,ss[0].z);
cube.transform.localScale = new Vector3(ss[1].x - ss[0].x, ss[1].y - ss[0].y,ss[1].z - ss[0].z);
}
}
Output
How to solve this?? Is there any formula to create properly??
thanks in advance...
try this out.
What you have to be aware of is that the cube's pivot is in its center, meaning you have to add half its size to its position to make it "start" at ss[0] and span all the way to ss[1].
Also, the wall need to be rotated to look at ss[1].
const float thickness = .1f; // how thick will the wall be
const float height = 1f; // how high will the wall be
Vector3 dist = ss[1] - ss[0];
float length = dist.magnitude; // make wall long enough to span ss[0] to ss[1]
Vector3 cubeSize = new Vector3(thickness, height, length);
Vector3 cubePos = ss[0] + (cubeSize * 0.5f); // cube pivot is in its center
Quaternion cubeOrientation = Quaternion.LookRotation(dist, Vector3.up); // rotate to look at ss[1]
GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
cube.transform.localPosition = cubePos;
cube.transform.localScale = cubeSize;
cube.transform.localRotation = cubeOrientation;

Imposing a limit on translation movement

I have a zoom function on my camera that works by moving it on the Z axis when I pinch my fingers on the screen. However, when the camera moves into any value greater than zero, it has adverse effects on the rest of my camera code (movement, orbiting).
I put in a place a bool that would stop my camera moving once it got to a certain value, but it makes it very jumpy. And if your pinching, the camera will still move past the value until you let go.
So what I'm trying to do now, is use Mathf.Clamp to limit the range it can move, but I'm unsure if I'm using it correctly. This is my method right now:
void CameraZoom()
{
// if fingers moved certain distance apart, zoom
float dot = Vector2.Dot(Input.GetTouch(0).deltaPosition.normalized, Input.GetTouch(1).deltaPosition.normalized);
if (dot < fingerDistance)
{
// Store both touches.
Touch touchZero = Input.GetTouch(0);
Touch touchOne = Input.GetTouch(1);
Vector2 touchZeroPrevPos = touchZero.position - touchZero.deltaPosition;
Vector2 touchOnePrevPos = touchOne.position - touchOne.deltaPosition;
float prevTouchDeltaMag = (touchZeroPrevPos - touchOnePrevPos).magnitude;
float touchDeltaMag = (touchZero.position - touchOne.position).magnitude;
float deltaMagnitudeDiff = prevTouchDeltaMag - touchDeltaMag;
// apply zoom to camera
transform.Translate(0, 0, -deltaMagnitudeDiff * perspectiveZoomSpeed);
// clamp movement
transform.position = new Vector3(transform.position.x, transform.position.y, Mathf.Clamp(0, 0, maxDistance));
}
}
}
I only want this to affect the Z axis, but when I zoom, my whole rig gets moved. What is it that I'm doing wrong?
Update
Ive changed my code to the following, but now when I zoom, it just jumps between two points and I can no longer zoom.
New code:
transform.Translate(0, 0, -deltaMagnitudeDiff * perspectiveZoomSpeed);
Vector3 pos = transform.position;
pos.z = Mathf.Clamp(transform.position.z, 0.0f, -200.0f);
transform.position = pos;
Check the documentation for the Mathf.Clamp. You are using the parameters in the wrong order, which breaks the internal implementation of the function. The min value should be the second and the max value should be the third. So changing your line to this should stop the odd behavior:
pos.z = Mathf.Clamp(transform.position.z, -200.0f, 0.0f);

Categories

Resources