I am making a game in which the balls are falling down on a plane one ball fall over the other ball and they make a line, which goes from bottom to top. I want that at certain point on y axis the ball stop falling. Don't know how to do it the code I used until now for balls to fall down is:
function calling(){
functionsRandom.Range(0, functions.Length);
}
function sphereA() {
var go = Instantiate(sphere,new Vector3(Random.Range(-3, 3),Random.Range(-3,3),-12.78451),Quaternion.identity);
go.renderer.material.color = Color(Random.value, Random.value, Random.value);
}
function sphereB() {
var go = Instantiate(sphere1,new Vector3(Random.Range(-3, 3),Random.Range(-3,3),-12.78451),Quaternion.identity);
go.renderer.material.color = Color(Random.value, Random.value, Random.value);
}
I used random.range, so that the ball falls from points between it both in x and y, for x it is working, but it is not working for y.
Add all the instantiated spheres to an array go[] instead of go. which are in line. Now at certain point where you want to stop generating other spheres, take the count of the sphere in the array. If the count is equal to the max limit. Then DON'T instantiate the spheres. If any doubts, come to unity3d chatroom.
Related
As per my game requirements, I was giving manual force when two cars collide with each other and move back.
So I want the correct code that can justify this. Here is the example, collision response that I want to get:
As per my understanding, I have written this code:
Vector3 reboundDirection = Vector3.Normalize(transform.position - other.transform.position);
reboundDirection.y = 0f;
int i = 0;
while (i < 3)
{
myRigidbody.AddForce(reboundDirection * 100f, ForceMode.Force);
appliedSpeed = speed * 0.5f;
yield return new WaitForFixedUpdate();
i++;
}
I am moving, my cars using this code:
//Move the player forward
appliedSpeed += Time.deltaTime * 7f;
appliedSpeed = Mathf.Min(appliedSpeed, speed);
myRigidbody.velocity = transform.forward * appliedSpeed;
Still, as per my observation, I was not getting, collision response in the proper direction. What is the correct way for getting above image reference collision response?
Until you clarify why you have use manual forces or how you handle forces generated by Unity Engine i would like to stress one problem in your approach. You calculate direction based on positions but positions are the center of your cars. Therefore, you are not getting a correct direction as you can see from the image below:
You calculate the direction between two pivot or center points therefore, your force is a bit tilted in left image. Instead of this you can use ContactPoint and then calculate the direction.
As more detailed information so that OP can understand what i said! In the above image you can see the region with blue rectangle. You will get all the contact points for the corresponding region using Collision.contacts
then calculate the center point or centroid like this
Vector3 centroid = new Vector3(0, 0, 0);
foreach (ContactPoint contact in col.contacts)
{
centroid += contact.point;
}
centroid = centroid / col.contacts.Length;
This is the center of the rectangle to find the direction you need to find its projection on your car like this:
Vector3 projection = gameObject.transform.position;
projection.x = centroid.x;
gameObject.GetComponent<Rigidbody>().AddForce((projection - centroid )*100, ForceMode.Impulse);
Since i do not know your set up i just got y and z values from car's position but x value from centroid therefore you get a straight blue line not an arrow tilted to left like in first image even in the case two of second image. I hope i am being clear.
I am trying to make a volleyball scene in unity. What I want is to create a scene where two NPCs are throwing the ball at each other. And I want the ball to land on random spots and the NPCs to reach the spot at the same time as the ball reaches the point. Now I am using the parabola equations to calculate where the ball should land and how much time will it take to get there. The time and the landing spot are working fine. But I can't seem to get the NPCs there at the exact time. I am using the following coroutine to move the NPC and the ball. The ball reaches the point on time but somehow the NPC reaches late.
IEnumerator playOneRound()
{
//this is the point where the ball is going to land
currentMovePoint.transform.position = currentRandomObjects[Random.Range(0, currentRandomObjects.Length)].transform.position;
parabolaStartPoint.transform.position = currentStartPoint.transform.position;
parabolaEndPoint.transform.position = currentBallPoint.transform.position;
ballController.FollowParabola();
//this is the time in which the ball will reach the end point of the parabola
time = ballController.GetDuration();
//this is the distance between the NPC and the point where the ball will land
distance = Vector3.Distance(currentPlayer.transform.position, currentMovePoint.transform.position);
speed = distance / time;
// clockspeed here is the amount of seconds I am going to wait for each iteration.
// so basically I am converting the the speed from distance-unit/second to
// distance-unit/clockspeed
distancePerClock = speed * clockSpeed;
while (Vector3.Distance(currentPlayer.transform.position, currentMovePoint.transform.position) > 0.1f)
{
currentPlayer.transform.position = Vector3.MoveTowards(currentPlayer.transform.position, currentMovePoint.transform.position, distancePerClock);
yield return new WaitForSeconds(clockSpeed);
}
}
The math seems to be right on paper. But somehow it's not working here. Am I missing something?
I am trying to get the angle between the bones, such as the metacarpal bone and the proximal bone (angle of moving the finger side to side, for example the angle when your index finger is as close to your thumb as you can move it and then the angle when your index finger is as close to your middle finger as you can move it).
I have tried using Vector3.Angle with the direction of the bones but that doesn't work as it includes the bending of the finger, so if the hand is in a fist it gives a completely different value to an open hand.
What i really want is a way i can "normalize" (i know normalizing isn't the correct term but it's the best i could think of) the direction of the bones so that even if the finger is bent, the direction vector would still point out forwards and not down, but would be in the direction of the finger (side to side).
I have added a diagram below to try and illustrate what i mean.
In the second diagram, the blue represents what i currently get if i use the bone's directions, the green is the metacarpal direction and the red is what i want (from the side view). The first diagram shows what i am looking for from a top-down view. The blue line is the metacarpal bone direction and in this example the red line is the proximal bone direction, with the green smudge representing the angle i am looking for.
To get this value, you need to "uncurl" the finger direction based on the current metacarpal direction. It's a little involved in the end; you have to construct some basis vectors in order to uncurl the hand along juuust the right axis. Hopefully the comments in this example script will explain everything.
using Leap;
using Leap.Unity;
using UnityEngine;
public class MeasureIndexSplay : MonoBehaviour {
// Update is called once per frame
void Update () {
var hand = Hands.Get(Chirality.Right);
if (hand != null) {
Debug.Log(GetIndexSplayAngle(hand));
}
}
// Some member variables for drawing gizmos.
private Ray _metacarpalRay;
private Ray _proximalRay;
private Ray _uncurledRay;
/// <summary>
/// This method returns the angle of the proximal bone of the index finger relative to
/// its metacarpal, when ignoring any angle due to the curling of the finger.
///
/// In other words, this method measures the "side-to-side" angle of the finger.
/// </summary>
public float GetIndexSplayAngle(Hand h) {
var index = h.GetIndex();
// These are the directions we care about.
var metacarpalDir = index.bones[0].Direction.ToVector3();
var proximalDir = index.bones[1].Direction.ToVector3();
// Let's start with the palm basis vectors.
var distalAxis = h.DistalAxis(); // finger axis
var radialAxis = h.RadialAxis(); // thumb axis
var palmarAxis = h.PalmarAxis(); // palm axis
// We need a basis whose forward direction is aligned to the metacarpal, so we can
// uncurl the finger with the proper uncurling axis. The hand's palm basis is close,
// but not aligned with any particular finger, so let's fix that.
//
// We construct a rotation from the palm "finger axis" to align it to the metacarpal
// direction. Then we apply that same rotation to the other two basis vectors so
// that we still have a set of orthogonal basis vectors.
var metacarpalRotation = Quaternion.FromToRotation(distalAxis, metacarpalDir);
distalAxis = metacarpalRotation * distalAxis;
radialAxis = metacarpalRotation * radialAxis;
palmarAxis = metacarpalRotation * palmarAxis;
// Note: At this point, we don't actually need the distal axis anymore, and we
// don't need to use the palmar axis, either. They're included above to clarify that
// we're able to apply the aligning rotation to each axis to maintain a set of
// orthogonal basis vectors, in case we wanted a complete "metacarpal-aligned basis"
// for performing other calculations.
// The radial axis, which has now been rotated a bit to be orthogonal to our
// metacarpal, is the axis pointing generally towards the thumb. This is our curl
// axis.
// If you're unfamiliar with using directions as rotation axes, check out the images
// here: https://en.wikipedia.org/wiki/Right-hand_rule
var curlAxis = radialAxis;
// We want to "uncurl" the proximal bone so that it is in line with the metacarpal,
// when considered only on the radial plane -- this is the plane defined by the
// direction approximately towards the thumb, and after the above step, it's also
// orthogonal to the direction our metacarpal is facing.
var proximalOnRadialPlane = Vector3.ProjectOnPlane(proximalDir, radialAxis);
var curlAngle = Vector3.SignedAngle(metacarpalDir, proximalOnRadialPlane,
curlAxis);
// Construct the uncurling rotation from the axis and angle and apply it to the
// *original* bone direction. We determined the angle of positive curl, so our
// rotation flips its sign to rotate the other direction -- to _un_curl.
var uncurlingRotation = Quaternion.AngleAxis(-curlAngle, curlAxis);
var uncurledProximal = uncurlingRotation * proximalDir;
// Upload some data for gizmo drawing (optional).
_metacarpalRay = new Ray(index.bones[0].PrevJoint.ToVector3(),
index.bones[0].Direction.ToVector3());
_proximalRay = new Ray(index.bones[1].PrevJoint.ToVector3(),
index.bones[1].Direction.ToVector3());
_uncurledRay = new Ray(index.bones[1].PrevJoint.ToVector3(),
uncurledProximal);
// This final direction is now uncurled and can be compared against the direction
// of the metacarpal under the assumption it was constructed from an open hand.
return Vector3.Angle(metacarpalDir, uncurledProximal);
}
// Draw some gizmos for debugging purposes.
public void OnDrawGizmos() {
Gizmos.color = Color.white;
Gizmos.DrawRay(_metacarpalRay.origin, _metacarpalRay.direction);
Gizmos.color = Color.blue;
Gizmos.DrawRay(_proximalRay.origin, _proximalRay.direction);
Gizmos.color = Color.red;
Gizmos.DrawRay(_uncurledRay.origin, _uncurledRay.direction);
}
}
For what it's worth, while the index finger is curled, tracked Leap hands don't have a whole lot of flexibility on this axis.
I would like to fill this auditorium seating area with chairs (in the editor) and have them all face the same focal point (the stage). I will then be randomly filling the chairs with different people (during runtime). After each run the chairs should stay the same, but the people should be cleared so that during the next run the crowd looks different.
The seating area does not currently have a collider attached to it, and neither do the chairs or people.
I found this code which has taken care of rotating the chairs so they target the same focal point. But I'm still curious if there are any better methods to do this.
//C# Example (LookAtPoint.cs)
using UnityEngine;
[ExecuteInEditMode]
public class LookAtPoint : MonoBehaviour
{
public Vector3 lookAtPoint = Vector3.zero;
void Update()
{
transform.LookAt(lookAtPoint);
}
}
Additional Screenshots
You can write a editor script to automatically place them evenly. In this script,
I don't handle world and local/model space in following code. Remember to do it when you need to.
Generate parallel rays that come from +y to -y in a grid. The patch size of this grid depends on how big you chair and the mesh(curved space) is. To get a proper patch size. Get the bounding box of a chair(A) and the curved space mesh(B), and then devide them(B/A) and use the result as the patch size.
Mesh chairMR;//Mesh of the chair
Mesh audiMR;//Mesh of the auditorium
var patchSizeX = audiMR.bounds.size.X;
var patchSizeZ = audiMR.bounds.size.Z;
var countX = audiMR.bounds.size.x / chairMR.bounds.size.x;
var countZ = audiMR.bounds.size.z / chairMR.bounds.size.z;
So the number of rays you need to generate is about countX*countZ. Patch size is (patchSizeX, patchSizeZ).
Then, origin points of the rays can be determined:
//Generate parallel rays that come form +y to -y.
List<Ray> rays = new List<Ray>(countX*countZ);
for(var i=0; i<countX; ++i)
{
var x = audiMR.bounds.min.x + i * sizeX + tolerance /*add some tolerance so the placed chairs not intersect each other when rotate them towards the stage*/;
for(var i=0; i<countZ; ++i)
{
var z = audiMR.bounds.min.z + i * sizeZ + tolerance;
var ray = new Ray(new Vector3(x, 10000, z), Vector3.down);
//You can also call `Physics.Raycast` here too.
}
}
Get postions to place chairs.
attach a MeshCollider to your mesh temporarily
foreach ray, Physics.Raycast it (you can place some obstacles on places that will not have a chair placed. Set special layer for those obstacles.)
get hit point and create a chair at the hit point and rotate it towards the stage
Reuse these hit points to place your people at runtime.
Convert each of them into a model/local space point. And save them into json or asset via serialization for later use at runtime: place people randomly.
I want to move a rigid body in an elliptical movement like the player movement "whale trail" game.What I did is:
Created a Cube called "Player" with scale(1.5,0.5,0.1)
Created another small cube called Point with scale(0.1,0.1,0.1) and positioned same as Player but 0.5 more in x (So that now the player looks like a 2D rectangle and a point on it little right to the centre of the rectangle).
Then I created a fixed joint between both bodies
Now I applied for on the player at the position of the Point as follows ,
float mfAngle = 0.0f;
void update()
{
mfAngle=transform.eulerAngles.z;
mfAngle=mfAngle%360;
if(mfAngle>=0 && mfAngle<90)
{
mfXforce=-0.1f;
mfYforce=0.1f;
}
if(mfAngle>=90 && mfAngle<180)
{
mfXforce=-0.1f;
mfYforce=0.1f;
}
if(mfAngle>=180 && mfAngle<270)
{
mfXforce=-0.1f;
mfYforce=-0.1f;
}
if(mfAngle>=270 && mfAngle<360)
{
mfXforce=0.1f;
mfYforce=-0.1f;
}
Debug.Log("Angle ="+mfAngle+"X = "+mfXforce+"Y = "+mfYforce);
Vector3 pointPos=_goPointObject.transform.position;
transform.rigidbody.AddForceAtPosition(new Vector3(mfXforce,mfYforce,0),pointPos);
}
But it doesn't works fine.I just moves upwards and the turns and moves in different direction.If anyone know how to move the rigid body in elliptical motion by applying force give me a solution.(I want to use it as like whale trail game u can see the video of the "loop movement" in this http://www.youtube.com/watch?v=wwr6c2Ws1yI video).Thanks in advance.
I had found the solution by myself.To achieve that elliptical movement u have to create two bodies and connect them with joint by placing it horizontally next to each other.Then u have to apply force in x direction constantly and in Y direction only when the Screen is be touched on the first body.
And its important to reduce the X speed when moving up then u will get that elliptical rotation.
It works fine for me.
Thanks,
Ashokkumar M