// Credit // http://wiki.unity3d.com/index.php/3d_Math_functions // http://creativecommons.org/licenses/by-sa/3.0/ public static bool ClosestPointsOnTwoLines(out Vector3 closestPointLine1, out Vector3 closestPointLine2, Vector3 linePoint1, Vector3 lineVec1, Vector3 linePoint2, Vector3 lineVec2) { closestPointLine1 = Vector3.zero; closestPointLine2 = Vector3.zero; float a = Vector3.Dot(lineVec1, lineVec1); float b = Vector3.Dot(lineVec1, lineVec2); float e = Vector3.Dot(lineVec2, lineVec2); float d = a * e - b * b; //lines are not parallel if (d != 0.0f) { Vector3 r = linePoint1 - linePoint2; float c = Vector3.Dot(lineVec1, r); float f = Vector3.Dot(lineVec2, r); float s = (b * f - c * e) / d; float t = (a * f - c * b) / d; closestPointLine1 = linePoint1 + lineVec1 * s; closestPointLine2 = linePoint2 + lineVec2 * t; return(true); } else { return(false); } }
private void Update() { var desired = (Enemy.Instance.transform.position - transform.position).normalized; PreviewRay(desired, Color.blue); desired = AvoidWalls(desired); PreviewRay(desired, Color.yellow); var anglebetween = Mathf.Acos(Vector3.Dot(desired, heading)) * Mathf.Rad2Deg; var maxAngle = maxAngularSpeed * Time.deltaTime * Mathf.Deg2Rad; if (anglebetween <= maxAngle) { heading = desired.normalized; } else { var normal = Vector2.Dot(new Vector2(-heading.y, heading.x), desired); if (normal < 0) { maxAngle *= -1; } heading = new Vector3( heading.x * Mathf.Cos(maxAngle) - heading.y * Mathf.Sin(maxAngle), heading.x * Mathf.Sin(maxAngle) + heading.y * Mathf.Cos(maxAngle)) .normalized; } UpdateOrientation(); transform.position += new Vector3(heading.x, heading.y) * maxSpeed * Time.deltaTime; }
private void MovePlayer(float translation, float rotation) { if (_navMeshAgent.isOnOffMeshLink) { _navMeshAgent.CompleteOffMeshLink(); companion.GetComponent <NavMeshAgent>().Warp(teleportLocation.position); MusicController.GetInstance().variation = MusicController.Variation.C_NoLowpass; } Vector3 velocityForward = transform.forward * translation; Vector3 velocitySideways = transform.right * rotation; Vector3 resultantVelocity = velocityForward + velocitySideways; Vector3 destination = resultantVelocity + transform.position; if (_isHeldBack) { Vector3 destFlat = new Vector3(destination.x, 0, destination.z).normalized; Vector3 companionDirection = (companion.transform.position - transform.position).normalized; Vector3 companionFlat = new Vector3(companionDirection.x, 0, companionDirection.z); float dot = Vector3.Dot(destFlat, companionFlat); if (dot < -0.5f) { return; } } _navMeshAgent.speed = resultantVelocity.magnitude; _navMeshAgent.velocity = resultantVelocity; _navMeshAgent.updateRotation = translation > 0.0f || Math.Abs(rotation) > 0.0f; _navMeshAgent.SetDestination(destination); }
// Credit // http://wiki.unity3d.com/index.php/3d_Math_functions // http://creativecommons.org/licenses/by-sa/3.0/ //This function finds out on which side of a line segment the point is located. //The point is assumed to be on a line created by linePoint1 and linePoint2. If the point is not on //the line segment, project it on the line using ProjectPointOnLine() first. //Returns 0 if point is on the line segment. //Returns 1 if point is outside of the line segment and located on the side of linePoint1. //Returns 2 if point is outside of the line segment and located on the side of linePoint2. public static int PointOnWhichSideOfLineSegment(Vector3 linePoint1, Vector3 linePoint2, Vector3 point) { Vector3 lineVec = linePoint2 - linePoint1; Vector3 pointVec = point - linePoint1; float dot = Vector3.Dot(pointVec, lineVec); //point is on side of linePoint2, compared to linePoint1 if (dot > 0) { //point is on the line segment if (pointVec.magnitude <= lineVec.magnitude) { return(0); } //point is not on the line segment and it is on the side of linePoint2 else { return(2); } } //Point is not on side of linePoint2, compared to linePoint1. //Point is not on the line segment and it is on the side of linePoint1. else { return(1); } }
public void Execute(int index) { int triIndex = index * 3; var v1 = rotation * Vec3.Scale(vertices[triangles[triIndex]], localScale) + position; var v2 = rotation * Vec3.Scale(vertices[triangles[triIndex + 1]], localScale) + position; var v3 = rotation * Vec3.Scale(vertices[triangles[triIndex + 2]], localScale) + position; var tri = new Triangle(v1, v2, v3); // calculate the angle of this triangles resistance var cosAngle = Vec3.Dot(tri.Normal, -velocity) / (velocity.magnitude * tri.Normal.magnitude); var angle = Mathf.Acos(cosAngle); // magnitude of drag: 180 = 1, 135 = 0.5, < 90 = 0 angleMags[index] = Mathf.Clamp((angle - Mathf.PI / 2) / (Mathf.PI / 2), 0, 1); var velSqu = Mathf.Pow(velocity.magnitude, 2); if (useSimpleDrag) { dragForces[index] = -.5f * velSqu * tri.Area * (angleMags[index] * dragMulti) * Vec3.Normalize(velocity); } else { dragForces[index] = -.5f * velSqu * tri.Area * (angleMags[index] * dragMulti) * Vec3.Normalize(tri.Normal); } midpoints[index] = tri.Midpoint; }
private bool GJK(Prism prismA, Prism prismB) { pointList = new List <Vector3>(); // Start at a random point dir = new Vector3(1, 1, 1); pointList.Add(getSupport(prismA, prismB, dir)); dir = -pointList[0]; var count = 0; while (count < 50) { count++; pointList.Add(getSupport(prismA, prismB, dir)); if (Vector3.Dot(pointList[pointList.Count - 1], dir) < 0) { pointList.Clear(); } if (OinSimplex(prismA, prismB)) { return(true); } } return(false); }
public bool Contains(Vector3 point) { // Transform to local space (shape in the XZ plane) point -= origin; var localSpacePoint = new Vector3(Vector3.Dot(point, right) / right.sqrMagnitude, 0, Vector3.Dot(point, forward) / forward.sqrMagnitude); if (convex) { if (_convexPoints == null) { return(false); } for (int i = 0, j = _convexPoints.Length - 1; i < _convexPoints.Length; j = i, i++) { if (VectorMath.RightOrColinearXZ(_convexPoints[i], _convexPoints[j], localSpacePoint)) { return(false); } } return(true); } else { return(_points != null && Polygon.ContainsPointXZ(_points, localSpacePoint)); } }
void LateUpdate() { for (int i = 0; i < _trackedTravellers.Count; i++) { PortalTraveller traveller = _trackedTravellers[i]; Transform travellerT = traveller.transform; Matrix4x4 m = otherPortal.transform.localToWorldMatrix * transform.worldToLocalMatrix * travellerT.localToWorldMatrix; Vector3 offsetFromPortal = travellerT.position - transform.position; int portalSide = Math.Sign(Vector3.Dot(offsetFromPortal, transform.forward)); int portalSideOld = Math.Sign(Vector3.Dot(traveller.prevOffsetFromPortal, transform.forward)); // Teleport the traveller if it has crossed from one side of the portal to the other if (portalSide != portalSideOld) { traveller.Teleport(transform, otherPortal.transform, m.GetColumn(3), m.rotation); // Can't rely on OnTriggerEnter/Exit to be called next frame since it depends on when FixedUpdate runs otherPortal.OnTravellerEnterPortal(traveller); _trackedTravellers.RemoveAt(i); i--; } else { traveller.prevOffsetFromPortal = offsetFromPortal; } } }
protected void RotateSlice(List <GameObject> slice, float angleInDeg) { Vector3 axis = (m_shuffleCoroutine != null || m_solveCoroutine != null) ? transform.TransformVector(m_selectedPlane .normal) : m_selectedPlane .normal; Vector3 point = m_selectedPlane.distance * axis; for (int i = 0; i < slice.Count; i++) { Vector3 position = slice[i].transform.position; slice[i].transform.position = point + Quaternion.AngleAxis(angleInDeg, axis) * (position - point); slice[i].transform.rotation = Quaternion.AngleAxis(angleInDeg, axis) * slice[i].transform.rotation; } Vector3 up = Mathf.Abs(Vector3.Dot(slice.Last().transform.up, axis)) < 0.5f ? slice.Last().transform.up : Mathf.Abs(Vector3.Dot(slice.Last().transform.right, axis)) < 0.5f ? slice.Last().transform.right : slice.Last().transform.forward; m_NeutralPlaneSlice1.transform.rotation = Quaternion.LookRotation(-axis, up); m_NeutralPlaneSlice2.transform.rotation = Quaternion.LookRotation(axis, up); }
public static float CalculateTurn(Quaternion originalRotation, Quaternion transformRotation) { var cross = Vector3.Cross(originalRotation * Vector3.forward, transformRotation * Vector3.forward); var dot = Vector3.Dot(cross, Vector3.up); return(dot); }
private void UpdateRpm() { var forwardVelocity = Vector3.Dot(velocity, transform.forward); var rotPerSec = forwardVelocity / (2 * Mathf.PI * _wheel.GetRadius()); _rpm = rotPerSec * 60; }
protected void FillSliceVoidWithNeutralPlane() { Vector3 axis = (m_shuffleCoroutine != null || m_solveCoroutine != null) ? transform.TransformVector(m_selectedPlane.normal) : m_selectedPlane .normal; if (m_selectedPlane.distance < (0.5f * m_width - 0.5f)) { m_NeutralPlaneRubix2.SetActive(true); m_NeutralPlaneSlice2.SetActive(true); } if (m_selectedPlane.distance > -(0.5f * m_width - 0.5f)) { m_NeutralPlaneRubix1.SetActive(true); m_NeutralPlaneSlice1.SetActive(true); } m_NeutralPlaneRubix1.transform.position = m_NeutralPlaneSlice1.transform.position = axis * -(m_selectedPlane.distance - 0.5f); m_NeutralPlaneRubix2.transform.position = m_NeutralPlaneSlice2.transform.position = axis * -(m_selectedPlane.distance + 0.5f); Vector3 up = Mathf.Abs(Vector3.Dot(transform.up, axis)) < 0.5f ? transform.up : Mathf.Abs(Vector3.Dot(transform.right, axis)) < 0.5f ? transform.right : transform.forward; m_NeutralPlaneRubix2.transform.rotation = m_NeutralPlaneSlice2.transform.rotation = Quaternion.LookRotation(-axis, up); m_NeutralPlaneRubix1.transform.rotation = m_NeutralPlaneSlice1.transform.rotation = Quaternion.LookRotation(axis, up); }
private bool OinSimplex(Prism prismA, Prism prismB) { switch (pointList.Count) { case 2: if (Vector3.Dot(pointList[0] - pointList[1], -pointList[1]) > 0) { // AB x AO x AB // Origin is in between A and B dir = Vector3.Cross(Vector3.Cross(pointList[0] - pointList[1], -pointList[1]), pointList[0] - pointList[1]); return(false); } else { pointList.RemoveAt(0); dir = -pointList[0]; return(false); } case 3: return(triangle(prismA, prismB)); case 4: return(tetrahedron(prismA, prismB)); default: return(false); } }
void SphereMovementVectors() { //THESE VECTORS LENGTH ISNT 2 (SPEED)! sphere1BlueInitialVelo = sphereBlueVeloAccess.sphereVelocity; //sphere1Blue.transform.forward * speed * Time.deltaTime; Debug.DrawRay(sphere1Blue.transform.position, sphere1Blue.transform.forward * speed, Color.blue); sphere2RedInitialVelo = sphereRedVeloAccess.sphereVelocity; //sphere2Red.transform.forward * speed * Time.deltaTime; Debug.DrawRay(sphere2Red.transform.position, sphere2Red.transform.forward * speed, Color.red); //Dir = target.Pos - current.Pos Vector3 dir2BlueS = (sphere1Blue.transform.position - sphere2Red.transform.position).normalized; //normalize? Debug.DrawRay(sphere2Red.transform.position, dir2BlueS.normalized * 1, Color.red); Vector3 dir2RedS = (sphere2Red.transform.position - sphere1Blue.transform.position).normalized; //normalize? Debug.DrawRay(sphere1Blue.transform.position, dir2RedS.normalized * 1, Color.blue); //====================================================================================================== Vector3 blueSphereHypo = sphere1BlueInitialVelo; Vector3 collisionDir = dir2RedS.normalized; float blueA1 = Vector3.Dot(blueSphereHypo, collisionDir); // length of the component of each of the movement vectors along the dir Vector3 redSphereHypo = sphere2RedInitialVelo; //Vector3 redSphereDir = dir2BlueS.normalized; float redA2 = Vector3.Dot(redSphereHypo, collisionDir); //redSphereDir); float P = (2 * (blueA1 - redA2)) / (1 + 1); Vector3 blueNewV1 = blueSphereHypo - P * 1 * collisionDir; //redSphereDir; Vector3 redNewV1 = redSphereHypo + P * 1 * collisionDir; //====================================================================================================== sphereRedVeloAccess.sphereVelocity = redNewV1; sphereBlueVeloAccess.sphereVelocity = blueNewV1; }
public int BestPlaneAxis() { Vector3 viewDir = Camera.main.transform.forward; Vector3 molDir = moleculeSpace.transform.forward; return((Mathf.Abs(Vector3.Dot(viewDir, molDir)) < 0.8f) ? 0 : 2); }
// Credit // http://wiki.unity3d.com/index.php/3d_Math_functions // http://creativecommons.org/licenses/by-sa/3.0/ //This function returns a point which is a projection from a point to a line. //The line is regarded infinite. If the line is finite, use ProjectPointOnLineSegment() instead. public static Vector3 ProjectPointOnLine(Vector3 linePoint, Vector3 lineVec, Vector3 point) { //get vector from point on line to point in space Vector3 linePointToPoint = point - linePoint; float t = Vector3.Dot(linePointToPoint, lineVec); return(linePoint + lineVec * t); }
private Vector3 EPA_3d(Prism prismA, Prism prismB) { var n = pointList.Count(); var minDist = float.MaxValue; var prevDist = 0f; Tuple <Vector3, Vector3, Vector3> closestPlane = null; Vector3 support = Vector3.zero; var normal = Vector3.zero; List <Tuple <Vector3, Vector3, Vector3> > simplex = new List <Tuple <Vector3, Vector3, Vector3> >(); for (var i = 0; i < n; i++) { for (var j = i + 1; j < n; j++) { for (var k = j + 1; k < n; k++) { simplex.Add(new Tuple <Vector3, Vector3, Vector3>(pointList[i], pointList[j], pointList[k])); } } } while (Mathf.Abs(prevDist - minDist) > 0.01f) { // DrawSimplex(simplex); prevDist = minDist; foreach (var plane in simplex) { // normal to the plane normal = Vector3.Cross(plane.Item2 - plane.Item1, plane.Item3 - plane.Item1).normalized; // projecttion of AO vector on this normal is the distance of Origin from the plane) float distanceFromOrigin = Vector3.Dot(normal, -plane.Item1); if (distanceFromOrigin < minDist) { minDist = distanceFromOrigin; closestPlane = plane; } } // find normal to this vector in the outward direction (away from origin) normal = -normal; // find support point on minkowski in the direction of this normal vector support = getSupport(prismA, prismB, normal); // remove this plane and 3 more to the list simplex.Remove(closestPlane); simplex.Add(new Tuple <Vector3, Vector3, Vector3>(closestPlane.Item1, closestPlane.Item2, support)); simplex.Add(new Tuple <Vector3, Vector3, Vector3>(closestPlane.Item1, closestPlane.Item3, support)); simplex.Add(new Tuple <Vector3, Vector3, Vector3>(closestPlane.Item2, closestPlane.Item3, support)); } return(support); }
/// <summary>Calcule distance minimum entre les deux droites</summary> public static float Dist(Line x, Line y) { Point n = Point.Cross(x.direction.normalized, y.direction.normalized); if (n.magnitude == 0) // if parallel { return(Dist(x, y.origin)); } return(Mathf.Abs(Point.Dot(n.normalized, (y.origin - x.origin)))); }
/// <summary>Calcule la distance signée entre une droite et un plan. Le signe dépend du côté duquel se trouve la droite par rapport au plan. Vaut 0 si ils ne sont pas parallèles.</summary> public static float DistSigned(Plane p, Line l) { Point d = l.direction, n = p.normal; if (Point.Dot(d, n) == 0) // plane parallel to ray { return(DistSigned(p, l.origin)); } return(0); }
float FCT_BBSK(Vector3 pos) { Vector3 cFcParams = new Vector3(2.18f, -0.18f, 0); Vector3 CSize = new Vector3(1.4f, 0.87f, 1.1f); Vector3 p; p.x = 2 * pos.x; p.y = 2 * pos.z; p.z = 2 * pos.y; float scale = 1.0f; for (int i = 0; i < 4; i++) { p.x = 2 * Mathf.Clamp(p.x, -CSize.x, CSize.x) - p.x; p.y = 2 * Mathf.Clamp(p.y, -CSize.y, CSize.y) - p.y; p.z = 2 * Mathf.Clamp(p.z, -CSize.z, CSize.x) - p.z; float r2 = Vector3.Dot(p, p); //float r2 = dot(p,p+sin(p.z*.5)); //Alternate fractal float k = Mathf.Max((2f) / (r2), .17f); p *= k; //p *=rot; //p= p.yzx; p += new Vector3(0.2f, 0.2f, -0.5f); scale *= k; } p.x = 2 * Mathf.Clamp(p.x, -CSize.x * 4, CSize.x * 4) - p.x; p.y = 2 * Mathf.Clamp(p.y, -CSize.y * 4, CSize.y * 4) - p.y; p.z = 2 * Mathf.Clamp(p.z, -CSize.z * 4, CSize.x * 4) - p.z; for (int i = 0; i < 8; i++) { p.x = 2 * Mathf.Clamp(p.x, -CSize.x, CSize.x) - p.x; p.y = 2 * Mathf.Clamp(p.y, -CSize.y, CSize.y) - p.y; p.z = 2 * Mathf.Clamp(p.z, -CSize.z, CSize.x) - p.z; float r2 = Vector3.Dot(p, p); //float r2 = dot(p,p+sin(p.z*.3)); //Alternate fractal float k = Math.Max((cFcParams.x) / (r2), 0.027f); p *= k; scale *= k; p.y += cFcParams.y; } float l = Mathf.Sqrt(Vector2.SqrMagnitude(new Vector2(p.x, p.y))); //l = mix(l,l2,0.5); float rxy = l - 4; float n = p.z; rxy = Math.Max(rxy, -(n) / 4); float dist = (rxy) / Math.Abs(scale); dist *= .75f; return(dist); }
private Vector3 DampenVelocity(ParticleCollider particleCollider, Vector3 velocity, Vector3 penetrationNormal, float drag) { Vector3 newVelocity = Vector3.Dot(velocity, penetrationNormal) * _damping * penetrationNormal + Vector3.Dot(velocity, particleCollider.Right) * drag * particleCollider.Right + Vector3.Dot(velocity, particleCollider.Up) * Drag * particleCollider.Up; return(Vector3.Dot(newVelocity, Vector3.forward) * Vector3.forward + Vector3.Dot(newVelocity, Vector3.right) * Vector3.right + Vector3.Dot(newVelocity, Vector3.up) * Vector3.up); }
/** True if the matrix will reverse orientations of faces. * * Scaling by a negative value along an odd number of axes will reverse * the orientation of e.g faces on a mesh. This must be counter adjusted * by for example the recast rasterization system to be able to handle * meshes with negative scales properly. * * We can find out if they are flipped by finding out how the signed * volume of a unit cube is transformed when applying the matrix * * If the (signed) volume turns out to be negative * that also means that the orientation of it has been reversed. * * \see https://en.wikipedia.org/wiki/Normal_(geometry) * \see https://en.wikipedia.org/wiki/Parallelepiped */ public static bool ReversesFaceOrientations(Matrix4x4 matrix) { var dX = matrix.MultiplyVector(new Vector3(1, 0, 0)); var dY = matrix.MultiplyVector(new Vector3(0, 1, 0)); var dZ = matrix.MultiplyVector(new Vector3(0, 0, 1)); // Calculate the signed volume of the parallelepiped var volume = Vector3.Dot(Vector3.Cross(dX, dY), dZ); return(volume < 0); }
void OnControllerColliderHit(ControllerColliderHit hit) { if (hit.collider) { velocity -= Vector3.Dot(velocity, hit.normal) * hit.normal; if (Vector3.Dot(Vector3.up, hit.normal) >= minVerticalGroundNormal) { groundNormal = hit.normal; } } }
private bool CheckCollision(ParticleCollider particleCollider, Vector3 position, float radius, out Vector3 penetrationNormal, out Vector3 penetrationPosition, out float penetrationLength) { Vector3 colliderProjection = particleCollider.Position - position; penetrationNormal = Vector3.Cross(particleCollider.Right, particleCollider.Up); penetrationLength = Mathf.Abs(Vector3.Dot(colliderProjection, penetrationNormal)) - (radius / 2.0f); penetrationPosition = particleCollider.Position - colliderProjection; return(penetrationLength < 0.0f && Mathf.Abs(Vector3.Dot(colliderProjection, particleCollider.Right)) < particleCollider.Scale.x && Mathf.Abs(Vector3.Dot(colliderProjection, particleCollider.Up)) < particleCollider.Scale.y); }
private bool isLookAtTarget(MyObject currentTarget) { Vector3 dirFromAtoB = (currentTarget.transform.position - transform.position).normalized; float dotProd = Vector3.Dot(dirFromAtoB, transform.forward); if (dotProd > facingThreshold) { return(true); } return(false); }
private Vector3 EPA_2D(Prism prismA, Prism prismB) { var n = pointList.Count(); var minDist = float.MaxValue; var prevDist = 0f; Tuple <Vector3, Vector3> closestSide = null; Vector3 support = Vector3.zero; var normal = Vector3.zero; List <Tuple <Vector3, Vector3> > simplex = new List <Tuple <Vector3, Vector3> >(); for (var i = 0; i < n; i++) { simplex.Add(new Tuple <Vector3, Vector3>(pointList[i], pointList[(i + 1) % n])); } while (Mathf.Abs(prevDist - minDist) > 0.01f) { // DrawSimplex(simplex); prevDist = minDist; foreach (var side in simplex) { float distanceFromOrigin = Vector3.Cross(side.Item2 - side.Item1, -side.Item1).magnitude; if (distanceFromOrigin < minDist) { minDist = distanceFromOrigin; closestSide = side; } } // find normal to this vector in the outward direction (away from origin) var direction = closestSide.Item2 - closestSide.Item1; normal = new Vector3(-direction.z, 0f, direction.x); if (Vector3.Dot(normal, -closestSide.Item1) > 0) { normal = -normal; } // find support point on minkowski in the direction of this normal vector support = getSupport(prismA, prismB, normal); // remove this side from from the list and add the two new sides in the list simplex.Remove(closestSide); simplex.Add(new Tuple <Vector3, Vector3>(closestSide.Item1, support - closestSide.Item1)); simplex.Add(new Tuple <Vector3, Vector3>(support, closestSide.Item2)); } // Debug.DrawLine(Vector3.zero, support, Color.yellow,UPDATE_RATE); return(support); }
// Sets the thickness of the portal screen so as not to clip with camera near plane when player goes through void ProtectScreenFromClipping(Vector3 viewPoint) { float halfHeight = Camera.main.nearClipPlane * Mathf.Tan(Camera.main.fieldOfView * 0.5f * Mathf.Deg2Rad); float halfWidth = halfHeight * Camera.main.aspect; float dstToNearClipPlaneCorner = new Vector3(halfWidth, halfHeight, Camera.main.nearClipPlane).magnitude; float screenThickness = dstToNearClipPlaneCorner; Transform screenT = screen.transform; bool camFacingSameDirAsPortal = Vector3.Dot(transform.forward, transform.position - viewPoint) > 0; screenT.localScale = new Vector3(screenT.localScale.x, screenT.localScale.y, screenThickness); screenT.localPosition = Vector3.forward * screenThickness * (camFacingSameDirAsPortal ? 0.5f : -0.5f); }
public Vector3 PositionUnderMousePlaneAndSphere(out bool fail) { fail = false; Vector3 result = PositionUnderMousePlane(out fail); Vector3 d = result - atom.molecularParent.transform.position; float targetDistance = atom.distanceToMolecularParent; float dot = Vector3.Dot(WorldNormal(), d); Vector3 dn = WorldNormal() * dot; //component along plane normal Vector3 dp = d - dn; //component on plane (d = dn + dp) float targetDp = Mathf.Sqrt(Mathf.Abs(targetDistance * targetDistance - dot * dot)); dp = dp.normalized * targetDp; return(atom.molecularParent.transform.position + dp + dn); }
void AdjustVelocity() { float acceleration, speed; Vector3 xAxis, zAxis; if (Climbing) { acceleration = maxClimbAcceleration; speed = maxClimbSpeed; xAxis = Vector3.Cross(contactNormal, upAxis); zAxis = upAxis; } else if (InWater) { float swimFactor = Mathf.Min(1f, submergence / swimThreshold); acceleration = Mathf.LerpUnclamped(OnGround ? maxAcceleration : maxAirAcceleration, maxSwimAcceleration, swimFactor); speed = Mathf.LerpUnclamped(maxSpeed, maxSwimSpeed, swimFactor); xAxis = rightAxis; zAxis = forwardAxis; } else { acceleration = OnGround ? maxAcceleration : maxAirAcceleration; speed = OnGround && desiresClimbing ? maxClimbSpeed : maxSpeed; xAxis = rightAxis; zAxis = forwardAxis; } float maxSpeedChange = acceleration * Time.deltaTime; xAxis = ProjectOnContactPlane(xAxis, contactNormal); zAxis = ProjectOnContactPlane(zAxis, contactNormal); Vector3 relativeVelocity = velocity - connectionVelocity; float currentX = Vector3.Dot(relativeVelocity, xAxis); float currentZ = Vector3.Dot(relativeVelocity, zAxis); float newX = Mathf.MoveTowards(currentX, playerInput.x * speed, maxSpeedChange); float newZ = Mathf.MoveTowards(currentZ, playerInput.y * speed, maxSpeedChange); velocity += xAxis * (newX - currentX) + zAxis * (newZ - currentZ); if (Swimming) { float currentY = Vector3.Dot(relativeVelocity, upAxis); float newY = Mathf.MoveTowards(currentY, playerInput.z * speed, maxSpeedChange); velocity += upAxis * (newY - currentY); } }
/** Finds the closest point on the current path and configures the #interpolator */ protected virtual void ConfigureNewPath() { var hadValidPath = interpolator.valid; var prevTangent = hadValidPath ? interpolator.tangent : Vector3.zero; interpolator.SetPath(path.vectorPath); interpolator.MoveToClosestPoint(GetFeetPosition()); if (interpolatePathSwitches && switchPathInterpolationSpeed > 0.01f && hadValidPath) { var correctionFactor = Mathf.Max(-Vector3.Dot(prevTangent.normalized, interpolator.tangent.normalized), 0); interpolator.distance -= speed * correctionFactor * (1f / switchPathInterpolationSpeed); } }