Saving a float value in a certain moment in unity - c#

Hello I did the Brackeys Tutorial and I am trying to make my own game off of it and the first thing i wanted to do was a restart screen and for that i need the score but if the cube falls off it still goes forward so i need the z value of the cube when it falls of the edge

What do you mean?
If you just want to save the float value of a transform, use something like
float z = cube.transform.position.z;
When setting the transform, you need to use a whole Vector3; you can't just change one value.
cube.transform.position = Vector3(cube.transform.position.x, cube.transform.position.y, z);
Ok. According to your comment,
bool checkForY = true;
GameObject cube;
float cubeZ;
void Update()
{
if (checkForY)
{
if (cube.transform.position.y < 0)
{
cubeZ = cube.transform.position.z;
checkForY = false;
}
}
}
This should work. You might want to rename "cubeZ" to whatever you're using it for, though.

Related

Place object without overlap others

Im having a problem in one of my projects in unity. I basicly have a system where you click an object and then you click somewhere inside an area and the object goes to that position. the problem is that those objects can't overlap. And they can't use physics. to detect colision with each other. I have been working on this for a long time I got something but still not totally working and I hoped someone could help me.
What im basicly doing is getting all objects near the click and then if there are some just calculate the directions between the click and those objects and then add them to the position that seems to work sometimes they don't overlap other times they do and they go to far away and I need them to be near the click.
code:
public Vector3 GetPossiblePosition(List<GameObject> nearbyDiscs, Vector3 position)
{
float initialY = transform.position.y;
Vector3 idealPosition = position;
List<Vector3> directions = new List<Vector3>();
if(nearbyDiscs.Count > 0)
{
foreach (GameObject disc in nearbyDiscs)
{
Vector3 newDirection = position - disc.transform.position;
directions.Add(newDirection);
}
for (int i = 0; i < directions.Count; i++)
{
idealPosition += directions[i] / directions.Count;
List<GameObject> discs = CheckForNearbyDiscs(idealPosition);
if (discs.Count < 1)
break;
}
}
idealPosition.y = initialY;
return idealPosition;
}
behaviour:
You can easily do this using Physics2D.OverlapCircleAll
public static Collider2D[] OverlapCircleAll(Vector2 point, float radius, int layerMask = DefaultRaycastLayers, float minDepth = -Mathf.Infinity, float maxDepth = Mathf.Infinity);
this method returns an array of colliders, you can simply check overlapping if the length of the returning array is greater than one and can handle accordingly.

Unity wall climbing 2D

I made little code for detect climbing (script attached to the player object):
private float PlayerColHeight;
private float PlayerColWidth;
private bool Climb = false;
void Start () {
PlayerCol = GetComponent<CapsuleCollider2D> ();
PlayerColHeight = PlayerCol.bounds.size.y;
PlayerColWidth = PlayerCol.bounds.size.x;
}
private void OnCollisionStay2D(Collision2D col){
if (!IsGrounded() && (col.gameObject.tag == "Wall")) {
Vector2 position = transform.position;
Vector2 wallPos = col.transform.position;
float wallColHeight = col.gameObject.GetComponent<BoxCollider2D> ().bounds.size.y;
if ((position.y+PlayerColHeight/2)==(wallPos.y + wallColHeight/2)){
Climb = true;
}
Debug.Log (Climb);
}
}
This means when player in the air and colliding with wall, i need to check if player top point Y = wall top point Y and understand that it works.
But this is not works... Console returns only False.
Image:
Why it doesn't works? If you know another way to make climbing, can you explain how?
I think your condition statement is wrong
if ((position.y+PlayerColHeight/2)==(wallPos.y + wallColHeight/2)){
Climb = true;
}
It should be
if ((position.y+PlayerColHeight/2) <= (wallPos.y + wallColHeight/2)){
Climb = true;
}
Climb was true only when both values were equal but you are interested on climbing when the player position is smaller than the wall, right?
In any case you should check your values debugging the game or just writing logs with the values position.y+PlayerColHeight/2 and wallPos.y + wallColHeight/2 to understand what's going on.
Edit: It could happen that when you are close to get out of the "climbing zone" your player gets stucked as he will get Climb = false, the ideal should be enable climbing when you are in the wall, you don't care if jumping again will leave the player above the wall, what it's more you could be interested on that for reaching the top of the wall in same situations
The chances that these variables are exactly the same is low. One frame the player will be a bit above, and the next frame a bit below.
The Player should have a range below the wall in which he can climb. Try this:
const float climbZoneHeight = 1f; // In world unit, the range of the wall on which the player can climb. Choose a value that works well in your case;
const float distToWallTop = (wallPos.y + wallColHeight/2) - (position.y+PlayerColHeight/2);
if (distToWallTop >= 0 && distToWallTop <= climbZoneHeight )
{
Climb = true;
}
For this scenario, consider the following cases:
As already posted in another response, you should not use equality comparison, instead you should make less than comparison, i.e. player_top_y <= wall_top_y
Secondly, instead of calculating player_top_y as player_y + player_collider_y, you should directly use the collision contact point

How can I get the camera to pause on 3 objects on the x axis?

I am a new student working on a class project. I have 1 script attached to the camera in my only scene. I want the camera to pause over the 1st object, scroll to the 2nd object and pause then scroll to the 3rd object and pause then end. Putting this code in the UPDATE, the camera never stops. Here in the START, it hesitates around 15 sec and then it goes right to the last object, then the function stops. Note the delay set for 10 seconds. I tried putting the code in a function and calling the function from START… but no good. What am I doing wrong? HELP ME OB1....
One more thing... Is START the best place to play sound?
using UnityEngine;
using System.Collections;
// I want the camera to pause over the 1st object, scroll to the 2nd object and pause
// then scroll to the 3rd object and pause then end. Putting this code in the UPDATE
// the camera never stops. Here in the START, it hesitates around 15 sec and then it
// goes right to the last object, then the function stops. Note the delay set for 10
// seconds.
public class CameraControl : MonoBehaviour
{
public float speed; // How fast to move the camera
public int moves; // How many moves to make
public float MyWait; // How long to pause over object
// Use this for initialization
void Start()
{
StartCoroutine(MyDelay());
for (int y = 1; y <= 2; y++) // go to the next two objects
{
for (int i = 1; i <= moves; i++) // Move the camera to the next position
{
Camera.main.transform.Translate(new Vector3(1.0f, 0.0f, 0.0f) * speed * Time.deltaTime);
Debug.LogFormat("moves = {0} ", i);
}
StartCoroutine(MyDelay());
}
}
IEnumerator MyDelay()
{
yield return new WaitForSeconds(10.0f);
}
}
Try placing this code on your camera and place all the game objects you'd like the camera to move to in the Objects list. If you'd like the camera to be a little further back so it can see the object, create a new Vector3 instead of simply giving the exact position and then give that new Vector3 the x, y and z of the iterating object and then add distance to which ever axis you'd like for the camera to be distanced from the object.
public float MyWait = 5; // How long to pause over object
public float speed = 5f; // How fast to move the camera
public List<GameObject> Objects; //List of each object for the camera to go to
void Start()
{
StartCoroutine(MoveToObject(0));
}
IEnumerator MoveToObject(int iteratingObject)
{
//Wait for however many seconds
yield return new WaitForSeconds(MyWait);
bool atDestination = false;
//Move the camera until at destination
while (!atDestination)
{
yield return new WaitForFixedUpdate();
transform.position = Vector3.MoveTowards(transform.position, Objects[iteratingObject].transform.position, Time.deltaTime * speed);
if (transform.position == Objects[iteratingObject].transform.position)
atDestination = true;
}
//Continue iterating until moved over all objects in list
if(iteratingObject != Objects.Count - 1)
StartCoroutine(MoveToObject(iteratingObject + 1));
}
I think you're going to need to put some code in the Update function for this to work smoothly.
Time.deltaTime will only really make sense in an Update function, using it here and trying to do everything in the Start function won't work. Also setting the Translate transform will instantly set the position to the given value. Look up linear interpolation (lerp).
I would suggest you have a member that you use to track the current state, i.e. which object you're looking at, but an Enum of states might be easier to read.
Then you can keep a member for how long you've been in that state, which you can increase in the Update.
Then within the Update you can check whether it is time to change state or update your moving camera.
Good luck!

Unity3D: Adding charged force in relation to position

I am trying to make a game which "kind of" simulates the shooting of the "worms" game. The player can choose the position (circular) of an object and then, the force that is applied to the object should move in the direction its pointing towards. I tried using the AddForce(transform.right) code, but it would just go to the right. (2D BoxCollider and RigidBody2D)
Then comes the hard part, making the player choose the force by charging the power. When the player holds down the "f" key, I want the power to go up to a certain point. Once it reaches that point, I want it to go down again and then up again, so the player can choose the power he wants. I have no idea how to go about this.
It's been awhile since I've did Unity coding, so there may be some minor errors with my syntax but it should give you an idea of how to accomplish this. Your best bet for the loop is to use a coroutine to not block the main thread.
in Update() check for 'on key down' for F and start this coroutine:
IEnumerator Cycle()
{
float max = 10.0f;
float min = 1.0f;
float interval = 0.5f;
do
{
for(int i=min;i<max;i++)
{
PowerValue = i;
yield return new waitforseconds(interval);
if(!input.getkey(f))
break;
}
for(int i=max;i>min;i--)
{
PowerValue = i;
yield return new waitforseconds(interval);
if(!input.getkey(f))
break;
}
} while(input.getkey(f));
}
And back in update() use that powerValue with getKeyUp(f)
And here is PowerValue setup as a parameter that prevents code from setting the max and min outside of a 1 to 10 range (configurable)
private float powerValue = 1.0f;
public float PowerValue
{
get { return powerValue; }
set {
if(value>10f)
powerValue=10f;
else if (value<1f)
powerValue=1f;
else
powerValue=value;
}
}

Moving a 3d object back and forth between points

I tried to make a script that moves an object back and forth between two points. But it just flies in the ifinity. I tried to find the problem whole evening but idk.
here is the code:
using UnityEngine;
public class MovementBetweenPoints : MonoBehaviour {
public Transform[] keyPoints;
public float speed;
private int currentKeyPoint;
// Use this for initialization
void Start ()
{
transform.position = keyPoints[0].position;
currentKeyPoint = 1;
}
// Update is called once per frame
void Update ()
{
if (transform.position == keyPoints[currentKeyPoint].position)
{
currentKeyPoint++;
}
if (currentKeyPoint >= keyPoints.Length)
{
currentKeyPoint = 0;
}
transform.position = Vector3.MoveTowards(transform.position, keyPoints[currentKeyPoint].position, speed * Time.deltaTime);
}
}
Your script works fine as it is. you need to make sure that speed is set to a value greater than 0 in the inspector, and that the keypoints array contains some gameobjects in the inspector too, and you are good to go
I'm sure the problem comes with this part of the code where you check if the position of the object is equal at some waypoint. Instead of:
if (transform.position == keyPoints[currentKeyPoint].position)
{
currentKeyPoint++;
}
try to do something less agressive, and give a bit of margin like:
if (Vector3.Distance(transform.position - keyPoints[currentKeyPoint].position) <= min_Distance)
{
currentKeyPoint++;
}
because it's almost impossible that two objects with different speeds match at the same point. Instead of this, you'll use min_Distance to check it.

Categories

Resources